From 2944ba2c83b2f59bf8d49e5a6187f5b1bf394343 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 25 Jul 2019 16:13:19 +0200 Subject: [PATCH 001/636] initial implementation of redux for collapsable defi cards --- .../investment-cards/InvestmentCardHeader.js | 60 +++++++++++-------- .../investment-cards/UniswapInvestmentCard.js | 7 ++- src/hoc/index.js | 1 + src/hoc/withOpenInvestmentCards.js | 9 +++ src/redux/openInvestmentCards.js | 30 ++++++++++ src/redux/reducers.js | 2 + 6 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 src/hoc/withOpenInvestmentCards.js create mode 100644 src/redux/openInvestmentCards.js diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index 27a273782b2..c7af671e8df 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -11,6 +11,8 @@ import { RowWithMargins, } from '../layout'; import { Emoji, Monospace, Text } from '../text'; +import { ButtonPressAnimation } from '../animations'; +import { withOpenInvestmentCards } from '../../hoc'; const HeaderHeight = 48; @@ -32,7 +34,14 @@ const InvestmentCardHeader = enhance(({ title, titleColor, value, -}) => ( + openInvestmentCards, + setOpenInvestmentCards, +}) => { + const onPress = () => { + setOpenInvestmentCards({ index: 0, state: !openInvestmentCards[0] }); + } + + return ( {value} - {isCollapsible && ( - - - + + {isCollapsible && ( + + + + - - )} + )} + -)); + ) +}); InvestmentCardHeader.propTypes = { collapsed: PropTypes.bool, @@ -106,4 +118,4 @@ InvestmentCardHeader.defaultProps = { InvestmentCardHeader.height = HeaderHeight; -export default InvestmentCardHeader; +export default withOpenInvestmentCards(InvestmentCardHeader); diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 6a381beb793..0a8ac59d491 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -8,7 +8,7 @@ import { withProps, } from 'recompact'; import { convertAmountToNativeDisplay } from '../../helpers/utilities'; -import { withAccountSettings } from '../../hoc'; +import { withAccountSettings, withOpenInvestmentCards } from '../../hoc'; import { colors, padding } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import Divider from '../Divider'; @@ -47,6 +47,7 @@ const UniswapInvestmentCard = enhance(({ onPress, onPressContainer, nativeCurrency, + openInvestmentCards, ...props }) => ( ({ openInvestmentCards }); + +export default Component => connect(mapStateToProps, { + pushOpenInvestmentCard, + setOpenInvestmentCards, +})(Component); diff --git a/src/redux/openInvestmentCards.js b/src/redux/openInvestmentCards.js new file mode 100644 index 00000000000..69c4607e9af --- /dev/null +++ b/src/redux/openInvestmentCards.js @@ -0,0 +1,30 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_OPEN_INVESTMENT_CARDS = 'openInvestmentCards/SET_OPEN_INVESTMENT_CARDS'; +const PUSH_OPEN_INVESTMENT_CARD = 'openInvestmentCards/PUSH_OPEN_INVESTMENT_CARD'; + +export const setOpenInvestmentCards = payload => dispatch => dispatch({ + payload, + type: SET_OPEN_INVESTMENT_CARDS, +}); + +export const pushOpenInvestmentCard = payload => dispatch => dispatch({ + payload, + type: PUSH_OPEN_INVESTMENT_CARD, +}); + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + openInvestmentCards: [false], +}; + +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + if (action.type === SET_OPEN_INVESTMENT_CARDS) { + draft.openInvestmentCards[action.payload.index] = action.payload.state; + } else if (action.type === PUSH_OPEN_INVESTMENT_CARD) { + draft.openInvestmentCards = state.openInvestmentCards.concat(false); + } + }) +); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 92c2e5e9018..343393746b5 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -7,6 +7,7 @@ import isWalletEmpty from './isWalletEmpty'; import navigation from './navigation'; import nonce from './nonce'; import openFamilyTabs from './openFamilyTabs'; +import openInvestmentCards from './openInvestmentCards'; import requests from './requests'; import selectedWithFab from './selectedWithFab'; import send from './send'; @@ -23,6 +24,7 @@ export default combineReducers({ navigation, nonce, openFamilyTabs, + openInvestmentCards, requests, selectedWithFab, send, From 42ea39c4aa90674d7772ca79b0b17cf7a1b6decb Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 25 Jul 2019 16:42:44 +0200 Subject: [PATCH 002/636] add closed defi cards to recycledassetlist --- .../asset-list/RecyclerAssetList.js | 27 ++++++++++++++----- .../investment-cards/UniswapInvestmentCard.js | 1 + 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 3a6aae9a080..ffb99a30cda 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -19,7 +19,7 @@ import { buildAssetHeaderUniqueIdentifier, buildAssetUniqueIdentifier, } from '../../helpers/assets'; -import { withOpenFamilyTabs } from '../../hoc'; +import { withOpenFamilyTabs, withOpenInvestmentCards } from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; import { CoinRow, CollectiblesSendRow } from '../coin-row'; @@ -39,6 +39,8 @@ export const ViewTypes = { UNIQUE_TOKEN_ROW_LAST: 9, // TODO remove UNISWAP_ROW: 6, UNISWAP_ROW_LAST: 7, + UNISWAP_ROW_CLOSED: 8, + UNISWAP_ROW_CLOSED_LAST: 9, FOOTER: 10, }; @@ -97,6 +99,7 @@ class RecyclerAssetList extends PureComponent { fetchData: PropTypes.func, hideHeader: PropTypes.bool, openFamilyTabs: PropTypes.array, + openInvestmentCards: PropTypes.array, paddingBottom: PropTypes.number, renderAheadOffset: PropTypes.number, scrollingVelocity: PropTypes.number, @@ -139,7 +142,7 @@ class RecyclerAssetList extends PureComponent { this.layoutProvider = new LayoutProvider( index => { - const { openFamilyTabs, sections } = this.props; + const { openFamilyTabs, openInvestmentCards, sections } = this.props; const { headersIndices } = this.state; if (headersIndices.includes(index)) { return ViewTypes.HEADER; @@ -166,9 +169,15 @@ class RecyclerAssetList extends PureComponent { const lastInvestmentIndex = headersIndices[investmentsIndex] + investmentItemsCount; if ((index > headersIndices[investmentsIndex]) && (index <= lastInvestmentIndex)) { - return index === lastInvestmentIndex - ? ViewTypes.UNISWAP_ROW_LAST - : ViewTypes.UNISWAP_ROW; + if (!openInvestmentCards[index - headersIndices[investmentsIndex] - 1]) { + return index === lastInvestmentIndex + ? ViewTypes.UNISWAP_ROW_LAST + : ViewTypes.UNISWAP_ROW; + } else { + return index === lastInvestmentIndex + ? ViewTypes.UNISWAP_ROW_CLOSED_LAST + : ViewTypes.UNISWAP_ROW_CLOSED; + } } } @@ -224,6 +233,10 @@ class RecyclerAssetList extends PureComponent { dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical + ListFooter.height + 7; } else if (type === ViewTypes.UNISWAP_ROW) { dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical; + } else if (type === ViewTypes.UNISWAP_ROW_CLOSED_LAST) { + dim.height = UniswapInvestmentCard.headerHeight + InvestmentCard.margin.vertical + ListFooter.height + 7; + } else if (type === ViewTypes.UNISWAP_ROW_CLOSED) { + dim.height = UniswapInvestmentCard.headerHeight + InvestmentCard.margin.vertical; } else if (type == ViewTypes.HEADER) { dim.height = this.props.hideHeader ? 0 : AssetListHeader.height; } else if (type == ViewTypes.FOOTER) { @@ -379,6 +392,8 @@ class RecyclerAssetList extends PureComponent { || type === ViewTypes.COIN_ROW_LAST || type === ViewTypes.UNISWAP_ROW || type === ViewTypes.UNISWAP_ROW_LAST + || type === ViewTypes.UNISWAP_ROW_CLOSED + || type === ViewTypes.UNISWAP_ROW_CLOSED_LAST ); // TODO sections @@ -449,4 +464,4 @@ const mapStateToProps = ({ }) => ({ scrollingVelocity, }); -export default connect(mapStateToProps)(withOpenFamilyTabs(RecyclerAssetList)); +export default connect(mapStateToProps)(withOpenFamilyTabs(withOpenInvestmentCards(RecyclerAssetList))); diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 0a8ac59d491..2518d8ba04b 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -101,5 +101,6 @@ UniswapInvestmentCard.propTypes = { }; UniswapInvestmentCard.height = 114; +UniswapInvestmentCard.headerHeight = 45; export default withOpenInvestmentCards(UniswapInvestmentCard); From ac43f111cc023bd1f81f6478659902a4da5e97b5 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 25 Jul 2019 18:54:06 +0200 Subject: [PATCH 003/636] add transition to make animation of the investment card height --- .../investment-cards/InvestmentCard.js | 104 +++++++++++------- .../investment-cards/InvestmentCardHeader.js | 11 +- .../investment-cards/UniswapInvestmentCard.js | 48 ++++---- src/components/shadow-stack/ShadowStack.js | 4 +- 4 files changed, 93 insertions(+), 74 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 0c8dcc3e7be..951e7fa534a 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -1,6 +1,6 @@ import withViewLayoutProps from '@hocs/with-view-layout-props'; import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useState, useRef } from 'react'; import LinearGradient from 'react-native-linear-gradient'; import { compose, pure } from 'recompact'; import { colors, margin, position } from '../../styles'; @@ -9,6 +9,9 @@ import InnerBorder from '../InnerBorder'; import { Column } from '../layout'; import { ShadowStack } from '../shadow-stack'; import InvestmentCardHeader from './InvestmentCardHeader'; +import { Transitioning, Transition } from 'react-native-reanimated'; +import { ButtonPressAnimation } from '../animations'; +import { withOpenInvestmentCards } from '../../hoc'; const InvestmentCardMargin = { horizontal: 19, @@ -22,7 +25,7 @@ const enhance = compose( pure, ); -const InvestmentCard = enhance(({ +const InvestmentCard = ({ children, collapsed, containerHeight, @@ -30,42 +33,65 @@ const InvestmentCard = enhance(({ headerProps, onLayout, shadows, + setOpenInvestmentCards, + openInvestmentCards, ...props -}) => ( - - { + const transition = ; + + let [perc, setPerc] = useState(114); + const ref = useRef(); + + const onPress = () => { + setOpenInvestmentCards({ index: 0, state: !openInvestmentCards[0] }); + ref.current.animateNextTransition(); + setPerc(perc == 114 ? 50 : 114); + } + + return ( + - - - {collapsed ? null : children} - - - -)); + + + + + + + {children} + + + + + )}; InvestmentCard.propTypes = { children: PropTypes.node, @@ -81,11 +107,11 @@ InvestmentCard.defaultProps = { containerHeight: DefaultContainerHeight, gradientColors: ['#F7FAFC', '#E0E6EC'], shadows: [ - [0, 1, 3, colors.dark, 0.08], - [0, 4, 6, colors.dark, 0.04], + [0, 1, 3, colors.dark, 0.00], + [0, 4, 6, colors.dark, 0.00], ], }; InvestmentCard.margin = InvestmentCardMargin; -export default InvestmentCard; +export default withOpenInvestmentCards(InvestmentCard); diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index c7af671e8df..2410ba9313a 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -11,8 +11,6 @@ import { RowWithMargins, } from '../layout'; import { Emoji, Monospace, Text } from '../text'; -import { ButtonPressAnimation } from '../animations'; -import { withOpenInvestmentCards } from '../../hoc'; const HeaderHeight = 48; @@ -34,12 +32,7 @@ const InvestmentCardHeader = enhance(({ title, titleColor, value, - openInvestmentCards, - setOpenInvestmentCards, }) => { - const onPress = () => { - setOpenInvestmentCards({ index: 0, state: !openInvestmentCards[0] }); - } return ( @@ -72,7 +65,6 @@ const InvestmentCardHeader = enhance(({ > {value} - {isCollapsible && ( )} - ) @@ -118,4 +109,4 @@ InvestmentCardHeader.defaultProps = { InvestmentCardHeader.height = HeaderHeight; -export default withOpenInvestmentCards(InvestmentCardHeader); +export default InvestmentCardHeader; diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 2518d8ba04b..0728e6af642 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -50,11 +50,6 @@ const UniswapInvestmentCard = enhance(({ openInvestmentCards, ...props }) => ( - - - - Ethereum - {tokenName} - - - - - - + + + + Ethereum + {tokenName} + + + + + + + - -)); + )); UniswapInvestmentCard.propTypes = { item: PropTypes.object, diff --git a/src/components/shadow-stack/ShadowStack.js b/src/components/shadow-stack/ShadowStack.js index 9dc9facd557..78f843b71b1 100644 --- a/src/components/shadow-stack/ShadowStack.js +++ b/src/components/shadow-stack/ShadowStack.js @@ -30,6 +30,7 @@ export default class ShadowStack extends PureComponent { height: PropTypes.number.isRequired, shadows: PropTypes.arrayOf(PropTypes.array).isRequired, style: stylePropType, + childrenWrapperStyle: stylePropType, width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, } @@ -51,13 +52,14 @@ export default class ShadowStack extends PureComponent { children, shadows, style, + childrenWrapperStyle, ...props } = this.props; return ( {shadows.map(this.renderItem)} - + {children} From ccafbccfb8054638ce19f54d0c249fdeca2049ba Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 25 Jul 2019 20:54:40 +0200 Subject: [PATCH 004/636] create template for working shadow below investment card transition --- .../asset-list/RecyclerAssetList.js | 6 +- .../investment-cards/InvestmentCard.js | 93 +++++++++++-------- .../investment-cards/UniswapInvestmentCard.js | 2 +- 3 files changed, 57 insertions(+), 44 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index ffb99a30cda..83a9cc9674b 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -23,7 +23,7 @@ import { withOpenFamilyTabs, withOpenInvestmentCards } from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; import { CoinRow, CollectiblesSendRow } from '../coin-row'; -import { InvestmentCard, UniswapInvestmentCard } from '../investment-cards'; +import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../investment-cards'; import { ListFooter } from '../list'; import { CardMargin, CardSize, RowPadding } from '../unique-token/UniqueTokenRow'; import AssetListHeader from './AssetListHeader'; @@ -234,9 +234,9 @@ class RecyclerAssetList extends PureComponent { } else if (type === ViewTypes.UNISWAP_ROW) { dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED_LAST) { - dim.height = UniswapInvestmentCard.headerHeight + InvestmentCard.margin.vertical + ListFooter.height + 7; + dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical + ListFooter.height + 7; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED) { - dim.height = UniswapInvestmentCard.headerHeight + InvestmentCard.margin.vertical; + dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical; } else if (type == ViewTypes.HEADER) { dim.height = this.props.hideHeader ? 0 : AssetListHeader.height; } else if (type == ViewTypes.FOOTER) { diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 951e7fa534a..d372242cb98 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React, { useState, useRef } from 'react'; import LinearGradient from 'react-native-linear-gradient'; import { compose, pure } from 'recompact'; -import { colors, margin, position } from '../../styles'; +import { colors, margin, position, shadow as shadowUtil } from '../../styles'; import { deviceUtils } from '../../utils'; import InnerBorder from '../InnerBorder'; import { Column } from '../layout'; @@ -12,6 +12,7 @@ import InvestmentCardHeader from './InvestmentCardHeader'; import { Transitioning, Transition } from 'react-native-reanimated'; import { ButtonPressAnimation } from '../animations'; import { withOpenInvestmentCards } from '../../hoc'; +import { View } from 'react-native'; const InvestmentCardMargin = { horizontal: 19, @@ -35,17 +36,18 @@ const InvestmentCard = ({ shadows, setOpenInvestmentCards, openInvestmentCards, + openHeight, ...props }) => { const transition = ; - let [perc, setPerc] = useState(114); + let [perc, setPerc] = useState(openHeight); const ref = useRef(); const onPress = () => { setOpenInvestmentCards({ index: 0, state: !openInvestmentCards[0] }); ref.current.animateNextTransition(); - setPerc(perc == 114 ? 50 : 114); + setPerc(perc == openHeight ? InvestmentCardHeader.height : openHeight); } return ( @@ -53,43 +55,54 @@ const InvestmentCard = ({ ref={ref} transition={transition} > - - - - - + - - {children} - - - + + + + {children} + + + )}; @@ -107,8 +120,8 @@ InvestmentCard.defaultProps = { containerHeight: DefaultContainerHeight, gradientColors: ['#F7FAFC', '#E0E6EC'], shadows: [ - [0, 1, 3, colors.dark, 0.00], - [0, 4, 6, colors.dark, 0.00], + [0, 1, 3, colors.dark, 0.08], + [0, 4, 6, colors.dark, 0.04], ], }; diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 0728e6af642..1c51b8964aa 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -55,6 +55,7 @@ const UniswapInvestmentCard = enhance(({ flex={0} gradientColors={['#ECF1F5', '#E4E9F0']} collapsed={openInvestmentCards[0]} + openHeight={UniswapInvestmentCard.height} headerProps={{ color: colors.dark, emoji: 'unicorn_face', @@ -101,6 +102,5 @@ UniswapInvestmentCard.propTypes = { }; UniswapInvestmentCard.height = 114; -UniswapInvestmentCard.headerHeight = 45; export default withOpenInvestmentCards(UniswapInvestmentCard); From fa7fa968cc2feba13b521f8069f3a0fc3fd33b3a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 25 Jul 2019 21:04:32 +0200 Subject: [PATCH 005/636] remove unnecessary prop --- src/components/investment-cards/InvestmentCard.js | 14 +++----------- .../investment-cards/UniswapInvestmentCard.js | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index d372242cb98..2869c8e8293 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -19,13 +19,6 @@ const InvestmentCardMargin = { vertical: 15, }; -const DefaultContainerHeight = InvestmentCardHeader.height; - -const enhance = compose( - withViewLayoutProps(({ height }) => ({ containerHeight: height || DefaultContainerHeight })), - pure, -); - const InvestmentCard = ({ children, collapsed, @@ -36,18 +29,17 @@ const InvestmentCard = ({ shadows, setOpenInvestmentCards, openInvestmentCards, - openHeight, ...props }) => { const transition = ; - let [perc, setPerc] = useState(openHeight); + let [perc, setPerc] = useState(containerHeight); const ref = useRef(); const onPress = () => { setOpenInvestmentCards({ index: 0, state: !openInvestmentCards[0] }); ref.current.animateNextTransition(); - setPerc(perc == openHeight ? InvestmentCardHeader.height : openHeight); + setPerc(perc == containerHeight ? InvestmentCardHeader.height : containerHeight); } return ( @@ -117,7 +109,7 @@ InvestmentCard.propTypes = { }; InvestmentCard.defaultProps = { - containerHeight: DefaultContainerHeight, + containerHeight: InvestmentCardHeader.height, gradientColors: ['#F7FAFC', '#E0E6EC'], shadows: [ [0, 1, 3, colors.dark, 0.08], diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 1c51b8964aa..78d1cfbffab 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -55,7 +55,7 @@ const UniswapInvestmentCard = enhance(({ flex={0} gradientColors={['#ECF1F5', '#E4E9F0']} collapsed={openInvestmentCards[0]} - openHeight={UniswapInvestmentCard.height} + containerHeight={UniswapInvestmentCard.height} headerProps={{ color: colors.dark, emoji: 'unicorn_face', From dc587503414292c6808499d0968f79e7e2cc5fbb Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 26 Jul 2019 14:06:35 +0200 Subject: [PATCH 006/636] adjust moving fab and auto scroll to investments collapsing mechanics --- .../asset-list/RecyclerAssetList.js | 12 ++++++++++-- src/components/fab/MovableFabWrapper.js | 19 +++++++++++++------ .../investment-cards/InvestmentCard.js | 7 ++++--- .../investment-cards/UniswapInvestmentCard.js | 4 +++- src/redux/openInvestmentCards.js | 2 +- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 83a9cc9674b..c7a61c34541 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -169,7 +169,7 @@ class RecyclerAssetList extends PureComponent { const lastInvestmentIndex = headersIndices[investmentsIndex] + investmentItemsCount; if ((index > headersIndices[investmentsIndex]) && (index <= lastInvestmentIndex)) { - if (!openInvestmentCards[index - headersIndices[investmentsIndex] - 1]) { + if (!openInvestmentCards[ sections[investmentsIndex].data[index - headersIndices[investmentsIndex] - 1].uniqueId ]) { return index === lastInvestmentIndex ? ViewTypes.UNISWAP_ROW_LAST : ViewTypes.UNISWAP_ROW; @@ -317,9 +317,17 @@ class RecyclerAssetList extends PureComponent { collectiblesHeight += 54; } } + let investmentHeight = ListFooter.height; + for (let i = 0; i < investments.data.length; i++) { + if(!this.props.openInvestmentCards[ investments.data[i].uniqueId ]) { + investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + } else { + investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + } + } const verticalOffset = 10; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + (UniswapInvestmentCard.height + InvestmentCard.margin.vertical) * get(investments, 'data.length', 0) + ListFooter.height; + const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + investmentHeight; const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; const renderSize = CardSize * collectibles.data[i].tokens.length + RowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; diff --git a/src/components/fab/MovableFabWrapper.js b/src/components/fab/MovableFabWrapper.js index bd7c9580676..9bcfce76c8b 100644 --- a/src/components/fab/MovableFabWrapper.js +++ b/src/components/fab/MovableFabWrapper.js @@ -4,7 +4,7 @@ import { PanGestureHandler, State } from 'react-native-gesture-handler'; import Animated from 'react-native-reanimated'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompact'; -import { withOpenFamilyTabs } from '../../hoc'; +import { withOpenFamilyTabs, withOpenInvestmentCards } from '../../hoc'; import { setActionType, setScrollingVelocity, @@ -14,7 +14,7 @@ import { deviceUtils } from '../../utils'; import { CoinRow } from '../coin-row'; import { ListFooter } from '../list'; import { CardSize, CardMargin } from '../unique-token/UniqueTokenRow'; -import { InvestmentCard, UniswapInvestmentCard } from '../investment-cards'; +import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../investment-cards'; const { add, @@ -95,6 +95,7 @@ class Movable extends React.Component { children: PropTypes.any, deleteButtonTranslate: PropTypes.object, openFamilyTabs: PropTypes.array, + openInvestmentCards: PropTypes.array, scrollViewTracker: PropTypes.object, sections: PropTypes.array, setActionType: PropTypes.func, @@ -283,7 +284,7 @@ class Movable extends React.Component { } } -const traverseSectionsToDimensions = ({ sections, openFamilyTabs }) => { +const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestmentCards }) => { let balances = false; let collectibles = false; let investments = false; @@ -315,8 +316,14 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs }) => { height += headerHeight; } if (investments) { - height += headerHeight; - height += investments.data.length * (UniswapInvestmentCard.height + InvestmentCard.margin.vertical) + ListFooter.height; + height += headerHeight + ListFooter.height; + for (let i = 0; i < investments.data.length; i++) { + if(!openInvestmentCards[ investments.data[i].uniqueId ]) { + height += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + } else { + height += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + } + } } if (collectibles) { for (let i = 0; i < collectibles.data.length; i++) { @@ -363,4 +370,4 @@ const EnhancedMovable = compose( )(Movable); -export default withOpenFamilyTabs(EnhancedMovable); +export default withOpenFamilyTabs(withOpenInvestmentCards(EnhancedMovable)); diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 2869c8e8293..820c365ab6e 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -29,17 +29,18 @@ const InvestmentCard = ({ shadows, setOpenInvestmentCards, openInvestmentCards, + uniqueId, ...props }) => { const transition = ; - let [perc, setPerc] = useState(containerHeight); + let [perc, setPerc] = useState(collapsed ? InvestmentCardHeader.height : containerHeight); const ref = useRef(); const onPress = () => { - setOpenInvestmentCards({ index: 0, state: !openInvestmentCards[0] }); + setOpenInvestmentCards({ index: uniqueId , state: !openInvestmentCards[uniqueId] }); ref.current.animateNextTransition(); - setPerc(perc == containerHeight ? InvestmentCardHeader.height : containerHeight); + setPerc(!openInvestmentCards[uniqueId] ? InvestmentCardHeader.height : containerHeight); } return ( diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 78d1cfbffab..9861aba0e60 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -43,6 +43,7 @@ const UniswapInvestmentCard = enhance(({ tokenSymbol, totalBalanceAmount, totalNativeDisplay, + uniqueId }, onPress, onPressContainer, @@ -54,7 +55,8 @@ const UniswapInvestmentCard = enhance(({ {...props} flex={0} gradientColors={['#ECF1F5', '#E4E9F0']} - collapsed={openInvestmentCards[0]} + collapsed={openInvestmentCards[uniqueId]} + uniqueId={uniqueId} containerHeight={UniswapInvestmentCard.height} headerProps={{ color: colors.dark, diff --git a/src/redux/openInvestmentCards.js b/src/redux/openInvestmentCards.js index 69c4607e9af..85a0f9ebb0f 100644 --- a/src/redux/openInvestmentCards.js +++ b/src/redux/openInvestmentCards.js @@ -16,7 +16,7 @@ export const pushOpenInvestmentCard = payload => dispatch => dispatch({ // -- Reducer ----------------------------------------- // const INITIAL_STATE = { - openInvestmentCards: [false], + openInvestmentCards: {}, }; export default (state = INITIAL_STATE, action) => ( From ca0bdbb27a28ff9587c903394754e3145b6b74d5 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 26 Jul 2019 15:10:15 +0200 Subject: [PATCH 007/636] add animated caret to collapsable investment card --- .../expanded-state/InvestmentExpandedState.js | 1 + .../investment-cards/InvestmentCard.js | 3 +- .../investment-cards/InvestmentCardHeader.js | 193 ++++++++++++------ .../investment-cards/UniswapInvestmentCard.js | 3 +- src/helpers/buildWalletSections.js | 2 +- 5 files changed, 133 insertions(+), 69 deletions(-) diff --git a/src/components/expanded-state/InvestmentExpandedState.js b/src/components/expanded-state/InvestmentExpandedState.js index 46196c51a19..44a340ae67b 100644 --- a/src/components/expanded-state/InvestmentExpandedState.js +++ b/src/components/expanded-state/InvestmentExpandedState.js @@ -11,6 +11,7 @@ const InvestmentExpandedState = ({ asset }) => ( css={margin(0)} item={asset} width="100%" + isCollapsible={false} /> ); diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 820c365ab6e..a82e1511c39 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -30,6 +30,7 @@ const InvestmentCard = ({ setOpenInvestmentCards, openInvestmentCards, uniqueId, + isCollapsible, ...props }) => { const transition = ; @@ -86,7 +87,7 @@ const InvestmentCard = ({ start={{ x: 0, y: 0.5 }} style={position.coverAsObject} /> - + { +function runTiming(clock, value, dest, isOpen) { + const state = { + finished: new Value(1), + frameTime: new Value(0), + position: new Value(value), + time: new Value(0), + }; - return ( - - - - - - - {title} - - - - - {value} - - {isCollapsible && ( - - - + const config = { + duration: 200, + easing: Easing.inOut(Easing.ease), + toValue: new Value(0), + }; + + const reset = [ + set(state.finished, 0), + set(state.time, 0), + set(state.frameTime, 0), + ]; + + return block([ + cond(state.finished, [ + ...reset, + set(config.toValue, dest), + ]), + cond(clockRunning(clock), 0, startClock(clock)), + timing(clock, state, config), + state.position, + ]); +} + +class InvestmentCardHeader extends React.Component { + componentWillUpdate(prev) { + if (prev.collapsed !== undefined + && prev.collapsed !== this.props.collapsed) { + const clock = new Clock(); + let base = undefined; + this.props.collapsed ? base = runTiming(clock, -1, 1, this.props.collapsed) : base = runTiming(clock, 1, -1, this.props.collapsed); + this._rotation = interpolate(base, { + inputRange: [-1, 1], + outputRange: [0, 90], + }); + } + } + + render() { + let { collapsed, + color, + emoji, + isCollapsible, + title, + titleColor, + value, + } = this.props; + + return ( + + + + + + + {title} + + + + + {value} + + {isCollapsible && ( + + + + + + - - )} - - - ) -}); + )} + + + ) + } +}; InvestmentCardHeader.propTypes = { collapsed: PropTypes.bool, diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 9861aba0e60..578d069408e 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -49,6 +49,7 @@ const UniswapInvestmentCard = enhance(({ onPressContainer, nativeCurrency, openInvestmentCards, + isCollapsible, ...props }) => ( ; const tokenFamilyItem = item => ; -const uniswapRenderItem = item => ; +const uniswapRenderItem = item => ; const filterWalletSections = sections => ( sections.filter(({ data, header }) => ( From 6bc5429a3011b8243d2303ac1be41c3337d2ce08 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 26 Jul 2019 15:38:44 +0200 Subject: [PATCH 008/636] little adjustement to auto scroll height --- src/components/asset-list/RecyclerAssetList.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index c7a61c34541..36cb2112035 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -317,12 +317,14 @@ class RecyclerAssetList extends PureComponent { collectiblesHeight += 54; } } - let investmentHeight = ListFooter.height; - for (let i = 0; i < investments.data.length; i++) { - if(!this.props.openInvestmentCards[ investments.data[i].uniqueId ]) { - investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); - } else { - investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + let investmentHeight = 0; + if (investments.data) { + for (let i = 0; i < investments.data.length; i++) { + if(!this.props.openInvestmentCards[ investments.data[i].uniqueId ]) { + investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + } else { + investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + } } } const verticalOffset = 10; From cc5aa16e2ef3423eadaf56d616f66f31baad36f2 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 27 Jul 2019 01:31:09 +0200 Subject: [PATCH 009/636] add initial collapsible small balances --- .../asset-list/RecyclerAssetList.js | 56 +++++++++++++------ src/components/coin-divider/CoinDivider.js | 42 ++++++++++++++ src/helpers/assets.js | 17 ++++++ src/helpers/buildWalletSections.js | 4 +- 4 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 src/components/coin-divider/CoinDivider.js diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 36cb2112035..2307e0072ce 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -27,21 +27,23 @@ import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../ import { ListFooter } from '../list'; import { CardMargin, CardSize, RowPadding } from '../unique-token/UniqueTokenRow'; import AssetListHeader from './AssetListHeader'; +import CoinDivider from '../coin-divider/CoinDivider'; export const ViewTypes = { HEADER: 0, COIN_ROW: 1, // eslint-disable-line sort-keys COIN_ROW_LAST: 2, - UNIQUE_TOKEN_ROW: 3, - UNIQUE_TOKEN_ROW_CLOSED: 4, - UNIQUE_TOKEN_ROW_CLOSED_LAST: 5, + COIN_SMALL_BALANCES: 3, + UNIQUE_TOKEN_ROW: 4, + UNIQUE_TOKEN_ROW_CLOSED: 5, + UNIQUE_TOKEN_ROW_CLOSED_LAST: 6, UNIQUE_TOKEN_ROW_FIRST: 8, // TODO remove UNIQUE_TOKEN_ROW_LAST: 9, // TODO remove - UNISWAP_ROW: 6, - UNISWAP_ROW_LAST: 7, - UNISWAP_ROW_CLOSED: 8, - UNISWAP_ROW_CLOSED_LAST: 9, - FOOTER: 10, + UNISWAP_ROW: 7, + UNISWAP_ROW_LAST: 8, + UNISWAP_ROW_CLOSED: 9, + UNISWAP_ROW_CLOSED_LAST: 10, + FOOTER: 11, }; const Wrapper = styled.View` @@ -160,7 +162,14 @@ class RecyclerAssetList extends PureComponent { const balanceItemsCount = get(sections, `[${balancesIndex}].data.length`, 0); const lastBalanceIndex = headersIndices[balancesIndex] + balanceItemsCount; if (index === lastBalanceIndex) { - return ViewTypes.COIN_ROW_LAST; + if (sections[balancesIndex].data[lastBalanceIndex - 1].smallBalancesContainer) { + return { + get: ViewTypes.COIN_SMALL_BALANCES, + size: get(sections, `[${balancesIndex}].data[${lastBalanceIndex - 1}].assets`, []).length, + } + } else { + return ViewTypes.COIN_ROW_LAST; + } } } @@ -169,14 +178,14 @@ class RecyclerAssetList extends PureComponent { const lastInvestmentIndex = headersIndices[investmentsIndex] + investmentItemsCount; if ((index > headersIndices[investmentsIndex]) && (index <= lastInvestmentIndex)) { - if (!openInvestmentCards[ sections[investmentsIndex].data[index - headersIndices[investmentsIndex] - 1].uniqueId ]) { + if (!openInvestmentCards[sections[investmentsIndex].data[index - headersIndices[investmentsIndex] - 1].uniqueId]) { return index === lastInvestmentIndex ? ViewTypes.UNISWAP_ROW_LAST : ViewTypes.UNISWAP_ROW; } else { return index === lastInvestmentIndex - ? ViewTypes.UNISWAP_ROW_CLOSED_LAST - : ViewTypes.UNISWAP_ROW_CLOSED; + ? ViewTypes.UNISWAP_ROW_CLOSED_LAST + : ViewTypes.UNISWAP_ROW_CLOSED; } } } @@ -227,6 +236,8 @@ class RecyclerAssetList extends PureComponent { dim.height = 54 + (type.isLast ? 90 : 0); } else if (type === ViewTypes.COIN_ROW_LAST) { dim.height = this.state.areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height - 1; + } else if (type.get === ViewTypes.COIN_SMALL_BALANCES) { + dim.height = this.state.areSmallCollectibles ? CoinDivider.height + (type.size * CoinRow.height) : CoinDivider.height + (type.size * CoinRow.height) + ListFooter.height - 1; } else if (type === ViewTypes.COIN_ROW) { dim.height = CoinRow.height; } else if (type === ViewTypes.UNISWAP_ROW_LAST) { @@ -268,7 +279,7 @@ class RecyclerAssetList extends PureComponent { } shouldComponentUpdate = (prev, next) => { - if(prev.openFamilyTabs !== this.props.openFamilyTabs) { + if (prev.openFamilyTabs !== this.props.openFamilyTabs) { return true; } else if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && this.position !== 60.5) { return false; @@ -320,7 +331,7 @@ class RecyclerAssetList extends PureComponent { let investmentHeight = 0; if (investments.data) { for (let i = 0; i < investments.data.length; i++) { - if(!this.props.openInvestmentCards[ investments.data[i].uniqueId ]) { + if (!this.props.openInvestmentCards[investments.data[i].uniqueId]) { investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); } else { investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); @@ -329,7 +340,7 @@ class RecyclerAssetList extends PureComponent { } const verticalOffset = 10; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + investmentHeight; + const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + CoinDivider.height + investmentHeight; const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; const renderSize = CardSize * collectibles.data[i].tokens.length + RowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; @@ -397,6 +408,17 @@ class RecyclerAssetList extends PureComponent { return hideHeader ? null : ; } + if (type.get === ViewTypes.COIN_SMALL_BALANCES) { + const renderList = []; + renderList.push(); + + for (let i = 0; i < item.assets.length; i++) { + const selectedItem = { item: item.assets[i] }; + renderList.push(renderItem(selectedItem)) + } + return renderList; + } + const isNotUniqueToken = ( type === ViewTypes.COIN_ROW || type === ViewTypes.COIN_ROW_LAST @@ -440,10 +462,10 @@ class RecyclerAssetList extends PureComponent { rowRenderer={this.rowRenderer} onScroll={(event, _offsetX, offsetY) => { this.position = offsetY; - if(this.contentSize !== event.nativeEvent.contentSize.height) { + if (this.contentSize !== event.nativeEvent.contentSize.height) { this.contentSize = event.nativeEvent.contentSize.height; } - if(this.layoutMeasurement !== event.nativeEvent.layoutMeasurement.height) { + if (this.layoutMeasurement !== event.nativeEvent.layoutMeasurement.height) { this.layoutMeasurement = event.nativeEvent.layoutMeasurement.height; } if (event.nativeEvent.contentSize.height - event.nativeEvent.layoutMeasurement.height >= offsetY && offsetY >= 0 diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js new file mode 100644 index 00000000000..4d633ebf36b --- /dev/null +++ b/src/components/coin-divider/CoinDivider.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { pure } from 'recompact'; +import styled from 'styled-components/primitives'; +import { View, Text } from 'react-native'; +import { colors, fonts } from '../../styles'; +import { ButtonPressAnimation } from '../animations'; + +const Container = styled(View)` + height: 30px; + width: 55px; + background-color: ${colors.lightGrey}; + border-radius: 15px; + margin-left: 15px; + margin-top: 8px; + justify-content: center; + padding: 0 10px; +`; + +const Header = styled(Text)` + font-family: ${fonts.family.SFProText}; + letter-spacing: ${fonts.letterSpacing.tighter}; + font-size: ${fonts.size.lmedium}; + color: ${colors.blueGreyDark}; + font-weight: ${fonts.weight.semibold}; + opacity: 0.6; +`; + + +const CoinDivider = () => ( + + +
+ All +
+
+
+); + +CoinDivider.height = 38; + + +export default CoinDivider; diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 35f5af22869..54989189ce1 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -22,6 +22,23 @@ export const buildAssetUniqueIdentifier = (item) => { return compact([balance, nativePrice, uniqueId]).join('_'); }; +export const buildCoinsList = (assets) => { + const newAssets = []; + const smallBalances = { + smallBalancesContainer: true, + assets: [], + }; + for (let i = 0; i < assets.length; i++) { + if( assets[i].native && assets[i].native.balance.amount > 1) { + newAssets.push(assets[i]); + } else { + smallBalances.assets.push(assets[i]); + } + } + + return newAssets.concat(smallBalances); +}; + export const buildUniqueTokenList = (uniqueTokens) => { let rows = []; const grouped = groupBy(uniqueTokens, token => token.asset_contract.name); diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index eb7148b45b3..afb2bc3d853 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -7,7 +7,7 @@ import { createSelector } from 'reselect'; import { BalanceCoinRow } from '../components/coin-row'; import { UniswapInvestmentCard } from '../components/investment-cards'; import { TokenFamilyWrap } from '../components/token-family'; -import { buildUniqueTokenList } from './assets'; +import { buildUniqueTokenList, buildCoinsList } from './assets'; import FastImage from 'react-native-fast-image'; const allAssetsSelector = state => state.allAssets; @@ -72,7 +72,7 @@ const buildWalletSections = ( const sections = [ { balances: true, - data: showShitcoins ? allAssets : assets, + data: showShitcoins ? buildCoinsList(allAssets) : assets, header: { showShitcoins, title: lang.t('account.tab_balances'), From 358c5a32c7680156a89790de1358317be589476b Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 29 Jul 2019 13:36:11 +0200 Subject: [PATCH 010/636] initial implementation of small balances collabsible --- .../asset-list/RecyclerAssetList.js | 27 ++++++++++++----- src/components/coin-divider/CoinDivider.js | 30 +++++++++++++------ src/hoc/index.js | 1 + src/hoc/withOpenBalances.js | 8 +++++ src/redux/openBalances.js | 22 ++++++++++++++ src/redux/reducers.js | 2 ++ 6 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 src/hoc/withOpenBalances.js create mode 100644 src/redux/openBalances.js diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 2307e0072ce..5f4288cc8ba 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -19,7 +19,7 @@ import { buildAssetHeaderUniqueIdentifier, buildAssetUniqueIdentifier, } from '../../helpers/assets'; -import { withOpenFamilyTabs, withOpenInvestmentCards } from '../../hoc'; +import { withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; import { CoinRow, CollectiblesSendRow } from '../coin-row'; @@ -102,6 +102,7 @@ class RecyclerAssetList extends PureComponent { hideHeader: PropTypes.bool, openFamilyTabs: PropTypes.array, openInvestmentCards: PropTypes.array, + openSmallBalances: PropTypes.bool, paddingBottom: PropTypes.number, renderAheadOffset: PropTypes.number, scrollingVelocity: PropTypes.number, @@ -144,7 +145,7 @@ class RecyclerAssetList extends PureComponent { this.layoutProvider = new LayoutProvider( index => { - const { openFamilyTabs, openInvestmentCards, sections } = this.props; + const { openFamilyTabs, openInvestmentCards, openSmallBalances, sections } = this.props; const { headersIndices } = this.state; if (headersIndices.includes(index)) { return ViewTypes.HEADER; @@ -165,7 +166,7 @@ class RecyclerAssetList extends PureComponent { if (sections[balancesIndex].data[lastBalanceIndex - 1].smallBalancesContainer) { return { get: ViewTypes.COIN_SMALL_BALANCES, - size: get(sections, `[${balancesIndex}].data[${lastBalanceIndex - 1}].assets`, []).length, + size: openSmallBalances ? get(sections, `[${balancesIndex}].data[${lastBalanceIndex - 1}].assets`, []).length : 0, } } else { return ViewTypes.COIN_ROW_LAST; @@ -338,9 +339,17 @@ class RecyclerAssetList extends PureComponent { } } } + let balancesHeight = 0; + if ( balances.data ) { + balancesHeight += CoinRow.height * (balances.data.length - 1); + balancesHeight += CoinDivider.height; + if (this.props.openSmallBalances) { + balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; + } + } const verticalOffset = 10; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + CoinDivider.height + investmentHeight; + const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + balancesHeight + investmentHeight; const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; const renderSize = CardSize * collectibles.data[i].tokens.length + RowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; @@ -412,9 +421,11 @@ class RecyclerAssetList extends PureComponent { const renderList = []; renderList.push(); - for (let i = 0; i < item.assets.length; i++) { - const selectedItem = { item: item.assets[i] }; - renderList.push(renderItem(selectedItem)) + if (this.props.openSmallBalances) { + for (let i = 0; i < item.assets.length; i++) { + const selectedItem = { item: item.assets[i] }; + renderList.push(renderItem(selectedItem)) + } } return renderList; } @@ -496,4 +507,4 @@ const mapStateToProps = ({ }) => ({ scrollingVelocity, }); -export default connect(mapStateToProps)(withOpenFamilyTabs(withOpenInvestmentCards(RecyclerAssetList))); +export default connect(mapStateToProps)(withOpenFamilyTabs(withOpenInvestmentCards(withOpenBalances(RecyclerAssetList)))); diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 4d633ebf36b..3f497da4b3d 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -4,6 +4,13 @@ import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; import { colors, fonts } from '../../styles'; import { ButtonPressAnimation } from '../animations'; +import { withOpenBalances } from '../../hoc'; +import { deviceUtils } from '../../utils'; + +const Wrapper = styled(View)` + width: ${deviceUtils.dimensions.width}; + flex-direction: row; +`; const Container = styled(View)` height: 30px; @@ -26,17 +33,22 @@ const Header = styled(Text)` `; -const CoinDivider = () => ( - - -
- All -
-
-
+const CoinDivider = ({ + openSmallBalances, + setOpenSmallBalances, +}) => ( + + {setOpenSmallBalances(!openSmallBalances)}}> + +
+ { openSmallBalances ? `Less` : `All` } +
+
+
+
); CoinDivider.height = 38; -export default CoinDivider; +export default withOpenBalances(CoinDivider); diff --git a/src/hoc/index.js b/src/hoc/index.js index f929e5f4a01..5947533f695 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -15,6 +15,7 @@ export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; export { default as withOpenFamilyTabs } from './withOpenFamilyTabs'; export { default as withOpenInvestmentCards } from './withOpenInvestmentCards'; +export { default as withOpenBalances } from './withOpenBalances'; export { default as withRequests } from './withRequests'; export { default as withRotationForDirection } from './withRotationForDirection'; export { default as withSafeAreaViewInsetValues } from './withSafeAreaViewInsetValues'; diff --git a/src/hoc/withOpenBalances.js b/src/hoc/withOpenBalances.js new file mode 100644 index 00000000000..049ff39b2a0 --- /dev/null +++ b/src/hoc/withOpenBalances.js @@ -0,0 +1,8 @@ +import { connect } from 'react-redux'; +import { setOpenSmallBalances } from '../redux/openBalances'; + +const mapStateToProps = ({ openBalances: { openSmallBalances } }) => ({ openSmallBalances }); + +export default Component => connect(mapStateToProps, { + setOpenSmallBalances, +})(Component); diff --git a/src/redux/openBalances.js b/src/redux/openBalances.js new file mode 100644 index 00000000000..34a59f9c57e --- /dev/null +++ b/src/redux/openBalances.js @@ -0,0 +1,22 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_OPEN_SMALL_BALANCES = 'openBalances/SET_OPEN_SMALL_BALANCES'; + +export const setOpenSmallBalances = payload => dispatch => dispatch({ + payload, + type: SET_OPEN_SMALL_BALANCES, +}); + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + openSmallBalances: false, +}; + +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + if (action.type === SET_OPEN_SMALL_BALANCES) { + draft.openSmallBalances = action.payload; + } + }) +); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 343393746b5..43074ae3cd1 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -8,6 +8,7 @@ import navigation from './navigation'; import nonce from './nonce'; import openFamilyTabs from './openFamilyTabs'; import openInvestmentCards from './openInvestmentCards'; +import openBalances from './openBalances'; import requests from './requests'; import selectedWithFab from './selectedWithFab'; import send from './send'; @@ -25,6 +26,7 @@ export default combineReducers({ nonce, openFamilyTabs, openInvestmentCards, + openBalances, requests, selectedWithFab, send, From ecfed34df892965b90f436ca77e9bfed78901f1c Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 29 Jul 2019 17:32:26 +0200 Subject: [PATCH 011/636] add wrapper for small balances to make animations --- .../asset-list/RecyclerAssetList.js | 17 +++-- src/components/coin-divider/CoinDivider.js | 65 ++++++++++++++----- .../coin-divider/SmallBalancesWrapper.js | 48 ++++++++++++++ 3 files changed, 105 insertions(+), 25 deletions(-) create mode 100644 src/components/coin-divider/SmallBalancesWrapper.js diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 5f4288cc8ba..a1b9ac51c48 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -28,6 +28,7 @@ import { ListFooter } from '../list'; import { CardMargin, CardSize, RowPadding } from '../unique-token/UniqueTokenRow'; import AssetListHeader from './AssetListHeader'; import CoinDivider from '../coin-divider/CoinDivider'; +import SmallBalancesWrapper from '../coin-divider/SmallBalancesWrapper'; export const ViewTypes = { HEADER: 0, @@ -416,18 +417,16 @@ class RecyclerAssetList extends PureComponent { if (type === ViewTypes.HEADER) { return hideHeader ? null : ; } - + if (type.get === ViewTypes.COIN_SMALL_BALANCES) { const renderList = []; - renderList.push(); - - if (this.props.openSmallBalances) { - for (let i = 0; i < item.assets.length; i++) { - const selectedItem = { item: item.assets[i] }; - renderList.push(renderItem(selectedItem)) - } + for (let i = 0; i < item.assets.length; i++) { + const selectedItem = { item: item.assets[i] }; + renderList.push(renderItem(selectedItem)) } - return renderList; + + wrappedRenderList = + return wrappedRenderList; } const isNotUniqueToken = ( diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 3f497da4b3d..d25653d1725 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -1,11 +1,15 @@ +import PropTypes from 'prop-types'; import React from 'react'; import { pure } from 'recompact'; import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; -import { colors, fonts } from '../../styles'; +import { colors, fonts, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; -import { withOpenBalances } from '../../hoc'; import { deviceUtils } from '../../utils'; +import { Icon } from '../icons'; +import { Centered } from '../layout'; +import Animated from 'react-native-reanimated'; + const Wrapper = styled(View)` width: ${deviceUtils.dimensions.width}; @@ -14,13 +18,13 @@ const Wrapper = styled(View)` const Container = styled(View)` height: 30px; - width: 55px; background-color: ${colors.lightGrey}; border-radius: 15px; margin-left: 15px; margin-top: 8px; - justify-content: center; + align-items: center; padding: 0 10px; + flex-direction: row; `; const Header = styled(Text)` @@ -35,20 +39,49 @@ const Header = styled(Text)` const CoinDivider = ({ openSmallBalances, - setOpenSmallBalances, + onChangeOpenBalances, }) => ( - - {setOpenSmallBalances(!openSmallBalances)}}> - -
- { openSmallBalances ? `Less` : `All` } -
-
-
-
-); + + + +
+ {openSmallBalances ? `Less` : `All`} +
+ + + + + + + +
+
+
+ ); + +CoinDivider.propTypes = { + openSmallBalances: PropTypes.bool, + onChangeOpenBalances: PropTypes.func, +}; CoinDivider.height = 38; -export default withOpenBalances(CoinDivider); +export default CoinDivider; diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js new file mode 100644 index 00000000000..7a2507891a7 --- /dev/null +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -0,0 +1,48 @@ +import React, { useState, useRef } from 'react'; +import { Transitioning, Transition } from 'react-native-reanimated'; +import { View } from 'react-native'; +import { withOpenBalances } from '../../hoc'; +import CoinDivider from './CoinDivider'; +import { CoinRow } from '../coin-row'; + +const SmallBalancesWrapper = ({ + openSmallBalances, + setOpenSmallBalances, + assets, + ...props +}) => { + const transition = ; + + let [height, setHeight] = useState(0); + const ref = useRef(); + + + const onPress = () => { + ref.current.animateNextTransition(); + setHeight(!openSmallBalances ? (CoinRow.height * assets.length) : 0); + setOpenSmallBalances(!openSmallBalances); + } + + return ( + + + + + + {assets} + + + + + ) +}; + +export default withOpenBalances(SmallBalancesWrapper); From a0ea270ce8d5262e3dd8b8a0ed2351d1845f2423 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 01:46:55 +0200 Subject: [PATCH 012/636] add basic animation for header and make fab button work with collapsible small balances --- src/components/coin-divider/CoinDivider.js | 6 ++-- .../coin-divider/SmallBalancesWrapper.js | 2 +- src/components/fab/MovableFabWrapper.js | 30 ++++++++++++++----- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index d25653d1725..c3f40c31c30 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -25,6 +25,7 @@ const Container = styled(View)` align-items: center; padding: 0 10px; flex-direction: row; + justify-content: space-between; `; const Header = styled(Text)` @@ -33,6 +34,7 @@ const Header = styled(Text)` font-size: ${fonts.size.lmedium}; color: ${colors.blueGreyDark}; font-weight: ${fonts.weight.semibold}; + width: 40px; opacity: 0.6; `; @@ -44,8 +46,8 @@ const CoinDivider = ({ -
- {openSmallBalances ? `Less` : `All`} +
+ { openSmallBalances ? `Less` : `All` }
- + { +const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestmentCards, openSmallBalances }) => { let balances = false; let collectibles = false; let investments = false; @@ -303,7 +305,7 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment const familyHeaderHeight = 52; let height = 55 + headerHeight; if (balances) { - for (let i = 0; i < balances.data.length; i++) { + for (let i = 0; i < balances.data.length - 1; i++) { areas.push({ bottom: height + CoinRow.height, id: balances.data[i].uniqueId, @@ -311,14 +313,28 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment right: deviceUtils.dimensions.width, top: height, }); - height += CoinRow.height + (balances.data.length - 1 === i ? ListFooter.height : 0); + height += CoinRow.height; } - height += headerHeight; + height += CoinDivider.height; + if (openSmallBalances) { + let smallBalances = balances.data[balances.data.length - 1].assets; + for (let i = 0; i < smallBalances.length; i++) { + areas.push({ + bottom: height + CoinRow.height, + id: smallBalances[i].uniqueId, + left: 0, + right: deviceUtils.dimensions.width, + top: height, + }); + height += CoinRow.height; + } + } + height += ListFooter.height + headerHeight; } if (investments) { height += headerHeight + ListFooter.height; for (let i = 0; i < investments.data.length; i++) { - if(!openInvestmentCards[ investments.data[i].uniqueId ]) { + if (!openInvestmentCards[investments.data[i].uniqueId]) { height += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); } else { height += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); @@ -370,4 +386,4 @@ const EnhancedMovable = compose( )(Movable); -export default withOpenFamilyTabs(withOpenInvestmentCards(EnhancedMovable)); +export default withOpenFamilyTabs(withOpenInvestmentCards(withOpenBalances(EnhancedMovable))); From 9c3c216755b8fb39d634fa7cc1166397f48226d9 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 02:25:00 +0200 Subject: [PATCH 013/636] add sum of small balances to the header --- src/components/coin-divider/CoinDivider.js | 22 ++++++++++++++----- .../coin-divider/SmallBalancesWrapper.js | 14 +++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index c3f40c31c30..fd57e562cec 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -9,19 +9,24 @@ import { deviceUtils } from '../../utils'; import { Icon } from '../icons'; import { Centered } from '../layout'; import Animated from 'react-native-reanimated'; +import { Monospace } from '../text'; - +const marginLeft = 15; +const marginRight = 19; const Wrapper = styled(View)` - width: ${deviceUtils.dimensions.width}; + margin-top: 8px; + margin-right: ${marginRight}px; + margin-left: ${marginLeft}px; + width: ${deviceUtils.dimensions.width - marginRight - marginLeft}; flex-direction: row; + align-items: center; + justify-content: space-between; `; const Container = styled(View)` height: 30px; background-color: ${colors.lightGrey}; border-radius: 15px; - margin-left: 15px; - margin-top: 8px; align-items: center; padding: 0 10px; flex-direction: row; @@ -42,12 +47,13 @@ const Header = styled(Text)` const CoinDivider = ({ openSmallBalances, onChangeOpenBalances, + balancesSum, }) => (
- { openSmallBalances ? `Less` : `All` } + {openSmallBalances ? `Less` : `All`}
+ + {balancesSum} +
); diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 64ac7a6a65d..7c5fd8d5e4f 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -5,6 +5,18 @@ import { withOpenBalances } from '../../hoc'; import CoinDivider from './CoinDivider'; import { CoinRow } from '../coin-row'; +balancesSum = (balances) => { + let sum = 0; + for (let i = 0; i < balances.length; i++) { + if(balances[i].props.item.native) { + if(!isNaN(balances[i].props.item.native.balance.amount)) { + sum += Number(balances[i].props.item.native.balance.amount); + } + } + } + return `$${Number(sum).toFixed(2)}`; +} + const SmallBalancesWrapper = ({ openSmallBalances, setOpenSmallBalances, @@ -29,7 +41,7 @@ const SmallBalancesWrapper = ({ ref={ref} transition={transition} > - + Date: Tue, 30 Jul 2019 03:51:14 -0700 Subject: [PATCH 014/636] Visual cleanup feat. @mikedemarais --- src/assets/family-dropdown-arrow.png | Bin 381 -> 447 bytes src/assets/family-dropdown-arrow@2x.png | Bin 745 -> 906 bytes src/assets/family-dropdown-arrow@3x.png | Bin 1158 -> 1371 bytes .../asset-list/RecyclerAssetList.js | 20 ++++++-- .../token-family/TokenFamilyHeader.js | 44 ++++++++++-------- .../token-family/TokenFamilyWrap.js | 6 ++- 6 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/assets/family-dropdown-arrow.png b/src/assets/family-dropdown-arrow.png index 112863ed81709bd69ac692b447fe04ad221fffa3..a800285173f7ab2577031cd9194dd2b803c8b00e 100644 GIT binary patch delta 440 zcmV;p0Z0D*0>1+xiBL{Q4GJ0x0000DNk~Le000090000H2nGNE01p&~=8+*2e|AYk zK~yLejgh-c13?hRXKoXNDNAWnfSF)mhI`!%e^a+VE zCUM}J$6-5ZWM=y?z#6s6i>zn}f54|X;Cx&gK60wBPB%=Kbj>*?jO+m=iwO7>jbPrg ztY!d8B0)qR8w{<`Zc*vP#~0r(7KvJB*Rh9;E;jugSL=&SA_&f4KD<4=#gU zDAB|Pp)>%Y^FNSoWD7Lmj(9+Jtd+~xl^)12%n|D4kje}Yv-Nmi+7oaGGEFnu;_YKH zR3VMC?1a7{01^LpTsLx?;!DW-CWgZc-CyD>B`0%JZri;eQIAP5_fRhRF8g(U7s>NH ivI1=hVZ9$9xF4~MmHW5r4uGow0000=1N{OaiBL{Q4GJ0x0000DNk~Le000070000F2nGNE04M>~zL6mle>6!% zK~xwSV^-7DTP7kdVet0#%l!;!fQf;TQSRTr|21mb2H9wG3`}fHY>^C%3@;h}|DT|) zt>=WSfDy#e&@r(3_wOIb*e`5MtY%lPoV^PYX95v7u3R|wpOGp3|9=Ldpa1@BGB-Ep z1Bo+(2oQMp`o#qiF$q4P@qRykfBx0W&BLx7HlU- z0tPfS4dwqZ{Jqb}$hZ@1CrlzVG?e)-|NhMf2Ff)dUJlEXCr^HY`}6PLfBP628NMR>lUYZ{RQC73OFw&o4&Vk# z`dz_Aesf}=|@aVjQek1y)YG70>lOY8gOuW T&da`~00000NkvXXu0mjfU!<%7 diff --git a/src/assets/family-dropdown-arrow@2x.png b/src/assets/family-dropdown-arrow@2x.png index 9c2ec6cb03cac8c5014cc77ce7f6dd414fca0e9b..0579ce1de4de835339c694af4c72df271aa4f1c0 100644 GIT binary patch literal 906 zcmV;519kj~P)K_RAWiXqac|0NNk~%LKA6BFxq%9Bt{a9i3xhs z7%}m26Xn9iL{AzI#uz;qm6HbodIRMkF=;hW?1Pf{I$$M*#sm%p+JBt=+x@$L-|T^z z`SzRdpPkumpahrI(bY{9VagxVp0ZrQXuqjP8-_Hrck&(PSZE6}>a#mx@pXx15R)jhv*cu2f7;(yz5>~t-L29+sUBYJjM9eJ^ zxNWm{@uO?2V6(N|jAL`TS|FkLP@qNHOW@H@EC&5vj^&+IB5H1AcJ>c4`w>WJAR$H^ z#aKtjF*CsJBk;mgP!iF-IbB73{?6SB+T&QeC)w^n6;#KbDWU=r_4;I7zha%>-WJTDQAru*q z6L8?~2F~~2)nka}0wQj6IM1Z;=3<=v7^NX*-hDJOGqWam!WI-N_OR_>)$TyxtJ+*4 zAZ+$)8H7KzNdn{g*O5Q9^jt9!o~jeV300-mHr~qbwW?3)%~J1mp3qY4-(!4jJZiG| zL+R7S;M@}t7PDGKwsz+r{v$D{C(`NKomDsVSm8)*_MvvyaY~gb{2f&Z8s3$k%v968 z;PtKwtdvzNLXmrV5wd2ehQ3Ng_y^KQ16|V<$_y97^YejH73A)vg&4hsXN=(ej3IC( g5}X~+C6q8jl-bMkyccZ1+9O=YRaP+klDy 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 Y0f~QZH=752C;$Ke07*qoM6N<$f?WJ6F#rGn diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 4ffea173bb8..09ca7bcc178 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -178,13 +178,15 @@ class RecyclerAssetList extends Component { if (get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`)) { return { get: ViewTypes.UNIQUE_TOKEN_ROW, + isFirst: index === headersIndices[collectiblesIndex] + 1, isLast: index === this.state.length - 2, - size: get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`, []).length, + rowCount: get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`, []).length, }; } } return { get: ViewTypes.UNIQUE_TOKEN_ROW_CLOSED, + isFirst: index === headersIndices[collectiblesIndex] + 1, isLast: index === this.state.length - 2, }; } @@ -206,11 +208,20 @@ class RecyclerAssetList extends Component { const fabPositionBottom = type.isLast ? (paddingBottom - (FloatingActionButton.size / 2)) : 0; const TokenFamilyHeaderHeight = TokenFamilyHeader.height + fabPositionBottom; + const firstRowExtraTopPadding = type.isFirst ? 4 : 0; if (type.get === ViewTypes.UNIQUE_TOKEN_ROW) { - const extraSpaceForDropShadow = 12; - dim.height = TokenFamilyHeaderHeight + (type.size * UniqueTokenRow.cardSize) + (UniqueTokenRow.cardMargin * (type.size - 1)) + extraSpaceForDropShadow; + const heightOfRows = type.rowCount * UniqueTokenRow.cardSize; + const heightOfRowMargins = UniqueTokenRow.cardMargin * (type.rowCount - 1); + const extraSpaceForDropShadow = 19; + dim.height = ( + TokenFamilyHeaderHeight + + heightOfRows + + heightOfRowMargins + + firstRowExtraTopPadding + + extraSpaceForDropShadow + ); } else if (type.get === ViewTypes.UNIQUE_TOKEN_ROW_CLOSED) { - dim.height = TokenFamilyHeaderHeight; + dim.height = TokenFamilyHeaderHeight + firstRowExtraTopPadding; } else if (type === ViewTypes.COIN_ROW_LAST) { dim.height = areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height - 1; } else if (type === ViewTypes.COIN_ROW) { @@ -419,6 +430,7 @@ class RecyclerAssetList extends Component { childrenAmount: item.childrenAmount, familyId: item.familyId, familyImage: item.familyImage, + marginTop: type.isFirst ? 4 : 0, familyName: item.familyName, item: item.tokens, shouldPrioritizeImageLoading: index < get(sections, '[0].data.length', 0) + 9, diff --git a/src/components/token-family/TokenFamilyHeader.js b/src/components/token-family/TokenFamilyHeader.js index b0c2889584d..6260b1d0196 100644 --- a/src/components/token-family/TokenFamilyHeader.js +++ b/src/components/token-family/TokenFamilyHeader.js @@ -22,7 +22,7 @@ const AnimatedMonospace = Animated.createAnimatedComponent(toClass(Monospace)); const AnimatedFastImage = Animated.createAnimatedComponent(FastImage); const TokenFamilyHeaderAnimationDuration = 200; -const TokenFamilyHeaderHeight = 54; +const TokenFamilyHeaderHeight = 50; const FamilyIcon = withProps(({ familyImage }) => ({ id: familyImage, @@ -57,7 +57,7 @@ export default class TokenFamilyHeader extends PureComponent { runTiming = () => ( timing(this.animation, { duration: TokenFamilyHeaderAnimationDuration, - easing: Easing.bezier(0.25, 0.46, 0.45, 0.94), + easing: Easing.bezier(0.25, 0.1, 0.25, 1), toValue: this.props.isOpen ? 1 : 0, }).start() ) @@ -94,46 +94,52 @@ export default class TokenFamilyHeader extends PureComponent { height={TokenFamilyHeaderHeight} justify="space-between" paddingHorizontal={this.props.isCoinRow ? 16 : 19} - paddingVertical={7.5} width="100%" > - + {this.renderFamilyIcon()} {this.props.familyName} + + + + {this.props.childrenAmount} + - - {this.props.childrenAmount} - ) diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index 4a6a16596c0..423d2844890 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -45,10 +45,11 @@ const TokenFamilyWrap = ({ highlight, isFamilyOpen, item, + marginTop, onPressFamilyHeader, renderCollectibleItem, }) => ( - + {times(item.length, renderCollectibleItem)} @@ -76,6 +78,7 @@ TokenFamilyWrap.propTypes = { familyName: PropTypes.string, highlight: PropTypes.bool, isFamilyOpen: PropTypes.bool, + marginTop: PropTypes.number, isOpen: PropTypes.bool, item: PropTypes.array, onPressFamilyHeader: PropTypes.func, @@ -142,6 +145,7 @@ export default compose( 'areChildrenVisible', 'childrenAmount', 'highlight', + 'marginTop', 'isFamilyOpen', 'uniqueId', ]), From 0222787085fa570baf889281c29764f8310e1924 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 13:49:33 +0200 Subject: [PATCH 015/636] make small balances header responsible for moving fab and initial opening logic --- src/components/coin-divider/CoinDivider.js | 38 ++++++++++++------- .../coin-divider/SmallBalancesWrapper.js | 8 +++- src/components/fab/MovableFabWrapper.js | 7 ++++ src/hoc/withFabSendAction.js | 9 ++++- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index fd57e562cec..9fe6a3ae9ef 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -10,20 +10,24 @@ import { Icon } from '../icons'; import { Centered } from '../layout'; import Animated from 'react-native-reanimated'; import { Monospace } from '../text'; +import { withFabSendAction } from '../../hoc'; +import { compose } from 'recompact'; +import Highlight from '../Highlight'; const marginLeft = 15; const marginRight = 19; const Wrapper = styled(View)` - margin-top: 8px; - margin-right: ${marginRight}px; - margin-left: ${marginLeft}px; - width: ${deviceUtils.dimensions.width - marginRight - marginLeft}; + padding-right: ${marginRight}px; + padding-left: ${marginLeft}px; + width: ${deviceUtils.dimensions.width}; flex-direction: row; align-items: center; justify-content: space-between; + height: 50px; `; const Container = styled(View)` + margin-top: 4px; height: 30px; background-color: ${colors.lightGrey}; border-radius: 15px; @@ -43,13 +47,18 @@ const Header = styled(Text)` opacity: 0.6; `; +const enhance = compose( + withFabSendAction, +); -const CoinDivider = ({ +const CoinDivider = enhance(({ openSmallBalances, onChangeOpenBalances, balancesSum, + isCoinDivider, }) => ( +
@@ -81,21 +90,24 @@ const CoinDivider = ({ - - {balancesSum} - + {!openSmallBalances && + + {balancesSum} + + } - ); + )); CoinDivider.propTypes = { openSmallBalances: PropTypes.bool, onChangeOpenBalances: PropTypes.func, + balancesSum: PropTypes.string, }; -CoinDivider.height = 38; +CoinDivider.height = 50; export default CoinDivider; diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 7c5fd8d5e4f..63a60c15fb2 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -28,20 +28,24 @@ const SmallBalancesWrapper = ({ let [height, setHeight] = useState(0); const ref = useRef(); - const onPress = () => { ref.current.animateNextTransition(); setHeight(!openSmallBalances ? (CoinRow.height * assets.length) : 0); setOpenSmallBalances(!openSmallBalances); } + if (openSmallBalances && height === 0 ) { + ref.current.animateNextTransition(); + setHeight(CoinRow.height * assets.length); + } + return ( - + ({ fabDropped: selectedId === -3, family: selectedId === familyName, highlight: selectedId === uniqueId || selectedId === familyName, + isCoinDivider: selectedId === 'smallBalancesHeader', })), omitProps('selectedId'), lifecycle({ @@ -47,6 +49,11 @@ export default compose( } else { openFamilyCheck = 0; } + if( this.props.isCoinDivider == true && !this.props.fabDropped ) { + timer = setTimeout(() => { + this.props.setOpenSmallBalances(true); + }, 300); + } if (prevProps.highlight && !this.props.highlight && this.props.fabDropped) { if (this.props.actionType === 'send') { this.props.onPressSend(); From 245e07572a2edb30ad82b557ac39bf0526f30e94 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 14:38:15 +0200 Subject: [PATCH 016/636] add timer to fab moving opening small balances --- src/hoc/withFabSendAction.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hoc/withFabSendAction.js b/src/hoc/withFabSendAction.js index dc80dcd0889..90337b2924c 100644 --- a/src/hoc/withFabSendAction.js +++ b/src/hoc/withFabSendAction.js @@ -22,6 +22,7 @@ const mapStateToProps = ({ let openFamilyCheck = 0; let currentFamilyId; let timer; +let timerBlocker = false; export default compose( connect(mapStateToProps, { setOpenFamilyTabs, setOpenSmallBalances }), @@ -49,9 +50,13 @@ export default compose( } else { openFamilyCheck = 0; } - if( this.props.isCoinDivider == true && !this.props.fabDropped ) { + if (this.props.isCoinDivider == true && !this.props.fabDropped && !timerBlocker) { + timerBlocker = true; timer = setTimeout(() => { - this.props.setOpenSmallBalances(true); + if (this.props.isCoinDivider) { + this.props.setOpenSmallBalances(true); + } + timerBlocker = false; }, 300); } if (prevProps.highlight && !this.props.highlight && this.props.fabDropped) { From 831bd84f2e2be4153c9da4a72129b150c6a3ea7a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 16:05:28 +0200 Subject: [PATCH 017/636] fix syntax for coin wrapper --- src/components/coin-divider/CoinDivider.js | 81 +++++++++---------- .../coin-divider/SmallBalancesWrapper.js | 24 ++++-- 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 9fe6a3ae9ef..425e9fa6028 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -1,17 +1,16 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { pure } from 'recompact'; import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; +import Animated from 'react-native-reanimated'; +import { compose } from 'recompact'; import { colors, fonts, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { deviceUtils } from '../../utils'; import { Icon } from '../icons'; import { Centered } from '../layout'; -import Animated from 'react-native-reanimated'; import { Monospace } from '../text'; import { withFabSendAction } from '../../hoc'; -import { compose } from 'recompact'; import Highlight from '../Highlight'; const marginLeft = 15; @@ -57,54 +56,54 @@ const CoinDivider = enhance(({ balancesSum, isCoinDivider, }) => ( - - - - -
- {openSmallBalances ? `Less` : `All`} -
- - + + + +
+ {openSmallBalances ? 'Less' : 'All'} +
+ + + - - - - + + -
-
- {!openSmallBalances && - +
+
+ {!openSmallBalances + && {balancesSum} - } -
- )); + } + +)); CoinDivider.propTypes = { - openSmallBalances: PropTypes.bool, - onChangeOpenBalances: PropTypes.func, balancesSum: PropTypes.string, + onChangeOpenBalances: PropTypes.func, + openSmallBalances: PropTypes.bool, }; CoinDivider.height = 50; diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 63a60c15fb2..81428f39344 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types'; import React, { useState, useRef } from 'react'; import { Transitioning, Transition } from 'react-native-reanimated'; import { View } from 'react-native'; @@ -5,17 +6,17 @@ import { withOpenBalances } from '../../hoc'; import CoinDivider from './CoinDivider'; import { CoinRow } from '../coin-row'; -balancesSum = (balances) => { +const balancesSum = (balances) => { let sum = 0; for (let i = 0; i < balances.length; i++) { - if(balances[i].props.item.native) { - if(!isNaN(balances[i].props.item.native.balance.amount)) { + if (balances[i].props.item.native) { + if (!isNaN(balances[i].props.item.native.balance.amount)) { sum += Number(balances[i].props.item.native.balance.amount); } } } return `$${Number(sum).toFixed(2)}`; -} +}; const SmallBalancesWrapper = ({ openSmallBalances, @@ -25,16 +26,16 @@ const SmallBalancesWrapper = ({ }) => { const transition = ; - let [height, setHeight] = useState(0); + const [height, setHeight] = useState(0); const ref = useRef(); const onPress = () => { ref.current.animateNextTransition(); setHeight(!openSmallBalances ? (CoinRow.height * assets.length) : 0); setOpenSmallBalances(!openSmallBalances); - } + }; - if (openSmallBalances && height === 0 ) { + if (openSmallBalances && height === 0) { ref.current.animateNextTransition(); setHeight(CoinRow.height * assets.length); } @@ -48,7 +49,7 @@ const SmallBalancesWrapper = ({ @@ -61,4 +62,11 @@ const SmallBalancesWrapper = ({ ) }; +SmallBalancesWrapper.propTypes = { + assets: PropTypes.array, + balancesSum: PropTypes.string, + openSmallBalances: PropTypes.bool, + setOpenSmallBalances: PropTypes.func, +}; + export default withOpenBalances(SmallBalancesWrapper); From 657f9ab150f6aeb98a6b7058da433eb1c3b64faf Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 19:06:03 +0200 Subject: [PATCH 018/636] investment card clean up --- .../investment-cards/InvestmentCard.js | 83 ++++++++++--------- .../investment-cards/InvestmentCardHeader.js | 15 ++-- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index a82e1511c39..687617bf46e 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -1,18 +1,14 @@ -import withViewLayoutProps from '@hocs/with-view-layout-props'; import PropTypes from 'prop-types'; import React, { useState, useRef } from 'react'; import LinearGradient from 'react-native-linear-gradient'; -import { compose, pure } from 'recompact'; -import { colors, margin, position, shadow as shadowUtil } from '../../styles'; -import { deviceUtils } from '../../utils'; +import { View } from 'react-native'; +import { Transitioning, Transition } from 'react-native-reanimated'; +import { colors, position } from '../../styles'; import InnerBorder from '../InnerBorder'; import { Column } from '../layout'; -import { ShadowStack } from '../shadow-stack'; import InvestmentCardHeader from './InvestmentCardHeader'; -import { Transitioning, Transition } from 'react-native-reanimated'; import { ButtonPressAnimation } from '../animations'; import { withOpenInvestmentCards } from '../../hoc'; -import { View } from 'react-native'; const InvestmentCardMargin = { horizontal: 19, @@ -35,14 +31,14 @@ const InvestmentCard = ({ }) => { const transition = ; - let [perc, setPerc] = useState(collapsed ? InvestmentCardHeader.height : containerHeight); + const [perc, setPerc] = useState(collapsed ? InvestmentCardHeader.height : containerHeight); const ref = useRef(); const onPress = () => { - setOpenInvestmentCards({ index: uniqueId , state: !openInvestmentCards[uniqueId] }); + setOpenInvestmentCards({ index: uniqueId, state: !openInvestmentCards[uniqueId] }); ref.current.animateNextTransition(); setPerc(!openInvestmentCards[uniqueId] ? InvestmentCardHeader.height : containerHeight); - } + }; return ( - - + + + - - - - {children} - - + + {children} + + - )}; + ); +}; InvestmentCard.propTypes = { children: PropTypes.node, @@ -106,8 +103,12 @@ InvestmentCard.propTypes = { containerHeight: PropTypes.number, gradientColors: PropTypes.arrayOf(PropTypes.string).isRequired, headerProps: PropTypes.shape(InvestmentCardHeader.propTypes), + isCollapsible: PropTypes.bool, onLayout: PropTypes.func.isRequired, + openInvestmentCards: PropTypes.bool, + setOpenInvestmentCards: PropTypes.func, shadows: PropTypes.arrayOf(PropTypes.array), + uniqueId: PropTypes.string, }; InvestmentCard.defaultProps = { diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index 0a833e2b36b..28067861bdd 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components/primitives'; +import Animated, { Easing } from 'react-native-reanimated'; import { colors, padding, position } from '../../styles'; import { Icon } from '../icons'; import { @@ -11,7 +11,6 @@ import { RowWithMargins, } from '../layout'; import { Emoji, Monospace, Text } from '../text'; -import Animated, { Easing } from 'react-native-reanimated'; const HeaderHeight = 48; @@ -72,8 +71,7 @@ class InvestmentCardHeader extends React.Component { if (prev.collapsed !== undefined && prev.collapsed !== this.props.collapsed) { const clock = new Clock(); - let base = undefined; - this.props.collapsed ? base = runTiming(clock, -1, 1, this.props.collapsed) : base = runTiming(clock, 1, -1, this.props.collapsed); + const base = this.props.collapsed ? runTiming(clock, -1, 1, this.props.collapsed) : runTiming(clock, 1, -1, this.props.collapsed); this._rotation = interpolate(base, { inputRange: [-1, 1], outputRange: [0, 90], @@ -82,13 +80,14 @@ class InvestmentCardHeader extends React.Component { } render() { - let { collapsed, + const { + collapsed, color, emoji, isCollapsible, title, titleColor, - value, + value, } = this.props; return ( @@ -149,9 +148,9 @@ class InvestmentCardHeader extends React.Component { )} - ) + ); } -}; +} InvestmentCardHeader.propTypes = { collapsed: PropTypes.bool, From 73f3d0ad585a00096faca7d842aca9b0bc48815f Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 19:54:46 +0200 Subject: [PATCH 019/636] code clean up --- .../asset-list/RecyclerAssetList.js | 126 +++++++++--------- .../coin-divider/SmallBalancesWrapper.js | 2 +- src/helpers/assets.js | 5 +- src/hoc/withFabSendAction.js | 2 +- src/redux/reducers.js | 4 +- 5 files changed, 72 insertions(+), 67 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index a1b9ac51c48..2c6f710a28b 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -41,9 +41,9 @@ export const ViewTypes = { UNIQUE_TOKEN_ROW_FIRST: 8, // TODO remove UNIQUE_TOKEN_ROW_LAST: 9, // TODO remove UNISWAP_ROW: 7, - UNISWAP_ROW_LAST: 8, UNISWAP_ROW_CLOSED: 9, UNISWAP_ROW_CLOSED_LAST: 10, + UNISWAP_ROW_LAST: 8, FOOTER: 11, }; @@ -131,8 +131,11 @@ class RecyclerAssetList extends PureComponent { rlv = React.createRef(); position = 0; + contentSize = 0; + layoutMeasurement = 0; + refresh = false; constructor(props) { @@ -146,7 +149,9 @@ class RecyclerAssetList extends PureComponent { this.layoutProvider = new LayoutProvider( index => { - const { openFamilyTabs, openInvestmentCards, openSmallBalances, sections } = this.props; + const { + openFamilyTabs, openInvestmentCards, openSmallBalances, sections, + } = this.props; const { headersIndices } = this.state; if (headersIndices.includes(index)) { return ViewTypes.HEADER; @@ -168,10 +173,9 @@ class RecyclerAssetList extends PureComponent { return { get: ViewTypes.COIN_SMALL_BALANCES, size: openSmallBalances ? get(sections, `[${balancesIndex}].data[${lastBalanceIndex - 1}].assets`, []).length : 0, - } - } else { - return ViewTypes.COIN_ROW_LAST; + }; } + return ViewTypes.COIN_ROW_LAST; } } @@ -184,11 +188,10 @@ class RecyclerAssetList extends PureComponent { return index === lastInvestmentIndex ? ViewTypes.UNISWAP_ROW_LAST : ViewTypes.UNISWAP_ROW; - } else { - return index === lastInvestmentIndex - ? ViewTypes.UNISWAP_ROW_CLOSED_LAST - : ViewTypes.UNISWAP_ROW_CLOSED; } + return index === lastInvestmentIndex + ? ViewTypes.UNISWAP_ROW_CLOSED_LAST + : ViewTypes.UNISWAP_ROW_CLOSED; } } @@ -239,7 +242,7 @@ class RecyclerAssetList extends PureComponent { } else if (type === ViewTypes.COIN_ROW_LAST) { dim.height = this.state.areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height - 1; } else if (type.get === ViewTypes.COIN_SMALL_BALANCES) { - dim.height = this.state.areSmallCollectibles ? CoinDivider.height + (type.size * CoinRow.height) : CoinDivider.height + (type.size * CoinRow.height) + ListFooter.height - 1; + dim.height = this.state.areSmallCollectibles ? CoinDivider.height + (type.size * CoinRow.height) : CoinDivider.height + (type.size * CoinRow.height) + ListFooter.height - 1; } else if (type === ViewTypes.COIN_ROW) { dim.height = CoinRow.height; } else if (type === ViewTypes.UNISWAP_ROW_LAST) { @@ -250,9 +253,9 @@ class RecyclerAssetList extends PureComponent { dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical + ListFooter.height + 7; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED) { dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical; - } else if (type == ViewTypes.HEADER) { + } else if (type === ViewTypes.HEADER) { dim.height = this.props.hideHeader ? 0 : AssetListHeader.height; - } else if (type == ViewTypes.FOOTER) { + } else if (type === ViewTypes.FOOTER) { dim.height = 0; } }, @@ -283,11 +286,11 @@ class RecyclerAssetList extends PureComponent { shouldComponentUpdate = (prev, next) => { if (prev.openFamilyTabs !== this.props.openFamilyTabs) { return true; - } else if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && this.position !== 60.5) { + } + if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && this.position !== 60.5) { return false; - } else { - return true; } + return true; } componentDidMount = () => { @@ -320,51 +323,48 @@ class RecyclerAssetList extends PureComponent { let i = 0; while (i < this.props.openFamilyTabs.length) { if (this.props.openFamilyTabs[i] === true && prev.openFamilyTabs[i] === false) { - // TODO no function creation in while loop - setTimeout(() => { - let collectiblesHeight = 0; - for (let j = 0; j < i; j++) { - if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { - collectiblesHeight += collectibles.data[j].tokens.length * CardSize + 54 + RowPadding * (collectibles.data[j].tokens.length - 1); - } else { - collectiblesHeight += 54; - } + let collectiblesHeight = 0; + for (let j = 0; j < i; j++) { + if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + collectiblesHeight += collectibles.data[j].tokens.length * CardSize + 54 + RowPadding * (collectibles.data[j].tokens.length - 1); + } else { + collectiblesHeight += 54; } - let investmentHeight = 0; - if (investments.data) { - for (let i = 0; i < investments.data.length; i++) { - if (!this.props.openInvestmentCards[investments.data[i].uniqueId]) { - investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); - } else { - investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); - } + } + let investmentHeight = 0; + if (investments.data) { + for (let k = 0; k < investments.data.length; k++) { + if (!this.props.openInvestmentCards[investments.data[k].uniqueId]) { + investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + } else { + investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); } } - let balancesHeight = 0; - if ( balances.data ) { - balancesHeight += CoinRow.height * (balances.data.length - 1); - balancesHeight += CoinDivider.height; - if (this.props.openSmallBalances) { - balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; - } + } + let balancesHeight = 0; + if (balances.data) { + balancesHeight += CoinRow.height * (balances.data.length - 1); + balancesHeight += CoinDivider.height; + if (this.props.openSmallBalances) { + balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; } - const verticalOffset = 10; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + balancesHeight + investmentHeight; - const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; - const renderSize = CardSize * collectibles.data[i].tokens.length + RowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; - - if (renderSize >= deviceDimensions) { - const scrollDistance = sectionsHeight - this.position; - this.rlv.scrollToOffset(0, this.position + scrollDistance - verticalOffset, true); - } else { - const diff = this.position - sectionsHeight + deviceDimensions; - if (renderSize > diff) { - const scrollDistance = deviceDimensions > renderSize ? renderSize - diff : deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 250 : 280); - this.rlv.scrollToOffset(0, this.position + scrollDistance, true); - } + } + const verticalOffset = 10; + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); + const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + balancesHeight + investmentHeight; + const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; + const renderSize = CardSize * collectibles.data[i].tokens.length + RowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; + + if (renderSize >= deviceDimensions) { + const scrollDistance = sectionsHeight - this.position; + this.scrollToOffset(this.position + scrollDistance - verticalOffset); + } else { + const diff = this.position - sectionsHeight + deviceDimensions; + if (renderSize > diff) { + const scrollDistance = deviceDimensions > renderSize ? renderSize - diff : deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 250 : 280); + this.scrollToOffset(this.position + scrollDistance); } - }, 50); + } break; } i++; @@ -377,6 +377,12 @@ class RecyclerAssetList extends PureComponent { clearInterval(this.interval); }; + scrollToOffset = (position) => { + setTimeout(() => { + this.rlv.scrollToOffset(0, position, true); + }, 50); + } + getStableId = (index) => { const row = get(this.state, `dataProvider._data[${index}]`); if (get(row, 'item.isLastPlaceholder', false)) { @@ -417,15 +423,15 @@ class RecyclerAssetList extends PureComponent { if (type === ViewTypes.HEADER) { return hideHeader ? null : ; } - + if (type.get === ViewTypes.COIN_SMALL_BALANCES) { const renderList = []; for (let i = 0; i < item.assets.length; i++) { const selectedItem = { item: item.assets[i] }; - renderList.push(renderItem(selectedItem)) + renderList.push(renderItem(selectedItem)); } - wrappedRenderList = + const wrappedRenderList = ; return wrappedRenderList; } @@ -478,8 +484,8 @@ class RecyclerAssetList extends PureComponent { if (this.layoutMeasurement !== event.nativeEvent.layoutMeasurement.height) { this.layoutMeasurement = event.nativeEvent.layoutMeasurement.height; } - if (event.nativeEvent.contentSize.height - event.nativeEvent.layoutMeasurement.height >= offsetY && offsetY >= 0 - || offsetY < -60 && offsetY > -62) { + if ((event.nativeEvent.contentSize.height - event.nativeEvent.layoutMeasurement.height >= offsetY && offsetY >= 0) + || (offsetY < -60 && offsetY > -62)) { if (this.props.scrollViewTracker) { this.props.scrollViewTracker.setValue(offsetY); } diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 81428f39344..71dd24f3a82 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -59,7 +59,7 @@ const SmallBalancesWrapper = ({
- ) + ); }; SmallBalancesWrapper.propTypes = { diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 54989189ce1..76d072a91ff 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -25,11 +25,11 @@ export const buildAssetUniqueIdentifier = (item) => { export const buildCoinsList = (assets) => { const newAssets = []; const smallBalances = { - smallBalancesContainer: true, assets: [], + smallBalancesContainer: true, }; for (let i = 0; i < assets.length; i++) { - if( assets[i].native && assets[i].native.balance.amount > 1) { + if (assets[i].native && assets[i].native.balance.amount > 1) { newAssets.push(assets[i]); } else { smallBalances.assets.push(assets[i]); @@ -44,7 +44,6 @@ export const buildUniqueTokenList = (uniqueTokens) => { const grouped = groupBy(uniqueTokens, token => token.asset_contract.name); const families = Object.keys(grouped); for (let i = 0; i < families.length; i++) { - const tokensRow = []; for (let j = 0; j < grouped[families[i]].length; j += 2) { if (grouped[families[i]][j + 1]) { diff --git a/src/hoc/withFabSendAction.js b/src/hoc/withFabSendAction.js index 90337b2924c..c6c31070197 100644 --- a/src/hoc/withFabSendAction.js +++ b/src/hoc/withFabSendAction.js @@ -50,7 +50,7 @@ export default compose( } else { openFamilyCheck = 0; } - if (this.props.isCoinDivider == true && !this.props.fabDropped && !timerBlocker) { + if (this.props.isCoinDivider === true && !this.props.fabDropped && !timerBlocker) { timerBlocker = true; timer = setTimeout(() => { if (this.props.isCoinDivider) { diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 43074ae3cd1..145306fe22b 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -6,9 +6,9 @@ import imageDimensionsCache from './imageDimensionsCache'; import isWalletEmpty from './isWalletEmpty'; import navigation from './navigation'; import nonce from './nonce'; +import openBalances from './openBalances'; import openFamilyTabs from './openFamilyTabs'; import openInvestmentCards from './openInvestmentCards'; -import openBalances from './openBalances'; import requests from './requests'; import selectedWithFab from './selectedWithFab'; import send from './send'; @@ -24,9 +24,9 @@ export default combineReducers({ isWalletEmpty, navigation, nonce, + openBalances, openFamilyTabs, openInvestmentCards, - openBalances, requests, selectedWithFab, send, From 002b20c9a92f08a3d4a59935ccd571b3874a918e Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 20:08:56 +0200 Subject: [PATCH 020/636] fix auto scroll distance --- src/components/asset-list/RecyclerAssetList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 2c6f710a28b..b75809ab2f2 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -326,7 +326,7 @@ class RecyclerAssetList extends PureComponent { let collectiblesHeight = 0; for (let j = 0; j < i; j++) { if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { - collectiblesHeight += collectibles.data[j].tokens.length * CardSize + 54 + RowPadding * (collectibles.data[j].tokens.length - 1); + collectiblesHeight += collectibles.data[j].tokens.length * CardSize + 54 + (RowPadding - 4) * (collectibles.data[j].tokens.length - 1); } else { collectiblesHeight += 54; } @@ -344,7 +344,7 @@ class RecyclerAssetList extends PureComponent { let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); - balancesHeight += CoinDivider.height; + balancesHeight += CoinDivider.height + ListFooter.height; if (this.props.openSmallBalances) { balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; } From e0ebb1eec0d66d7f924593ddef5429845921faae Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 30 Jul 2019 22:45:23 +0200 Subject: [PATCH 021/636] add autoscroll for opening small balances --- src/components/asset-list/RecyclerAssetList.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index b75809ab2f2..98ce3d76f73 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -370,6 +370,23 @@ class RecyclerAssetList extends PureComponent { i++; } } + if (this.props.openSmallBalances !== prev.openSmallBalances && this.props.openSmallBalances) { + const verticalOffset = 15; + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); + const sectionsHeight = CoinRow.height * (balances.data.length - 1); + const renderSize = (CoinRow.height * balances.data[balances.data.length - 1].assets.length) - verticalOffset; + + if (renderSize >= deviceDimensions) { + const scrollDistance = sectionsHeight - this.position; + this.scrollToOffset(this.position + scrollDistance); + } else { + const diff = this.position - sectionsHeight + deviceDimensions; + if (renderSize > diff) { + const scrollDistance = deviceDimensions > renderSize ? renderSize - diff : deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 250 : 280); + this.scrollToOffset(this.position + scrollDistance); + } + } + } } componentWillUnmount = () => { From 2e4ce816456e7be429ceb0e9f512bebb6f17e68f Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 30 Jul 2019 17:17:18 -0400 Subject: [PATCH 022/636] cleanup copy --- src/components/AddFundsInterstitial.js | 2 +- src/components/settings-menu/BackupSection.js | 4 ++-- src/hoc/withDataInit.js | 4 ++-- src/languages/_english.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/AddFundsInterstitial.js b/src/components/AddFundsInterstitial.js index 5d952dad81f..cc380584796 100644 --- a/src/components/AddFundsInterstitial.js +++ b/src/components/AddFundsInterstitial.js @@ -62,7 +62,7 @@ const AddFundsInterstitial = ({ Import Wallet - Use your 12 to 24 word seed phrase from an existing wallet. + Use your private key or 12 to 24 word seed phrase from an existing wallet. diff --git a/src/components/settings-menu/BackupSection.js b/src/components/settings-menu/BackupSection.js index 02d68eccb7d..6eb5087cdf4 100644 --- a/src/components/settings-menu/BackupSection.js +++ b/src/components/settings-menu/BackupSection.js @@ -54,7 +54,7 @@ const BackupSection = ({ - {seedPhrase ? 'Hide' : 'Show'} Seed Phrase + {seedPhrase ? 'Hide' : 'Show'} Private Key ); diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 54672c92d0a..aaac0c15704 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -127,7 +127,7 @@ export default Component => compose( try { const { isImported, isNew, walletAddress } = await walletInit(seedPhrase); if (isNil(walletAddress)) { - Alert.alert('Import failed due to an invalid seed phrase. Please try again.'); + Alert.alert('Import failed due to an invalid private key. Please try again.'); return null; } if (isImported) { @@ -155,7 +155,7 @@ export default Component => compose( } catch (error) { // TODO specify error states more granular ownProps.onHideSplashScreen(); - Alert.alert('Import failed due to an invalid seed phrase. Please try again.'); + Alert.alert('Import failed due to an invalid private key. Please try again.'); return null; } }, diff --git a/src/languages/_english.json b/src/languages/_english.json index 31c07d0303d..c35147a1cef 100644 --- a/src/languages/_english.json +++ b/src/languages/_english.json @@ -241,7 +241,7 @@ }, "authenticate": { "please": "Please authenticate", - "please_seed_phrase": "Please authenticate to view seed phrase" + "please_seed_phrase": "Please authenticate to view private key" }, "push_notifications": { "please_enable_title": "Rainbow would like to send you push notifications", From a0ec153069575459b54de8af3072df832f9d9c0f Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 30 Jul 2019 18:45:10 -0400 Subject: [PATCH 023/636] version bump --- ios/Rainbow/Info.plist | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index e40b3318f40..64edfd7f921 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -34,7 +34,7 @@ CFBundleVersion - 1 + 2 CodePushDeploymentKey $(CODEPUSH_KEY) ITSAppUsesNonExemptEncryption diff --git a/package.json b/package.json index fe675592ce1..f3c05ae3a3a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.1.4-1", + "version": "1.1.4-2", "private": true, "scripts": { "clean": "react-native-clean-project", @@ -236,4 +236,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file From 14ebbf6a2869832546861d308db0b175fd91da29 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 30 Jul 2019 21:38:16 -0400 Subject: [PATCH 024/636] update defaults for loading state --- src/hoc/withDataInit.js | 2 +- src/redux/isWalletEthZero.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index aaac0c15704..5bdc681b1d5 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -141,7 +141,7 @@ export default Component => compose( } else { const isWalletEmpty = await getIsWalletEmpty(walletAddress, 'mainnet'); if (isNil(isWalletEmpty)) { - await ownProps.checkEthBalance(walletAddress); + ownProps.checkEthBalance(walletAddress); } else { ownProps.setIsWalletEthZero(isWalletEmpty); } diff --git a/src/redux/isWalletEthZero.js b/src/redux/isWalletEthZero.js index b689ac5fae5..95716cdade3 100644 --- a/src/redux/isWalletEthZero.js +++ b/src/redux/isWalletEthZero.js @@ -11,7 +11,7 @@ export const setIsWalletEthZero = payload => dispatch => ( ); // -- Reducer ----------------------------------------- // -const INITIAL_STATE = { isWalletEthZero: true }; +const INITIAL_STATE = { isWalletEthZero: false }; export default (state = INITIAL_STATE, action) => ( produce(state, draft => { From 0146ce5b139da1f64c2188ff0a97c3d44fbb8c25 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 30 Jul 2019 21:52:48 -0400 Subject: [PATCH 025/636] version bump --- ios/Rainbow/Info.plist | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index 64edfd7f921..e7d3c69e400 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -34,7 +34,7 @@ CFBundleVersion - 2 + 3 CodePushDeploymentKey $(CODEPUSH_KEY) ITSAppUsesNonExemptEncryption diff --git a/package.json b/package.json index f3c05ae3a3a..ecb95543107 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.1.4-2", + "version": "1.1.4-3", "private": true, "scripts": { "clean": "react-native-clean-project", From ac39dce6744cbb576b747a9e616a3dbcb389de31 Mon Sep 17 00:00:00 2001 From: Michal Osadnik Date: Wed, 31 Jul 2019 11:37:24 +0100 Subject: [PATCH 026/636] Bump to RN 0.60.4 --- ios/Podfile | 49 ++- ios/Podfile.lock | 246 +++++++++------ package.json | 10 +- yarn.lock | 788 ++++++++--------------------------------------- 4 files changed, 307 insertions(+), 786 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 87d25b84ac4..d10121ad511 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -15,33 +15,32 @@ target 'Rainbow' do pod 'Firebase/Messaging', '~> 5.3.0' # Core React - pod 'React', :path => "#{rn_path}", :subspecs => [ - 'Core', - 'CxxBridge', # Include this for RN >= 0.47 - 'cxxreact', - 'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43 - 'fishhook', - 'jsi', - 'jsiexecutor', - 'jsinspector', - 'RCTActionSheet', - 'RCTAnimation', # Needed for FlatList and animations running on native UI thread - 'RCTBlob', - 'RCTImage', - 'RCTLinkingIOS', - 'RCTNetwork', - 'RCTPushNotification', - 'RCTSettings', - 'RCTText', - 'RCTVibration', - 'RCTWebSocket', # needed for debugging - ] + pod 'React', :path => '../node_modules/react-native/' + pod 'React-Core', :path => '../node_modules/react-native/React' + pod 'React-DevSupport', :path => '../node_modules/react-native/React' + pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' + pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' + pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' + pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' + pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' + pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' + pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' + pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' + pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' + pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' + pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' + + pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' + pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' + pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' + pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' + # React Third Party - required - pod 'yoga', path: "#{rn_path}/ReactCommon/yoga" - pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec" - pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec" - pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec" + pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' + pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' + pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' + pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' # React-Native-Community packages pod 'react-native-blur', :path => '../node_modules/@react-native-community/blur' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 44c0b4cb979..d98bfe10aa1 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -31,6 +31,11 @@ PODS: - Protobuf (~> 3.1) - FLAnimatedImage (1.0.12) - Folly (2018.10.22.00): + - boost-for-react-native + - DoubleConversion + - Folly/Default (= 2018.10.22.00) + - glog + - Folly/Default (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog @@ -70,8 +75,52 @@ PODS: - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - Protobuf (3.7.0) - - React (0.59.9): - - React/Core (= 0.59.9) + - React (0.60.4): + - React-Core (= 0.60.4) + - React-DevSupport (= 0.60.4) + - React-RCTActionSheet (= 0.60.4) + - React-RCTAnimation (= 0.60.4) + - React-RCTBlob (= 0.60.4) + - React-RCTImage (= 0.60.4) + - React-RCTLinking (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTSettings (= 0.60.4) + - React-RCTText (= 0.60.4) + - React-RCTVibration (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-Core (0.60.4): + - Folly (= 2018.10.22.00) + - React-cxxreact (= 0.60.4) + - React-jsiexecutor (= 0.60.4) + - yoga (= 0.60.4.React) + - React-cxxreact (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsinspector (= 0.60.4) + - React-DevSupport (0.60.4): + - React-Core (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-fishhook (0.60.4) + - React-jsi (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsi/Default (= 0.60.4) + - React-jsi/Default (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsiexecutor (0.60.4): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.60.4) + - React-jsi (= 0.60.4) + - React-jsinspector (0.60.4) - react-native-blur (0.8.0): - React - react-native-camera (2.11.1): @@ -89,59 +138,30 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React/Core (0.59.9): - - yoga (= 0.59.9.React) - - React/CxxBridge (0.59.9): - - Folly (= 2018.10.22.00) - - React/Core - - React/cxxreact - - React/jsiexecutor - - React/cxxreact (0.59.9): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React/jsinspector - - React/DevSupport (0.59.9): - - React/Core - - React/RCTWebSocket - - React/fishhook (0.59.9) - - React/jsi (0.59.9): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React/jsiexecutor (0.59.9): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React/cxxreact - - React/jsi - - React/jsinspector (0.59.9) - - React/RCTActionSheet (0.59.9): - - React/Core - - React/RCTAnimation (0.59.9): - - React/Core - - React/RCTBlob (0.59.9): - - React/Core - - React/RCTImage (0.59.9): - - React/Core - - React/RCTNetwork - - React/RCTLinkingIOS (0.59.9): - - React/Core - - React/RCTNetwork (0.59.9): - - React/Core - - React/RCTPushNotification (0.59.9): - - React/Core - - React/RCTSettings (0.59.9): - - React/Core - - React/RCTText (0.59.9): - - React/Core - - React/RCTVibration (0.59.9): - - React/Core - - React/RCTWebSocket (0.59.9): - - React/Core - - React/fishhook - - React/RCTBlob + - React-RCTActionSheet (0.60.4): + - React-Core (= 0.60.4) + - React-RCTAnimation (0.60.4): + - React-Core (= 0.60.4) + - React-RCTBlob (0.60.4): + - React-Core (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-RCTImage (0.60.4): + - React-Core (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTLinking (0.60.4): + - React-Core (= 0.60.4) + - React-RCTNetwork (0.60.4): + - React-Core (= 0.60.4) + - React-RCTSettings (0.60.4): + - React-Core (= 0.60.4) + - React-RCTText (0.60.4): + - React-Core (= 0.60.4) + - React-RCTVibration (0.60.4): + - React-Core (= 0.60.4) + - React-RCTWebSocket (0.60.4): + - React-Core (= 0.60.4) + - React-fishhook (= 0.60.4) - RNAnalytics (1.0.1): - Analytics - React @@ -164,7 +184,7 @@ PODS: - SDWebImage (5.0.2): - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) - - yoga (0.59.9.React) + - yoga (0.60.4.React) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -177,30 +197,29 @@ DEPENDENCIES: - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - libwebp + - React (from `../node_modules/react-native/`) + - React-Core (from `../node_modules/react-native/React`) + - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) + - React-DevSupport (from `../node_modules/react-native/React`) + - React-fishhook (from `../node_modules/react-native/Libraries/fishhook`) + - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) + - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) + - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-camera (from `../node_modules/react-native-camera`) - react-native-fast-image (from `../node_modules/react-native-fast-image`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-version-number (from `../node_modules/react-native-version-number`) - - React/Core (from `../node_modules/react-native`) - - React/CxxBridge (from `../node_modules/react-native`) - - React/cxxreact (from `../node_modules/react-native`) - - React/DevSupport (from `../node_modules/react-native`) - - React/fishhook (from `../node_modules/react-native`) - - React/jsi (from `../node_modules/react-native`) - - React/jsiexecutor (from `../node_modules/react-native`) - - React/jsinspector (from `../node_modules/react-native`) - - React/RCTActionSheet (from `../node_modules/react-native`) - - React/RCTAnimation (from `../node_modules/react-native`) - - React/RCTBlob (from `../node_modules/react-native`) - - React/RCTImage (from `../node_modules/react-native`) - - React/RCTLinkingIOS (from `../node_modules/react-native`) - - React/RCTNetwork (from `../node_modules/react-native`) - - React/RCTPushNotification (from `../node_modules/react-native`) - - React/RCTSettings (from `../node_modules/react-native`) - - React/RCTText (from `../node_modules/react-native`) - - React/RCTVibration (from `../node_modules/react-native`) - - React/RCTWebSocket (from `../node_modules/react-native`) + - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) + - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) + - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) + - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) + - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) + - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) + - React-RCTText (from `../node_modules/react-native/Libraries/Text`) + - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -240,7 +259,21 @@ EXTERNAL SOURCES: glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" React: - :path: "../node_modules/react-native" + :path: "../node_modules/react-native/" + React-Core: + :path: "../node_modules/react-native/React" + React-cxxreact: + :path: "../node_modules/react-native/ReactCommon/cxxreact" + React-DevSupport: + :path: "../node_modules/react-native/React" + React-fishhook: + :path: "../node_modules/react-native/Libraries/fishhook" + React-jsi: + :path: "../node_modules/react-native/ReactCommon/jsi" + React-jsiexecutor: + :path: "../node_modules/react-native/ReactCommon/jsiexecutor" + React-jsinspector: + :path: "../node_modules/react-native/ReactCommon/jsinspector" react-native-blur: :path: "../node_modules/@react-native-community/blur" react-native-camera: @@ -251,6 +284,26 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/netinfo" react-native-version-number: :path: "../node_modules/react-native-version-number" + React-RCTActionSheet: + :path: "../node_modules/react-native/Libraries/ActionSheetIOS" + React-RCTAnimation: + :path: "../node_modules/react-native/Libraries/NativeAnimation" + React-RCTBlob: + :path: "../node_modules/react-native/Libraries/Blob" + React-RCTImage: + :path: "../node_modules/react-native/Libraries/Image" + React-RCTLinking: + :path: "../node_modules/react-native/Libraries/LinkingIOS" + React-RCTNetwork: + :path: "../node_modules/react-native/Libraries/Network" + React-RCTSettings: + :path: "../node_modules/react-native/Libraries/Settings" + React-RCTText: + :path: "../node_modules/react-native/Libraries/Text" + React-RCTVibration: + :path: "../node_modules/react-native/Libraries/Vibration" + React-RCTWebSocket: + :path: "../node_modules/react-native/Libraries/WebSocket" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -277,26 +330,43 @@ SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c - DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd + DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 - FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d - FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 - FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 - FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 + Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa + FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 + FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 + FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 + FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 - Folly: de497beb10f102453a1afa9edbf8cf8a251890de - glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d + Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 + glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a - React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f + React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 + React-Core: 8e0ea421cae5609d2562850f98421b15030476fa + React-cxxreact: 326880209990151a7182a813311054e9772ba510 + React-DevSupport: e9f10e6721e78e87622fc985db695c0c0168db8a + React-fishhook: 1f0e5b08449403fa75c3fb3881a0beefbada14af + React-jsi: 21d3153b1153fbf6510a92b6b11e33e725cb7432 + React-jsiexecutor: 7549641e48bafae7bfee3f3ea19bf4901639c5de + React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: f1fbfc336ba8ca6de5296190341d1b6022c71cff react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 react-native-netinfo: 0da34082d2cec3100c9b5073bb217e35f1142bdd react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f + React-RCTActionSheet: 9f71d7ae3e8fb10e08d162cbf14c621349dbfab3 + React-RCTAnimation: 981d8c95b0e30918a9832ccac32af83562a27fae + React-RCTBlob: 21e73d1020a302a75fed30dbaee9f15287b80baa + React-RCTImage: c0bc6ac0926517b6fb7e4c279b04843113e99d1d + React-RCTLinking: 1af3f3c59114bed3deec0107c62e7efad0932ee5 + React-RCTNetwork: 35df9de46e19cda5c56380be1a7759b9b8cb2fcd + React-RCTSettings: f580504c2cd1f44e25add10fb9ed3954f67f8ac5 + React-RCTText: e0f224898b13af9aa036ea7cb3d438daa68c1044 + React-RCTVibration: 0bea40cd51bd089bd591a8f74c86e91fdf2666c5 + React-RCTWebSocket: 163873f4cdd5f1058a9483443404fc3801581cb6 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 @@ -307,8 +377,8 @@ SPEC CHECKSUMS: RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 - yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee + yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 -PODFILE CHECKSUM: 9a1477d30332ab86b10fd2ec7e7842ad52b5382e +PODFILE CHECKSUM: 2faf7ebfb07db0bc35d060386204981cb07de5b7 -COCOAPODS: 1.6.1 +COCOAPODS: 1.7.4 diff --git a/package.json b/package.json index ecb95543107..871d90ef591 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "clean": "react-native-clean-project", - "start": "node node_modules/react-native/local-cli/cli.js start", + "start": "react-native start", "test": "jest test.js", "install-pods": "cd ios && pod install && cd ..", "ios": "react-native run-ios --simulator='iPhone X'", @@ -57,9 +57,9 @@ "prop-types": "^15.7.2", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "react": "16.8.3", + "react": "16.8.6", "react-coin-icon": "^0.1.9", - "react-native": "0.59.9", + "react-native": "0.60.4", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", @@ -126,8 +126,8 @@ "vm-browserify": "0.0.4" }, "devDependencies": { - "@babel/core": "^7.4.5", - "@babel/runtime": "^7.4.5", + "@babel/core": "^7.5.5", + "@babel/runtime": "^7.5.5", "@react-native-community/cli": "2.0.0-rc.2", "@react-native-community/eslint-config": "^0.0.5", "babel-core": "7.0.0-bridge.0", diff --git a/yarn.lock b/yarn.lock index 1e4a415a0f5..9bdfeb5ae60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,7 +16,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -659,7 +659,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== @@ -1078,7 +1078,7 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.0.0-rc.2": +"@react-native-community/cli-platform-android@^2.0.0-rc.2", "@react-native-community/cli-platform-android@^2.0.1", "@react-native-community/cli-platform-android@^2.7.0": version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== @@ -1091,7 +1091,7 @@ slash "^2.0.0" xmldoc "^0.4.0" -"@react-native-community/cli-platform-ios@^2.0.0-rc.2": +"@react-native-community/cli-platform-ios@^2.0.0-rc.2", "@react-native-community/cli-platform-ios@^2.0.1", "@react-native-community/cli-platform-ios@^2.8.0": version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== @@ -1150,45 +1150,44 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^1.2.1": - version "1.11.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.11.2.tgz#b14967f24a389f5a16889a747345cf0e5757a2f1" - integrity sha512-5NuYd30f5PCTrGUbZLnusZKv5nfTWvTDTRa/3Q4vwdMnUQrhm9sZXWGQ5CnFoQ7cE58EAqhj6/ShXeJF3DZ9uQ== +"@react-native-community/cli@^2.0.1": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.0.tgz#346ff73ace6b2265d99ec217a8624b8735d19930" + integrity sha512-sN43IyvBtFtC1iOjx3pfKeo7DK4wkJxWiggR3QkkNQdyjuGT3RGXiYZVPu+zda6BPKdeGYpS+7UJrkGT+1tuFg== dependencies: - chalk "^1.1.1" + "@hapi/joi" "^15.0.3" + "@react-native-community/cli-platform-android" "^2.7.0" + "@react-native-community/cli-platform-ios" "^2.8.0" + "@react-native-community/cli-tools" "^2.7.0" + chalk "^2.4.2" commander "^2.19.0" compression "^1.7.1" connect "^3.6.5" - denodeify "^1.2.1" - envinfo "^5.7.0" + cosmiconfig "^5.1.0" + deepmerge "^3.2.0" + envinfo "^7.1.0" errorhandler "^1.5.0" - escape-string-regexp "^1.0.5" execa "^1.0.0" fs-extra "^7.0.1" glob "^7.1.1" graceful-fs "^4.1.3" inquirer "^3.0.6" lodash "^4.17.5" - metro "^0.51.0" - metro-config "^0.51.0" - metro-core "^0.51.0" - metro-memory-fs "^0.51.0" - metro-react-native-babel-transformer "^0.51.0" - mime "^1.3.4" + metro "^0.54.1" + metro-config "^0.54.1" + metro-core "^0.54.1" + metro-react-native-babel-transformer "^0.54.1" minimist "^1.2.0" mkdirp "^0.5.1" morgan "^1.9.0" - node-fetch "^2.2.0" node-notifier "^5.2.1" - opn "^3.0.2" + open "^6.2.0" + ora "^3.4.0" plist "^3.0.0" semver "^5.0.3" serve-static "^1.13.1" shell-quote "1.6.1" - slash "^2.0.0" ws "^1.1.0" - xcode "^2.0.0" - xmldoc "^0.4.0" "@react-native-community/eslint-config@^0.0.5": version "0.0.5" @@ -1601,6 +1600,13 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + abs-svg-path@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" @@ -1794,11 +1800,6 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0: resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= -ansi@^0.3.0, ansi@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" - integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1840,13 +1841,6 @@ arr-diff@^1.0.1: arr-flatten "^1.0.1" array-slice "^0.2.3" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1917,11 +1911,6 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -2185,7 +2174,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-fbjs@^3.0.1, babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: +babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.2.0.tgz#c0e6347d3e0379ed84b3c2434d3467567aa05297" integrity sha512-5Jo+JeWiVz2wHUUyAlvb/sSYnXNig9r+HqGAOSfh5Fzxp7SnAaR/tEGRJ1ZX7C77kfk82658w6R5Z+uPATTD9g== @@ -2385,15 +2374,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -2652,13 +2632,6 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== -capture-exit@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" - integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= - dependencies: - rsvp "^3.3.3" - capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -2950,7 +2923,7 @@ command-exists@^1.2.8: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== -commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: +commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -3742,11 +3715,6 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -envinfo@^5.7.0: - version "5.12.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" - integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== - envinfo@^7.1.0: version "7.3.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" @@ -4111,10 +4079,10 @@ ethers@^4.0.33: uuid "2.0.1" xmlhttprequest "1.8.0" -event-target-shim@^1.0.5: - version "1.1.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-1.1.1.tgz#a86e5ee6bdaa16054475da797ccddf0c55698491" - integrity sha1-qG5e5r2qFgVEddp5fM3fDFVphJE= +event-target-shim@^5.0.0, event-target-shim@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== eventemitter3@^3.0.0: version "3.1.2" @@ -4141,13 +4109,6 @@ exception-formatter@^1.0.4: dependencies: colors "^1.0.3" -exec-sh@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" - integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== - dependencies: - merge "^1.2.0" - exec-sh@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" @@ -4196,13 +4157,6 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= - dependencies: - is-posix-bracket "^0.1.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -4216,13 +4170,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - expect@^24.8.0: version "24.8.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d" @@ -4289,13 +4236,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -4379,7 +4319,7 @@ fbjs-css-vars@^1.0.0: resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== -fbjs-scripts@^1.0.0: +fbjs-scripts@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.2.0.tgz#069a0c0634242d10031c6460ef1fccefcdae8b27" integrity sha512-5krZ8T0Bf8uky0abPoCLrfa7Orxd8UH4Qq8hRUF2RZYNMu+FmEOrBc7Ib3YVONmxTXTlLAvyrrdrVmksDb2OqQ== @@ -4449,22 +4389,6 @@ file-uri-to-path@1: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -4569,7 +4493,7 @@ for-in@^1.0.1, for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^0.1.3, for-own@^0.1.4: +for-own@^0.1.3: version "0.1.5" resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= @@ -4669,7 +4593,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.3, fsevents@^1.2.7: +fsevents@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== @@ -4707,17 +4631,6 @@ fwd-stream@^1.0.4: dependencies: readable-stream "~1.0.26-4" -gauge@~1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" - integrity sha1-6c7FSD09TuDvRLYKfZnkk14TbZM= - dependencies: - ansi "^0.3.0" - has-unicode "^2.0.0" - lodash.pad "^4.1.0" - lodash.padend "^4.1.0" - lodash.padstart "^4.1.0" - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -4790,21 +4703,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -5083,6 +4981,11 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hermesvm@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.0.tgz#4bfaf4ac682a2fd407b862ab641eb8deb232de83" + integrity sha512-GbP6dKaVW/V2QpB+DZPxcmhBhJVFa9cHS/xRX7FD1MGfa6Z1aHHD83VDCwo3SgcqNj5yHlVbe9UgrK1PFGCXpw== + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -5525,18 +5428,6 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -5549,11 +5440,6 @@ is-extendable@^1.0.0, is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -5581,13 +5467,6 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -5620,13 +5499,6 @@ is-npm@^1.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -5634,11 +5506,6 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -5673,16 +5540,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= - is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -5964,19 +5821,6 @@ jest-get-type@^24.8.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc" integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ== -jest-haste-map@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" - integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.11" - invariant "^2.2.4" - jest-serializer "^24.0.0-alpha.6" - jest-worker "^24.0.0-alpha.6" - micromatch "^2.3.11" - sane "^3.0.0" - jest-haste-map@^24.7.1, jest-haste-map@^24.8.0: version "24.8.1" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.1.tgz#f39cc1d2b1d907e014165b4bd5a957afcb992982" @@ -6140,12 +5984,7 @@ jest-runtime@^24.8.0: strip-bom "^3.0.0" yargs "^12.0.2" -jest-serializer@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" - integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== - -jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0: +jest-serializer@^24.4.0: version "24.4.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== @@ -6211,14 +6050,7 @@ jest-watcher@^24.8.0: jest-util "^24.8.0" string-length "^2.0.0" -jest-worker@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" - integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== - dependencies: - merge-stream "^1.0.1" - -jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0: +jest-worker@^24.6.0: version "24.6.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== @@ -6267,6 +6099,11 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsc-android@245459.0.0: + version "245459.0.0" + resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" + integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== + jsdom@^11.5.1: version "11.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" @@ -6618,21 +6455,6 @@ lodash.debounce@4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.pad@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" - integrity sha1-QzCUmoM6fI2iLMIPaibE1Z3runA= - -lodash.padend@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= - -lodash.padstart@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" - integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= - lodash.snakecase@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" @@ -6784,11 +6606,6 @@ markdown-table@^1.1.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== -math-random@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" - integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== - mathml-tag-names@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" @@ -6884,34 +6701,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - methods@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -metro-babel-register@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.51.0.tgz#d86d3f2d90b45c7a3c6ae67a53bd1e50bad7a24d" - integrity sha512-rhdvHFOZ7/ub019A3+aYs8YeLydb02/FAMsKr2Nz2Jlf6VUxWrMnrcT0NYX16F9TGdi2ulRlJ9dwvUmdhkk+Bw== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - metro-babel-register@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.54.1.tgz#7d2bfe444b1ccef8de99aedc7d9330891d806076" @@ -6930,20 +6724,6 @@ metro-babel-register@0.54.1: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-transformer@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.51.0.tgz#9ee5199163ac46b2057527b3f8cbd8b089ffc03e" - integrity sha512-M7KEY/hjD3E8tJEliWgI0VOSaJtqaznC0ItM6FiMrhoGDqqa1BvGofl+EPcKqjBSOV1UgExua/T1VOIWbjwQsw== - dependencies: - "@babel/core" "^7.0.0" - -metro-babel-transformer@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.51.1.tgz#97be9e2b96c78aa202b52ae05fb86f71327aef72" - integrity sha512-+tOnZZzOzufB86ASdfimUEGB1jBKsdsVpPdjNJZkueTFyvYlGqWDQKHM1w9bwKMeM/czPQ48Y6m8Bou6le0X4w== - dependencies: - "@babel/core" "^7.0.0" - metro-babel-transformer@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" @@ -6951,20 +6731,6 @@ metro-babel-transformer@0.54.1: dependencies: "@babel/core" "^7.0.0" -metro-babel7-plugin-react-transform@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.0.tgz#af27dd81666b91f05d2b371b0d6d283c585e38b6" - integrity sha512-dZ95kXcE2FJMoRsYhxr7YLCbOlHWKwe0bOpihRhfImDTgFfuKIzU4ROQwMUbE0NCbzB+ATFsa2FZ3pHDJ5GI0w== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - -metro-babel7-plugin-react-transform@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.1.tgz#9cce2c340cc4006fc82aa6dfab27af22d592607e" - integrity sha512-wzn4X9KgmAMZ7Bi6v9KxA7dw+AHGL0RODPxU5NDJ3A6d0yERvzfZ3qkzWhz8jbFkVBK12cu5DTho3HBazKQDOw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - metro-babel7-plugin-react-transform@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" @@ -6972,16 +6738,6 @@ metro-babel7-plugin-react-transform@0.54.1: dependencies: "@babel/helper-module-imports" "^7.0.0" -metro-cache@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.51.1.tgz#d0b296eab8e009214413bba87e4eac3d9b44cd04" - integrity sha512-0m1+aicsw77LVAehNuTxDpE1c/7Xv/ajRD+UL/lFCWUxnrjSbxVtIKr8l5DxEY11082c1axVRuaV9e436W+eXg== - dependencies: - jest-serializer "24.0.0-alpha.6" - metro-core "0.51.1" - mkdirp "^0.5.1" - rimraf "^2.5.4" - metro-cache@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1" @@ -6992,17 +6748,6 @@ metro-cache@0.54.1: mkdirp "^0.5.1" rimraf "^2.5.4" -metro-config@0.51.1, metro-config@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.51.1.tgz#8f1a241ce2c0b521cd492c39bc5c6c69e3397b82" - integrity sha512-WCNd0tTI9gb/ubgTqK1+ljZL4b3hsXVinsOAtep4nHiVb6DSDdbO2yXDD2rpYx3NE6hDRMFS9HHg6G0139pAqQ== - dependencies: - cosmiconfig "^5.0.5" - metro "0.51.1" - metro-cache "0.51.1" - metro-core "0.51.1" - pretty-format "24.0.0-alpha.6" - metro-config@0.54.1, metro-config@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd" @@ -7015,16 +6760,6 @@ metro-config@0.54.1, metro-config@^0.54.1: metro-core "0.54.1" pretty-format "^24.7.0" -metro-core@0.51.1, metro-core@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.51.1.tgz#e7227fb1dd1bb3f953272fad9876e6201140b038" - integrity sha512-sG1yACjdFqmIzZN50HqLTKUMp1oy0AehHhmIuYeIllo1DjX6Y2o3UAT3rGP8U+SAqJGXf/OWzl6VNyRPGDENfA== - dependencies: - jest-haste-map "24.0.0-alpha.6" - lodash.throttle "^4.1.1" - metro-resolver "0.51.1" - wordwrap "^1.0.0" - metro-core@0.54.1, metro-core@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b" @@ -7046,18 +6781,6 @@ metro-inspector-proxy@0.54.1: ws "^1.1.5" yargs "^9.0.0" -metro-memory-fs@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.51.1.tgz#624291f5956b0fd11532d80b1b85d550926f96c9" - integrity sha512-dXVUpLPLwfQcYHd1HlqHGVzBsiwvUdT92TDSbdc10152TP+iynHBqLDWbxt0MAtd6c/QXwOuGZZ1IcX3+lv5iw== - -metro-minify-uglify@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.51.1.tgz#60cd8fe4d3e82d6670c717b8ddb52ae63199c0e4" - integrity sha512-HAqd/rFrQ6mnbqVAszDXIKTg2rqHlY9Fm8DReakgbkAeyMbF2mH3kEgtesPmTrhajdFk81UZcNSm6wxj1JMgVg== - dependencies: - uglify-es "^3.1.9" - metro-minify-uglify@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3" @@ -7065,88 +6788,6 @@ metro-minify-uglify@0.54.1: dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.0.tgz#978d960acf2d214bbbe43e59145878d663bd07de" - integrity sha512-Y/aPeLl4RzY8IEAneOyDcpdjto/8yjIuX9eUWRngjSqdHYhGQtqiSBpfTpo0BvXpwNRLwCLHyXo58gNpckTJFw== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.51.0" - react-transform-hmr "^1.0.4" - -metro-react-native-babel-preset@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.1.tgz#44aeeedfea37f7c2ab8f6f273fa71b90fe65f089" - integrity sha512-e9tsYDFhU70gar0jQWcZXRPJVCv4k7tEs6Pm74wXO2OO/T1MEumbvniDIGwGG8bG8RUnYdHhjcaiub2Vc5BRWw== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.51.1" - react-transform-hmr "^1.0.4" - metro-react-native-babel-preset@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" @@ -7230,27 +6871,7 @@ metro-react-native-babel-preset@^0.55.0: "@babel/template" "^7.0.0" react-refresh "^0.2.0" -metro-react-native-babel-transformer@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz#57a695e97a19d95de63c9633f9d0dc024ee8e99a" - integrity sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.0" - metro-react-native-babel-preset "0.51.0" - -metro-react-native-babel-transformer@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.1.tgz#bac34f988c150c725cd1875c13701cc2032615f9" - integrity sha512-D0KU+JPb/Z76nUWt3+bkjKggOlGvqAVI2BpIH2JFKprpUyBjWaCRqHnkBfZGixYwUfmu93MIlKJWr6iKzzFrlg== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.1" - metro-react-native-babel-preset "0.51.1" - -metro-react-native-babel-transformer@^0.54.1: +metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== @@ -7260,13 +6881,6 @@ metro-react-native-babel-transformer@^0.54.1: metro-babel-transformer "0.54.1" metro-react-native-babel-preset "0.54.1" -metro-resolver@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.51.1.tgz#4c26f0baee47d30250187adca3d34c902e627611" - integrity sha512-zmWbD/287NDA/jLPuPV0hne/YMMSG0dljzu21TYMg2lXRLur/zROJHHhyepZvuBHgInXBi4Vhr2wvuSnY39SuA== - dependencies: - absolute-path "^0.0.0" - metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -7274,13 +6888,6 @@ metro-resolver@0.54.1: dependencies: absolute-path "^0.0.0" -metro-source-map@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.51.1.tgz#1a8da138e98e184304d5558b4f92a5c2141822d0" - integrity sha512-JyrE+RV4YumrboHPHTGsUUGERjQ681ImRLrSYDGcmNv4tfpk9nvAK26UAas4IvBYFCC9oW90m0udt3kaQGv59Q== - dependencies: - source-map "^0.5.6" - metro-source-map@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5" @@ -7290,62 +6897,28 @@ metro-source-map@0.54.1: "@babel/types" "^7.0.0" source-map "^0.5.6" -metro@0.51.1, metro@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.51.1.tgz#b0aad4731593b9f244261bad1abb2a006d1c8969" - integrity sha512-nM0dqn8LQlMjhChl2fzTUq2EWiUebZM7nkesD9vQe47W10bj/tbRLPiIIAxht6SRDbPd/hRA+t39PxLhPSKEKg== +metro-source-map@0.55.0, metro-source-map@^0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540" + integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw== dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.0.1" - buffer-crc32 "^0.2.13" - chalk "^2.4.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" invariant "^2.2.4" - jest-haste-map "24.0.0-alpha.6" - jest-worker "24.0.0-alpha.6" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-babel-transformer "0.51.1" - metro-cache "0.51.1" - metro-config "0.51.1" - metro-core "0.51.1" - metro-minify-uglify "0.51.1" - metro-react-native-babel-preset "0.51.1" - metro-resolver "0.51.1" - metro-source-map "0.51.1" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - react-transform-hmr "^1.0.4" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" + metro-symbolicate "0.55.0" + ob1 "0.55.0" source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.5" - xpipe "^1.0.5" - yargs "^9.0.0" + vlq "^1.0.0" + +metro-symbolicate@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1" + integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg== + dependencies: + metro-source-map "0.55.0" + source-map "^0.5.6" + through2 "^2.0.1" + vlq "^1.0.0" metro@0.54.1, metro@^0.54.1: version "0.54.1" @@ -7406,25 +6979,6 @@ metro@0.54.1, metro@^0.54.1: xpipe "^1.0.5" yargs "^9.0.0" -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7484,7 +7038,7 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime@1.6.0, mime@^1.3.4: +mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -7847,7 +7401,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -7891,15 +7445,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" - integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= - dependencies: - ansi "~0.3.1" - are-we-there-yet "~1.1.2" - gauge "~1.2.5" - npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -7942,6 +7487,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +ob1@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd" + integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw== + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -8020,14 +7570,6 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - object.omit@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-3.0.0.tgz#0e3edc2fce2ba54df5577ff529f6d97bd8a522af" @@ -8120,13 +7662,6 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" -opn@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a" - integrity sha1-ttmec5n3jWXDuq/+8fsojpuFJDo= - dependencies: - object-assign "^4.0.1" - optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -8350,16 +7885,6 @@ parse-entities@^1.0.2, parse-entities@^1.1.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -8738,11 +8263,6 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= - prettier@1.16.4: version "1.16.4" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" @@ -8753,14 +8273,6 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== -pretty-format@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" - integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - pretty-format@^24.7.0, pretty-format@^24.8.0: version "24.8.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2" @@ -8818,7 +8330,7 @@ prop-types@15.5.8: dependencies: fbjs "^0.8.9" -prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8959,15 +8471,6 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - randombytes@^2.0.0, randombytes@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -9000,11 +8503,6 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-clone-referenced-element@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" - integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== - react-coin-icon@^0.1.9: version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" @@ -9019,7 +8517,7 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.0: +react-devtools-core@^3.6.1: version "3.6.3" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== @@ -9325,61 +8823,39 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.59.9: - version "0.59.9" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.59.9.tgz#c94ee4fa35121720c05235a2dd6cdd2784bf5177" - integrity sha512-/+8EgIZwFpYHyyJ7Zav7B6LHNrytwUQ+EKGT/QV7HSrgpf2Y5NZNeUYUHKiVKLYpBip1G32/LcAECQj37YRwGQ== +react-native@0.60.4: + version "0.60.4" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.4.tgz#4378171e63dd5310497e15e54ec9185cb470752d" + integrity sha512-WE41lbGQjnzM9srIFtMDtMJkQAvk95iZwuFvAxl68s80bkYa7Ou9sGFHpeYIV6cY8yHtheCSo5q6YMxhdfkdOw== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^1.2.1" - absolute-path "^0.0.0" + "@react-native-community/cli" "^2.0.1" + "@react-native-community/cli-platform-android" "^2.0.1" + "@react-native-community/cli-platform-ios" "^2.0.1" + abort-controller "^3.0.0" art "^0.10.0" base64-js "^1.1.2" - chalk "^2.4.1" - commander "^2.9.0" - compression "^1.7.1" connect "^3.6.5" create-react-class "^15.6.3" - debug "^2.2.0" - denodeify "^1.2.1" - errorhandler "^1.5.0" escape-string-regexp "^1.0.5" - event-target-shim "^1.0.5" + event-target-shim "^5.0.1" fbjs "^1.0.0" - fbjs-scripts "^1.0.0" - fs-extra "^1.0.0" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" + fbjs-scripts "^1.1.0" + hermesvm "^0.1.0" invariant "^2.2.4" - lodash "^4.17.5" - metro-babel-register "0.51.0" - metro-react-native-babel-transformer "0.51.0" - mime "^1.3.4" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-fetch "^2.2.0" - node-notifier "^5.2.1" - npmlog "^2.0.4" + jsc-android "245459.0.0" + metro-babel-register "0.54.1" + metro-react-native-babel-transformer "0.54.1" + metro-source-map "^0.55.0" nullthrows "^1.1.0" - opn "^3.0.2" - optimist "^0.6.1" - plist "^3.0.0" - pretty-format "24.0.0-alpha.6" + pretty-format "^24.7.0" promise "^7.1.1" - prop-types "^15.5.8" - react-clone-referenced-element "^1.0.1" - react-devtools-core "^3.6.0" - regenerator-runtime "^0.11.0" - rimraf "^2.5.4" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" + prop-types "^15.7.2" + react-devtools-core "^3.6.1" + regenerator-runtime "^0.13.2" + scheduler "0.14.0" stacktrace-parser "^0.1.3" - ws "^1.1.5" - xmldoc "^0.4.0" - yargs "^9.0.0" + whatwg-fetch "^3.0.0" react-navigation-drawer@~1.2.1: version "1.2.1" @@ -9487,15 +8963,15 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@16.8.3: - version "16.8.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" - integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== +react@16.8.6: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" + integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.3" + scheduler "^0.13.6" read-pkg-up@^2.0.0: version "2.0.0" @@ -9693,13 +9169,6 @@ regenerator-transform@^0.14.0: dependencies: private "^0.1.6" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== - dependencies: - is-equal-shallow "^0.1.3" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -9812,7 +9281,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -9996,11 +9465,6 @@ rn-nodeify@^10.0.1: semver "^5.0.1" xtend "^4.0.0" -rsvp@^3.3.3: - version "3.6.2" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" - integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== - rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -10076,23 +9540,6 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" - integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== - dependencies: - anymatch "^2.0.0" - capture-exit "^1.2.0" - exec-sh "^0.2.0" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.2.3" - sane@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" @@ -10132,7 +9579,15 @@ schedule@0.4.0: dependencies: object-assign "^4.1.1" -scheduler@^0.13.3: +scheduler@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b" + integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +scheduler@^0.13.3, scheduler@^0.13.6: version "0.13.6" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== @@ -11013,7 +10468,7 @@ throat@^4.0.0, throat@^4.1.0: resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= -through2@^2.0.0: +through2@^2.0.0, through2@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -11538,6 +10993,11 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" +vlq@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" + integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== + vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -11566,14 +11026,6 @@ warning@^4.0.2: dependencies: loose-envify "^1.0.0" -watch@~0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" - integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= - dependencies: - exec-sh "^0.2.0" - minimist "^1.2.0" - wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -11593,7 +11045,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" -whatwg-fetch@>=0.10.0: +whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== From 19d538d60b71a1a2e9580a7c9334cd75e902e49e Mon Sep 17 00:00:00 2001 From: Michal Osadnik Date: Wed, 31 Jul 2019 11:41:51 +0100 Subject: [PATCH 027/636] drop linking libs --- ios/Rainbow.xcodeproj/project.pbxproj | 53 --------------------------- 1 file changed, 53 deletions(-) diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 9a87f5b136e..a0f4a92e61a 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -7,26 +7,17 @@ objects = { /* Begin PBXBuildFile section */ - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 00E356F31AD99517003FC87E /* RainbowTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RainbowTests.m */; }; 03252948A60F4C4C87E4FD9E /* SF-Pro-Display-Ultralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */; }; 06B78001D9F2456D9C2D4A86 /* Graphik-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */; }; 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */; }; 0AB30EE90F554EE59F57DFC1 /* SF-Pro-Display-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */; }; 0F4372360E744AF4B37EB905 /* Graphik-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */; }; - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D755E71324B04FEE9C691D14 /* libRNFirebase.a */; }; 16934DFE7F154B06ADAD8A0B /* SF-Pro-Display-ThinItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */; }; 184EB33331FB47F2960D2507 /* SF-Pro-Display-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */; }; @@ -57,7 +48,6 @@ 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */; }; 549287401A7648CCB32F36E0 /* SF-Pro-Display-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */; }; 5D1949044DCB413FBE7AE82E /* SFMono-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */; }; - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 5F34DEED060F41878C4C5A59 /* SFMono-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */; }; 66620AB752074CB6938E956A /* Graphik-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */; }; 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; @@ -65,7 +55,6 @@ 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */; }; - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 872630C5E4CA448D8DDC783E /* Graphik-Extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */; }; 87808B52A9E224F3D11532B5 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 823BD6129C8AA3FD7CDD46BE /* libPods-Rainbow.a */; }; 8B7F7FDAB33B4D119E087D57 /* Graphik-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */; }; @@ -77,7 +66,6 @@ 96E52368EDC94B9B80D1F29C /* SF-Pro-Text-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */; }; 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EA95F99E656542F790F685B6 /* libSplashScreen.a */; }; 9E8553031AD44F52A814F2AB /* SF-Pro-Display-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */; }; - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; }; AE47B46652EA48AFB68E7832 /* SF-Pro-Text-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */; }; AFCABA638327463693E67FD4 /* SF-Pro-Text-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */; }; AFD75D0B6EC9465C92C493A7 /* SF-Pro-Display-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */; }; @@ -112,13 +100,6 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RCTActionSheet; }; - 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTGeolocation; - }; 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -593,7 +574,6 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; @@ -758,19 +738,6 @@ buildActionMask = 2147483647; files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 146834051AC3E58100842450 /* libReact.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */, 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */, 94822FBFCA7246168685FA85 /* libRNMail.a in Frameworks */, @@ -806,14 +773,6 @@ name = Products; sourceTree = ""; }; - 00C302B61ABCB90400DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, - ); - name = Products; - sourceTree = ""; - }; 00C302BC1ABCB91800DB3ED1 /* Products */ = { isa = PBXGroup; children = ( @@ -1178,7 +1137,6 @@ 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */, - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, @@ -1436,10 +1394,6 @@ ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */; ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; }, - { - ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; - ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - }, { ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -1561,13 +1515,6 @@ remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTGeolocation.a; - remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; From 676d56e1750bf0f685c63022ea09bd943b08655a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 31 Jul 2019 15:46:34 +0200 Subject: [PATCH 028/636] fix autoscroll for closing and opening and remove creating function in loop --- .../asset-list/RecyclerAssetList.js | 78 ++++++++++++------- .../token-family/TokenFamilyWrap.js | 6 +- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 859e3981e88..2590c850931 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -21,13 +21,14 @@ import { import { withFabSelection, withOpenFamilyTabs } from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; -import { CoinRow, CollectiblesSendRow } from '../coin-row'; +import { CoinRow } from '../coin-row'; import { TokenFamilyHeader } from '../token-family'; import { FloatingActionButton } from '../fab'; import { InvestmentCard, UniswapInvestmentCard } from '../investment-cards'; import { ListFooter } from '../list'; import { UniqueTokenRow } from '../unique-token'; import AssetListHeader from './AssetListHeader'; +import { TokenFamilyWrapPaddingTop } from '../token-family/TokenFamilyWrap'; /* eslint-disable sort-keys */ export const ViewTypes = { @@ -306,35 +307,52 @@ class RecyclerAssetList extends Component { let i = 0; while (i < this.props.openFamilyTabs.length) { if (this.props.openFamilyTabs[i] === true && prev.openFamilyTabs[i] === false) { - // TODO no function creation in while loop - setTimeout(() => { - let collectiblesHeight = 0; - for (let j = 0; j < i; j++) { - if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { - collectiblesHeight += collectibles.data[j].tokens.length * UniqueTokenRow.cardSize + TokenFamilyHeader.height + UniqueTokenRow.rowPadding * (collectibles.data[j].tokens.length - 1); - } else { - collectiblesHeight += TokenFamilyHeader.height; - } - } - const verticalOffset = 17.5; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + (UniswapInvestmentCard.height + InvestmentCard.margin.vertical) * get(investments, 'data.length', 0) + ListFooter.height; - const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; - const renderSize = UniqueTokenRow.cardSize * collectibles.data[i].tokens.length + UniqueTokenRow.rowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; - - if (renderSize >= deviceDimensions) { - const scrollDistance = sectionsHeight - this.position; - this.rlv.scrollToOffset(0, this.position + scrollDistance - verticalOffset, true); + let collectiblesHeight = 0; + for (let j = 0; j < i; j++) { + if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; } else { - const diff = this.position - sectionsHeight + deviceDimensions; - if (renderSize > diff) { - const scrollDistance = deviceDimensions > renderSize ? renderSize - diff : deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 250 : 280); - this.rlv.scrollToOffset(0, this.position + scrollDistance, true); - } + collectiblesHeight += TokenFamilyHeader.height; + } + } + const verticalOffset = 17.5; + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 200 : 235); + const sectionBeforeCollectibles = (AssetListHeader.height * (this.props.sections.length - 1) + + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + + (UniswapInvestmentCard.height + InvestmentCard.margin.vertical) * get(investments, 'data.length', 0) + ListFooter.height); + const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; + const renderSize = collectibles.data[i].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop; + + if (renderSize >= deviceDimensions) { + const scrollDistance = sectionsHeight - this.position; + this.scrollToOffset(this.position + scrollDistance - verticalOffset); + } else { + const diff = this.position - sectionsHeight + deviceDimensions; + if (renderSize > diff) { + const scrollDistance = renderSize - diff; + this.scrollToOffset(this.position + scrollDistance); } - }, 50); + } break; } + if (this.props.openFamilyTabs[i] === false && prev.openFamilyTabs[i] === true) { + const balancesHeight = AssetListHeader.height + CoinRow.height * get(balances, 'data.length', 0); + const investmentHeight = (AssetListHeader.height + (UniswapInvestmentCard.height + + InvestmentCard.margin.vertical) * get(investments, 'data.length', 0)); + let collectiblesHeight = collectibles.data.length > 0 ? AssetListHeader.height : 0; + for (let j = 0; j < collectibles.data.length; j++) { + if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; + } else { + collectiblesHeight += TokenFamilyHeader.height; + } + } + const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 270); + if (this.position + deviceDimensions > renderSize) { + this.scrollToOffset(renderSize - deviceDimensions); + } + } i++; } } @@ -345,6 +363,12 @@ class RecyclerAssetList extends Component { clearInterval(this.interval); }; + scrollToOffset = (position) => { + setTimeout(() => { + this.rlv.scrollToOffset(0, position, true); + }, 50); + } + getStableId = (index) => { const row = get(this.state, `dataProvider._data[${index}]`); if (get(row, 'item.isLastPlaceholder', false)) { @@ -430,9 +454,9 @@ class RecyclerAssetList extends Component { childrenAmount: item.childrenAmount, familyId: item.familyId, familyImage: item.familyImage, - marginTop: type.isFirst ? 4 : 0, familyName: item.familyName, item: item.tokens, + marginTop: type.isFirst ? 4 : 0, shouldPrioritizeImageLoading: index < get(sections, '[0].data.length', 0) + 9, uniqueId: item.uniqueId, }); diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index 423d2844890..77be2ce7427 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -19,6 +19,8 @@ import { FadeInAnimation } from '../animations'; import { UniqueTokenRow } from '../unique-token'; import TokenFamilyHeader from './TokenFamilyHeader'; +export const TokenFamilyWrapPaddingTop = 6; + const EnhancedUniqueTokenRow = compose( withNavigation, withHandlers({ @@ -62,7 +64,7 @@ const TokenFamilyWrap = ({ {times(item.length, renderCollectibleItem)} @@ -78,9 +80,9 @@ TokenFamilyWrap.propTypes = { familyName: PropTypes.string, highlight: PropTypes.bool, isFamilyOpen: PropTypes.bool, - marginTop: PropTypes.number, isOpen: PropTypes.bool, item: PropTypes.array, + marginTop: PropTypes.number, onPressFamilyHeader: PropTypes.func, renderCollectibleItem: PropTypes.func, }; From e653216d3c6e9f889edb33715a624c66c02fec7c Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 31 Jul 2019 15:52:57 +0200 Subject: [PATCH 029/636] fix distance for Xs Max --- src/components/asset-list/RecyclerAssetList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 2590c850931..8d3c8218d57 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -316,7 +316,7 @@ class RecyclerAssetList extends Component { } } const verticalOffset = 17.5; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 200 : 235); + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 200 : 225); const sectionBeforeCollectibles = (AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + CoinRow.height * get(balances, 'data.length', 0) + (UniswapInvestmentCard.height + InvestmentCard.margin.vertical) * get(investments, 'data.length', 0) + ListFooter.height); From f8644cb1a123dac6eee7fb645eecf9df27ab5bdf Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 14:52:58 +0200 Subject: [PATCH 030/636] syncing closing animation and scrolling animation, and alignment in values for distance of closing scroll --- src/components/asset-list/RecyclerAssetList.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 8d3c8218d57..1eee682e114 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -325,12 +325,12 @@ class RecyclerAssetList extends Component { if (renderSize >= deviceDimensions) { const scrollDistance = sectionsHeight - this.position; - this.scrollToOffset(this.position + scrollDistance - verticalOffset); + this.scrollToOffset(this.position + scrollDistance - verticalOffset, true); } else { const diff = this.position - sectionsHeight + deviceDimensions; if (renderSize > diff) { const scrollDistance = renderSize - diff; - this.scrollToOffset(this.position + scrollDistance); + this.scrollToOffset(this.position + scrollDistance, true); } } break; @@ -348,9 +348,13 @@ class RecyclerAssetList extends Component { } } const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 270); + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 160 : 280); if (this.position + deviceDimensions > renderSize) { - this.scrollToOffset(renderSize - deviceDimensions); + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(300, 'easeInEaseOut', 'opacity')); + this.scrollToOffset(renderSize - deviceDimensions, true); + setTimeout(() => { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); + }, 300); } } i++; @@ -363,10 +367,10 @@ class RecyclerAssetList extends Component { clearInterval(this.interval); }; - scrollToOffset = (position) => { + scrollToOffset = (position, animated) => { setTimeout(() => { - this.rlv.scrollToOffset(0, position, true); - }, 50); + this.rlv.scrollToOffset(0, position, animated); + }, 5); } getStableId = (index) => { From f9fec867b7971630661d64fa9da83cf6cd615398 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 15:02:02 +0200 Subject: [PATCH 031/636] little alignment for sync times --- src/components/asset-list/RecyclerAssetList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 1eee682e114..a992bce3462 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -350,7 +350,7 @@ class RecyclerAssetList extends Component { const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 160 : 280); if (this.position + deviceDimensions > renderSize) { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(300, 'easeInEaseOut', 'opacity')); + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); this.scrollToOffset(renderSize - deviceDimensions, true); setTimeout(() => { layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); From b186dbcc90b1d0cb16c655b93bfb6ebbafe334eb Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 15:44:10 +0200 Subject: [PATCH 032/636] add reusable rotate arrow component and make codebase work on it --- src/components/animations/RotationArrow.js | 80 +++++++++++++++ src/components/coin-divider/CoinDivider.js | 43 ++++---- .../investment-cards/InvestmentCardHeader.js | 98 ++++--------------- .../token-family/TokenFamilyHeader.js | 64 +----------- 4 files changed, 118 insertions(+), 167 deletions(-) create mode 100644 src/components/animations/RotationArrow.js diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js new file mode 100644 index 00000000000..3154488a365 --- /dev/null +++ b/src/components/animations/RotationArrow.js @@ -0,0 +1,80 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import Animated, { Easing } from 'react-native-reanimated'; + +const { + block, + Clock, + clockRunning, + concat, + cond, + interpolate, + set, + startClock, + timing, + Value, +} = Animated; + +function runTiming(clock, value, dest, isOpen) { + const state = { + finished: new Value(1), + frameTime: new Value(0), + position: new Value(value), + time: new Value(0), + }; + + const config = { + duration: 200, + easing: Easing.inOut(Easing.ease), + toValue: new Value(0), + }; + + const reset = [ + set(state.finished, 0), + set(state.time, 0), + set(state.frameTime, 0), + ]; + + return block([ + cond(state.finished, [ + ...reset, + set(config.toValue, dest), + ]), + cond(clockRunning(clock), 0, startClock(clock)), + timing(clock, state, config), + state.position, + ]); +} + +class RotationArrow extends React.Component { + componentWillUpdate(prev) { + if (prev.isOpen !== undefined + && prev.isOpen !== this.props.isOpen) { + const clock = new Clock(); + const base = this.props.isOpen ? runTiming(clock, -1, 1, this.props.isOpen) : runTiming(clock, 1, -1, this.props.isOpen); + this._rotation = interpolate(base, { + inputRange: [-1, 1], + outputRange: [this.props.endingPosition, this.props.startingPosition], + }); + } + } + + render() { + return ( + + {this.props.children} + + ); + } +} + +RotationArrow.propTypes = { + children: PropTypes.any, + endingPosition: PropTypes.number, + isOpen: PropTypes.bool, + startingPosition: PropTypes.number, +}; + +export default RotationArrow; diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 425e9fa6028..d0cc4cd3f1b 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -4,6 +4,7 @@ import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; import Animated from 'react-native-reanimated'; import { compose } from 'recompact'; +import FastImage from 'react-native-fast-image'; import { colors, fonts, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { deviceUtils } from '../../utils'; @@ -12,6 +13,8 @@ import { Centered } from '../layout'; import { Monospace } from '../text'; import { withFabSendAction } from '../../hoc'; import Highlight from '../Highlight'; +import RotationArrow from '../animations/RotationArrow'; +import Caret from '../../assets/family-dropdown-arrow.png'; const marginLeft = 15; const marginRight = 19; @@ -46,6 +49,15 @@ const Header = styled(Text)` opacity: 0.6; `; +const SettingIconWrap = styled(View)` + opacity: 0.6; +`; + +const SettingIcon = styled(FastImage)` + height: 17px; + width: 8px; +`; + const enhance = compose( withFabSendAction, ); @@ -60,33 +72,14 @@ const CoinDivider = enhance(({ -
+
{openSmallBalances ? 'Less' : 'All'}
- - - - - - - + + + + + {!openSmallBalances diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index 28067861bdd..da620da184a 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -1,16 +1,17 @@ import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components/primitives'; -import Animated, { Easing } from 'react-native-reanimated'; -import { colors, padding, position } from '../../styles'; -import { Icon } from '../icons'; +import FastImage from 'react-native-fast-image'; +import { View } from 'react-native'; +import { colors, padding } from '../../styles'; import { - Centered, Column, Row, RowWithMargins, } from '../layout'; import { Emoji, Monospace, Text } from '../text'; +import RotationArrow from '../animations/RotationArrow'; +import Caret from '../../assets/family-dropdown-arrow.png'; const HeaderHeight = 48; @@ -22,63 +23,16 @@ const Container = styled(Row).attrs({ height: ${HeaderHeight}; `; -const { - block, - Clock, - clockRunning, - concat, - cond, - interpolate, - set, - startClock, - timing, - Value, -} = Animated; - -function runTiming(clock, value, dest, isOpen) { - const state = { - finished: new Value(1), - frameTime: new Value(0), - position: new Value(value), - time: new Value(0), - }; - - const config = { - duration: 200, - easing: Easing.inOut(Easing.ease), - toValue: new Value(0), - }; - - const reset = [ - set(state.finished, 0), - set(state.time, 0), - set(state.frameTime, 0), - ]; +const SettingIconWrap = styled(View)` + padding-left: 10px; +`; - return block([ - cond(state.finished, [ - ...reset, - set(config.toValue, dest), - ]), - cond(clockRunning(clock), 0, startClock(clock)), - timing(clock, state, config), - state.position, - ]); -} +const SettingIcon = styled(FastImage)` + height: 13.5px; + width: 6.5px; +`; class InvestmentCardHeader extends React.Component { - componentWillUpdate(prev) { - if (prev.collapsed !== undefined - && prev.collapsed !== this.props.collapsed) { - const clock = new Clock(); - const base = this.props.collapsed ? runTiming(clock, -1, 1, this.props.collapsed) : runTiming(clock, 1, -1, this.props.collapsed); - this._rotation = interpolate(base, { - inputRange: [-1, 1], - outputRange: [0, 90], - }); - } - } - render() { const { collapsed, @@ -122,29 +76,11 @@ class InvestmentCardHeader extends React.Component { {value} {isCollapsible && ( - - - - - - - + + + + + )} diff --git a/src/components/token-family/TokenFamilyHeader.js b/src/components/token-family/TokenFamilyHeader.js index c329406b030..91213042e96 100644 --- a/src/components/token-family/TokenFamilyHeader.js +++ b/src/components/token-family/TokenFamilyHeader.js @@ -9,6 +9,7 @@ import { ButtonPressAnimation } from '../animations'; import Highlight from '../Highlight'; import { ShadowStack } from '../shadow-stack'; import { TruncatedText, Monospace } from '../text'; +import RotationArrow from '../animations/RotationArrow'; const Wrapper = styled.View` height: 56px; @@ -44,64 +45,7 @@ const SettingIcon = styled(FastImage)` width: 9px; `; -const { - block, - Clock, - clockRunning, - concat, - cond, - interpolate, - set, - startClock, - timing, - Value, -} = Animated; - -function runTiming(clock, value, dest, isOpen) { - const state = { - finished: new Value(1), - frameTime: new Value(0), - position: new Value(value), - time: new Value(0), - }; - - const config = { - duration: 200, - easing: Easing.inOut(Easing.ease), - toValue: new Value(0), - }; - - const reset = [ - set(state.finished, 0), - set(state.time, 0), - set(state.frameTime, 0), - ]; - - return block([ - cond(state.finished, [ - ...reset, - set(config.toValue, dest), - ]), - cond(clockRunning(clock), 0, startClock(clock)), - timing(clock, state, config), - state.position, - ]); -} - class TokenListHeader extends React.Component { - componentWillUpdate(prev) { - if (prev.isOpen !== undefined - && prev.isOpen !== this.props.isOpen) { - const clock = new Clock(); - let base = undefined; - this.props.isOpen ? base = runTiming(clock, -1, 1, this.props.isOpen) : base = runTiming(clock, 1, -1, this.props.isOpen); - this._rotation = interpolate(base, { - inputRange: [-1, 1], - outputRange: [90, 0], - }); - } - } - render() { dimension = this.props.isCoinRow ? 40 : 34; padding = this.props.isCoinRow ? 16 : 19; @@ -144,11 +88,9 @@ class TokenListHeader extends React.Component { {this.props.familyName} - + - + {!this.props.isOpen && From 6f707902ff25829459a1b903084496d5150a744b Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 16:22:37 +0200 Subject: [PATCH 033/636] change animation, and minor design tweaks, add handling for no small balances --- src/components/asset-list/RecyclerAssetList.js | 10 +++++++--- src/components/coin-divider/CoinDivider.js | 4 ++-- src/components/coin-divider/SmallBalancesWrapper.js | 8 +++++--- .../investment-cards/InvestmentCardHeader.js | 2 +- src/helpers/assets.js | 5 ++++- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 98ce3d76f73..77dfe8b9df9 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -344,9 +344,13 @@ class RecyclerAssetList extends PureComponent { let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); - balancesHeight += CoinDivider.height + ListFooter.height; - if (this.props.openSmallBalances) { - balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; + if (balances.data[balances.data.length - 1].smallBalancesContainer) { + balancesHeight += CoinDivider.height + ListFooter.height; + if (this.props.openSmallBalances) { + balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; + } + } else { + balancesHeight += CoinRow.height + ListFooter.height; } } const verticalOffset = 10; diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index d0cc4cd3f1b..414b7bb40d2 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -72,10 +72,10 @@ const CoinDivider = enhance(({ -
+
{openSmallBalances ? 'Less' : 'All'}
- + diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 71dd24f3a82..d356dcdc4ef 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -30,9 +30,11 @@ const SmallBalancesWrapper = ({ const ref = useRef(); const onPress = () => { - ref.current.animateNextTransition(); - setHeight(!openSmallBalances ? (CoinRow.height * assets.length) : 0); - setOpenSmallBalances(!openSmallBalances); + if (ref.current) { + ref.current.animateNextTransition(); + setHeight(!openSmallBalances ? (CoinRow.height * assets.length) : 0); + setOpenSmallBalances(!openSmallBalances); + } }; if (openSmallBalances && height === 0) { diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index da620da184a..98097844fad 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -77,7 +77,7 @@ class InvestmentCardHeader extends React.Component { {isCollapsible && ( - + diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 76d072a91ff..7c4b561048a 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -36,7 +36,10 @@ export const buildCoinsList = (assets) => { } } - return newAssets.concat(smallBalances); + if (smallBalances.assets.length > 0) { + return newAssets.concat(smallBalances); + } + return newAssets; }; export const buildUniqueTokenList = (uniqueTokens) => { From c2913e01c7cdf4dce19ff1495279be43b0e14b7b Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 16:33:38 +0200 Subject: [PATCH 034/636] initial removal of show shitcoins --- src/components/asset-list/AssetListHeader.js | 2 +- .../coin-divider/SmallBalancesWrapper.js | 6 ++++-- src/handlers/commonStorage.js | 18 ---------------- src/helpers/buildWalletSections.js | 21 +------------------ src/screens/WalletScreen.js | 15 ------------- 5 files changed, 6 insertions(+), 56 deletions(-) diff --git a/src/components/asset-list/AssetListHeader.js b/src/components/asset-list/AssetListHeader.js index a413a3391f9..c8cf96d88a3 100644 --- a/src/components/asset-list/AssetListHeader.js +++ b/src/components/asset-list/AssetListHeader.js @@ -13,7 +13,7 @@ const AssetListHeader = enhance(({ totalValue, ...props }) => ( - + {totalValue ? ( {totalValue} diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index d356dcdc4ef..cc8f3595919 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -38,8 +38,10 @@ const SmallBalancesWrapper = ({ }; if (openSmallBalances && height === 0) { - ref.current.animateNextTransition(); - setHeight(CoinRow.height * assets.length); + if (ref.current) { + ref.current.animateNextTransition(); + setHeight(CoinRow.height * assets.length); + } } return ( diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 2ad77608fb6..884996fa321 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -353,24 +353,6 @@ export const saveLanguage = async language => { await saveLocal('language', { data: language }); }; -/** - * @desc get show shitcoins setting - * @return {True|False} - */ -export const getShowShitcoinsSetting = async () => { - const showShitcoins = await getLocal('showShitcoins'); - return showShitcoins ? showShitcoins.data : null; -}; - -/** - * @desc update show shitcoins setting - * @param {Boolean} [updatedSetting] - * @return {Void} - */ -export const updateShowShitcoinsSetting = async (updatedSetting) => { - await saveLocal('showShitcoins', { data: updatedSetting }); -}; - const isRequestStillValid = (request) => { const createdAt = request.displayDetails.timestampInMs; return (differenceInMinutes(Date.now(), createdAt) < 60); diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index afb2bc3d853..3a3462ebc1e 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -72,9 +72,8 @@ const buildWalletSections = ( const sections = [ { balances: true, - data: showShitcoins ? buildCoinsList(allAssets) : assets, + data: buildCoinsList(allAssets), header: { - showShitcoins, title: lang.t('account.tab_balances'), totalItems: allAssetsCount, totalValue: get(assetsTotal, 'display', ''), @@ -119,24 +118,6 @@ const buildWalletSections = ( FastImage.preload(imageTokens); - if (shitcoinsCount) { - // 99 is an arbitrarily high number used to disable the 'destructiveButton' option - const destructiveButtonIndex = showShitcoins ? 0 : 99; - - const index = findIndex(sections, (section) => section.balances === true); - if (index > -1) { - sections[index].header.contextMenuOptions = { - cancelButtonIndex: 1, - destructiveButtonIndex, - onPressActionSheet: onToggleShowShitcoins, - options: [ - `${lang.t(`account.${showShitcoins ? 'hide' : 'show'}`)} ${lang.t('wallet.assets.no_price')}`, - lang.t('wallet.action.cancel'), - ], - }; - } - } - const filteredSections = filterWalletSections(sections); const isEmpty = !filteredSections.length; diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 6bd28e7a5cd..267a00767da 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -21,10 +21,6 @@ import { } from '../components/header'; import { Page } from '../components/layout'; import buildWalletSectionsSelector from '../helpers/buildWalletSections'; -import { - getShowShitcoinsSetting, - updateShowShitcoinsSetting, -} from '../handlers/commonStorage'; import { withAccountData, withAccountSettings, @@ -58,17 +54,6 @@ class WalletScreen extends Component { uniqueTokens: PropTypes.array, } - componentDidMount = async () => { - try { - const showShitcoins = await getShowShitcoinsSetting(); - if (showShitcoins !== null) { - this.props.toggleShowShitcoins(showShitcoins); - } - } catch (error) { - // TODO - } - } - shouldComponentUpdate = (nextProps) => { const isNewBlurOpacity = isNewValueForPath(this.props, nextProps, 'blurOpacity'); const isNewCurrency = isNewValueForPath(this.props, nextProps, 'nativeCurrency'); From bd64f683480f557eee2a611fbe780d14569a75e7 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 16:34:22 +0200 Subject: [PATCH 035/636] complete removal of show showShitcoin logic --- src/components/asset-list/AssetListHeader.js | 4 +--- .../asset-list/RecyclerAssetList.js | 3 +-- src/helpers/assets.js | 3 +-- src/helpers/buildWalletSections.js | 8 +------- src/screens/WalletScreen.js | 19 ------------------- 5 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/components/asset-list/AssetListHeader.js b/src/components/asset-list/AssetListHeader.js index c8cf96d88a3..77b20a8e62f 100644 --- a/src/components/asset-list/AssetListHeader.js +++ b/src/components/asset-list/AssetListHeader.js @@ -5,10 +5,9 @@ import Divider from '../Divider'; import { Monospace } from '../text'; import { ListHeader } from '../list'; -const enhance = onlyUpdateForKeys(['showShitcoins', 'title', 'totalValue']); +const enhance = onlyUpdateForKeys(['title', 'totalValue']); const AssetListHeader = enhance(({ - showShitcoins, title, totalValue, ...props @@ -23,7 +22,6 @@ const AssetListHeader = enhance(({ )); AssetListHeader.propTypes = { - showShitcoins: PropTypes.bool, title: PropTypes.string, totalValue: PropTypes.string, }; diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 77dfe8b9df9..5cb7fb98d49 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -68,12 +68,11 @@ const AssetListHeaderRenderer = pure(data => ); const hasRowChanged = (r1, r2) => { if (has(r1, 'isHeader')) { - const isNewShowShitcoinsValue = isNewValueForPath(r1, r2, 'showShitcoins'); const isNewTitle = isNewValueForPath(r1, r2, 'title'); const isNewTotalItems = isNewValueForPath(r1, r2, 'totalItems'); const isNewTotalValue = isNewValueForPath(r1, r2, 'totalValue'); - return isNewShowShitcoinsValue || isNewTitle || isNewTotalItems || isNewTotalValue; + return isNewTitle || isNewTotalItems || isNewTotalValue; } const isNewAsset = isNewValueForPath(r1, r2, 'item.uniqueId'); diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 7c4b561048a..9df55c20b6d 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -8,11 +8,10 @@ import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; import store from '../redux/store'; export const buildAssetHeaderUniqueIdentifier = ({ - showShitcoins, title, totalItems, totalValue, -}) => ([showShitcoins, title, totalItems, totalValue].join('_')); +}) => ([title, totalItems, totalValue].join('_')); export const buildAssetUniqueIdentifier = (item) => { const balance = get(item, 'balance.amount', ''); diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index 3a3462ebc1e..5625e1a09ad 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -4,11 +4,11 @@ import React from 'react'; import { withNavigation } from 'react-navigation'; import { compose, withHandlers } from 'recompact'; import { createSelector } from 'reselect'; +import FastImage from 'react-native-fast-image'; import { BalanceCoinRow } from '../components/coin-row'; import { UniswapInvestmentCard } from '../components/investment-cards'; import { TokenFamilyWrap } from '../components/token-family'; import { buildUniqueTokenList, buildCoinsList } from './assets'; -import FastImage from 'react-native-fast-image'; const allAssetsSelector = state => state.allAssets; const allAssetsCountSelector = state => state.allAssetsCount; @@ -16,10 +16,8 @@ const assetsSelector = state => state.assets; const assetsTotalSelector = state => state.assetsTotal; const languageSelector = state => state.language; const nativeCurrencySelector = state => state.nativeCurrency; -const onToggleShowShitcoinsSelector = state => state.onToggleShowShitcoins; const setIsWalletEmptySelector = state => state.setIsWalletEmpty; const shitcoinsCountSelector = state => state.shitcoinsCount; -const showShitcoinsSelector = state => state.showShitcoins; const uniqueTokensSelector = state => state.uniqueTokens; const uniswapSelector = state => state.uniswap; const uniswapTotalSelector = state => state.uniswapTotal; @@ -61,10 +59,8 @@ const buildWalletSections = ( assetsTotal, language, nativeCurrency, - onToggleShowShitcoins, setIsWalletEmpty, shitcoinsCount, - showShitcoins, uniqueTokens = [], uniswap = [], uniswapTotal, @@ -138,10 +134,8 @@ export default createSelector( assetsTotalSelector, languageSelector, nativeCurrencySelector, - onToggleShowShitcoinsSelector, setIsWalletEmptySelector, shitcoinsCountSelector, - showShitcoinsSelector, uniqueTokensSelector, uniswapSelector, uniswapTotalSelector, diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 267a00767da..aaa6a3d4614 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -50,7 +50,6 @@ class WalletScreen extends Component { sections: PropTypes.array, setSafeTimeout: PropTypes.func, showBlur: PropTypes.bool, - toggleShowShitcoins: PropTypes.func, uniqueTokens: PropTypes.array, } @@ -63,7 +62,6 @@ class WalletScreen extends Component { const isNewLanguage = isNewValueForPath(this.props, nextProps, 'language'); const isNewSections = isNewValueForPath(this.props, nextProps, 'sections'); const isNewShowBlur = isNewValueForPath(this.props, nextProps, 'showBlur'); - const isNewShowShitcoins = isNewValueForPath(this.props, nextProps, 'showShitcoins'); const isNewTransitionProps = isNewValueForPath(this.props, nextProps, 'transitionProps'); if (!nextProps.isFocused && !nextProps.showBlur) { @@ -79,7 +77,6 @@ class WalletScreen extends Component { || isNewCurrency || isNewBlurOpacity || isNewSections - || isNewShowShitcoins || isNewTransitionProps || isNewShowBlur; } @@ -149,22 +146,6 @@ export default compose( withBlurTransitionProps, withIsWalletEmpty, withStatusBarStyle('dark-content'), - withState('showShitcoins', 'toggleShowShitcoins', true), - withHandlers({ - onToggleShowShitcoins: ({ showShitcoins, toggleShowShitcoins }) => (index) => { - if (index === 0) { - const updatedShowShitcoinsSetting = !showShitcoins; - toggleShowShitcoins(updatedShowShitcoinsSetting); - updateShowShitcoinsSetting(updatedShowShitcoinsSetting); - - if (updatedShowShitcoinsSetting) { - analytics.track('Showed shitcoins'); - } else { - analytics.track('Hid shitcoins'); - } - } - }, - }), withProps(buildWalletSectionsSelector), withProps({ scrollViewTracker: new Animated.Value(0) }), )(WalletScreen); From f5b2eacddce3d67f42154452819109941797080c Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 17:04:25 +0200 Subject: [PATCH 036/636] add white background to avoid overflow --- src/components/investment-cards/InvestmentCard.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 687617bf46e..ccf76c1e140 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -47,6 +47,7 @@ const InvestmentCard = ({ > + > Date: Thu, 1 Aug 2019 12:25:02 -0700 Subject: [PATCH 037/636] version bump --- ios/Rainbow/Info.plist | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index e7d3c69e400..fdd8318f7d2 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.1.4 + 1.1.5 CFBundleSignature ???? CFBundleURLTypes @@ -34,7 +34,7 @@ CFBundleVersion - 3 + 1 CodePushDeploymentKey $(CODEPUSH_KEY) ITSAppUsesNonExemptEncryption diff --git a/package.json b/package.json index ecb95543107..3c7fc570587 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.1.4-3", + "version": "1.1.5-1", "private": true, "scripts": { "clean": "react-native-clean-project", From 10aa77ef9d8e8ebefa2c6b7fec4464ce9d81c147 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 2 Aug 2019 14:16:06 +0200 Subject: [PATCH 038/636] add opacity toggler for coin divider --- src/components/animations/OpacityToggler.js | 86 +++++++++++++++++++ src/components/coin-divider/CoinDivider.js | 35 ++++---- .../coin-divider/SmallBalancesWrapper.js | 19 ++-- .../token-family/TokenFamilyWrap.js | 3 +- 4 files changed, 118 insertions(+), 25 deletions(-) create mode 100644 src/components/animations/OpacityToggler.js diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js new file mode 100644 index 00000000000..764749bc725 --- /dev/null +++ b/src/components/animations/OpacityToggler.js @@ -0,0 +1,86 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import Animated, { Easing } from 'react-native-reanimated'; + +const { + block, + Clock, + clockRunning, + cond, + interpolate, + set, + startClock, + timing, + Value, +} = Animated; + +function runTiming(clock, value, dest, duration) { + const state = { + finished: new Value(1), + frameTime: new Value(0), + position: new Value(value), + time: new Value(0), + }; + + const config = { + duration, + easing: Easing.inOut(Easing.ease), + toValue: new Value(0), + }; + + const reset = [ + set(state.finished, 0), + set(state.time, 0), + set(state.frameTime, 0), + ]; + + return block([ + cond(state.finished, [ + ...reset, + set(config.toValue, dest), + ]), + cond(clockRunning(clock), 0, startClock(clock)), + timing(clock, state, config), + state.position, + ]); +} + +class OpacityToggler extends React.Component { + componentWillUpdate(prev) { + if (prev.isVisible !== undefined + && prev.isVisible !== this.props.isVisible) { + const clock = new Clock(); + const base = this.props.isVisible ? runTiming(clock, -1, 1, this.props.duration) : runTiming(clock, 1, -1, this.props.duration); + this._opacity = interpolate(base, { + inputRange: [-1, 1], + outputRange: [this.props.endingOpacity, this.props.startingOpacity], + }); + } + } + + render() { + return ( + + {this.props.children} + + ); + } +} + +OpacityToggler.propTypes = { + children: PropTypes.any, + duration: PropTypes.number, + endingOpacity: PropTypes.number, + isVisible: PropTypes.bool, + startingOpacity: PropTypes.number, +}; + +OpacityToggler.defaultProps = { + duration: 200, + endingOpacity: 0, + startingOpacity: 1, +}; + +export default OpacityToggler; diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 414b7bb40d2..465e9914b84 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -2,19 +2,17 @@ import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; -import Animated from 'react-native-reanimated'; import { compose } from 'recompact'; import FastImage from 'react-native-fast-image'; -import { colors, fonts, position } from '../../styles'; +import { colors, fonts } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { deviceUtils } from '../../utils'; -import { Icon } from '../icons'; -import { Centered } from '../layout'; import { Monospace } from '../text'; import { withFabSendAction } from '../../hoc'; import Highlight from '../Highlight'; import RotationArrow from '../animations/RotationArrow'; import Caret from '../../assets/family-dropdown-arrow.png'; +import OpacityToggler from '../animations/OpacityToggler'; const marginLeft = 15; const marginRight = 19; @@ -72,9 +70,16 @@ const CoinDivider = enhance(({ -
- {openSmallBalances ? 'Less' : 'All'} -
+ +
+ All +
+
+ +
+ Less +
+
@@ -82,14 +87,14 @@ const CoinDivider = enhance(({
- {!openSmallBalances - && - {balancesSum} - - } + + + {balancesSum} + + )); diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index cc8f3595919..844467ba51d 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -24,7 +24,13 @@ const SmallBalancesWrapper = ({ assets, ...props }) => { - const transition = ; + const transition = ( + + + + + + ); const [height, setHeight] = useState(0); const ref = useRef(); @@ -51,16 +57,11 @@ const SmallBalancesWrapper = ({ transition={transition} > - - + {openSmallBalances + && {assets} - + } ); diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index 90976bd6b7b..f5162cec9b7 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -12,6 +12,7 @@ import { withOpenFamilyTabs, withFabSendAction } from '../../hoc'; import { UniqueTokenRow } from '../unique-token'; import TokenFamilyHeader from './TokenFamilyHeader'; import { FadeInAnimation } from '../animations'; +import { colors } from '../../styles'; const enhanceRenderItem = compose( withNavigation, @@ -95,7 +96,7 @@ class TokenFamilyWrap extends Component { render() { return ( - + Date: Fri, 2 Aug 2019 17:09:33 +0200 Subject: [PATCH 039/636] replace Easing animation with spring animation for rotation arrow --- src/components/animations/RotationArrow.js | 19 +++++++-------- src/components/send/SendAssetList.js | 27 ++++++++++++---------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index 3154488a365..8f900e2c9d8 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -11,28 +11,29 @@ const { interpolate, set, startClock, - timing, + spring, Value, + SpringUtils, } = Animated; function runTiming(clock, value, dest, isOpen) { const state = { finished: new Value(1), - frameTime: new Value(0), position: new Value(value), time: new Value(0), + velocity: new Value(0), }; - const config = { - duration: 200, - easing: Easing.inOut(Easing.ease), - toValue: new Value(0), - }; + const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + ...SpringUtils.makeDefaultConfig(), + friction: 20, + tension: 200, + }); const reset = [ set(state.finished, 0), set(state.time, 0), - set(state.frameTime, 0), + set(state.velocity, 0), ]; return block([ @@ -41,7 +42,7 @@ function runTiming(clock, value, dest, isOpen) { set(config.toValue, dest), ]), cond(clockRunning(clock), 0, startClock(clock)), - timing(clock, state, config), + spring(clock, state, config), state.position, ]); } diff --git a/src/components/send/SendAssetList.js b/src/components/send/SendAssetList.js index 2f6b3f2c655..233f4093406 100644 --- a/src/components/send/SendAssetList.js +++ b/src/components/send/SendAssetList.js @@ -42,15 +42,16 @@ class SendAssetList extends React.Component { ); TokenItem = React.memo(this.enhanceRenderItem(SendCoinRow)); + UniqueTokenItem = React.memo(this.enhanceRenderItem(CollectiblesSendRow)); rlv = React.createRef(); changeOpenTab = (index) => { - let openCards = this.state.openCards; + const { openCards } = this.state; LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); openCards[index] = !openCards[index]; - this.setState({ openCards: openCards }); + this.setState({ openCards }); let familiesHeight = 0; if (openCards[index]) { for (let i = 0; i < index; i++) { @@ -79,8 +80,8 @@ class SendAssetList extends React.Component { } mapTokens = (collectibles) => { - items = collectibles.map((collectible) => { - let newItem = {} + const items = collectibles.map((collectible) => { + const newItem = {}; newItem.item = collectible; return ; }); @@ -88,12 +89,14 @@ class SendAssetList extends React.Component { } balancesRenderItem = item => ; - balancesRenderLastItem = item => {return <> - - - + + balancesRenderLastItem = item => { + return <> + + + ; }; - + collectiblesRenderItem = item => { return { this.changeOpenTab(item.familyId) }} + onHeaderPress={() => { this.changeOpenTab(item.familyId); }} /> {this.state.openCards[item.familyId] && this.mapTokens(item.data)} - + ; } constructor(args) { @@ -136,7 +139,7 @@ class SendAssetList extends React.Component { } else if (i == this.props.allAssets.length - 1) { return 'COIN_ROW_LAST'; } else { - if (this.state.openCards[i - this.props.allAssets.length]) { + if (this.state.openCards[this.props.uniqueTokens[i - this.props.allAssets.length].familyId]) { return { type: 'COLLECTIBLE_ROW', size: this.props.uniqueTokens[i - this.props.allAssets.length].data.length + 1 }; } else { return 'COLLECTIBLE_ROW_CLOSED'; From e75f382b2fcf7f3ad52a89605c7071aa84e9ba00 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 3 Aug 2019 21:46:07 +0200 Subject: [PATCH 040/636] fix stable id/type issue, and add fixes to small balances logic --- .../asset-list/RecyclerAssetList.js | 53 ++++++++++++------- src/helpers/assets.js | 8 +-- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 5cb7fb98d49..f98f5867728 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -15,10 +15,6 @@ import { } from 'recyclerlistview'; import StickyContainer from 'recyclerlistview/dist/reactnative/core/StickyContainer'; import styled from 'styled-components/primitives'; -import { - buildAssetHeaderUniqueIdentifier, - buildAssetUniqueIdentifier, -} from '../../helpers/assets'; import { withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; @@ -35,6 +31,7 @@ export const ViewTypes = { COIN_ROW: 1, // eslint-disable-line sort-keys COIN_ROW_LAST: 2, COIN_SMALL_BALANCES: 3, + FOOTER: 11, UNIQUE_TOKEN_ROW: 4, UNIQUE_TOKEN_ROW_CLOSED: 5, UNIQUE_TOKEN_ROW_CLOSED_LAST: 6, @@ -44,7 +41,6 @@ export const ViewTypes = { UNISWAP_ROW_CLOSED: 9, UNISWAP_ROW_CLOSED_LAST: 10, UNISWAP_ROW_LAST: 8, - FOOTER: 11, }; const Wrapper = styled.View` @@ -149,7 +145,7 @@ class RecyclerAssetList extends PureComponent { this.layoutProvider = new LayoutProvider( index => { const { - openFamilyTabs, openInvestmentCards, openSmallBalances, sections, + openFamilyTabs, openInvestmentCards, sections, } = this.props; const { headersIndices } = this.state; if (headersIndices.includes(index)) { @@ -169,10 +165,7 @@ class RecyclerAssetList extends PureComponent { const lastBalanceIndex = headersIndices[balancesIndex] + balanceItemsCount; if (index === lastBalanceIndex) { if (sections[balancesIndex].data[lastBalanceIndex - 1].smallBalancesContainer) { - return { - get: ViewTypes.COIN_SMALL_BALANCES, - size: openSmallBalances ? get(sections, `[${balancesIndex}].data[${lastBalanceIndex - 1}].assets`, []).length : 0, - }; + return ViewTypes.COIN_SMALL_BALANCES; } return ViewTypes.COIN_ROW_LAST; } @@ -239,9 +232,11 @@ class RecyclerAssetList extends PureComponent { } else if (type.get === ViewTypes.UNIQUE_TOKEN_ROW_CLOSED) { dim.height = 54 + (type.isLast ? 90 : 0); } else if (type === ViewTypes.COIN_ROW_LAST) { - dim.height = this.state.areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height - 1; - } else if (type.get === ViewTypes.COIN_SMALL_BALANCES) { - dim.height = this.state.areSmallCollectibles ? CoinDivider.height + (type.size * CoinRow.height) : CoinDivider.height + (type.size * CoinRow.height) + ListFooter.height - 1; + dim.height = this.state.areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height; + } else if (type === ViewTypes.COIN_SMALL_BALANCES) { + const balancesIndex = findIndex(this.props.sections, ({ name }) => name === 'balances'); + const size = this.props.sections[balancesIndex].data[this.props.sections[balancesIndex].data.length - 1].assets.length; + dim.height = this.props.openSmallBalances ? CoinDivider.height + (size * CoinRow.height) + ListFooter.height : CoinDivider.height + ListFooter.height; } else if (type === ViewTypes.COIN_ROW) { dim.height = CoinRow.height; } else if (type === ViewTypes.UNISWAP_ROW_LAST) { @@ -405,13 +400,32 @@ class RecyclerAssetList extends PureComponent { getStableId = (index) => { const row = get(this.state, `dataProvider._data[${index}]`); - if (get(row, 'item.isLastPlaceholder', false)) { - return 'isLastPlaceholder'; + let stableId; + if (row.isHeader) { + return `header_${row.title}`; + } + + if (row.item && row.item.address) { + return `balance_${row.item.address}`; + } + + if (row.item && row.item.uniqueId) { + return `investment_${row.item.uniqueId}`; + } + + if (row.item && row.item.familyName) { + return `family_${row.item.familyName}`; + } + + if (row.item && row.item.smallBalancesContainer) { + return `balance_${row.item.stableId}`; + } + + if (index === this.state.dataProvider._data.length - 1) { + return 'footer'; } - return has(row, 'isHeader') - ? buildAssetHeaderUniqueIdentifier(row) - : buildAssetUniqueIdentifier(row.item); + return stableId; }; handleRefresh = () => { @@ -444,7 +458,7 @@ class RecyclerAssetList extends PureComponent { return hideHeader ? null : ; } - if (type.get === ViewTypes.COIN_SMALL_BALANCES) { + if (type === ViewTypes.COIN_SMALL_BALANCES) { const renderList = []; for (let i = 0; i < item.assets.length; i++) { const selectedItem = { item: item.assets[i] }; @@ -492,7 +506,6 @@ class RecyclerAssetList extends PureComponent { {...props} layoutProvider={this.layoutProvider} dataProvider={dataProvider} - extendedState={{ headersIndices }} renderAheadOffset={renderAheadOffset} itemAnimator={layoutItemAnimator} rowRenderer={this.rowRenderer} diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 9df55c20b6d..295c0b7c79a 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -28,15 +28,16 @@ export const buildCoinsList = (assets) => { smallBalancesContainer: true, }; for (let i = 0; i < assets.length; i++) { - if (assets[i].native && assets[i].native.balance.amount > 1) { + if ((assets[i].native && assets[i].native.balance.amount > 1) || assets.address === 'eth' || assets.length < 4) { newAssets.push(assets[i]); - } else { + } else if (assets[i].native && assets[i].native.balance.amount <= 1) { smallBalances.assets.push(assets[i]); } } if (smallBalances.assets.length > 0) { - return newAssets.concat(smallBalances); + newAssets.push(smallBalances); + return newAssets; } return newAssets; }; @@ -59,6 +60,7 @@ export const buildUniqueTokenList = (uniqueTokens) => { childrenAmount: grouped[families[i]].length, familyImage: get(tokensRow, '[0][0].familyImage', null), familyName: families[i], + stableId: tokensRow[0].map(({ uniqueId }) => uniqueId).join('__'), tokens, uniqueId: tokensRow[0].map(({ uniqueId }) => uniqueId).join('__'), }); From 9fa3a32648a260ea700d12ad87c3a83bf9b487aa Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 3 Aug 2019 21:57:33 +0200 Subject: [PATCH 041/636] make eth always visible in balances --- src/helpers/assets.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 295c0b7c79a..6722a57cbcc 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -28,9 +28,9 @@ export const buildCoinsList = (assets) => { smallBalancesContainer: true, }; for (let i = 0; i < assets.length; i++) { - if ((assets[i].native && assets[i].native.balance.amount > 1) || assets.address === 'eth' || assets.length < 4) { + if ((assets[i].native && assets[i].native.balance.amount > 1) || assets[i].address === 'eth' || assets.length < 4) { newAssets.push(assets[i]); - } else if (assets[i].native && assets[i].native.balance.amount <= 1) { + } else { smallBalances.assets.push(assets[i]); } } From a7831e1008b06843c62f23f152fcce3193e33553 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 3 Aug 2019 22:59:04 +0200 Subject: [PATCH 042/636] hid coins with no balance --- src/helpers/assets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 6722a57cbcc..f38ec60bc7e 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -30,7 +30,7 @@ export const buildCoinsList = (assets) => { for (let i = 0; i < assets.length; i++) { if ((assets[i].native && assets[i].native.balance.amount > 1) || assets[i].address === 'eth' || assets.length < 4) { newAssets.push(assets[i]); - } else { + } else if (assets[i].native && assets[i].native.balance.amount <= 1) { smallBalances.assets.push(assets[i]); } } From 90f7bcea1d8642aeedf706a9002ad7728561a88f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Sat, 3 Aug 2019 23:15:16 -0400 Subject: [PATCH 043/636] Design adjustments --- src/assets/show-all-arrow.png | Bin 0 -> 470 bytes src/assets/show-all-arrow@2x.png | Bin 0 -> 908 bytes src/assets/show-all-arrow@3x.png | Bin 0 -> 1372 bytes .../asset-list/RecyclerAssetList.js | 8 +++--- src/components/coin-divider/CoinDivider.js | 26 ++++++++++-------- .../coin-row/CollectiblesSendRow.js | 2 +- src/styles/colors.js | 3 +- 7 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 src/assets/show-all-arrow.png create mode 100644 src/assets/show-all-arrow@2x.png create mode 100644 src/assets/show-all-arrow@3x.png diff --git a/src/assets/show-all-arrow.png b/src/assets/show-all-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..2f510be4f86be7b36c8e50fb9088e77875624331 GIT binary patch literal 470 zcmV;{0V)28P)3M2aSJw=Q_wsmuc-Cy(f#XZ7_a~)=D$o#4F4G<85kL+*t!I} zV^PDv{P6y@Cko2ijQ{`tcVzs};G?Xrv*E#=Yj2SiGlDok1&nqsA*+FOFe4+wEoNRm z^8*_ee1Iur0x=jF8UG7#3C95$7ykceQ2YDo^UBcBP-YZGAkOB^v%YaKGWi4D_Ub>w zf43L!|MtKX!Bv9y!IMD1Epl7TVl(il|ym$RP*iA4UFxt)~IO*TN|8s%X z|6*Zhl1DKKrU;}P7;dgWFDd@}&u|XxaF`^F2AKqOmo?ZVR;K+Jifmnjtbw|xgETNP zGGrduw)zE%A{UoXx&Qwd)&T>Kjgg6A!l6BD=YbW&tnl?sA#L!6H{eD&(pe_@KizT1EFY6DPVCNMlcu&^;ZAK0?&DNF%~ zX0&$>wfy`4?@?gX`~!xz_u)NjcOokQv6+BA`3sbM4s=TnHU%I>05tuT2bHt>-2eap M07*qoM6N<$f*GsSg8%>k literal 0 HcmV?d00001 diff --git a/src/assets/show-all-arrow@2x.png b/src/assets/show-all-arrow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b991867e1d3c5a20f1ed955b9036856a63e013ce GIT binary patch literal 908 zcmV;719SX|P)22aL4YHPS*yb4F{^EE>hgD6tqa z=x5j8#!XPW7A+#GMSmdv5K|JFPseE>(3X`HG@>nn{z1ZV=FK~u^M?Dp&*n`tXYua2 z-#zDh=bm%!y_})6`Fp(?&>wKdDmaHrF>U-V;l+qT#s=s&7=xX_pvqwUwy(1%SPTi- znnb|Cup9vtBa?a9-qpL?!U|AKB1L6aa9g@$UzW+}5x@UfrG({GO`_Q3c#J9htZWGY zwQKCpXgD0+B;!uHDi)R#3vYJRH*R6T_6Q8en(x0?t8i^X!g8u+L}Ep4@tk3tN5z~* zFyK^+zx%X|<oBmgX2homip#DV%l9YU48k+c^G1LfD;Wp*AsNle!27?3ZVsJ3-Rr>jSZ-JB&UYN=dW(8aOi&Cpc&G zHr#*z<4HVWZLg+B<_If@hzwghdYbWg&*H&$ z)0_k&{Q_=xQ+(p_ubfrOn%TefXU_Ra8O1_u<;m1V!U`rLUN8|Q8?Tl-f`GFzlE_oyJ1wxouII?bT zM)EAs;<+qiq&s$YTSw?%hBMp}SU*sp~Vtb>eaOS zKO}oc)r`og-)2$Ih zRPaI3Ck?)e3qJZM(I@q3Xrhs>4U+gLV=WCUe})ez!8I!EPiLfP7_i0~yWV^JzH58A zy*=l)U3*^6Ip4qE`Of*y`M!H8DYV|f1Frna%14wCALo3LQu@|ZG<>SaZ$uBa3F#dj zwJTFsuX0X03`RL2?Ab(YJY=BNHDsu*Ubwc?1cYQts5<8J4?l{NMl=mfYKRjjZ0Xm1 zea~%`%GAKnz_xCr)0C2=NDn-IILC95U@+(q@oS-JV4+Y*fq*y&8J?c4 z@BOWA?`4p?F5*|Bm3aU_)aM@wK|d@~2EcpvHEh?}??b1Ve$z z$xwcrqlhwcF+H_ zBwUFrZJv%zgp=JRnuQ6cbkObb#^+~eQX;;QCf!D(Q1fQnoA6Lh7-{;Lb4Q*l;k{1= z+H{&^P!{?UIfBurWR|BfI3zMZIqmDaF}NgrQk7?@96vR7*S^NKA69o)Vr)k?pZyH) zsf1rW7#h$nGNT9JE-GS!JOB^EsF+7c#Q-rYLWJIE^K@n)VD_1Lg}JY_eftbPeP({m zU}yjUFSWIIU_gixE5s6i3a-p|__!MZt3ETM5{{d<*p7hJ3ud}Dmn2>3VG50yh?v21 zj0(e@Ic4)9`dT1u%dP_iQu!w8#^$rpUGEu|iJYR$~xt-6AoluooRvbrvbv;ZFaX*IXY{TKK%as~ z@5sLCYC5wg27}x3Ipq>~B`Hv8WGXs7f`zV*ZWvVU8P*_J3Cn>9)F93mWI%{n6&O~& z%5vr_S+Ro`*RhTaSrt1~gQf2%@4=}L7t#^5D&7?t!fr5`4uVd+A2xxzr|ncp951&<>v+s7s^_5%-&I!-kz$xQh5PTA629(f*@kPgnrqm*>;90^tJ6 z>c+F@e;x(ES4FD>j}%T=;M|$ew1{7cRJUp=)QRy%4JMg%k*rU=w?#8iQ6c8rZFSd>1@L#y@hpj+O+eBLJyg{B5mE zRvwf^V~L6+36{vzFwwx+9`9wrk1}ZztigVXs22M3@wn>Vw&NQp$2<_;%^-0d`Xh;0 eI8q{A=j1<2)zdGiEuLKf0000 name === 'balances'); const size = this.props.sections[balancesIndex].data[this.props.sections[balancesIndex].data.length - 1].assets.length; - dim.height = this.props.openSmallBalances ? CoinDivider.height + (size * CoinRow.height) + ListFooter.height : CoinDivider.height + ListFooter.height; + dim.height = this.props.openSmallBalances ? CoinDivider.height + (size * CoinRow.height) + ListFooter.height + 9 : CoinDivider.height + ListFooter.height + 16; } else if (type === ViewTypes.COIN_ROW) { dim.height = CoinRow.height; } else if (type === ViewTypes.UNISWAP_ROW_LAST) { - dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical + ListFooter.height + 7; + dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical + ListFooter.height + 8; } else if (type === ViewTypes.UNISWAP_ROW) { dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED_LAST) { - dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical + ListFooter.height + 7; + dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical + ListFooter.height + 8; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED) { dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical; } else if (type === ViewTypes.HEADER) { diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 465e9914b84..81a29d99d6f 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -11,25 +11,25 @@ import { Monospace } from '../text'; import { withFabSendAction } from '../../hoc'; import Highlight from '../Highlight'; import RotationArrow from '../animations/RotationArrow'; -import Caret from '../../assets/family-dropdown-arrow.png'; +import Caret from '../../assets/show-all-arrow.png'; import OpacityToggler from '../animations/OpacityToggler'; -const marginLeft = 15; +const marginLeft = 19; const marginRight = 19; const Wrapper = styled(View)` + margin: 8px 0 0 0; padding-right: ${marginRight}px; padding-left: ${marginLeft}px; width: ${deviceUtils.dimensions.width}; flex-direction: row; align-items: center; justify-content: space-between; - height: 50px; + height: 30px; `; const Container = styled(View)` - margin-top: 4px; height: 30px; - background-color: ${colors.lightGrey}; + background-color: ${colors.lightBlueGrey}; border-radius: 15px; align-items: center; padding: 0 10px; @@ -38,17 +38,18 @@ const Container = styled(View)` `; const Header = styled(Text)` + color: ${colors.blueGreyDark}; font-family: ${fonts.family.SFProText}; - letter-spacing: ${fonts.letterSpacing.tighter}; font-size: ${fonts.size.lmedium}; - color: ${colors.blueGreyDark}; font-weight: ${fonts.weight.semibold}; - width: 40px; + letter-spacing: ${fonts.letterSpacing.tighter}; opacity: 0.6; + padding-bottom: 1; `; const SettingIconWrap = styled(View)` opacity: 0.6; + padding-bottom: 1; `; const SettingIcon = styled(FastImage)` @@ -68,7 +69,7 @@ const CoinDivider = enhance(({ }) => ( - +
@@ -76,11 +77,11 @@ const CoinDivider = enhance(({
-
+
Less
- + @@ -91,6 +92,7 @@ const CoinDivider = enhance(({ {balancesSum} @@ -104,7 +106,7 @@ CoinDivider.propTypes = { openSmallBalances: PropTypes.bool, }; -CoinDivider.height = 50; +CoinDivider.height = 30; export default CoinDivider; diff --git a/src/components/coin-row/CollectiblesSendRow.js b/src/components/coin-row/CollectiblesSendRow.js index 49454bf15f0..be0c7f671e6 100644 --- a/src/components/coin-row/CollectiblesSendRow.js +++ b/src/components/coin-row/CollectiblesSendRow.js @@ -117,7 +117,7 @@ const CollectiblesSendRow = enhance(({ {isFirstRow && ( - + )} diff --git a/src/styles/colors.js b/src/styles/colors.js index b7b7c7e7540..c5b1f35401e 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -10,7 +10,7 @@ const base = { blueGreyDarker: '#0F0F11', // '15, 15, 17' blueGreyLight: '#A1A5AC', blueGreyLightest: '#8A8E97', // '138, 142, 151' - blueGreyLigter: '#666A73', // '102, 106, 115' + blueGreyLighter: '#666A73', // '102, 106, 115' blueGreyMedium: '#636875', // '99, 104, 117' blueGreyMediumLight: '#7b7f8a', // '123, 127, 138' blueHover: '#6c87f5', // '108, 135, 245' @@ -28,6 +28,7 @@ const base = { headerTitle: '#aaafbd', // '170, 175, 189' highlightBackground: '#f6f7f8', // '170, 175, 189' lightBlue: '#c5f2ff', // '197, 242, 255' + lightBlueGrey: '#F3F5F7', // '243, 245, 247' lightestGrey: '#E9EBEF', // '238, 233, 232' lightGreen: '#54d192', // '84, 209, 146' lightGrey: '#f7f7f8', // '247, 247, 248' From 9e803cf452ab6c0f0bd187d940d0133a16f38ca1 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Sat, 3 Aug 2019 23:23:30 -0400 Subject: [PATCH 044/636] Adjust small balances sum text color --- src/components/coin-divider/CoinDivider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 81a29d99d6f..83e4a6f0902 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -90,7 +90,7 @@ const CoinDivider = enhance(({ From a27813d8abb8453234df45fac2c10e75a4cee527 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sun, 4 Aug 2019 13:09:48 +0200 Subject: [PATCH 045/636] show balance with no value --- src/helpers/assets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/assets.js b/src/helpers/assets.js index f38ec60bc7e..6722a57cbcc 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -30,7 +30,7 @@ export const buildCoinsList = (assets) => { for (let i = 0; i < assets.length; i++) { if ((assets[i].native && assets[i].native.balance.amount > 1) || assets[i].address === 'eth' || assets.length < 4) { newAssets.push(assets[i]); - } else if (assets[i].native && assets[i].native.balance.amount <= 1) { + } else { smallBalances.assets.push(assets[i]); } } From ec4c8eff4ce87ad72f301c4b2b560b1f67d86072 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sun, 4 Aug 2019 19:17:19 +0200 Subject: [PATCH 046/636] rewrite animation for small balances to use spring --- src/components/animations/OpacityToggler.js | 70 +++++++++++++++---- .../asset-list/RecyclerAssetList.js | 9 ++- src/components/coin-divider/CoinDivider.js | 43 +++++++----- .../coin-divider/SmallBalancesWrapper.js | 61 ++++------------ 4 files changed, 104 insertions(+), 79 deletions(-) diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js index 764749bc725..3409cc18b9e 100644 --- a/src/components/animations/OpacityToggler.js +++ b/src/components/animations/OpacityToggler.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import Animated, { Easing } from 'react-native-reanimated'; +import Animated from 'react-native-reanimated'; const { block, @@ -10,28 +10,29 @@ const { interpolate, set, startClock, - timing, + spring, Value, + SpringUtils, } = Animated; -function runTiming(clock, value, dest, duration) { +function runTiming(clock, value, dest) { const state = { finished: new Value(1), - frameTime: new Value(0), position: new Value(value), time: new Value(0), + velocity: new Value(0), }; - const config = { - duration, - easing: Easing.inOut(Easing.ease), - toValue: new Value(0), - }; + const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + ...SpringUtils.makeDefaultConfig(), + friction: 20, + tension: 200, + }); const reset = [ set(state.finished, 0), set(state.time, 0), - set(state.frameTime, 0), + set(state.velocity, 0), ]; return block([ @@ -40,17 +41,17 @@ function runTiming(clock, value, dest, duration) { set(config.toValue, dest), ]), cond(clockRunning(clock), 0, startClock(clock)), - timing(clock, state, config), + spring(clock, state, config), state.position, ]); } -class OpacityToggler extends React.Component { +export class OpacityToggler extends React.Component { componentWillUpdate(prev) { if (prev.isVisible !== undefined && prev.isVisible !== this.props.isVisible) { const clock = new Clock(); - const base = this.props.isVisible ? runTiming(clock, -1, 1, this.props.duration) : runTiming(clock, 1, -1, this.props.duration); + const base = this.props.isVisible ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); this._opacity = interpolate(base, { inputRange: [-1, 1], outputRange: [this.props.endingOpacity, this.props.startingOpacity], @@ -83,4 +84,45 @@ OpacityToggler.defaultProps = { startingOpacity: 1, }; -export default OpacityToggler; +export class SizeToggler extends React.Component { + componentWillMount() { + this._width = new Value(this.props.startingWidth); + } + + componentWillUpdate(prev) { + if (prev.toggle !== undefined + && prev.toggle !== this.props.toggle) { + const clock = new Clock(); + const base = this.props.toggle ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); + this._width = interpolate(base, { + inputRange: [-1, 1], + outputRange: [this.props.endingWidth, this.props.startingWidth], + }); + } + } + + render() { + console.log(this._width); + return ( + + {this.props.children} + + ); + } +} + +SizeToggler.propTypes = { + children: PropTypes.any, + duration: PropTypes.number, + endingWidth: PropTypes.number, + startingWidth: PropTypes.number, + toggle: PropTypes.bool, +}; + +SizeToggler.defaultProps = { + duration: 200, + endingOpacity: 0, + startingOpacity: 1, +}; diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 420a5317bf7..b7d5e2bfa6d 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -52,7 +52,14 @@ const NOOP = () => undefined; const layoutItemAnimator = { animateDidMount: NOOP, - animateShift: () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')), + animateShift: () => LayoutAnimation.configureNext({ + duration: 200, + update: { + initialVelocity: 0, + springDamping: 1, + type: LayoutAnimation.Types.spring, + }, + }), animateWillMount: NOOP, animateWillUnmount: NOOP, animateWillUpdate: NOOP, diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 83e4a6f0902..1594fea7da2 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -12,7 +12,7 @@ import { withFabSendAction } from '../../hoc'; import Highlight from '../Highlight'; import RotationArrow from '../animations/RotationArrow'; import Caret from '../../assets/show-all-arrow.png'; -import OpacityToggler from '../animations/OpacityToggler'; +import { OpacityToggler, SizeToggler } from '../animations/OpacityToggler'; const marginLeft = 19; const marginRight = 19; @@ -35,6 +35,7 @@ const Container = styled(View)` padding: 0 10px; flex-direction: row; justify-content: space-between; + width: 100%; `; const Header = styled(Text)` @@ -45,6 +46,8 @@ const Header = styled(Text)` letter-spacing: ${fonts.letterSpacing.tighter}; opacity: 0.6; padding-bottom: 1; + position: absolute; + margin-top: -10px; `; const SettingIconWrap = styled(View)` @@ -70,23 +73,27 @@ const CoinDivider = enhance(({ - - -
- All -
-
- -
- Less -
-
- - - - - -
+ + + + +
+ All +
+
+ +
+ Less +
+
+
+ + + + + +
+
{ let sum = 0; @@ -23,49 +22,19 @@ const SmallBalancesWrapper = ({ setOpenSmallBalances, assets, ...props -}) => { - const transition = ( - - - - - - ); - - const [height, setHeight] = useState(0); - const ref = useRef(); - - const onPress = () => { - if (ref.current) { - ref.current.animateNextTransition(); - setHeight(!openSmallBalances ? (CoinRow.height * assets.length) : 0); - setOpenSmallBalances(!openSmallBalances); - } - }; - - if (openSmallBalances && height === 0) { - if (ref.current) { - ref.current.animateNextTransition(); - setHeight(CoinRow.height * assets.length); - } - } - - return ( - - - - {openSmallBalances - && - {assets} - - } - - - ); -}; +}) => ( + + setOpenSmallBalances(!openSmallBalances)} + /> + + {assets} + + +); SmallBalancesWrapper.propTypes = { assets: PropTypes.array, From bc315f818cd2d2a8f99c5e9620af03346428753f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Sun, 4 Aug 2019 14:15:17 -0400 Subject: [PATCH 047/636] Spacing tweaks --- src/components/coin-divider/CoinDivider.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 1594fea7da2..ca8deaddd72 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -44,20 +44,19 @@ const Header = styled(Text)` font-size: ${fonts.size.lmedium}; font-weight: ${fonts.weight.semibold}; letter-spacing: ${fonts.letterSpacing.tighter}; + top: -10.25px; opacity: 0.6; - padding-bottom: 1; position: absolute; - margin-top: -10px; `; const SettingIconWrap = styled(View)` opacity: 0.6; - padding-bottom: 1; + padding-bottom: 1px; `; const SettingIcon = styled(FastImage)` height: 17px; - width: 8px; + width: 9px; `; const enhance = compose( @@ -73,7 +72,7 @@ const CoinDivider = enhance(({ - + From 2be06fddd07e6c21bd351ad631aa9da9716513be Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sun, 4 Aug 2019 21:13:38 +0200 Subject: [PATCH 048/636] change logic in rotation arrow to add translate --- src/components/animations/RotationArrow.js | 15 +++++++++++---- src/components/coin-divider/CoinDivider.js | 2 +- .../investment-cards/InvestmentCardHeader.js | 2 +- src/components/token-family/TokenFamilyHeader.js | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index 8f900e2c9d8..59d10974298 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -9,6 +9,7 @@ const { concat, cond, interpolate, + multiply, set, startClock, spring, @@ -53,9 +54,9 @@ class RotationArrow extends React.Component { && prev.isOpen !== this.props.isOpen) { const clock = new Clock(); const base = this.props.isOpen ? runTiming(clock, -1, 1, this.props.isOpen) : runTiming(clock, 1, -1, this.props.isOpen); - this._rotation = interpolate(base, { + this._transform = interpolate(base, { inputRange: [-1, 1], - outputRange: [this.props.endingPosition, this.props.startingPosition], + outputRange: this.props.reversed ? [1, 0] : [0, 1], }); } } @@ -63,7 +64,12 @@ class RotationArrow extends React.Component { render() { return ( {this.props.children} @@ -73,9 +79,10 @@ class RotationArrow extends React.Component { RotationArrow.propTypes = { children: PropTypes.any, + endingOffset: PropTypes.number, endingPosition: PropTypes.number, isOpen: PropTypes.bool, - startingPosition: PropTypes.number, + reversed: PropTypes.bool, }; export default RotationArrow; diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index ca8deaddd72..9e620deaa85 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -87,7 +87,7 @@ const CoinDivider = enhance(({ - + diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index 98097844fad..eece63e9169 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -77,7 +77,7 @@ class InvestmentCardHeader extends React.Component { {isCollapsible && ( - + diff --git a/src/components/token-family/TokenFamilyHeader.js b/src/components/token-family/TokenFamilyHeader.js index 91213042e96..1b25592dee7 100644 --- a/src/components/token-family/TokenFamilyHeader.js +++ b/src/components/token-family/TokenFamilyHeader.js @@ -88,7 +88,7 @@ class TokenListHeader extends React.Component { {this.props.familyName} - + From fd070f525d305d767bd0e4441fd30a39855f5bda Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sun, 4 Aug 2019 21:45:02 +0200 Subject: [PATCH 049/636] add transparent headers to list --- patches/recyclerlistview+2.0.1-alpha.1.patch | 10 +++++++++- src/components/asset-list/AssetListHeader.js | 8 +++++++- src/components/investment-cards/InvestmentCard.js | 1 - src/components/list/ListHeader.js | 4 ++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/patches/recyclerlistview+2.0.1-alpha.1.patch b/patches/recyclerlistview+2.0.1-alpha.1.patch index 916baead915..c1105f54514 100644 --- a/patches/recyclerlistview+2.0.1-alpha.1.patch +++ b/patches/recyclerlistview+2.0.1-alpha.1.patch @@ -12,7 +12,7 @@ index 7074f36..5e72f6e 100644 return StickyHeader; }(StickyObject_1.default)); diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js -index 8da004f..417bf8c 100644 +index 8da004f..28b61b6 100644 --- a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js +++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js @@ -32,6 +32,7 @@ var StickyObject = /** @class */ (function (_super) { @@ -57,6 +57,14 @@ index 8da004f..417bf8c 100644 this._initParams(); this._offsetY = offsetY; this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); +@@ -179,6 +189,7 @@ var StickyObject = /** @class */ (function (_super) { + var _stickyLayoutType = this.props.getLayoutTypeForIndex(this.currentStickyIndex); + var _extendedState = this.props.getExtendedState(); + var _rowRenderer = this.props.getRowRenderer(); ++ _stickyData.isSticky = true; + if (this.props.overrideRowRenderer) { + return this.props.overrideRowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); + } diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js index 0ad973f..74f37c5 100644 --- a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js diff --git a/src/components/asset-list/AssetListHeader.js b/src/components/asset-list/AssetListHeader.js index 77b20a8e62f..ad2e0c22166 100644 --- a/src/components/asset-list/AssetListHeader.js +++ b/src/components/asset-list/AssetListHeader.js @@ -10,9 +10,10 @@ const enhance = onlyUpdateForKeys(['title', 'totalValue']); const AssetListHeader = enhance(({ title, totalValue, + isSticky, ...props }) => ( - + {totalValue ? ( {totalValue} @@ -22,10 +23,15 @@ const AssetListHeader = enhance(({ )); AssetListHeader.propTypes = { + isSticky: PropTypes.bool, title: PropTypes.string, totalValue: PropTypes.string, }; +AssetListHeader.defaultProps = { + isSticky: false, +}; + AssetListHeader.height = ListHeader.height + Divider.size; export default AssetListHeader; diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index ccf76c1e140..9a3fc8960ed 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -47,7 +47,6 @@ const InvestmentCard = ({ > ( -
+
{createElement(titleRenderer, { children: title })} {contextMenuOptions && ()} From b43d99e105a820597ba73544e74938c8a565f312 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Mon, 5 Aug 2019 03:03:21 -0400 Subject: [PATCH 050/636] Fix wide button on launch --- src/components/coin-divider/CoinDivider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index 9e620deaa85..a55a18dcd10 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -35,7 +35,7 @@ const Container = styled(View)` padding: 0 10px; flex-direction: row; justify-content: space-between; - width: 100%; + min-width: 41.5px; `; const Header = styled(Text)` From 52cb5bcbb60287db565643421640e53071ad7b44 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 5 Aug 2019 16:10:51 +0200 Subject: [PATCH 051/636] animations in small balances button in sync --- src/components/animations/OpacityToggler.js | 57 ++---- src/components/animations/RotationArrow.js | 22 ++- .../animations/RoundButtonSizeToggler.js | 132 ++++++++++++++ src/components/coin-divider/CoinDivider.js | 163 ++++++++++++------ .../coin-divider/SmallBalancesWrapper.js | 2 +- 5 files changed, 273 insertions(+), 103 deletions(-) create mode 100644 src/components/animations/RoundButtonSizeToggler.js diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js index 3409cc18b9e..50376047ae2 100644 --- a/src/components/animations/OpacityToggler.js +++ b/src/components/animations/OpacityToggler.js @@ -1,16 +1,21 @@ import PropTypes from 'prop-types'; import React from 'react'; import Animated from 'react-native-reanimated'; +import { View } from 'react-native'; const { + add, block, Clock, clockRunning, cond, + divide, interpolate, + multiply, set, startClock, spring, + sub, Value, SpringUtils, } = Animated; @@ -46,10 +51,9 @@ function runTiming(clock, value, dest) { ]); } -export class OpacityToggler extends React.Component { +export default class OpacityToggler extends React.Component { componentWillUpdate(prev) { - if (prev.isVisible !== undefined - && prev.isVisible !== this.props.isVisible) { + if (prev.isVisible !== undefined && prev.isVisible !== this.props.isVisible && !this.props.animationNode) { const clock = new Clock(); const base = this.props.isVisible ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); this._opacity = interpolate(base, { @@ -60,9 +64,10 @@ export class OpacityToggler extends React.Component { } render() { + return ( {this.props.children} @@ -71,6 +76,7 @@ export class OpacityToggler extends React.Component { } OpacityToggler.propTypes = { + animationNode: PropTypes.any, children: PropTypes.any, duration: PropTypes.number, endingOpacity: PropTypes.number, @@ -83,46 +89,3 @@ OpacityToggler.defaultProps = { endingOpacity: 0, startingOpacity: 1, }; - -export class SizeToggler extends React.Component { - componentWillMount() { - this._width = new Value(this.props.startingWidth); - } - - componentWillUpdate(prev) { - if (prev.toggle !== undefined - && prev.toggle !== this.props.toggle) { - const clock = new Clock(); - const base = this.props.toggle ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); - this._width = interpolate(base, { - inputRange: [-1, 1], - outputRange: [this.props.endingWidth, this.props.startingWidth], - }); - } - } - - render() { - console.log(this._width); - return ( - - {this.props.children} - - ); - } -} - -SizeToggler.propTypes = { - children: PropTypes.any, - duration: PropTypes.number, - endingWidth: PropTypes.number, - startingWidth: PropTypes.number, - toggle: PropTypes.bool, -}; - -SizeToggler.defaultProps = { - duration: 200, - endingOpacity: 0, - startingOpacity: 1, -}; diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index 59d10974298..52ec414d2d3 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import Animated, { Easing } from 'react-native-reanimated'; +import Animated from 'react-native-reanimated'; const { block, @@ -64,14 +64,26 @@ class RotationArrow extends React.Component { render() { return ( - {this.props.children} + + {this.props.children} + ); } diff --git a/src/components/animations/RoundButtonSizeToggler.js b/src/components/animations/RoundButtonSizeToggler.js new file mode 100644 index 00000000000..9dc2397f6d1 --- /dev/null +++ b/src/components/animations/RoundButtonSizeToggler.js @@ -0,0 +1,132 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import Animated from 'react-native-reanimated'; +import { View } from 'react-native'; +import { colors } from '../../styles'; + +const { + add, + block, + Clock, + clockRunning, + cond, + divide, + interpolate, + multiply, + set, + startClock, + spring, + sub, + Value, + SpringUtils, +} = Animated; + +function runTiming(clock, value, dest) { + const state = { + finished: new Value(1), + position: new Value(value), + time: new Value(0), + velocity: new Value(0), + }; + + const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + ...SpringUtils.makeDefaultConfig(), + friction: 20, + tension: 200, + }); + + const reset = [ + set(state.finished, 0), + set(state.time, 0), + set(state.velocity, 0), + ]; + + return block([ + cond(state.finished, [ + ...reset, + set(config.toValue, dest), + ]), + cond(clockRunning(clock), 0, startClock(clock)), + spring(clock, state, config), + state.position, + ]); +} + +export default class RoundButtonSizeToggler extends React.Component { + componentWillMount() { + this._width = new Value(this.props.startingWidth); + } + + componentWillUpdate(prev) { + if (prev.toggle !== undefined && prev.toggle !== this.props.toggle && !this.props.animationNode) { + const clock = new Clock(); + const base = this.props.toggle ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); + this._width = interpolate(base, { + inputRange: [-1, 1], + outputRange: [1, 0], + }); + } + } + + render() { + return ( + + + + + {this.props.children} + + + + + ); + } +} + +RoundButtonSizeToggler.propTypes = { + animationNode: PropTypes.any, + children: PropTypes.any, + duration: PropTypes.number, + endingWidth: PropTypes.number, + isAbsolute: PropTypes.bool, + startingWidth: PropTypes.number, + toggle: PropTypes.bool, +}; + +RoundButtonSizeToggler.defaultProps = { + duration: 200, + endingOpacity: 0, + startingOpacity: 1, +}; diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index a55a18dcd10..c043fb141de 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -2,17 +2,61 @@ import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; -import { compose } from 'recompact'; import FastImage from 'react-native-fast-image'; import { colors, fonts } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { deviceUtils } from '../../utils'; import { Monospace } from '../text'; -import { withFabSendAction } from '../../hoc'; import Highlight from '../Highlight'; import RotationArrow from '../animations/RotationArrow'; import Caret from '../../assets/show-all-arrow.png'; -import { OpacityToggler, SizeToggler } from '../animations/OpacityToggler'; +import OpacityToggler from '../animations/OpacityToggler'; +import Animated from 'react-native-reanimated'; +import RoundButtonSizeToggler from '../animations/RoundButtonSizeToggler'; + +const { + block, + Clock, + clockRunning, + cond, + interpolate, + set, + startClock, + spring, + Value, + SpringUtils, +} = Animated; + +function runTiming(clock, value, dest, isOpen) { + const state = { + finished: new Value(1), + position: new Value(value), + time: new Value(0), + velocity: new Value(0), + }; + + const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + ...SpringUtils.makeDefaultConfig(), + friction: 20, + tension: 200, + }); + + const reset = [ + set(state.finished, 0), + set(state.time, 0), + set(state.velocity, 0), + ]; + + return block([ + cond(state.finished, [ + ...reset, + set(config.toValue, dest), + ]), + cond(clockRunning(clock), 0, startClock(clock)), + spring(clock, state, config), + state.position, + ]); +} const marginLeft = 19; const marginRight = 19; @@ -29,7 +73,6 @@ const Wrapper = styled(View)` const Container = styled(View)` height: 30px; - background-color: ${colors.lightBlueGrey}; border-radius: 15px; align-items: center; padding: 0 10px; @@ -38,6 +81,10 @@ const Container = styled(View)` min-width: 41.5px; `; +const BackgroundColor = styled(View)` + height: 30px; +`; + const Header = styled(Text)` color: ${colors.blueGreyDark}; font-family: ${fonts.family.SFProText}; @@ -59,55 +106,71 @@ const SettingIcon = styled(FastImage)` width: 9px; `; -const enhance = compose( - withFabSendAction, -); - -const CoinDivider = enhance(({ - openSmallBalances, - onChangeOpenBalances, - balancesSum, - isCoinDivider, -}) => ( - - - - - - - -
- All -
-
- -
- Less -
-
-
- - - - - -
-
-
- - - {balancesSum} - - -
-)); +class CoinDivider extends React.Component { + componentWillUpdate(prev) { + if (prev.openSmallBalances !== undefined + && prev.openSmallBalances !== this.props.openSmallBalances) { + const clock = new Clock(); + const base = this.props.openSmallBalances ? runTiming(clock, -1, 1, this.props.openSmallBalances) : runTiming(clock, 1, -1, this.props.openSmallBalances); + this._node = interpolate(base, { + inputRange: [-1, 1], + outputRange: [1, 0], + }); + } + } + + render() { + const { + openSmallBalances, + onChangeOpenBalances, + balancesSum, + isCoinDivider, + } = this.props; + + return ( + + + + + + + + + +
+ All +
+
+ +
+ Less +
+
+
+ + + + + +
+
+ + + {balancesSum} + + +
+ ); + } +} CoinDivider.propTypes = { balancesSum: PropTypes.string, + isCoinDivider: PropTypes.bool, onChangeOpenBalances: PropTypes.func, openSmallBalances: PropTypes.bool, }; diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 4100d6ce024..3b52a57d818 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -3,7 +3,7 @@ import React from 'react'; import { View } from 'react-native'; import { withOpenBalances } from '../../hoc'; import CoinDivider from './CoinDivider'; -import { OpacityToggler } from '../animations/OpacityToggler'; +import OpacityToggler from '../animations/OpacityToggler'; const balancesSum = (balances) => { let sum = 0; From e51f98a98f3eb1ecb7725c6ddacd29ff76902f7b Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 5 Aug 2019 17:19:14 +0200 Subject: [PATCH 052/636] change animation for investment card --- src/components/animations/SizeToggler.js | 91 +++++++++++++++ .../investment-cards/InvestmentCard.js | 108 ++++++++---------- 2 files changed, 141 insertions(+), 58 deletions(-) create mode 100644 src/components/animations/SizeToggler.js diff --git a/src/components/animations/SizeToggler.js b/src/components/animations/SizeToggler.js new file mode 100644 index 00000000000..f77f05b41da --- /dev/null +++ b/src/components/animations/SizeToggler.js @@ -0,0 +1,91 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import Animated from 'react-native-reanimated'; + +const { + add, + block, + Clock, + clockRunning, + cond, + interpolate, + multiply, + set, + startClock, + spring, + Value, + SpringUtils, +} = Animated; + +function runTiming(clock, value, dest) { + const state = { + finished: new Value(1), + position: new Value(value), + time: new Value(0), + velocity: new Value(0), + }; + + const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + ...SpringUtils.makeDefaultConfig(), + friction: 20, + tension: 200, + }); + + const reset = [ + set(state.finished, 0), + set(state.time, 0), + set(state.velocity, 0), + ]; + + return block([ + cond(state.finished, [ + ...reset, + set(config.toValue, dest), + ]), + cond(clockRunning(clock), 0, startClock(clock)), + spring(clock, state, config), + state.position, + ]); +} + +export default class SizeToggler extends React.Component { + componentWillMount() { + this._height = new Value(this.props.startingWidth); + } + + componentWillUpdate(prev) { + if (prev.toggle !== undefined && prev.toggle !== this.props.toggle && !this.props.animationNode) { + const clock = new Clock(); + const base = this.props.toggle ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); + this._height = interpolate(base, { + inputRange: [-1, 1], + outputRange: [this.props.endingWidth, this.props.startingWidth], + }); + } + } + + render() { + return ( + + {this.props.children} + + ); + } +} + +SizeToggler.propTypes = { + animationNode: PropTypes.any, + children: PropTypes.any, + duration: PropTypes.number, + endingWidth: PropTypes.number, + startingWidth: PropTypes.number, + toggle: PropTypes.bool, +}; + +SizeToggler.defaultProps = { + duration: 200, + endingOpacity: 0, + startingOpacity: 1, +}; diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 9a3fc8960ed..56eeb773dc9 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -1,14 +1,14 @@ import PropTypes from 'prop-types'; -import React, { useState, useRef } from 'react'; +import React from 'react'; import LinearGradient from 'react-native-linear-gradient'; import { View } from 'react-native'; -import { Transitioning, Transition } from 'react-native-reanimated'; import { colors, position } from '../../styles'; import InnerBorder from '../InnerBorder'; import { Column } from '../layout'; import InvestmentCardHeader from './InvestmentCardHeader'; import { ButtonPressAnimation } from '../animations'; import { withOpenInvestmentCards } from '../../hoc'; +import SizeToggler from '../animations/SizeToggler'; const InvestmentCardMargin = { horizontal: 19, @@ -29,71 +29,63 @@ const InvestmentCard = ({ isCollapsible, ...props }) => { - const transition = ; - - const [perc, setPerc] = useState(collapsed ? InvestmentCardHeader.height : containerHeight); - const ref = useRef(); - const onPress = () => { setOpenInvestmentCards({ index: uniqueId, state: !openInvestmentCards[uniqueId] }); - ref.current.animateNextTransition(); - setPerc(!openInvestmentCards[uniqueId] ? InvestmentCardHeader.height : containerHeight); }; return ( - - - + + - - - + - - {children} - - - - + + + + {children} + + +
+ + ); }; From 618a2c10a131ac9e2e736924ac9f1b0963fc1d7e Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Tue, 6 Aug 2019 01:14:48 -0400 Subject: [PATCH 053/636] Fix button size and gap between button sections --- src/components/animations/RoundButtonSizeToggler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/animations/RoundButtonSizeToggler.js b/src/components/animations/RoundButtonSizeToggler.js index 9dc2397f6d1..8f2b5699752 100644 --- a/src/components/animations/RoundButtonSizeToggler.js +++ b/src/components/animations/RoundButtonSizeToggler.js @@ -104,7 +104,7 @@ export default class RoundButtonSizeToggler extends React.Component { borderBottomRightRadius: 15, borderTopRightRadius: 15, height: 30, - marginLeft: -10, + marginLeft: -11, transform: [ { translateX: this.props.animationNode ? multiply(-100, sub(1, add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100)), this.props.startingWidth / 100))) : -1 * (95 - (this.props.startingWidth / 100)) }, ], From ecd8e3ba5795e4d81d727a3edd9dea4f0b97e096 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Tue, 6 Aug 2019 01:58:56 -0400 Subject: [PATCH 054/636] Adjust CoinRow padding --- src/components/coin-row/CoinRow.js | 2 +- src/components/coin-row/SendCoinRow.js | 9 +++++++-- src/components/coin-row/TransactionCoinRow.js | 6 ++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/coin-row/CoinRow.js b/src/components/coin-row/CoinRow.js index 7cbea03cb2d..d0fcee11705 100644 --- a/src/components/coin-row/CoinRow.js +++ b/src/components/coin-row/CoinRow.js @@ -12,7 +12,7 @@ const CoinRowPaddingTop = 15; const CoinRowPaddingBottom = 7; const Container = styled(Row)` - ${padding(CoinRowPaddingTop, 19, CoinRowPaddingBottom, 15)} + ${padding(CoinRowPaddingTop, 19, CoinRowPaddingBottom, 19)} background-color: ${colors.white}; width: 100%; `; diff --git a/src/components/coin-row/SendCoinRow.js b/src/components/coin-row/SendCoinRow.js index 3e06e2fd55c..63629052b03 100644 --- a/src/components/coin-row/SendCoinRow.js +++ b/src/components/coin-row/SendCoinRow.js @@ -10,10 +10,15 @@ import { Monospace } from '../text'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; +const containerStyles = css` + paddingLeft: 15; + paddingTop: 17; +`; + const selectedHeight = 78; const selectedStyles = css` - ${padding(17, 15, 19, 15)}; + ${padding(15, 15, 19, 15)}; height: ${selectedHeight}; `; @@ -65,7 +70,7 @@ const SendCoinRow = enhance(({ {...item} {...props} bottomRowRender={BottomRow} - containerStyles={selected ? selectedStyles : null} + containerStyles={selected ? selectedStyles : containerStyles} selected={selected} topRowRender={TopRow} /> diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 37dea9bc7bc..91dfc4b6331 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -8,6 +8,7 @@ import { withHandlers, } from 'recompact'; import { Linking } from 'react-native'; +import { css } from 'styled-components/primitives'; import TransactionStatusTypes from '../../helpers/transactionStatusTypes'; import { colors } from '../../styles'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; @@ -19,6 +20,10 @@ import CoinName from './CoinName'; import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; +const containerStyles = css` + paddingLeft: 15; +`; + const rowRenderPropTypes = { balance: PropTypes.object, item: PropTypes.object, @@ -79,6 +84,7 @@ const TransactionCoinRow = ({ item, onPressTransaction, ...props }) => ( {...item} {...props} bottomRowRender={BottomRow} + containerStyles={containerStyles} shouldRasterizeIOS={true} topRowRender={TopRow} /> From 4f76e715fb524224e9660fe2330fc272b6a508d9 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 6 Aug 2019 12:51:53 +0200 Subject: [PATCH 055/636] fix sticky headers for activity list --- patches/recyclerlistview+2.0.1-alpha.1.patch | 8 +++++--- src/components/activity-list/ActivityListHeader.js | 1 + src/components/asset-list/AssetListHeader.js | 2 +- src/components/list/ListHeader.js | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/patches/recyclerlistview+2.0.1-alpha.1.patch b/patches/recyclerlistview+2.0.1-alpha.1.patch index c1105f54514..64fb161ecf5 100644 --- a/patches/recyclerlistview+2.0.1-alpha.1.patch +++ b/patches/recyclerlistview+2.0.1-alpha.1.patch @@ -12,7 +12,7 @@ index 7074f36..5e72f6e 100644 return StickyHeader; }(StickyObject_1.default)); diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js -index 8da004f..28b61b6 100644 +index 8da004f..6964e85 100644 --- a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js +++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js @@ -32,6 +32,7 @@ var StickyObject = /** @class */ (function (_super) { @@ -57,11 +57,13 @@ index 8da004f..28b61b6 100644 this._initParams(); this._offsetY = offsetY; this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); -@@ -179,6 +189,7 @@ var StickyObject = /** @class */ (function (_super) { +@@ -179,6 +189,9 @@ var StickyObject = /** @class */ (function (_super) { var _stickyLayoutType = this.props.getLayoutTypeForIndex(this.currentStickyIndex); var _extendedState = this.props.getExtendedState(); var _rowRenderer = this.props.getRowRenderer(); -+ _stickyData.isSticky = true; ++ if(_stickyData) { ++ _stickyData.isSticky = true; ++ } if (this.props.overrideRowRenderer) { return this.props.overrideRowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); } diff --git a/src/components/activity-list/ActivityListHeader.js b/src/components/activity-list/ActivityListHeader.js index 11007823242..28286ecd584 100644 --- a/src/components/activity-list/ActivityListHeader.js +++ b/src/components/activity-list/ActivityListHeader.js @@ -15,6 +15,7 @@ const titleRenderer = withProps({ export default compose( pickProps(Object.keys(ListHeader.propTypes)), withProps({ + isSticky: true, shouldRasterizeIOS: true, showDivider: false, titleRenderer, diff --git a/src/components/asset-list/AssetListHeader.js b/src/components/asset-list/AssetListHeader.js index ad2e0c22166..aff6a968c14 100644 --- a/src/components/asset-list/AssetListHeader.js +++ b/src/components/asset-list/AssetListHeader.js @@ -13,7 +13,7 @@ const AssetListHeader = enhance(({ isSticky, ...props }) => ( - + {totalValue ? ( {totalValue} diff --git a/src/components/list/ListHeader.js b/src/components/list/ListHeader.js index a8c15922a76..afe768e1c59 100644 --- a/src/components/list/ListHeader.js +++ b/src/components/list/ListHeader.js @@ -22,13 +22,13 @@ const Header = styled(Row).attrs({ const ListHeader = pure(({ children, contextMenuOptions, + isSticky, showDivider, title, titleRenderer, - style, }) => ( -
+
{createElement(titleRenderer, { children: title })} {contextMenuOptions && ()} From efec559d2ee99d4b7b4b08b47414994cfc07b153 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 6 Aug 2019 13:32:39 +0200 Subject: [PATCH 056/636] add tension and friction as props to modify animation dynamically --- src/components/animations/OpacityToggler.js | 18 ++++++++---------- src/components/animations/RotationArrow.js | 15 +++++++++++---- .../animations/RoundButtonSizeToggler.js | 16 ++++++++-------- src/components/animations/SizeToggler.js | 14 ++++++++------ 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js index 50376047ae2..347386036c3 100644 --- a/src/components/animations/OpacityToggler.js +++ b/src/components/animations/OpacityToggler.js @@ -1,7 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; import Animated from 'react-native-reanimated'; -import { View } from 'react-native'; const { add, @@ -9,18 +8,16 @@ const { Clock, clockRunning, cond, - divide, interpolate, multiply, set, startClock, spring, - sub, Value, SpringUtils, } = Animated; -function runTiming(clock, value, dest) { +function runTiming(clock, value, dest, friction, tension) { const state = { finished: new Value(1), position: new Value(value), @@ -30,8 +27,8 @@ function runTiming(clock, value, dest) { const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ ...SpringUtils.makeDefaultConfig(), - friction: 20, - tension: 200, + friction, + tension, }); const reset = [ @@ -55,7 +52,7 @@ export default class OpacityToggler extends React.Component { componentWillUpdate(prev) { if (prev.isVisible !== undefined && prev.isVisible !== this.props.isVisible && !this.props.animationNode) { const clock = new Clock(); - const base = this.props.isVisible ? runTiming(clock, -1, 1) : runTiming(clock, 1, -1); + const base = runTiming(clock, this.props.isVisible ? -1 : 1, this.props.isVisible ? 1 : -1, this.props.friction, this.props.tension); this._opacity = interpolate(base, { inputRange: [-1, 1], outputRange: [this.props.endingOpacity, this.props.startingOpacity], @@ -64,7 +61,6 @@ export default class OpacityToggler extends React.Component { } render() { - return ( Date: Tue, 6 Aug 2019 19:37:50 +0200 Subject: [PATCH 057/636] add open balance to async storage to save the last position of openSmallBalance toggler --- src/App.js | 5 +++++ src/components/animations/OpacityToggler.js | 8 +++++++- src/components/animations/RotationArrow.js | 5 +++-- .../animations/RoundButtonSizeToggler.js | 7 ++++--- src/components/coin-divider/CoinDivider.js | 12 ++++++++---- .../investment-cards/InvestmentCardHeader.js | 2 +- src/handlers/commonStorage.js | 17 +++++++++++++++++ src/redux/openBalances.js | 2 ++ 8 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/App.js b/src/App.js index 6397ecd14e0..8c546c39905 100644 --- a/src/App.js +++ b/src/App.js @@ -29,6 +29,8 @@ import store from './redux/store'; import { requestsForTopic } from './redux/requests'; import Routes from './screens/Routes'; import { parseQueryParams } from './utils'; +import { setOpenSmallBalances } from './redux/openBalances'; +import { getSmallBalanceToggle } from './handlers/commonStorage'; if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; @@ -89,6 +91,8 @@ class App extends Component { }; async componentDidMount() { + const toggle = await getSmallBalanceToggle(); + await store.dispatch(setOpenSmallBalances(toggle)); AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.props.initializeWallet(); @@ -179,6 +183,7 @@ class App extends Component { ) } + const AppWithRedux = compose( withProps({ store }), withDataInit, diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js index 347386036c3..6395e4448bd 100644 --- a/src/components/animations/OpacityToggler.js +++ b/src/components/animations/OpacityToggler.js @@ -49,6 +49,12 @@ function runTiming(clock, value, dest, friction, tension) { } export default class OpacityToggler extends React.Component { + componentWillMount() { + if (!this.props.animationNode) { + this._isVisible = this.props.isVisible; + } + } + componentWillUpdate(prev) { if (prev.isVisible !== undefined && prev.isVisible !== this.props.isVisible && !this.props.animationNode) { const clock = new Clock(); @@ -63,7 +69,7 @@ export default class OpacityToggler extends React.Component { render() { return ( {this.props.children} diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index b9068de3eac..b7b58ad82e3 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -11,6 +11,7 @@ const { interpolate, multiply, set, + sub, startClock, spring, Value, @@ -67,7 +68,7 @@ class RotationArrow extends React.Component { style={{ transform: [{ - translateX: this._transform ? multiply(this._transform, this.props.endingOffset) : 0, + translateX: this.props.endingOffset ? this._transform ? this.props.reversed ? multiply(this._transform, this.props.endingOffset) : sub(this.props.endingOffset, multiply(this._transform, this.props.endingOffset)) : this.props.reversed ? 0 : this.props.endingOffset : 0, }], }} > @@ -77,7 +78,7 @@ class RotationArrow extends React.Component { [{ // eslint-disable-next-line no-nested-ternary rotate: this._transform - ? (concat(multiply(this._transform, this.props.endingPosition), 'deg')) + ? (this.props.reversed ? concat(multiply(this._transform, this.props.endingPosition), 'deg') : concat(sub(this.props.endingPosition, multiply(this._transform, this.props.endingPosition)), 'deg')) : (this.props.reversed ? 0 : `${this.props.endingPosition}deg`), }], }} diff --git a/src/components/animations/RoundButtonSizeToggler.js b/src/components/animations/RoundButtonSizeToggler.js index c5d9475c15c..82ca8bcb4e3 100644 --- a/src/components/animations/RoundButtonSizeToggler.js +++ b/src/components/animations/RoundButtonSizeToggler.js @@ -90,8 +90,8 @@ export default class RoundButtonSizeToggler extends React.Component { style={{ backgroundColor: colors.lightBlueGrey, transform: [ - { scaleX: this.props.animationNode ? add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100)), this.props.startingWidth / 100) : this.props.startingWidth / 100 }, - { translateX: this.props.animationNode ? multiply(divide(sub(1, add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100), this.props.startingWidth / 100), 100)), 2), -1) : this.props.startingWidth }, + { scaleX: this.props.animationNode ? add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100)), this.props.startingWidth / 100) : this.props.reversed ? this.props.startingWidth / 100 : ((this.props.startingWidth + this.props.endingWidth + 5) / 100) }, + { translateX: this.props.animationNode ? multiply(divide(sub(1, add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100), this.props.startingWidth / 100), 100)), 2), -1) : this.props.reversed ? this.props.startingWidth : this.props.endingWidth }, ], width: 100, }} @@ -106,7 +106,7 @@ export default class RoundButtonSizeToggler extends React.Component { height: 30, marginLeft: -11, transform: [ - { translateX: this.props.animationNode ? multiply(-100, sub(1, add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100)), this.props.startingWidth / 100))) : -1 * (95 - (this.props.startingWidth / 100)) }, + { translateX: this.props.animationNode ? multiply(-100, sub(1, add(multiply(this.props.animationNode, (this.props.endingWidth / 100 - this.props.startingWidth / 100)), this.props.startingWidth / 100))) : this.props.reversed ? -1 * (100 - this.props.startingWidth) : -1 * (100 - this.props.endingWidth) }, ], width: 30, }} /> @@ -121,6 +121,7 @@ RoundButtonSizeToggler.propTypes = { endingWidth: PropTypes.number, friction: PropTypes.number, isAbsolute: PropTypes.bool, + reversed: PropTypes.bool, startingWidth: PropTypes.number, tension: PropTypes.number, toggle: PropTypes.bool, diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index c043fb141de..f0eb626c073 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -3,6 +3,7 @@ import React from 'react'; import styled from 'styled-components/primitives'; import { View, Text } from 'react-native'; import FastImage from 'react-native-fast-image'; +import Animated from 'react-native-reanimated'; import { colors, fonts } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { deviceUtils } from '../../utils'; @@ -11,7 +12,6 @@ import Highlight from '../Highlight'; import RotationArrow from '../animations/RotationArrow'; import Caret from '../../assets/show-all-arrow.png'; import OpacityToggler from '../animations/OpacityToggler'; -import Animated from 'react-native-reanimated'; import RoundButtonSizeToggler from '../animations/RoundButtonSizeToggler'; const { @@ -107,6 +107,10 @@ const SettingIcon = styled(FastImage)` `; class CoinDivider extends React.Component { + componentWillMount() { + this._initialState = this.props.openSmallBalances; + } + componentWillUpdate(prev) { if (prev.openSmallBalances !== undefined && prev.openSmallBalances !== this.props.openSmallBalances) { @@ -131,12 +135,12 @@ class CoinDivider extends React.Component { - + - +
All
@@ -148,7 +152,7 @@ class CoinDivider extends React.Component {
- + diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index eece63e9169..872e76a9139 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -77,7 +77,7 @@ class InvestmentCardHeader extends React.Component { {isCollapsible && ( - + diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 884996fa321..ef7ae6956c5 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -409,3 +409,20 @@ export const removeLocalRequests = async (address, network) => { const requestsKey = getRequestsKey(address, network); await removeLocal(requestsKey); }; + +/** + * @desc get open small balance toggle + * @return {Boolean} + */ +export const getSmallBalanceToggle = async () => { + const toggle = await getLocal('smallBalanceToggle'); + return toggle.data || false; +}; + +/** + * @desc save open small balance toggle + * @param {Boolean} [language] + */ +export const saveSmallBalanceToggle = async toggle => { + await saveLocal('smallBalanceToggle', { data: toggle }); +}; diff --git a/src/redux/openBalances.js b/src/redux/openBalances.js index 34a59f9c57e..e033a17c9c7 100644 --- a/src/redux/openBalances.js +++ b/src/redux/openBalances.js @@ -1,4 +1,5 @@ import produce from 'immer'; +import { saveSmallBalanceToggle } from '../handlers/commonStorage'; // -- Constants --------------------------------------- // const SET_OPEN_SMALL_BALANCES = 'openBalances/SET_OPEN_SMALL_BALANCES'; @@ -16,6 +17,7 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => ( produce(state, draft => { if (action.type === SET_OPEN_SMALL_BALANCES) { + saveSmallBalanceToggle(action.payload); draft.openSmallBalances = action.payload; } }) From 6378d92efea2d989006496cb9cba6c2a5acc5242 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 7 Aug 2019 12:45:12 +0200 Subject: [PATCH 058/636] add saving open investment cards logic --- src/App.js | 5 ++++- src/components/animations/RotationArrow.js | 16 ++++++++++++---- src/components/animations/SizeToggler.js | 6 +++++- src/components/coin-divider/CoinDivider.js | 2 +- .../investment-cards/InvestmentCardHeader.js | 2 +- .../token-family/TokenFamilyHeader.js | 2 +- src/handlers/commonStorage.js | 17 +++++++++++++++++ src/redux/openInvestmentCards.js | 4 +++- 8 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/App.js b/src/App.js index 8c546c39905..2228b4ac6b2 100644 --- a/src/App.js +++ b/src/App.js @@ -30,7 +30,8 @@ import { requestsForTopic } from './redux/requests'; import Routes from './screens/Routes'; import { parseQueryParams } from './utils'; import { setOpenSmallBalances } from './redux/openBalances'; -import { getSmallBalanceToggle } from './handlers/commonStorage'; +import { getSmallBalanceToggle, getOpenInvestmentCards } from './handlers/commonStorage'; +import { pushOpenInvestmentCard } from './redux/openInvestmentCards'; if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; @@ -92,7 +93,9 @@ class App extends Component { async componentDidMount() { const toggle = await getSmallBalanceToggle(); + const openInvestmentCards = await getOpenInvestmentCards(); await store.dispatch(setOpenSmallBalances(toggle)); + await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.props.initializeWallet(); diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index b7b58ad82e3..83f7b2b42e3 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -50,6 +50,14 @@ function runTiming(clock, value, dest, friction, tension) { } class RotationArrow extends React.Component { + componentWillMount() { + if (!this.props.isOpen === true) { + this._transform = new Value(1); + return; + } + this._transform = new Value(0); + } + componentWillUpdate(prev) { if (prev.isOpen !== undefined && prev.isOpen !== this.props.isOpen) { @@ -57,7 +65,7 @@ class RotationArrow extends React.Component { const base = runTiming(clock, this.props.isOpen ? -1 : 1, this.props.isOpen ? 1 : -1, this.props.friction, this.props.tension); this._transform = interpolate(base, { inputRange: [-1, 1], - outputRange: this.props.reversed ? [1, 0] : [0, 1], + outputRange: [0, 1], }); } } @@ -68,7 +76,7 @@ class RotationArrow extends React.Component { style={{ transform: [{ - translateX: this.props.endingOffset ? this._transform ? this.props.reversed ? multiply(this._transform, this.props.endingOffset) : sub(this.props.endingOffset, multiply(this._transform, this.props.endingOffset)) : this.props.reversed ? 0 : this.props.endingOffset : 0, + translateX: this.props.endingOffset ? (this._transform ? sub(this.props.endingOffset, multiply(this._transform, this.props.endingOffset)) : this.props.endingOffset) : 0, }], }} > @@ -78,8 +86,8 @@ class RotationArrow extends React.Component { [{ // eslint-disable-next-line no-nested-ternary rotate: this._transform - ? (this.props.reversed ? concat(multiply(this._transform, this.props.endingPosition), 'deg') : concat(sub(this.props.endingPosition, multiply(this._transform, this.props.endingPosition)), 'deg')) - : (this.props.reversed ? 0 : `${this.props.endingPosition}deg`), + ? (concat(sub(this.props.endingPosition, multiply(this._transform, this.props.endingPosition)), 'deg')) + : (`${this.props.endingPosition}deg`), }], }} > diff --git a/src/components/animations/SizeToggler.js b/src/components/animations/SizeToggler.js index a3043eaedb8..b54b36b78ae 100644 --- a/src/components/animations/SizeToggler.js +++ b/src/components/animations/SizeToggler.js @@ -50,7 +50,11 @@ function runTiming(clock, value, dest, friction, tension) { export default class SizeToggler extends React.Component { componentWillMount() { - this._height = new Value(this.props.startingWidth); + if (!this.props.toggle === true) { + this._height = new Value(this.props.startingWidth); + return; + } + this._height = new Value(this.props.endingWidth); } componentWillUpdate(prev) { diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index f0eb626c073..ea759a8b406 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -152,7 +152,7 @@ class CoinDivider extends React.Component { - + diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index 872e76a9139..b7978c00775 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -77,7 +77,7 @@ class InvestmentCardHeader extends React.Component { {isCollapsible && ( - + diff --git a/src/components/token-family/TokenFamilyHeader.js b/src/components/token-family/TokenFamilyHeader.js index 1b25592dee7..95b7ab03111 100644 --- a/src/components/token-family/TokenFamilyHeader.js +++ b/src/components/token-family/TokenFamilyHeader.js @@ -88,7 +88,7 @@ class TokenListHeader extends React.Component { {this.props.familyName} - + diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index ef7ae6956c5..9c22f01cca6 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -426,3 +426,20 @@ export const getSmallBalanceToggle = async () => { export const saveSmallBalanceToggle = async toggle => { await saveLocal('smallBalanceToggle', { data: toggle }); }; + +/** + * @desc get open investment cards + * @return {Boolean} + */ +export const getOpenInvestmentCards = async () => { + const openInvestmentCards = await getLocal('openInvestmentCards'); + return openInvestmentCards.data || {}; +}; + +/** + * @desc save open investment cards + * @param {Boolean} [language] + */ +export const saveOpenInvestmentCards = async openInvestmentCards => { + await saveLocal('openInvestmentCards', { data: openInvestmentCards }); +}; \ No newline at end of file diff --git a/src/redux/openInvestmentCards.js b/src/redux/openInvestmentCards.js index 85a0f9ebb0f..00ce89d5722 100644 --- a/src/redux/openInvestmentCards.js +++ b/src/redux/openInvestmentCards.js @@ -1,4 +1,5 @@ import produce from 'immer'; +import { saveOpenInvestmentCards } from '../handlers/commonStorage'; // -- Constants --------------------------------------- // const SET_OPEN_INVESTMENT_CARDS = 'openInvestmentCards/SET_OPEN_INVESTMENT_CARDS'; @@ -23,8 +24,9 @@ export default (state = INITIAL_STATE, action) => ( produce(state, draft => { if (action.type === SET_OPEN_INVESTMENT_CARDS) { draft.openInvestmentCards[action.payload.index] = action.payload.state; + saveOpenInvestmentCards(draft.openInvestmentCards); } else if (action.type === PUSH_OPEN_INVESTMENT_CARD) { - draft.openInvestmentCards = state.openInvestmentCards.concat(false); + draft.openInvestmentCards = action.payload; } }) ); From 2c085bc7dbb444c7dd977aee1d2be4357f473832 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 7 Aug 2019 14:15:13 +0200 Subject: [PATCH 059/636] change open families tabs logic to work on object using family names instead of indexes in table --- .../asset-list/RecyclerAssetList.js | 8 +++---- src/components/fab/MovableFabWrapper.js | 2 +- .../token-family/TokenFamilyWrap.js | 12 +++++------ src/handlers/commonStorage.js | 21 +++++++++++++++++-- src/helpers/assets.js | 5 ----- src/redux/openFamilyTabs.js | 4 +++- 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index b7d5e2bfa6d..e6ab7df1f2f 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -197,7 +197,7 @@ class RecyclerAssetList extends PureComponent { if (collectiblesIndex > -1) { if (index > headersIndices[collectiblesIndex]) { const familyIndex = index - headersIndices[collectiblesIndex] - 1; - if (openFamilyTabs[familyIndex]) { + if (openFamilyTabs[sections[collectiblesIndex].data[familyIndex].familyName]) { if (get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`)) { return { get: ViewTypes.UNIQUE_TOKEN_ROW, @@ -322,11 +322,11 @@ class RecyclerAssetList extends PureComponent { } if (this.props.openFamilyTabs !== prev.openFamilyTabs) { let i = 0; - while (i < this.props.openFamilyTabs.length) { - if (this.props.openFamilyTabs[i] === true && prev.openFamilyTabs[i] === false) { + while (i < collectibles.data.length) { + if (this.props.openFamilyTabs[collectibles.data[i].familyName] === true && !prev.openFamilyTabs[collectibles.data[i].familyName]) { let collectiblesHeight = 0; for (let j = 0; j < i; j++) { - if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + if (this.props.openFamilyTabs[collectibles.data[j].familyName] && collectibles.data[j].tokens) { collectiblesHeight += collectibles.data[j].tokens.length * CardSize + 54 + (RowPadding - 4) * (collectibles.data[j].tokens.length - 1); } else { collectiblesHeight += 54; diff --git a/src/components/fab/MovableFabWrapper.js b/src/components/fab/MovableFabWrapper.js index 2d911edf3e3..9421b69ab68 100644 --- a/src/components/fab/MovableFabWrapper.js +++ b/src/components/fab/MovableFabWrapper.js @@ -369,7 +369,7 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment top: height, }); } - if (openFamilyTabs[i]) { + if (openFamilyTabs[collectibles.data[i].familyName]) { height += CardSize; if (j > 0) { height += CardMargin; diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index f5162cec9b7..79f8765eae2 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -49,7 +49,7 @@ class TokenFamilyWrap extends Component { } shouldComponentUpdate = (prev, next) => { - const familyId = this.props.item[0][0].rowNumber; + const familyId = this.props.item[0][0].asset_contract.name; if (this.props.openFamilyTabs[familyId] !== prev.openFamilyTabs[familyId] || this.state.opacity != next.opacity || this.props.highlight !== prev.highlight) { @@ -59,7 +59,7 @@ class TokenFamilyWrap extends Component { } componentDidUpdate = () => { - const familyId = this.props.item[0][0].rowNumber; + const familyId = this.props.item[0][0].asset_contract.name; const newOpacity = this.props.openFamilyTabs[familyId] ? 1 : 0; if (newOpacity) { setTimeout(() => { @@ -71,7 +71,7 @@ class TokenFamilyWrap extends Component { } collectiblesRenderItem = item => { - if (this.props.openFamilyTabs[item.item[0][0].rowNumber]) { + if (this.props.openFamilyTabs[item.item[0][0].asset_contract.name]) { const tokens = []; for (let i = 0; i < item.item.length; i++) { tokens.push( @@ -89,8 +89,8 @@ class TokenFamilyWrap extends Component { onHeaderPress = () => { this.props.setOpenFamilyTabs({ - index: this.props.item[0][0].rowNumber, - state: !this.props.openFamilyTabs[this.props.item[0][0].rowNumber], + index: this.props.item[0][0].asset_contract.name, + state: !this.props.openFamilyTabs[this.props.item[0][0].asset_contract.name], }); }; @@ -102,7 +102,7 @@ class TokenFamilyWrap extends Component { familyImage={this.props.familyImage} childrenAmount={this.props.childrenAmount} highlight={this.props.highlight} - isOpen={this.props.openFamilyTabs[this.props.item[0][0].rowNumber]} + isOpen={this.props.openFamilyTabs[this.props.item[0][0].asset_contract.name]} onHeaderPress={this.onHeaderPress} /> {this.state.opacity == 1 && diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 9c22f01cca6..350e727cfd5 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -429,7 +429,7 @@ export const saveSmallBalanceToggle = async toggle => { /** * @desc get open investment cards - * @return {Boolean} + * @return {Object} */ export const getOpenInvestmentCards = async () => { const openInvestmentCards = await getLocal('openInvestmentCards'); @@ -438,8 +438,25 @@ export const getOpenInvestmentCards = async () => { /** * @desc save open investment cards - * @param {Boolean} [language] + * @param {Object} [openInvestmentCards] */ export const saveOpenInvestmentCards = async openInvestmentCards => { await saveLocal('openInvestmentCards', { data: openInvestmentCards }); +}; + +/** + * @desc get open families + * @return {Object} + */ +export const getOpenFamilies = async () => { + const openFamilies = await getLocal('openFamilies'); + return openFamilies.data || {}; +}; + +/** + * @desc save open families + * @param {Object} [openFamilies] + */ +export const saveOpenFamilies = async openFamilies => { + await saveLocal('openFamilies', { data: openFamilies }); }; \ No newline at end of file diff --git a/src/helpers/assets.js b/src/helpers/assets.js index 6722a57cbcc..d4df22652af 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -4,8 +4,6 @@ import { groupBy, sortBy, } from 'lodash'; -import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; -import store from '../redux/store'; export const buildAssetHeaderUniqueIdentifier = ({ title, @@ -66,9 +64,6 @@ export const buildUniqueTokenList = (uniqueTokens) => { }); } - while (rows.length > store.getState().openFamilyTabs.openFamilyTabs.length) { - store.dispatch(pushOpenFamilyTab()); - } rows = sortBy(rows, ['familyName']); rows.forEach((row, i) => { row.familyId = i; diff --git a/src/redux/openFamilyTabs.js b/src/redux/openFamilyTabs.js index 4d6989b4bb1..09d7f437834 100644 --- a/src/redux/openFamilyTabs.js +++ b/src/redux/openFamilyTabs.js @@ -1,4 +1,5 @@ import produce from 'immer'; +import { saveOpenFamilies } from '../handlers/commonStorage'; // -- Constants --------------------------------------- // const SET_OPEN_FAMILY_TABS = 'openFamilyTabs/SET_OPEN_FAMILY_TABS'; @@ -16,13 +17,14 @@ export const pushOpenFamilyTab = payload => dispatch => dispatch({ // -- Reducer ----------------------------------------- // const INITIAL_STATE = { - openFamilyTabs: [], + openFamilyTabs: {}, }; export default (state = INITIAL_STATE, action) => ( produce(state, draft => { if (action.type === SET_OPEN_FAMILY_TABS) { draft.openFamilyTabs[action.payload.index] = action.payload.state; + saveOpenFamilies(draft.openFamilyTabs); } else if (action.type === PUSH_OPEN_FAMILY_TAB) { draft.openFamilyTabs = state.openFamilyTabs.concat(false); } From a7b5c307cbf85edc0ea02688f7e516f79f19d81a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 7 Aug 2019 15:17:19 +0200 Subject: [PATCH 060/636] add saving state of open families and loading on open app --- src/App.js | 5 ++++- src/components/token-family/TokenFamilyWrap.js | 18 ++++++++++++------ src/redux/openFamilyTabs.js | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/App.js b/src/App.js index 2228b4ac6b2..189b7db7f67 100644 --- a/src/App.js +++ b/src/App.js @@ -30,8 +30,9 @@ import { requestsForTopic } from './redux/requests'; import Routes from './screens/Routes'; import { parseQueryParams } from './utils'; import { setOpenSmallBalances } from './redux/openBalances'; -import { getSmallBalanceToggle, getOpenInvestmentCards } from './handlers/commonStorage'; +import { getSmallBalanceToggle, getOpenInvestmentCards, getOpenFamilies } from './handlers/commonStorage'; import { pushOpenInvestmentCard } from './redux/openInvestmentCards'; +import { pushOpenFamilyTab } from './redux/openFamilyTabs'; if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; @@ -94,8 +95,10 @@ class App extends Component { async componentDidMount() { const toggle = await getSmallBalanceToggle(); const openInvestmentCards = await getOpenInvestmentCards(); + const openFamilies = await getOpenFamilies(); await store.dispatch(setOpenSmallBalances(toggle)); await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); + await store.dispatch(pushOpenFamilyTab(openFamilies)); AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.props.initializeWallet(); diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index 79f8765eae2..9501612097b 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -37,8 +37,6 @@ const getHeight = (openFamilyTab) => ( : 100 ); -const header = (child) => child; - class TokenFamilyWrap extends Component { constructor(props) { super(props); @@ -71,7 +69,7 @@ class TokenFamilyWrap extends Component { } collectiblesRenderItem = item => { - if (this.props.openFamilyTabs[item.item[0][0].asset_contract.name]) { + if (this.props.openFamilyTabs[item.familyName]) { const tokens = []; for (let i = 0; i < item.item.length; i++) { tokens.push( @@ -94,7 +92,15 @@ class TokenFamilyWrap extends Component { }); }; + componentDidMount = () => { + if (this.props.openFamilyTabs[this.props.familyName]) { + this.setState({ opacity: 1 }); + } + } + render() { + const content = this.collectiblesRenderItem(this.props); + return ( - {this.state.opacity == 1 && - - {header(this.collectiblesRenderItem(this.props))} + {this.state.opacity === 1 + && + {content} } diff --git a/src/redux/openFamilyTabs.js b/src/redux/openFamilyTabs.js index 09d7f437834..319147b08e8 100644 --- a/src/redux/openFamilyTabs.js +++ b/src/redux/openFamilyTabs.js @@ -26,7 +26,7 @@ export default (state = INITIAL_STATE, action) => ( draft.openFamilyTabs[action.payload.index] = action.payload.state; saveOpenFamilies(draft.openFamilyTabs); } else if (action.type === PUSH_OPEN_FAMILY_TAB) { - draft.openFamilyTabs = state.openFamilyTabs.concat(false); + draft.openFamilyTabs = action.payload; } }) ); From 22b2af34cc2bd0b10c99b313f31a4948c9f05475 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 7 Aug 2019 15:23:39 +0200 Subject: [PATCH 061/636] remove autoscroll for smll balances --- src/components/asset-list/RecyclerAssetList.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index e6ab7df1f2f..b18bedf8b5b 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -375,23 +375,6 @@ class RecyclerAssetList extends PureComponent { i++; } } - if (this.props.openSmallBalances !== prev.openSmallBalances && this.props.openSmallBalances) { - const verticalOffset = 15; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionsHeight = CoinRow.height * (balances.data.length - 1); - const renderSize = (CoinRow.height * balances.data[balances.data.length - 1].assets.length) - verticalOffset; - - if (renderSize >= deviceDimensions) { - const scrollDistance = sectionsHeight - this.position; - this.scrollToOffset(this.position + scrollDistance); - } else { - const diff = this.position - sectionsHeight + deviceDimensions; - if (renderSize > diff) { - const scrollDistance = deviceDimensions > renderSize ? renderSize - diff : deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 250 : 280); - this.scrollToOffset(this.position + scrollDistance); - } - } - } } componentWillUnmount = () => { From 25f02225ae419649f765e8934710ce71f8845889 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 7 Aug 2019 16:25:36 +0200 Subject: [PATCH 062/636] add suport for fresh install with no saved state for open assets --- src/App.js | 7 ++++++- src/components/asset-list/RecyclerAssetList.js | 6 ++++-- src/handlers/commonStorage.js | 15 ++++++++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/App.js b/src/App.js index 189b7db7f67..f260686662f 100644 --- a/src/App.js +++ b/src/App.js @@ -92,13 +92,18 @@ class App extends Component { return Navigation.handleAction({ routeName: 'ProfileScreen' }); }; - async componentDidMount() { + setInitialStatesForOpenAssets = async () => { const toggle = await getSmallBalanceToggle(); const openInvestmentCards = await getOpenInvestmentCards(); const openFamilies = await getOpenFamilies(); await store.dispatch(setOpenSmallBalances(toggle)); await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); await store.dispatch(pushOpenFamilyTab(openFamilies)); + return true; + } + + async componentDidMount() { + await this.setInitialStatesForOpenAssets(); AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.props.initializeWallet(); diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index b18bedf8b5b..dfe7f73f887 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -65,6 +65,8 @@ const layoutItemAnimator = { animateWillUpdate: NOOP, }; +const reloadHeightOfsetTop = -60; +const reloadHeightOffsetBottom = -62; // eslint-disable-next-line react/prop-types const AssetListHeaderRenderer = pure(data => ); @@ -288,7 +290,7 @@ class RecyclerAssetList extends PureComponent { if (prev.openFamilyTabs !== this.props.openFamilyTabs) { return true; } - if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && this.position !== 60.5) { + if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && !(this.position <= reloadHeightOfsetTop && this.position > reloadHeightOffsetBottom)) { return false; } return true; @@ -508,7 +510,7 @@ class RecyclerAssetList extends PureComponent { this.layoutMeasurement = event.nativeEvent.layoutMeasurement.height; } if ((event.nativeEvent.contentSize.height - event.nativeEvent.layoutMeasurement.height >= offsetY && offsetY >= 0) - || (offsetY < -60 && offsetY > -62)) { + || (offsetY < reloadHeightOfsetTop && offsetY > reloadHeightOffsetBottom)) { if (this.props.scrollViewTracker) { this.props.scrollViewTracker.setValue(offsetY); } diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 350e727cfd5..c01066104a9 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -416,7 +416,10 @@ export const removeLocalRequests = async (address, network) => { */ export const getSmallBalanceToggle = async () => { const toggle = await getLocal('smallBalanceToggle'); - return toggle.data || false; + if (toggle) { + return toggle.data; + } + return false; }; /** @@ -433,7 +436,10 @@ export const saveSmallBalanceToggle = async toggle => { */ export const getOpenInvestmentCards = async () => { const openInvestmentCards = await getLocal('openInvestmentCards'); - return openInvestmentCards.data || {}; + if (openInvestmentCards) { + return openInvestmentCards.data; + } + return {}; }; /** @@ -450,7 +456,10 @@ export const saveOpenInvestmentCards = async openInvestmentCards => { */ export const getOpenFamilies = async () => { const openFamilies = await getLocal('openFamilies'); - return openFamilies.data || {}; + if (openFamilies) { + return openFamilies.data; + } + return {}; }; /** From 49930dc6cbb9fc48cd5cfe14fc46a8cb7a41140c Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 8 Aug 2019 15:36:26 +0200 Subject: [PATCH 063/636] merge develop into collapsible-small-collectibles --- CHANGELOG.md | 4 +- android/app/build.gradle | 1 + .../java/com/rainbow/MainApplication.java | 2 + android/settings.gradle | 2 + config/test/jest-setup.js | 7 + ios/Podfile | 52 +- ios/Podfile.lock | 286 ++- ios/Rainbow.xcodeproj/project.pbxproj | 97 +- ios/Rainbow/Info.plist | 10 +- package.json | 48 +- patches/recyclerlistview+2.0.1-alpha.1.patch | 51 + src/App.js | 4 - src/assets/family-dropdown-arrow.png | Bin 381 -> 447 bytes src/assets/family-dropdown-arrow@2x.png | Bin 745 -> 906 bytes src/assets/family-dropdown-arrow@3x.png | Bin 1158 -> 1371 bytes src/components/AddFundsInterstitial.js | 2 +- src/components/Divider.js | 3 +- src/components/Highlight.js | 48 +- src/components/Shimmer.js | 59 - .../animations/ButtonPressAnimation.js | 2 +- src/components/asset-list/AssetList.js | 36 +- .../asset-list/AssetListItemSkeleton.js | 213 +- ...AssetListSkeleton.js => EmptyAssetList.js} | 17 +- .../asset-list/RecyclerAssetList.js | 296 ++- src/components/coin-row/BottomRowText.js | 5 +- src/components/coin-row/CoinRow.js | 24 +- src/components/coin-row/TransactionCoinRow.js | 20 +- .../coin-row/TransactionStatusBadge.js | 4 +- .../expanded-state/asset-panel/AssetPanel.js | 13 +- src/components/fab/DeleteButton.js | 38 +- src/components/fab/FabWrapper.js | 27 +- src/components/fab/FloatingActionButton.js | 180 +- src/components/fab/MovableFabWrapper.js | 165 +- src/components/fab/SendFab.js | 103 +- src/components/header/Header.js | 2 +- src/components/icons/Icon.js | 2 - .../icons/svg/AssetListItemSkeletonIcon.js | 27 - src/components/icons/svg/CaretThinIcon.js | 6 +- .../icons/svg/CheckmarkCircledIcon.js | 2 +- src/components/icons/svg/CloseIcon.js | 8 +- src/components/icons/svg/SpinnerIcon.js | 2 +- .../investment-cards/InvestmentCard.js | 3 +- .../investment-cards/UniswapInvestmentCard.js | 8 +- src/components/layout/ColumnWithDividers.js | 13 + src/components/layout/Flex.js | 7 +- src/components/layout/LayoutWithDividers.js | 40 + src/components/layout/RowWithDividers.js | 13 + src/components/layout/index.js | 3 + src/components/list/ListItem.js | 98 +- src/components/list/ListItemArrowGroup.js | 19 +- src/components/list/ListItemDivider.js | 3 +- src/components/list/SectionList.js | 101 - src/components/list/index.js | 1 - src/components/settings-menu/BackupSection.js | 8 +- .../settings-menu/CurrencySection.js | 11 +- .../settings-menu/SettingsSection.js | 101 +- src/components/shadow-stack/ShadowStack.js | 6 +- src/components/text/TruncatedText.js | 3 +- .../token-family/TokenFamilyHeader.js | 224 +- .../token-family/TokenFamilyWrap.js | 216 +- src/components/token-family/index.js | 1 + .../unique-token/UniqueTokenCard.js | 10 +- src/components/unique-token/UniqueTokenRow.js | 31 +- src/handlers/__tests__/web3.test.js | 30 + src/handlers/commonStorage.js | 47 +- src/handlers/web3.js | 33 +- src/helpers/assets.js | 4 +- src/helpers/buildWalletSections.js | 249 ++- src/helpers/sortList.js | 42 +- src/helpers/validators.js | 13 +- .../__tests__/withUniswapLiquidity.test.js | 3 +- src/hoc/assetSelectors.js | 1 + src/hoc/index.js | 3 + src/hoc/withDataInit.js | 101 +- src/hoc/withFabSelection.js | 39 + src/hoc/withFabSendAction.js | 80 +- src/hoc/withIsWalletEthZero.js | 6 + src/hoc/withIsWalletImporting.js | 6 + src/hoc/withUniqueTokens.js | 5 +- src/languages/_english.json | 2 +- src/model/__tests__/wallet.test.js | 38 + src/model/wallet.js | 55 +- src/parsers/accounts.js | 3 +- src/redux/data.js | 5 +- src/redux/isWalletEmpty.js | 41 +- src/redux/isWalletEthZero.js | 22 + src/redux/isWalletImporting.js | 22 + src/redux/openFamilyTabs.js | 15 +- src/redux/reducers.js | 6 +- src/redux/requests.js | 7 +- src/redux/selectedWithFab.js | 63 +- src/redux/uniqueTokens.js | 68 +- src/redux/uniswap.js | 44 +- src/redux/walletconnect.js | 12 +- src/screens/ExampleScreen.js | 29 + src/screens/ImportSeedPhraseSheet.js | 8 +- src/screens/ImportSeedPhraseSheetWithData.js | 53 +- src/screens/Routes.js | 2 + src/screens/SettingsModal.js | 1 + .../TransactionConfirmationScreenWithData.js | 4 +- src/screens/WalletConnectConfirmationModal.js | 58 +- src/screens/WalletScreen.js | 49 +- src/styles/buildLayoutStyles.js | 22 +- src/styles/colors.js | 23 +- src/styles/margin.js | 2 +- src/styles/padding.js | 2 +- src/styles/position.js | 8 + yarn.lock | 1925 ++++++----------- 108 files changed, 3191 insertions(+), 2848 deletions(-) create mode 100644 config/test/jest-setup.js delete mode 100644 src/components/Shimmer.js rename src/components/asset-list/{AssetListSkeleton.js => EmptyAssetList.js} (62%) delete mode 100644 src/components/icons/svg/AssetListItemSkeletonIcon.js create mode 100644 src/components/layout/ColumnWithDividers.js create mode 100644 src/components/layout/LayoutWithDividers.js create mode 100644 src/components/layout/RowWithDividers.js delete mode 100644 src/components/list/SectionList.js create mode 100644 src/handlers/__tests__/web3.test.js create mode 100644 src/hoc/withFabSelection.js create mode 100644 src/hoc/withIsWalletEthZero.js create mode 100644 src/hoc/withIsWalletImporting.js create mode 100644 src/model/__tests__/wallet.test.js create mode 100644 src/redux/isWalletEthZero.js create mode 100644 src/redux/isWalletImporting.js create mode 100644 src/screens/ExampleScreen.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 198843126c4..73e70494029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,11 +12,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ### Removed -## [1.1.0-7](https://github.com/rainbow-me/rainbow/releases/tag/v1.1.0-7) +## [1.1.4-1](https://github.com/rainbow-me/rainbow/releases/tag/v1.1.4-1) ### Added +* Support for importing private key and seed key * Collectibles grouped by families * Uniswap liquidity tokens -* Drag-able send fab over tokens and collectibles ### Changed * WalletConnect support for RPC methods diff --git a/android/app/build.gradle b/android/app/build.gradle index 1300f224a10..7efec0dde67 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -153,6 +153,7 @@ android { } dependencies { + implementation project(':@react-native-community_masked-view') implementation project(':@segment_analytics-react-native') implementation project(':react-native-firebase') implementation project(':@staltz_react-native-tcp') diff --git a/android/app/src/main/java/com/rainbow/MainApplication.java b/android/app/src/main/java/com/rainbow/MainApplication.java index c750cd43314..c0dcf6a0001 100644 --- a/android/app/src/main/java/com/rainbow/MainApplication.java +++ b/android/app/src/main/java/com/rainbow/MainApplication.java @@ -3,6 +3,7 @@ import android.app.Application; import com.facebook.react.ReactApplication; +import org.reactnative.maskedview.RNCMaskedViewPackage; import com.segment.analytics.reactnative.core.RNAnalyticsPackage; import io.invertase.firebase.RNFirebasePackage; import react-native-tcp.TcpSocketsModule; @@ -58,6 +59,7 @@ public boolean getUseDeveloperSupport() { protected List getPackages() { return Arrays.asList( new MainReactPackage(), + new RNCMaskedViewPackage(), new RNAnalyticsPackage(), new RNFirebasePackage(), new TcpSocketsModule(), diff --git a/android/settings.gradle b/android/settings.gradle index 838fc231cd5..68970552dbf 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'Rainbow' +include ':@react-native-community_masked-view' +project(':@react-native-community_masked-view').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/masked-view/android') include ':@segment_analytics-react-native' project(':@segment_analytics-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/@segment/analytics-react-native/android') include ':react-native-firebase' diff --git a/config/test/jest-setup.js b/config/test/jest-setup.js new file mode 100644 index 00000000000..c582ef34605 --- /dev/null +++ b/config/test/jest-setup.js @@ -0,0 +1,7 @@ +jest.autoMockOff(); +jest.mock('react-native-keychain', () => ({ + setGenericPassword: jest.fn(), + getGenericPassword: jest.fn(), + resetGenericPassword: jest.fn() +})); + diff --git a/ios/Podfile b/ios/Podfile index 9955b6cdd9e..d10121ad511 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -15,33 +15,32 @@ target 'Rainbow' do pod 'Firebase/Messaging', '~> 5.3.0' # Core React - pod 'React', :path => "#{rn_path}", :subspecs => [ - 'Core', - 'CxxBridge', # Include this for RN >= 0.47 - 'cxxreact', - 'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43 - 'fishhook', - 'jsi', - 'jsiexecutor', - 'jsinspector', - 'RCTActionSheet', - 'RCTAnimation', # Needed for FlatList and animations running on native UI thread - 'RCTBlob', - 'RCTImage', - 'RCTLinkingIOS', - 'RCTNetwork', - 'RCTPushNotification', - 'RCTSettings', - 'RCTText', - 'RCTVibration', - 'RCTWebSocket', # needed for debugging - ] + pod 'React', :path => '../node_modules/react-native/' + pod 'React-Core', :path => '../node_modules/react-native/React' + pod 'React-DevSupport', :path => '../node_modules/react-native/React' + pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' + pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' + pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' + pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' + pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' + pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' + pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' + pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' + pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' + pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' + pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' + + pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' + pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' + pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' + pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' + # React Third Party - required - pod 'yoga', path: "#{rn_path}/ReactCommon/yoga" - pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec" - pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec" - pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec" + pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' + pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' + pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' + pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' # React-Native-Community packages pod 'react-native-blur', :path => '../node_modules/@react-native-community/blur' @@ -59,9 +58,12 @@ target 'Rainbow' do pod 'RNLanguages', :path => '../node_modules/react-native-languages' pod 'RNReanimated', :path => '../node_modules/react-native-reanimated' pod 'RNScreens', :path => '../node_modules/react-native-screens' + pod 'RNStoreReview', :path => '../node_modules/react-native-store-review/ios' pod 'FLAnimatedImage' pod 'libwebp' pod 'RNAnalytics', :path => '../node_modules/@segment/analytics-react-native' + pod 'RNCMaskedView', :path => '../node_modules/@react-native-community/masked-view' + end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e18401b9851..524da25ca05 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,7 +1,7 @@ PODS: - Analytics (3.6.10) - boost-for-react-native (1.63.0) - - BVLinearGradient (2.5.4): + - BVLinearGradient (2.5.6): - React - Crashlytics (3.10.9): - Fabric (~> 1.7.13) @@ -31,6 +31,11 @@ PODS: - Protobuf (~> 3.1) - FLAnimatedImage (1.0.12) - Folly (2018.10.22.00): + - boost-for-react-native + - DoubleConversion + - Folly/Default (= 2018.10.22.00) + - glog + - Folly/Default (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog @@ -70,17 +75,61 @@ PODS: - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - Protobuf (3.7.0) - - React (0.59.9): - - React/Core (= 0.59.9) + - React (0.60.4): + - React-Core (= 0.60.4) + - React-DevSupport (= 0.60.4) + - React-RCTActionSheet (= 0.60.4) + - React-RCTAnimation (= 0.60.4) + - React-RCTBlob (= 0.60.4) + - React-RCTImage (= 0.60.4) + - React-RCTLinking (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTSettings (= 0.60.4) + - React-RCTText (= 0.60.4) + - React-RCTVibration (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-Core (0.60.4): + - Folly (= 2018.10.22.00) + - React-cxxreact (= 0.60.4) + - React-jsiexecutor (= 0.60.4) + - yoga (= 0.60.4.React) + - React-cxxreact (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsinspector (= 0.60.4) + - React-DevSupport (0.60.4): + - React-Core (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-fishhook (0.60.4) + - React-jsi (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsi/Default (= 0.60.4) + - React-jsi/Default (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsiexecutor (0.60.4): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.60.4) + - React-jsi (= 0.60.4) + - React-jsinspector (0.60.4) - react-native-blur (0.8.0): - React - - react-native-camera (2.11.1): + - react-native-camera (2.11.2): - React - - react-native-camera/RCT (= 2.11.1) - - react-native-camera/RN (= 2.11.1) - - react-native-camera/RCT (2.11.1): + - react-native-camera/RCT (= 2.11.2) + - react-native-camera/RN (= 2.11.2) + - react-native-camera/RCT (2.11.2): - React - - react-native-camera/RN (2.11.1): + - react-native-camera/RN (2.11.2): - React - react-native-fast-image (6.1.1): - React @@ -89,65 +138,38 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React/Core (0.59.9): - - yoga (= 0.59.9.React) - - React/CxxBridge (0.59.9): - - Folly (= 2018.10.22.00) - - React/Core - - React/cxxreact - - React/jsiexecutor - - React/cxxreact (0.59.9): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React/jsinspector - - React/DevSupport (0.59.9): - - React/Core - - React/RCTWebSocket - - React/fishhook (0.59.9) - - React/jsi (0.59.9): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React/jsiexecutor (0.59.9): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React/cxxreact - - React/jsi - - React/jsinspector (0.59.9) - - React/RCTActionSheet (0.59.9): - - React/Core - - React/RCTAnimation (0.59.9): - - React/Core - - React/RCTBlob (0.59.9): - - React/Core - - React/RCTImage (0.59.9): - - React/Core - - React/RCTNetwork - - React/RCTLinkingIOS (0.59.9): - - React/Core - - React/RCTNetwork (0.59.9): - - React/Core - - React/RCTPushNotification (0.59.9): - - React/Core - - React/RCTSettings (0.59.9): - - React/Core - - React/RCTText (0.59.9): - - React/Core - - React/RCTVibration (0.59.9): - - React/Core - - React/RCTWebSocket (0.59.9): - - React/Core - - React/fishhook - - React/RCTBlob + - React-RCTActionSheet (0.60.4): + - React-Core (= 0.60.4) + - React-RCTAnimation (0.60.4): + - React-Core (= 0.60.4) + - React-RCTBlob (0.60.4): + - React-Core (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-RCTImage (0.60.4): + - React-Core (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTLinking (0.60.4): + - React-Core (= 0.60.4) + - React-RCTNetwork (0.60.4): + - React-Core (= 0.60.4) + - React-RCTSettings (0.60.4): + - React-Core (= 0.60.4) + - React-RCTText (0.60.4): + - React-Core (= 0.60.4) + - React-RCTVibration (0.60.4): + - React-Core (= 0.60.4) + - React-RCTWebSocket (0.60.4): + - React-Core (= 0.60.4) + - React-fishhook (= 0.60.4) - RNAnalytics (1.0.1): - Analytics - React - RNCAsyncStorage (1.5.0): - React - - RNDeviceInfo (2.2.2): + - RNCMaskedView (0.1.1): + - React + - RNDeviceInfo (2.3.2): - React - RNIOS11DeviceCheck (0.0.3): - React @@ -157,10 +179,12 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React + - RNStoreReview (0.1.5): + - React - SDWebImage (5.0.2): - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) - - yoga (0.59.9.React) + - yoga (0.60.4.React) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -173,37 +197,38 @@ DEPENDENCIES: - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - libwebp + - React (from `../node_modules/react-native/`) + - React-Core (from `../node_modules/react-native/React`) + - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) + - React-DevSupport (from `../node_modules/react-native/React`) + - React-fishhook (from `../node_modules/react-native/Libraries/fishhook`) + - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) + - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) + - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-camera (from `../node_modules/react-native-camera`) - react-native-fast-image (from `../node_modules/react-native-fast-image`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-version-number (from `../node_modules/react-native-version-number`) - - React/Core (from `../node_modules/react-native`) - - React/CxxBridge (from `../node_modules/react-native`) - - React/cxxreact (from `../node_modules/react-native`) - - React/DevSupport (from `../node_modules/react-native`) - - React/fishhook (from `../node_modules/react-native`) - - React/jsi (from `../node_modules/react-native`) - - React/jsiexecutor (from `../node_modules/react-native`) - - React/jsinspector (from `../node_modules/react-native`) - - React/RCTActionSheet (from `../node_modules/react-native`) - - React/RCTAnimation (from `../node_modules/react-native`) - - React/RCTBlob (from `../node_modules/react-native`) - - React/RCTImage (from `../node_modules/react-native`) - - React/RCTLinkingIOS (from `../node_modules/react-native`) - - React/RCTNetwork (from `../node_modules/react-native`) - - React/RCTPushNotification (from `../node_modules/react-native`) - - React/RCTSettings (from `../node_modules/react-native`) - - React/RCTText (from `../node_modules/react-native`) - - React/RCTVibration (from `../node_modules/react-native`) - - React/RCTWebSocket (from `../node_modules/react-native`) + - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) + - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) + - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) + - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) + - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) + - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) + - React-RCTText (from `../node_modules/react-native/Libraries/Text`) + - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" + - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNIOS11DeviceCheck (from `../node_modules/react-native-ios11-devicecheck/ios`) - RNLanguages (from `../node_modules/react-native-languages`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) + - RNStoreReview (from `../node_modules/react-native-store-review/ios`) - yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -234,7 +259,21 @@ EXTERNAL SOURCES: glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" React: - :path: "../node_modules/react-native" + :path: "../node_modules/react-native/" + React-Core: + :path: "../node_modules/react-native/React" + React-cxxreact: + :path: "../node_modules/react-native/ReactCommon/cxxreact" + React-DevSupport: + :path: "../node_modules/react-native/React" + React-fishhook: + :path: "../node_modules/react-native/Libraries/fishhook" + React-jsi: + :path: "../node_modules/react-native/ReactCommon/jsi" + React-jsiexecutor: + :path: "../node_modules/react-native/ReactCommon/jsiexecutor" + React-jsinspector: + :path: "../node_modules/react-native/ReactCommon/jsinspector" react-native-blur: :path: "../node_modules/@react-native-community/blur" react-native-camera: @@ -245,10 +284,32 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/netinfo" react-native-version-number: :path: "../node_modules/react-native-version-number" + React-RCTActionSheet: + :path: "../node_modules/react-native/Libraries/ActionSheetIOS" + React-RCTAnimation: + :path: "../node_modules/react-native/Libraries/NativeAnimation" + React-RCTBlob: + :path: "../node_modules/react-native/Libraries/Blob" + React-RCTImage: + :path: "../node_modules/react-native/Libraries/Image" + React-RCTLinking: + :path: "../node_modules/react-native/Libraries/LinkingIOS" + React-RCTNetwork: + :path: "../node_modules/react-native/Libraries/Network" + React-RCTSettings: + :path: "../node_modules/react-native/Libraries/Settings" + React-RCTText: + :path: "../node_modules/react-native/Libraries/Text" + React-RCTVibration: + :path: "../node_modules/react-native/Libraries/Vibration" + React-RCTWebSocket: + :path: "../node_modules/react-native/Libraries/WebSocket" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: :path: "../node_modules/@react-native-community/async-storage" + RNCMaskedView: + :path: "../node_modules/@react-native-community/masked-view" RNDeviceInfo: :path: "../node_modules/react-native-device-info" RNIOS11DeviceCheck: @@ -259,44 +320,65 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" + RNStoreReview: + :path: "../node_modules/react-native-store-review/ios" yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c - BVLinearGradient: 8cbc5155c978f2e43098818c91d206d07aae6d30 + BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c - DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd + DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 - FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d - FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 - FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 - FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 + Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa + FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 + FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 + FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 + FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 - Folly: de497beb10f102453a1afa9edbf8cf8a251890de - glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d + Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 + glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a - React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f + React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 + React-Core: 8e0ea421cae5609d2562850f98421b15030476fa + React-cxxreact: 326880209990151a7182a813311054e9772ba510 + React-DevSupport: e9f10e6721e78e87622fc985db695c0c0168db8a + React-fishhook: 1f0e5b08449403fa75c3fb3881a0beefbada14af + React-jsi: 21d3153b1153fbf6510a92b6b11e33e725cb7432 + React-jsiexecutor: 7549641e48bafae7bfee3f3ea19bf4901639c5de + React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: f1fbfc336ba8ca6de5296190341d1b6022c71cff + react-native-camera: 375843010be62aed072d83c9df30efdeb3c8cbcb react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 - react-native-netinfo: 0da34082d2cec3100c9b5073bb217e35f1142bdd - react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f + react-native-netinfo: 27d908bc7ee7b9f29400c02938a0b2a27a1015be + react-native-version-number: 15563dc4145a94aabfc1faab2a9af10174a4204e + React-RCTActionSheet: 9f71d7ae3e8fb10e08d162cbf14c621349dbfab3 + React-RCTAnimation: 981d8c95b0e30918a9832ccac32af83562a27fae + React-RCTBlob: 21e73d1020a302a75fed30dbaee9f15287b80baa + React-RCTImage: c0bc6ac0926517b6fb7e4c279b04843113e99d1d + React-RCTLinking: 1af3f3c59114bed3deec0107c62e7efad0932ee5 + React-RCTNetwork: 35df9de46e19cda5c56380be1a7759b9b8cb2fcd + React-RCTSettings: f580504c2cd1f44e25add10fb9ed3954f67f8ac5 + React-RCTText: e0f224898b13af9aa036ea7cb3d438daa68c1044 + React-RCTVibration: 0bea40cd51bd089bd591a8f74c86e91fdf2666c5 + React-RCTWebSocket: 163873f4cdd5f1058a9483443404fc3801581cb6 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 - RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 - RNDeviceInfo: 1215084f45c1059b031c530281442dc7079ccf0a - RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa + RNCAsyncStorage: 63407ea82f1b5ac8fc53a0b8c569b08e0516a9e0 + RNCMaskedView: 6200428cc4fb088ee7ae64a648e39bd8f4e70b41 + RNDeviceInfo: bdc3e922b2ed0f086e9d9ab534e61bc316f08576 + RNIOS11DeviceCheck: d525b786c29d2793f8534bd3a321998a7a827a5f RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 7a52c90473b5e81c13408d40d797b98387eaddde RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 + RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 - yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee + yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 -PODFILE CHECKSUM: 36995f140ff80c2bc171b1dba21e18a683124fe8 +PODFILE CHECKSUM: 2faf7ebfb07db0bc35d060386204981cb07de5b7 -COCOAPODS: 1.6.1 +COCOAPODS: 1.7.0 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 93e3f8d6fb5..a0f4a92e61a 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -7,26 +7,17 @@ objects = { /* Begin PBXBuildFile section */ - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 00E356F31AD99517003FC87E /* RainbowTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RainbowTests.m */; }; 03252948A60F4C4C87E4FD9E /* SF-Pro-Display-Ultralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */; }; 06B78001D9F2456D9C2D4A86 /* Graphik-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */; }; 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */; }; 0AB30EE90F554EE59F57DFC1 /* SF-Pro-Display-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */; }; 0F4372360E744AF4B37EB905 /* Graphik-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */; }; - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D755E71324B04FEE9C691D14 /* libRNFirebase.a */; }; 16934DFE7F154B06ADAD8A0B /* SF-Pro-Display-ThinItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */; }; 184EB33331FB47F2960D2507 /* SF-Pro-Display-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */; }; @@ -57,7 +48,6 @@ 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */; }; 549287401A7648CCB32F36E0 /* SF-Pro-Display-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */; }; 5D1949044DCB413FBE7AE82E /* SFMono-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */; }; - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 5F34DEED060F41878C4C5A59 /* SFMono-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */; }; 66620AB752074CB6938E956A /* Graphik-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */; }; 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; @@ -65,7 +55,6 @@ 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */; }; - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 872630C5E4CA448D8DDC783E /* Graphik-Extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */; }; 87808B52A9E224F3D11532B5 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 823BD6129C8AA3FD7CDD46BE /* libPods-Rainbow.a */; }; 8B7F7FDAB33B4D119E087D57 /* Graphik-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */; }; @@ -77,7 +66,6 @@ 96E52368EDC94B9B80D1F29C /* SF-Pro-Text-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */; }; 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EA95F99E656542F790F685B6 /* libSplashScreen.a */; }; 9E8553031AD44F52A814F2AB /* SF-Pro-Display-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */; }; - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; }; AE47B46652EA48AFB68E7832 /* SF-Pro-Text-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */; }; AFCABA638327463693E67FD4 /* SF-Pro-Text-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */; }; AFD75D0B6EC9465C92C493A7 /* SF-Pro-Display-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */; }; @@ -93,6 +81,7 @@ D77132C4B96040C39FED1AD5 /* libUdpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5AC94663BD4242A29273D66F /* libUdpSockets.a */; }; DBBDEB86E54044EE8712C882 /* Graphik-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEC826911B5641B8AF788BB3 /* Graphik-BlackItalic.otf */; }; E98BBF45029948B38545996F /* Graphik-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = E6F010E529544E518E1792C7 /* Graphik-Bold.otf */; }; + EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 91A43F69E797469687978D51 /* libRNStoreReview.a */; }; ECF14FECD39C459D86EDCB82 /* libCodePush.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E39434CDDE4C54848FBFD5 /* libCodePush.a */; }; ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; }; ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A014AE1645874354A732EB35 /* libToolTipMenu.a */; }; @@ -111,13 +100,6 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RCTActionSheet; }; - 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTGeolocation; - }; 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -216,6 +198,13 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RNFirebase; }; + 2488BC2C22E97316006847C7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RNStoreReview; + }; 24979D5C20F83E3E007EB0DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */; @@ -585,7 +574,6 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; @@ -640,6 +628,7 @@ 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-MediumItalic.otf"; path = "../src/assets/fonts/Graphik-MediumItalic.otf"; sourceTree = ""; }; 2DB932A7706945C787DE22A6 /* SplashScreen.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = SplashScreen.xcodeproj; path = "../node_modules/react-native-splash-screen/ios/SplashScreen.xcodeproj"; sourceTree = ""; }; 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSRSRadialGradient.a; sourceTree = ""; }; + 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNStoreReview.xcodeproj; path = "../node_modules/react-native-store-review/ios/RNStoreReview.xcodeproj"; sourceTree = ""; }; 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-MediumItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-MediumItalic.otf"; sourceTree = ""; }; 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Ultralight.otf"; path = "../src/assets/fonts/SF-Pro-Display-Ultralight.otf"; sourceTree = ""; }; 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Text-Medium.otf"; sourceTree = ""; }; @@ -684,6 +673,7 @@ 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNRandomBytes.a; sourceTree = ""; }; 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Display-Heavy.otf"; sourceTree = ""; }; 9165B952731E4502857CC0B4 /* SF-Pro-Display-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Regular.otf"; path = "../src/assets/fonts/SF-Pro-Display-Regular.otf"; sourceTree = ""; }; + 91A43F69E797469687978D51 /* libRNStoreReview.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNStoreReview.a; sourceTree = ""; }; 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Extralight.otf"; path = "../src/assets/fonts/Graphik-Extralight.otf"; sourceTree = ""; }; 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Regular.otf"; path = "../src/assets/fonts/SF-Pro-Text-Regular.otf"; sourceTree = ""; }; 95F2888C850F40C8A26E083B /* SFMono-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Regular.otf"; path = "../src/assets/fonts/SFMono-Regular.otf"; sourceTree = ""; }; @@ -748,19 +738,6 @@ buildActionMask = 2147483647; files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 146834051AC3E58100842450 /* libReact.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */, 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */, 94822FBFCA7246168685FA85 /* libRNMail.a in Frameworks */, @@ -781,6 +758,7 @@ F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */, 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, 87808B52A9E224F3D11532B5 /* libPods-Rainbow.a in Frameworks */, + EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -795,14 +773,6 @@ name = Products; sourceTree = ""; }; - 00C302B61ABCB90400DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, - ); - name = Products; - sourceTree = ""; - }; 00C302BC1ABCB91800DB3ED1 /* Products */ = { isa = PBXGroup; children = ( @@ -920,6 +890,14 @@ name = Products; sourceTree = ""; }; + 2488BC2922E97315006847C7 /* Products */ = { + isa = PBXGroup; + children = ( + 2488BC2D22E97316006847C7 /* libRNStoreReview.a */, + ); + name = Products; + sourceTree = ""; + }; 24979D1220F83E3D007EB0DA /* Recovered References */ = { isa = PBXGroup; children = ( @@ -945,6 +923,7 @@ 3A7E5E09E14B4EA4B52CC6EE /* libRNGestureHandler.a */, 22E39434CDDE4C54848FBFD5 /* libCodePush.a */, D755E71324B04FEE9C691D14 /* libRNFirebase.a */, + 91A43F69E797469687978D51 /* libRNStoreReview.a */, ); name = "Recovered References"; sourceTree = ""; @@ -1158,7 +1137,6 @@ 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */, - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, @@ -1184,6 +1162,7 @@ 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */, 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */, 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */, + 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1415,10 +1394,6 @@ ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */; ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; }, - { - ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; - ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - }, { ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -1491,6 +1466,10 @@ ProductGroup = 244C64062108794F007A5856 /* Products */; ProjectRef = 1A7B7E90124047F8A3CA4B84 /* RNReactNativeHapticFeedback.xcodeproj */; }, + { + ProductGroup = 2488BC2922E97315006847C7 /* Products */; + ProjectRef = 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */; + }, { ProductGroup = 24979D5420F83E3E007EB0DA /* Products */; ProjectRef = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; @@ -1536,13 +1515,6 @@ remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTGeolocation.a; - remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1634,6 +1606,13 @@ remoteRef = 2481F3202261753900D0349A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 2488BC2D22E97316006847C7 /* libRNStoreReview.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNStoreReview.a; + remoteRef = 2488BC2C22E97316006847C7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 24979D5D20F83E3E007EB0DA /* libBVLinearGradient.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -2200,6 +2179,7 @@ "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -2207,6 +2187,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2247,6 +2228,7 @@ "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -2254,6 +2236,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2302,6 +2285,7 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2355,6 +2339,7 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2443,6 +2428,7 @@ "$(SRCROOT)/../node_modules/react-native-code-push/ios/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2487,6 +2473,7 @@ "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -2494,6 +2481,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2579,6 +2567,7 @@ "$(SRCROOT)/../node_modules/react-native-code-push/ios/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2624,6 +2613,7 @@ "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", + "$(SRCROOT)/../node_modules/react-native-store-review/ios", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -2631,6 +2621,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index b4218cc13a3..fdd8318f7d2 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.1.0 + 1.1.5 CFBundleSignature ???? CFBundleURLTypes @@ -34,11 +34,17 @@ CFBundleVersion - 7 + 1 CodePushDeploymentKey $(CODEPUSH_KEY) ITSAppUsesNonExemptEncryption + LSApplicationQueriesSchemes + + itms + itms-apps + twitter + LSRequiresIPhoneOS NSAppTransportSecurity diff --git a/package.json b/package.json index 947cbaecad4..96f644c9c35 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "Rainbow", - "version": "1.1.0-7", + "version": "1.1.5-1", "private": true, "scripts": { "clean": "react-native-clean-project", - "start": "node node_modules/react-native/local-cli/cli.js start", + "start": "react-native start", "test": "jest test.js", "install-pods": "cd ios && pod install && cd ..", "ios": "react-native run-ios --simulator='iPhone X'", @@ -18,11 +18,12 @@ "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.5.0", "@react-native-community/blur": "^3.3.1", + "@react-native-community/masked-view": "^0.1.1", "@react-native-community/netinfo": "^3.2.1", "@segment/analytics-react-native": "^1.0.1", "@staltz/react-native-tcp": "^3.3.1", "@tradle/react-native-http": "^2.0.1", - "@walletconnect/react-native": "^1.0.0-beta.26", + "@walletconnect/react-native": "^1.0.0-beta.29", "assert": "^1.4.1", "asyncstorage-down": "^4.2.0", "axios": "^0.19.0", @@ -31,34 +32,34 @@ "buffer": "^4.9.1", "chroma-js": "^1.3.7", "code-push": "^2.0.6", - "color": "^3.0.0", "console-browserify": "^1.1.0", "constants-browserify": "^1.0.0", - "date-fns": "^1.29.0", + "date-fns": "^1.30.1", + "delay": "^4.3.0", "dns.js": "^1.0.1", "domain-browser": "^1.2.0", "eth-contract-metadata": "^1.9.2", - "ethers": "^4.0.31", + "ethers": "^4.0.33", "events": "^1.1.1", "global": "^4.3.2", "https-browserify": "0.0.1", "i18n-js": "^3.0.11", "i18next": "^17.0.3", - "immer": "^1.7.4", + "immer": "^3.1.3", "inherits": "^2.0.3", - "lodash": "^4.17.13", + "lodash": "^4.17.15", "nanoid": "^2.0.3", "patch-package": "^6.1.2", "path-browserify": "0.0.0", "postcss": "^7.0.13", "postinstall-postinstall": "^2.0.0", "process": "^0.11.10", - "prop-types": "^15.6.1", + "prop-types": "^15.7.2", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "react": "16.8.3", - "react-coin-icon": "^0.1.8", - "react-native": "0.59.9", + "react": "16.8.6", + "react-coin-icon": "^0.1.9", + "react-native": "0.60.4", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", @@ -70,7 +71,7 @@ "react-native-fast-image": "^6.0.3", "react-native-firebase": "^4.3.8", "react-native-gesture-handler": "^1.3.0", - "react-native-haptic-feedback": "^1.8.0", + "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", @@ -86,18 +87,19 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "1.1.0", + "react-native-redash": "^7.2.1", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", - "react-native-screens": "^1.0.0-alpha.22", - "react-native-shimmer-placeholder": "^1.0.29", + "react-native-screens": "^1.0.0-alpha.23", "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", + "react-native-store-review": "^0.1.5", "react-native-svg": "^9.5.1", "react-native-tcp": "^3.3.0", "react-native-tooltip": "^5.2.0", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", - "react-navigation": "^3.11.0", + "react-navigation": "^3.11.1", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", @@ -124,8 +126,8 @@ "vm-browserify": "0.0.4" }, "devDependencies": { - "@babel/core": "^7.4.5", - "@babel/runtime": "^7.4.5", + "@babel/core": "^7.5.5", + "@babel/runtime": "^7.5.5", "@react-native-community/cli": "2.0.0-rc.2", "@react-native-community/eslint-config": "^0.0.5", "babel-core": "7.0.0-bridge.0", @@ -133,7 +135,8 @@ "babel-jest": "^24.8.0", "babel-plugin-date-fns": "^0.2.1", "babel-plugin-lodash": "^3.3.4", - "babel-plugin-styled-components": "^1.10.2", + "babel-plugin-styled-components": "^1.10.6", + "babel-plugin-rewire": "^1.2.0", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", "eslint": "^5.16.0", @@ -143,7 +146,7 @@ "eslint-plugin-react-native": "^3.7.0", "eslint-plugin-react-native-animation-linter": "^0.1.2", "jest": "^24.8.0", - "metro-react-native-babel-preset": "^0.54.1", + "metro-react-native-babel-preset": "^0.55.0", "mocha": "^6.1.4", "react-native-clean-project": "^3.1.0", "react-test-renderer": "16.8.3", @@ -154,7 +157,10 @@ "**/resolve": "1.8.1" }, "jest": { - "preset": "react-native" + "preset": "react-native", + "setupFiles": [ + "./config/test/jest-setup.js" + ] }, "rnpm": { "assets": [ diff --git a/patches/recyclerlistview+2.0.1-alpha.1.patch b/patches/recyclerlistview+2.0.1-alpha.1.patch index 64fb161ecf5..f4d9d630724 100644 --- a/patches/recyclerlistview+2.0.1-alpha.1.patch +++ b/patches/recyclerlistview+2.0.1-alpha.1.patch @@ -1,3 +1,54 @@ +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js +index e3af431..8de1ec4 100644 +--- a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js ++++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js +@@ -54,14 +54,14 @@ var StickyContainer = /** @class */ (function (_super) { + } + }; + _this._getStickyHeaderRef = function (stickyHeaderRef) { +- if (!_this._stickyHeaderRef) { ++ if (_this._stickyHeaderRef !== stickyHeaderRef) { + _this._stickyHeaderRef = stickyHeaderRef; + // TODO: Resetting state once ref is initialized. Can look for better solution. + _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); + } + }; + _this._getStickyFooterRef = function (stickyFooterRef) { +- if (!_this._stickyFooterRef) { ++ if (_this._stickyFooterRef !== stickyFooterRef) { + _this._stickyFooterRef = stickyFooterRef; + // TODO: Resetting state once ref is initialized. Can look for better solution. + _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js +index 26e19af..e2a2913 100644 +--- a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js +@@ -36,9 +36,8 @@ var ViewabilityTracker = /** @class */ (function () { + this._windowBound = isHorizontal ? dimension.width : dimension.height; + }; + ViewabilityTracker.prototype.forceRefresh = function () { +- var shouldForceScroll = this._currentOffset >= (this._maxOffset - this._windowBound); + this.forceRefreshWithOffset(this._currentOffset); +- return shouldForceScroll; ++ return false; + }; + ViewabilityTracker.prototype.forceRefreshWithOffset = function (offset) { + this._currentOffset = -1; +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js +index 3851852..23075a0 100644 +--- a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js ++++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js +@@ -172,6 +172,10 @@ var WrapGridLayoutManager = /** @class */ (function (_super) { + } + var i = startIndex - 1; + for (; i >= 0; i--) { ++ if (!this._layouts[i]) { ++ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line ++ continue; ++ } + if (this._isHorizontal) { + if (this._layouts[i].y === 0) { + break; diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js index 7074f36..5e72f6e 100644 --- a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js diff --git a/src/App.js b/src/App.js index f260686662f..29e71f60e14 100644 --- a/src/App.js +++ b/src/App.js @@ -18,7 +18,6 @@ import { compose, withProps } from 'recompact'; import { FlexItem } from './components/layout'; import OfflineBadge from './components/OfflineBadge'; import { - withDataInit, withWalletConnectConnections, withWalletConnectOnSessionRequest, } from './hoc'; @@ -43,7 +42,6 @@ useScreens(); class App extends Component { static propTypes = { appInitTimestamp: PropTypes.number, - initializeWallet: PropTypes.func, requestsForTopic: PropTypes.func, sortedWalletConnectors: PropTypes.arrayOf(PropTypes.object), walletConnectClearTimestamp: PropTypes.func, @@ -106,7 +104,6 @@ class App extends Component { await this.setInitialStatesForOpenAssets(); AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); - await this.props.initializeWallet(); await this.handleInitializeAnalytics(); firebase.notifications().getInitialNotification().then(notificationOpen => { if (notificationOpen) { @@ -197,7 +194,6 @@ class App extends Component { const AppWithRedux = compose( withProps({ store }), - withDataInit, withWalletConnectConnections, withWalletConnectOnSessionRequest, connect( diff --git a/src/assets/family-dropdown-arrow.png b/src/assets/family-dropdown-arrow.png index 112863ed81709bd69ac692b447fe04ad221fffa3..a800285173f7ab2577031cd9194dd2b803c8b00e 100644 GIT binary patch delta 440 zcmV;p0Z0D*0>1+xiBL{Q4GJ0x0000DNk~Le000090000H2nGNE01p&~=8+*2e|AYk zK~yLejgh-c13?hRXKoXNDNAWnfSF)mhI`!%e^a+VE zCUM}J$6-5ZWM=y?z#6s6i>zn}f54|X;Cx&gK60wBPB%=Kbj>*?jO+m=iwO7>jbPrg ztY!d8B0)qR8w{<`Zc*vP#~0r(7KvJB*Rh9;E;jugSL=&SA_&f4KD<4=#gU zDAB|Pp)>%Y^FNSoWD7Lmj(9+Jtd+~xl^)12%n|D4kje}Yv-Nmi+7oaGGEFnu;_YKH zR3VMC?1a7{01^LpTsLx?;!DW-CWgZc-CyD>B`0%JZri;eQIAP5_fRhRF8g(U7s>NH ivI1=hVZ9$9xF4~MmHW5r4uGow0000=1N{OaiBL{Q4GJ0x0000DNk~Le000070000F2nGNE04M>~zL6mle>6!% zK~xwSV^-7DTP7kdVet0#%l!;!fQf;TQSRTr|21mb2H9wG3`}fHY>^C%3@;h}|DT|) zt>=WSfDy#e&@r(3_wOIb*e`5MtY%lPoV^PYX95v7u3R|wpOGp3|9=Ldpa1@BGB-Ep z1Bo+(2oQMp`o#qiF$q4P@qRykfBx0W&BLx7HlU- z0tPfS4dwqZ{Jqb}$hZ@1CrlzVG?e)-|NhMf2Ff)dUJlEXCr^HY`}6PLfBP628NMR>lUYZ{RQC73OFw&o4&Vk# z`dz_Aesf}=|@aVjQek1y)YG70>lOY8gOuW T&da`~00000NkvXXu0mjfU!<%7 diff --git a/src/assets/family-dropdown-arrow@2x.png b/src/assets/family-dropdown-arrow@2x.png index 9c2ec6cb03cac8c5014cc77ce7f6dd414fca0e9b..0579ce1de4de835339c694af4c72df271aa4f1c0 100644 GIT binary patch literal 906 zcmV;519kj~P)K_RAWiXqac|0NNk~%LKA6BFxq%9Bt{a9i3xhs z7%}m26Xn9iL{AzI#uz;qm6HbodIRMkF=;hW?1Pf{I$$M*#sm%p+JBt=+x@$L-|T^z z`SzRdpPkumpahrI(bY{9VagxVp0ZrQXuqjP8-_Hrck&(PSZE6}>a#mx@pXx15R)jhv*cu2f7;(yz5>~t-L29+sUBYJjM9eJ^ zxNWm{@uO?2V6(N|jAL`TS|FkLP@qNHOW@H@EC&5vj^&+IB5H1AcJ>c4`w>WJAR$H^ z#aKtjF*CsJBk;mgP!iF-IbB73{?6SB+T&QeC)w^n6;#KbDWU=r_4;I7zha%>-WJTDQAru*q z6L8?~2F~~2)nka}0wQj6IM1Z;=3<=v7^NX*-hDJOGqWam!WI-N_OR_>)$TyxtJ+*4 zAZ+$)8H7KzNdn{g*O5Q9^jt9!o~jeV300-mHr~qbwW?3)%~J1mp3qY4-(!4jJZiG| zL+R7S;M@}t7PDGKwsz+r{v$D{C(`NKomDsVSm8)*_MvvyaY~gb{2f&Z8s3$k%v968 z;PtKwtdvzNLXmrV5wd2ehQ3Ng_y^KQ16|V<$_y97^YejH73A)vg&4hsXN=(ej3IC( g5}X~+C6q8jl-bMkyccZ1+9O=YRaP+klDy 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 Y0f~QZH=752C;$Ke07*qoM6N<$f?WJ6F#rGn diff --git a/src/components/AddFundsInterstitial.js b/src/components/AddFundsInterstitial.js index 5d952dad81f..cc380584796 100644 --- a/src/components/AddFundsInterstitial.js +++ b/src/components/AddFundsInterstitial.js @@ -62,7 +62,7 @@ const AddFundsInterstitial = ({ Import Wallet - Use your 12 to 24 word seed phrase from an existing wallet. + Use your private key or 12 to 24 word seed phrase from an existing wallet.
diff --git a/src/components/Divider.js b/src/components/Divider.js index 697141be727..ffa5b1b68bb 100644 --- a/src/components/Divider.js +++ b/src/components/Divider.js @@ -8,7 +8,6 @@ import PropTypes from 'prop-types'; import React from 'react'; import { onlyUpdateForKeys } from 'recompact'; import styled, { css } from 'styled-components/primitives'; -import { Row } from './layout'; import { borders, colors, position } from '../styles'; const DefaultDividerSize = 2; @@ -53,7 +52,7 @@ const BorderLine = styled.View` top: 0; `; -const Container = styled(Row)` +const Container = styled.View` background-color: ${({ backgroundColor }) => (backgroundColor || colors.white)}; flex-shrink: 0; height: ${({ horizontal, size }) => (horizontal ? size : '100%')}; diff --git a/src/components/Highlight.js b/src/components/Highlight.js index 5d525fa740d..5ef58f593ec 100644 --- a/src/components/Highlight.js +++ b/src/components/Highlight.js @@ -1,14 +1,34 @@ -import styled from 'styled-components/primitives'; -import { colors } from '../styles/index'; -import Flex from './layout/Row'; - -export default styled(Flex)` - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; - margin: 7px; - background-color: ${({ highlight }) => (highlight ? colors.highlightBackground : colors.transparent)}; - border-radius: 10; -`; +import PropTypes from 'prop-types'; +import React from 'react'; +import { onlyUpdateForKeys } from 'recompact'; +import { View } from 'react-primitives'; +import { colors, position } from '../styles'; + +const Highlight = ({ + backgroundColor, + borderRadius, + visible, + ...props +}) => ( + +); + +Highlight.propTypes = { + backgroundColor: PropTypes.string, + borderRadius: PropTypes.number, + visible: PropTypes.bool, +}; + +Highlight.defaultProps = { + backgroundColor: colors.highlightBackground, + borderRadius: 10, +}; + +export default onlyUpdateForKeys(['visible'])(Highlight); diff --git a/src/components/Shimmer.js b/src/components/Shimmer.js deleted file mode 100644 index 440d028a25e..00000000000 --- a/src/components/Shimmer.js +++ /dev/null @@ -1,59 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ShimmerPlaceHolder from 'react-native-shimmer-placeholder'; -import styled from 'styled-components/primitives'; -import { colors, position } from '../styles'; - -const ShimmerElement = styled(ShimmerPlaceHolder)` - ${position.cover} - background-color: ${colors.transparent}; -`; - -const generateColorShimmerTheme = (color, opacity) => ([ - colors.alpha(color, opacity * 0.166), - colors.alpha(color, opacity * 0.333), - colors.alpha(color, opacity), - colors.alpha(color, opacity * 0.333), - colors.alpha(color, opacity * 0.166), -]); - -const Shimmer = ({ - autoRun, - backgroundColorBehindBorder, - color, - duration, - height, - opacity, - width, - ...props -}) => ( - -); - -Shimmer.propTypes = { - autoRun: PropTypes.bool, - backgroundColorBehindBorder: PropTypes.string, - color: PropTypes.string, - duration: PropTypes.number, - height: PropTypes.number.isRequired, - opacity: PropTypes.number, - width: PropTypes.number.isRequired, -}; - -Shimmer.defaultProps = { - autoRun: true, - backgroundColorBehindBorder: colors.transparent, - color: colors.white, - duration: 1000, - opacity: 0.1, -}; - -export default Shimmer; diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index dff3be2360f..cb145ac14fa 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -167,7 +167,7 @@ export default class ButtonPressAnimation extends PureComponent { enabled={!disabled} ref={tapRef} onHandlerStateChange={this.handleStateChange} - waitFor={this.props.waitFor} + waitFor={waitFor} > ( - isEmpty - ? - : ( - + ) : ( + ) ); @@ -37,8 +43,18 @@ AssetList.propTypes = { fetchData: PropTypes.func.isRequired, hideHeader: PropTypes.bool, isEmpty: PropTypes.bool, + isImporting: PropTypes.bool, + isWalletEthZero: PropTypes.bool, scrollViewTracker: PropTypes.object, sections: PropTypes.arrayOf(PropTypes.object), }; -export default onlyUpdateForKeys(['isEmpty', 'sections'])(AssetList); +export default compose( + withIsWalletImporting, + onlyUpdateForKeys([ + 'isEmpty', + 'isImporting', + 'isWalletEthZero', + 'sections', + ]), +)(AssetList); diff --git a/src/components/asset-list/AssetListItemSkeleton.js b/src/components/asset-list/AssetListItemSkeleton.js index 2400d607ee5..5ff4fd15782 100644 --- a/src/components/asset-list/AssetListItemSkeleton.js +++ b/src/components/asset-list/AssetListItemSkeleton.js @@ -1,44 +1,171 @@ +import MaskedView from '@react-native-community/masked-view'; import PropTypes from 'prop-types'; -import React from 'react'; -import { Circle, G, Rect } from 'svgs'; -import { withNeverRerender } from '../../hoc'; -import { colors, padding } from '../../styles'; -import { Svg } from '../icons'; -import { Row } from '../layout'; - -const AssetListItemSkeleton = ({ color, index }) => ( - - - - - - - - - - - - - - - -); - -AssetListItemSkeleton.propTypes = { - color: PropTypes.string, - index: PropTypes.number, -}; - -AssetListItemSkeleton.defaultProps = { - color: colors.skeleton, - index: 0, -}; - -export default withNeverRerender(AssetListItemSkeleton); +import React, { PureComponent } from 'react'; +import { View } from 'react-native'; +import LinearGradient from 'react-native-linear-gradient'; +import Animated, { Easing } from 'react-native-reanimated'; +import { withProps } from 'recompact'; +import styled from 'styled-components/primitives'; +import { colors, padding, position } from '../../styles'; +import { deviceUtils } from '../../utils'; +import { CoinRow } from '../coin-row'; +import { ColumnWithMargins, Row, RowWithMargins } from '../layout'; + +const { + block, + Clock, + cond, + interpolate, + set, + startClock, + stopClock, + timing, + Value, +} = Animated; + +const AnimatedLinearGradient = Animated.createAnimatedComponent(LinearGradient); + +const Container = styled.View` + height: ${CoinRow.height}; + opacity: ${({ descendingOpacity, index }) => (1 - (0.2 * (descendingOpacity ? index : 0)))}; + width: 100%; +`; + +const FakeAvatar = styled.View` + ${position.size(40)}; + background-color: ${colors.skeleton}; + border-radius: 20; +`; + +const FakeRow = withProps({ + align: 'center', + flex: 0, + justify: 'space-between', +})(Row); + +const FakeText = styled.View` + background-color: ${colors.skeleton}; + border-radius: 5; + height: 10; +`; + +const Wrapper = styled(RowWithMargins).attrs({ + align: 'center', + justify: 'space-between', + margin: 11, +})` + ${({ index }) => padding((index === 0 ? 15 : 12.5), 19, 12.5, 15)}; + ${position.size('100%')}; + background-color: ${colors.transparent}; +`; + +export default class AssetListItemSkeleton extends PureComponent { + static propTypes = { + animated: PropTypes.bool, + descendingOpacity: PropTypes.bool, + index: PropTypes.number, + } + + static defaultProps = { + animated: true, + index: 0, + } + + startShimmerLoop = () => { + const clock = new Clock(); + + const state = { + finished: new Value(0), + frameTime: new Value(0), + position: new Value(0), + time: new Value(0), + }; + + const config = { + duration: new Value(1250), + easing: Easing.linear, + toValue: new Value(1), + }; + + return block([ + startClock(clock), + timing(clock, state, config), + cond(state.finished, [ + stopClock(clock), + set(state.finished, 0), + set(state.position, 0), + set(state.time, 0), + set(state.frameTime, 0), + startClock(clock), + ]), + state.position, + ]); + } + + animation = this.startShimmerLoop() + + renderShimmer = () => { + const gradientColors = [ + colors.skeleton, + colors.shimmer, + colors.skeleton, + colors.skeleton, + ]; + + const gradientSteps = [0, 0.2, 0.4, 1]; + + const translateX = interpolate(this.animation, { + inputRange: [0, 1], + outputRange: [ + deviceUtils.dimensions.width * -1.17, + deviceUtils.dimensions.width * 1.17, + ], + }); + + return ( + + + + ); + } + + render = () => { + const { animated, descendingOpacity, index } = this.props; + + const skeletonElement = ( + + + + + + + + + + + + + + ); + + return ( + + {animated + ? {this.renderShimmer()} + : skeletonElement + } + + ); + } +} diff --git a/src/components/asset-list/AssetListSkeleton.js b/src/components/asset-list/EmptyAssetList.js similarity index 62% rename from src/components/asset-list/AssetListSkeleton.js rename to src/components/asset-list/EmptyAssetList.js index 7d74b6dac71..0c10cf0138e 100644 --- a/src/components/asset-list/AssetListSkeleton.js +++ b/src/components/asset-list/EmptyAssetList.js @@ -1,5 +1,6 @@ import lang from 'i18n-js'; import { times } from 'lodash'; +import PropTypes from 'prop-types'; import React from 'react'; import { withNeverRerender } from '../../hoc'; import { position } from '../../styles'; @@ -11,23 +12,29 @@ import AssetListItemSkeleton from './AssetListItemSkeleton'; const InterstitialOffset = AssetListHeader.height + FabWrapper.bottomPosition; -const renderSkeleton = index => ( +const renderSkeleton = (index, isWalletEthZero) => ( ); -const AssetListSkeleton = (props) => ( +const EmptyAssetList = ({ isWalletEthZero, ...props }) => ( - {times(5, renderSkeleton)} + {times(5, index => renderSkeleton(index, isWalletEthZero))} - + {isWalletEthZero && ()} ); -export default withNeverRerender(AssetListSkeleton); +EmptyAssetList.propTypes = { + isWalletEthZero: PropTypes.bool, +}; + +export default withNeverRerender(EmptyAssetList); diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index dfe7f73f887..b90f8dc6ba7 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -2,12 +2,12 @@ import { findIndex, get, has, + isNil, } from 'lodash'; import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import { LayoutAnimation, RefreshControl } from 'react-native'; -import { connect } from 'react-redux'; -import { pure } from 'recompact'; +import React, { Component } from 'react'; +import { LayoutAnimation, RefreshControl, View } from 'react-native'; +import { compose, pure } from 'recompact'; import { DataProvider, LayoutProvider, @@ -15,20 +15,28 @@ import { } from 'recyclerlistview'; import StickyContainer from 'recyclerlistview/dist/reactnative/core/StickyContainer'; import styled from 'styled-components/primitives'; -import { withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; +import { withFabSelection, withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; +import { + buildAssetHeaderUniqueIdentifier, + buildAssetUniqueIdentifier, +} from '../../helpers/assets'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; -import { CoinRow, CollectiblesSendRow } from '../coin-row'; +import { CoinRow } from '../coin-row'; +import { TokenFamilyHeader } from '../token-family'; +import { FloatingActionButton } from '../fab'; import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../investment-cards'; import { ListFooter } from '../list'; -import { CardMargin, CardSize, RowPadding } from '../unique-token/UniqueTokenRow'; +import { UniqueTokenRow } from '../unique-token'; import AssetListHeader from './AssetListHeader'; import CoinDivider from '../coin-divider/CoinDivider'; import SmallBalancesWrapper from '../coin-divider/SmallBalancesWrapper'; +import { TokenFamilyWrapPaddingTop } from '../token-family/TokenFamilyWrap'; +/* eslint-disable sort-keys */ export const ViewTypes = { HEADER: 0, - COIN_ROW: 1, // eslint-disable-line sort-keys + COIN_ROW: 1, COIN_ROW_LAST: 2, COIN_SMALL_BALANCES: 3, FOOTER: 11, @@ -42,11 +50,7 @@ export const ViewTypes = { UNISWAP_ROW_CLOSED_LAST: 10, UNISWAP_ROW_LAST: 8, }; - -const Wrapper = styled.View` - flex: 1; - overflow: hidden; -`; +/* eslint-enable sort-keys */ const NOOP = () => undefined; @@ -72,19 +76,16 @@ const reloadHeightOffsetBottom = -62; const AssetListHeaderRenderer = pure(data => ); const hasRowChanged = (r1, r2) => { - if (has(r1, 'isHeader')) { - const isNewTitle = isNewValueForPath(r1, r2, 'title'); - const isNewTotalItems = isNewValueForPath(r1, r2, 'totalItems'); - const isNewTotalValue = isNewValueForPath(r1, r2, 'totalValue'); - - return isNewTitle || isNewTotalItems || isNewTotalValue; - } - + const isNewShowShitcoinsValue = isNewValueForPath(r1, r2, 'showShitcoins'); + const isNewTitle = isNewValueForPath(r1, r2, 'title'); + const isNewTotalItems = isNewValueForPath(r1, r2, 'totalItems'); + const isNewTotalValue = isNewValueForPath(r1, r2, 'totalValue'); const isNewAsset = isNewValueForPath(r1, r2, 'item.uniqueId'); - const isNewTokenFirst = isNewValueForPath(r1, r2, 'item.tokens.[0].uniqueId'); - const isNewTokenSecond = isNewValueForPath(r1, r2, 'item.tokens.[1].uniqueId'); - const isNewUniswapFirst = isNewValueForPath(r1, r2, 'item.tokens.[0].percentageOwned'); - const isNewUniswapSecond = isNewValueForPath(r1, r2, 'item.tokens.[1].percentageOwned'); + const isNewTokenFamilyId = isNewValueForPath(r1, r2, 'item.familyId'); + const isNewTokenFamilyName = isNewValueForPath(r1, r2, 'item.familyName'); + const isNewTokenFamilySize = isNewValueForPath(r1, r2, 'item.childrenAmount'); + const isNewUniswapPercentageOwned = isNewValueForPath(r1, r2, 'item.percentageOwned'); + const isNewUniswapToken = isNewValueForPath(r1, r2, 'item.tokenSymbol'); const isCollectiblesRow = has(r1, 'item.tokens') && has(r2, 'item.tokens'); let isNewAssetBalance = false; @@ -95,18 +96,23 @@ const hasRowChanged = (r1, r2) => { return isNewAsset || isNewAssetBalance - || isNewTokenFirst - || isNewTokenSecond - || isNewUniswapFirst - || isNewUniswapSecond; + || isNewShowShitcoinsValue + || isNewTitle + || isNewTokenFamilyId + || isNewTokenFamilyName + || isNewTokenFamilySize + || isNewTotalItems + || isNewTotalValue + || isNewUniswapPercentageOwned + || isNewUniswapToken; }; -class RecyclerAssetList extends PureComponent { +class RecyclerAssetList extends Component { static propTypes = { fetchData: PropTypes.func, hideHeader: PropTypes.bool, - openFamilyTabs: PropTypes.array, - openInvestmentCards: PropTypes.array, + openFamilyTabs: PropTypes.object, + openInvestmentCards: PropTypes.object, openSmallBalances: PropTypes.bool, paddingBottom: PropTypes.number, renderAheadOffset: PropTypes.number, @@ -134,12 +140,12 @@ class RecyclerAssetList extends PureComponent { rlv = React.createRef(); - position = 0; - contentSize = 0; layoutMeasurement = 0; + position = 0; + refresh = false; constructor(props) { @@ -199,17 +205,19 @@ class RecyclerAssetList extends PureComponent { if (collectiblesIndex > -1) { if (index > headersIndices[collectiblesIndex]) { const familyIndex = index - headersIndices[collectiblesIndex] - 1; - if (openFamilyTabs[sections[collectiblesIndex].data[familyIndex].familyName]) { + if (openFamilyTabs[familyIndex]) { if (get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`)) { return { get: ViewTypes.UNIQUE_TOKEN_ROW, + isFirst: index === headersIndices[collectiblesIndex] + 1, isLast: index === this.state.length - 2, - size: get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`, []).length, + rowCount: get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`, []).length, }; } } return { get: ViewTypes.UNIQUE_TOKEN_ROW_CLOSED, + isFirst: index === headersIndices[collectiblesIndex] + 1, isLast: index === this.state.length - 2, }; } @@ -218,28 +226,33 @@ class RecyclerAssetList extends PureComponent { return ViewTypes.COIN_ROW; }, (type, dim) => { + const { hideHeader, paddingBottom } = this.props; + const { areSmallCollectibles } = this.state; + dim.width = deviceUtils.dimensions.width; - if (this.state.areSmallCollectibles - && ( - type === ViewTypes.UNIQUE_TOKEN_ROW_LAST - || type === ViewTypes.UNIQUE_TOKEN_ROW_FIRST - || type === ViewTypes.UNIQUE_TOKEN_ROW - ) - ) { + + if (areSmallCollectibles && type === ViewTypes.UNIQUE_TOKEN_ROW) { dim.height = CoinRow.height; - if (type === ViewTypes.UNIQUE_TOKEN_ROW_FIRST) { - dim.height += CollectiblesSendRow.dividerHeight; - } else if (type === ViewTypes.UNIQUE_TOKEN_ROW_LAST) { - // We want to add enough spacing below the list so that when the user scrolls to the bottom, - // the bottom of the list content lines up with the top of the FABs (+ padding). - dim.height += (props.paddingBottom || 0); - } return; } + + const fabPositionBottom = type.isLast ? (paddingBottom - (FloatingActionButton.size / 2)) : 0; + const TokenFamilyHeaderHeight = TokenFamilyHeader.height + fabPositionBottom; + + const firstRowExtraTopPadding = type.isFirst ? 4 : 0; if (type.get === ViewTypes.UNIQUE_TOKEN_ROW) { - dim.height = type.size * CardSize + 54 + CardMargin * (type.size - 1) + (type.isLast ? 90 : 0); + const heightOfRows = type.rowCount * UniqueTokenRow.cardSize; + const heightOfRowMargins = UniqueTokenRow.cardMargin * (type.rowCount - 1); + const extraSpaceForDropShadow = 19; + dim.height = ( + TokenFamilyHeaderHeight + + heightOfRows + + heightOfRowMargins + + firstRowExtraTopPadding + + extraSpaceForDropShadow + ); } else if (type.get === ViewTypes.UNIQUE_TOKEN_ROW_CLOSED) { - dim.height = 54 + (type.isLast ? 90 : 0); + dim.height = TokenFamilyHeaderHeight + firstRowExtraTopPadding; } else if (type === ViewTypes.COIN_ROW_LAST) { dim.height = this.state.areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height + 1; } else if (type === ViewTypes.COIN_SMALL_BALANCES) { @@ -267,6 +280,7 @@ class RecyclerAssetList extends PureComponent { static getDerivedStateFromProps({ sections }, state) { const headersIndices = []; + console.log(sections); const items = sections.reduce((ctx, section) => { headersIndices.push(ctx.length); return ctx @@ -286,13 +300,19 @@ class RecyclerAssetList extends PureComponent { }; } - shouldComponentUpdate = (prev, next) => { - if (prev.openFamilyTabs !== this.props.openFamilyTabs) { + shouldComponentUpdate = (nextProps, nextState) => { + if (nextProps.openFamilyTabs !== this.props.openFamilyTabs) { return true; } + + if (nextState.isRefreshing !== this.state.isRefreshing) { + return true; + } + if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && !(this.position <= reloadHeightOfsetTop && this.position > reloadHeightOffsetBottom)) { return false; } + return true; } @@ -322,16 +342,16 @@ class RecyclerAssetList extends PureComponent { this.rlv.scrollToOffset(0, this.position + this.props.scrollingVelocity * 10); }, 30); } - if (this.props.openFamilyTabs !== prev.openFamilyTabs) { + if (this.props.openFamilyTabs !== prev.openFamilyTabs && collectibles.data) { let i = 0; while (i < collectibles.data.length) { - if (this.props.openFamilyTabs[collectibles.data[i].familyName] === true && !prev.openFamilyTabs[collectibles.data[i].familyName]) { + if (this.props.openFamilyTabs[i] === true && !prev.openFamilyTabs[i]) { let collectiblesHeight = 0; for (let j = 0; j < i; j++) { - if (this.props.openFamilyTabs[collectibles.data[j].familyName] && collectibles.data[j].tokens) { - collectiblesHeight += collectibles.data[j].tokens.length * CardSize + 54 + (RowPadding - 4) * (collectibles.data[j].tokens.length - 1); + if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; } else { - collectiblesHeight += 54; + collectiblesHeight += TokenFamilyHeader.height; } } let investmentHeight = 0; @@ -360,20 +380,63 @@ class RecyclerAssetList extends PureComponent { const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + balancesHeight + investmentHeight; const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; - const renderSize = CardSize * collectibles.data[i].tokens.length + RowPadding * (collectibles.data[i].tokens.length - 1) - verticalOffset; + const renderSize = collectibles.data[i].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop; if (renderSize >= deviceDimensions) { const scrollDistance = sectionsHeight - this.position; - this.scrollToOffset(this.position + scrollDistance - verticalOffset); + this.scrollToOffset(this.position + scrollDistance - verticalOffset, true); } else { const diff = this.position - sectionsHeight + deviceDimensions; if (renderSize > diff) { - const scrollDistance = deviceDimensions > renderSize ? renderSize - diff : deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 250 : 280); - this.scrollToOffset(this.position + scrollDistance); + const scrollDistance = renderSize - diff; + this.scrollToOffset(this.position + scrollDistance, true); } } break; } + if (this.props.openFamilyTabs[i] === false && prev.openFamilyTabs[i] === true) { + let balancesHeight = 0; + if (balances.data) { + balancesHeight += CoinRow.height * (balances.data.length - 1); + if (balances.data[balances.data.length - 1].smallBalancesContainer) { + balancesHeight += CoinDivider.height + ListFooter.height; + if (this.props.openSmallBalances) { + balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; + } + } else { + balancesHeight += CoinRow.height + ListFooter.height; + } + } + + let investmentHeight = 0; + if (investments.data) { + for (let k = 0; k < investments.data.length; k++) { + if (!this.props.openInvestmentCards[investments.data[k].uniqueId]) { + investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + } else { + investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + } + } + } + + let collectiblesHeight = collectibles.data.length > 0 ? AssetListHeader.height : 0; + for (let j = 0; j < collectibles.data.length; j++) { + if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; + } else { + collectiblesHeight += TokenFamilyHeader.height; + } + } + const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 280); + if (this.position + deviceDimensions > renderSize) { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); + this.scrollToOffset(renderSize - deviceDimensions, true); + setTimeout(() => { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); + }, 300); + } + } i++; } } @@ -384,10 +447,10 @@ class RecyclerAssetList extends PureComponent { clearInterval(this.interval); }; - scrollToOffset = (position) => { + scrollToOffset = (position, animated) => { setTimeout(() => { - this.rlv.scrollToOffset(0, position, true); - }, 50); + this.rlv.scrollToOffset(0, position, animated); + }, 5); } getStableId = (index) => { @@ -420,20 +483,45 @@ class RecyclerAssetList extends PureComponent { return stableId; }; + handleListRef = (ref) => { this.rlv = ref; } + handleRefresh = () => { if (this.state.isRefreshing) return; - this.setState({ isRefreshing: true }); - this.props.fetchData().then(() => { - if (!this.isCancelled) { - this.setState({ isRefreshing: false }); - } - }).catch(error => { - if (!this.isCancelled) { - this.setState({ isRefreshing: false }); - } + + this.setState({ isRefreshing: true }, () => { + this.props.fetchData().then(() => { + if (!this.isCancelled) { + this.setState({ isRefreshing: false }); + } + }).catch(error => { + if (!this.isCancelled) { + this.setState({ isRefreshing: false }); + } + }); }); }; + handleScroll = ({ nativeEvent }, _, offsetY) => { + const { contentSize, layoutMeasurement } = nativeEvent; + + this.position = offsetY; + + if (this.contentSize !== contentSize.height) { + this.contentSize = contentSize.height; + } + + if (this.layoutMeasurement !== layoutMeasurement.height) { + this.layoutMeasurement = layoutMeasurement.height; + } + + if ((contentSize.height - layoutMeasurement.height >= offsetY && offsetY >= 0) + || (offsetY < -60 && offsetY > -62)) { + if (this.props.scrollViewTracker) { + this.props.scrollViewTracker.setValue(offsetY); + } + } + }; + renderRefreshControl = () => ( { - const { item, renderItem } = data; + if (isNil(data) || isNil(index)) { + return NOOP; + } + + const { item = {}, renderItem } = data; const { hideHeader, sections } = this.props; if (type === ViewTypes.HEADER) { - return hideHeader ? null : ; + return hideHeader ? NOOP : ; } if (type === ViewTypes.COIN_SMALL_BALANCES) { @@ -468,6 +560,7 @@ class RecyclerAssetList extends PureComponent { || type === ViewTypes.UNISWAP_ROW_LAST || type === ViewTypes.UNISWAP_ROW_CLOSED || type === ViewTypes.UNISWAP_ROW_CLOSED_LAST + || type === ViewTypes.FOOTER ); // TODO sections @@ -478,10 +571,9 @@ class RecyclerAssetList extends PureComponent { familyId: item.familyId, familyImage: item.familyImage, familyName: item.familyName, - isFirstRow: type === ViewTypes.UNIQUE_TOKEN_ROW_FIRST, - isLastRow: type === ViewTypes.UNIQUE_TOKEN_ROW_LAST, item: item.tokens, - shouldPrioritizeImageLoading: index < sections[0].data.length + 9, + marginTop: type.isFirst ? 4 : 0, + shouldPrioritizeImageLoading: index < get(sections, '[0].data.length', 0) + 9, uniqueId: item.uniqueId, }); }; @@ -491,31 +583,18 @@ class RecyclerAssetList extends PureComponent { const { dataProvider, headersIndices } = this.state; return ( - + { this.rlv = ref; }} {...props} - layoutProvider={this.layoutProvider} dataProvider={dataProvider} - renderAheadOffset={renderAheadOffset} + extendedState={{ headersIndices }} itemAnimator={layoutItemAnimator} + layoutProvider={this.layoutProvider} + onScroll={this.handleScroll} + ref={this.handleListRef} + renderAheadOffset={renderAheadOffset} rowRenderer={this.rowRenderer} - onScroll={(event, _offsetX, offsetY) => { - this.position = offsetY; - if (this.contentSize !== event.nativeEvent.contentSize.height) { - this.contentSize = event.nativeEvent.contentSize.height; - } - if (this.layoutMeasurement !== event.nativeEvent.layoutMeasurement.height) { - this.layoutMeasurement = event.nativeEvent.layoutMeasurement.height; - } - if ((event.nativeEvent.contentSize.height - event.nativeEvent.layoutMeasurement.height >= offsetY && offsetY >= 0) - || (offsetY < reloadHeightOfsetTop && offsetY > reloadHeightOffsetBottom)) { - if (this.props.scrollViewTracker) { - this.props.scrollViewTracker.setValue(offsetY); - } - } - }} scrollIndicatorInsets={{ bottom: safeAreaInsetValues.bottom, top: hideHeader ? 0 : AssetListHeader.height, @@ -523,18 +602,19 @@ class RecyclerAssetList extends PureComponent { scrollViewProps={{ refreshControl: this.renderRefreshControl(), }} + style={{ + backgroundColor: colors.white, + }} /> - + ); } } -const mapStateToProps = ({ - selectedWithFab: { - scrollingVelocity, - }, -}) => ({ - scrollingVelocity, -}); -export default connect(mapStateToProps)(withOpenFamilyTabs(withOpenInvestmentCards(withOpenBalances(RecyclerAssetList)))); +export default compose( + withFabSelection, + withOpenFamilyTabs, + withOpenInvestmentCards, + withOpenBalances, +)(RecyclerAssetList); diff --git a/src/components/coin-row/BottomRowText.js b/src/components/coin-row/BottomRowText.js index bd06ea23b53..57118e31ee9 100644 --- a/src/components/coin-row/BottomRowText.js +++ b/src/components/coin-row/BottomRowText.js @@ -1,8 +1,9 @@ import { withProps } from 'recompact'; import { colors } from '../../styles'; -import { Monospace } from '../text'; +import { Monospace, TruncatedText } from '../text'; export default withProps(({ color }) => ({ color: color || colors.alpha(colors.blueGreyDark, 0.5), + component: Monospace, size: 'smedium', -}))(Monospace); +}))(TruncatedText); diff --git a/src/components/coin-row/CoinRow.js b/src/components/coin-row/CoinRow.js index d0fcee11705..3f09b46ceb0 100644 --- a/src/components/coin-row/CoinRow.js +++ b/src/components/coin-row/CoinRow.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React, { createElement } from 'react'; -import { compose } from 'recompact'; +import { compose, withProps } from 'recompact'; import styled from 'styled-components/primitives'; import { withAccountSettings, withFabSendAction } from '../../hoc'; import { colors, padding } from '../../styles'; @@ -8,8 +8,8 @@ import { CoinIcon } from '../coin-icon'; import Highlight from '../Highlight'; import { Column, Row } from '../layout'; -const CoinRowPaddingTop = 15; -const CoinRowPaddingBottom = 7; +const CoinRowPaddingTop = 10; +const CoinRowPaddingBottom = 11.5; const Container = styled(Row)` ${padding(CoinRowPaddingTop, 19, CoinRowPaddingBottom, 19)} @@ -17,11 +17,20 @@ const Container = styled(Row)` width: 100%; `; -const Content = styled(Column)` +const Content = styled(Column).attrs({ + flex: 1, + justify: 'space-between', +})` height: ${CoinIcon.size}; margin-left: 10; `; +const CoinRowHighlight = withProps({ + borderRadius: 18, + margin: 2, + marginHorizontal: 8, +})(Highlight); + const enhance = compose( withAccountSettings, withFabSendAction, @@ -38,10 +47,10 @@ const CoinRow = enhance(({ topRowRender, ...props }) => ( - - + + {createElement(coinIconRender, { symbol, ...props })} - + {topRowRender({ symbol, ...props })} @@ -73,5 +82,4 @@ CoinRow.defaultProps = { CoinRow.height = CoinIcon.size + CoinRowPaddingTop + CoinRowPaddingBottom; - export default CoinRow; diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 91dfc4b6331..18291a7c571 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -1,6 +1,6 @@ import { compact, get } from 'lodash'; import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; +import React from 'react'; import { compose, mapProps, @@ -13,7 +13,7 @@ import TransactionStatusTypes from '../../helpers/transactionStatusTypes'; import { colors } from '../../styles'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { ButtonPressAnimation } from '../animations'; -import { FlexItem, Row } from '../layout'; +import { FlexItem, Row, RowWithMargins } from '../layout'; import BottomRowText from './BottomRowText'; import BalanceText from './BalanceText'; import CoinName from './CoinName'; @@ -65,15 +65,21 @@ const BottomRow = ({ name, native, status }) => { BottomRow.propTypes = rowRenderPropTypes; const TopRow = ({ balance, pending, status }) => ( - + - - {get(balance, 'display', '')} - - + + + {get(balance, 'display', '')} + + + ); TopRow.propTypes = rowRenderPropTypes; diff --git a/src/components/coin-row/TransactionStatusBadge.js b/src/components/coin-row/TransactionStatusBadge.js index 457d76b2ca7..9dd3e00753b 100644 --- a/src/components/coin-row/TransactionStatusBadge.js +++ b/src/components/coin-row/TransactionStatusBadge.js @@ -28,11 +28,11 @@ const StatusProps = { }, }; -const TransactionStatusBadge = ({ pending, status }) => { +const TransactionStatusBadge = ({ pending, status, ...props }) => { const statusColor = pending ? colors.primaryBlue : colors.blueGreyMediumLight; return ( - + {pending && ( ( - {Children.map(children, (child, index) => ( - - {child} - {(index < children.length - 1) && } - - ))} + + {children} + ); diff --git a/src/components/fab/DeleteButton.js b/src/components/fab/DeleteButton.js index b68d2621c6d..cc42a74deae 100644 --- a/src/components/fab/DeleteButton.js +++ b/src/components/fab/DeleteButton.js @@ -1,41 +1,45 @@ import PropTypes from 'prop-types'; import React from 'react'; import Animated from 'react-native-reanimated'; -import { borders, colors } from '../../styles'; -import Icon from '../icons/Icon'; +import { transformOrigin } from 'react-native-redash'; +import { onlyUpdateForKeys } from 'recompact'; +import { borders, colors, position } from '../../styles'; +import { Icon } from '../icons'; import { ShadowStack } from '../shadow-stack'; -import { buildFabShadow } from './FloatingActionButton'; +import FloatingActionButton from './FloatingActionButton'; -const DeleteButton = ({ deleteButtonTranslate }) => ( +const size = 34; + +const enhance = onlyUpdateForKeys(['deleteButtonScale']); +const DeleteButton = enhance(({ deleteButtonScale }) => ( -); +)); DeleteButton.propTypes = { - deleteButtonTranslate: PropTypes.object, + deleteButtonScale: PropTypes.object, }; +DeleteButton.size = size; + +DeleteButton.defaultScale = 1.25; + export default DeleteButton; diff --git a/src/components/fab/FabWrapper.js b/src/components/fab/FabWrapper.js index d852c5f8e2e..72a9798cf73 100644 --- a/src/components/fab/FabWrapper.js +++ b/src/components/fab/FabWrapper.js @@ -1,29 +1,25 @@ import PropTypes from 'prop-types'; import React, { createElement } from 'react'; -import Animated from 'react-native-reanimated'; -import { hoistStatics, withProps } from 'recompact'; +import { onlyUpdateForKeys } from 'recompact'; import { safeAreaInsetValues } from '../../utils'; import { FlexItem, RowWithMargins } from '../layout'; -import DeleteButton from './DeleteButton'; import SendFab from './SendFab'; -const FabWrapperBottomPosition = 21; +const bottomPosition = 21 + safeAreaInsetValues.bottom; -const FabWrapper = ({ +const enhance = onlyUpdateForKeys(['children', 'disabled']); +const FabWrapper = enhance(({ children, disabled, fabs, - ...rest + ...props }) => ( {children} - {!disabled && ( - {fabs.map(fab => createElement(fab, rest))} + {fabs.map(fab => createElement(fab, props))} )} -); +)); FabWrapper.propTypes = { children: PropTypes.node, - deleteButtonTranslate: PropTypes.object, disabled: PropTypes.bool, fabs: PropTypes.arrayOf(PropTypes.func).isRequired, scrollViewTracker: PropTypes.object, @@ -51,8 +46,6 @@ FabWrapper.defaultProps = { fabs: [SendFab], }; -FabWrapper.bottomPosition = FabWrapperBottomPosition; +FabWrapper.bottomPosition = bottomPosition; -export default hoistStatics(withProps({ - deleteButtonTranslate: new Animated.Value(100), -}))(FabWrapper); +export default FabWrapper; diff --git a/src/components/fab/FloatingActionButton.js b/src/components/fab/FloatingActionButton.js index db9635eb762..61f138fd679 100644 --- a/src/components/fab/FloatingActionButton.js +++ b/src/components/fab/FloatingActionButton.js @@ -1,102 +1,106 @@ -/* eslint-disable no-nested-ternary */ import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; +import React, { Component } from 'react'; +import { View } from 'react-primitives'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import { compose, pure, withHandlers } from 'recompact'; -import styled from 'styled-components/primitives'; import { ButtonPressAnimation } from '../animations'; import InnerBorder from '../InnerBorder'; -import { Centered } from '../layout'; import { borders, colors, position } from '../../styles'; +import { isNewValueForPath } from '../../utils'; import { ShadowStack } from '../shadow-stack'; -const Container = styled(Centered)` - ${position.cover} - background-color: ${({ disabled, greyed }) => (disabled ? '#F6F7F9' : (greyed ? colors.grey : colors.paleBlue))}; -`; +const FabSize = 56; +const FabShadow = [ + [0, 2, 5, colors.dark, 0.2], + [0, 6, 10, colors.dark, 0.14], + [0, 1, 18, colors.dark, 0.12], +]; -export const buildFabShadow = disabled => ( - disabled - ? [] - : [ - [0, 2, 5, colors.dark, 0.2], - [0, 6, 10, colors.dark, 0.14], - [0, 1, 18, colors.dark, 0.12], - ] -); +export default class FloatingActionButton extends Component { + static propTypes = { + children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + disabled: PropTypes.bool, + isFabSelectionValid: PropTypes.bool, + onPress: PropTypes.func, + onPressIn: PropTypes.func, + scaleTo: PropTypes.number, + size: PropTypes.number, + tapRef: PropTypes.object, + } -const enhance = compose( - pure, - withHandlers({ - onPress: ({ onPress }) => (event) => { - ReactNativeHapticFeedback.trigger('impactLight'); - if (onPress) onPress(event); - }, - onPressIn: ({ onPressIn }) => (event) => { - ReactNativeHapticFeedback.trigger('impactLight'); - if (onPressIn) onPressIn(event); - }, - }), -); + static defaultProps = { + scaleTo: 0.82, + size: FabSize, + } -const FloatingActionButton = enhance(({ - children, - disabled, - greyed, - onPress, - onPressIn, - onPressOut, - size, - style, - ...props -}) => ( - - - - - {(typeof children === 'function') - ? children({ size }) - : children - } - {!disabled && ( - - )} - - - - -)); + static size = FabSize -FloatingActionButton.propTypes = { - children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), - disabled: PropTypes.bool, - greyed: PropTypes.bool, - onPress: PropTypes.func, - onPressIn: PropTypes.func, - onPressOut: PropTypes.func, - size: PropTypes.number, - tapRef: PropTypes.object, -}; + static sizeWhileDragging = 74 -FloatingActionButton.size = 56; + static shadow = FabShadow -FloatingActionButton.defaultProps = { - size: FloatingActionButton.size, -}; + shouldComponentUpdate = nextProps => ( + isNewValueForPath(this.props, nextProps, 'disabled') + || isNewValueForPath(this.props, nextProps, 'isFabSelectionValid') + || isNewValueForPath(this.props, nextProps, 'scaleTo') + ) -export default FloatingActionButton; + handlePress = (event) => { + const { onPress } = this.props; + ReactNativeHapticFeedback.trigger('impactLight'); + if (onPress) onPress(event); + } + + handlePressIn = (event) => { + const { onPressIn } = this.props; + ReactNativeHapticFeedback.trigger('impactLight'); + if (onPressIn) onPressIn(event); + } + + render = () => { + const { + children, + disabled, + isFabSelectionValid, + scaleTo, + size, + ...props + } = this.props; + + const isDisabled = disabled || !isFabSelectionValid; + + return ( + + + + {(typeof children === 'function') + ? children({ size }) + : children + } + {!disabled && ( + + )} + + + + ); + } +} diff --git a/src/components/fab/MovableFabWrapper.js b/src/components/fab/MovableFabWrapper.js index 9421b69ab68..323f7639fcf 100644 --- a/src/components/fab/MovableFabWrapper.js +++ b/src/components/fab/MovableFabWrapper.js @@ -1,10 +1,9 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { PureComponent } from 'react'; import { PanGestureHandler, State } from 'react-native-gesture-handler'; import Animated from 'react-native-reanimated'; -import { connect } from 'react-redux'; import { compose, withProps } from 'recompact'; -import { withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; +import { withFabSelection, withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; import { setActionType, setScrollingVelocity, @@ -16,8 +15,11 @@ import { ListFooter } from '../list'; import { CardSize, CardMargin } from '../unique-token/UniqueTokenRow'; import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../investment-cards'; import CoinDivider from '../coin-divider/CoinDivider'; +import { UniqueTokenRow } from '../unique-token'; +import DeleteButton from './DeleteButton'; const { + abs, add, and, block, @@ -88,13 +90,12 @@ export const extraStates = { overX: -2, }; - -class Movable extends React.Component { +class MovableFabWrapper extends PureComponent { static propTypes = { actionType: PropTypes.string, areas: PropTypes.array, children: PropTypes.any, - deleteButtonTranslate: PropTypes.object, + deleteButtonScale: PropTypes.object, openFamilyTabs: PropTypes.array, openInvestmentCards: PropTypes.array, openSmallBalances: PropTypes.bool, @@ -110,15 +111,15 @@ class Movable extends React.Component { scrollOffset: new Animated.Value(0), }; - dragX = new Animated.Value(0); - - selectedIndex = new Animated.Value(0); - absoluteX = new Animated.Value(0); absoluteY = new Animated.Value(0); - key = 0; + clockX = new Clock(); + + clockY = new Clock(); + + dragX = new Animated.Value(0); dragY = new Animated.Value(0); @@ -128,13 +129,19 @@ class Movable extends React.Component { gestureState = new Animated.Value(0); + isOverDeleteButtonBoundary = position => greaterThan(abs(position), DeleteButton.size * 2); + + key = 0; + + selectedIndex = new Animated.Value(0); + springOffsetX = new Animated.Value(0); springOffsetY = new Animated.Value(0); - clockX = new Clock(); + translateX = add(this.dragX, this.springOffsetX); - clockY = new Clock(); + translateY = add(this.dragY, this.springOffsetY); wasRunSpring = new Animated.Value(0); @@ -142,6 +149,33 @@ class Movable extends React.Component { xClockShow = new Clock(); + calculateSelectedIndex = () => cond( + or( + lessThan(this.absoluteY, 109), + this.isOverX, + ), + extraStates.overX, + this.props.areas.reduce((prev, curr, i) => cond( + and( + greaterThan(this.absoluteX, curr.left), + greaterThan(add(this.absoluteY, this.props.scrollViewTracker), curr.top), + lessThan(add(this.absoluteY, this.props.scrollViewTracker), curr.bottom), + lessThan(this.absoluteX, curr.right), + ), i, prev, + ), extraStates.nothing), + ); + + isOverX = and( + greaterThan(this.absoluteY, deviceUtils.dimensions.height - 120), + greaterThan(this.absoluteX, deviceUtils.dimensions.width - 100), + ); + + manageUpAndDownScrolling = cond( + and(greaterThan(this.absoluteY, deviceUtils.dimensions.height - 20), not(this.isOverX)), + 1, + cond(lessThan(this.absoluteY, 120), 2, 0), + ); + onGestureEvent = event([ { nativeEvent: { @@ -164,81 +198,66 @@ class Movable extends React.Component { }, ]); - isOverX = and( - greaterThan(this.absoluteY, deviceUtils.dimensions.height - 120), - greaterThan(this.absoluteX, deviceUtils.dimensions.width - 100), - ); - - calculateSelectedIndex = () => cond( - or( - lessThan(this.absoluteY, 109), - this.isOverX, - ), - extraStates.overX, - this.props.areas.reduce((prev, curr, i) => cond( - and( - greaterThan(this.absoluteX, curr.left), - greaterThan(add(this.absoluteY, this.props.scrollViewTracker), curr.top), - lessThan(add(this.absoluteY, this.props.scrollViewTracker), curr.bottom), - lessThan(this.absoluteX, curr.right), - ), i, prev, - ), extraStates.nothing), - ); + render() { + const selectedIndexWithState = cond( + eq(this.gestureState, State.ACTIVE), + this.selectedIndex, + extraStates.gestureInactive, + ); - manageUpAndDownScrolling = cond( - and(greaterThan(this.absoluteY, deviceUtils.dimensions.height - 20), not(this.isOverX)), - 1, - cond(lessThan(this.absoluteY, 120), 2, 0), - ); + const showDeleteButton = or( + this.isOverDeleteButtonBoundary(this.translateX), + this.isOverDeleteButtonBoundary(this.translateY), + ); - render() { - const selectedIndexWithState = cond(eq(this.gestureState, State.ACTIVE), this.selectedIndex, extraStates.gestureInactive); return ( - - {this.props.areas && this.props.areas.length !== 0 - && } + /> + )} this.props.setScrollingVelocity(v === 1 ? 1 : (v === 2 ? -1 : 0))), - ])} + exec={( + onChange(this.manageUpAndDownScrolling, [ + // eslint-disable-next-line no-nested-ternary + call([this.manageUpAndDownScrolling], ([v]) => this.props.setScrollingVelocity(v === 1 ? 1 : (v === 2 ? -1 : 0))), + ]) + )} /> this.props.setScrollingVelocity(0)), - set(this.props.deleteButtonTranslate, runSpring(this.xClockHide, this.props.deleteButtonTranslate, 0, 100)), + set(this.props.deleteButtonScale, runSpring(this.xClockHide, this.props.deleteButtonScale, 0, DeleteButton.defaultScale)), stopClock(this.xClockShow), ], ), @@ -253,13 +272,13 @@ class Movable extends React.Component { cond( eq(this.gestureState, State.END), [ - set(this.springOffsetX, add(this.dragX, this.springOffsetX)), - set(this.springOffsetY, add(this.dragY, this.springOffsetY)), + set(this.springOffsetX, this.translateX), + set(this.springOffsetY, this.translateY), set(this.dragX, 0), set(this.dragY, 0), ], cond( - eq(this.gestureState, State.ACTIVE), + eq(this.gestureState, State.BEGAN), call([], () => this.props.setActionType(this.props.actionType)), ), ), @@ -362,7 +381,7 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment for (let j = 0; j < tokens.length; j++) { for (let k = 0; k < tokens[j].length; k++) { areas.push({ - bottom: height + CardSize, + bottom: height + UniqueTokenRow.cardSize, id: tokens[j][k].isSendable ? tokens[j][k].uniqueId : extraStates.notSendable, left: k === 0 ? 0 : deviceUtils.dimensions.width / 2, right: deviceUtils.dimensions.width / (k === 0 ? 2 : 1), @@ -370,9 +389,9 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment }); } if (openFamilyTabs[collectibles.data[i].familyName]) { - height += CardSize; + height += UniqueTokenRow.cardSize; if (j > 0) { - height += CardMargin; + height += UniqueTokenRow.cardMargin; } } } @@ -383,14 +402,10 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment return null; }; -const EnhancedMovable = compose( - connect(null, { - setActionType, - setScrollingVelocity, - updateSelectedID, - }), +export default compose( + withFabSelection, + withOpenFamilyTabs, + withOpenInvestmentCards, + withOpenBalances, withProps(traverseSectionsToDimensions), -)(Movable); - - -export default withOpenFamilyTabs(withOpenInvestmentCards(withOpenBalances(EnhancedMovable))); +)(MovableFabWrapper); diff --git a/src/components/fab/SendFab.js b/src/components/fab/SendFab.js index 23925c138d6..9942b4a760f 100644 --- a/src/components/fab/SendFab.js +++ b/src/components/fab/SendFab.js @@ -1,92 +1,85 @@ import PropTypes from 'prop-types'; import React from 'react'; +import Animated from 'react-native-reanimated'; import { withNavigation } from 'react-navigation'; -import { connect } from 'react-redux'; import { compose, - omitProps, onlyUpdateForKeys, withHandlers, withProps, } from 'recompact'; -import Icon from '../icons/Icon'; +import { withFabSelection } from '../../hoc'; +import { Icon } from '../icons'; +import { Centered } from '../layout'; +// import DeleteButton from './DeleteButton'; import FloatingActionButton from './FloatingActionButton'; -import EnhancedMovable, { extraStates } from './MovableFabWrapper'; +// import MovableFabWrapper from './MovableFabWrapper'; - -const mapStateToProps = ({ - selectedWithFab: { - selectedId, - }, -}) => ({ - selectedId, -}); - -const FloatingActionButtonWithDisabled = compose( - connect(mapStateToProps), - withProps(({ selectedId }) => ({ - greyed: selectedId === extraStates.notSendable, - size: FloatingActionButton.size, - })), - omitProps('selectedId'), -)(FloatingActionButton); +const FloatingActionButtonWithDisabled = withFabSelection(FloatingActionButton); const SendFab = ({ areas, - deleteButtonTranslate, + deleteButtonScale, disabled, onPress, + scaleTo, scrollViewTracker, sections, tapRef, ...props }) => ( - - - - - + + {/* + + + */} + + + + {/* + + */} + ); - SendFab.propTypes = { areas: PropTypes.array, children: PropTypes.any, - deleteButtonTranslate: PropTypes.object, + deleteButtonScale: PropTypes.object, disabled: PropTypes.bool, onPress: PropTypes.func, + scaleTo: PropTypes.number, scrollViewTracker: PropTypes.object, sections: PropTypes.array, tapRef: PropTypes.object, }; +SendFab.defaultProps = { + // scaleTo: FloatingActionButton.sizeWhileDragging / FloatingActionButton.size +}; + export default compose( withNavigation, - withHandlers({ - onPress: ({ navigation }) => () => { - navigation.navigate('SendSheet'); - }, - }), + withHandlers({ onPress: ({ navigation }) => () => navigation.navigate('SendSheet') }), onlyUpdateForKeys(['disabled', 'sections']), - withProps({ - tapRef: React.createRef(), - }), + // withProps({ + // deleteButtonScale: new Animated.Value(DeleteButton.defaultScale), + // tapRef: React.createRef(), + // }), )(SendFab); diff --git a/src/components/header/Header.js b/src/components/header/Header.js index f4c99fd8131..3fbde49e01e 100644 --- a/src/components/header/Header.js +++ b/src/components/header/Header.js @@ -9,7 +9,7 @@ const HeaderHeight = 52; const HeaderHeightWithStatusBar = HeaderHeight + StatusBarHeight; const Container = styled(Row).attrs({ align: 'end' })` - ${padding(StatusBarHeight, 9, 0)} + ${padding(StatusBarHeight, 9, 0)}; flex-shrink: 0; height: ${({ excludeStatusBarHeight }) => ( (excludeStatusBarHeight === true) diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index f94c8bcbcb4..5ec537f91dd 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -4,7 +4,6 @@ import Flex from '../layout/Flex'; import ArrowCircledIcon from './svg/ArrowCircledIcon'; import ArrowIcon from './svg/ArrowIcon'; -import AssetListItemSkeletonIcon from './svg/AssetListItemSkeletonIcon'; import AvatarIcon from './svg/AvatarIcon'; import CameraIcon from './svg/CameraIcon'; import CaretIcon from './svg/CaretIcon'; @@ -40,7 +39,6 @@ const Icon = ({ name, ...props }) => createElement(Icon.IconTypes[name] || Flex, Icon.IconTypes = { arrow: ArrowIcon, arrowCircled: ArrowCircledIcon, - assetListItemSkeleton: AssetListItemSkeletonIcon, avatar: AvatarIcon, camera: CameraIcon, caret: CaretIcon, diff --git a/src/components/icons/svg/AssetListItemSkeletonIcon.js b/src/components/icons/svg/AssetListItemSkeletonIcon.js deleted file mode 100644 index 9e8d24a218a..00000000000 --- a/src/components/icons/svg/AssetListItemSkeletonIcon.js +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Circle, G, Rect } from 'svgs'; -import { colors } from '../../../styles'; -import Svg from '../Svg'; - -const AssetListItemSkeletonIcon = ({ color, ...props }) => ( - - - - - - - - - -); - -AssetListItemSkeletonIcon.propTypes = { - color: PropTypes.string, -}; - -AssetListItemSkeletonIcon.defaultProps = { - color: colors.skeleton, -}; - -export default AssetListItemSkeletonIcon; diff --git a/src/components/icons/svg/CaretThinIcon.js b/src/components/icons/svg/CaretThinIcon.js index 6e1eccdf410..71983dd9784 100644 --- a/src/components/icons/svg/CaretThinIcon.js +++ b/src/components/icons/svg/CaretThinIcon.js @@ -5,12 +5,13 @@ import { withRotationForDirection } from '../../../hoc'; import { colors } from '../../../styles'; import Svg from '../Svg'; +/* eslint-disable max-len */ const CaretThinIcon = ({ color, ...props }) => ( ( /> ); +/* eslint-enable max-len */ CaretThinIcon.propTypes = { color: PropTypes.string, diff --git a/src/components/icons/svg/CheckmarkCircledIcon.js b/src/components/icons/svg/CheckmarkCircledIcon.js index 09aea9892ed..657f720c1ea 100644 --- a/src/components/icons/svg/CheckmarkCircledIcon.js +++ b/src/components/icons/svg/CheckmarkCircledIcon.js @@ -14,7 +14,7 @@ const CheckmarkCircledIcon = ({ color, ...props }) => ( /> ); -/* eslint-disable max-len */ +/* eslint-enable max-len */ CheckmarkCircledIcon.propTypes = { color: PropTypes.string, diff --git a/src/components/icons/svg/CloseIcon.js b/src/components/icons/svg/CloseIcon.js index f31388bf415..414b592d616 100644 --- a/src/components/icons/svg/CloseIcon.js +++ b/src/components/icons/svg/CloseIcon.js @@ -5,10 +5,10 @@ import { colors } from '../../../styles'; import Svg from '../Svg'; /* eslint-disable max-len */ -const CloseIcon = ({ color, ...props }) => ( - +const CloseIcon = ({ color, size, ...props }) => ( + @@ -18,10 +18,12 @@ const CloseIcon = ({ color, ...props }) => ( CloseIcon.propTypes = { color: PropTypes.string, + size: PropTypes.number, }; CloseIcon.defaultProps = { color: colors.black, + size: 12, }; export default CloseIcon; diff --git a/src/components/icons/svg/SpinnerIcon.js b/src/components/icons/svg/SpinnerIcon.js index 80221abde43..e5478a48930 100644 --- a/src/components/icons/svg/SpinnerIcon.js +++ b/src/components/icons/svg/SpinnerIcon.js @@ -22,7 +22,7 @@ SpinnerIcon.propTypes = { }; SpinnerIcon.defaultProps = { - color: colors.blue, + color: colors.appleBlue, size: 12, }; diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 56eeb773dc9..6e27accd7dc 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -21,6 +21,7 @@ const InvestmentCard = ({ containerHeight, gradientColors, headerProps, + height, onLayout, shadows, setOpenInvestmentCards, @@ -92,7 +93,6 @@ const InvestmentCard = ({ InvestmentCard.propTypes = { children: PropTypes.node, collapsed: PropTypes.bool, - containerHeight: PropTypes.number, gradientColors: PropTypes.arrayOf(PropTypes.string).isRequired, headerProps: PropTypes.shape(InvestmentCardHeader.propTypes), isCollapsible: PropTypes.bool, @@ -106,6 +106,7 @@ InvestmentCard.propTypes = { InvestmentCard.defaultProps = { containerHeight: InvestmentCardHeader.height, gradientColors: ['#F7FAFC', '#E0E6EC'], + height: InvestmentCardHeader.height, shadows: [ [0, 1, 3, colors.dark, 0.08], [0, 4, 6, colors.dark, 0.04], diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index 578d069408e..2bdae3760d7 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -17,6 +17,8 @@ import { Text } from '../text'; import InvestmentCard from './InvestmentCard'; import InvestmentCardPill from './InvestmentCardPill'; +const UniswapInvestmentCardHeight = 114; + const AssetLabel = withProps({ color: 'blueGreyDarkTransparent', lineHeight: 'tight', @@ -69,6 +71,7 @@ const UniswapInvestmentCard = enhance(({ : `< ${convertAmountToNativeDisplay(0.01, nativeCurrency)}`, isCollapsible: isCollapsible, }} + height={UniswapInvestmentCardHeight} > ({ + direction: 'column', + dividerProps: { + horizontal: true, + ...dividerProps, + }, + })), +)(LayoutWithDividers); diff --git a/src/components/layout/Flex.js b/src/components/layout/Flex.js index 6cee1cde718..69a6a642b1f 100644 --- a/src/components/layout/Flex.js +++ b/src/components/layout/Flex.js @@ -1,6 +1,5 @@ import omitProps from '@hocs/omit-props'; import PropTypes from 'prop-types'; -import React from 'react'; import { View } from 'react-primitives'; import { componentFromProp } from 'recompact'; import styled from 'styled-components/primitives'; @@ -11,9 +10,7 @@ export const getFlexStyleKeysFromShorthand = style => ( : style ); -const DefaultFlexView = props => ; - -const FlexPropBlacklist = ['align', 'direction', 'flex', 'justify', 'wrap']; +const FlexPropBlacklist = ['align', 'direction', 'flex', 'justify', 'self', 'wrap']; const FlexElement = omitProps(...FlexPropBlacklist)(componentFromProp('component')); const Flex = styled(FlexElement)` @@ -39,7 +36,7 @@ Flex.propTypes = { Flex.defaultProps = { align: 'stretch', - component: DefaultFlexView, + component: View, direction: 'row', justify: 'start', }; diff --git a/src/components/layout/LayoutWithDividers.js b/src/components/layout/LayoutWithDividers.js new file mode 100644 index 00000000000..a3400218d3a --- /dev/null +++ b/src/components/layout/LayoutWithDividers.js @@ -0,0 +1,40 @@ +import PropTypes from 'prop-types'; +import React, { + Children, + cloneElement, + createElement, + Fragment, +} from 'react'; +import Flex from './Flex'; +import Divider from '../Divider'; + +const LayoutWithDividers = ({ + children, + dividerProps, + dividerRenderer, + ...props +}) => ( + + {Children.toArray(children).map((child, index, array) => ( + + {cloneElement(child)} + {(index < array.length - 1) + ? createElement(dividerRenderer, dividerProps) + : null + } + + ))} + +); + +LayoutWithDividers.propTypes = { + children: PropTypes.node, + dividerProps: PropTypes.object, + dividerRenderer: PropTypes.func, +}; + +LayoutWithDividers.defaultProps = { + dividerRenderer: Divider, +}; + +export default LayoutWithDividers; diff --git a/src/components/layout/RowWithDividers.js b/src/components/layout/RowWithDividers.js new file mode 100644 index 00000000000..1f1740fe1ec --- /dev/null +++ b/src/components/layout/RowWithDividers.js @@ -0,0 +1,13 @@ +import { compose, setDisplayName, withProps } from 'recompact'; +import LayoutWithDividers from './LayoutWithDividers'; + +export default compose( + setDisplayName('RowWithDividers'), + withProps(({ dividerProps }) => ({ + direction: 'row', + dividerProps: { + horizontal: false, + ...dividerProps, + }, + })), +)(LayoutWithDividers); diff --git a/src/components/layout/index.js b/src/components/layout/index.js index 11700256eaf..8e6ffb4819a 100644 --- a/src/components/layout/index.js +++ b/src/components/layout/index.js @@ -1,9 +1,12 @@ export { default as Centered } from './Centered'; export { default as Column } from './Column'; +export { default as ColumnWithDividers } from './ColumnWithDividers'; export { default as ColumnWithMargins } from './ColumnWithMargins'; export { default as Flex } from './Flex'; export { default as FlexItem } from './FlexItem'; +export { default as LayoutWithDividers } from './LayoutWithDividers'; export { default as LayoutWithMargins } from './LayoutWithMargins'; export { default as Page } from './Page'; export { default as Row } from './Row'; +export { default as RowWithDividers } from './RowWithDividers'; export { default as RowWithMargins } from './RowWithMargins'; diff --git a/src/components/list/ListItem.js b/src/components/list/ListItem.js index ffaf506fcda..1d4b0bc6b54 100644 --- a/src/components/list/ListItem.js +++ b/src/components/list/ListItem.js @@ -1,16 +1,10 @@ import { isString } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; -import { - compose, - onlyUpdateForPropTypes, - setStatic, - withHandlers, -} from 'recompact'; -import styled from 'styled-components'; +import { compose, onlyUpdateForKeys, withHandlers } from 'recompact'; import { fonts, padding, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; -import Icon from '../icons/Icon'; +import { Icon } from '../icons'; import { Centered, FlexItem, @@ -21,28 +15,33 @@ import { TruncatedText } from '../text'; const ListItemHeight = 54; -const Container = styled(Row).attrs({ - align: 'center', - justify: 'space-between', -})` - ${padding(0, 16, 2)}; - height: ${ListItemHeight}; -`; - -const Label = styled(TruncatedText).attrs({ - size: 'bmedium', -})` - flex: 1; - padding-right: ${fonts.size.bmedium}; -`; - -const renderListItemIcon = icon => ( +const renderIcon = icon => ( isString(icon) ? : icon ); -const ListItem = ({ +const propTypes = { + activeOpacity: PropTypes.number, + children: PropTypes.node, + icon: PropTypes.oneOfType([Icon.propTypes.name, PropTypes.node]), + iconMargin: PropTypes.number, + label: PropTypes.string.isRequired, + onPress: PropTypes.func, +}; + +const enhance = compose( + onlyUpdateForKeys(Object.keys(propTypes)), + withHandlers({ + onPress: ({ onPress, value }) => () => { + if (onPress) { + onPress(value); + } + }, + }), +); + +const ListItem = enhance(({ activeOpacity, children, icon, @@ -57,46 +56,39 @@ const ListItem = ({ onPress={onPress} scaleTo={1} > - + - {icon && ( - - {renderListItemIcon(icon)} - - )} - + {icon && {renderIcon(icon)}} + + {label} + {children && ( {children} )} - +
-); +)); -ListItem.propTypes = { - activeOpacity: PropTypes.number, - children: PropTypes.node, - icon: PropTypes.oneOfType([Icon.propTypes.name, PropTypes.node]), - iconMargin: PropTypes.number, - label: PropTypes.string.isRequired, - onPress: PropTypes.func, -}; +ListItem.propTypes = propTypes; + +ListItem.height = ListItemHeight; ListItem.defaultProps = { activeOpacity: 0.3, iconMargin: 9, }; -export default compose( - setStatic({ height: ListItemHeight }), - withHandlers({ - onPress: ({ onPress, value }) => () => { - if (onPress) { - onPress(value); - } - }, - }), - onlyUpdateForPropTypes, -)(ListItem); +export default ListItem; diff --git a/src/components/list/ListItemArrowGroup.js b/src/components/list/ListItemArrowGroup.js index cb0890e1800..79a8182d816 100644 --- a/src/components/list/ListItemArrowGroup.js +++ b/src/components/list/ListItemArrowGroup.js @@ -3,20 +3,27 @@ import React from 'react'; import { pure } from 'recompact'; import { colors } from '../../styles'; import { Icon } from '../icons'; -import { Row } from '../layout'; +import { RowWithMargins } from '../layout'; import { Text } from '../text'; const ListItemArrowGroup = ({ children }) => ( - - - {children} - + + {typeof children === 'string' + ? {children} + : children + } - + ); ListItemArrowGroup.propTypes = { diff --git a/src/components/list/ListItemDivider.js b/src/components/list/ListItemDivider.js index a3dbcb77b44..a0d779b2bea 100644 --- a/src/components/list/ListItemDivider.js +++ b/src/components/list/ListItemDivider.js @@ -1,5 +1,6 @@ import { PropTypes } from 'prop-types'; import React from 'react'; +import { withNeverRerender } from '../../hoc'; import Divider from '../Divider'; const ListItemDivider = ({ inset }) => ; @@ -12,4 +13,4 @@ ListItemDivider.defaultProps = { inset: 16, }; -export default ListItemDivider; +export default withNeverRerender(ListItemDivider); diff --git a/src/components/list/SectionList.js b/src/components/list/SectionList.js deleted file mode 100644 index 138fdc06a58..00000000000 --- a/src/components/list/SectionList.js +++ /dev/null @@ -1,101 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import { RefreshControl, SectionList as ReactSectionList } from 'react-native'; -import { View } from 'react-primitives'; -import styled from 'styled-components/primitives'; -import { withSafeAreaViewInsetValues } from '../../hoc'; -import { colors, position } from '../../styles'; -import ListFooter from './ListFooter'; -import ListHeader from './ListHeader'; - -const DefaultRenderItem = renderItemProps => ; - -const List = styled(ReactSectionList)` - ${position.size('100%')} - background-color: ${colors.white}; -`; - -class SectionList extends PureComponent { - static propTypes = { - enablePullToRefresh: PropTypes.bool, - fetchData: PropTypes.func, - hideHeader: PropTypes.bool, - isRefreshing: PropTypes.bool, - onRefresh: PropTypes.func, - renderItem: PropTypes.func, - renderSectionFooter: PropTypes.func, - safeAreaInset: PropTypes.object, - showSafeAreaInsetBottom: PropTypes.bool, - } - - static defaultProps = { - enablePullToRefresh: false, - renderItem: DefaultRenderItem, - renderSectionFooter: ListFooter, - showSafeAreaInsetBottom: true, - } - - state = { isRefreshing: false } - - componentDidMount = () => { - this.isCancelled = false; - } - - componentWillUnmount = () => { - this.isCancelled = true; - } - - listRef = null - - handleListRef = (ref) => { this.listRef = ref; } - - handleRefresh = () => { - if (this.state.isRefreshing) return; - - this.setState({ isRefreshing: true }); - this.props.fetchData().then(() => { - if (!this.isCancelled) { - this.setState({ isRefreshing: false }); - } - }); - } - - renderRefreshControl = () => { - if (!this.props.enablePullToRefresh) return null; - - return ( - - ); - } - - render = () => { - const { - hideHeader, - renderItem, - renderSectionFooter, - safeAreaInset, - showSafeAreaInsetBottom, - ...props - } = this.props; - - return ( - - ); - } -} - -export default withSafeAreaViewInsetValues(SectionList); diff --git a/src/components/list/index.js b/src/components/list/index.js index 92f3e7a8c1b..ad6a5eeba32 100644 --- a/src/components/list/index.js +++ b/src/components/list/index.js @@ -4,4 +4,3 @@ export { default as ListHeader } from './ListHeader'; export { default as ListItem } from './ListItem'; export { default as ListItemArrowGroup } from './ListItemArrowGroup'; export { default as ListItemDivider } from './ListItemDivider'; -export { default as SectionList } from './SectionList'; diff --git a/src/components/settings-menu/BackupSection.js b/src/components/settings-menu/BackupSection.js index ca131195f90..6eb5087cdf4 100644 --- a/src/components/settings-menu/BackupSection.js +++ b/src/components/settings-menu/BackupSection.js @@ -46,7 +46,7 @@ const BackupSection = ({ size="large" weight="semibold" > - Your Seed Phrase + Your Private Key {seedPhrase @@ -54,7 +54,7 @@ const BackupSection = ({ If you lose access to your device, the only way to restore your - funds is with your 12-word seed phrase. + funds is with your private key.

Please store it in a safe place. @@ -81,7 +81,7 @@ const BackupSection = ({ }
- {seedPhrase ? 'Hide' : 'Show'} Seed Phrase + {seedPhrase ? 'Hide' : 'Show'} Private Key ); diff --git a/src/components/settings-menu/CurrencySection.js b/src/components/settings-menu/CurrencySection.js index f20a74eeb1b..9629c7f1fdb 100644 --- a/src/components/settings-menu/CurrencySection.js +++ b/src/components/settings-menu/CurrencySection.js @@ -29,8 +29,7 @@ const renderCurrencyIcon = (currency, emojiName) => { ); }; -// eslint-disable-next-line react/prop-types -const renderCurrencyListItem = ({ +const CurrencyListItem = ({ currency, emojiName, label, @@ -44,12 +43,18 @@ const renderCurrencyListItem = ({ /> ); +CurrencyListItem.propTypes = { + currency: PropTypes.string, + emojiName: PropTypes.string, + label: PropTypes.string, +}; + const CurrencySection = ({ nativeCurrency, onSelectCurrency }) => ( ); diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index 63bb6b839fb..23fda7a9b1f 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -1,20 +1,26 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { Linking, ScrollView } from 'react-native'; +import { InteractionManager, Linking, ScrollView } from 'react-native'; +import DeviceInfo from 'react-native-device-info'; import FastImage from 'react-native-fast-image'; +import * as StoreReview from 'react-native-store-review'; import { compose, onlyUpdateForKeys, withHandlers } from 'recompact'; import styled from 'styled-components/primitives'; import BackupIcon from '../../assets/backup-icon.png'; import CurrencyIcon from '../../assets/currency-icon.png'; import LanguageIcon from '../../assets/language-icon.png'; import NetworkIcon from '../../assets/network-icon.png'; -import { supportedLanguages } from '../../languages'; // import SecurityIcon from '../../assets/security-icon.png'; +import { + getAppStoreReviewRequestCount, + setAppStoreReviewRequestCount, +} from '../../handlers/commonStorage'; import { withAccountSettings, withSendFeedback } from '../../hoc'; -import { position } from '../../styles'; +import { supportedLanguages } from '../../languages'; +import { colors, position } from '../../styles'; import AppVersionStamp from '../AppVersionStamp'; import { Icon } from '../icons'; -import { Column } from '../layout'; +import { Centered, Column, ColumnWithDividers } from '../layout'; import { ListFooter, ListItem, @@ -24,9 +30,9 @@ import { import { Emoji } from '../text'; const SettingsExternalURLs = { - about: 'https://twitter.com/rainbowdotme', - feedback: 'http://rainbow.me', - legal: 'https://github.com/rainbow-me/rainbow/blob/master/LICENSE', + review: 'itms-apps://itunes.apple.com/us/app/appName/id1457119021?mt=8&action=write-review', + twitterDeepLink: 'twitter://user?screen_name=rainbowdotme', + twitterWebUrl: 'https://twitter.com/rainbowdotme', }; // ⚠️ Beware: magic numbers lol @@ -46,9 +52,10 @@ const SettingsSection = ({ onPressImportSeedPhrase, onPressLanguage, onPressNetwork, + onPressReview, + onPressTwitter, onSendFeedback, // onPressSecurity, - openWebView, ...props }) => ( - + } onPress={onPressBackup} label="Backup" > - + {/* + + + XXX TODO: show this icon after a user has completed the "backup" user flow + + + + + */} - } onPress={onPressNetwork} @@ -80,7 +94,6 @@ const SettingsSection = ({ {network || ''} - } onPress={onPressCurrency} @@ -90,7 +103,6 @@ const SettingsSection = ({ {nativeCurrency || ''} - } onPress={onPressLanguage} @@ -110,40 +122,36 @@ const SettingsSection = ({ */} - + - + } - label="Import Seed Phrase" + label="Import Wallet" onPress={onPressImportSeedPhrase} /> - } label="Follow Us" - onPress={openWebView} - value={SettingsExternalURLs.about} + onPress={onPressTwitter} + value={SettingsExternalURLs.twitter} /> - } + icon={} label="Leave Feedback️" onPress={onSendFeedback} /> - } - label="Legal" - onPress={openWebView} - value={SettingsExternalURLs.legal} + icon={} + label="Review Rainbow" + onPress={onPressReview} /> - + @@ -159,9 +167,10 @@ SettingsSection.propTypes = { onPressImportSeedPhrase: PropTypes.func.isRequired, onPressLanguage: PropTypes.func.isRequired, onPressNetwork: PropTypes.func, - onSendFeedback: PropTypes.func.isRequired, + onPressReview: PropTypes.func, // onPressSecurity: PropTypes.func.isRequired, - openWebView: PropTypes.func, + onPressTwitter: PropTypes.func, + onSendFeedback: PropTypes.func.isRequired, }; SettingsSection.defaultProps = { @@ -172,6 +181,28 @@ SettingsSection.defaultProps = { export default compose( withAccountSettings, withSendFeedback, - withHandlers({ openWebView: () => uri => Linking.openURL(uri) }), + withHandlers({ + onPressReview: ({ onCloseModal }) => async () => { + const maxRequestCount = 2; + const count = await getAppStoreReviewRequestCount(); + const shouldDeeplinkToAppStore = (count >= maxRequestCount) || !StoreReview.isAvailable; + + if (shouldDeeplinkToAppStore && !DeviceInfo.isEmulator()) { + Linking.openURL(SettingsExternalURLs.review); + } else { + onCloseModal(); + InteractionManager.runAfterInteractions(StoreReview.requestReview); + } + + return setAppStoreReviewRequestCount(count + 1); + }, + onPressTwitter: () => async () => { + Linking.canOpenURL(SettingsExternalURLs.twitterDeepLink).then((supported) => ( + supported + ? Linking.openURL(SettingsExternalURLs.twitterDeepLink) + : Linking.openURL(SettingsExternalURLs.twitterWebUrl) + )); + }, + }), onlyUpdateForKeys(['language', 'nativeCurrency']), )(SettingsSection); diff --git a/src/components/shadow-stack/ShadowStack.js b/src/components/shadow-stack/ShadowStack.js index 78f843b71b1..dc81789832b 100644 --- a/src/components/shadow-stack/ShadowStack.js +++ b/src/components/shadow-stack/ShadowStack.js @@ -23,11 +23,14 @@ const ShadowStackContainer = styled.View` z-index: 1; `; +const ShadowItemPropBlacklist = ['children', 'shadowProps', 'shadows', 'style']; + export default class ShadowStack extends PureComponent { static propTypes = { borderRadius: PropTypes.number.isRequired, children: PropTypes.node, height: PropTypes.number.isRequired, + shadowProps: PropTypes.object, shadows: PropTypes.arrayOf(PropTypes.array).isRequired, style: stylePropType, childrenWrapperStyle: stylePropType, @@ -40,10 +43,11 @@ export default class ShadowStack extends PureComponent { renderItem = (shadow, index) => ( ) diff --git a/src/components/text/TruncatedText.js b/src/components/text/TruncatedText.js index 6624eec129a..42c3627968c 100644 --- a/src/components/text/TruncatedText.js +++ b/src/components/text/TruncatedText.js @@ -1,4 +1,5 @@ import PropTypes from 'prop-types'; +import { pure } from 'recompact'; import { createElement } from 'react'; import Text from './Text'; @@ -16,4 +17,4 @@ TruncatedText.defaultProps = { numberOfLines: 1, }; -export default TruncatedText; +export default pure(TruncatedText); diff --git a/src/components/token-family/TokenFamilyHeader.js b/src/components/token-family/TokenFamilyHeader.js index 95b7ab03111..0c1e58ad460 100644 --- a/src/components/token-family/TokenFamilyHeader.js +++ b/src/components/token-family/TokenFamilyHeader.js @@ -1,119 +1,147 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { PureComponent } from 'react'; +import { FallbackIcon } from 'react-coin-icon'; import FastImage from 'react-native-fast-image'; import Animated, { Easing } from 'react-native-reanimated'; +import { toRad } from 'react-native-redash'; +import { toClass, withProps } from 'recompact'; import styled from 'styled-components/primitives'; -import Caret from '../../assets/family-dropdown-arrow.png'; -import { colors } from '../../styles'; +import CaretImageSource from '../../assets/family-dropdown-arrow.png'; +import { borders, colors, padding } from '../../styles'; +import { initials, isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; import Highlight from '../Highlight'; +import ImageWithCachedDimensions from '../ImageWithCachedDimensions'; +import { Row, RowWithMargins } from '../layout'; import { ShadowStack } from '../shadow-stack'; import { TruncatedText, Monospace } from '../text'; import RotationArrow from '../animations/RotationArrow'; -const Wrapper = styled.View` - height: 56px; - width: 100%; - padding: 11px; - align-items: center; - flex-direction: row; - justify-content: space-between; -`; +const { interpolate, timing, Value } = Animated; -const Image = styled.View` - background-color: #ffd9fe; - justify-content: center; - border-radius: 10.3px; -`; +const AnimatedMonospace = Animated.createAnimatedComponent(toClass(Monospace)); +const AnimatedFastImage = Animated.createAnimatedComponent(FastImage); -const FamilyImage = styled(FastImage)` - border-radius: 10.3px; -`; +const TokenFamilyHeaderAnimationDuration = 200; +const TokenFamilyHeaderHeight = 50; -const LeftView = styled.View` - align-items: center; - flex-direction: row; -`; +const FamilyIcon = withProps(({ familyImage }) => ({ + id: familyImage, + source: { uri: familyImage }, +}))(ImageWithCachedDimensions); -const ArrowWrap = styled.View` - padding-left: 9px; - transform: scale(0.8); -`; +export default class TokenFamilyHeader extends PureComponent { + static propTypes = { + childrenAmount: PropTypes.number, + familyImage: PropTypes.string, + familyName: PropTypes.string, + highlight: PropTypes.bool, + isCoinRow: PropTypes.bool, + isOpen: PropTypes.bool, + onHeaderPress: PropTypes.func, + } + + static animationDuration = TokenFamilyHeaderAnimationDuration; + + static height = TokenFamilyHeaderHeight; + + animation = new Value(0) + + componentDidMount = () => this.runTiming() + + componentDidUpdate = (prevProps) => { + if (isNewValueForPath(this.props, prevProps, 'isOpen')) { + this.runTiming(); + } + } + + runTiming = () => ( + timing(this.animation, { + duration: TokenFamilyHeaderAnimationDuration, + easing: Easing.bezier(0.25, 0.1, 0.25, 1), + toValue: this.props.isOpen ? 1 : 0, + }).start() + ) -const SettingIcon = styled(FastImage)` - height: 20px; - width: 9px; -`; + renderFamilyIcon = () => { + const { familyImage, familyName, isCoinRow } = this.props; + const size = borders.buildCircleAsObject(isCoinRow ? 40 : 32); -class TokenListHeader extends React.Component { - render() { - dimension = this.props.isCoinRow ? 40 : 34; - padding = this.props.isCoinRow ? 16 : 19; return ( - { - this.props.onHeaderPress(); - }} + - - - - - {(this.props.familyImage) ? ( - - ) : ( - - )} - - - {this.props.familyName} - - - - - - - - {!this.props.isOpen && - - {this.props.childrenAmount} - - } - - + {familyImage + ? + : + } + ); } -} -TokenListHeader.propTypes = { - childrenAmount: PropTypes.number, - familyImage: PropTypes.string, - familyName: PropTypes.string, - highlight: PropTypes.bool, - isOpen: PropTypes.bool, - onHeaderPress: PropTypes.func, -}; - -export default TokenListHeader; + render = () => ( + + + + + {this.renderFamilyIcon()} + + {this.props.familyName} + + + + + {this.props.childrenAmount} + + + + + + ) +} diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index 9501612097b..77be2ce7427 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -1,20 +1,27 @@ +import { withSafeTimeout } from '@hocs/safe-timers'; +import { times } from 'lodash'; import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React from 'react'; import { withNavigation } from 'react-navigation'; import { View } from 'react-primitives'; import { compose, + lifecycle, + onlyUpdateForKeys, + withState, withHandlers, withProps, - onlyUpdateForKeys, } from 'recompact'; +import { createSelector } from 'reselect'; import { withOpenFamilyTabs, withFabSendAction } from '../../hoc'; +import { colors } from '../../styles'; +import { FadeInAnimation } from '../animations'; import { UniqueTokenRow } from '../unique-token'; import TokenFamilyHeader from './TokenFamilyHeader'; -import { FadeInAnimation } from '../animations'; -import { colors } from '../../styles'; -const enhanceRenderItem = compose( +export const TokenFamilyWrapPaddingTop = 6; + +const EnhancedUniqueTokenRow = compose( withNavigation, withHandlers({ onPress: ({ assetType, navigation }) => (item) => { @@ -27,132 +34,121 @@ const enhanceRenderItem = compose( navigation.navigate('SendSheet', { asset }); }, }), -); +)(UniqueTokenRow); -const UniqueTokenItem = enhanceRenderItem(UniqueTokenRow); +const getHeight = (openFamilyTab) => (openFamilyTab ? UniqueTokenRow.height + 100 : 100); -const getHeight = (openFamilyTab) => ( - openFamilyTab - ? UniqueTokenRow.getHeight(false, false) + 100 - : 100 +const TokenFamilyWrap = ({ + areChildrenVisible, + childrenAmount, + familyId, + familyImage, + familyName, + highlight, + isFamilyOpen, + item, + marginTop, + onPressFamilyHeader, + renderCollectibleItem, +}) => ( + + + {areChildrenVisible && ( + + {times(item.length, renderCollectibleItem)} + + )} + ); -class TokenFamilyWrap extends Component { - constructor(props) { - super(props); - - this.state = { - opacity: 0, - }; - } - - shouldComponentUpdate = (prev, next) => { - const familyId = this.props.item[0][0].asset_contract.name; - if (this.props.openFamilyTabs[familyId] !== prev.openFamilyTabs[familyId] - || this.state.opacity != next.opacity - || this.props.highlight !== prev.highlight) { - return true; - } - return false; - } - - componentDidUpdate = () => { - const familyId = this.props.item[0][0].asset_contract.name; - const newOpacity = this.props.openFamilyTabs[familyId] ? 1 : 0; - if (newOpacity) { - setTimeout(() => { - this.setState({ opacity: newOpacity }); - }, 100); - } else { - this.setState({ opacity: newOpacity }); - } - } - - collectiblesRenderItem = item => { - if (this.props.openFamilyTabs[item.familyName]) { - const tokens = []; - for (let i = 0; i < item.item.length; i++) { - tokens.push( - - ); - } - return tokens; - } - }; - - onHeaderPress = () => { - this.props.setOpenFamilyTabs({ - index: this.props.item[0][0].asset_contract.name, - state: !this.props.openFamilyTabs[this.props.item[0][0].asset_contract.name], - }); - }; - - componentDidMount = () => { - if (this.props.openFamilyTabs[this.props.familyName]) { - this.setState({ opacity: 1 }); - } - } - - render() { - const content = this.collectiblesRenderItem(this.props); - - return ( - - - {this.state.opacity === 1 - && - {content} - - } - - ); - } -} - TokenFamilyWrap.propTypes = { + areChildrenVisible: PropTypes.bool, childrenAmount: PropTypes.number, + familyId: PropTypes.string, familyImage: PropTypes.string, familyName: PropTypes.string, highlight: PropTypes.bool, + isFamilyOpen: PropTypes.bool, + isOpen: PropTypes.bool, item: PropTypes.array, - openFamilyTabs: PropTypes.array, - setOpenFamilyTabs: PropTypes.func, + marginTop: PropTypes.number, + onPressFamilyHeader: PropTypes.func, + renderCollectibleItem: PropTypes.func, }; TokenFamilyWrap.getHeight = getHeight; +const familyIdSelector = state => state.familyId; +const openFamilyTabsSelector = state => state.openFamilyTabs; + +const isFamilyOpenSelector = (familyId, openFamilyTabs) => ({ + isFamilyOpen: openFamilyTabs && openFamilyTabs[familyId], +}); + +const withFamilyOpenStateProps = createSelector( + [familyIdSelector, openFamilyTabsSelector], + isFamilyOpenSelector, +); + export default compose( + withSafeTimeout, + withFabSendAction, + withOpenFamilyTabs, + withProps(withFamilyOpenStateProps), + withState('areChildrenVisible', 'setAreChildrenVisible', false), withHandlers({ - onPress: ({ item, onPress }) => () => { - if (onPress) { - onPress(item); + onHideChildren: ({ areChildrenVisible, setAreChildrenVisible }) => () => { + if (areChildrenVisible) { + setAreChildrenVisible(false); } }, - onPressSend: ({ item, onPressSend }) => () => { - if (onPressSend) { - onPressSend(item); + onPressFamilyHeader: ({ familyId, isFamilyOpen, setOpenFamilyTabs }) => () => ( + setOpenFamilyTabs({ + index: familyId, + state: !isFamilyOpen, + }) + ), + onShowChildren: ({ areChildrenVisible, setAreChildrenVisible }) => () => { + if (!areChildrenVisible) { + setAreChildrenVisible(true); + } + }, + /* eslint-disable react/display-name */ + renderCollectibleItem: ({ familyId, item }) => (index) => ( + + ), + /* eslint-enable react/display-name */ + }), + lifecycle({ + componentDidUpdate() { + if (!this.props.isFamilyOpen) { + this.props.onHideChildren(); + } else if (!this.props.areChildrenVisible) { + this.props.setSafeTimeout(this.props.onShowChildren, TokenFamilyHeader.animationDuration); } }, }), - withProps(({ item: { uniqueId } }) => ({ uniqueId })), - withFabSendAction, onlyUpdateForKeys([ - 'height', - 'style', - 'uniqueId', - 'width', + 'areChildrenVisible', + 'childrenAmount', 'highlight', + 'marginTop', + 'isFamilyOpen', + 'uniqueId', ]), -)(withOpenFamilyTabs(TokenFamilyWrap)); +)(TokenFamilyWrap); diff --git a/src/components/token-family/index.js b/src/components/token-family/index.js index 2992ad9a562..00af6d8c6b6 100644 --- a/src/components/token-family/index.js +++ b/src/components/token-family/index.js @@ -1 +1,2 @@ +export { default as TokenFamilyHeader } from './TokenFamilyHeader'; export { default as TokenFamilyWrap } from './TokenFamilyWrap'; diff --git a/src/components/unique-token/UniqueTokenCard.js b/src/components/unique-token/UniqueTokenCard.js index 6656fb6b88b..0dbfaeb7166 100644 --- a/src/components/unique-token/UniqueTokenCard.js +++ b/src/components/unique-token/UniqueTokenCard.js @@ -7,7 +7,6 @@ import { withHandlers, withProps, } from 'recompact'; -import styled from 'styled-components/primitives'; import { withFabSendAction } from '../../hoc'; import { colors, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; @@ -19,10 +18,6 @@ import UniqueTokenImage from './UniqueTokenImage'; const UniqueTokenCardBorderRadius = 18; -const Shadow = styled(Highlight)` - background-color: ${({ highlight }) => (highlight ? '#FFFFFF33' : colors.transparent)}; -`; - const UniqueTokenCard = ({ disabled, height, @@ -75,7 +70,10 @@ const UniqueTokenCard = ({ opacity={0.04} radius={UniqueTokenCardBorderRadius} /> - + diff --git a/src/components/unique-token/UniqueTokenRow.js b/src/components/unique-token/UniqueTokenRow.js index fc8a2a1944b..c98c2acfe03 100644 --- a/src/components/unique-token/UniqueTokenRow.js +++ b/src/components/unique-token/UniqueTokenRow.js @@ -1,24 +1,18 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { onlyUpdateForKeys } from 'recompact'; +import { shouldUpdate } from 'recompact'; import { padding, position } from '../../styles'; -import { deviceUtils } from '../../utils'; +import { deviceUtils, isNewValueForPath } from '../../utils'; import { Row } from '../layout'; import UniqueTokenCard from './UniqueTokenCard'; -export const CardMargin = 15; -export const RowPadding = 19; -export const CardSize = (deviceUtils.dimensions.width - (RowPadding * 2) - CardMargin) / 2; +const CardMargin = 15; +const RowPadding = 19; +const CardSize = (deviceUtils.dimensions.width - (RowPadding * 2) - CardMargin) / 2; -const getHeight = (isFirstRow, isLastRow) => CardSize - + CardMargin * (isLastRow ? 1.25 : 1) - + (isFirstRow ? CardMargin : 0); - -const enhance = onlyUpdateForKeys(['isFirstRow', 'isLastRow', 'uniqueId']); +const enhance = shouldUpdate((...props) => isNewValueForPath(...props, 'item.uniqueId')); const UniqueTokenRow = enhance(({ - isFirstRow, - isLastRow, item, onPress, onPressSend, @@ -27,8 +21,8 @@ const UniqueTokenRow = enhance(({ align="center" css={` ${padding(0, RowPadding)}; - margin-bottom: ${CardMargin * (isLastRow ? 1.25 : 1)}; - margin-top: ${isFirstRow ? CardMargin : 0}; + margin-bottom: ${CardMargin}; + margin-top: 0; width: 100%; `} > @@ -36,7 +30,7 @@ const UniqueTokenRow = enhance(({ = 1) ? CardMargin : 0 }} @@ -46,13 +40,14 @@ const UniqueTokenRow = enhance(({ )); UniqueTokenRow.propTypes = { - isFirstRow: PropTypes.bool, - isLastRow: PropTypes.bool, item: PropTypes.array, onPress: PropTypes.func, onPressSend: PropTypes.func, }; -UniqueTokenRow.getHeight = getHeight; +UniqueTokenRow.height = CardSize + CardMargin; +UniqueTokenRow.cardSize = CardSize; +UniqueTokenRow.cardMargin = CardMargin; +UniqueTokenRow.rowPadding = RowPadding; export default UniqueTokenRow; diff --git a/src/handlers/__tests__/web3.test.js b/src/handlers/__tests__/web3.test.js new file mode 100644 index 00000000000..118e4d874a0 --- /dev/null +++ b/src/handlers/__tests__/web3.test.js @@ -0,0 +1,30 @@ +import { ethers } from 'ethers'; +import { + isHexString, + isValidMnemonic, + mnemonicToSeed, +} from '../web3'; + +test('isHexString', () => { + const address = '0x1492004547FF0eFd778CC2c14E794B26B4701105'; + const result = isHexString(address); + expect(result).toBeTruthy(); +}); + +test('isHexStringFalse', () => { + const address = '1492004547FF0eFd778CC2c14E794B26B4701105'; + const result = isHexString(address); + expect(result).toBeFalsy(); +}); + +test('isHexStringFalse', () => { + const address = '1492004547FF0eFd778CC2c14E794B26B470110'; + const result = isHexString(address); + expect(result).toBeFalsy(); +}); + +test('isValidMnemonic', () => { + const seed = 'blah'; + const result = isValidMnemonic(seed); + expect(result).toBeFalsy(); +}); diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index c01066104a9..b5002ec3bfe 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -69,6 +69,7 @@ export const removeLocal = (key = '') => { }; const getAssetsKey = (accountAddress, network) => `assets-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; +const getIsWalletEmptyKey = (accountAddress, network) => `iswalletempty-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getRequestsKey = (accountAddress, network) => `requests-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getTransactionsKey = (accountAddress, network) => `transactions-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniqueTokensKey = (accountAddress, network) => `uniquetokens-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; @@ -214,6 +215,38 @@ export const removeLocalTransactions = (accountAddress, network) => { removeLocal(key, transactionsVersion); }; +/** + * @desc get is wallet empty + * @param {String} [address] + * @param {String} [network] + * @return {Boolean} + */ +export const getIsWalletEmpty = async (accountAddress, network) => await getLocal(getIsWalletEmptyKey(accountAddress, network)); + +/** + * @desc save is wallet empty + * @param {String} [address] + * @param {Boolean} [isWalletEmpty] + * @param {String} [network] + */ +export const saveIsWalletEmpty = async (accountAddress, isWalletEmpty, network) => { + await saveLocal( + getIsWalletEmptyKey(accountAddress, network), + isWalletEmpty, + ); +}; + +/** + * @desc remove is wallet empty + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeIsWalletEmpty = (accountAddress, network) => { + const key = getIsWalletEmptyKey(accountAddress, network); + removeLocal(key); +}; + /** * @desc get unique tokens * @param {String} [address] @@ -468,4 +501,16 @@ export const getOpenFamilies = async () => { */ export const saveOpenFamilies = async openFamilies => { await saveLocal('openFamilies', { data: openFamilies }); -}; \ No newline at end of file +}; + +// apple restricts number of times developers are allowed to throw +// the in-app AppStore Review interface. +// see here for more: https://github.com/oblador/react-native-store-review +export const getAppStoreReviewRequestCount = async () => { + const count = await getLocal('appStoreReviewRequestCount'); + return count ? count.data : 0; +}; + +export const setAppStoreReviewRequestCount = async (newCount) => { + await saveLocal('appStoreReviewRequestCount', { data: newCount }); +}; diff --git a/src/handlers/web3.js b/src/handlers/web3.js index c95af274d4a..2b3c8c6e48e 100644 --- a/src/handlers/web3.js +++ b/src/handlers/web3.js @@ -1,5 +1,9 @@ import { ethers } from 'ethers'; -import { get, replace } from 'lodash'; +import { + get, + replace, + startsWith, +} from 'lodash'; import { REACT_APP_INFURA_PROJECT_ID } from 'react-native-dotenv'; import { ethereumUtils } from '../utils'; import { @@ -34,6 +38,23 @@ export const sendRpcCall = async (payload) => web3Provider.send(payload.method, */ export const isHexString = value => ethers.utils.isHexString(value); +export const isHexStringIgnorePrefix = value => { + const trimmedValue = value.trim(); + const updatedValue = addHexPrefix(trimmedValue); + return isHexString(updatedValue); +}; + +export const addHexPrefix = value => (startsWith(value, '0x')) ? value : '0x' + value; + +export const mnemonicToSeed = value => ethers.utils.HDNode.mnemonicToSeed(value); + +/** + * @desc is valid mnemonic + * @param {String} value + * @return {Boolean} + */ +export const isValidMnemonic = value => ethers.utils.HDNode.isValidMnemonic(value); + /** * @desc convert to checksum address * @param {String} address @@ -54,6 +75,16 @@ export const toChecksumAddress = async (address) => { */ export const toHex = value => ethers.utils.hexlify(ethers.utils.bigNumberify(value)); +/** + * @desc has ETH balance + * @param {String} address + * @return {Boolean} + */ +export const hasEthBalance = async (address) => { + const weiBalance = await web3Provider.getBalance(address, "pending"); + return weiBalance > 0; +}; + /** * @desc estimate gas limit * @param {String} address diff --git a/src/helpers/assets.js b/src/helpers/assets.js index d4df22652af..6f565f11dbe 100644 --- a/src/helpers/assets.js +++ b/src/helpers/assets.js @@ -9,7 +9,7 @@ export const buildAssetHeaderUniqueIdentifier = ({ title, totalItems, totalValue, -}) => ([title, totalItems, totalValue].join('_')); +}) => (compact([title, totalItems, totalValue]).join('_')); export const buildAssetUniqueIdentifier = (item) => { const balance = get(item, 'balance.amount', ''); @@ -42,8 +42,10 @@ export const buildCoinsList = (assets) => { export const buildUniqueTokenList = (uniqueTokens) => { let rows = []; + const grouped = groupBy(uniqueTokens, token => token.asset_contract.name); const families = Object.keys(grouped); + for (let i = 0; i < families.length; i++) { const tokensRow = []; for (let j = 0; j < grouped[families[i]].length; j += 2) { diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index 5625e1a09ad..d82ae2f1740 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -1,10 +1,18 @@ import lang from 'i18n-js'; -import { findIndex, get } from 'lodash'; +import { + compact, + findIndex, + flattenDeep, + get, + groupBy, + property, +} from 'lodash'; import React from 'react'; +import FastImage from 'react-native-fast-image'; import { withNavigation } from 'react-navigation'; import { compose, withHandlers } from 'recompact'; import { createSelector } from 'reselect'; -import FastImage from 'react-native-fast-image'; +import { AssetListItemSkeleton } from '../components/asset-list'; import { BalanceCoinRow } from '../components/coin-row'; import { UniswapInvestmentCard } from '../components/investment-cards'; import { TokenFamilyWrap } from '../components/token-family'; @@ -14,6 +22,8 @@ const allAssetsSelector = state => state.allAssets; const allAssetsCountSelector = state => state.allAssetsCount; const assetsSelector = state => state.assets; const assetsTotalSelector = state => state.assetsTotal; +const isBalancesSectionEmptySelector = state => state.isBalancesSectionEmpty; +const isWalletEthZeroSelector = state => state.isWalletEthZero; const languageSelector = state => state.language; const nativeCurrencySelector = state => state.nativeCurrency; const setIsWalletEmptySelector = state => state.setIsWalletEmpty; @@ -40,8 +50,15 @@ const enhanceRenderItem = compose( const TokenItem = enhanceRenderItem(BalanceCoinRow); const UniswapCardItem = enhanceRenderItem(UniswapInvestmentCard); +const balancesSkeletonRenderItem = item => ( + +); const balancesRenderItem = item => ; -const tokenFamilyItem = item => ; +const tokenFamilyItem = item => ; const uniswapRenderItem = item => ; const filterWalletSections = sections => ( @@ -53,92 +70,200 @@ const filterWalletSections = sections => ( ); const buildWalletSections = ( + balanceSection, + setIsWalletEmpty, + uniqueTokenFamiliesSection, + uniswapSection, +) => { + const sections = [ + balanceSection, + uniswapSection, + uniqueTokenFamiliesSection, + ]; + + console.log(uniswapSection); + + const filteredSections = filterWalletSections(sections); + const isEmpty = !filteredSections.length; + setIsWalletEmpty(isEmpty); + + return { + isEmpty, + sections: filteredSections, + }; +}; + +const withUniswapSection = ( + language, + nativeCurrency, + uniswap, + uniswapTotal, +) => { + return { + data: uniswap, + header: { + title: 'Investments', + totalItems: uniswap.length, + totalValue: uniswapTotal, + }, + investments: true, + name: 'investments', + renderItem: uniswapRenderItem, + }; +}; + +const withBalanceSection = ( allAssets, allAssetsCount, assets, assetsTotal, + isBalancesSectionEmpty, + isWalletEthZero, language, nativeCurrency, - setIsWalletEmpty, - shitcoinsCount, - uniqueTokens = [], - uniswap = [], - uniswapTotal, + showShitcoins, ) => { - const sections = [ - { - balances: true, - data: buildCoinsList(allAssets), - header: { - title: lang.t('account.tab_balances'), - totalItems: allAssetsCount, - totalValue: get(assetsTotal, 'display', ''), - }, - name: 'balances', - renderItem: balancesRenderItem, - }, - { - data: uniswap, - header: { - title: 'Investments', - totalItems: uniswap.length, - totalValue: uniswapTotal, - }, - investments: true, - name: 'investments', - renderItem: uniswapRenderItem, - }, - { - collectibles: true, - data: buildUniqueTokenList(uniqueTokens), - header: { - title: lang.t('account.tab_collectibles'), - totalItems: uniqueTokens.length, - totalValue: '', - }, - name: 'collectibles', - renderItem: tokenFamilyItem, - type: 'big', + let balanceSectionData = buildCoinsList(allAssets); + const isLoadingBalances = (!isWalletEthZero && isBalancesSectionEmpty); + if (isLoadingBalances) { + balanceSectionData = [{ item: { uniqueId: 'skeleton0' } }]; + } + + return { + balances: true, + data: balanceSectionData, + header: { + showShitcoins, + title: lang.t('account.tab_balances'), + totalItems: isLoadingBalances ? 1 : allAssetsCount, + totalValue: get(assetsTotal, 'display', ''), }, - ]; + name: 'balances', + renderItem: isLoadingBalances + ? balancesSkeletonRenderItem + : balancesRenderItem, + }; +}; - const imageTokens = []; - uniqueTokens.forEach(token => { - if (token.image_preview_url) { - imageTokens.push({ - uri: token.image_preview_url, - id: token.id - }); +let isPreloadComplete = false; +const largeFamilyThreshold = 4; +const jumboFamilyThreshold = largeFamilyThreshold * 2; +const minTopFoldThreshold = 10; + +const buildImagesToPreloadArray = (family, index, families) => { + const isLargeFamily = family.tokens.length > largeFamilyThreshold; + const isJumboFamily = family.tokens.length >= jumboFamilyThreshold; + const isTopFold = index < Math.max(families.length / 2, minTopFoldThreshold); + + return family.tokens.map((token, rowIndex) => { + let priority = FastImage.priority[isTopFold ? 'high' : 'normal']; + + if (isTopFold && isLargeFamily) { + if (rowIndex <= largeFamilyThreshold) { + priority = FastImage.priority.high; + } else if (isJumboFamily) { + const isMedium = (rowIndex > largeFamilyThreshold) && (rowIndex <= jumboFamilyThreshold); + priority = FastImage.priority[isMedium ? 'normal' : 'low']; + } else { + priority = FastImage.priority.normal; + } } - }); - FastImage.preload(imageTokens); + /* eslint-disable camelcase */ + const images = token.map(({ image_preview_url, uniqueId }) => { + if (!image_preview_url) return null; + return ({ + id: uniqueId, + priority, + uri: image_preview_url, + }); + }); + /* eslint-enable camelcase */ - const filteredSections = filterWalletSections(sections); - const isEmpty = !filteredSections.length; + return images.length ? images : null; + }); +}; - // Save wallet empty status to state - setIsWalletEmpty(isEmpty); +const sortImagesToPreload = images => { + const filtered = compact(flattenDeep(images)); + const grouped = groupBy(filtered, property('priority')); + return [ + ...get(grouped, 'high', []), + ...get(grouped, 'normal', []), + ...get(grouped, 'low', []), + ]; +}; + +const withUniqueTokenFamiliesSection = ( + language, + uniqueTokens, + data, +) => { + // TODO preload elsewhere? + if (!isPreloadComplete) { + const imagesToPreload = sortImagesToPreload(data.map(buildImagesToPreloadArray)); + isPreloadComplete = !!imagesToPreload.length; + FastImage.preload(imagesToPreload); + } return { - isEmpty, - sections: filteredSections, + collectibles: true, + data, + header: { + title: lang.t('account.tab_collectibles'), + totalItems: uniqueTokens.length, + totalValue: '', + }, + name: 'collectibles', + renderItem: tokenFamilyItem, + type: 'big', }; }; -export default createSelector( +const uniqueTokenDataSelector = createSelector( + [uniqueTokensSelector], + buildUniqueTokenList, +); + +const balanceSectionSelector = createSelector( [ allAssetsSelector, allAssetsCountSelector, assetsSelector, assetsTotalSelector, + isBalancesSectionEmptySelector, + isWalletEthZeroSelector, + languageSelector, + nativeCurrencySelector, + ], + withBalanceSection, +); + +const uniswapSectionSelector = createSelector( + [ languageSelector, nativeCurrencySelector, - setIsWalletEmptySelector, - shitcoinsCountSelector, - uniqueTokensSelector, uniswapSelector, uniswapTotalSelector, ], + withUniswapSection, +); + +const uniqueTokenFamiliesSelector = createSelector( + [ + languageSelector, + uniqueTokensSelector, + uniqueTokenDataSelector, + ], + withUniqueTokenFamiliesSection, +); + +export default createSelector( + [ + balanceSectionSelector, + setIsWalletEmptySelector, + uniqueTokenFamiliesSelector, + uniswapSectionSelector, + ], buildWalletSections, ); diff --git a/src/helpers/sortList.js b/src/helpers/sortList.js index 6f30811a64b..bc254c4f72c 100644 --- a/src/helpers/sortList.js +++ b/src/helpers/sortList.js @@ -1,28 +1,30 @@ import { get, isFunction, isString } from 'lodash'; -export const sortList = (array = [], sortByKey, direction, defaultValue, formatter) => array.slice(0).sort((a, b) => { - const isAscending = direction === 'asc'; +export const sortList = (array = [], sortByKey, direction, defaultValue, formatter) => ( + array.slice(0).sort((a, b) => { + const isAscending = direction === 'asc'; - let itemA = a; - let itemB = b; + let itemA = a; + let itemB = b; - if (sortByKey) { - itemA = get(a, sortByKey, defaultValue); - itemB = get(b, sortByKey, defaultValue); - } + if (sortByKey) { + itemA = get(a, sortByKey, defaultValue); + itemB = get(b, sortByKey, defaultValue); + } - if (isFunction(formatter)) { - itemA = formatter(itemA); - itemB = formatter(itemB); - } + if (isFunction(formatter)) { + itemA = formatter(itemA); + itemB = formatter(itemB); + } - if (isString(itemA) && isString(itemB)) { - itemA = itemA.toLowerCase(); - itemB = itemB.toLowerCase(); - } + if (isString(itemA) && isString(itemB)) { + itemA = itemA.toLowerCase(); + itemB = itemB.toLowerCase(); + } - if (itemA < itemB) return isAscending ? -1 : 1; - if (itemA > itemB) return isAscending ? 1 : -1; + if (itemA < itemB) return isAscending ? -1 : 1; + if (itemA > itemB) return isAscending ? 1 : -1; - return 0; -}); + return 0; + }) +); diff --git a/src/helpers/validators.js b/src/helpers/validators.js index c8b1e38bada..11ed9d05c0d 100644 --- a/src/helpers/validators.js +++ b/src/helpers/validators.js @@ -1,5 +1,7 @@ import { isHexString, + isHexStringIgnorePrefix, + isValidMnemonic, toChecksumAddress, web3Provider, } from '../handlers/web3'; @@ -41,7 +43,14 @@ export const isValidAddress = async (address) => { * @param {String} seed phrase mnemonic * @return {Boolean} */ -export const isValidSeedPhrase = (seedPhrase) => { +const isValidSeedPhrase = (seedPhrase) => { const phrases = seedPhrase.split(' ').filter(word => !!word).length; - return phrases >= 12 && phrases <= 24; + return phrases >= 12 && isValidMnemonic(seedPhrase); }; + +/** + * @desc validate seed phrase mnemonic or private key + * @param {String} seed phrase mnemonic or private key + * @return {Boolean} + */ +export const isValidSeed = (seed) => isHexStringIgnorePrefix(seed) || isValidSeedPhrase(seed); diff --git a/src/hoc/__tests__/withUniswapLiquidity.test.js b/src/hoc/__tests__/withUniswapLiquidity.test.js index f045058644a..4b0a10a090b 100644 --- a/src/hoc/__tests__/withUniswapLiquidity.test.js +++ b/src/hoc/__tests__/withUniswapLiquidity.test.js @@ -13,7 +13,6 @@ test('transformPool', async () => { }; const balancePriceUnit = '1.01'; const result = transformPool(pool, balancePriceUnit, 'USD'); - console.log('result', result); - expect(result).toHaveProperty('ethBalance', '1.12'); + expect(result).toHaveProperty('ethBalance', 1.12); expect(result).toHaveProperty('nativeDisplay'); }); diff --git a/src/hoc/assetSelectors.js b/src/hoc/assetSelectors.js index 9119eac3ccc..00fd7961d3b 100644 --- a/src/hoc/assetSelectors.js +++ b/src/hoc/assetSelectors.js @@ -44,6 +44,7 @@ const sortAssetsByNativeAmount = (originalAssets, nativeCurrency) => { assets: sortedAssets, assetsCount: sortedAssets.length, assetsTotal: total, + isBalancesSectionEmpty: isEmpty(allAssets), shitcoins: sortedShitcoins, shitcoinsCount: sortedShitcoins.length, }; diff --git a/src/hoc/index.js b/src/hoc/index.js index 5947533f695..852ce83a0a7 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -6,10 +6,13 @@ export { default as withActionSheetManager } from './withActionSheetManager'; export { default as withAppState } from './withAppState'; export { default as withBlurTransitionProps } from './withBlurTransitionProps'; export { default as withDataInit } from './withDataInit'; +export { default as withFabSelection } from './withFabSelection'; export { default as withFabSendAction } from './withFabSendAction'; export { default as withHideSplashScreen } from './withHideSplashScreen'; export { default as withImageDimensionsCache } from './withImageDimensionsCache'; export { default as withIsWalletEmpty } from './withIsWalletEmpty'; +export { default as withIsWalletEthZero } from './withIsWalletEthZero'; +export { default as withIsWalletImporting } from './withIsWalletImporting'; export { default as withMessageSigningScreen } from './withMessageSigningScreen'; export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 16426708929..5bdc681b1d5 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -1,12 +1,19 @@ +import delay from 'delay'; +import { isNil } from 'lodash'; import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { compose, withHandlers } from 'recompact'; +import { getIsWalletEmpty } from '../handlers/commonStorage'; +import { hasEthBalance } from '../handlers/web3'; import { dataClearState, dataLoadState, dataInit, } from '../redux/data'; +import { clearIsWalletEmpty, loadIsWalletEmpty } from '../redux/isWalletEmpty'; +import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; +import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; import { requestsLoadState, requestsClearState, @@ -30,15 +37,26 @@ import { walletConnectLoadState, walletConnectClearState, } from '../redux/walletconnect'; +import withHideSplashScreen from './withHideSplashScreen'; + +const PromiseAllWithFails = async (promises) => ( + Promise.all(promises.map(promise => ( + (promise && promise.catch) + ? promise.catch(error => error) + : promise + )))); export default Component => compose( connect(null, { + clearIsWalletEmpty, + clearOpenFamilyTab, dataClearState, dataInit, dataLoadState, nonceClearState, requestsClearState, requestsLoadState, + setIsWalletEthZero, settingsLoadState, settingsUpdateAccountAddress, uniqueTokensClearState, @@ -50,47 +68,54 @@ export default Component => compose( walletConnectClearState, walletConnectLoadState, }), + withHideSplashScreen, withHandlers({ - clearAccountData: (ownProps) => async () => { + checkEthBalance: (ownProps) => async (walletAddress) => { try { - ownProps.dataClearState(); - ownProps.uniqueTokensClearState(); - ownProps.walletConnectClearState(); - ownProps.nonceClearState(); - ownProps.requestsClearState(); - ownProps.uniswapClearState(); + const ethBalance = await hasEthBalance(walletAddress); + ownProps.setIsWalletEthZero(!ethBalance); } catch (error) { + console.log('Error: Checking eth balance', error); } }, + clearAccountData: (ownProps) => async () => { + const p1 = ownProps.dataClearState(); + const p2 = ownProps.clearIsWalletEmpty(); + const p3 = ownProps.uniqueTokensClearState(); + const p4 = ownProps.clearOpenFamilyTab(); + const p5 = ownProps.walletConnectClearState(); + const p6 = ownProps.nonceClearState(); + const p7 = ownProps.requestsClearState(); + const p8 = ownProps.uniswapClearState(); + return PromiseAllWithFails([p1, p2, p3, p4, p5, p6, p7, p8]); + }, initializeAccountData: (ownProps) => async () => { - ownProps.dataInit(); try { + ownProps.dataInit(); await ownProps.uniqueTokensRefreshState(); } catch (error) { + // TODO } }, loadAccountData: (ownProps) => async () => { - try { - await ownProps.settingsLoadState(); - } catch (error) { - } - try { - await ownProps.uniqueTokensLoadState(); - } catch (error) { - } - try { - await ownProps.dataLoadState(); - } catch (error) { - } - ownProps.walletConnectLoadState(); - ownProps.uniswapLoadState(); - ownProps.requestsLoadState(); + const p1 = ownProps.settingsLoadState(); + const p2 = ownProps.dataLoadState(); + const p3 = ownProps.uniqueTokensLoadState(); + const p4 = ownProps.walletConnectLoadState(); + const p5 = ownProps.uniswapLoadState(); + const p6 = ownProps.requestsLoadState(); + return PromiseAllWithFails([p1, p2, p3, p4, p5, p6]); }, refreshAccountData: (ownProps) => async () => { try { const getUniswap = ownProps.uniswapUpdateState(); const getUniqueTokens = ownProps.uniqueTokensRefreshState(); - return Promise.all([getUniswap, getUniqueTokens]); + + return Promise.all([ + delay(1250), // minimum duration we want the "Pull to Refresh" animation to last + getUniswap, + getUniqueTokens, + ]); } catch (error) { console.log('Error refreshing data', error); throw error; @@ -100,15 +125,37 @@ export default Component => compose( withHandlers({ initializeWallet: (ownProps) => async (seedPhrase) => { try { - const { isWalletBrandNew, walletAddress } = await walletInit(seedPhrase); + const { isImported, isNew, walletAddress } = await walletInit(seedPhrase); + if (isNil(walletAddress)) { + Alert.alert('Import failed due to an invalid private key. Please try again.'); + return null; + } + if (isImported) { + await ownProps.clearAccountData(); + } ownProps.settingsUpdateAccountAddress(walletAddress, 'RAINBOWWALLET'); - if (!isWalletBrandNew) { + if (isNew) { + ownProps.setIsWalletEthZero(true); + } else if (isImported) { + await ownProps.checkEthBalance(walletAddress); + } else { + const isWalletEmpty = await getIsWalletEmpty(walletAddress, 'mainnet'); + if (isNil(isWalletEmpty)) { + ownProps.checkEthBalance(walletAddress); + } else { + ownProps.setIsWalletEthZero(isWalletEmpty); + } + } + if (!(isImported || isNew)) { await ownProps.loadAccountData(); } + ownProps.onHideSplashScreen(); ownProps.initializeAccountData(); return walletAddress; } catch (error) { - Alert.alert('Import failed due to an invalid seed phrase. Please try again.'); + // TODO specify error states more granular + ownProps.onHideSplashScreen(); + Alert.alert('Import failed due to an invalid private key. Please try again.'); return null; } }, diff --git a/src/hoc/withFabSelection.js b/src/hoc/withFabSelection.js new file mode 100644 index 00000000000..50a63c326e9 --- /dev/null +++ b/src/hoc/withFabSelection.js @@ -0,0 +1,39 @@ +import { connect } from 'react-redux'; +import { compose, withProps } from 'recompact'; +import { createSelector } from 'reselect'; +import { extraStates } from '../components/fab/MovableFabWrapper'; +import { + setActionType, + setScrollingVelocity, + updateSelectedID, +} from '../redux/selectedWithFab'; + +const mapStateToProps = ({ + selectedWithFab: { + scrollingVelocity, + selectedId, + }, +}) => ({ + scrollingVelocity, + selectedId, +}); + +const fabSelectedIdSelector = state => state.selectedId; + +const withFabSelectionValidation = selectedId => ({ + isFabSelectionValid: selectedId !== extraStates.notSendable, +}); + +const withFabSelectionValidationSelector = createSelector( + [fabSelectedIdSelector], + withFabSelectionValidation, +); + +export default compose( + connect(mapStateToProps, { + setActionType, + setScrollingVelocity, + updateSelectedID, + }), + withProps(withFabSelectionValidationSelector), +); diff --git a/src/hoc/withFabSendAction.js b/src/hoc/withFabSendAction.js index c6c31070197..1ce4ca1b5e4 100644 --- a/src/hoc/withFabSendAction.js +++ b/src/hoc/withFabSendAction.js @@ -6,62 +6,76 @@ import { pure, withProps, } from 'recompact'; -import { setOpenFamilyTabs } from '../redux/openFamilyTabs'; -import { setOpenSmallBalances } from '../redux/openBalances'; +import { createSelector } from 'reselect'; +import withFabSelection from './withFabSelection'; +import withOpenFamilyTabs from './withOpenFamilyTabs'; +import { extraStates } from '../components/fab/MovableFabWrapper'; -const mapStateToProps = ({ - selectedWithFab: { - selectedId, - actionType, - }, -}) => ({ - actionType, - selectedId, +const mapStateToProps = ({ selectedWithFab: { actionType } }) => ({ actionType }); + +const familyNameSelector = state => state.familyName; +const selectedIdSelector = state => state.selectedId; +const uniqueIdSelector = state => state.uniqueId; + +const derivePropsFromSelectedId = (familyName, selectedId, uniqueId) => ({ + fabDropped: selectedId === extraStates.gestureInactive, + family: selectedId === familyName, + highlight: (selectedId === uniqueId) || (selectedId === familyName), }); +const withPropsDerivedFromSelectedId = createSelector( + [ + familyNameSelector, + selectedIdSelector, + uniqueIdSelector, + ], + derivePropsFromSelectedId, +); + let openFamilyCheck = 0; let currentFamilyId; let timer; let timerBlocker = false; export default compose( - connect(mapStateToProps, { setOpenFamilyTabs, setOpenSmallBalances }), - withProps(({ selectedId, uniqueId, familyName }) => ({ - fabDropped: selectedId === -3, - family: selectedId === familyName, - highlight: selectedId === uniqueId || selectedId === familyName, - isCoinDivider: selectedId === 'smallBalancesHeader', - })), + connect(mapStateToProps), + withFabSelection, + withOpenFamilyTabs, + withProps(withPropsDerivedFromSelectedId), omitProps('selectedId'), lifecycle({ componentDidUpdate(prevProps) { - if (this.props.family && !this.props.fabDropped) { - if (currentFamilyId !== this.props.family) { + const { + actionType, + fabDropped, + family, + familyId, + highlight, + onPressSend, + setOpenFamilyTabs, + } = this.props; + + if (family && !fabDropped) { + if (currentFamilyId !== family) { openFamilyCheck = 0; clearTimeout(timer); } + if (++openFamilyCheck === 1) { timer = setTimeout(() => { - if (this.props.family) { - this.props.setOpenFamilyTabs({ index: this.props.familyId, state: true }); + if (family) { + setOpenFamilyTabs({ index: familyId, state: true }); } }, 300); } } else { openFamilyCheck = 0; } - if (this.props.isCoinDivider === true && !this.props.fabDropped && !timerBlocker) { - timerBlocker = true; - timer = setTimeout(() => { - if (this.props.isCoinDivider) { - this.props.setOpenSmallBalances(true); - } - timerBlocker = false; - }, 300); - } - if (prevProps.highlight && !this.props.highlight && this.props.fabDropped) { - if (this.props.actionType === 'send') { - this.props.onPressSend(); + + const wasHighlighted = highlight || prevProps.highlight; + if (fabDropped && wasHighlighted) { + if (actionType === 'send' && onPressSend) { + onPressSend(); } } }, diff --git a/src/hoc/withIsWalletEthZero.js b/src/hoc/withIsWalletEthZero.js new file mode 100644 index 00000000000..2da2cd6a885 --- /dev/null +++ b/src/hoc/withIsWalletEthZero.js @@ -0,0 +1,6 @@ +import { connect } from 'react-redux'; +import { setIsWalletEthZero } from '../redux/isWalletEthZero'; + +const mapStateToProps = ({ isWalletEthZero }) => isWalletEthZero; + +export default Component => connect(mapStateToProps, { setIsWalletEthZero })(Component); diff --git a/src/hoc/withIsWalletImporting.js b/src/hoc/withIsWalletImporting.js new file mode 100644 index 00000000000..1f689a15af6 --- /dev/null +++ b/src/hoc/withIsWalletImporting.js @@ -0,0 +1,6 @@ +import { connect } from 'react-redux'; +import { setIsWalletImporting } from '../redux/isWalletImporting'; + +const mapStateToProps = ({ isWalletImporting }) => isWalletImporting; + +export default Component => connect(mapStateToProps, { setIsWalletImporting })(Component); diff --git a/src/hoc/withUniqueTokens.js b/src/hoc/withUniqueTokens.js index 7e8458ecb50..5e92e583ab1 100644 --- a/src/hoc/withUniqueTokens.js +++ b/src/hoc/withUniqueTokens.js @@ -1,4 +1,4 @@ -import { groupBy, sortBy } from 'lodash'; +import { groupBy } from 'lodash'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompact'; import { sendableUniqueTokensSelector } from './uniqueTokenSelectors'; @@ -16,7 +16,7 @@ const mapStateToProps = ({ const sendableUniqueTokens = (state) => { const sendableUniqueTokens = sendableUniqueTokensSelector(state).sendableUniqueTokens; const grouped = groupBy(sendableUniqueTokens, token => token.asset_contract.name); - const families = Object.keys(grouped); + const families = Object.keys(grouped).sort(); let sendableTokens = [] for (let i = 0; i < families.length; i++) { let newObject = {}; @@ -28,7 +28,6 @@ const sendableUniqueTokens = (state) => { }; sendableTokens.push(newObject); }; - sendableTokens = sortBy(sendableTokens, ['name']); return { sendableUniqueTokens: sendableTokens}; } diff --git a/src/languages/_english.json b/src/languages/_english.json index 31c07d0303d..c35147a1cef 100644 --- a/src/languages/_english.json +++ b/src/languages/_english.json @@ -241,7 +241,7 @@ }, "authenticate": { "please": "Please authenticate", - "please_seed_phrase": "Please authenticate to view seed phrase" + "please_seed_phrase": "Please authenticate to view private key" }, "push_notifications": { "please_enable_title": "Rainbow would like to send you push notifications", diff --git a/src/model/__tests__/wallet.test.js b/src/model/__tests__/wallet.test.js new file mode 100644 index 00000000000..1eebf8c55ae --- /dev/null +++ b/src/model/__tests__/wallet.test.js @@ -0,0 +1,38 @@ +import { loadAddress, walletInit, __RewireAPI__ as WalletRewireAPI } from '../wallet'; + +test('import good seed phrase', async () => { + const goodSeedPhrase = "there night cash clap pottery cereal silly silent hybrid hour visual hurry"; + const expectedAddress = "0x41f99409865FB23b833C1cD40C1c03BDd3E2C575"; + const { isImported, isNew, walletAddress } = await walletInit(goodSeedPhrase); + expect(isImported).toBeTruthy(); + expect(isNew).toBeFalsy(); + expect(walletAddress).toBe(expectedAddress); +}); + +test('import bad seed phrase should return null', async () => { + const badSeedPhrase = "merp merp merp"; + const { isImported, isNew, walletAddress } = await walletInit(badSeedPhrase); + expect(isImported).toBeFalsy(); + expect(isNew).toBeFalsy(); + expect(walletAddress).toBeNull(); +}); + +test('create a new wallet', async () => { + WalletRewireAPI.__Rewire__('loadAddress', () => null); + WalletRewireAPI.__Rewire__('createWallet', () => "hello"); + const { isImported, isNew, walletAddress } = await walletInit(); + expect(isImported).toBeFalsy(); + expect(isNew).toBeTruthy(); + expect(walletAddress).toBe("hello"); + WalletRewireAPI.__ResetDependency__('loadAddress'); + WalletRewireAPI.__ResetDependency__('createWallet'); +}); + +test('load existing wallet', async () => { + WalletRewireAPI.__Rewire__('loadAddress', () => "hello"); + const { isImported, isNew, walletAddress } = await walletInit(); + expect(isImported).toBeFalsy(); + expect(isNew).toBeFalsy(); + expect(walletAddress).toBe("hello"); + WalletRewireAPI.__ResetDependency__('loadAddress'); +}); diff --git a/src/model/wallet.js b/src/model/wallet.js index 240506a622d..dcab4280615 100644 --- a/src/model/wallet.js +++ b/src/model/wallet.js @@ -1,6 +1,6 @@ import { ethers } from 'ethers'; import lang from 'i18n-js'; -import { get } from 'lodash'; +import { get, isEmpty, isNil } from 'lodash'; import { Alert } from 'react-native'; import { ACCESS_CONTROL, @@ -9,7 +9,13 @@ import { canImplyAuthentication, } from 'react-native-keychain'; import * as keychain from './keychain'; -import { web3Provider } from '../handlers/web3'; +import { + addHexPrefix, + isHexString, + isHexStringIgnorePrefix, + isValidMnemonic, + web3Provider, +} from '../handlers/web3'; const seedPhraseKey = 'rainbowSeedPhrase'; const privateKeyKey = 'rainbowPrivateKey'; @@ -21,19 +27,19 @@ export function generateSeedPhrase() { export const walletInit = async (seedPhrase = null) => { let walletAddress = null; - let isWalletBrandNew = false; - if (seedPhrase) { + let isImported = false; + let isNew = false; + if (!isEmpty(seedPhrase)) { walletAddress = await createWallet(seedPhrase); - isWalletBrandNew = true; - } - if (!walletAddress) { - walletAddress = await loadAddress(); + isImported = !isNil(walletAddress); + return { isImported, isNew, walletAddress }; } + walletAddress = await loadAddress(); if (!walletAddress) { walletAddress = await createWallet(); - isWalletBrandNew = true; + isNew = true; } - return { isWalletBrandNew, walletAddress }; + return { isImported, isNew, walletAddress }; }; export const loadWallet = async () => { @@ -95,7 +101,7 @@ export const signPersonalMessage = async (message, authenticationPrompt = lang.t try { const wallet = await loadWallet(authenticationPrompt); try { - return await wallet.signMessage(ethers.utils.isHexString(message) ? ethers.utils.arrayify(message) : message); + return await wallet.signMessage(isHexString(message) ? ethers.utils.arrayify(message) : message); } catch (error) { return null; } @@ -118,11 +124,28 @@ export const loadAddress = async () => { } }; -const createWallet = async (seedPhrase) => { - const walletSeedPhrase = seedPhrase || generateSeedPhrase(); - const wallet = ethers.Wallet.fromMnemonic(walletSeedPhrase); - saveWalletDetails(walletSeedPhrase, wallet.privateKey, wallet.address); - return wallet.address; +const createWallet = async (seed) => { + const walletSeed = seed || generateSeedPhrase(); + let wallet = null; + try { + if (isHexStringIgnorePrefix(walletSeed) + && addHexPrefix(walletSeed).length === 66) { + wallet = new ethers.Wallet(walletSeed); + } else if (isValidMnemonic(walletSeed)) { + wallet = ethers.Wallet.fromMnemonic(walletSeed); + } else { + let hdnode = ethers.utils.HDNode.fromSeed(walletSeed); + let node = hdnode.derivePath("m/44'/60'/0'/0/0"); + wallet = new ethers.Wallet(node.privateKey); + } + if (wallet) { + saveWalletDetails(walletSeed, wallet.privateKey, wallet.address); + return wallet.address; + } + return null; + } catch (error) { + return null; + } }; const saveWalletDetails = async (seedPhrase, privateKey, address) => { diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index bb9a9c838d7..29ec6217f02 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -27,8 +27,7 @@ export const parseAccountAssets = data => { }); assets = assets.filter( - asset => (asset.address === 'eth' - || !!Number(get(asset, 'balance.amount'))), + asset => !!Number(get(asset, 'balance.amount')), ); return assets; diff --git a/src/redux/data.js b/src/redux/data.js index 4f6551e81f6..124bd9f0177 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -14,8 +14,6 @@ import { uniqBy, } from 'lodash'; import { DATA_API_KEY, DATA_ORIGIN } from 'react-native-dotenv'; -import io from 'socket.io-client'; -import { parseAccountAssets } from '../parsers/accounts'; import { getAssets, getLocalTransactions, @@ -24,11 +22,12 @@ import { saveAssets, saveLocalTransactions, } from '../handlers/commonStorage'; +import io from 'socket.io-client'; import { parseAccountAssets } from '../parsers/accounts'; import { parseNewTransaction } from '../parsers/newTransaction'; import { parseTransactions } from '../parsers/transactions'; -import { uniswapAddLiquidityTokens, uniswapUpdateLiquidityTokens } from './uniswap'; import { getFamilies } from '../parsers/uniqueTokens'; import { isLowerCaseMatch } from '../utils'; +import { uniswapAddLiquidityTokens, uniswapUpdateLiquidityTokens } from './uniswap'; // -- Constants --------------------------------------- // diff --git a/src/redux/isWalletEmpty.js b/src/redux/isWalletEmpty.js index b3b3c4df85f..aea6a231bf3 100644 --- a/src/redux/isWalletEmpty.js +++ b/src/redux/isWalletEmpty.js @@ -1,22 +1,55 @@ import produce from 'immer'; +import { isNull } from 'lodash'; +import { + getIsWalletEmpty, + removeIsWalletEmpty, + saveIsWalletEmpty, +} from '../handlers/commonStorage'; // -- Constants --------------------------------------- // const SET_IS_WALLET_EMPTY = 'isWalletEmpty/SET_IS_WALLET_EMPTY'; +const CLEAR_IS_WALLET_EMPTY = 'isWalletEmpty/CLEAR_IS_WALLET_EMPTY'; -export const setIsWalletEmpty = payload => dispatch => ( +export const loadIsWalletEmpty = () => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + const isWalletEmpty = getIsWalletEmpty(accountAddress, network); + if (!isNull(isWalletEmpty)) { + dispatch({ + payload: isWalletEmpty, + type: SET_IS_WALLET_EMPTY, + }); + } +}; + +export const setIsWalletEmpty = payload => (dispatch, getState) => { dispatch({ payload, type: SET_IS_WALLET_EMPTY, - }) -); + }); + const { accountAddress, network } = getState().settings; + saveIsWalletEmpty(accountAddress, payload, network); +}; + +export const clearIsWalletEmpty = () => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + removeIsWalletEmpty(accountAddress, network); + dispatch({ type: CLEAR_IS_WALLET_EMPTY }); +}; + // -- Reducer ----------------------------------------- // const INITIAL_STATE = { isWalletEmpty: true }; export default (state = INITIAL_STATE, action) => ( produce(state, draft => { - if (action.type === SET_IS_WALLET_EMPTY) { + switch (action.type) { + case SET_IS_WALLET_EMPTY: draft.isWalletEmpty = action.payload; + break; + case CLEAR_IS_WALLET_EMPTY: + return INITIAL_STATE; + default: + break; } }) ); diff --git a/src/redux/isWalletEthZero.js b/src/redux/isWalletEthZero.js new file mode 100644 index 00000000000..95716cdade3 --- /dev/null +++ b/src/redux/isWalletEthZero.js @@ -0,0 +1,22 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_IS_WALLET_ETH_ZERO = 'isWalletEthZero/SET_IS_WALLET_ETH_ZERO'; + +export const setIsWalletEthZero = payload => dispatch => ( + dispatch({ + payload, + type: SET_IS_WALLET_ETH_ZERO, + }) +); + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { isWalletEthZero: false }; + +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + if (action.type === SET_IS_WALLET_ETH_ZERO) { + draft.isWalletEthZero = action.payload; + } + }) +); diff --git a/src/redux/isWalletImporting.js b/src/redux/isWalletImporting.js new file mode 100644 index 00000000000..a7719114db1 --- /dev/null +++ b/src/redux/isWalletImporting.js @@ -0,0 +1,22 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_IS_WALLET_IMPORTING = 'isWalletImporting/SET_IS_WALLET_IMPORTING'; + +export const setIsWalletImporting = payload => dispatch => ( + dispatch({ + payload, + type: SET_IS_WALLET_IMPORTING, + }) +); + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { isImporting: false }; + +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + if (action.type === SET_IS_WALLET_IMPORTING) { + draft.isImporting = action.payload; + } + }) +); diff --git a/src/redux/openFamilyTabs.js b/src/redux/openFamilyTabs.js index 319147b08e8..05e7d2c3c88 100644 --- a/src/redux/openFamilyTabs.js +++ b/src/redux/openFamilyTabs.js @@ -2,12 +2,12 @@ import produce from 'immer'; import { saveOpenFamilies } from '../handlers/commonStorage'; // -- Constants --------------------------------------- // -const SET_OPEN_FAMILY_TABS = 'openFamilyTabs/SET_OPEN_FAMILY_TABS'; +const CLEAR_OPEN_FAMILY_TAB = 'openFamilyTabs/CLEAR_OPEN_FAMILY_TAB'; const PUSH_OPEN_FAMILY_TAB = 'openFamilyTabs/PUSH_OPEN_FAMILY_TAB'; +const SET_OPEN_FAMILY_TABS = 'openFamilyTabs/SET_OPEN_FAMILY_TABS'; -export const setOpenFamilyTabs = payload => dispatch => dispatch({ - payload, - type: SET_OPEN_FAMILY_TABS, +export const clearOpenFamilyTab = () => dispatch => dispatch({ + type: CLEAR_OPEN_FAMILY_TAB, }); export const pushOpenFamilyTab = payload => dispatch => dispatch({ @@ -15,6 +15,11 @@ export const pushOpenFamilyTab = payload => dispatch => dispatch({ type: PUSH_OPEN_FAMILY_TAB, }); +export const setOpenFamilyTabs = payload => dispatch => dispatch({ + payload, + type: SET_OPEN_FAMILY_TABS, +}); + // -- Reducer ----------------------------------------- // const INITIAL_STATE = { openFamilyTabs: {}, @@ -27,6 +32,8 @@ export default (state = INITIAL_STATE, action) => ( saveOpenFamilies(draft.openFamilyTabs); } else if (action.type === PUSH_OPEN_FAMILY_TAB) { draft.openFamilyTabs = action.payload; + } else if (action.type === CLEAR_OPEN_FAMILY_TAB) { + return INITIAL_STATE; } }) ); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 145306fe22b..c0ebec7e366 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -4,6 +4,8 @@ import actionSheetManager from './actionSheetManager'; import data from './data'; import imageDimensionsCache from './imageDimensionsCache'; import isWalletEmpty from './isWalletEmpty'; +import isWalletEthZero from './isWalletEthZero'; +import isWalletImporting from './isWalletImporting'; import navigation from './navigation'; import nonce from './nonce'; import openBalances from './openBalances'; @@ -13,8 +15,8 @@ import requests from './requests'; import selectedWithFab from './selectedWithFab'; import send from './send'; import settings from './settings'; -import uniswap from './uniswap'; import uniqueTokens from './uniqueTokens'; +import uniswap from './uniswap'; import walletconnect from './walletconnect'; export default combineReducers({ @@ -22,6 +24,8 @@ export default combineReducers({ data, imageDimensionsCache, isWalletEmpty, + isWalletEthZero, + isWalletImporting, navigation, nonce, openBalances, diff --git a/src/redux/requests.js b/src/redux/requests.js index 24246480f27..aa64ccae383 100644 --- a/src/redux/requests.js +++ b/src/redux/requests.js @@ -53,7 +53,12 @@ const getRequestDisplayDetails = (payload, assets, nativeCurrency) => { return getMessageDisplayDetails(message, timestampInMs); } if (payload.method === 'personal_sign') { - const message = convertHexToUtf8(get(payload, 'params[0]')); + let message = ''; + try { + message = convertHexToUtf8(get(payload, 'params[0]')); + } catch (error) { + message = get(payload, 'params[0]'); + } return getMessageDisplayDetails(message, timestampInMs, 'messagePersonal'); } if (payload.method === 'eth_signTypedData' diff --git a/src/redux/selectedWithFab.js b/src/redux/selectedWithFab.js index b7ee2fc5afb..dfd00cd3554 100644 --- a/src/redux/selectedWithFab.js +++ b/src/redux/selectedWithFab.js @@ -1,19 +1,24 @@ +import produce from 'immer'; + // -- Constants --------------------------------------- // +const UPDATE_ACTION_TYPE = 'selected/UPDATE_ACTION_TYPE'; const UPDATE_SELECTED_ID = 'selected/UPDATE_SELECTED_ID'; const UPDATE_VELOCITY = 'selected/UPDATE_VELOCITY'; -const UPDATE_ACTION_TYPE = 'selected/UPDATE_ACTION_TYPE'; -export const updateSelectedID = (selectedId) => (dispatch) => { - dispatch({ selectedId, type: UPDATE_SELECTED_ID }); -}; +export const setActionType = actionType => dispatch => dispatch({ + actionType, + type: UPDATE_ACTION_TYPE, +}); -export const setScrollingVelocity = (scrollingVelocity) => (dispatch) => { - dispatch({ scrollingVelocity, type: UPDATE_VELOCITY }); -}; +export const setScrollingVelocity = scrollingVelocity => dispatch => dispatch({ + scrollingVelocity, + type: UPDATE_VELOCITY, +}); -export const setActionType = (actionType) => (dispatch) => { - dispatch({ actionType, type: UPDATE_ACTION_TYPE }); -}; +export const updateSelectedID = selectedId => dispatch => dispatch({ + selectedId, + type: UPDATE_SELECTED_ID, +}); // -- Reducer ----------------------------------------- // const INITIAL_STATE = { @@ -22,24 +27,20 @@ const INITIAL_STATE = { selectedId: -1, }; -export default (state = INITIAL_STATE, action) => { - switch (action.type) { - case UPDATE_ACTION_TYPE: - return { - ...state, - actionType: action.actionType, - }; - case UPDATE_SELECTED_ID: - return { - ...state, - selectedId: action.selectedId, - }; - case UPDATE_VELOCITY: - return { - ...state, - scrollingVelocity: action.scrollingVelocity, - }; - default: - return state; - } -}; +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + switch (action.type) { + case UPDATE_ACTION_TYPE: + draft.actionType = action.actionType; + break; + case UPDATE_SELECTED_ID: + draft.selectedId = action.selectedId; + break; + case UPDATE_VELOCITY: + draft.scrollingVelocity = action.scrollingVelocity; + break; + default: + break; + } + }) +); diff --git a/src/redux/uniqueTokens.js b/src/redux/uniqueTokens.js index c4513d770f4..f50ec77b42b 100644 --- a/src/redux/uniqueTokens.js +++ b/src/redux/uniqueTokens.js @@ -43,41 +43,43 @@ export const uniqueTokensClearState = () => (dispatch, getState) => { dispatch({ type: UNIQUE_TOKENS_CLEAR_STATE }); }; -export const uniqueTokensRefreshState = () => (dispatch, getState) => new Promise((resolve, reject) => { - const fetchUniqueTokens = () => new Promise((resolve, reject) => { - dispatch({ type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_REQUEST }); - const { accountAddress, network } = getState().settings; - const { uniqueTokens: existingUniqueTokens } = getState().uniqueTokens; - apiGetAccountUniqueTokens(accountAddress) - .then(uniqueTokens => { - const existingFamilies = getFamilies(existingUniqueTokens); - const newFamilies = getFamilies(uniqueTokens); - const incomingFamilies = without(newFamilies, ...existingFamilies); - if (incomingFamilies.length) { - dispatch(dedupeAssetsWithFamilies(incomingFamilies)); - } - saveUniqueTokens(accountAddress, uniqueTokens, network); - dispatch({ - payload: uniqueTokens, - type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_SUCCESS, +export const uniqueTokensRefreshState = () => (dispatch, getState) => ( + new Promise((resolve, reject) => { + const fetchUniqueTokens = () => new Promise((fetchResolve, fetchReject) => { + dispatch({ type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_REQUEST }); + const { accountAddress, network } = getState().settings; + const { uniqueTokens: existingUniqueTokens } = getState().uniqueTokens; + apiGetAccountUniqueTokens(accountAddress) + .then(uniqueTokens => { + const existingFamilies = getFamilies(existingUniqueTokens); + const newFamilies = getFamilies(uniqueTokens); + const incomingFamilies = without(newFamilies, ...existingFamilies); + if (incomingFamilies.length) { + dispatch(dedupeAssetsWithFamilies(incomingFamilies)); + } + saveUniqueTokens(accountAddress, uniqueTokens, network); + dispatch({ + payload: uniqueTokens, + type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_SUCCESS, + }); + fetchResolve(true); + }).catch(error => { + dispatch({ type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_FAILURE }); + fetchReject(error); }); - resolve(true); - }).catch(error => { - dispatch({ type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_FAILURE }); - reject(error); - }); - }); - fetchUniqueTokens().then(() => { - clearInterval(getUniqueTokensInterval); - getUniqueTokensInterval = setInterval(fetchUniqueTokens, 15000); // 15 secs - resolve(true); - }).catch(error => { - clearInterval(getUniqueTokensInterval); - getUniqueTokensInterval = setInterval(fetchUniqueTokens, 15000); // 15 secs - reject(error); - }); -}); + }); + return fetchUniqueTokens().then(() => { + clearInterval(getUniqueTokensInterval); + getUniqueTokensInterval = setInterval(fetchUniqueTokens, 15000); // 15 secs + resolve(true); + }).catch(error => { + clearInterval(getUniqueTokensInterval); + getUniqueTokensInterval = setInterval(fetchUniqueTokens, 15000); // 15 secs + reject(error); + }); + }) +); // -- Reducer --------------------------------------------------------------- // export const INITIAL_UNIQUE_TOKENS_STATE = { diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index f4fd19fe5de..c4839c226dc 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -75,27 +75,33 @@ export const uniswapAddLiquidityTokens = (newLiquidityTokens) => (dispatch, getS dispatch(uniswapUpdateState()); }; -export const uniswapUpdateState = () => (dispatch, getState) => new Promise((resolve, reject) => { - const { accountAddress, network } = getState().settings; - const { liquidityTokens } = getState().uniswap; - if (isEmpty(liquidityTokens)) return; - const exchangeContracts = map(liquidityTokens, x => get(x, 'asset.asset_code')); +export const uniswapUpdateState = () => (dispatch, getState) => ( + new Promise((resolve, reject) => { + const { accountAddress, network } = getState().settings; + const { liquidityTokens } = getState().uniswap; + + if (isEmpty(liquidityTokens)) { + return resolve(false); + } - dispatch({ type: UNISWAP_UPDATE_REQUEST }); - getUniswapLiquidityInfo(accountAddress, exchangeContracts) - .then(uniswap => { - saveUniswap(accountAddress, uniswap, network); - dispatch({ - payload: uniswap, - type: UNISWAP_UPDATE_SUCCESS, + dispatch({ type: UNISWAP_UPDATE_REQUEST }); + + const exchangeContracts = map(liquidityTokens, x => get(x, 'asset.asset_code')); + return getUniswapLiquidityInfo(accountAddress, exchangeContracts) + .then(uniswap => { + saveUniswap(accountAddress, uniswap, network); + dispatch({ + payload: uniswap, + type: UNISWAP_UPDATE_SUCCESS, + }); + resolve(true); + }) + .catch(error => { + dispatch({ type: UNISWAP_UPDATE_FAILURE }); + reject(error); }); - resolve(true); - }) - .catch(error => { - dispatch({ type: UNISWAP_UPDATE_FAILURE }); - reject(error); - }); -}); + }) +); // -- Reducer --------------------------------------------------------------- // export const INITIAL_UNISWAP_STATE = { diff --git a/src/redux/walletconnect.js b/src/redux/walletconnect.js index d0c0d77e846..06e82e5092b 100644 --- a/src/redux/walletconnect.js +++ b/src/redux/walletconnect.js @@ -95,11 +95,11 @@ export const walletConnectOnSessionRequest = (uri, callback) => async (dispatch) }; const signingMethods = [ - "eth_sendTransaction", - "eth_signTransaction", - "personal_sign", - "eth_sign", - "eth_signTypedData", + "eth_sendTransaction", + "eth_signTransaction", + "personal_sign", + "eth_sign", + "eth_signTypedData", ]; const listenOnNewMessages = walletConnector => (dispatch, getState) => { @@ -259,7 +259,7 @@ export const walletConnectDisconnectAllByDappName = dappName => async (dispatch, try { const peerIds = values(mapValues(matchingWalletConnectors, walletConnector => walletConnector.peerId)); await removeWalletConnectSessions(peerIds); - forEach(walletConnectors, walletConnector => walletConnector.killSession()); + forEach(matchingWalletConnectors, walletConnector => walletConnector.killSession()); dispatch({ payload: omitBy(walletConnectors, (wc) => wc.peerMeta.name === dappName), type: WALLETCONNECT_REMOVE_SESSION, diff --git a/src/screens/ExampleScreen.js b/src/screens/ExampleScreen.js new file mode 100644 index 00000000000..e8e04c3c275 --- /dev/null +++ b/src/screens/ExampleScreen.js @@ -0,0 +1,29 @@ +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { Page } from '../components/layout'; +import { withHideSplashScreen } from '../hoc'; +import { position } from '../styles'; + +class ExampleScreen extends PureComponent { + static propTypes = { + onHideSplashScreen: PropTypes.func, + } + + componentDidMount = () => this.props.onHideSplashScreen() + + render = () => ( + + {/* + // haha you can put stuff here if you wanna test a component in isolation! + // ... i dont want to set up storybook right now + + */} + + ) +} + +export default withHideSplashScreen(ExampleScreen); diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index ba0035a3d77..cb9ef3edc20 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -29,12 +29,6 @@ const HandleIcon = styled(Icon).attrs({ margin-bottom: 2; `; -const HelpButton = styled(BorderlessButton)` - ${padding(6, 8)} - border: 1px solid #f6f7f7; - border-radius: 15px; -`; - const ImportButton = styled(Row).attrs({ align: 'center', component: BorderlessButton, @@ -74,7 +68,7 @@ const ImportSeedPhraseSheet = ({ enablesReturnKeyAutomatically={true} onChange={onInputChange} onSubmitEditing={onPressEnterKey} - placeholder="Type your seed phrase" + placeholder="Seed phrase or private key" returnKeyType="done" size="large" style={{ width: '100%' }} diff --git a/src/screens/ImportSeedPhraseSheetWithData.js b/src/screens/ImportSeedPhraseSheetWithData.js index 85dd35f5930..0018dee9a2d 100644 --- a/src/screens/ImportSeedPhraseSheetWithData.js +++ b/src/screens/ImportSeedPhraseSheetWithData.js @@ -11,22 +11,23 @@ import { withState, } from 'recompact'; import { Alert } from '../components/alerts'; -import { withDataInit, withIsWalletEmpty } from '../hoc'; +import { withDataInit, withIsWalletEmpty, withIsWalletImporting } from '../hoc'; import { deviceUtils } from '../utils'; import ImportSeedPhraseSheet from './ImportSeedPhraseSheet'; -import { isValidSeedPhrase as validateSeedPhrase } from '../helpers/validators'; +import { isValidSeed as validateSeed } from '../helpers/validators'; const ConfirmImportAlert = onSuccess => ( Alert({ buttons: [{ onPress: onSuccess, - text: 'Import', + style: 'destructive', + text: 'Delete and Import', }, { style: 'cancel', text: 'Cancel', }], // eslint-disable-next-line - message: 'Importing this seed phrase will overwrite your existing wallet. Before continuing, please make sure you’ve transferred its contents or backed up its seed phrase.', + message: 'Importing this private key will overwrite your existing wallet. Before continuing, please make sure you’ve transferred its contents or backed up its private key.', title: 'Are you sure you want to import?', }) ); @@ -34,42 +35,38 @@ const ConfirmImportAlert = onSuccess => ( const ImportSeedPhraseSheetWithData = compose( withDataInit, withIsWalletEmpty, + withIsWalletImporting, withNavigation, withState('clipboardContents', 'setClipboardContents', ''), - withState('isImporting', 'setIsImporting', false), withState('seedPhrase', 'setSeedPhrase', ''), withHandlers({ importSeedPhrase: ({ - clearAccountData, initializeWallet, isEmpty, navigation, seedPhrase, - setIsImporting, + setIsWalletImporting, }) => async () => { - await clearAccountData(); - - return initializeWallet(seedPhrase.trim()) - .then((address) => { - if (address) { - analytics.track('Imported seed phrase', { - hadPreviousAddressWithValue: isEmpty, - }); - setIsImporting(false); - navigation.navigate('WalletScreen'); - } else { - setIsImporting(false); - } - }) - .catch((error) => { - setIsImporting(false); - console.error('error importing seed phrase: ', error); - }); + try { + const address = await initializeWallet(seedPhrase.trim()); + if (address) { + analytics.track('Imported seed phrase', { + hadPreviousAddressWithValue: isEmpty, + }); + setIsWalletImporting(false); + navigation.navigate('WalletScreen'); + } else { + setIsWalletImporting(false); + } + } catch (error) { + setIsWalletImporting(false); + console.error('error importing seed phrase: ', error); + } }, }), withHandlers({ getClipboardContents: ({ setClipboardContents }) => async () => Clipboard.getString().then(setClipboardContents), - onImportSeedPhrase: ({ setIsImporting }) => () => ConfirmImportAlert(() => setIsImporting(true)), + onImportSeedPhrase: ({ setIsWalletImporting }) => () => ConfirmImportAlert(() => setIsWalletImporting(true)), onInputChange: ({ isImporting, setSeedPhrase }) => ({ nativeEvent }) => { if (!isImporting) { setSeedPhrase(nativeEvent.text); @@ -83,8 +80,8 @@ const ImportSeedPhraseSheetWithData = compose( onPressHelp: () => () => Linking.openURL('http://rainbow.me'), }), withProps(({ clipboardContents, seedPhrase }) => ({ - isClipboardContentsValidSeedPhrase: validateSeedPhrase(clipboardContents), - isSeedPhraseValid: validateSeedPhrase(seedPhrase), + isClipboardContentsValidSeedPhrase: validateSeed(clipboardContents), + isSeedPhraseValid: validateSeed(seedPhrase), })), onlyUpdateForKeys([ 'isClipboardContentsValidSeedPhrase', diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 3cf3e9977bf..17ad4ac388e 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -16,6 +16,7 @@ import ImportSeedPhraseSheetWithData from './ImportSeedPhraseSheetWithData'; import ProfileScreenWithData from './ProfileScreenWithData'; import QRScannerScreenWithData from './QRScannerScreenWithData'; import ReceiveModal from './ReceiveModal'; +import ExampleScreen from './ExampleScreen'; import WalletConnectConfirmationModal from './WalletConnectConfirmationModal'; import SendSheetWithData from './SendSheetWithData'; import SettingsModal from './SettingsModal'; @@ -58,6 +59,7 @@ const SwipeStack = createMaterialTopTabNavigator({ const MainNavigator = createStackNavigator({ ConfirmRequest: TransactionConfirmationScreenWithData, + ExampleScreen, ExpandedAssetScreen: { navigationOptions: { effect: 'expanded', diff --git a/src/screens/SettingsModal.js b/src/screens/SettingsModal.js index 9819f39ad0c..2a07eed9596 100644 --- a/src/screens/SettingsModal.js +++ b/src/screens/SettingsModal.js @@ -67,6 +67,7 @@ const SettingsModal = ({ style={{ top: ModalHeader.height }} > { const { transactionDetails } = this.props.navigation.state.params; - const message = get(transactionDetails, 'displayDetails.payload'); + let message = null; let flatFormatSignature = null; if (requestType === 'message') { + message = get(transactionDetails, 'payload.params[1]'); flatFormatSignature = await signMessage(message); } else if (requestType === 'messagePersonal') { + message = get(transactionDetails, 'payload.params[0]'); flatFormatSignature = await signPersonalMessage(message); } diff --git a/src/screens/WalletConnectConfirmationModal.js b/src/screens/WalletConnectConfirmationModal.js index f802dcc1a9a..fe86b85c5dd 100644 --- a/src/screens/WalletConnectConfirmationModal.js +++ b/src/screens/WalletConnectConfirmationModal.js @@ -1,27 +1,16 @@ +import { get } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { compose, withHandlers, withProps } from 'recompact'; import styled from 'styled-components/primitives'; +import { Button } from '../components/buttons'; import Divider from '../components/Divider'; +import { Nbsp } from '../components/html-entities'; import { Column } from '../components/layout'; -import { - Modal, -} from '../components/modal'; -import { - Bold, - Text, -} from '../components/text'; -import { Button } from '../components/buttons'; -import { padding } from '../styles'; +import { Modal } from '../components/modal'; +import { Bold, Text } from '../components/text'; import { withWalletConnectConfirmationModal } from '../hoc'; - -const Content = styled(Column).attrs({ - align: 'center', - flex: 1, - justify: 'start', -})` - ${padding(25)} -`; +import { padding } from '../styles'; const DescriptionText = styled(Text)` line-height: 21; @@ -30,25 +19,26 @@ const DescriptionText = styled(Text)` `; const WalletConnectConfirmationModal = ({ - onCloseModal, onApprove, + onCloseModal, onReject, peerMeta, }) => ( - + - {`${peerMeta.name}`} - {' wants to connect to your wallet.'} + {get(peerMeta, 'name', 'Unknown dapp')} + wants to connect to your wallet. - + - - + + ); @@ -63,13 +53,11 @@ WalletConnectConfirmationModal.propTypes = { export default compose( withWalletConnectConfirmationModal, - withProps(({ navigation }) => { - const { peerId, peerMeta } = navigation.state.params; - return { peerId, peerMeta }; - }), - withHandlers({ - onCloseModal: ({ navigation }) => () => navigation.goBack(), - }), + withProps(({ navigation }) => ({ + peerId: navigation.getParam('peerId'), + peerMeta: navigation.getParam('peerMeta'), + })), + withHandlers({ onCloseModal: ({ navigation }) => () => navigation.goBack() }), withHandlers({ onApprove: ({ onCloseModal, peerId, walletConnectApproveSession }) => () => { walletConnectApproveSession(peerId); diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index aaa6a3d4614..6bac62be229 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -26,14 +26,14 @@ import { withAccountSettings, withBlurTransitionProps, withDataInit, - withHideSplashScreen, withIsWalletEmpty, + withIsWalletEthZero, withUniqueTokens, withStatusBarStyle, withUniswapLiquidity, } from '../hoc'; -import { colors, position } from '../styles'; -import { deviceUtils, isNewValueForPath } from '../utils'; +import { position } from '../styles'; +import { isNewValueForPath } from '../utils'; class WalletScreen extends Component { static propTypes = { @@ -41,10 +41,11 @@ class WalletScreen extends Component { assets: PropTypes.array, assetsTotal: PropTypes.object, blurOpacity: PropTypes.object, + initializeWallet: PropTypes.func, isEmpty: PropTypes.bool.isRequired, isFocused: PropTypes.bool, + isWalletEthZero: PropTypes.bool.isRequired, navigation: PropTypes.object, - onHideSplashScreen: PropTypes.func, refreshAccountData: PropTypes.func, scrollViewTracker: PropTypes.object, sections: PropTypes.array, @@ -53,12 +54,21 @@ class WalletScreen extends Component { uniqueTokens: PropTypes.array, } + componentDidMount = async () => { + try { + await this.props.initializeWallet(); + } catch (error) { + // TODO + } + } + shouldComponentUpdate = (nextProps) => { const isNewBlurOpacity = isNewValueForPath(this.props, nextProps, 'blurOpacity'); const isNewCurrency = isNewValueForPath(this.props, nextProps, 'nativeCurrency'); const isNewFetchingAssets = isNewValueForPath(this.props, nextProps, 'fetchingAssets'); const isNewFetchingUniqueTokens = isNewValueForPath(this.props, nextProps, 'fetchingUniqueTokens'); - const isNewIsEmpty = isNewValueForPath(this.props, nextProps, 'isEmpty'); + const isNewIsWalletEmpty = isNewValueForPath(this.props, nextProps, 'isEmpty'); + const isNewIsWalletEthZero = isNewValueForPath(this.props, nextProps, 'isWalletEthZero'); const isNewLanguage = isNewValueForPath(this.props, nextProps, 'language'); const isNewSections = isNewValueForPath(this.props, nextProps, 'sections'); const isNewShowBlur = isNewValueForPath(this.props, nextProps, 'showBlur'); @@ -72,7 +82,8 @@ class WalletScreen extends Component { return isNewFetchingAssets || isNewFetchingUniqueTokens - || isNewIsEmpty + || isNewIsWalletEmpty + || isNewIsWalletEthZero || isNewLanguage || isNewCurrency || isNewBlurOpacity @@ -81,15 +92,11 @@ class WalletScreen extends Component { || isNewShowBlur; } - hideSplashScreen = () => { - const { onHideSplashScreen, setSafeTimeout } = this.props; - setSafeTimeout(onHideSplashScreen, 200); - } - render = () => { const { blurOpacity, isEmpty, + isWalletEthZero, navigation, refreshAccountData, scrollViewTracker, @@ -98,16 +105,14 @@ class WalletScreen extends Component { } = this.props; return ( - + {/* Line below appears to be needed for having scrollViewTracker persistent while reattaching of react subviews */} - +
@@ -116,16 +121,14 @@ class WalletScreen extends Component { {showBlur && ( - - + + )} @@ -139,12 +142,12 @@ export default compose( withAccountSettings, withDataInit, withUniswapLiquidity, - withHideSplashScreen, withSafeTimeout, withNavigation, withNavigationFocus, withBlurTransitionProps, withIsWalletEmpty, + withIsWalletEthZero, withStatusBarStyle('dark-content'), withProps(buildWalletSectionsSelector), withProps({ scrollViewTracker: new Animated.Value(0) }), diff --git a/src/styles/buildLayoutStyles.js b/src/styles/buildLayoutStyles.js index 44e20bac8da..334fe7e7eee 100644 --- a/src/styles/buildLayoutStyles.js +++ b/src/styles/buildLayoutStyles.js @@ -1,15 +1,23 @@ import { isNil } from 'lodash'; import { css } from 'styled-components'; -export default (values, type) => { +export default (values, type, shouldReturnCss) => { // Replicating the CSS API, if no second value parameter is given // apply the first parameter as both horizontal and vertical values. const defaultHorizontal = !isNil(values[1]) ? values[1] : values[0]; + const separator = type ? '-' : ''; - return css` - ${type}-bottom: ${!isNil(values[2]) ? values[2] : values[0]}; - ${type}-left: ${!isNil(values[3]) ? values[3] : defaultHorizontal}; - ${type}-right: ${defaultHorizontal}; - ${type}-top: ${values[0]}; - `; + const coordinates = { + bottom: !isNil(values[2]) ? values[2] : values[0], + left: !isNil(values[3]) ? values[3] : defaultHorizontal, + right: defaultHorizontal, + top: values[0], + }; + + return shouldReturnCss ? css` + ${type}${separator}bottom: ${coordinates.bottom}; + ${type}${separator}left: ${coordinates.left}; + ${type}${separator}right: ${coordinates.right}; + ${type}${separator}top: ${coordinates.top}; + ` : coordinates; }; diff --git a/src/styles/colors.js b/src/styles/colors.js index c5b1f35401e..1128d036851 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -4,48 +4,35 @@ import PropTypes from 'prop-types'; const base = { appleBlue: '#0E76FD', // 14, 118, 253 black: '#000000', // '0, 0, 0' - blue: '#657fe6', // '101, 127, 230' - blueActive: '#5a71cc', // '90, 113, 204' blueGreyDark: '#3C4252', // '60, 66, 82' blueGreyDarker: '#0F0F11', // '15, 15, 17' blueGreyLight: '#A1A5AC', - blueGreyLightest: '#8A8E97', // '138, 142, 151' blueGreyLighter: '#666A73', // '102, 106, 115' + blueGreyLightest: '#8A8E97', // '138, 142, 151' blueGreyMedium: '#636875', // '99, 104, 117' blueGreyMediumLight: '#7b7f8a', // '123, 127, 138' - blueHover: '#6c87f5', // '108, 135, 245' - bodyBackground: '#2c2f38', // '44, 47, 56' - brightBlue: '#5983FF', // '89, 131, 255' - brightGreen: '#12b878', // '18, 184, 120' - brightGreenHover: '#15c17f', // '21, 193, 127' dark: '#25292E', // '37, 41, 46' darkGrey: '#71778a', // '113, 119, 138' - darkText: '#2b2d33', // '43, 45, 51' - fadedBlue: '#6781e6', // '103, 129, 230' - gold: '#fabc2d', // '250, 188, 45' green: '#00994d', // '0, 153, 77' grey: '#a9adb9', // '169, 173, 185' headerTitle: '#aaafbd', // '170, 175, 189' - highlightBackground: '#f6f7f8', // '170, 175, 189' + highlightBackground: '#F0F7FF', // '240, 247, 255' lightBlue: '#c5f2ff', // '197, 242, 255' lightBlueGrey: '#F3F5F7', // '243, 245, 247' lightestGrey: '#E9EBEF', // '238, 233, 232' - lightGreen: '#54d192', // '84, 209, 146' lightGrey: '#f7f7f8', // '247, 247, 248' limeGreen: '#3FCC18', // '58, 166, 134' mediumGrey: '#a1a5b3', // '161, 165, 179' - orange: '#f6851b', // '246, 133, 27' - orangeLight: '#FFAF24', // '255, 175, 36' orangeMedium: '#FCA247', // '252, 162, 71' paleBlue: '#579DFF', placeholder: '#C4C6CB', // 196, 198, 203 primaryBlue: '#5d9df6', // '93, 157, 246' - primaryGreen: '#139E74', // '19, 158, 116' purple: '#32325d', // '50, 50, 93' + purpleLight: '#FFD9FE', // '255, 217, 254' red: '#d64b47', // '214, 75, 71' rowDivider: '#f9f9fa', // '249, 249, 250' - skeleton: '#f7f7f8', // '247, 247, 248' - teal: '#84f8da', // '132, 248, 218' + shimmer: '#edeef1', // '237, 238, 241' + skeleton: '#f6f7f8', // '246, 247, 248' transparent: 'transparent', white: '#ffffff', // '255, 255, 255' }; diff --git a/src/styles/margin.js b/src/styles/margin.js index 6be15468d5a..7ef5d089902 100644 --- a/src/styles/margin.js +++ b/src/styles/margin.js @@ -1,3 +1,3 @@ import buildLayoutStyles from './buildLayoutStyles'; -export default (...options) => buildLayoutStyles(options, 'margin'); +export default (...options) => buildLayoutStyles(options, 'margin', true); diff --git a/src/styles/padding.js b/src/styles/padding.js index b3277737fb1..1e45c007798 100644 --- a/src/styles/padding.js +++ b/src/styles/padding.js @@ -1,3 +1,3 @@ import buildLayoutStyles from './buildLayoutStyles'; -export default (...options) => buildLayoutStyles(options, 'padding'); +export default (...options) => buildLayoutStyles(options, 'padding', true); diff --git a/src/styles/position.js b/src/styles/position.js index fda1483e747..b71fd47afd4 100644 --- a/src/styles/position.js +++ b/src/styles/position.js @@ -1,6 +1,7 @@ import { upperFirst } from 'lodash'; import { StyleSheet } from 'react-native'; import { css } from 'styled-components'; +import buildLayoutStyles from './buildLayoutStyles'; const position = {}; @@ -31,8 +32,15 @@ position.cover = css` top: 0; `; +position.centeredAsObject = { + alignItems: 'center', + justifyContent: 'center', +}; + position.coverAsObject = StyleSheet.absoluteFillObject; +position.layout = (...args) => buildLayoutStyles(args); + const buildSizeKey = (prefix, key) => (prefix ? upperFirst(key) : key); position.size = (size, prefix = '') => css` diff --git a/yarn.lock b/yarn.lock index a14412f20c1..9bdfeb5ae60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,29 +9,29 @@ dependencies: "@babel/highlight" "7.0.0-beta.44" -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd" - integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ== +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" + integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/helpers" "^7.5.4" - "@babel/parser" "^7.5.0" + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.5.5" + "@babel/helpers" "^7.5.5" + "@babel/parser" "^7.5.5" "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" - lodash "^4.17.11" + lodash "^4.17.13" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" @@ -47,14 +47,14 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a" - integrity sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" + integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== dependencies: - "@babel/types" "^7.5.0" + "@babel/types" "^7.5.5" jsesc "^2.5.1" - lodash "^4.17.11" + lodash "^4.17.13" source-map "^0.5.0" trim-right "^1.0.1" @@ -90,26 +90,26 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/helper-create-class-features-plugin@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz#02edb97f512d44ba23b3227f1bf2ed43454edac5" - integrity sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA== +"@babel/helper-create-class-features-plugin@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" + integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== dependencies: "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-member-expression-to-functions" "^7.5.5" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-replace-supers" "^7.5.5" "@babel/helper-split-export-declaration" "^7.4.4" -"@babel/helper-define-map@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a" - integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg== +"@babel/helper-define-map@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" + integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== dependencies: "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.4.4" - lodash "^4.17.11" + "@babel/types" "^7.5.5" + lodash "^4.17.13" "@babel/helper-explode-assignable-expression@^7.1.0": version "7.1.0" @@ -158,12 +158,12 @@ dependencies: "@babel/types" "^7.4.4" -"@babel/helper-member-expression-to-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" - integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== +"@babel/helper-member-expression-to-functions@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" + integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.5.5" "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49": version "7.0.0" @@ -173,16 +173,16 @@ "@babel/types" "^7.0.0" "@babel/helper-module-transforms@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8" - integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" + integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" "@babel/template" "^7.4.4" - "@babel/types" "^7.4.4" - lodash "^4.17.11" + "@babel/types" "^7.5.5" + lodash "^4.17.13" "@babel/helper-optimise-call-expression@^7.0.0": version "7.0.0" @@ -197,11 +197,11 @@ integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== "@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" - integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" + integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== dependencies: - lodash "^4.17.11" + lodash "^4.17.13" "@babel/helper-remap-async-to-generator@^7.1.0": version "7.1.0" @@ -214,15 +214,15 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27" - integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg== +"@babel/helper-replace-supers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" + integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== dependencies: - "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-member-expression-to-functions" "^7.5.5" "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" "@babel/helper-simple-access@^7.1.0": version "7.1.0" @@ -256,14 +256,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.5.4": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.4.tgz#2f00608aa10d460bde0ccf665d6dcf8477357cf0" - integrity sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow== +"@babel/helpers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" + integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== dependencies: "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" @@ -283,10 +283,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" - integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" + integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -296,11 +296,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007" - integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" + integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.0" + "@babel/helper-create-class-features-plugin" "^7.5.5" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": @@ -320,9 +320,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331" - integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" + integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -437,24 +437,24 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d" - integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" + integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.11" + lodash "^4.17.13" "@babel/plugin-transform-classes@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6" - integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" + integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.4.4" + "@babel/helper-define-map" "^7.5.5" "@babel/helper-function-name" "^7.1.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-replace-supers" "^7.5.5" "@babel/helper-split-export-declaration" "^7.4.4" globals "^11.1.0" @@ -535,12 +535,12 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-object-super@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" - integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" + integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-replace-supers" "^7.5.5" "@babel/plugin-transform-parameters@^7.0.0": version "7.4.4" @@ -590,9 +590,9 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.0.tgz#45242c2c9281158c5f06d25beebac63e498a284e" - integrity sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" + integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -630,11 +630,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz#ea7da440d29b8ccdb1bd02e18f6cfdc7ce6c16f5" - integrity sha512-r4zJOMbKY5puETm8+cIpaa0RQZG/sSASW1u0pj8qYklcERgVIbxVbP2wyJA7zI1//h7lEagQmXi9IL9iI5rfsA== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" + integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.0" + "@babel/helper-create-class-features-plugin" "^7.5.5" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -648,21 +648,21 @@ regexpu-core "^4.5.4" "@babel/register@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.4.4.tgz#370a68ba36f08f015a8b35d4864176c6b65d7a23" - integrity sha512-sn51H88GRa00+ZoMqCVgOphmswG4b7mhf9VOB0LUBAieykq2GnRFerlN+JQkO/ntT7wz4jaHNSRPg9IdMPEUkA== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.5.5.tgz#40fe0d474c8c8587b28d6ae18a03eddad3dac3c1" + integrity sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ== dependencies: core-js "^3.0.0" find-cache-dir "^2.0.0" - lodash "^4.17.11" + lodash "^4.17.13" mkdirp "^0.5.1" pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b" - integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" + integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== dependencies: regenerator-runtime "^0.13.2" @@ -701,20 +701,20 @@ invariant "^2.2.0" lodash "^4.2.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.0.tgz#4216d6586854ef5c3c4592dab56ec7eb78485485" - integrity sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" + integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.5.5" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.0" - "@babel/types" "^7.5.0" + "@babel/parser" "^7.5.5" + "@babel/types" "^7.5.5" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.11" + lodash "^4.17.13" "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" @@ -725,13 +725,13 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" - integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" + integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== dependencies: esutils "^2.0.2" - lodash "^4.17.11" + lodash "^4.17.13" to-fast-properties "^2.0.0" "@cnakazawa/watch@^1.0.3": @@ -826,9 +826,9 @@ js-sha3 "0.5.7" "@ethersproject/properties@>5.0.0-beta.0": - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.127.tgz#ec2032675e909fa1d2e6adae09502271b2a702c6" - integrity sha512-zD14d+byTbdDRDPzHGkSW30bBtpFWaQpgzHh3ia6huJfr3qK8rVqGiDSYeNGJQdtdscss2l/F9yFuLd6ZdITPQ== + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.128.tgz#26e8a4cb95f0d048531f0a8da39773b16b4633b4" + integrity sha512-4ABgX2WmpQLlmbyR6EwxoT5YTRYxV6fGRtK+1nt48dvG2Y8FSkg33JvCfei3w432RjEEHEN5IOmTf+nTr9n6VA== dependencies: "@ethersproject/errors" ">5.0.0-beta.0" @@ -840,9 +840,9 @@ "@ethersproject/bytes" ">5.0.0-beta.0" "@ethersproject/strings@^5.0.0-beta.125": - version "5.0.0-beta.125" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.125.tgz#031066eeb8ffd166d25b0600e0a9c75682c1bbd0" - integrity sha512-UQ4w+38bFAbbikk/Wtq1YayhIPGFP80ICJDxy0wtNW7U4k4rs6+tIFVOx6PnmqOJG4cDuxItlFsn4+1rIJcJ6Q== + version "5.0.0-beta.127" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.127.tgz#e07848b92cb1b615a11d7289449312c069a234e9" + integrity sha512-FKQDBKgcX7Bc0J45TIwwT4PTnE1TvtDRka3dAkH1VX4odnj6DzpZ99QdkhX4mBL2J+6/XK+trA7m/HTDx+5YqA== dependencies: "@ethersproject/bytes" ">5.0.0-beta.0" "@ethersproject/constants" ">5.0.0-beta.0" @@ -859,9 +859,9 @@ integrity sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A== "@hapi/hoek@8.x.x": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.0.2.tgz#f63a5ff00e891a4e7aa98f11119f9515c6672032" - integrity sha512-O6o6mrV4P65vVccxymuruucb+GhP2zl9NLCG8OdoFRS8BEGw3vwpPp20wpAtpbQQxz1CEUtmxJGgWhjq1XA3qw== + version "8.1.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.1.0.tgz#8f7627b23ed9bf67088fc7f9669e48c63ad421bd" + integrity sha512-b1J4jxYnW+n6lC91V6Pqg9imP9BZq0HNCeM+3sbXg05rQsE9cGYrKFpZjyztVesGmNRE6R+QaEoWGATeIiUVjA== "@hapi/joi@^15.0.3": version "15.1.0" @@ -1078,31 +1078,32 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.0.0-rc.2": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.5.0.tgz#36071ebc07a1ef455eca1061d8b3d51f48ed73a6" - integrity sha512-Rh6FvaaUKIDbqcLfuo62GuT8aI38Qkya+3NyKRPhD265QeAGK00JGXl/tV2c2qCZT+QqMZ+/S4EFRoABZRHmyA== +"@react-native-community/cli-platform-android@^2.0.0-rc.2", "@react-native-community/cli-platform-android@^2.0.1", "@react-native-community/cli-platform-android@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" + integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== dependencies: - "@react-native-community/cli-tools" "^2.4.1" + "@react-native-community/cli-tools" "^2.7.0" chalk "^2.4.2" + execa "^1.0.0" jetifier "^1.6.2" logkitty "^0.5.0" slash "^2.0.0" xmldoc "^0.4.0" -"@react-native-community/cli-platform-ios@^2.0.0-rc.2": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" - integrity sha512-EKfnN+ubIcCHbCCo2a1SlYcd4jLZDT12HfoLHhFg8WXG3/zFWc/vMNpBi+omrvT7Hoktr8cTtROXPg9cIS7FCQ== +"@react-native-community/cli-platform-ios@^2.0.0-rc.2", "@react-native-community/cli-platform-ios@^2.0.1", "@react-native-community/cli-platform-ios@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" + integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== dependencies: - "@react-native-community/cli-tools" "^2.4.1" + "@react-native-community/cli-tools" "^2.7.0" chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.4.1.tgz#5a23b92d0b486753add00a27d77d0ea9e8c331e1" - integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== +"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" + integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1149,45 +1150,44 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^1.2.1": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.10.0.tgz#66e3c9f407763281f7060c034145650bf0d6786c" - integrity sha512-48tIWsMKhwbDsKhe5tYcsspsAy7aR3J/yRjdsVh+M2qkKEASe66Xbhiw5RK2nhfzd1IdOdlIxNMiC+9uad6NMQ== +"@react-native-community/cli@^2.0.1": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.0.tgz#346ff73ace6b2265d99ec217a8624b8735d19930" + integrity sha512-sN43IyvBtFtC1iOjx3pfKeo7DK4wkJxWiggR3QkkNQdyjuGT3RGXiYZVPu+zda6BPKdeGYpS+7UJrkGT+1tuFg== dependencies: - chalk "^1.1.1" + "@hapi/joi" "^15.0.3" + "@react-native-community/cli-platform-android" "^2.7.0" + "@react-native-community/cli-platform-ios" "^2.8.0" + "@react-native-community/cli-tools" "^2.7.0" + chalk "^2.4.2" commander "^2.19.0" compression "^1.7.1" connect "^3.6.5" - denodeify "^1.2.1" - envinfo "^5.7.0" + cosmiconfig "^5.1.0" + deepmerge "^3.2.0" + envinfo "^7.1.0" errorhandler "^1.5.0" - escape-string-regexp "^1.0.5" execa "^1.0.0" fs-extra "^7.0.1" glob "^7.1.1" graceful-fs "^4.1.3" inquirer "^3.0.6" lodash "^4.17.5" - metro "^0.51.0" - metro-config "^0.51.0" - metro-core "^0.51.0" - metro-memory-fs "^0.51.0" - metro-react-native-babel-transformer "^0.51.0" - mime "^1.3.4" + metro "^0.54.1" + metro-config "^0.54.1" + metro-core "^0.54.1" + metro-react-native-babel-transformer "^0.54.1" minimist "^1.2.0" mkdirp "^0.5.1" morgan "^1.9.0" - node-fetch "^2.2.0" node-notifier "^5.2.1" - opn "^3.0.2" + open "^6.2.0" + ora "^3.4.0" plist "^3.0.0" semver "^5.0.3" serve-static "^1.13.1" shell-quote "1.6.1" - slash "^2.0.0" ws "^1.1.0" - xcode "^2.0.0" - xmldoc "^0.4.0" "@react-native-community/eslint-config@^0.0.5": version "0.0.5" @@ -1206,6 +1206,11 @@ eslint-plugin-react-native "3.6.0" prettier "1.16.4" +"@react-native-community/masked-view@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.1.tgz#dbcfc5ec08efbb02d4142dd9426c8d7a396829d7" + integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== + "@react-native-community/netinfo@^3.2.1": version "3.2.1" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-3.2.1.tgz#cd073b81a4b978f7f55f1a960a0b56c462813e02" @@ -1303,13 +1308,13 @@ "@svgr/babel-plugin-transform-svg-component" "^4.2.0" "@svgr/cli@^4.3.0": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.1.tgz#ee4da73b866c81d3fca4ea642df1279924d0cf77" - integrity sha512-et42q/arMztdgzwqVm3IEu1b/sDDOvqYgu3DHZ8wOBkn34XwPbIYfhHfWSYxyqAOBa3zarOPmJJsfv7+gIugAw== + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.2.tgz#fb20fd33429f0d0dfc6c7178e8bfc1e86006e9de" + integrity sha512-QdYzVgsowOWpOwkX+3+EK6zxlttADc2v6t0Baj2xETAdhBcpFAf/nZ0xw6b5zxdbGk8fm3nxJyPUddYuBkgzpg== dependencies: - "@svgr/core" "^4.3.1" - "@svgr/plugin-jsx" "^4.3.1" - "@svgr/plugin-prettier" "^4.3.1" + "@svgr/core" "^4.3.2" + "@svgr/plugin-jsx" "^4.3.2" + "@svgr/plugin-prettier" "^4.3.2" "@svgr/plugin-svgo" "^4.3.1" camelcase "^5.3.1" chalk "^2.4.2" @@ -1319,38 +1324,36 @@ output-file-sync "^2.0.1" recursive-readdir "^2.2.2" -"@svgr/core@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.1.tgz#58c44d0ccc3fe41718c50433758b549dabd4d197" - integrity sha512-TXFcvzp6QjxKP5Oy7qoQY08w/nAix9TMOc4jSi3wjIJBBMUqypVwQJFMxtHrViGMQGmFdaN1y2diQrhvA+xNNQ== +"@svgr/core@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.2.tgz#939c89be670ad79b762f4c063f213f0e02535f2e" + integrity sha512-N+tP5CLFd1hP9RpO83QJPZY3NL8AtrdqNbuhRgBkjE/49RnMrrRsFm1wY8pueUfAGvzn6tSXUq29o6ah8RuR5w== dependencies: - "@svgr/plugin-jsx" "^4.3.1" + "@svgr/plugin-jsx" "^4.3.2" camelcase "^5.3.1" cosmiconfig "^5.2.1" -"@svgr/hast-util-to-babel-ast@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.1.tgz#b3ea5b2228b50ff335a5d3cf3855f4b1f9fbc70e" - integrity sha512-MZbRccEpsro70mE6mhiv5QUXjBwHGDQZ7XrVcrDs44inaNvYUtIcheX0d9eColcnNgJmsfU3tEFfoGRnJ9E5pA== +"@svgr/hast-util-to-babel-ast@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz#1d5a082f7b929ef8f1f578950238f630e14532b8" + integrity sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg== dependencies: "@babel/types" "^7.4.4" -"@svgr/plugin-jsx@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.1.tgz#5b7f849213d1411886e1cec9b6c287faec69143e" - integrity sha512-v9sgsn/VpDM9G1U0ZDCair7ZmYqNrVC5LiSyIQli03DAm34bYLM12xVOOrl3dg8NGNY1k4C3A6YgBL3VKjA6Og== +"@svgr/plugin-jsx@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.2.tgz#ce9ddafc8cdd74da884c9f7af014afcf37f93d3c" + integrity sha512-+1GW32RvmNmCsOkMoclA/TppNjHPLMnNZG3/Ecscxawp051XJ2MkO09Hn11VcotdC2EPrDfT8pELGRo+kbZ1Eg== dependencies: "@babel/core" "^7.4.5" "@svgr/babel-preset" "^4.3.1" - "@svgr/hast-util-to-babel-ast" "^4.3.1" - rehype-parse "^6.0.0" - unified "^7.1.0" - vfile "^4.0.1" + "@svgr/hast-util-to-babel-ast" "^4.3.2" + svg-parser "^2.0.0" -"@svgr/plugin-prettier@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-4.3.1.tgz#b50347ec95a0163091ecbbc305991e727076c7d8" - integrity sha512-RTTZniRGtUQw+BufJk1sLKbeglZlHXCoJeE/op+hhrVLI3UZSbtliaQbyV6Rm5tZOed+08miuSWTLa6x3Tf10w== +"@svgr/plugin-prettier@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-4.3.2.tgz#41a95cf0c52a58e2d9841434d227e120d7d533f7" + integrity sha512-GErOZQ0n/OinFDjyXg9svfVRNWP+18qqIxsc/9xRoRY7R/cPlnXkadLF7NdgDgSP2BYtt7XGcZ9TU+Skr1B3tw== dependencies: merge-deep "^3.0.2" prettier "^1.17.1" @@ -1444,25 +1447,30 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/json-schema@^7.0.3": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" + integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" - integrity sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ== + version "12.6.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" + integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== "@types/node@^10.3.2": - version "10.14.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f" - integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg== + version "10.14.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" + integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ== "@types/node@^8.0.7": - version "8.10.50" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.50.tgz#f3d68482b1f54b5f4fba8daaac385db12bb6a706" - integrity sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA== + version "8.10.51" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627" + integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== "@types/q@^1.5.1": version "1.5.2" @@ -1474,7 +1482,7 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": +"@types/unist@*", "@types/unist@^2.0.0": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== @@ -1502,73 +1510,74 @@ integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== "@typescript-eslint/eslint-plugin@^1.5.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.12.0.tgz#96b4e08b5f998a198b8414508b1a289f9e8c549a" - integrity sha512-J/ZTZF+pLNqjXBGNfq5fahsoJ4vJOkYbitWPavA05IrZ7BXUaf4XWlhUB/ic1lpOGTRpLWF+PLAePjiHp6dz8g== + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz#22fed9b16ddfeb402fd7bcde56307820f6ebc49f" + integrity sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g== dependencies: - "@typescript-eslint/experimental-utils" "1.12.0" + "@typescript-eslint/experimental-utils" "1.13.0" eslint-utils "^1.3.1" functional-red-black-tree "^1.0.1" regexpp "^2.0.1" tsutils "^3.7.0" -"@typescript-eslint/experimental-utils@1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.12.0.tgz#98417ee2e0c6fe8d1e50d934a6535d9c0f4277b6" - integrity sha512-s0soOTMJloytr9GbPteMLNiO2HvJ+qgQkRNplABXiVw6vq7uQRvidkby64Gqt/nA7pys74HksHwRULaB/QRVyw== +"@typescript-eslint/experimental-utils@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e" + integrity sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg== dependencies: - "@typescript-eslint/typescript-estree" "1.12.0" + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "1.13.0" eslint-scope "^4.0.0" "@typescript-eslint/parser@^1.5.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-1.12.0.tgz#9965895ec4745578185965d63f21510f93a3f35a" - integrity sha512-0uzbaa9ZLCA5yMWJywnJJ7YVENKGWVUhJDV5UrMoldC5HoI54W5kkdPhTfmtFKpPFp93MIwmJj0/61ztvmz5Dw== + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-1.13.0.tgz#61ac7811ea52791c47dc9fd4dd4a184fae9ac355" + integrity sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "1.12.0" - "@typescript-eslint/typescript-estree" "1.12.0" + "@typescript-eslint/experimental-utils" "1.13.0" + "@typescript-eslint/typescript-estree" "1.13.0" eslint-visitor-keys "^1.0.0" -"@typescript-eslint/typescript-estree@1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.12.0.tgz#d8dd0a7cffb5e3c0c3e98714042d83e316dfc9a9" - integrity sha512-nwN6yy//XcVhFs0ZyU+teJHB8tbCm7AIA8mu6E2r5hu6MajwYBY3Uwop7+rPZWUN/IUOHpL8C+iUPMDVYUU3og== +"@typescript-eslint/typescript-estree@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz#8140f17d0f60c03619798f1d628b8434913dc32e" + integrity sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw== dependencies: lodash.unescape "4.0.1" semver "5.5.0" -"@walletconnect/core@^1.0.0-beta.26": - version "1.0.0-beta.26" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.26.tgz#74796fe0372028110ff892320308dbc29d0f655e" - integrity sha512-2xeztI0Lpz6QluIGLDkfmJIPm+g3KbD3w+KzGJ2E1cWqQb1Tsvj+6zpNLn2WTQGn5xLub1b3BLgXwGxLcMsA9w== +"@walletconnect/core@^1.0.0-beta.31": + version "1.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.31.tgz#ce9257c13a0da7a52a61829b66c45a9686cedca9" + integrity sha512-EggZFGdQ0EMjWZrtqAn6PJslLDlc5suyPBWfp4PP0247tYorcXXz/7OSiek0XWBVQ7dakCqeJAOteuc/FaQ+hw== dependencies: - "@walletconnect/types" "^1.0.0-beta.26" - "@walletconnect/utils" "^1.0.0-beta.26" + "@walletconnect/types" "^1.0.0-beta.31" + "@walletconnect/utils" "^1.0.0-beta.31" -"@walletconnect/react-native@^1.0.0-beta.26": - version "1.0.0-beta.26" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.26.tgz#5a5ff2fa7059e2220cf6b62b29d9097664f531e7" - integrity sha512-fgYJFTEjcF6I28xLKtkuxDItpR2rDcKReYs1HjjPNxUtk/rx2aWbVn/mxjkqEzTTKOMb1b5SrXQdIleLq84P6Q== +"@walletconnect/react-native@^1.0.0-beta.29": + version "1.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.31.tgz#097af6bf635bf4917e4fc6cc0cbd39609aed64f6" + integrity sha512-zscEiCUshvMfV9/yU+UL5gKZ/0WD+UH+Ar0XBdWA/BVu306maCoqNUWTV3Txj7gl+1L/hwIchbrT8np9dgK1tQ== dependencies: - "@walletconnect/core" "^1.0.0-beta.26" - "@walletconnect/types" "^1.0.0-beta.26" - "@walletconnect/utils" "^1.0.0-beta.26" + "@walletconnect/core" "^1.0.0-beta.31" + "@walletconnect/types" "^1.0.0-beta.31" + "@walletconnect/utils" "^1.0.0-beta.31" -"@walletconnect/types@^1.0.0-beta.26": - version "1.0.0-beta.26" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.26.tgz#a21def3fb302b55f8e93532a9c33e5a2f4b93588" - integrity sha512-uUNDKo3gr18AtGTFi8+VrcZiV2eHlaq2+uMGkAoMeUZe2MK28MH3GkH0Dh2yDTVCh1bopMri61eMvwqKaW6/VQ== +"@walletconnect/types@^1.0.0-beta.31": + version "1.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.31.tgz#a35049a719042bda819759e4cd77591c5315a6a6" + integrity sha512-C6W4K+YWoAl69xDvbbhjBtQ02Xx2eBsfLyezSvs8eFw4toKkkJ5Uw5dp9C6qmUBDrKIIcmP2004F1MniLnnk3Q== -"@walletconnect/utils@^1.0.0-beta.26": - version "1.0.0-beta.26" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.26.tgz#0dc9dc7a79fb17696266278fba00801a08ca81b3" - integrity sha512-CW2rkccGtKZNjr+vtTCXyB986g8OWX9ove957a36CdVrSzTQvMNpprzeatpBEzNlwX1KxNyJL/zBqnc1Maf1aw== +"@walletconnect/utils@^1.0.0-beta.31": + version "1.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.31.tgz#a73ea81325750208b5298680bf3f82208f0d4f37" + integrity sha512-cTZu+EzoEdvbkT36o+4VqBsD7ro5pXrOu9sswgcWkZ2xVFfRSnNctJkUdeK3JOu1wPnG25/QaRr3fQx4ZoIBrQ== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.26" + "@walletconnect/types" "^1.0.0-beta.31" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1591,6 +1600,18 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abs-svg-path@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" + integrity sha1-32Acjo0roQ1KdtYl4japo5wnI78= + absolute-path@^0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" @@ -1642,9 +1663,9 @@ acorn@^5.5.3: integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.1, acorn@^6.0.7: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" - integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== + version "6.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" + integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== aes-js@3.0.0: version "3.0.0" @@ -1656,17 +1677,24 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@^4.3.0: +agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" -ajv@^6.5.5, ajv@^6.9.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" - integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== +agent-base@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -1772,11 +1800,6 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0: resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= -ansi@^0.3.0, ansi@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" - integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1818,13 +1841,6 @@ arr-diff@^1.0.1: arr-flatten "^1.0.1" array-slice "^0.2.3" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1895,11 +1911,6 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1975,11 +1986,11 @@ async-limiter@~1.0.0: integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== async@^2.4.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== dependencies: - lodash "^4.17.11" + lodash "^4.17.14" asynckit@^0.4.0: version "0.4.0" @@ -2097,10 +2108,11 @@ babel-plugin-dynamic-import-node@^2.3.0: object.assign "^4.1.0" babel-plugin-istanbul@^5.1.0: - version "5.1.4" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz#841d16b9a58eeb407a0ddce622ba02fe87a752ba" - integrity sha512-dySz4VJMH+dpndj0wjJ8JPs/7i1TdSPb1nRrn56/92pKOF9VKC1FMFJmMXjzlGGusnCAqujP6PBCiKq0sVA+YQ== + version "5.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" + integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== dependencies: + "@babel/helper-plugin-utils" "^7.0.0" find-up "^3.0.0" istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" @@ -2123,7 +2135,12 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.2: +babel-plugin-rewire@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" + integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ== + +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -2157,7 +2174,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-fbjs@^3.0.1, babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: +babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.2.0.tgz#c0e6347d3e0379ed84b3c2434d3467567aa05297" integrity sha512-5Jo+JeWiVz2wHUUyAlvb/sSYnXNig9r+HqGAOSfh5Fzxp7SnAaR/tEGRJ1ZX7C77kfk82658w6R5Z+uPATTD9g== @@ -2357,15 +2374,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -2471,12 +2479,12 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.6.3: - version "4.6.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" - integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== + version "4.6.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" + integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== dependencies: - caniuse-lite "^1.0.30000981" - electron-to-chromium "^1.3.188" + caniuse-lite "^1.0.30000984" + electron-to-chromium "^1.3.191" node-releases "^1.1.25" bser@^2.0.0: @@ -2619,17 +2627,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: - version "1.0.30000983" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" - integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== - -capture-exit@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" - integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= - dependencies: - rsvp "^3.3.3" +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: + version "1.0.30000987" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" + integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== capture-exit@^2.0.0: version "2.0.0" @@ -2648,7 +2649,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -ccount@^1.0.0, ccount@^1.0.3: +ccount@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== @@ -2858,16 +2859,16 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -code-push@2.0.6, code-push@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/code-push/-/code-push-2.0.6.tgz#fb4e140c90fdb7fa047f3be6f53caacc8915d0b8" - integrity sha512-3ln6rqE9KkYUhSzgjKVOAd2pUijBFY3QG951fgIiG3uNGg8V57XuYmftPq3EGS0YTxX2SPEUOQvHPhw7Wxmggw== +code-push@^2.0.6, code-push@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/code-push/-/code-push-2.0.7.tgz#aa2303376552a15ea3c2092ff2f19e4d6666ab9e" + integrity sha512-8cEO60OYPiDj4vaSBxRAySzShYrKLi8GXdxcbJhTJ25PAvMUkf9rC/IQxgRK01EqWcGwKvIAGvz+Xk9YJcMM+A== dependencies: q "^1.4.1" - recursive-fs "0.1.4" - slash "1.0.0" - superagent "^3.8.0" - superagent-proxy "^1.0.3" + recursive-fs "^1.1.2" + slash "3.0.0" + superagent "^5.1.0" + superagent-proxy "^2.0.0" yazl "^2.4.1" collapse-white-space@^1.0.2: @@ -2883,7 +2884,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -2895,32 +2896,11 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -color@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - colorette@^1.0.7: version "1.1.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.1.0.tgz#1f943e5a357fac10b4e0f5aaef3b14cdc1af6ec7" @@ -2938,17 +2918,12 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comma-separated-tokens@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz#419cd7fb3258b1ed838dc0953167a25e152f5b59" - integrity sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ== - command-exists@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== -commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: +commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -2973,7 +2948,7 @@ component-emitter@1.2.1: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= -component-emitter@^1.2.0, component-emitter@^1.2.1: +component-emitter@^1.2.1, component-emitter@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== @@ -3074,7 +3049,7 @@ convert-source-map@^1.1.0, convert-source-map@^1.4.0: dependencies: safe-buffer "~5.1.1" -cookiejar@^2.1.0: +cookiejar@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== @@ -3223,14 +3198,6 @@ css-to-react-native@^2.2.2: css-color-keywords "^1.0.0" postcss-value-parser "^3.3.0" -css-tree@1.0.0-alpha.28: - version "1.0.0-alpha.28" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.28.tgz#8e8968190d886c9477bc8d61e96f61af3f7ffa7f" - integrity sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w== - dependencies: - mdn-data "~1.1.0" - source-map "^0.5.3" - css-tree@1.0.0-alpha.29: version "1.0.0-alpha.29" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" @@ -3239,10 +3206,13 @@ css-tree@1.0.0-alpha.29: mdn-data "~1.1.0" source-map "^0.5.3" -css-url-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" - integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= +css-tree@1.0.0-alpha.33: + version "1.0.0-alpha.33" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.33.tgz#970e20e5a91f7a378ddd0fc58d0b6c8d4f3be93e" + integrity sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w== + dependencies: + mdn-data "2.0.4" + source-map "^0.5.3" css-what@^2.1.2: version "2.1.3" @@ -3256,17 +3226,17 @@ csso@^3.5.1: dependencies: css-tree "1.0.0-alpha.29" -"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== cssstyle@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.3.0.tgz#c36c466f7037fd30f03baa271b65f0f17b50585c" - integrity sha512-wXsoRfsRfsLVNaVzoKdqvEmK/5PFaEXNspVT22Ots6K/cnJdpoDKuQFw+qlMiXnmaif1OgeC466X1zISgAOcGg== + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== dependencies: - cssom "~0.3.6" + cssom "0.3.x" currently-unhandled@^0.4.1: version "0.4.1" @@ -3308,7 +3278,7 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -date-fns@^1.29.0: +date-fns@^1.30.1: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== @@ -3441,6 +3411,11 @@ degenerator@^1.0.4: escodegen "1.x.x" esprima "3.x.x" +delay@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-4.3.0.tgz#efeebfb8f545579cb396b3a722443ec96d14c50e" + integrity sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -3650,10 +3625,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.188: - version "1.3.190" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz#5bf599519983bfffd9d4387817039a3ed7ca085f" - integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== +electron-to-chromium@^1.3.191: + version "1.3.205" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" + integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== elliptic@6.3.3: version "6.3.3" @@ -3740,11 +3715,6 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -envinfo@^5.7.0: - version "5.12.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" - integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== - envinfo@^7.1.0: version "7.3.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" @@ -3845,9 +3815,9 @@ eslint-import-resolver-node@^0.3.1, eslint-import-resolver-node@^0.3.2: resolve "^1.5.0" eslint-module-utils@^2.2.0, eslint-module-utils@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" - integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw== + version "2.4.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c" + integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw== dependencies: debug "^2.6.8" pkg-dir "^2.0.0" @@ -3884,9 +3854,9 @@ eslint-plugin-import@2.14.0: resolve "^1.6.0" eslint-plugin-import@^2.14.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz#7a5ba8d32622fb35eb9c8db195c2090bd18a3678" - integrity sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig== + version "2.18.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" + integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== dependencies: array-includes "^3.0.3" contains-path "^0.1.0" @@ -3895,8 +3865,8 @@ eslint-plugin-import@^2.14.0: eslint-import-resolver-node "^0.3.2" eslint-module-utils "^2.4.0" has "^1.0.3" - lodash "^4.17.11" minimatch "^3.0.4" + object.values "^1.1.0" read-pkg-up "^2.0.0" resolve "^1.11.0" @@ -3956,9 +3926,9 @@ eslint-plugin-react@7.12.4: resolve "^1.9.0" eslint-plugin-react@^7.13.0: - version "7.14.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz#94c193cc77a899ac0ecbb2766fbef88685b7ecc1" - integrity sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA== + version "7.14.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" + integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" @@ -3987,9 +3957,11 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: estraverse "^4.1.1" eslint-utils@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c" + integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ== + dependencies: + eslint-visitor-keys "^1.0.0" eslint-visitor-keys@^1.0.0: version "1.0.0" @@ -4091,7 +4063,7 @@ eth-contract-metadata@^1.9.2: resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.2.tgz#6c23383e35de1014c1c00f2c8c787cd48d54ae20" integrity sha512-2ycmqRQ9u4Tbpir7hwEKZ8Qjy1bc3KaiRBd/jkL8Xye9wqnYMpgaUK4UHPm1uTnCZZ+KoN0Mxg6kL9JILrYdhA== -ethers@^4.0.31: +ethers@^4.0.33: version "4.0.33" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== @@ -4107,10 +4079,10 @@ ethers@^4.0.31: uuid "2.0.1" xmlhttprequest "1.8.0" -event-target-shim@^1.0.5: - version "1.1.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-1.1.1.tgz#a86e5ee6bdaa16054475da797ccddf0c55698491" - integrity sha1-qG5e5r2qFgVEddp5fM3fDFVphJE= +event-target-shim@^5.0.0, event-target-shim@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== eventemitter3@^3.0.0: version "3.1.2" @@ -4137,13 +4109,6 @@ exception-formatter@^1.0.4: dependencies: colors "^1.0.3" -exec-sh@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" - integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== - dependencies: - merge "^1.2.0" - exec-sh@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" @@ -4192,13 +4157,6 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= - dependencies: - is-posix-bracket "^0.1.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -4212,13 +4170,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - expect@^24.8.0: version "24.8.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d" @@ -4258,7 +4209,7 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^1.0.1: +external-editor@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b" integrity sha1-Etew24UPf/fnCBuvQAVwAGDEYAs= @@ -4285,13 +4236,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -4358,6 +4302,11 @@ fast-levenshtein@~2.0.4: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-safe-stringify@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" + integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg== + fb-watchman@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" @@ -4370,7 +4319,7 @@ fbjs-css-vars@^1.0.0: resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== -fbjs-scripts@^1.0.0: +fbjs-scripts@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.2.0.tgz#069a0c0634242d10031c6460ef1fccefcdae8b27" integrity sha512-5krZ8T0Bf8uky0abPoCLrfa7Orxd8UH4Qq8hRUF2RZYNMu+FmEOrBc7Ib3YVONmxTXTlLAvyrrdrVmksDb2OqQ== @@ -4440,22 +4389,6 @@ file-uri-to-path@1: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -4560,7 +4493,7 @@ for-in@^1.0.1, for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^0.1.3, for-own@^0.1.4: +for-own@^0.1.3: version "0.1.5" resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= @@ -4577,7 +4510,7 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@^2.3.1: +form-data@^2.3.3: version "2.5.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== @@ -4595,7 +4528,7 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -formidable@^1.2.0: +formidable@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659" integrity sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg== @@ -4660,7 +4593,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.3, fsevents@^1.2.7: +fsevents@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== @@ -4698,17 +4631,6 @@ fwd-stream@^1.0.4: dependencies: readable-stream "~1.0.26-4" -gauge@~1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" - integrity sha1-6c7FSD09TuDvRLYKfZnkk14TbZM= - dependencies: - ansi "^0.3.0" - has-unicode "^2.0.0" - lodash.pad "^4.1.0" - lodash.padend "^4.1.0" - lodash.padstart "^4.1.0" - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -4781,21 +4703,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -5069,37 +4976,16 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hast-util-from-parse5@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.1.tgz#7da8841d707dcf7be73715f7f3b14e021c4e469a" - integrity sha512-UfPzdl6fbxGAxqGYNThRUhRlDYY7sXu6XU9nQeX4fFZtV+IHbyEJtd+DUuwOqNV4z3K05E/1rIkoVr/JHmeWWA== - dependencies: - ccount "^1.0.3" - hastscript "^5.0.0" - property-information "^5.0.0" - web-namespaces "^1.1.2" - xtend "^4.0.1" - -hast-util-parse-selector@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz#66aabccb252c47d94975f50a281446955160380b" - integrity sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw== - -hastscript@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.0.tgz#a19b3cca6a26a2bcd0f1b1eac574af9427c1c7df" - integrity sha512-7mOQX5VfVs/gmrOGlN8/EDfp1GqV6P3gTNVt+KnX4gbYhpASTM8bklFdFQCbFRAadURXAmw0R1QQdBdqp7jswQ== - dependencies: - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.2.0" - property-information "^5.0.1" - space-separated-tokens "^1.0.0" - he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hermesvm@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.0.tgz#4bfaf4ac682a2fd407b862ab641eb8deb232de83" + integrity sha512-GbP6dKaVW/V2QpB+DZPxcmhBhJVFa9cHS/xRX7FD1MGfa6Z1aHHD83VDCwo3SgcqNj5yHlVbe9UgrK1PFGCXpw== + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -5197,9 +5083,9 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: - version "17.0.6" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.6.tgz#01079cc2bcef408139ea8ce24d18ac0d512fbe85" - integrity sha512-bdNhzhcM6RG5m82RypVguCrAQNie/ycxW0Q5C6K9UDWD5hqApZfdJFbj4Ikz9jxIR+Ja1eg0yCQLhlCT+opwIg== + version "17.0.7" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.7.tgz#aae8591634b109c0ecec755b46c6414b0d743e07" + integrity sha512-fQn+gcyDaHb3qXIeahjCnGMsCeHaKveSORclang55stBjOL13oK7ZYxXVz1AaFV6p3SzOSu/KW+tgZcUuDdf6Q== dependencies: "@babel/runtime" "^7.3.1" @@ -5237,10 +5123,10 @@ image-size@^0.6.0: resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2" integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== -immer@^1.7.4: - version "1.12.1" - resolved "https://registry.yarnpkg.com/immer/-/immer-1.12.1.tgz#40c6e5b292c00560836c2993bda3a24379d466f5" - integrity sha512-3fmKM6ovaqDt0CdC9daXpNi5x/YCYS3i4cwLdTVkhJdk5jrDXoPs7lCm3IqM3yhfSnz4tjjxbRG2CziQ7m8ztg== +immer@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/immer/-/immer-3.1.3.tgz#59bc742b2aab6e2c676445edb653e588a23c70fc" + integrity sha512-HG5SXTXTTVy9lGNwS075cNhQoV375jHsIJO3UtMjuUWJOuwlMr0u42FlsKTJcppt5AzsFAsmj9r4kHvsSHh3hQ== import-fresh@^2.0.0: version "2.0.0" @@ -5324,42 +5210,42 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -inquirer@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.1.2.tgz#ac3ba5f06b8e7291abd9f22912c03f09cfe2dd1f" - integrity sha1-rDul8GuOcpGr2fIpEsA/Cc/i3R8= +inquirer@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" + integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= dependencies: ansi-escapes "^1.1.0" chalk "^1.0.0" - cli-cursor "^1.0.1" + cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^1.0.1" - figures "^1.3.5" + external-editor "^2.0.1" + figures "^2.0.0" lodash "^4.3.0" - mute-stream "0.0.6" - pinkie-promise "^2.0.0" + mute-stream "0.0.7" run-async "^2.2.0" rx "^4.1.0" - string-width "^1.0.1" + string-width "^2.0.0" strip-ansi "^3.0.0" through "^2.3.6" -inquirer@3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" - integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= +inquirer@^1.1.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918" + integrity sha1-TexvMvN+97sLLtPx0aXD9UUHSRg= dependencies: ansi-escapes "^1.1.0" chalk "^1.0.0" - cli-cursor "^2.1.0" + cli-cursor "^1.0.1" cli-width "^2.0.0" - external-editor "^2.0.1" - figures "^2.0.0" + external-editor "^1.1.0" + figures "^1.3.5" lodash "^4.3.0" - mute-stream "0.0.7" + mute-stream "0.0.6" + pinkie-promise "^2.0.0" run-async "^2.2.0" rx "^4.1.0" - string-width "^2.0.0" + string-width "^1.0.1" strip-ansi "^3.0.0" through "^2.3.6" @@ -5424,7 +5310,7 @@ ip-regex@^1.0.3: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0= -ip@^1.1.4, ip@^1.1.5: +ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -5466,11 +5352,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - is-buffer@^1.0.2, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -5547,18 +5428,6 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -5571,11 +5440,6 @@ is-extendable@^1.0.0, is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -5603,13 +5467,6 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -5642,13 +5499,6 @@ is-npm@^1.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -5656,11 +5506,6 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -5695,16 +5540,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= - is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -5749,10 +5584,10 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-what@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.2.3.tgz#50f76f1bd8e56967e15765d1d34302513701997b" - integrity sha512-c4syLgFnjXTH5qd82Fp/qtUIeM0wA69xbI0KH1QpurMIvDaZFrS8UtAa4U52Dc2qSznaMxHit0gErMp6A/Qk1w== +is-what@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.2.4.tgz#da528659017bdd4b07892dfe4fd60da6ac500e98" + integrity sha512-0awkPsfVd85bYStP99EqLxKvhc5SiE70hSZCPxJN2SYZ5d+IkX+r1Ri0qnPWPnuRVFrqrEnI3JgFN3yrGtjXaw== is-whitespace-character@^1.0.0: version "1.0.3" @@ -5986,19 +5821,6 @@ jest-get-type@^24.8.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc" integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ== -jest-haste-map@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" - integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.11" - invariant "^2.2.4" - jest-serializer "^24.0.0-alpha.6" - jest-worker "^24.0.0-alpha.6" - micromatch "^2.3.11" - sane "^3.0.0" - jest-haste-map@^24.7.1, jest-haste-map@^24.8.0: version "24.8.1" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.1.tgz#f39cc1d2b1d907e014165b4bd5a957afcb992982" @@ -6162,12 +5984,7 @@ jest-runtime@^24.8.0: strip-bom "^3.0.0" yargs "^12.0.2" -jest-serializer@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" - integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== - -jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0: +jest-serializer@^24.4.0: version "24.4.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== @@ -6233,14 +6050,7 @@ jest-watcher@^24.8.0: jest-util "^24.8.0" string-length "^2.0.0" -jest-worker@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" - integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== - dependencies: - merge-stream "^1.0.1" - -jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0: +jest-worker@^24.6.0: version "24.6.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== @@ -6257,9 +6067,9 @@ jest@^24.8.0: jest-cli "^24.8.0" jetifier@^1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.2.tgz#c1d8b7cc2af1d3a255963dbdaed3d56157e94712" - integrity sha512-KQKWmj7CNGcOztXwkWoZHoGHJqHBM2hI7YXRHv0tdSz5Gw063CU6z6o8sXaD1+ctTfYQOk+I87NPvPnX/3B3Kw== + version "1.6.3" + resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.3.tgz#61a95b29aefddfe3b6d81ee956f5e99f8b9cba19" + integrity sha512-i0rb2nHVPZDPzFhgs9+yYxEDMh2z0iSHRD3vBQmvn98wlgWKwhmU2F3MUEEXfK+MLnKwLKqsCTvlcS1+CpDTUg== js-sha3@0.5.7: version "0.5.7" @@ -6289,6 +6099,11 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsc-android@245459.0.0: + version "245459.0.0" + resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" + integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== + jsdom@^11.5.1: version "11.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" @@ -6640,21 +6455,6 @@ lodash.debounce@4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.pad@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" - integrity sha1-QzCUmoM6fI2iLMIPaibE1Z3runA= - -lodash.padend@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= - -lodash.padstart@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" - integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= - lodash.snakecase@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" @@ -6680,15 +6480,10 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: - version "4.17.13" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" - integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA== - -lodash@^4.17.12: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" @@ -6811,11 +6606,6 @@ markdown-table@^1.1.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== -math-random@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" - integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== - mathml-tag-names@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" @@ -6837,6 +6627,11 @@ mdast-util-compact@^1.0.0: dependencies: unist-util-visit "^1.1.0" +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + mdn-data@~1.1.0: version "1.1.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" @@ -6879,11 +6674,11 @@ meow@^5.0.0: yargs-parser "^10.0.0" merge-anything@^2.2.4, merge-anything@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.2.5.tgz#37ef13f36359ee64f09c657d2cef45f7e29493f9" - integrity sha512-WgZGR7EQ1D8pyh57uKBbkPhUCJZLGdMzbDaxL4MDTJSGsvtpGdm8myr6DDtgJwT46xiFBlHqxbveDRpFBWlKWQ== + version "2.4.0" + resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.0.tgz#86959caf02bb8969d1ae5e1b652862bc5fe54e44" + integrity sha512-MhJcPOEcDUIbwU0LnEfx5S9s9dfQ/KPu4g2UA5T5G1LRKS0XmpDvJ9+UUfTkfhge+nA1gStE4tJAvx6lXLs+rg== dependencies: - is-what "^3.2.3" + is-what "^3.2.4" merge-deep@^3.0.2: version "3.0.2" @@ -6906,34 +6701,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - -methods@^1.1.1: +methods@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -metro-babel-register@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.51.0.tgz#d86d3f2d90b45c7a3c6ae67a53bd1e50bad7a24d" - integrity sha512-rhdvHFOZ7/ub019A3+aYs8YeLydb02/FAMsKr2Nz2Jlf6VUxWrMnrcT0NYX16F9TGdi2ulRlJ9dwvUmdhkk+Bw== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - metro-babel-register@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.54.1.tgz#7d2bfe444b1ccef8de99aedc7d9330891d806076" @@ -6952,20 +6724,6 @@ metro-babel-register@0.54.1: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-transformer@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.51.0.tgz#9ee5199163ac46b2057527b3f8cbd8b089ffc03e" - integrity sha512-M7KEY/hjD3E8tJEliWgI0VOSaJtqaznC0ItM6FiMrhoGDqqa1BvGofl+EPcKqjBSOV1UgExua/T1VOIWbjwQsw== - dependencies: - "@babel/core" "^7.0.0" - -metro-babel-transformer@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.51.1.tgz#97be9e2b96c78aa202b52ae05fb86f71327aef72" - integrity sha512-+tOnZZzOzufB86ASdfimUEGB1jBKsdsVpPdjNJZkueTFyvYlGqWDQKHM1w9bwKMeM/czPQ48Y6m8Bou6le0X4w== - dependencies: - "@babel/core" "^7.0.0" - metro-babel-transformer@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" @@ -6973,20 +6731,6 @@ metro-babel-transformer@0.54.1: dependencies: "@babel/core" "^7.0.0" -metro-babel7-plugin-react-transform@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.0.tgz#af27dd81666b91f05d2b371b0d6d283c585e38b6" - integrity sha512-dZ95kXcE2FJMoRsYhxr7YLCbOlHWKwe0bOpihRhfImDTgFfuKIzU4ROQwMUbE0NCbzB+ATFsa2FZ3pHDJ5GI0w== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - -metro-babel7-plugin-react-transform@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.1.tgz#9cce2c340cc4006fc82aa6dfab27af22d592607e" - integrity sha512-wzn4X9KgmAMZ7Bi6v9KxA7dw+AHGL0RODPxU5NDJ3A6d0yERvzfZ3qkzWhz8jbFkVBK12cu5DTho3HBazKQDOw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - metro-babel7-plugin-react-transform@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" @@ -6994,16 +6738,6 @@ metro-babel7-plugin-react-transform@0.54.1: dependencies: "@babel/helper-module-imports" "^7.0.0" -metro-cache@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.51.1.tgz#d0b296eab8e009214413bba87e4eac3d9b44cd04" - integrity sha512-0m1+aicsw77LVAehNuTxDpE1c/7Xv/ajRD+UL/lFCWUxnrjSbxVtIKr8l5DxEY11082c1axVRuaV9e436W+eXg== - dependencies: - jest-serializer "24.0.0-alpha.6" - metro-core "0.51.1" - mkdirp "^0.5.1" - rimraf "^2.5.4" - metro-cache@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1" @@ -7014,17 +6748,6 @@ metro-cache@0.54.1: mkdirp "^0.5.1" rimraf "^2.5.4" -metro-config@0.51.1, metro-config@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.51.1.tgz#8f1a241ce2c0b521cd492c39bc5c6c69e3397b82" - integrity sha512-WCNd0tTI9gb/ubgTqK1+ljZL4b3hsXVinsOAtep4nHiVb6DSDdbO2yXDD2rpYx3NE6hDRMFS9HHg6G0139pAqQ== - dependencies: - cosmiconfig "^5.0.5" - metro "0.51.1" - metro-cache "0.51.1" - metro-core "0.51.1" - pretty-format "24.0.0-alpha.6" - metro-config@0.54.1, metro-config@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd" @@ -7037,16 +6760,6 @@ metro-config@0.54.1, metro-config@^0.54.1: metro-core "0.54.1" pretty-format "^24.7.0" -metro-core@0.51.1, metro-core@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.51.1.tgz#e7227fb1dd1bb3f953272fad9876e6201140b038" - integrity sha512-sG1yACjdFqmIzZN50HqLTKUMp1oy0AehHhmIuYeIllo1DjX6Y2o3UAT3rGP8U+SAqJGXf/OWzl6VNyRPGDENfA== - dependencies: - jest-haste-map "24.0.0-alpha.6" - lodash.throttle "^4.1.1" - metro-resolver "0.51.1" - wordwrap "^1.0.0" - metro-core@0.54.1, metro-core@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b" @@ -7068,18 +6781,6 @@ metro-inspector-proxy@0.54.1: ws "^1.1.5" yargs "^9.0.0" -metro-memory-fs@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.51.1.tgz#624291f5956b0fd11532d80b1b85d550926f96c9" - integrity sha512-dXVUpLPLwfQcYHd1HlqHGVzBsiwvUdT92TDSbdc10152TP+iynHBqLDWbxt0MAtd6c/QXwOuGZZ1IcX3+lv5iw== - -metro-minify-uglify@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.51.1.tgz#60cd8fe4d3e82d6670c717b8ddb52ae63199c0e4" - integrity sha512-HAqd/rFrQ6mnbqVAszDXIKTg2rqHlY9Fm8DReakgbkAeyMbF2mH3kEgtesPmTrhajdFk81UZcNSm6wxj1JMgVg== - dependencies: - uglify-es "^3.1.9" - metro-minify-uglify@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3" @@ -7087,51 +6788,10 @@ metro-minify-uglify@0.54.1: dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.0.tgz#978d960acf2d214bbbe43e59145878d663bd07de" - integrity sha512-Y/aPeLl4RzY8IEAneOyDcpdjto/8yjIuX9eUWRngjSqdHYhGQtqiSBpfTpo0BvXpwNRLwCLHyXo58gNpckTJFw== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.51.0" - react-transform-hmr "^1.0.4" - -metro-react-native-babel-preset@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.1.tgz#44aeeedfea37f7c2ab8f6f273fa71b90fe65f089" - integrity sha512-e9tsYDFhU70gar0jQWcZXRPJVCv4k7tEs6Pm74wXO2OO/T1MEumbvniDIGwGG8bG8RUnYdHhjcaiub2Vc5BRWw== +metro-react-native-babel-preset@0.54.1: + version "0.54.1" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" + integrity sha512-Hfr32+u5yYl3qhYQJU8NQ26g4kQlc3yFMg7keVR/3H8rwBIbFqXgsKt8oe0dOrv7WvrMqBHhDtVdU9ls3sSq8g== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" @@ -7141,6 +6801,7 @@ metro-react-native-babel-preset@0.51.1: "@babel/plugin-proposal-optional-chaining" "^7.0.0" "@babel/plugin-syntax-dynamic-import" "^7.0.0" "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.2.0" "@babel/plugin-transform-arrow-functions" "^7.0.0" "@babel/plugin-transform-block-scoping" "^7.0.0" "@babel/plugin-transform-classes" "^7.0.0" @@ -7166,13 +6827,13 @@ metro-react-native-babel-preset@0.51.1: "@babel/plugin-transform-typescript" "^7.0.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.51.1" + metro-babel7-plugin-react-transform "0.54.1" react-transform-hmr "^1.0.4" -metro-react-native-babel-preset@0.54.1, metro-react-native-babel-preset@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" - integrity sha512-Hfr32+u5yYl3qhYQJU8NQ26g4kQlc3yFMg7keVR/3H8rwBIbFqXgsKt8oe0dOrv7WvrMqBHhDtVdU9ls3sSq8g== +metro-react-native-babel-preset@^0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.55.0.tgz#d5d4a6cbe9ccbcedd72fcbb71c0c311e3d56876e" + integrity sha512-HUI+dEiVym8f1NYIF1grY9PdoY0d3SSS/HED2dDDvTORwndsAEWuXiUgKFOGWX18+RUAQog8obVQuBMgrr8ZBQ== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" @@ -7208,30 +6869,9 @@ metro-react-native-babel-preset@0.54.1, metro-react-native-babel-preset@^0.54.1: "@babel/plugin-transform-typescript" "^7.0.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.54.1" - react-transform-hmr "^1.0.4" - -metro-react-native-babel-transformer@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz#57a695e97a19d95de63c9633f9d0dc024ee8e99a" - integrity sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.0" - metro-react-native-babel-preset "0.51.0" + react-refresh "^0.2.0" -metro-react-native-babel-transformer@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.1.tgz#bac34f988c150c725cd1875c13701cc2032615f9" - integrity sha512-D0KU+JPb/Z76nUWt3+bkjKggOlGvqAVI2BpIH2JFKprpUyBjWaCRqHnkBfZGixYwUfmu93MIlKJWr6iKzzFrlg== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.1" - metro-react-native-babel-preset "0.51.1" - -metro-react-native-babel-transformer@^0.54.1: +metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== @@ -7241,13 +6881,6 @@ metro-react-native-babel-transformer@^0.54.1: metro-babel-transformer "0.54.1" metro-react-native-babel-preset "0.54.1" -metro-resolver@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.51.1.tgz#4c26f0baee47d30250187adca3d34c902e627611" - integrity sha512-zmWbD/287NDA/jLPuPV0hne/YMMSG0dljzu21TYMg2lXRLur/zROJHHhyepZvuBHgInXBi4Vhr2wvuSnY39SuA== - dependencies: - absolute-path "^0.0.0" - metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -7255,13 +6888,6 @@ metro-resolver@0.54.1: dependencies: absolute-path "^0.0.0" -metro-source-map@0.51.1: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.51.1.tgz#1a8da138e98e184304d5558b4f92a5c2141822d0" - integrity sha512-JyrE+RV4YumrboHPHTGsUUGERjQ681ImRLrSYDGcmNv4tfpk9nvAK26UAas4IvBYFCC9oW90m0udt3kaQGv59Q== - dependencies: - source-map "^0.5.6" - metro-source-map@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5" @@ -7271,62 +6897,28 @@ metro-source-map@0.54.1: "@babel/types" "^7.0.0" source-map "^0.5.6" -metro@0.51.1, metro@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.51.1.tgz#b0aad4731593b9f244261bad1abb2a006d1c8969" - integrity sha512-nM0dqn8LQlMjhChl2fzTUq2EWiUebZM7nkesD9vQe47W10bj/tbRLPiIIAxht6SRDbPd/hRA+t39PxLhPSKEKg== +metro-source-map@0.55.0, metro-source-map@^0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540" + integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw== dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.0.1" - buffer-crc32 "^0.2.13" - chalk "^2.4.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" invariant "^2.2.4" - jest-haste-map "24.0.0-alpha.6" - jest-worker "24.0.0-alpha.6" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-babel-transformer "0.51.1" - metro-cache "0.51.1" - metro-config "0.51.1" - metro-core "0.51.1" - metro-minify-uglify "0.51.1" - metro-react-native-babel-preset "0.51.1" - metro-resolver "0.51.1" - metro-source-map "0.51.1" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - react-transform-hmr "^1.0.4" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" + metro-symbolicate "0.55.0" + ob1 "0.55.0" source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.5" - xpipe "^1.0.5" - yargs "^9.0.0" + vlq "^1.0.0" + +metro-symbolicate@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1" + integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg== + dependencies: + metro-source-map "0.55.0" + source-map "^0.5.6" + through2 "^2.0.1" + vlq "^1.0.0" metro@0.54.1, metro@^0.54.1: version "0.54.1" @@ -7387,25 +6979,6 @@ metro@0.54.1, metro@^0.54.1: xpipe "^1.0.5" yargs "^9.0.0" -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7465,12 +7038,12 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime@1.6.0, mime@^1.3.4, mime@^1.4.1: +mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.1: +mime@^2.4.1, mime@^2.4.4: version "2.4.4" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== @@ -7576,9 +7149,9 @@ mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: minimist "0.0.8" mocha@^6.1.4: - version "6.1.4" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.1.4.tgz#e35fada242d5434a7e163d555c705f6875951640" - integrity sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg== + version "6.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.0.tgz#f896b642843445d1bb8bca60eabd9206b8916e56" + integrity sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ== dependencies: ansi-colors "3.2.3" browser-stdout "1.3.1" @@ -7794,9 +7367,9 @@ node-pre-gyp@^0.12.0: tar "^4" node-releases@^1.1.25: - version "1.1.25" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3" - integrity sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ== + version "1.1.26" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937" + integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ== dependencies: semver "^5.3.0" @@ -7828,7 +7401,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -7845,6 +7418,13 @@ normalize-selector@^0.2.0: resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM= +normalize-svg-path@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/normalize-svg-path/-/normalize-svg-path-1.0.1.tgz#6f729ad6b70bb4ca4eff2fe4b107489efe1d56fe" + integrity sha1-b3Ka1rcLtMpO/y/ksQdInv4dVv4= + dependencies: + svg-arc-to-cubic-bezier "^3.0.0" + npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" @@ -7865,15 +7445,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" - integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= - dependencies: - ansi "~0.3.1" - are-we-there-yet "~1.1.2" - gauge "~1.2.5" - npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -7916,6 +7487,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +ob1@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd" + integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw== + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -7994,14 +7570,6 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - object.omit@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-3.0.0.tgz#0e3edc2fce2ba54df5577ff529f6d97bd8a522af" @@ -8094,13 +7662,6 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" -opn@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a" - integrity sha1-ttmec5n3jWXDuq/+8fsojpuFJDo= - dependencies: - object-assign "^4.0.1" - optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -8253,10 +7814,10 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pac-proxy-agent@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz#90d9f6730ab0f4d2607dcdcd4d3d641aa26c3896" - integrity sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA== +pac-proxy-agent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-3.0.0.tgz#11d578b72a164ad74bf9d5bac9ff462a38282432" + integrity sha512-AOUX9jES/EkQX2zRz0AW7lSx9jD//hQS8wFXBvcnd/J2Py9KaMJMqV/LPqJssj1tgGufotb2mmopGPR15ODv1Q== dependencies: agent-base "^4.2.0" debug "^3.1.0" @@ -8265,7 +7826,7 @@ pac-proxy-agent@^2.0.1: https-proxy-agent "^2.2.1" pac-resolver "^3.0.0" raw-body "^2.2.0" - socks-proxy-agent "^3.0.0" + socks-proxy-agent "^4.0.1" pac-resolver@^3.0.0: version "3.0.0" @@ -8324,16 +7885,6 @@ parse-entities@^1.0.2, parse-entities@^1.1.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -8354,16 +7905,16 @@ parse-node-version@^1.0.0: resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== +parse-svg-path@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-svg-path/-/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb" + integrity sha1-en7A0esG+lMlx9PgCbhZoJtdSes= + parse5@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== -parse5@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - parseqs@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" @@ -8596,9 +8147,9 @@ postcss-html@^0.36.0: htmlparser2 "^3.10.0" postcss-jsx@^0.36.1: - version "0.36.1" - resolved "https://registry.yarnpkg.com/postcss-jsx/-/postcss-jsx-0.36.1.tgz#ab5e469e7449b84bd1a5973ff555fbe84c39f91d" - integrity sha512-xaZpy01YR7ijsFUtu5rViYCFHurFIPHir+faiOQp8g/NfTfWqZCKDhKrydQZ4d8WlSAmVdXGwLjpFbsNUI26Sw== + version "0.36.3" + resolved "https://registry.yarnpkg.com/postcss-jsx/-/postcss-jsx-0.36.3.tgz#c91113eae2935a1c94f00353b788ece9acae3f46" + integrity sha512-yV8Ndo6KzU8eho5mCn7LoLUGPkXrRXRjhMpX4AaYJ9wLJPv099xbtpbRQ8FrPnzVxb/cuMebbPR7LweSt+hTfA== dependencies: "@babel/core" ">=7.2.2" @@ -8712,11 +8263,6 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= - prettier@1.16.4: version "1.16.4" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" @@ -8727,14 +8273,6 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== -pretty-format@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" - integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - pretty-format@^24.7.0, pretty-format@^24.8.0: version "24.8.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2" @@ -8792,7 +8330,7 @@ prop-types@15.5.8: dependencies: fbjs "^0.8.9" -prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8810,26 +8348,19 @@ proper-lockfile@^3.0.2: retry "^0.12.0" signal-exit "^3.0.2" -property-information@^5.0.0, property-information@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.1.0.tgz#e4755eee5319f03f7f6f5a9bc1a6a7fea6609e2c" - integrity sha512-tODH6R3+SwTkAQckSp2S9xyYX8dEKYkeXw+4TmJzTxnNzd6mQPu1OD4f9zPrvw/Rm4wpPgI+Zp63mNSGNzUgHg== - dependencies: - xtend "^4.0.1" - -proxy-agent@2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-2.3.1.tgz#3d49d863d46cf5f37ca8394848346ea02373eac6" - integrity sha512-CNKuhC1jVtm8KJYFTS2ZRO71VCBx3QSA92So/e6NrY6GoJonkx3Irnk4047EsCcswczwqAekRj3s8qLRGahSKg== +proxy-agent@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.1.0.tgz#3cf86ee911c94874de4359f37efd9de25157c113" + integrity sha512-IkbZL4ClW3wwBL/ABFD2zJ8iP84CY0uKMvBPk/OceQe/cEjrxzN1pMHsLwhbzUoRhG9QbSxYC+Z7LBkTiBNvrA== dependencies: agent-base "^4.2.0" debug "^3.1.0" http-proxy-agent "^2.1.0" https-proxy-agent "^2.2.1" lru-cache "^4.1.2" - pac-proxy-agent "^2.0.1" + pac-proxy-agent "^3.0.0" proxy-from-env "^1.0.0" - socks-proxy-agent "^3.0.0" + socks-proxy-agent "^4.0.1" proxy-from-env@^1.0.0: version "1.0.0" @@ -8897,16 +8428,16 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.0.tgz#b4b41b4bbfd5eeac8d5163efacef34ee5b8ad455" - integrity sha512-18u+bdSosXO0+wx6F1UUFzJz01VRfMBcb/wbBw/tKYRD0A2Vho5WQ4xz30pHwhh4IE/qhObqIs5yNO0mGdHKkA== + version "1.4.1" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" + integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w== dependencies: dijkstrajs "^1.0.1" isarray "^2.0.1" pngjs "^3.3.0" yargs "^13.2.4" -qs@^6.5.1: +qs@^6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== @@ -8917,9 +8448,9 @@ qs@~6.5.2: integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^6.4.2: - version "6.8.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.1.tgz#62c54a7ef37d01b538c8fd56f95740c81d438a26" - integrity sha512-g6y0Lbq10a5pPQpjlFuojfMfV1Pd2Jw9h75ypiYPPia3Gcq2rgkKiIwbkS6JxH7c5f5u/B/sB+d13PU+g1eu4Q== + version "6.8.2" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.2.tgz#36cb7e452ae11a4b5e9efee83375e0954407b2f6" + integrity sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -8940,15 +8471,6 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - randombytes@^2.0.0, randombytes@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -8981,12 +8503,7 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-clone-referenced-element@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" - integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== - -react-coin-icon@^0.1.8: +react-coin-icon@^0.1.9: version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== @@ -9000,10 +8517,10 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.1.tgz#51af81ceada65209bbccb8b547a01187cd1cbf04" - integrity sha512-I/LSX+tpeTrGKaF1wXSfJ/kP+6iaP2JfshEjW8LtQBdz6c6HhzOJtjZXhqOUrAdysuey8M1/JgPY1flSVVt8Ig== +react-devtools-core@^3.6.1: + version "3.6.3" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" + integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== dependencies: shell-quote "^1.6.1" ws "^3.3.1" @@ -9036,26 +8553,26 @@ react-native-camera@^2.11.0: prop-types "^15.6.2" react-native-circular-progress@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-native-circular-progress/-/react-native-circular-progress-1.1.0.tgz#5cb3efe570796226c59bf15a35250fb8b0d45025" - integrity sha512-4Fx7hDGUJyLHTc9fThnXmsW+ea3wjNC8xUwoTCnaL6W29ki9IJQZY9QiDzwtReDxHW6CvNiEzeYB3obNgOfUrQ== + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-native-circular-progress/-/react-native-circular-progress-1.3.0.tgz#76bf4062d8ddc059e4f2bce88be600dbf5efd857" + integrity sha512-g9T6S9320PeDW7T4l+7fV9Bdt9oy2OdWWm2UXceP6VGF1bE19I0++1Di01WQyc9nPpo2ZQ4pO51zkbg1sbY77Q== dependencies: - prop-types "^15.6.2" + prop-types "^15.7.2" react-native-clean-project@^3.1.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.3.tgz#40313a3a4131353d5d082d7691b41b4de6f40eb2" - integrity sha512-c8NgNTXAwugyuP+bS5b5mwpML4JrSP+u9D5b6X5OudU6hPlzPsiFLnBzQUvJVSPRHRwCFj30/qHGCjLc/jPzUw== + version "3.2.4" + resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.4.tgz#55a71006eb4336dff91d0ca5ab3564d8f0db45cc" + integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== react-native-code-push@^5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/react-native-code-push/-/react-native-code-push-5.6.0.tgz#e905d32d188c5f7bcff446d813271d03a69543fd" - integrity sha512-NDZG+t1K+7ubjdtkuQ5UjcqRZbtqZMiMPCnp3VJRfdcX2KcgivW0piRZ3myuAYd6Jyxs4w13rIXo2kzLW4sxBQ== + version "5.6.1" + resolved "https://registry.yarnpkg.com/react-native-code-push/-/react-native-code-push-5.6.1.tgz#d08d5a05ec619c6909822c2f6c4130da5d264d93" + integrity sha512-3iAKPeVCiqOdpBes7KQ4mUXjFTYiY2YdNR5smFfebGZQTgMj1hDWknQfIULaIwr7yE7+UiBe+WsnoAzepoNOIA== dependencies: - code-push "2.0.6" + code-push "^2.0.7" glob "^5.0.15" hoist-non-react-statics "^2.3.1" - inquirer "1.1.2" + inquirer "^1.1.2" plist "3.0.1" semver "^5.6.0" xcode "1.0.0" @@ -9076,9 +8593,9 @@ react-native-crypto@^2.1.2: public-encrypt "^4.0.0" react-native-device-info@^2.1.3: - version "2.2.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.2.2.tgz#777388b8cff4594c8db2ea3a53f2f1f9e2c611a1" - integrity sha512-2b0TycUJbW/9T7L070L6q4+ce8guD4c0c8mWWjiVNuvCrZVf7VNomvNk1BqIVXcnYbZO43V0SVN6z1fvp2HTyg== + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" + integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== react-native-dotenv@^0.2.0: version "0.2.0" @@ -9117,7 +8634,7 @@ react-native-gesture-handler@^1.3.0: invariant "^2.2.2" prop-types "^15.5.10" -react-native-haptic-feedback@^1.8.0: +react-native-haptic-feedback@^1.8.2: version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== @@ -9158,9 +8675,9 @@ react-native-level-fs@^3.0.1: levelup "^0.18.2" react-native-linear-gradient@^2.5.4: - version "2.5.4" - resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.4.tgz#dce133526f5a5510a639af94544f1ed0c984bd1e" - integrity sha512-FF1NhlerA4uBiS0gFIHa4FBp8/aftv4vPj14Y47lGNkYjSI94tnI6oYO3EfUxXjEyCUPiOVNKZOB9kScyjc5Ew== + version "2.5.6" + resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz#96215cbc5ec7a01247a20890888aa75b834d44a0" + integrity sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg== react-native-mail@^3.0.6: version "3.0.7" @@ -9173,9 +8690,9 @@ react-native-os@^1.2.2: integrity sha512-ohlP5BxJxvWp8JZ99g8+xdZ2s8Z4bEoP6g99VDeytz04m+VYdVrCP7Xovy6FoEqA4qxyUbv4xeGHR+pzNnkZeg== react-native-permissions@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.1.1.tgz#4876004681ff8556454613d85249b01baff9b35b" - integrity sha512-t0Ujm177bagjUOSzhpmkSz+LqFW04HnY9TeZFavDCmV521fQvFz82aD+POXqWsAdsJVOK3umJYBNNqCjC3g0hQ== + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.2.0.tgz#0deb616bf1565c17c91f1cb1f953809b2892c29e" + integrity sha512-+KrP1JZ30RI9p30wsGlGQx22qwiClDnznSQZPpvBMkOIZQ9kXOkLAFXS+vwiHRiiRu/pBMBXYHfI7ng6t2+LbQ== react-native-qrcode-scanner@mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e: version "1.0.1" @@ -9208,6 +8725,16 @@ react-native-reanimated@1.1.0: resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz#ba6864055ec3a206cdd5209a293fe653ce276206" integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== +react-native-redash@^7.2.1: + version "7.5.0" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.0.tgz#fa72c7a23ad2f3f884a494ed76a0e79041ae70e1" + integrity sha512-y2J19HbBYWOYq4kq+3U86wfbsDusxv1/ak4a6KqvfTmt/E3i85mnnUDIF+nk1Shqz0aYcwNMB2KD7bEWsVK/sw== + dependencies: + abs-svg-path "^0.1.1" + normalize-svg-path "^1.0.1" + parse-svg-path "^0.1.2" + use-memo-one "^1.1.1" + react-native-safe-area-view@^0.14.1: version "0.14.6" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" @@ -9221,18 +8748,13 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.22: +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== dependencies: debounce "^1.2.0" -react-native-shimmer-placeholder@^1.0.29: - version "1.0.35" - resolved "https://registry.yarnpkg.com/react-native-shimmer-placeholder/-/react-native-shimmer-placeholder-1.0.35.tgz#e75612297155a337690a42faf606fdcc4660bd39" - integrity sha512-qJS+eHjOuXZAxn4tFQFnRGHq6fzJOcNHrCKhbfx2+5v/Oa/W5G9Ww9DSPLiaAqzpRl74lcVZSufKTAxiVSB4qQ== - react-native-splash-screen@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#d47ec8557b1ba988ee3ea98d01463081b60fff45" @@ -9246,10 +8768,15 @@ react-native-storage@^1.0.1: opencollective "^1.0.3" opencollective-postinstall "^2.0.2" +react-native-store-review@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" + integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== + react-native-svg@^9.5.1: - version "9.5.1" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.5.1.tgz#eb21fa7eb5d71649620541e6549c6ed425d80240" - integrity sha512-cRGfomzG/5LEwuJ6ct3m5yccckeI9aj8BNYwDPVxOeJ84LuJuvk5OqcjlYNeEzOWmWiH+QrFXfpLH1ag04bUeQ== + version "9.5.3" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.5.3.tgz#2389f3ffd700c6441166496a1aeade31ead89c59" + integrity sha512-VUOe4TLz7RFdmm/XT9EH87VSwlRykx49qbwJMA+dh9eFM7KPY1qH3kEyN7uRCqJD2eE8toxt9NpjR6ByvtPNlA== react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -9296,61 +8823,39 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.59.9: - version "0.59.9" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.59.9.tgz#c94ee4fa35121720c05235a2dd6cdd2784bf5177" - integrity sha512-/+8EgIZwFpYHyyJ7Zav7B6LHNrytwUQ+EKGT/QV7HSrgpf2Y5NZNeUYUHKiVKLYpBip1G32/LcAECQj37YRwGQ== +react-native@0.60.4: + version "0.60.4" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.4.tgz#4378171e63dd5310497e15e54ec9185cb470752d" + integrity sha512-WE41lbGQjnzM9srIFtMDtMJkQAvk95iZwuFvAxl68s80bkYa7Ou9sGFHpeYIV6cY8yHtheCSo5q6YMxhdfkdOw== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^1.2.1" - absolute-path "^0.0.0" + "@react-native-community/cli" "^2.0.1" + "@react-native-community/cli-platform-android" "^2.0.1" + "@react-native-community/cli-platform-ios" "^2.0.1" + abort-controller "^3.0.0" art "^0.10.0" base64-js "^1.1.2" - chalk "^2.4.1" - commander "^2.9.0" - compression "^1.7.1" connect "^3.6.5" create-react-class "^15.6.3" - debug "^2.2.0" - denodeify "^1.2.1" - errorhandler "^1.5.0" escape-string-regexp "^1.0.5" - event-target-shim "^1.0.5" + event-target-shim "^5.0.1" fbjs "^1.0.0" - fbjs-scripts "^1.0.0" - fs-extra "^1.0.0" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" + fbjs-scripts "^1.1.0" + hermesvm "^0.1.0" invariant "^2.2.4" - lodash "^4.17.5" - metro-babel-register "0.51.0" - metro-react-native-babel-transformer "0.51.0" - mime "^1.3.4" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-fetch "^2.2.0" - node-notifier "^5.2.1" - npmlog "^2.0.4" + jsc-android "245459.0.0" + metro-babel-register "0.54.1" + metro-react-native-babel-transformer "0.54.1" + metro-source-map "^0.55.0" nullthrows "^1.1.0" - opn "^3.0.2" - optimist "^0.6.1" - plist "^3.0.0" - pretty-format "24.0.0-alpha.6" + pretty-format "^24.7.0" promise "^7.1.1" - prop-types "^15.5.8" - react-clone-referenced-element "^1.0.1" - react-devtools-core "^3.6.0" - regenerator-runtime "^0.11.0" - rimraf "^2.5.4" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" + prop-types "^15.7.2" + react-devtools-core "^3.6.1" + regenerator-runtime "^0.13.2" + scheduler "0.14.0" stacktrace-parser "^0.1.3" - ws "^1.1.5" - xmldoc "^0.4.0" - yargs "^9.0.0" + whatwg-fetch "^3.0.0" react-navigation-drawer@~1.2.1: version "1.2.1" @@ -9374,10 +8879,10 @@ react-navigation-tabs@~1.1.4: react-lifecycles-compat "^3.0.4" react-native-tab-view "^1.4.1" -react-navigation@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.0.tgz#2c82217c452d07d8b9b0929bc7e77e2bcfaf9388" - integrity sha512-wlPcDtNiIdPeYxNQ/MN4arY5Xe9EphD2QVpRuvvuPWW+BamF3AJaIy060r3Yz59DODAoWllscabat/yqnih8Tg== +react-navigation@^3.11.1: + version "3.11.1" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.1.tgz#ba696ad6b512088a97a20cc7e6a250c53dbddd26" + integrity sha512-n64HxLG5s5ucVFo1Gs+D9ujChhHDd98lpQ1p27wL7gq8V1PaRJMvsBEIsguhtc2rTIL/TWDynOesXQDG+Eg6FQ== dependencies: "@react-navigation/core" "~3.4.1" "@react-navigation/native" "~3.5.0" @@ -9416,6 +8921,11 @@ react-redux@^5.0.7: react-is "^16.6.0" react-lifecycles-compat "^3.0.0" +react-refresh@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.2.0.tgz#f0cff375e8f75dea7133a847a1b40cf5c073dd0d" + integrity sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg== + react-spring@^5.7.2: version "5.9.2" resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-5.9.2.tgz#4c4e048ffce24755eaa60acd2f3fe4a3d686ef16" @@ -9453,15 +8963,15 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@16.8.3: - version "16.8.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" - integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== +react@16.8.6: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" + integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.3" + scheduler "^0.13.6" read-pkg-up@^2.0.0: version "2.0.0" @@ -9515,7 +9025,7 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@3, readable-stream@^3.1.1: +readable-stream@3, readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== @@ -9524,7 +9034,7 @@ readable-stream@3, readable-stream@^3.1.1: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@~2.3.6: +readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -9578,10 +9088,10 @@ recompose@^0.30.0: react-lifecycles-compat "^3.0.2" symbol-observable "^1.0.4" -recursive-fs@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/recursive-fs/-/recursive-fs-0.1.4.tgz#47e08b1ddab8d7d9a960aa0d0daea76f875b63fa" - integrity sha1-R+CLHdq419mpYKoNDa6nb4dbY/o= +recursive-fs@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/recursive-fs/-/recursive-fs-1.1.2.tgz#1d752e2f1a65d25fb6964109a9dbf83a335f90f0" + integrity sha512-QPFEt5EwzwlHoqYsZc+NkUSyDTQf1Hvq7c/kpQJHi77OSCAiDXI3wfB0J04ZG+ekGHmv37mdR8MDPEshD3/RlQ== recursive-readdir@^2.2.2: version "2.2.2" @@ -9648,24 +9158,17 @@ regenerator-runtime@^0.11.0: integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-runtime@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" - integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" + integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== regenerator-transform@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" - integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w== + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" + integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== dependencies: private "^0.1.6" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== - dependencies: - is-equal-shallow "^0.1.3" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -9718,15 +9221,6 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" -rehype-parse@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.1.tgz#a5401d7f4144d5e17cbb69be11f05a2a7ba87e27" - integrity sha512-FrGSbOzcGxIvWty1qHjKTvHT4WBTt7C6JLs65EkvFPa7ZKraSmsoDDj6al1eBxaXS1t/kiGdPYazUe58Mgflgw== - dependencies: - hast-util-from-parse5 "^5.0.0" - parse5 "^5.0.0" - xtend "^4.0.1" - remark-parse@^6.0.0: version "6.0.3" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" @@ -9787,7 +9281,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -9971,11 +9465,6 @@ rn-nodeify@^10.0.1: semver "^5.0.1" xtend "^4.0.0" -rsvp@^3.3.3: - version "3.6.2" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" - integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== - rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -10051,23 +9540,6 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" - integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== - dependencies: - anymatch "^2.0.0" - capture-exit "^1.2.0" - exec-sh "^0.2.0" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.2.3" - sane@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" @@ -10084,9 +9556,9 @@ sane@^4.0.3: walker "~1.0.5" sanitize-filename@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" - integrity sha1-YS2hyWRz+gLczaktzVtKsWSmdyo= + version "1.6.2" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.2.tgz#01b4fc8809f14e9d22761fe70380fe7f3f902185" + integrity sha512-cmTzND7RMxUB+f7gI+4+KAVHWEg0lfXvQJdko+FXDP5bNbGIdx4KMP5pX6lv5jfT9jSf6OBbjyxjFtZQwYA/ig== dependencies: truncate-utf8-bytes "^1.0.0" @@ -10107,7 +9579,15 @@ schedule@0.4.0: dependencies: object-assign "^4.1.1" -scheduler@^0.13.3: +scheduler@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b" + integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +scheduler@^0.13.3, scheduler@^0.13.6: version "0.13.6" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== @@ -10137,10 +9617,10 @@ semver@5.5.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== -semver@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" - integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== +semver@^6.0.0, semver@^6.1.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@~2.3.1: version "2.3.2" @@ -10291,13 +9771,6 @@ simple-plist@^1.0.0: bplist-parser "0.1.1" plist "^3.0.1" -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - sisteransi@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.2.tgz#ec57d64b6f25c4f26c0e2c7dd23f2d7f12f7e418" @@ -10308,21 +9781,16 @@ sjcl@^1.0.3: resolved "https://registry.yarnpkg.com/sjcl/-/sjcl-1.0.8.tgz#f2ec8d7dc1f0f21b069b8914a41a8f236b0e252a" integrity sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ== -slash@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= +slash@3.0.0, slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - slice-ansi@^2.0.0, slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -10337,10 +9805,10 @@ slide@^1.1.5: resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= -smart-buffer@^1.0.13: - version "1.1.15" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" - integrity sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY= +smart-buffer@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d" + integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw== snapdragon-node@^2.0.1: version "2.1.1" @@ -10401,21 +9869,21 @@ socket.io-parser@~3.3.0: debug "~3.1.0" isarray "2.0.1" -socks-proxy-agent@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659" - integrity sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA== +socks-proxy-agent@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== dependencies: - agent-base "^4.1.0" - socks "^1.1.10" + agent-base "~4.2.1" + socks "~2.3.2" -socks@^1.1.10: - version "1.1.10" - resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" - integrity sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o= +socks@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e" + integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ== dependencies: - ip "^1.1.4" - smart-buffer "^1.0.13" + ip "^1.1.5" + smart-buffer "4.0.2" source-map-resolve@^0.5.0: version "0.5.2" @@ -10451,11 +9919,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -space-separated-tokens@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz#27910835ae00d0adfcdbd0ad7e611fb9544351fa" - integrity sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA== - spawn-sync@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" @@ -10814,29 +10277,30 @@ sugarss@^2.0.0: dependencies: postcss "^7.0.2" -superagent-proxy@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/superagent-proxy/-/superagent-proxy-1.0.3.tgz#acfa776672f11c24a90ad575e855def8be44f741" - integrity sha512-79Ujg1lRL2ICfuHUdX+H2MjIw73kB7bXsIkxLwHURz3j0XUmEEEoJ+u/wq+mKwna21Uejsm2cGR3OESA00TIjA== +superagent-proxy@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/superagent-proxy/-/superagent-proxy-2.0.0.tgz#9f57515cd660e2e9ce55c0e6bd70f92eb07c3ee0" + integrity sha512-TktJma5jPdiH1BNN+reF/RMW3b8aBTCV7KlLFV0uYcREgNf3pvo7Rdt564OcFHwkGb3mYEhHuWPBhSbOwiNaYw== dependencies: debug "^3.1.0" - proxy-agent "2" + proxy-agent "3" -superagent@^3.8.0: - version "3.8.3" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" - integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA== +superagent@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.0.tgz#9ce4f38bee64d65a56166423b573222fa1b8f041" + integrity sha512-7V6JVx5N+eTL1MMqRBX0v0bG04UjrjAvvZJTF/VDH/SH2GjSLqlrcYepFlpTrXpm37aSY6h3GGVWGxXl/98TKA== dependencies: - component-emitter "^1.2.0" - cookiejar "^2.1.0" - debug "^3.1.0" - extend "^3.0.0" - form-data "^2.3.1" - formidable "^1.2.0" - methods "^1.1.1" - mime "^1.4.1" - qs "^6.5.1" - readable-stream "^2.3.5" + component-emitter "^1.3.0" + cookiejar "^2.1.2" + debug "^4.1.1" + fast-safe-stringify "^2.0.6" + form-data "^2.3.3" + formidable "^1.2.1" + methods "^1.1.2" + mime "^2.4.4" + qs "^6.7.0" + readable-stream "^3.4.0" + semver "^6.1.1" supports-color@6.0.0: version "6.0.0" @@ -10864,22 +10328,31 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +svg-arc-to-cubic-bezier@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz#390c450035ae1c4a0104d90650304c3bc814abe6" + integrity sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g== + +svg-parser@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.2.tgz#d134cc396fa2681dc64f518330784e98bd801ec8" + integrity sha512-1gtApepKFweigFZj3sGO8KT8LvVZK8io146EzXrpVuWCDAbISz/yMucco3hWTkpZNoPabM+dnMOpy6Swue68Zg== + svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= svgo@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316" - integrity sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" + integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== dependencies: chalk "^2.4.1" coa "^2.0.2" css-select "^2.0.0" css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.28" - css-url-regex "^1.1.0" + css-tree "1.0.0-alpha.33" csso "^3.5.1" js-yaml "^3.13.1" mkdirp "~0.5.1" @@ -10913,12 +10386,12 @@ symbol-tree@^3.2.2: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^5.2.3: - version "5.4.1" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.1.tgz#0691ae2ebe8259858efb63e550b6d5f9300171e8" - integrity sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w== + version "5.4.4" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.4.tgz#6e0f88fdae3692793d1077fd172a4667afe986a6" + integrity sha512-IIfEAUx5QlODLblLrGTTLJA7Tk0iLSGBvgY8essPRVNGHAzThujww1YqHLs6h3HfTg55h++RzLHH5Xw/rfv+mg== dependencies: - ajv "^6.9.1" - lodash "^4.17.11" + ajv "^6.10.2" + lodash "^4.17.14" slice-ansi "^2.1.0" string-width "^3.0.0" @@ -10995,7 +10468,7 @@ throat@^4.0.0, throat@^4.1.0: resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= -through2@^2.0.0: +through2@^2.0.0, through2@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -11167,9 +10640,9 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== tsutils@^3.7.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.14.0.tgz#bf8d5a7bae5369331fa0f2b0a5a10bd7f7396c77" - integrity sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw== + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.14.1.tgz#f1d2b93d2a0876481f2f1f98c25ba42bbd7ee860" + integrity sha512-kiuZzD1uUA5DxGj/uxbde+ymp6VVdAxdzOIlAFbYKrPyla8/uiJ9JLBm1QsPhOm4Muj0/+cWEDP99yoCUcSl6Q== dependencies: tslib "^1.8.1" @@ -11269,7 +10742,7 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== -unified@^7.0.0, unified@^7.1.0: +unified@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" integrity sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw== @@ -11329,13 +10802,6 @@ unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ== -unist-util-stringify-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz#de2a2bc8d3febfa606652673a91455b6a36fb9f3" - integrity sha512-Zqlf6+FRI39Bah8Q6ZnNGrEHUhwJOkHde2MHVk96lLyftfJJckaPslKgzhVcviXj8KcE9UJM9F+a4JEiBUTYgA== - dependencies: - "@types/unist" "^2.0.2" - unist-util-visit-parents@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" @@ -11421,6 +10887,11 @@ url@^0.10.3: punycode "1.3.2" querystring "0.2.0" +use-memo-one@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.1.tgz#39e6f08fe27e422a7d7b234b5f9056af313bd22c" + integrity sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -11512,14 +10983,6 @@ vfile-message@^1.0.0: dependencies: unist-util-stringify-position "^1.1.1" -vfile-message@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.1.tgz#951881861c22fc1eb39f873c0b93e336a64e8f6d" - integrity sha512-KtasSV+uVU7RWhUn4Lw+wW1Zl/nW8JWx7JCPps10Y9JRRIDeDXf8wfBLoOSsJLyo27DqMyAi54C6Jf/d6Kr2Bw== - dependencies: - "@types/unist" "^2.0.2" - unist-util-stringify-position "^2.0.0" - vfile@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" @@ -11530,16 +10993,10 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" -vfile@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.1.tgz#fc3d43a1c71916034216bf65926d5ee3c64ed60c" - integrity sha512-lRHFCuC4SQBFr7Uq91oJDJxlnftoTLQ7eKIpMdubhYcVMho4781a8MWXLy3qZrZ0/STD1kRiKc0cQOHm4OkPeA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" +vlq@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" + integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== vm-browserify@0.0.4: version "0.0.4" @@ -11569,14 +11026,6 @@ warning@^4.0.2: dependencies: loose-envify "^1.0.0" -watch@~0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" - integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= - dependencies: - exec-sh "^0.2.0" - minimist "^1.2.0" - wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -11584,11 +11033,6 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -web-namespaces@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.3.tgz#9bbf5c99ff0908d2da031f1d732492a96571a83f" - integrity sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA== - webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -11601,7 +11045,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" -whatwg-fetch@>=0.10.0: +whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== @@ -11892,7 +11336,7 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.0.0, yargs-parser@^13.1.0: +yargs-parser@^13.0.0, yargs-parser@^13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== @@ -11952,21 +11396,20 @@ yargs@^12.0.2, yargs@^12.0.5: yargs-parser "^11.1.1" yargs@^13.0.0, yargs@^13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + version "13.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" + integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== dependencies: cliui "^5.0.0" find-up "^3.0.0" get-caller-file "^2.0.1" - os-locale "^3.1.0" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" string-width "^3.0.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.1.0" + yargs-parser "^13.1.1" yargs@^9.0.0: version "9.0.1" From 0d8852a3b40d1b641a08a29af1270ee630219cba Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 8 Aug 2019 16:41:37 +0200 Subject: [PATCH 064/636] adjust back scroll on big devices --- src/components/asset-list/RecyclerAssetList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index b90f8dc6ba7..0076b699b85 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -428,7 +428,7 @@ class RecyclerAssetList extends Component { } } const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 280); + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); if (this.position + deviceDimensions > renderSize) { layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); this.scrollToOffset(renderSize - deviceDimensions, true); From 090c6a5d03ac0be33a56afab8f62ec6997cdc94a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 9 Aug 2019 11:57:57 +0200 Subject: [PATCH 065/636] make invisible small balances not clickable --- src/components/asset-list/RecyclerAssetList.js | 1 + src/components/coin-row/BalanceCoinRow.js | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 0076b699b85..efde98a986f 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -546,6 +546,7 @@ class RecyclerAssetList extends Component { const renderList = []; for (let i = 0; i < item.assets.length; i++) { const selectedItem = { item: item.assets[i] }; + selectedItem.item.isSmall = true; renderList.push(renderItem(selectedItem)); } diff --git a/src/components/coin-row/BalanceCoinRow.js b/src/components/coin-row/BalanceCoinRow.js index 68f754e5664..888d331b77b 100644 --- a/src/components/coin-row/BalanceCoinRow.js +++ b/src/components/coin-row/BalanceCoinRow.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React, { Fragment } from 'react'; import { compose, shouldUpdate, withHandlers } from 'recompact'; import { buildAssetUniqueIdentifier } from '../../helpers/assets'; -import { withAccountSettings } from '../../hoc'; +import { withAccountSettings, withOpenBalances } from '../../hoc'; import { colors } from '../../styles'; import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; @@ -63,12 +63,14 @@ TopRow.propTypes = { }; const BalanceCoinRow = ({ + isSmall, item, onPress, onPressSend, + openSmallBalances, ...props }) => ( - + () => { if (onPress) { @@ -102,12 +106,13 @@ export default compose( }, }), shouldUpdate((props, nextProps) => { + const isChangeInOpenAssets = props.openSmallBalances !== nextProps.openSmallBalances; const itemIdentifier = buildAssetUniqueIdentifier(props.item); const nextItemIdentifier = buildAssetUniqueIdentifier(nextProps.item); const isNewItem = itemIdentifier !== nextItemIdentifier; const isNewNativeCurrency = isNewValueForPath(props, nextProps, 'nativeCurrency'); - return isNewItem || isNewNativeCurrency; + return isNewItem || isNewNativeCurrency || isChangeInOpenAssets; }), )(BalanceCoinRow); From 9fe528b942bcc773e975e22369adb69808cf7e32 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 9 Aug 2019 12:57:43 +0200 Subject: [PATCH 066/636] sync all closing animations for families --- src/components/asset-list/RecyclerAssetList.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index efde98a986f..a92fbb1aaca 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -395,6 +395,7 @@ class RecyclerAssetList extends Component { break; } if (this.props.openFamilyTabs[i] === false && prev.openFamilyTabs[i] === true) { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); @@ -430,12 +431,11 @@ class RecyclerAssetList extends Component { const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); if (this.position + deviceDimensions > renderSize) { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); this.scrollToOffset(renderSize - deviceDimensions, true); - setTimeout(() => { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); - }, 300); } + setTimeout(() => { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); + }, 300); } i++; } From 212df43c3f609f96fd9d3062b2efd1b3ac7948b4 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 9 Aug 2019 13:40:57 +0200 Subject: [PATCH 067/636] fix sync of closing animation for small render sizes --- src/components/asset-list/RecyclerAssetList.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index a92fbb1aaca..b383611f0ec 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -395,7 +395,6 @@ class RecyclerAssetList extends Component { break; } if (this.props.openFamilyTabs[i] === false && prev.openFamilyTabs[i] === true) { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); @@ -430,12 +429,13 @@ class RecyclerAssetList extends Component { } const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); - if (this.position + deviceDimensions > renderSize) { + if (this.position + deviceDimensions > renderSize && renderSize > deviceDimensions) { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); this.scrollToOffset(renderSize - deviceDimensions, true); + setTimeout(() => { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); + }, 300); } - setTimeout(() => { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); - }, 300); } i++; } From 02566bf90a923e1f12ff7dc60f4ca97a5d46bcb0 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 9 Aug 2019 16:48:17 +0200 Subject: [PATCH 068/636] move loading open assets state to wallet screen, and make components open on render not animate it after --- src/App.js | 15 ------- .../coin-divider/SmallBalancesWrapper.js | 45 ++++++++++++++++++- .../token-family/TokenFamilyHeader.js | 4 +- .../token-family/TokenFamilyWrap.js | 3 ++ src/helpers/buildWalletSections.js | 2 - src/screens/WalletScreen.js | 16 +++++++ 6 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/App.js b/src/App.js index 29e71f60e14..1261da742e7 100644 --- a/src/App.js +++ b/src/App.js @@ -28,10 +28,6 @@ import store from './redux/store'; import { requestsForTopic } from './redux/requests'; import Routes from './screens/Routes'; import { parseQueryParams } from './utils'; -import { setOpenSmallBalances } from './redux/openBalances'; -import { getSmallBalanceToggle, getOpenInvestmentCards, getOpenFamilies } from './handlers/commonStorage'; -import { pushOpenInvestmentCard } from './redux/openInvestmentCards'; -import { pushOpenFamilyTab } from './redux/openFamilyTabs'; if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; @@ -90,18 +86,7 @@ class App extends Component { return Navigation.handleAction({ routeName: 'ProfileScreen' }); }; - setInitialStatesForOpenAssets = async () => { - const toggle = await getSmallBalanceToggle(); - const openInvestmentCards = await getOpenInvestmentCards(); - const openFamilies = await getOpenFamilies(); - await store.dispatch(setOpenSmallBalances(toggle)); - await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); - await store.dispatch(pushOpenFamilyTab(openFamilies)); - return true; - } - async componentDidMount() { - await this.setInitialStatesForOpenAssets(); AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.handleInitializeAnalytics(); diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index 3b52a57d818..f2de07269ed 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -1,6 +1,13 @@ +import { withSafeTimeout } from '@hocs/safe-timers'; import PropTypes from 'prop-types'; import React from 'react'; import { View } from 'react-native'; +import { + compose, + lifecycle, + withState, + withHandlers, +} from 'recompact'; import { withOpenBalances } from '../../hoc'; import CoinDivider from './CoinDivider'; import OpacityToggler from '../animations/OpacityToggler'; @@ -18,6 +25,7 @@ const balancesSum = (balances) => { }; const SmallBalancesWrapper = ({ + areChildrenVisible, openSmallBalances, setOpenSmallBalances, assets, @@ -31,16 +39,49 @@ const SmallBalancesWrapper = ({ onChangeOpenBalances={() => setOpenSmallBalances(!openSmallBalances)} /> - {assets} + {areChildrenVisible && assets} ); SmallBalancesWrapper.propTypes = { + areChildrenVisible: PropTypes.bool, assets: PropTypes.array, balancesSum: PropTypes.string, openSmallBalances: PropTypes.bool, setOpenSmallBalances: PropTypes.func, }; -export default withOpenBalances(SmallBalancesWrapper); +export default compose( + withSafeTimeout, + withOpenBalances, + withState('areChildrenVisible', 'setAreChildrenVisible', true), + withHandlers({ + onHideChildren: ({ areChildrenVisible, setAreChildrenVisible }) => () => { + if (areChildrenVisible) { + setAreChildrenVisible(false); + } + }, + onShowChildren: ({ areChildrenVisible, setAreChildrenVisible }) => () => { + if (!areChildrenVisible) { + setAreChildrenVisible(true); + } + }, + }), + lifecycle({ + componentDidMount() { + this.props.onShowChildren(); + }, + componentDidUpdate() { + if (!this.props.openSmallBalances) { + setTimeout(() => { + if (!this.props.openSmallBalance) { + this.props.onHideChildren(); + } + }, 200); + } else { + this.props.onShowChildren(); + } + }, + }), +)(SmallBalancesWrapper); diff --git a/src/components/token-family/TokenFamilyHeader.js b/src/components/token-family/TokenFamilyHeader.js index 0c1e58ad460..459e97d0a38 100644 --- a/src/components/token-family/TokenFamilyHeader.js +++ b/src/components/token-family/TokenFamilyHeader.js @@ -45,9 +45,7 @@ export default class TokenFamilyHeader extends PureComponent { static height = TokenFamilyHeaderHeight; - animation = new Value(0) - - componentDidMount = () => this.runTiming() + animation = new Value(this.props.isOpen ? 1 : 0); componentDidUpdate = (prevProps) => { if (isNewValueForPath(this.props, prevProps, 'isOpen')) { diff --git a/src/components/token-family/TokenFamilyWrap.js b/src/components/token-family/TokenFamilyWrap.js index 77be2ce7427..9b6fff74dbd 100644 --- a/src/components/token-family/TokenFamilyWrap.js +++ b/src/components/token-family/TokenFamilyWrap.js @@ -135,6 +135,9 @@ export default compose( /* eslint-enable react/display-name */ }), lifecycle({ + componentDidMount() { + this.props.onShowChildren(); + }, componentDidUpdate() { if (!this.props.isFamilyOpen) { this.props.onHideChildren(); diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index d82ae2f1740..7b0eb748203 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -81,8 +81,6 @@ const buildWalletSections = ( uniqueTokenFamiliesSection, ]; - console.log(uniswapSection); - const filteredSections = filterWalletSections(sections); const isEmpty = !filteredSections.length; setIsWalletEmpty(isEmpty); diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 6bac62be229..bd4cf42db6a 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -32,8 +32,13 @@ import { withStatusBarStyle, withUniswapLiquidity, } from '../hoc'; +import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForPath } from '../utils'; +import { getSmallBalanceToggle, getOpenInvestmentCards, getOpenFamilies } from '../handlers/commonStorage'; +import { setOpenSmallBalances } from '../redux/openBalances'; +import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; +import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; class WalletScreen extends Component { static propTypes = { @@ -54,8 +59,19 @@ class WalletScreen extends Component { uniqueTokens: PropTypes.array, } + setInitialStatesForOpenAssets = async () => { + const toggle = await getSmallBalanceToggle(); + const openInvestmentCards = await getOpenInvestmentCards(); + const openFamilies = await getOpenFamilies(); + await store.dispatch(setOpenSmallBalances(toggle)); + await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); + await store.dispatch(pushOpenFamilyTab(openFamilies)); + return true; + } + componentDidMount = async () => { try { + await this.setInitialStatesForOpenAssets(); await this.props.initializeWallet(); } catch (error) { // TODO From 4d8d03ad452c95647c9d30285a56fb3c91513004 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 9 Aug 2019 17:41:37 +0200 Subject: [PATCH 069/636] add sized present in recycled list height calculations --- src/components/asset-list/RecyclerAssetList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index b383611f0ec..aca87437732 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -368,12 +368,12 @@ class RecyclerAssetList extends Component { if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); if (balances.data[balances.data.length - 1].smallBalancesContainer) { - balancesHeight += CoinDivider.height + ListFooter.height; + balancesHeight += CoinDivider.height + ListFooter.height + 9; if (this.props.openSmallBalances) { balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; } } else { - balancesHeight += CoinRow.height + ListFooter.height; + balancesHeight += CoinDivider.height + ListFooter.height + 16; } } const verticalOffset = 10; From 8e9b85d59cacc2371caa0466d476dea8e0cd6425 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 9 Aug 2019 20:42:48 +0200 Subject: [PATCH 070/636] remove shouldComponentUpdate from Recycler Asset List --- src/components/asset-list/RecyclerAssetList.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index aca87437732..832e29baa07 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -300,22 +300,6 @@ class RecyclerAssetList extends Component { }; } - shouldComponentUpdate = (nextProps, nextState) => { - if (nextProps.openFamilyTabs !== this.props.openFamilyTabs) { - return true; - } - - if (nextState.isRefreshing !== this.state.isRefreshing) { - return true; - } - - if (this.contentSize - this.layoutMeasurement < this.position && this.position !== 0 && !(this.position <= reloadHeightOfsetTop && this.position > reloadHeightOffsetBottom)) { - return false; - } - - return true; - } - componentDidMount = () => { this.isCancelled = false; }; From b228a923d5231e1389718c7557255cdd1efc0909 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Fri, 9 Aug 2019 11:56:41 -0700 Subject: [PATCH 071/636] Adjust CoinRow padding --- src/components/coin-row/CoinRow.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/coin-row/CoinRow.js b/src/components/coin-row/CoinRow.js index 3f09b46ceb0..daf91bdcc6b 100644 --- a/src/components/coin-row/CoinRow.js +++ b/src/components/coin-row/CoinRow.js @@ -8,8 +8,8 @@ import { CoinIcon } from '../coin-icon'; import Highlight from '../Highlight'; import { Column, Row } from '../layout'; -const CoinRowPaddingTop = 10; -const CoinRowPaddingBottom = 11.5; +const CoinRowPaddingTop = 15; +const CoinRowPaddingBottom = 7; const Container = styled(Row)` ${padding(CoinRowPaddingTop, 19, CoinRowPaddingBottom, 19)} From b38387b594861ab9fd45ab3fdf327afcd0506428 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 9 Aug 2019 18:25:59 -0700 Subject: [PATCH 072/636] Revert "Bump to RN 0.60.4" --- ios/Podfile | 49 +- ios/Podfile.lock | 246 +++----- ios/Rainbow.xcodeproj/project.pbxproj | 53 ++ package.json | 10 +- yarn.lock | 788 ++++++++++++++++++++++---- 5 files changed, 839 insertions(+), 307 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index d10121ad511..87d25b84ac4 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -15,32 +15,33 @@ target 'Rainbow' do pod 'Firebase/Messaging', '~> 5.3.0' # Core React - pod 'React', :path => '../node_modules/react-native/' - pod 'React-Core', :path => '../node_modules/react-native/React' - pod 'React-DevSupport', :path => '../node_modules/react-native/React' - pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' - pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' - pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' - pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' - pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' - pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' - pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' - pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' - pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' - pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' - pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' - - pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' - pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' - pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' - pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' - + pod 'React', :path => "#{rn_path}", :subspecs => [ + 'Core', + 'CxxBridge', # Include this for RN >= 0.47 + 'cxxreact', + 'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43 + 'fishhook', + 'jsi', + 'jsiexecutor', + 'jsinspector', + 'RCTActionSheet', + 'RCTAnimation', # Needed for FlatList and animations running on native UI thread + 'RCTBlob', + 'RCTImage', + 'RCTLinkingIOS', + 'RCTNetwork', + 'RCTPushNotification', + 'RCTSettings', + 'RCTText', + 'RCTVibration', + 'RCTWebSocket', # needed for debugging + ] # React Third Party - required - pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' - pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' - pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' - pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' + pod 'yoga', path: "#{rn_path}/ReactCommon/yoga" + pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec" + pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec" + pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec" # React-Native-Community packages pod 'react-native-blur', :path => '../node_modules/@react-native-community/blur' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d98bfe10aa1..44c0b4cb979 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -31,11 +31,6 @@ PODS: - Protobuf (~> 3.1) - FLAnimatedImage (1.0.12) - Folly (2018.10.22.00): - - boost-for-react-native - - DoubleConversion - - Folly/Default (= 2018.10.22.00) - - glog - - Folly/Default (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog @@ -75,52 +70,8 @@ PODS: - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - Protobuf (3.7.0) - - React (0.60.4): - - React-Core (= 0.60.4) - - React-DevSupport (= 0.60.4) - - React-RCTActionSheet (= 0.60.4) - - React-RCTAnimation (= 0.60.4) - - React-RCTBlob (= 0.60.4) - - React-RCTImage (= 0.60.4) - - React-RCTLinking (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTSettings (= 0.60.4) - - React-RCTText (= 0.60.4) - - React-RCTVibration (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-Core (0.60.4): - - Folly (= 2018.10.22.00) - - React-cxxreact (= 0.60.4) - - React-jsiexecutor (= 0.60.4) - - yoga (= 0.60.4.React) - - React-cxxreact (0.60.4): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-jsinspector (= 0.60.4) - - React-DevSupport (0.60.4): - - React-Core (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-fishhook (0.60.4) - - React-jsi (0.60.4): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-jsi/Default (= 0.60.4) - - React-jsi/Default (0.60.4): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-jsiexecutor (0.60.4): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-cxxreact (= 0.60.4) - - React-jsi (= 0.60.4) - - React-jsinspector (0.60.4) + - React (0.59.9): + - React/Core (= 0.59.9) - react-native-blur (0.8.0): - React - react-native-camera (2.11.1): @@ -138,30 +89,59 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React-RCTActionSheet (0.60.4): - - React-Core (= 0.60.4) - - React-RCTAnimation (0.60.4): - - React-Core (= 0.60.4) - - React-RCTBlob (0.60.4): - - React-Core (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-RCTImage (0.60.4): - - React-Core (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTLinking (0.60.4): - - React-Core (= 0.60.4) - - React-RCTNetwork (0.60.4): - - React-Core (= 0.60.4) - - React-RCTSettings (0.60.4): - - React-Core (= 0.60.4) - - React-RCTText (0.60.4): - - React-Core (= 0.60.4) - - React-RCTVibration (0.60.4): - - React-Core (= 0.60.4) - - React-RCTWebSocket (0.60.4): - - React-Core (= 0.60.4) - - React-fishhook (= 0.60.4) + - React/Core (0.59.9): + - yoga (= 0.59.9.React) + - React/CxxBridge (0.59.9): + - Folly (= 2018.10.22.00) + - React/Core + - React/cxxreact + - React/jsiexecutor + - React/cxxreact (0.59.9): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React/jsinspector + - React/DevSupport (0.59.9): + - React/Core + - React/RCTWebSocket + - React/fishhook (0.59.9) + - React/jsi (0.59.9): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React/jsiexecutor (0.59.9): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React/cxxreact + - React/jsi + - React/jsinspector (0.59.9) + - React/RCTActionSheet (0.59.9): + - React/Core + - React/RCTAnimation (0.59.9): + - React/Core + - React/RCTBlob (0.59.9): + - React/Core + - React/RCTImage (0.59.9): + - React/Core + - React/RCTNetwork + - React/RCTLinkingIOS (0.59.9): + - React/Core + - React/RCTNetwork (0.59.9): + - React/Core + - React/RCTPushNotification (0.59.9): + - React/Core + - React/RCTSettings (0.59.9): + - React/Core + - React/RCTText (0.59.9): + - React/Core + - React/RCTVibration (0.59.9): + - React/Core + - React/RCTWebSocket (0.59.9): + - React/Core + - React/fishhook + - React/RCTBlob - RNAnalytics (1.0.1): - Analytics - React @@ -184,7 +164,7 @@ PODS: - SDWebImage (5.0.2): - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) - - yoga (0.60.4.React) + - yoga (0.59.9.React) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -197,29 +177,30 @@ DEPENDENCIES: - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - libwebp - - React (from `../node_modules/react-native/`) - - React-Core (from `../node_modules/react-native/React`) - - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) - - React-DevSupport (from `../node_modules/react-native/React`) - - React-fishhook (from `../node_modules/react-native/Libraries/fishhook`) - - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-camera (from `../node_modules/react-native-camera`) - react-native-fast-image (from `../node_modules/react-native-fast-image`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-version-number (from `../node_modules/react-native-version-number`) - - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) - - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) - - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) - - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) - - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`) + - React/Core (from `../node_modules/react-native`) + - React/CxxBridge (from `../node_modules/react-native`) + - React/cxxreact (from `../node_modules/react-native`) + - React/DevSupport (from `../node_modules/react-native`) + - React/fishhook (from `../node_modules/react-native`) + - React/jsi (from `../node_modules/react-native`) + - React/jsiexecutor (from `../node_modules/react-native`) + - React/jsinspector (from `../node_modules/react-native`) + - React/RCTActionSheet (from `../node_modules/react-native`) + - React/RCTAnimation (from `../node_modules/react-native`) + - React/RCTBlob (from `../node_modules/react-native`) + - React/RCTImage (from `../node_modules/react-native`) + - React/RCTLinkingIOS (from `../node_modules/react-native`) + - React/RCTNetwork (from `../node_modules/react-native`) + - React/RCTPushNotification (from `../node_modules/react-native`) + - React/RCTSettings (from `../node_modules/react-native`) + - React/RCTText (from `../node_modules/react-native`) + - React/RCTVibration (from `../node_modules/react-native`) + - React/RCTWebSocket (from `../node_modules/react-native`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -259,21 +240,7 @@ EXTERNAL SOURCES: glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" React: - :path: "../node_modules/react-native/" - React-Core: - :path: "../node_modules/react-native/React" - React-cxxreact: - :path: "../node_modules/react-native/ReactCommon/cxxreact" - React-DevSupport: - :path: "../node_modules/react-native/React" - React-fishhook: - :path: "../node_modules/react-native/Libraries/fishhook" - React-jsi: - :path: "../node_modules/react-native/ReactCommon/jsi" - React-jsiexecutor: - :path: "../node_modules/react-native/ReactCommon/jsiexecutor" - React-jsinspector: - :path: "../node_modules/react-native/ReactCommon/jsinspector" + :path: "../node_modules/react-native" react-native-blur: :path: "../node_modules/@react-native-community/blur" react-native-camera: @@ -284,26 +251,6 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/netinfo" react-native-version-number: :path: "../node_modules/react-native-version-number" - React-RCTActionSheet: - :path: "../node_modules/react-native/Libraries/ActionSheetIOS" - React-RCTAnimation: - :path: "../node_modules/react-native/Libraries/NativeAnimation" - React-RCTBlob: - :path: "../node_modules/react-native/Libraries/Blob" - React-RCTImage: - :path: "../node_modules/react-native/Libraries/Image" - React-RCTLinking: - :path: "../node_modules/react-native/Libraries/LinkingIOS" - React-RCTNetwork: - :path: "../node_modules/react-native/Libraries/Network" - React-RCTSettings: - :path: "../node_modules/react-native/Libraries/Settings" - React-RCTText: - :path: "../node_modules/react-native/Libraries/Text" - React-RCTVibration: - :path: "../node_modules/react-native/Libraries/Vibration" - React-RCTWebSocket: - :path: "../node_modules/react-native/Libraries/WebSocket" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -330,43 +277,26 @@ SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c - DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 + DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa - FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 - FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 - FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 - FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb + Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 + FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d + FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 + FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 + FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 - Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 - glog: 1f3da668190260b06b429bb211bfbee5cd790c28 + Folly: de497beb10f102453a1afa9edbf8cf8a251890de + glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a - React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 - React-Core: 8e0ea421cae5609d2562850f98421b15030476fa - React-cxxreact: 326880209990151a7182a813311054e9772ba510 - React-DevSupport: e9f10e6721e78e87622fc985db695c0c0168db8a - React-fishhook: 1f0e5b08449403fa75c3fb3881a0beefbada14af - React-jsi: 21d3153b1153fbf6510a92b6b11e33e725cb7432 - React-jsiexecutor: 7549641e48bafae7bfee3f3ea19bf4901639c5de - React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 + React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: f1fbfc336ba8ca6de5296190341d1b6022c71cff react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 react-native-netinfo: 0da34082d2cec3100c9b5073bb217e35f1142bdd react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 9f71d7ae3e8fb10e08d162cbf14c621349dbfab3 - React-RCTAnimation: 981d8c95b0e30918a9832ccac32af83562a27fae - React-RCTBlob: 21e73d1020a302a75fed30dbaee9f15287b80baa - React-RCTImage: c0bc6ac0926517b6fb7e4c279b04843113e99d1d - React-RCTLinking: 1af3f3c59114bed3deec0107c62e7efad0932ee5 - React-RCTNetwork: 35df9de46e19cda5c56380be1a7759b9b8cb2fcd - React-RCTSettings: f580504c2cd1f44e25add10fb9ed3954f67f8ac5 - React-RCTText: e0f224898b13af9aa036ea7cb3d438daa68c1044 - React-RCTVibration: 0bea40cd51bd089bd591a8f74c86e91fdf2666c5 - React-RCTWebSocket: 163873f4cdd5f1058a9483443404fc3801581cb6 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 @@ -377,8 +307,8 @@ SPEC CHECKSUMS: RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 - yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 + yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee -PODFILE CHECKSUM: 2faf7ebfb07db0bc35d060386204981cb07de5b7 +PODFILE CHECKSUM: 9a1477d30332ab86b10fd2ec7e7842ad52b5382e -COCOAPODS: 1.7.4 +COCOAPODS: 1.6.1 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index a0f4a92e61a..9a87f5b136e 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -7,17 +7,26 @@ objects = { /* Begin PBXBuildFile section */ + 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; + 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; + 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; + 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; + 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 00E356F31AD99517003FC87E /* RainbowTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RainbowTests.m */; }; 03252948A60F4C4C87E4FD9E /* SF-Pro-Display-Ultralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */; }; 06B78001D9F2456D9C2D4A86 /* Graphik-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */; }; 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */; }; 0AB30EE90F554EE59F57DFC1 /* SF-Pro-Display-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */; }; 0F4372360E744AF4B37EB905 /* Graphik-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */; }; + 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; + 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; + 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; + 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D755E71324B04FEE9C691D14 /* libRNFirebase.a */; }; 16934DFE7F154B06ADAD8A0B /* SF-Pro-Display-ThinItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */; }; 184EB33331FB47F2960D2507 /* SF-Pro-Display-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */; }; @@ -48,6 +57,7 @@ 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */; }; 549287401A7648CCB32F36E0 /* SF-Pro-Display-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */; }; 5D1949044DCB413FBE7AE82E /* SFMono-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */; }; + 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 5F34DEED060F41878C4C5A59 /* SFMono-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */; }; 66620AB752074CB6938E956A /* Graphik-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */; }; 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; @@ -55,6 +65,7 @@ 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */; }; + 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 872630C5E4CA448D8DDC783E /* Graphik-Extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */; }; 87808B52A9E224F3D11532B5 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 823BD6129C8AA3FD7CDD46BE /* libPods-Rainbow.a */; }; 8B7F7FDAB33B4D119E087D57 /* Graphik-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */; }; @@ -66,6 +77,7 @@ 96E52368EDC94B9B80D1F29C /* SF-Pro-Text-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */; }; 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EA95F99E656542F790F685B6 /* libSplashScreen.a */; }; 9E8553031AD44F52A814F2AB /* SF-Pro-Display-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */; }; + ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; }; AE47B46652EA48AFB68E7832 /* SF-Pro-Text-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */; }; AFCABA638327463693E67FD4 /* SF-Pro-Text-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */; }; AFD75D0B6EC9465C92C493A7 /* SF-Pro-Display-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */; }; @@ -100,6 +112,13 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RCTActionSheet; }; + 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RCTGeolocation; + }; 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -574,6 +593,7 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; + 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; @@ -738,6 +758,19 @@ buildActionMask = 2147483647; files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, + ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */, + 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, + 146834051AC3E58100842450 /* libReact.a in Frameworks */, + 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, + 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, + 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, + 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, + 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, + 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, + 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, + 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, + 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, + 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */, 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */, 94822FBFCA7246168685FA85 /* libRNMail.a in Frameworks */, @@ -773,6 +806,14 @@ name = Products; sourceTree = ""; }; + 00C302B61ABCB90400DB3ED1 /* Products */ = { + isa = PBXGroup; + children = ( + 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, + ); + name = Products; + sourceTree = ""; + }; 00C302BC1ABCB91800DB3ED1 /* Products */ = { isa = PBXGroup; children = ( @@ -1137,6 +1178,7 @@ 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */, + 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, @@ -1394,6 +1436,10 @@ ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */; ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; }, + { + ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; + ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; + }, { ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -1515,6 +1561,13 @@ remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRCTGeolocation.a; + remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; diff --git a/package.json b/package.json index 96f644c9c35..3c7fc570587 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "clean": "react-native-clean-project", - "start": "react-native start", + "start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest test.js", "install-pods": "cd ios && pod install && cd ..", "ios": "react-native run-ios --simulator='iPhone X'", @@ -57,9 +57,9 @@ "prop-types": "^15.7.2", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "react": "16.8.6", + "react": "16.8.3", "react-coin-icon": "^0.1.9", - "react-native": "0.60.4", + "react-native": "0.59.9", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", @@ -126,8 +126,8 @@ "vm-browserify": "0.0.4" }, "devDependencies": { - "@babel/core": "^7.5.5", - "@babel/runtime": "^7.5.5", + "@babel/core": "^7.4.5", + "@babel/runtime": "^7.4.5", "@react-native-community/cli": "2.0.0-rc.2", "@react-native-community/eslint-config": "^0.0.5", "babel-core": "7.0.0-bridge.0", diff --git a/yarn.lock b/yarn.lock index 9bdfeb5ae60..1e4a415a0f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,7 +16,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -659,7 +659,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== @@ -1078,7 +1078,7 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.0.0-rc.2", "@react-native-community/cli-platform-android@^2.0.1", "@react-native-community/cli-platform-android@^2.7.0": +"@react-native-community/cli-platform-android@^2.0.0-rc.2": version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== @@ -1091,7 +1091,7 @@ slash "^2.0.0" xmldoc "^0.4.0" -"@react-native-community/cli-platform-ios@^2.0.0-rc.2", "@react-native-community/cli-platform-ios@^2.0.1", "@react-native-community/cli-platform-ios@^2.8.0": +"@react-native-community/cli-platform-ios@^2.0.0-rc.2": version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== @@ -1150,44 +1150,45 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^2.0.1": - version "2.8.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.0.tgz#346ff73ace6b2265d99ec217a8624b8735d19930" - integrity sha512-sN43IyvBtFtC1iOjx3pfKeo7DK4wkJxWiggR3QkkNQdyjuGT3RGXiYZVPu+zda6BPKdeGYpS+7UJrkGT+1tuFg== +"@react-native-community/cli@^1.2.1": + version "1.11.2" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.11.2.tgz#b14967f24a389f5a16889a747345cf0e5757a2f1" + integrity sha512-5NuYd30f5PCTrGUbZLnusZKv5nfTWvTDTRa/3Q4vwdMnUQrhm9sZXWGQ5CnFoQ7cE58EAqhj6/ShXeJF3DZ9uQ== dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.7.0" - "@react-native-community/cli-platform-ios" "^2.8.0" - "@react-native-community/cli-tools" "^2.7.0" - chalk "^2.4.2" + chalk "^1.1.1" commander "^2.19.0" compression "^1.7.1" connect "^3.6.5" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - envinfo "^7.1.0" + denodeify "^1.2.1" + envinfo "^5.7.0" errorhandler "^1.5.0" + escape-string-regexp "^1.0.5" execa "^1.0.0" fs-extra "^7.0.1" glob "^7.1.1" graceful-fs "^4.1.3" inquirer "^3.0.6" lodash "^4.17.5" - metro "^0.54.1" - metro-config "^0.54.1" - metro-core "^0.54.1" - metro-react-native-babel-transformer "^0.54.1" + metro "^0.51.0" + metro-config "^0.51.0" + metro-core "^0.51.0" + metro-memory-fs "^0.51.0" + metro-react-native-babel-transformer "^0.51.0" + mime "^1.3.4" minimist "^1.2.0" mkdirp "^0.5.1" morgan "^1.9.0" + node-fetch "^2.2.0" node-notifier "^5.2.1" - open "^6.2.0" - ora "^3.4.0" + opn "^3.0.2" plist "^3.0.0" semver "^5.0.3" serve-static "^1.13.1" shell-quote "1.6.1" + slash "^2.0.0" ws "^1.1.0" + xcode "^2.0.0" + xmldoc "^0.4.0" "@react-native-community/eslint-config@^0.0.5": version "0.0.5" @@ -1600,13 +1601,6 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - abs-svg-path@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" @@ -1800,6 +1794,11 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0: resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= +ansi@^0.3.0, ansi@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" + integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1841,6 +1840,13 @@ arr-diff@^1.0.1: arr-flatten "^1.0.1" array-slice "^0.2.3" +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1911,6 +1917,11 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -2174,7 +2185,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: +babel-preset-fbjs@^3.0.1, babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.2.0.tgz#c0e6347d3e0379ed84b3c2434d3467567aa05297" integrity sha512-5Jo+JeWiVz2wHUUyAlvb/sSYnXNig9r+HqGAOSfh5Fzxp7SnAaR/tEGRJ1ZX7C77kfk82658w6R5Z+uPATTD9g== @@ -2374,6 +2385,15 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -2632,6 +2652,13 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= + dependencies: + rsvp "^3.3.3" + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -2923,7 +2950,7 @@ command-exists@^1.2.8: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== -commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: +commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -3715,6 +3742,11 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +envinfo@^5.7.0: + version "5.12.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" + integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== + envinfo@^7.1.0: version "7.3.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" @@ -4079,10 +4111,10 @@ ethers@^4.0.33: uuid "2.0.1" xmlhttprequest "1.8.0" -event-target-shim@^5.0.0, event-target-shim@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +event-target-shim@^1.0.5: + version "1.1.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-1.1.1.tgz#a86e5ee6bdaa16054475da797ccddf0c55698491" + integrity sha1-qG5e5r2qFgVEddp5fM3fDFVphJE= eventemitter3@^3.0.0: version "3.1.2" @@ -4109,6 +4141,13 @@ exception-formatter@^1.0.4: dependencies: colors "^1.0.3" +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== + dependencies: + merge "^1.2.0" + exec-sh@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" @@ -4157,6 +4196,13 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -4170,6 +4216,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + expect@^24.8.0: version "24.8.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d" @@ -4236,6 +4289,13 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -4319,7 +4379,7 @@ fbjs-css-vars@^1.0.0: resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== -fbjs-scripts@^1.1.0: +fbjs-scripts@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.2.0.tgz#069a0c0634242d10031c6460ef1fccefcdae8b27" integrity sha512-5krZ8T0Bf8uky0abPoCLrfa7Orxd8UH4Qq8hRUF2RZYNMu+FmEOrBc7Ib3YVONmxTXTlLAvyrrdrVmksDb2OqQ== @@ -4389,6 +4449,22 @@ file-uri-to-path@1: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -4493,7 +4569,7 @@ for-in@^1.0.1, for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^0.1.3: +for-own@^0.1.3, for-own@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= @@ -4593,7 +4669,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.7: +fsevents@^1.2.3, fsevents@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== @@ -4631,6 +4707,17 @@ fwd-stream@^1.0.4: dependencies: readable-stream "~1.0.26-4" +gauge@~1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" + integrity sha1-6c7FSD09TuDvRLYKfZnkk14TbZM= + dependencies: + ansi "^0.3.0" + has-unicode "^2.0.0" + lodash.pad "^4.1.0" + lodash.padend "^4.1.0" + lodash.padstart "^4.1.0" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -4703,6 +4790,21 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -4981,11 +5083,6 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermesvm@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.0.tgz#4bfaf4ac682a2fd407b862ab641eb8deb232de83" - integrity sha512-GbP6dKaVW/V2QpB+DZPxcmhBhJVFa9cHS/xRX7FD1MGfa6Z1aHHD83VDCwo3SgcqNj5yHlVbe9UgrK1PFGCXpw== - hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -5428,6 +5525,18 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -5440,6 +5549,11 @@ is-extendable@^1.0.0, is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -5467,6 +5581,13 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -5499,6 +5620,13 @@ is-npm@^1.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -5506,6 +5634,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -5540,6 +5673,16 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -5821,6 +5964,19 @@ jest-get-type@^24.8.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc" integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ== +jest-haste-map@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" + integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-serializer "^24.0.0-alpha.6" + jest-worker "^24.0.0-alpha.6" + micromatch "^2.3.11" + sane "^3.0.0" + jest-haste-map@^24.7.1, jest-haste-map@^24.8.0: version "24.8.1" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.1.tgz#f39cc1d2b1d907e014165b4bd5a957afcb992982" @@ -5984,7 +6140,12 @@ jest-runtime@^24.8.0: strip-bom "^3.0.0" yargs "^12.0.2" -jest-serializer@^24.4.0: +jest-serializer@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" + integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== + +jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0: version "24.4.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== @@ -6050,7 +6211,14 @@ jest-watcher@^24.8.0: jest-util "^24.8.0" string-length "^2.0.0" -jest-worker@^24.6.0: +jest-worker@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" + integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== + dependencies: + merge-stream "^1.0.1" + +jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0: version "24.6.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== @@ -6099,11 +6267,6 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsc-android@245459.0.0: - version "245459.0.0" - resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" - integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== - jsdom@^11.5.1: version "11.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" @@ -6455,6 +6618,21 @@ lodash.debounce@4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= +lodash.pad@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" + integrity sha1-QzCUmoM6fI2iLMIPaibE1Z3runA= + +lodash.padend@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= + +lodash.padstart@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" + integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= + lodash.snakecase@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" @@ -6606,6 +6784,11 @@ markdown-table@^1.1.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + mathml-tag-names@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" @@ -6701,11 +6884,34 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + methods@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +metro-babel-register@0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.51.0.tgz#d86d3f2d90b45c7a3c6ae67a53bd1e50bad7a24d" + integrity sha512-rhdvHFOZ7/ub019A3+aYs8YeLydb02/FAMsKr2Nz2Jlf6VUxWrMnrcT0NYX16F9TGdi2ulRlJ9dwvUmdhkk+Bw== + dependencies: + "@babel/core" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/register" "^7.0.0" + core-js "^2.2.2" + escape-string-regexp "^1.0.5" + metro-babel-register@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.54.1.tgz#7d2bfe444b1ccef8de99aedc7d9330891d806076" @@ -6724,6 +6930,20 @@ metro-babel-register@0.54.1: core-js "^2.2.2" escape-string-regexp "^1.0.5" +metro-babel-transformer@0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.51.0.tgz#9ee5199163ac46b2057527b3f8cbd8b089ffc03e" + integrity sha512-M7KEY/hjD3E8tJEliWgI0VOSaJtqaznC0ItM6FiMrhoGDqqa1BvGofl+EPcKqjBSOV1UgExua/T1VOIWbjwQsw== + dependencies: + "@babel/core" "^7.0.0" + +metro-babel-transformer@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.51.1.tgz#97be9e2b96c78aa202b52ae05fb86f71327aef72" + integrity sha512-+tOnZZzOzufB86ASdfimUEGB1jBKsdsVpPdjNJZkueTFyvYlGqWDQKHM1w9bwKMeM/czPQ48Y6m8Bou6le0X4w== + dependencies: + "@babel/core" "^7.0.0" + metro-babel-transformer@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" @@ -6731,6 +6951,20 @@ metro-babel-transformer@0.54.1: dependencies: "@babel/core" "^7.0.0" +metro-babel7-plugin-react-transform@0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.0.tgz#af27dd81666b91f05d2b371b0d6d283c585e38b6" + integrity sha512-dZ95kXcE2FJMoRsYhxr7YLCbOlHWKwe0bOpihRhfImDTgFfuKIzU4ROQwMUbE0NCbzB+ATFsa2FZ3pHDJ5GI0w== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + +metro-babel7-plugin-react-transform@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.1.tgz#9cce2c340cc4006fc82aa6dfab27af22d592607e" + integrity sha512-wzn4X9KgmAMZ7Bi6v9KxA7dw+AHGL0RODPxU5NDJ3A6d0yERvzfZ3qkzWhz8jbFkVBK12cu5DTho3HBazKQDOw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + metro-babel7-plugin-react-transform@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" @@ -6738,6 +6972,16 @@ metro-babel7-plugin-react-transform@0.54.1: dependencies: "@babel/helper-module-imports" "^7.0.0" +metro-cache@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.51.1.tgz#d0b296eab8e009214413bba87e4eac3d9b44cd04" + integrity sha512-0m1+aicsw77LVAehNuTxDpE1c/7Xv/ajRD+UL/lFCWUxnrjSbxVtIKr8l5DxEY11082c1axVRuaV9e436W+eXg== + dependencies: + jest-serializer "24.0.0-alpha.6" + metro-core "0.51.1" + mkdirp "^0.5.1" + rimraf "^2.5.4" + metro-cache@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1" @@ -6748,6 +6992,17 @@ metro-cache@0.54.1: mkdirp "^0.5.1" rimraf "^2.5.4" +metro-config@0.51.1, metro-config@^0.51.0: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.51.1.tgz#8f1a241ce2c0b521cd492c39bc5c6c69e3397b82" + integrity sha512-WCNd0tTI9gb/ubgTqK1+ljZL4b3hsXVinsOAtep4nHiVb6DSDdbO2yXDD2rpYx3NE6hDRMFS9HHg6G0139pAqQ== + dependencies: + cosmiconfig "^5.0.5" + metro "0.51.1" + metro-cache "0.51.1" + metro-core "0.51.1" + pretty-format "24.0.0-alpha.6" + metro-config@0.54.1, metro-config@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd" @@ -6760,6 +7015,16 @@ metro-config@0.54.1, metro-config@^0.54.1: metro-core "0.54.1" pretty-format "^24.7.0" +metro-core@0.51.1, metro-core@^0.51.0: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.51.1.tgz#e7227fb1dd1bb3f953272fad9876e6201140b038" + integrity sha512-sG1yACjdFqmIzZN50HqLTKUMp1oy0AehHhmIuYeIllo1DjX6Y2o3UAT3rGP8U+SAqJGXf/OWzl6VNyRPGDENfA== + dependencies: + jest-haste-map "24.0.0-alpha.6" + lodash.throttle "^4.1.1" + metro-resolver "0.51.1" + wordwrap "^1.0.0" + metro-core@0.54.1, metro-core@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b" @@ -6781,6 +7046,18 @@ metro-inspector-proxy@0.54.1: ws "^1.1.5" yargs "^9.0.0" +metro-memory-fs@^0.51.0: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.51.1.tgz#624291f5956b0fd11532d80b1b85d550926f96c9" + integrity sha512-dXVUpLPLwfQcYHd1HlqHGVzBsiwvUdT92TDSbdc10152TP+iynHBqLDWbxt0MAtd6c/QXwOuGZZ1IcX3+lv5iw== + +metro-minify-uglify@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.51.1.tgz#60cd8fe4d3e82d6670c717b8ddb52ae63199c0e4" + integrity sha512-HAqd/rFrQ6mnbqVAszDXIKTg2rqHlY9Fm8DReakgbkAeyMbF2mH3kEgtesPmTrhajdFk81UZcNSm6wxj1JMgVg== + dependencies: + uglify-es "^3.1.9" + metro-minify-uglify@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3" @@ -6788,6 +7065,88 @@ metro-minify-uglify@0.54.1: dependencies: uglify-es "^3.1.9" +metro-react-native-babel-preset@0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.0.tgz#978d960acf2d214bbbe43e59145878d663bd07de" + integrity sha512-Y/aPeLl4RzY8IEAneOyDcpdjto/8yjIuX9eUWRngjSqdHYhGQtqiSBpfTpo0BvXpwNRLwCLHyXo58gNpckTJFw== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.0.0" + "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-object-assign" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-runtime" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.0.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + "@babel/template" "^7.0.0" + metro-babel7-plugin-react-transform "0.51.0" + react-transform-hmr "^1.0.4" + +metro-react-native-babel-preset@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.1.tgz#44aeeedfea37f7c2ab8f6f273fa71b90fe65f089" + integrity sha512-e9tsYDFhU70gar0jQWcZXRPJVCv4k7tEs6Pm74wXO2OO/T1MEumbvniDIGwGG8bG8RUnYdHhjcaiub2Vc5BRWw== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.0.0" + "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-object-assign" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-runtime" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.0.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + "@babel/template" "^7.0.0" + metro-babel7-plugin-react-transform "0.51.1" + react-transform-hmr "^1.0.4" + metro-react-native-babel-preset@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" @@ -6871,7 +7230,27 @@ metro-react-native-babel-preset@^0.55.0: "@babel/template" "^7.0.0" react-refresh "^0.2.0" -metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: +metro-react-native-babel-transformer@0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz#57a695e97a19d95de63c9633f9d0dc024ee8e99a" + integrity sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.0.1" + metro-babel-transformer "0.51.0" + metro-react-native-babel-preset "0.51.0" + +metro-react-native-babel-transformer@^0.51.0: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.1.tgz#bac34f988c150c725cd1875c13701cc2032615f9" + integrity sha512-D0KU+JPb/Z76nUWt3+bkjKggOlGvqAVI2BpIH2JFKprpUyBjWaCRqHnkBfZGixYwUfmu93MIlKJWr6iKzzFrlg== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.0.1" + metro-babel-transformer "0.51.1" + metro-react-native-babel-preset "0.51.1" + +metro-react-native-babel-transformer@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== @@ -6881,6 +7260,13 @@ metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transforme metro-babel-transformer "0.54.1" metro-react-native-babel-preset "0.54.1" +metro-resolver@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.51.1.tgz#4c26f0baee47d30250187adca3d34c902e627611" + integrity sha512-zmWbD/287NDA/jLPuPV0hne/YMMSG0dljzu21TYMg2lXRLur/zROJHHhyepZvuBHgInXBi4Vhr2wvuSnY39SuA== + dependencies: + absolute-path "^0.0.0" + metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -6888,6 +7274,13 @@ metro-resolver@0.54.1: dependencies: absolute-path "^0.0.0" +metro-source-map@0.51.1: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.51.1.tgz#1a8da138e98e184304d5558b4f92a5c2141822d0" + integrity sha512-JyrE+RV4YumrboHPHTGsUUGERjQ681ImRLrSYDGcmNv4tfpk9nvAK26UAas4IvBYFCC9oW90m0udt3kaQGv59Q== + dependencies: + source-map "^0.5.6" + metro-source-map@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5" @@ -6897,28 +7290,62 @@ metro-source-map@0.54.1: "@babel/types" "^7.0.0" source-map "^0.5.6" -metro-source-map@0.55.0, metro-source-map@^0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540" - integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw== +metro@0.51.1, metro@^0.51.0: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.51.1.tgz#b0aad4731593b9f244261bad1abb2a006d1c8969" + integrity sha512-nM0dqn8LQlMjhChl2fzTUq2EWiUebZM7nkesD9vQe47W10bj/tbRLPiIIAxht6SRDbPd/hRA+t39PxLhPSKEKg== dependencies: + "@babel/core" "^7.0.0" + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/plugin-external-helpers" "^7.0.0" + "@babel/template" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" + absolute-path "^0.0.0" + async "^2.4.0" + babel-preset-fbjs "^3.0.1" + buffer-crc32 "^0.2.13" + chalk "^2.4.1" + concat-stream "^1.6.0" + connect "^3.6.5" + debug "^2.2.0" + denodeify "^1.2.1" + eventemitter3 "^3.0.0" + fbjs "^1.0.0" + fs-extra "^1.0.0" + graceful-fs "^4.1.3" + image-size "^0.6.0" invariant "^2.2.4" - metro-symbolicate "0.55.0" - ob1 "0.55.0" - source-map "^0.5.6" - vlq "^1.0.0" - -metro-symbolicate@0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1" - integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg== - dependencies: - metro-source-map "0.55.0" + jest-haste-map "24.0.0-alpha.6" + jest-worker "24.0.0-alpha.6" + json-stable-stringify "^1.0.1" + lodash.throttle "^4.1.1" + merge-stream "^1.0.1" + metro-babel-transformer "0.51.1" + metro-cache "0.51.1" + metro-config "0.51.1" + metro-core "0.51.1" + metro-minify-uglify "0.51.1" + metro-react-native-babel-preset "0.51.1" + metro-resolver "0.51.1" + metro-source-map "0.51.1" + mime-types "2.1.11" + mkdirp "^0.5.1" + node-fetch "^2.2.0" + nullthrows "^1.1.0" + react-transform-hmr "^1.0.4" + resolve "^1.5.0" + rimraf "^2.5.4" + serialize-error "^2.1.0" source-map "^0.5.6" - through2 "^2.0.1" - vlq "^1.0.0" + temp "0.8.3" + throat "^4.1.0" + wordwrap "^1.0.0" + write-file-atomic "^1.2.0" + ws "^1.1.5" + xpipe "^1.0.5" + yargs "^9.0.0" metro@0.54.1, metro@^0.54.1: version "0.54.1" @@ -6979,6 +7406,25 @@ metro@0.54.1, metro@^0.54.1: xpipe "^1.0.5" yargs "^9.0.0" +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7038,7 +7484,7 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime@1.6.0: +mime@1.6.0, mime@^1.3.4: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -7401,7 +7847,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: +normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -7445,6 +7891,15 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npmlog@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" + integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= + dependencies: + ansi "~0.3.1" + are-we-there-yet "~1.1.2" + gauge "~1.2.5" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -7487,11 +7942,6 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -ob1@0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd" - integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw== - object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -7570,6 +8020,14 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + object.omit@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-3.0.0.tgz#0e3edc2fce2ba54df5577ff529f6d97bd8a522af" @@ -7662,6 +8120,13 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" +opn@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a" + integrity sha1-ttmec5n3jWXDuq/+8fsojpuFJDo= + dependencies: + object-assign "^4.0.1" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -7885,6 +8350,16 @@ parse-entities@^1.0.2, parse-entities@^1.1.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -8263,6 +8738,11 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + prettier@1.16.4: version "1.16.4" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" @@ -8273,6 +8753,14 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +pretty-format@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" + integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== + dependencies: + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + pretty-format@^24.7.0, pretty-format@^24.8.0: version "24.8.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2" @@ -8330,7 +8818,7 @@ prop-types@15.5.8: dependencies: fbjs "^0.8.9" -prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8471,6 +8959,15 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + randombytes@^2.0.0, randombytes@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -8503,6 +9000,11 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-clone-referenced-element@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" + integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== + react-coin-icon@^0.1.9: version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" @@ -8517,7 +9019,7 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.1: +react-devtools-core@^3.6.0: version "3.6.3" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== @@ -8823,39 +9325,61 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.60.4: - version "0.60.4" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.4.tgz#4378171e63dd5310497e15e54ec9185cb470752d" - integrity sha512-WE41lbGQjnzM9srIFtMDtMJkQAvk95iZwuFvAxl68s80bkYa7Ou9sGFHpeYIV6cY8yHtheCSo5q6YMxhdfkdOw== +react-native@0.59.9: + version "0.59.9" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.59.9.tgz#c94ee4fa35121720c05235a2dd6cdd2784bf5177" + integrity sha512-/+8EgIZwFpYHyyJ7Zav7B6LHNrytwUQ+EKGT/QV7HSrgpf2Y5NZNeUYUHKiVKLYpBip1G32/LcAECQj37YRwGQ== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^2.0.1" - "@react-native-community/cli-platform-android" "^2.0.1" - "@react-native-community/cli-platform-ios" "^2.0.1" - abort-controller "^3.0.0" + "@react-native-community/cli" "^1.2.1" + absolute-path "^0.0.0" art "^0.10.0" base64-js "^1.1.2" + chalk "^2.4.1" + commander "^2.9.0" + compression "^1.7.1" connect "^3.6.5" create-react-class "^15.6.3" + debug "^2.2.0" + denodeify "^1.2.1" + errorhandler "^1.5.0" escape-string-regexp "^1.0.5" - event-target-shim "^5.0.1" + event-target-shim "^1.0.5" fbjs "^1.0.0" - fbjs-scripts "^1.1.0" - hermesvm "^0.1.0" + fbjs-scripts "^1.0.0" + fs-extra "^1.0.0" + glob "^7.1.1" + graceful-fs "^4.1.3" + inquirer "^3.0.6" invariant "^2.2.4" - jsc-android "245459.0.0" - metro-babel-register "0.54.1" - metro-react-native-babel-transformer "0.54.1" - metro-source-map "^0.55.0" + lodash "^4.17.5" + metro-babel-register "0.51.0" + metro-react-native-babel-transformer "0.51.0" + mime "^1.3.4" + minimist "^1.2.0" + mkdirp "^0.5.1" + morgan "^1.9.0" + node-fetch "^2.2.0" + node-notifier "^5.2.1" + npmlog "^2.0.4" nullthrows "^1.1.0" - pretty-format "^24.7.0" + opn "^3.0.2" + optimist "^0.6.1" + plist "^3.0.0" + pretty-format "24.0.0-alpha.6" promise "^7.1.1" - prop-types "^15.7.2" - react-devtools-core "^3.6.1" - regenerator-runtime "^0.13.2" - scheduler "0.14.0" + prop-types "^15.5.8" + react-clone-referenced-element "^1.0.1" + react-devtools-core "^3.6.0" + regenerator-runtime "^0.11.0" + rimraf "^2.5.4" + semver "^5.0.3" + serve-static "^1.13.1" + shell-quote "1.6.1" stacktrace-parser "^0.1.3" - whatwg-fetch "^3.0.0" + ws "^1.1.5" + xmldoc "^0.4.0" + yargs "^9.0.0" react-navigation-drawer@~1.2.1: version "1.2.1" @@ -8963,15 +9487,15 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@16.8.6: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" - integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== +react@16.8.3: + version "16.8.3" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" + integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.6" + scheduler "^0.13.3" read-pkg-up@^2.0.0: version "2.0.0" @@ -9169,6 +9693,13 @@ regenerator-transform@^0.14.0: dependencies: private "^0.1.6" +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -9281,7 +9812,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -9465,6 +9996,11 @@ rn-nodeify@^10.0.1: semver "^5.0.1" xtend "^4.0.0" +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -9540,6 +10076,23 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sane@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" + integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + sane@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" @@ -9579,15 +10132,7 @@ schedule@0.4.0: dependencies: object-assign "^4.1.1" -scheduler@0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b" - integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -scheduler@^0.13.3, scheduler@^0.13.6: +scheduler@^0.13.3: version "0.13.6" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== @@ -10468,7 +11013,7 @@ throat@^4.0.0, throat@^4.1.0: resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= -through2@^2.0.0, through2@^2.0.1: +through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -10993,11 +11538,6 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" -vlq@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" - integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== - vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -11026,6 +11566,14 @@ warning@^4.0.2: dependencies: loose-envify "^1.0.0" +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -11045,7 +11593,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" -whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: +whatwg-fetch@>=0.10.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== From d7377d5ba9ef36128aa58fed93e8f7fbe8371ea2 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 10 Aug 2019 16:44:02 +0200 Subject: [PATCH 073/636] add back autoscroll for investment cards and small balances --- .../asset-list/RecyclerAssetList.js | 99 ++++++++++++------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 832e29baa07..4a42e218d9b 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -280,7 +280,6 @@ class RecyclerAssetList extends Component { static getDerivedStateFromProps({ sections }, state) { const headersIndices = []; - console.log(sections); const items = sections.reduce((ctx, section) => { headersIndices.push(ctx.length); return ctx @@ -378,50 +377,74 @@ class RecyclerAssetList extends Component { } break; } + i++; + } + } + + let shouldAutoscrollBack = false; + if (collectibles.data) { + for (let i = 0; i < collectibles.data.length; i++) { if (this.props.openFamilyTabs[i] === false && prev.openFamilyTabs[i] === true) { - let balancesHeight = 0; - if (balances.data) { - balancesHeight += CoinRow.height * (balances.data.length - 1); - if (balances.data[balances.data.length - 1].smallBalancesContainer) { - balancesHeight += CoinDivider.height + ListFooter.height; - if (this.props.openSmallBalances) { - balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; - } - } else { - balancesHeight += CoinRow.height + ListFooter.height; - } - } + shouldAutoscrollBack = true; + break; + } + } + } - let investmentHeight = 0; - if (investments.data) { - for (let k = 0; k < investments.data.length; k++) { - if (!this.props.openInvestmentCards[investments.data[k].uniqueId]) { - investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); - } else { - investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); - } - } + if (investments.data && !shouldAutoscrollBack) { + for (let i = 0; i < investments.data.length; i++) { + if (this.props.openInvestmentCards[investments.data[i].uniqueId] === true && prev.openInvestmentCards[investments.data[i].uniqueId] === false) { + shouldAutoscrollBack = true; + break; + } + } + } + + if (shouldAutoscrollBack + || (this.props.openSmallBalances === false && prev.openSmallBalances === true)) { + let balancesHeight = 0; + if (balances.data) { + balancesHeight += CoinRow.height * (balances.data.length - 1); + if (balances.data[balances.data.length - 1].smallBalancesContainer) { + balancesHeight += CoinDivider.height + ListFooter.height; + if (this.props.openSmallBalances) { + balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; } + } else { + balancesHeight += CoinRow.height + ListFooter.height; + } + } - let collectiblesHeight = collectibles.data.length > 0 ? AssetListHeader.height : 0; - for (let j = 0; j < collectibles.data.length; j++) { - if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { - collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; - } else { - collectiblesHeight += TokenFamilyHeader.height; - } + let investmentHeight = 0; + if (investments.data) { + for (let k = 0; k < investments.data.length; k++) { + if (!this.props.openInvestmentCards[investments.data[k].uniqueId]) { + investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + } else { + investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); } - const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); - if (this.position + deviceDimensions > renderSize && renderSize > deviceDimensions) { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); - this.scrollToOffset(renderSize - deviceDimensions, true); - setTimeout(() => { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); - }, 300); + } + } + + let collectiblesHeight = 0; + if (balances.data) { + collectiblesHeight = collectibles.data.length > 0 ? AssetListHeader.height : 0; + for (let j = 0; j < collectibles.data.length; j++) { + if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; + } else { + collectiblesHeight += TokenFamilyHeader.height; } } - i++; + } + const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; + const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); + if (this.position + deviceDimensions > renderSize && renderSize > deviceDimensions) { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); + this.scrollToOffset(renderSize - deviceDimensions, true); + setTimeout(() => { + layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); + }, 300); } } } From 293de69fad5e5b66da98db06299f69df251db54a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 10 Aug 2019 23:30:34 +0200 Subject: [PATCH 074/636] add isExtendedState to props of investment cards --- src/components/investment-cards/InvestmentCard.js | 6 ++++-- src/components/investment-cards/UniswapInvestmentCard.js | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 6e27accd7dc..bb8e1e8da46 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -20,6 +20,7 @@ const InvestmentCard = ({ collapsed, containerHeight, gradientColors, + isExtendedState, headerProps, height, onLayout, @@ -37,8 +38,8 @@ const InvestmentCard = ({ return ( Date: Fri, 23 Aug 2019 21:08:08 -0700 Subject: [PATCH 075/636] Update app icon, splash screen --- icon.png | Bin 1508000 -> 505131 bytes ios/Rainbow/Base.lproj/LaunchScreen.xib | 8 +- .../AppIcon.appiconset/1024.png | Bin 0 -> 505131 bytes .../AppIcon.appiconset/120-1.png | Bin 0 -> 12866 bytes .../AppIcon.appiconset/120.png | Bin 0 -> 12866 bytes .../AppIcon.appiconset/180.png | Bin 0 -> 24388 bytes .../Images.xcassets/AppIcon.appiconset/29.png | Bin 0 -> 2295 bytes .../Images.xcassets/AppIcon.appiconset/40.png | Bin 0 -> 3142 bytes .../Images.xcassets/AppIcon.appiconset/58.png | Bin 0 -> 4731 bytes .../Images.xcassets/AppIcon.appiconset/60.png | Bin 0 -> 4952 bytes .../Images.xcassets/AppIcon.appiconset/80.png | Bin 0 -> 7149 bytes .../Images.xcassets/AppIcon.appiconset/87.png | Bin 0 -> 8114 bytes .../AppIcon.appiconset/Contents.json | 193 ++++++++---------- .../ios-marketing-1024x1024-1x.png | Bin 82996 -> 0 bytes .../AppIcon.appiconset/ipad-20x20-1x.png | Bin 1264 -> 0 bytes .../AppIcon.appiconset/ipad-20x20-2x.png | Bin 2892 -> 0 bytes .../AppIcon.appiconset/ipad-29x29-1x.png | Bin 2010 -> 0 bytes .../AppIcon.appiconset/ipad-29x29-2x.png | Bin 4206 -> 0 bytes .../AppIcon.appiconset/ipad-40x40-1x.png | Bin 2892 -> 0 bytes .../AppIcon.appiconset/ipad-40x40-2x.png | Bin 5672 -> 0 bytes .../AppIcon.appiconset/ipad-50x50-1x.png | Bin 3616 -> 0 bytes .../AppIcon.appiconset/ipad-50x50-2x.png | Bin 7072 -> 0 bytes .../AppIcon.appiconset/ipad-72x72-1x.png | Bin 5114 -> 0 bytes .../AppIcon.appiconset/ipad-72x72-2x.png | Bin 10134 -> 0 bytes .../AppIcon.appiconset/ipad-76x76-1x.png | Bin 5327 -> 0 bytes .../AppIcon.appiconset/ipad-76x76-2x.png | Bin 10832 -> 0 bytes .../AppIcon.appiconset/ipad-83.5x83.5-2x.png | Bin 11802 -> 0 bytes .../AppIcon.appiconset/iphone-20x20-2x.png | Bin 2892 -> 0 bytes .../AppIcon.appiconset/iphone-20x20-3x.png | Bin 4261 -> 0 bytes .../AppIcon.appiconset/iphone-29x29-1x.png | Bin 2010 -> 0 bytes .../AppIcon.appiconset/iphone-29x29-2x.png | Bin 4206 -> 0 bytes .../AppIcon.appiconset/iphone-29x29-3x.png | Bin 6260 -> 0 bytes .../AppIcon.appiconset/iphone-40x40-2x.png | Bin 5672 -> 0 bytes .../AppIcon.appiconset/iphone-40x40-3x.png | Bin 8478 -> 0 bytes .../AppIcon.appiconset/iphone-57x57-1x.png | Bin 4130 -> 0 bytes .../AppIcon.appiconset/iphone-57x57-2x.png | Bin 8095 -> 0 bytes .../AppIcon.appiconset/iphone-60x60-2x.png | Bin 8478 -> 0 bytes .../AppIcon.appiconset/iphone-60x60-3x.png | Bin 12600 -> 0 bytes .../SplashIcon.imageset/Contents.json | 6 +- .../SplashIcon.imageset/splash-icon.png | Bin 0 -> 4524 bytes .../SplashIcon.imageset/splash-icon@2x.png | Bin 0 -> 10296 bytes .../SplashIcon.imageset/splash-icon@3x.png | Bin 0 -> 16515 bytes .../SplashIcon.imageset/splashscreen-icon.png | Bin 4082 -> 0 bytes .../splashscreen-icon@2x.png | Bin 10159 -> 0 bytes .../splashscreen-icon@3x.png | Bin 18297 -> 0 bytes 45 files changed, 96 insertions(+), 111 deletions(-) create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/1024.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/120-1.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/120.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/180.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/29.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/40.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/58.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/60.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/80.png create mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/87.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ios-marketing-1024x1024-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-20x20-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-20x20-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-29x29-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-29x29-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-40x40-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-40x40-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-50x50-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-50x50-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-72x72-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-72x72-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-76x76-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-76x76-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-83.5x83.5-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-20x20-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-20x20-3x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-3x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-40x40-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-40x40-3x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-57x57-1x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-57x57-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-60x60-2x.png delete mode 100644 ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-60x60-3x.png create mode 100644 ios/Rainbow/Images.xcassets/SplashIcon.imageset/splash-icon.png create mode 100644 ios/Rainbow/Images.xcassets/SplashIcon.imageset/splash-icon@2x.png create mode 100644 ios/Rainbow/Images.xcassets/SplashIcon.imageset/splash-icon@3x.png delete mode 100644 ios/Rainbow/Images.xcassets/SplashIcon.imageset/splashscreen-icon.png delete mode 100644 ios/Rainbow/Images.xcassets/SplashIcon.imageset/splashscreen-icon@2x.png delete mode 100644 ios/Rainbow/Images.xcassets/SplashIcon.imageset/splashscreen-icon@3x.png diff --git a/icon.png b/icon.png index 431aa4f0eebd1e1707cb20b5632609d53a041e24..f959168df57f4d5b39c5db1752828d39a0bc5932 100644 GIT binary patch literal 505131 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
mPo|3!~H zR}|tLDW^YzzfA*JbGUgn(SS)P{V4e8JQ7nda(cYb>4rgUyDVh#_4sfOR7*oU$|1da z-;$7@F@0w6=nx@3{N)w!cplEQ3vBv}P|XAZ&k#s1-gKE0(q>aN z#7uR`1@k*(@gNoBJfLz9&V+mzWAd&Eix_9TU~+kMc<3JBtK2kbi1Mq9=`9Bfn7I}N3@Fe)iinO*dN^ezM1wMY65D(PYa?R!xQloU;hDQ)6=UNx0JvNZ znORd(j_L}g>5LR6@8C=>KkvF#g>ztHcWZ7J_pJ<}?n&sHn+6H?dg;?Uq! znzR>1&QYV0;}kvaT3V?D^K2a?T#uf8FvcNKbjQ;;kPB4&-V&HJopW~R&WhkG51}l5 zZYHs(xoICFYM4EZ6W@`KecG*me%PNmAjZU0A=>IY>@eeup+K9m9?)#psqkbHt*1e? z&;SDg`lI&L90r2dnp>;jFy3sR(laF;oqGj|oHl_CzISY2KdaCXH_b+EoMAN}mQhoeZIXjulXUth6yR*jRf0XZY^0#<@xMZ%h zDQG}s`p5G!WX6>{GEgTC%}^1YMfDj^jpgCM(~(E|A;@|N7rn!a?zrk>_0Vnv?!MsJjyRrWyE9fk z%AQc*{)%P?L-_U*^tIRXsK@APqL`pfia<0{WQM~rMNt}@z1vc$5d(~a-RG7Wb%dxr zs3a%4L3{eDvLElssSZRXCBSIR?O??thZ%nxn0%IhTDQSeY$$Ud5TJV&8TVz=OFpmV zQ#>0+g9VUXISwONJ_9D_qay=kg;Z%u4T0x2smTOgj=)IDblsVQ!xEN08y)Y%$l}hG z==auhLXi+08Z`QYO%6zltPcxs#0cl61YgM}0B>kN5MJRz@cJ<`Jt%}aFerRx-2T?E z6I>`}mp2;8h?!#PP{p}ZsUY8iH4hWdYucwlIQxqlBL3rb4l#=3oR3?e4e*>&jEQ+S z{D(YpitZcEs27g>=f}w7L@WmTb?3>FqYVg_IT-~}Q(i2IAMG?L%~h>*OQmtjabv(q z?~V%`k61hv1})2G5img(Qk391m>+loc~sqc_G}ymBuVWwuypvv>=axjMGldxg25EKm<)s0<|bqH0Jo17BmC2@XvH$otT5DDa(Y!i(+>UW}chv zxf6Js(F-ARu#`bvYlMB|TY|K8@+dPz#BIY17k1MPZu`eW?^yAFN6+Q8D4kmkl9{fs zTdQf4x)ut9Qxn$kB7q`!Vjsvy7b(0Gr_}%|^}ArQPCI3|?Tcf1H#UY$uizi6mn&}C zNHnGLv#fB}I9Z>Qq^H!G2gROvSnKQO+Uv$-ys#oHLR$hauY}U+LFHh23pNB+_+Jil zd8Xe5jyep(r;=9WX(uP_xSEcyB*cnc5`a=)8MTb0vgxBF%c#o~IkCc7 z_=efXDE%M_S0F2HHh+sqTk>nxth9iZ0VPkRtMDruJKeaYda;Rk)(4v%NuZz}j2JD= zk<`}sOi%Liu5h?@D$*gR6Guyr2bKhMh_r$Js7-`4yys9+Oa)IRRU0gx!F|)w3$F2} z@HS84Ole{H2oTrsaA=kL$%g9PHg2*SF(HD8WQruW*P=6*K`oon1RZ!Rv|6e%f>m}{ z1=~A{7$9Z>y_g0`2OLN(@rdMl9gIOj_;2=LnMd__S1jWa#)TGzQz0|p}I zQ3?l&ApxKMZ3=XO9NdlZ^u+Lxi)s=jC=#t{yEpt<;b)63`6ls{-Xv--3Xg8oL1nFx z%1*gr=z1&SuqR6l;Snq9EAEwp_yQUnX>?Uf_+IN$z(Jx7sgII3&?A&vBs$cNkt&TO%H;{u;t5L#+o(D5|~C>%;l7 zTmKnD4~`#R9>uTZh%uRYvZyhu;WZxe&^(vVD;GU4bu3pT+8``zY$1pNCZFNJe5sNn zl2Kt3jn9w~1k$8nR7waYrJUl7$iT*+>v(_<{35y=N7Jnw7%5KVf^+cr&DCv#B)n!$ zE8$I&P8njO3z;g`6e^;THF8GIB|P(?VYMk=&_oaQ+UuW6R0>B{(*!l5ErupLFm~k_ zN7MvPJOyH%_(CzGkM$hZm_PCKLuX2ID4a_0Cca$GTTbBGCngp1gh z)^(?05RWXjzc&s=vYnTVX<6n-ah^}TKFMwX?pMYW(rcB891;FL_F~1k9=yfp;0%jT z)F=gcmgB>doul~8;8^4V0!oy}XV}Gm2y!e}9iI}i1F=bZ+jK^k6iH=n2Pg$Mjqy2f zHS8sVOv1tX$Rklf!XiA&@%29&tQasci^6j*yLD(-Fp;J(M=9B_um(`k zI4y@#ng|&cpQKg`1i84TZN;7|hNvm2%btmg=JIGWjm7ywLlBpw_DGvD!RdEhb zE5R!|js19Wh?zl^nc$FKw!X2L6D3?_V4*T&pl|>=+|OEV15&$~Gp7;LSWF-|A5=5C zRUzJa4sh@d&Zg6#Qd%(`y;w(@RQ13-XQD>r55G_+fmXfwwcPv9Z_|h!&*TE3ZV~IC zs02XKj=ILBl_}SX5}Jok+~d51Nby5V3^gQ$5t070TL0_+_+S59ipxae)U5BlNlI%LNu)Pu{~u##mKc`1 z?zWbBk)p{xGwdv(g{<8Dv$|MT9ulnxc+5-2HlGD`ZZL@8MkTD#H#Y%D*m9<+0gfdx z3oWt^f|{VAMzth4&VeXKD$1bt;hBq03b9~S#Mgyk=JB5(K&yB#!VamNfXDGTb+)+o zHA&frO&{o1D13@%KQZ=uTXfZ>zCLwj0}bX8tGN3(&l$vmG+84iOB~KQDQ%CFl>%t1 zu0K5|I#~+BUWffg5Lh&{mEk!|MUyUW8Z5Y*o8BnXNEB|83iBsCtF!?3F?xc% zCwc^DrW9?1geHJ|cr5tL1L-!hNz4^iFHM6C!%;2E;;4dRoryahArIQ7`RHMg@TZWf zj;lt|E2!YHbFBXJqs zFh6hy%z_6esmKNq*Bi?Fo!JL5D`X>aeqQv2*=SIDmvNrV#x5SCXiycor&$F@hNm*y zDvf|7I}tuQDc+~C?-nQ?hT)#;#f2Lt_fNJR2=w|O@#Aw zoE>%d+-`)hH^Qn)lq|)8uFw?x_docj0Z1r+>0XO2Fj}~Cm(vQXgPJ!JH_r5VA^RAv zx<*(!M?+|?R}VO&*oBg?Um|>0aabjqtf)J|tH_1i8?yFy#w(c>U$KwoTTVZ%NX|S% zl)^vG+8AG6;Uz#rqy7_U78D0ScxJ9`i();T+eb^CJ5dQI=Owd37Xn5b!Ycb30XXQw zSaA(9ovkKleZ1$h8X;2R%FrI;r!L)heyo0vBlBl6Wl&OL(v{9v)-;*JKOYHC7Xu3~&NrUGJ!W9pRZR})M~gZ^`Q>vLi$Vp9Rko-)Nbz8URFZ;ptSZ-8uo1rz6t zyCs*aCRUCUA2+6Ivma635$vpZlXSl{4q$?vJ6h#f@91NTxZ!lwGQ|M&&}PT2g*e~| z&k?~liiVdrQo!DLO9Yd(X7)rgV!(1u$P{;t;7WA>_#8{Yvt5`?##&PdNb$UG_DPTZ3=;|gt$-wX8LQYLtyFX5&WMw~{RFP} zzoc7m6}u+8Isf70RU7}Ro+@Beo0tWBN8_{~EQ%qH!wBHYbzv&10w-iBDa}<}9k@m# z^O$A~hlw2g zEXe=*pa1KBD@|AxQ@-eboB5|069hcu3*Qvs3L)e3LNFZTcfx*m>l^Nsga2dyPba^F z!m}<<@Pq{=!mgE@2=fnE?BRFCKn~p$KueddlTxs;@Pn!&XPVMNy7mVN)(9~mX>WPV zPl}su1!jbJX!RedImNU<8SoZwQ89d5r;HUN59bi%g2Fi0$JU7xtJ|ju)}^dPX>voL zT47}m(vISsL<^;5aHpU?Xm?=qh1ZjG)KNp)ayH)9!b@VtG<=MTn7nv%!Gtky_wnM0 zfkM-j6w*s)^`*RUmZzL9%t*w{mFW8v{&P!tIEQn7ItgQ|0@Fg53%XPPa#aEZaT7Mh?*F6gZIdKRavVV->R(SEqIQlmGkgErEOt8GR0)7o^XQhA zlB&!IceD5Og9JdpF{WlAYPqNVM3d%DM3{xf3-a%VI70D1&SS_#B}&X$cOGjH70$$G z2~#?C+TWrH1F532J_7X`fX!GXE^57*62|fZ8hID+MIbla>$XRLq|uZTg99~C(W}$N zo7AEV2-KGF<`o{$S_U?NGPk(Ved;>~I2ChL4XzU52kN|Y(F!YSvL5#X3Zll4&3kP;HmpBIMMXQ`N^bdOHasz3d~0n!zyk}Xi|N~~~Fc^4+j zS)r=;y9BPXz2D5Hw*YEz^g=58|L|s}z(P8kerMfDZ zU#Q%)GN0&2s>P%MNyQrR2pDJT4K(~_2Up-Iwn6v*I$37Ow6&$^npDp=L0N+{Fi6@H zSW=i5Dz}v#m~YMlyi|6Jp@ne8+F&Jz(t?fYjE_`#RQZbNR!-Yz+RTFDs^j}$wglZ3 z4NiQ(wzBw{m6Dkh!c~z#*(Otgk`Hs#xYH~Gb0UbTkt&mk>vz3V01KyP1$NK&AV1ep zOcDMqQyOA|fzR&@<{3@Di$)-7N2Cyfl?NUvTZ!4>&?&P!_6mEhIUYit8R!9Sv$8pm zH=E0;0Ai-9LI%ARUDsu;A_7=RB>sq63Mnx*@D)yEhq>P!9g7OQ*4x7l2&i5XcD-Ce zqlSlm3o7pvF7>x~$K8RlgZM>OtMJR!A>>MkFel5p6C@IB%6lfne+Z*~xru2-7A!Bx zvEVL{W3t8cG7j4$G*Cm?nr3I>u65-TpVWc2rT5sx7Rxv`$UII3i9GOr{xKiBz)xZA7zyDuR zBANOiZ&DRHFxVrR*Q+Uho0SF-2P8s1Y%k8GPzbr39@SnmLX1mVQ@-qXr6c9LKp>~C z&yn>FhD4|@X#`)tp;OL!>L2`Ew=(CGBxdP^kHm&o#}owmZZIF9aiBubZVbV8f_u*1 zLPYxDZflDcsdFBhPF4({QLU9+*@WDEQ0K^+?__+@If-JVbFDaAyds;t0JK^|PSIIA z2Nw#^#SvhQo7rWJR}jr0mdbygsv_glTUn%cjKVH)-NQUkL*N38MS{Yj4T3!c+7n#y zT__{q(|}Os-il=trHD3pnYPcP(H9j3j}+LHw$<`d9<#$^EA$w<7FSr<3}`2EZ4s8% zE@*`ixu90zry&Vosy8GnD|DI(c$wk9+?q0L=~sarQIx@#^7?*gYt-h}W-rXu?xs#4 zwEQ*5DuuO6QAZ4!U{wFGn+-l*fF{39=&k$)ToYLOp}TUIZcox*SuvsEi%oYc=EwwG z%ZphT!?YSX9kz@`xt?_Baz=cMscadNk<|S;*~cjh9LI^MF?`v>Z?8%3giK+e0T-12^)|Q%-lA6@G=*&hIFO;-CfEoCHJ-J!xT! zfmQlCg$z3LExMmk+hX8l%pw{}={UwbR`jg#{oqEA6`GJ^QtoR-u}o|*%fi?^Q+%Se z+W_MNElB?Y2bBKxpa1iJ$Iyx{v3ZX`i7|*TKQY@hYrE&;Uf9oc9GZnzN+;q+8%3l_ zY_`03#*#}r=cl;7DA4IBEFfo}3NiVJ0kc9&hI+g#YMqLy9;WveFsZFgXb8luK+ilR zr5@`!EoCVlqKdMF0eiY=0gHPYA=~AV_GivSCdfthEyg`EFEVVKsbIX~rXdcnq89aL z2oFpL&su9Y1V!6byIW&HZ;!AAQMZw0QUzPvG=>@V&UPvXie!0;#fnvA%97{_EoCb` z4NRvcH;a@VDzppvnbpT|K)W|!g&^mW)xpR?r~G{G!=;0;JCInIb7v_R)&J5BEkqaK zWBffDCOi(I1*#H3eKtwR*3}wS3xuIes%sBtv%BHkc8A|t zK50#d7%^$Btb1*l^3h_c7{hR;<>vLFJ3mZKJ~G?O?iJBqk+Vo_bwpP4$T{k4;y3dF zlK>^EwjA+haW@L99X=m08N{pjx;-A9cla?Gkjh#_q^Jksm?yPpGsB!gk7G=0=Us;2 z-y9CYnU&6_UN5vDTOG^RT?S!Q2m4vdpoAg;b~dU+j+s_hR4?6 zkcM2yEU$isfNKJ>G}jZXt;s$!xpo^)-`hPqBt=GFGr{%+ssbcBGdC6NI8F_h89tQe zgW1fi3_OE1wXfoqR$`HiStu=t#iSpxD5wjgXT?sfBFKLXt*Kp?%Q0noyU@2oC3g#Q z8PzQmKKD6ljL;~vX-XLi1|V(4*`n$aQ5qaB9p@v4EHlonzPj=9WEHh&@?(mCV$r0k zia#1)z!XU=^=>W9j;4InIXzS?5LFC8O+HziWgSx1x1Y=Rjb^r(+fsB|Z zosgO`?{f14&ejDhY-lNk!WYc(^&N7C`8V|lXVk&_;z6)II^@Qcf?xh2s}_*A+Xy~Y z4nCZ*u^@M7W;{>qH?cMJ6sjkz^th6-=wf**>NNUvJz{~0Spc;h2l<8uiy0zM^ZXpo zGRkPNU@Y@_OT5F~HNtRA!CbD4r4EEww}Fdx!MzcN2j&W|LjTsl@LdQm<3lJfe@ys5 z@Npwj)T)JL@^op@D#Yo_es_>m~X*XrWPFQfrXkU8sdhU|BlZNY9SV9mj_k9tM<@RFR-4I zqJCi^Ri_Nop|O8{?Uv`E>%z=A?mg##9%nrk72&S`cCs^sGn>~7Y7<+DaTC9OXKSZt z4YJ*9KJfWG8O$>%M}5X?O5+jkz8ToAnT2~vs0w&#AeULQ?H5n>CXLtZnbf=Q4;LV3 zvBsW5hJwr+0$7&!+A}>~P%tK_1yCP-$QMcCtdh7is$;7y3~dZVDKWlGohs$T?es&o zWQODAV9KjM3#s7i@CaUZU63jBTZ=fF&-Q#uNk<@uCP$r6<}?m94^vZBtOAZnW&)4p zwLnI*&uk4)XuTEfvo3sEws7?1K0Y*!yDBCdxYm(-ce~%$8}EVFl1FxCNr1UG!@AIB z0~}gd*38Cv!Ua+3<1I;Cw0}Msj`t<3%Z6XbelW#gN%9*um&%{Eh;`U|Yp^hMmS#`1 z0mDfKx$+0K0dh6JQQbmmBIuap4IG)(aUM$`36xHesS}qRI~O=Sh3a|O&E_2SDzNdy9R{Mr4LtjH^37vn z>9qG&@m+Z2VTFM^OgLim;Cx)b`0cBt3ceQ8gmq)#u~UX!=9dd%*@gIR{A-rE242*} zhTlVF?PIjaQ8qZGkFSNoh@79V+jD(ZLmReBDmQWvSYM}h6!=>xZh;mbhb1Oby*a{d zpd4Tnz#P&8c8C(gMzFFLm}J`iN$O$VV1WTULokG(3+%o?hNzA9$GcxzuCRwL=8@m$ zaXr~4#UR9j1DM?eGZCSdFc9$Zbq>*cBtY}A+F;RszVF>%uUE&4>0!G% zzPDK4*Fsv?z8V@IS*>>?hpnE$`(9XGFNkT4L5J8jUUvff-okNX`)8#!%V3UAN_+q> zK+wN?i8@>SK+W)Ni{RT*|8=G3_!Qp7<)-`k3aUSGkiXs3kD5D6{$-G^FmU~q5YEW! zcf-Twy;s=nt>9P8I--6%`mkI(VN&&ya6_j>zcAF?U&wm-V6UXsjqoTe9~jxE0r&#B zVQVijgk1HeB(aT&tN~QN5q5qMu;$D7a&5An>v$k9F`Q|CMZX>e_;)Vu_nXAjRaIX~YiyM0Zzwyy;d|e@4ihMjg9W=) z)O$C+i`|!&6Uq2}`xW?`rkx{QSEvGeqdv9QQyh!$w;P@ZFS(S_m`{n{Powvl{N8S_ zpO0CWzZtskoDW_#5VNURs{gHy-FwBqxS%lUzIR_2D}M$4dfjq(`mK+8JFyYB!^5E< zNNoI$rTGuH2H>$AmILJn zkNV=7HV~4_SpHvh=y=OK_KP1c?DxM15#X13$QKAXo)R92i#+xfP8|Qp44PginmqM1 zb7$@6KHkm8C&ljD7k#3t%iPivDB?H7{p(LoU}l2l{O$ePK=}JQ-)>F(<+d!h<@0C4 zUx4~AkAjhsk@ehP_6gz}uy35-V4Vf8#U`fzo9?=Xbd~kxUftw33r{}Z`*+1E_gj!7 z4Y|T$9loT27ZAfoU@65kv@mh6$IIeolK2bnfr01kN2u0&5nxiQP%TA5U5tC_g`*(%xH|vovsk{|Q9^a1czeLu)qPE;1 zAJmde94+hbUrMWU_|BS<@DC_q6g6D;{2YmWs*g6<>)g%H8&m#abmCk_Jg{WO&2Hdj zAoBgd$6sP4zg~0vSe)@uikR2x=N#dyPx`weU|rapW0rAg{L=tnN2lU<D+_0>_iC|oI z|1SqSv;2ait6n!ORp(z^X8OeJ1J}1g`7Z})CY(Lx`(F_)FO&B7^6db_yK&t$k6!9L z2S`wVKF{R85X~PhuK!b;DAz)B-f$d`P=AES!UDgYiChFe_B&6>^wG;x|Jk6P=s)ob zPNvk`l836Lnx7Hh%}^h=bN@E|y>iP+vL^D8%0}S_E+2+HgXoaI&gNeE;N#)o;i)+| z9~giB%X!eG0SA!upr7ByH1YR*Z>bycTo`p{CF1z`r}5Um$r|rb$_o9F;Fx>^Vk1lt zmvhbQr_~RvYXY>L^NAHr{W*a&-P_%bKZP>AY{;QY7GBU zbG3R{-WZqu;pabDDTPwT)${JSEoKT>9ETGtHp7X_;5ZZR2Kwh*q&;0W@JEg+Or9av z%b4l>88?IHZ$$w(&=EwGz z9On^VCpT&yhJ9Roc9%VV_SuvN<@dtc;{tzcS(#e$&+Wx^c32MEyS(-mV(y(jaTcHg%CjJcc^Rqy6 z4p)Ly@0Ky?&3}Dya(oQ?qyr{rtW;<}d(Q#teuwv9KwK`6$HU$Wtnbj-+%&u^klU)h zS3W5pi1G3n-?ru$#zYug+1pH4avB1t#P=iPR*EP3YqzNv6XZ>D+g)L2$Med-I5Bw6 z=~@pxK2C==jeY2YZ=`2!h4=cq;&lbI$x~SVxxbUHgNrRi>#NlrA&VTyL0;VP41c;Y zrOEi2%yH`38*=)q@Bvk6^$XqY>m*;4O&Gi9J|8kp23Va>R9vFkbTaC(rX3hZGtAjk@4Wf*?Bt`0XJ5YJQwt<@sW?{zX(o1d4XO_ za=7FVY*}PhhhHp{ib9x#Bwjvl^~&YGeB5id#3QXzW-_{yN+tD~aJ{Oy_>3~~*YtW| zf@=IuP%a3_J*9cR`~beaH+HlKw!|R!&?&DcFIq6(Y4}r1O-muyb7w zDC#knnbBPAM-~dl)4y8< zLS7pRF2lRp@fv)(B>=6A%f?A=1jH!`&4CARL!=Yf%)J#>uo8A zVECD}Uwxv|dj$K{A6S!t8;FnP?MLVvYz4bV9UR34#^LCvN`sV%&L&8=w+u5V_yoohgfW^72gP4;j>m@wOa7H++DD_27&N%AM-x#0Ckhv|cW;C?(jb~-_%Hf7ORfAvLcDo6VQqW_n`fSm4AO>KQhsye`=!dI zK2lNxL=5d+1sY`FBRkTm#rHa?H0?H&5?RVTPnT;a0)G3}`nx!f=6o+dG7=63LViN? zp$O7(8BeoD)ouir+VP<**m1~L-Je7NRuCM}(np^)2dBDW=qA3>HfEU&r(LPBGp?$O z+TRT}@ANQuU?43oglk#2+sEBClb?B!Km7B<{=~1j^O@tbpr$@!)-%c#2u$l^*34=Q z4knYq^2$#nJ>h|1AiEbp`%P4QumRi`7Ohni;9MPdSPy*)s$W~Hb=cRjN>?sW@$-9N z=zeKMAQ<-nYXrFhx1Qc#1UH0Fm8?vxz`zEMgPx<`?W&LV4>^bJO|$deO=rkunA(!n zmxtc7t#I~a(bvLz9cbs%2kKUn;Qn5K&Hfa0hALzr7cAVD;6mQqLtkozyr(pfnc+Dx zym{?@)w0HWMYyo4c0&#L?&ip%77;ACeXI&1F*nOxi-#5KntvR&(>+#Y+YP_ zwzVbHlgg1sm-)ykmohiJU;n2SAGO*J+3-n{$DkeLBww1KR`6H~s{JRI>&@=kMK8|g z4k!EbDOypjk=XAWj*qfY9oyQtFX z2kzr)CG#q!31VgLx>&+Pcy_=n7 zN+`;(lx{ME?kUC(ujZmx!%%D$1N22+4#2x);e+|SD{t+&BA1p1e4@UVRh z23aI%AQ!wV8XetMq*>b=aPz~~D478%Xpv*VD{lZi%%bI8$AiUW9$>RDTtp&v`k|r# z?`5_d1#{0DWEor<3W}*!<3NA1L_6g(R%9*IJBsuV6l{6F8(Tjg&hG%^25(W$J=2nH zD(g78@fd2ePfi!*dIy_r(#2M))^r6tWT)U?xm1``Vbh5%uoE6XoWe+t{typh{PiA3 zdfYClByv=Z{vhyzFE{u`9`yoMe}4F%aiYP0O@PpwOv9QUt7G6U+t}AGJuZ#w*3b?f zOI;fyjOT>n%>5kLhV2bbZnyTZR0GbjZPZHifg7tC#{_BvCaD!kAMIdb0Nh%&T9XoJ zC+rmwi4>A}I04Rq2aF^(G;9*D7 z1tPR>oI)&kEj3Se?%Eq*;WIfqF>n9YWIJkR8r+bGCIvAU1WpOSF7rS=a0%}i=hPpN zJyP~^Det5n`_i(q=X0Q-A-`ajvK z;_Xx~qwK1?h^%|`Yu>Bpv!|FV2!oZajdh&*5PpG*={4~fQ(TU_7}DA<>pak`IX+Aj zei>Qp@Y%6DDwYSgM&Q?y2K&EBQ-#F z&}9Rd*vCNwP#8>L5M7vPSKxqitNIw%(_gywZlB!S@-O%A;#bi)DW{^wxXD;fF=pWn zlFlBvJR&0>vd7>KwJ_)uEb85-#C@lqO6jUrhF%06Dx(3xrDV(YJKTsi)AXiIZ70IlV!U90 zvbJ6@-5zthny9a~sp)_Z=2;V~g#(9H%$V=c**Vsuv%xueiiLvHI)Iyrckd45@fwxQ zykD0ie$QZ8zt|#>_%x~ytOcr#k;rsE-N?JD(epImFr?fZIoB}Bh2zF4K(VALIQ)cSL7vPHFb>yxd9LVcS zvRE;d?Gpmmf*vmPC~LRTyy(;nJ`lg?WPs#k)Kg>fs|UwlbPLxWWOmW2Ey-@7zFqmt zAx3K^^!~!=E@tiyA3uDX-CRz>K1I1OTue6Z)18BFv;~WB;0}#pI|&{_Uu+n(725oDb(3UdXE{)gHGM2D9hR2b@;cF9A<8 z$<~&$o{!z`0LF&mcGq03AB-tAZk3Z~fSx4N%7~sd?6VK5tmab^G#~Os36;yGZ&)^i z$IZr)!c@1{Dsq&`3P@+{KMX)USPWuLtZB;xh&C>)QB?pl(W8}2skS}IB`^2lXUv1l zdP{X*2vPE8(XM|6?{jc9AGCs=g{}E>QK`?^aDk{7PFBqye70V%Mm*@0Wu)wWn&!Ew+x(iXZR z3_KpAdl4Rm!obp>cpBI0?%@FKSm~zE!Ky1Ci_P76-sN)mk{dWgHFLwGJ{a%lY^@*YWTHW)#^FRTUbf2+D6<2$}#pDSC&RoJJ&r}=obO2afFv`|N^kp`%5{AToOZ$S+wr7RF_5ucA z$AMpR#^m-xyv6}pbka-k^64gc6ZLafD=#t4-?+hHo3)eMVHgWdEmnN*Cm*jTCtX8j zh2@G*R#INGI0o=b2ZC#U!+QksHN`x~*%HVnVO z*i(K3>R>A{fCw$RxDDxYK|ZCWk_$a{Xb!i!jh3J`T$>9>oz1WVzfv0-ow5!sFJ41w zM-8h>NxWiPu0KI9S*H`RpnHu<{E_Q~YL9tJDkL$YUzw);a<;lEvj6x6zVeO*iQ#KiVwN=9VaUF}Kkf zssszHiRrVWcGc950k%z?d)mnLm>J`r$94mQJdw4d_FT(0qd!lRrd*_`8!h4VrrQQ~)BIkIIrD6u70yV8!L#N&TdBa|5u_=AGE&~T^7 zdAsfu%=;U*H9zIx-oK$G`dFvv->H3$rSd6J0BYjd(t3R(n?I#67j=rGy$(IO9kWIq zs2U1282qoZv#4p2?xm8v7f8K~WB&$kDlq0oAjr#*zI^JP_FwJd+SI$KurSj(9QGCV z7{|1D?lcnv*ZD4fOqemOfMjr{9LE4hDM^38lipm7k>UI`bAiPqw;aKq9x$n!`IxjZ zfFJnGA#YXNapKb$D3upr)ZE5h3#V!pNcfeY30E!$S1@`X?i5Z;T5^fiqVXtmVJw6D ztXg?3nHBZ!gLZpvpq-r=^MPek4G0azF++R z2(0*YI@)^i7ouMqU2aC$+|VYjzw^#@+mnkYKd2rnH)EKDLpS_VH@Hukj@wb$LqEy} z!ulxM^jOAA%JHxu=njcJph5F6&s(p|=pC=F`!<-&?lV8qG?u~O@vzwaEg)`qK!E$d zg@**~N#|)X3^_ux4W`Y(0?GnyUCk{W1@Tf<>Qa~_pRiu*A?rP(;UM`d~ z`LxG}7F-WP#08+Cz09X1MWzfRP=B^19Af<7bgi@{5(n1Wk{7X#D>2U)#SW$^iX=Dbj$U&FB-W+M9`Ix+`d%7qL$auGN4Seb7|XeMqW29$2FsC00eby|@&FOWsd+BNU zJ9Oi)G1Lv)#*hH8M%m}P6;l+%$*bEou~~n{Z*57GjZ!Yqn9IJ#CNe8#8ap!WSi9P$ z`GMi#z8vV}ec?cQk(f|Zwe{;|$B`lDCT)6EDDO0>E>0_?P-Y7K2v+9py@IxN>(WMH z5ndsZsh$){ygT#>msjdg12%$Swv96AO!}M#lv)S>2(-Wtu1p6U=s3_F6#cSwUAdnZ zLve*qem2Y&9uNO@t_0JWZ`MA_+m$uGMMP820!<~4iik)AuC~xisT(FndvB$iGfP^D znH}KO-mweTz7ism$!qUhW7i3|$n3Ydm zJKI1yx}ps?Ytm)c)~SbQrg0NGxEct*sVhTtt-H?oAgpEKvOf|vCs0{lPf!LTYwpk> zMlkKgC*&*vYY!$z@U4;=RHSmNknGte$P`0LWHJB z2nJR6()G|on$KYBVWQ=M5Q%6aF?ykDbxf_oX3v1yum)A$-Zb+irp1)5#Nx=5 z*1_nQ94*TG&4RN^Lo$lfqL0@5&l-IoZjEY!y9P$T-9`^btqC~heYrcyZIr>4trfw@ zZIaIrv08ZNzD1G_k`$T%2HVC0+Wiy5oYv2s83V)pkrpN!FvIJ?`2Cm&?I4zWlv z3G{G&Au)#%_#(Bz^yD1B7EM$_kxoo~5jM(~z7=RL4_s9VI=3Q3E2r|R!Tz5w_Gf`_ z6$7K55t{?vI>TYclC&=g$hN0%_44({G2Ivph#)fEvtSw8Yz4^_i+c@u&w?rM6M~6z zDoZ!HWeQ>I;e;H~bxfz~Y&CER9{ALs`e`>O+8&3NWES%@o0jn2Ike5GLP4u`dHl4* z%i*yT=mCj{lz`idk9i>XvuBEGNY$8lCU@YDY)_-b2N@~Z+= zKw#noSV9Ue<7^!@=b?s_na%9gWs)7jp~DYo$^aQ@t}rzQtM)x5U>{Kuv&|!Z zR3|A;XmEkYZHQ2YaH@o+#Sx2$Llk<6puC0~YBD~EN42;!-h+b}tW8Acy`SF2oMY2? znBqM3HXnTBE~LnLN4e6PFBHOvSq@dbzO|Uy(Wiv)`j@|+z7!{DHszOW$b$nZRwMho z96913xG2aD*l`dLj=>==M+fMmaZ*Dsie+Z87<#`sxSBx2D=pL~fH;+G=ys8CoLY+M zE0MUUa?FMW(54pL?HVvTC2&NVyG#i2#o=%Oy*;Zfc|vHmrO_F6e2m_4MtWH*V(4=U zv!}{21c#pn0EUp6MtH=!g0ye*kdP&$yH z^_%|zsB$LVWq6MRGFJ>-Akic56zB`V6?+5Y^pH+%f_Y?j>Tx(ZjxdL1B0OfPY4Ls{FAKEJ63%j6GXsHghqvS(>B#Fuop>UoEd=YDdeK;1G

iQ4g?M+*l|#xcDVieX$_-dcvw_-l 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

`D^wi>e1M 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᎗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℞t1?VA@TQ(NN-%X92`xeXjyW_6wi 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�ctbI-WDVN%ZdJ%HvtZg z{`c<*9HM{6Ej%{m0L{AMwH6fl@%~bQd3_1TbNpHlH`L{N}xhl&W};frO4}MR{G+0Zv+kh2*L3 zsC2eGd_dfN>7=lhfApnZ7aA z(O8^>yfSmmz#)wap zWYA*|+DHhsCXqZh7?rMB^8PaQ7qw`^#EY5EftZ}T>C=G%WU~d6 zvZ4st&<+w^thZGl?!h(v+rHZlzq`X!z)?p67S03MGWEahGzxr-VF24+(0{>EzDIh& z4v!!318Ofbrpw<}L&sCyLoFe=wlid*2cf6>ECv++H@X)tK z8Fp+0Xkuhi$uCtXo#<6M79$v<_z0<$)Jd6EAT=DqT=7oPSFJ=N5Y>L!>14_WP*+KY zq+V<0;mx#ap1^%>WrL9Ngkj0>QE6G@n}}JFJc}Tz9k;TS!-lTaX@)-!3^faQR44Lnv?qGV@}DOEs75>lvua7I1yZ-TQr+yCt{g2HAmQ#YKg8s4h3obt^SVj-d-n{$#&wcIe zjXSpGWU!!88@l~;4xy&6UpN+QBRk85_Mm&C{Nr+fxet93F1Gbk8|V<%Blxw~>1D1# zt4E$Y!JmBnM<1I4xeay9!-{1%0y#OR40}uU!_LhUDUe2d4J|oqG7YTK*#WaqmWh<` ziFVlQcWKJ8WhpTg)>a}1B&Rn-p|L`3zxgwaW18|O<03WMX=$(2 zdS|?cxq*Mug(MkqVE0vPA`PSZ*m863d?No&L8|n8QZ$u|Y14)Q*Qx1Wel)XB5Oo4L z3{sQQL!xNa+?*N*=8#a!uuhJ2H#F}h_LOT?i}nUq6zSu#OG~2~87@+nC?WOR&I~s! z;Jpyff;z?W37wpQvD_GiW2RXg=3$i+rGt^}2O+@8&X?(WA9!;rqNCF}G)Y$*X=Wk` zL~T7ym{nMR$X3YG(}#)ruXa?NXh}_8)>nckGOUp$gv^djpy>S2b}mD*<~V+=JFwDs zN?!!7Hk4*fBJEC6%T}gC$ZDeHRhLj2g0sq@<9UEyOgCUpVsJV80GBfjz;>bpPX+y7 ze2xF&S%EFx8@T>BGx+-FzcmU9Sl|w{)FE_`5}@^C8+eH>u?Cv82i+zj;3;r`bwJ;^ z!&7Ekd<#YG%gX$gh~KO+=wnl$f8({EJdsgxzd`x{pNRtt+WidL3ujWEnJB)+wwrp{ zgvFd@stM*Ao>rAj8xVmzS)3=eH?R4+I_;-{P|THT3oAbq)YagU&jm0K5kqM31mDnU zp#+mKbnAwZUwN{0*NS7

#k1#m^|SH8INc55-_6S&HxmLaO&@4I!iqQYL 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
o(D1LzoIP*iIFjW}L6 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
nX1ek-Be*j4%W+L<#lV#Wyccv34BE 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%0Dj{EsZf$n-Nv3kP~<*7;B!~ zGI@u*ph}p77Nc@v3#Uo&zUaT^F9dhvPjz*eW{0;qrd?iylvH_jA z4&DSJcPCRGbJD3Y!8tb430ROBTJ^)ZlCV;lMKd?URjLcD7xdaZ(i)+mchnHd7(>e| zSF>tDR!J$sQPjCB!E+Q$q!pB+N-qmcO-rqY8WOpOVsY4*Pt~HZMnwXj^1YE7T^*P; z3Hwk(9@?#GbBnqFcA~JhCzw8#(tl%6I^ldrv74{FT(LYdMj?kF04y(G77Z=ycG(Ry z!4R5*J#5jDhsu@)jiQEHn3AQCk;gNgeo2_0aP?g^-+)~{eKN|SOLCGuFC{#d)qWX; z!4L6cqNE;-(a(UiAk;9p{1fC6x&dS!KRwBS?9Rbvg*qC~V=940h2pg!BJ2eaD zidC-@tJA61k>I=^xZscy;0S8IYOR9<2>nGe-wS_v^&i}l zMB~itWj@Jq_P)pafBo5~*A(uLWC0y~i&+h?+D-onDI?-gh@z5eU6AB#agX z#zSQceq2=m!OH~>Pm496ls@05W|~S_0q<{CQLsdk1sIUo)aZJS;gPc)E65vrzNQF#*}O9_296N_ktMt$AbF zrPYYTFPWbK8gf5LryPxu%MBaI7=GLLx^_3JxSs=Fu(2p(#(JYahW#S?=~Lx^+fdog zS)dIGSY2Ee_Dt6dqudK<8BfOD>H zK99RUE)Hz7#D5|kFb<3Y{@FY4_nw8q$EuBk^Y%x2qztE80#?6`GMAK<0^;PsAa$2J zUt&e}Mxzo`74E58pYyf?Ly${8$+D=)@OtT`bkLCskUsyJ{e)5aN9^bv#R zCl#Det?iooj_9z5*A+DT5h2pRU^pAXxUcHz)$ZWPr4ppt1D@IoM=}GUq$$qT&94=X zD+CGE4UZu~1~#XP{)QcE)NWEC)?TLj0VuaAB_rZSU(^|wtg6e;8rfrX;zsKPI^>aP6Pfnuw8=v&482~j%Or(36nV8iO=@Uy%j^!oax~J1NSnmTEf-bx zkv@iNn~~pSp64~%{cN*IA(pq*64Gx_WEaV4M0)&C`>z^_X1_1_Su&agryHJL%~MD_ zHn*+LioH?f^lvS}f?6*Cz}oIk85}_N1RqWnHFUU@v7{=GhOP9fy*wbKZ$TqDvGwE* zy7f)ZwABCYFYkZ(H}?!Hj}HOPsDZB=0^pJ%05*#IZK}^Yr~j-$&^VtYa6T1yW&w>0 z0s-RdKRo~7|9SQHle2&>lK)--|G)V;z>~uNYo`m(cu^WamaPY{cJ4D<&eCIc@Nx{E zh2f9L0M=PLX9z#?{YUG7=NFmVfdA>8ueHB-$cC85|3l51+b&T?b+8T1?vZphVO3Bf zMINdnEjxc(Xf&cosz%UjEf~=VGR*IVEBir0(4#TL+Fw+(wAysgkx_0fc)sw_IpQ?7 zlA)7!sj*g>_|?T&!H)IVrrVP`=*Vk&H${hvX{Hvbqr#S~79{jT3f)ItPptwVW=y(D z?7Zr3k~*-0R9VI5)+$=#a!lU;D@P*YI3?lX(y*4!8@;vk zM?#xHYKtPL5H@#m=7_hUr9erCN}3czNj0<{rkE_YS^|c3Ns_M*3X|qlL?=0F6UJ+* z7y)4fjml-VF51qOOi~cC2(?qrPYgRNLgXAUP91C>%hLTzAc;`lB#?v>EHT!0APlwh zoEA}p&Ig#vZ0bDWJcs&GoeimHcF5C~i6}LKp zZ9AY%)6cWhfNNZU4wHy>nEg+v1OCSS-Me3TUy(;>+@-Aag~$U9%3=9vFV#P3Nd0sJ z<~~9Jg$Knv++N&1jMo37>^IyqL!e1Jd(?etmfi-L_Dw~93q`ZLAzoK9a zR!NlJ>@3q=yuw4usvgyCI_z|hfP74&hZ(-L1!wM zov<_vbhMKqia=4-nCy1D64N7UPPA2^TZrtitYll!v?NuSn3XLIJvNR8U^4>?rZpb> zaH1_zB}1O;k%j}I5tG;_s^xYdwg#lr2vG)aY3K__CBlnTB{`fF(!=!h(W)P4=s<~%GS|M1!Uzxz3_EVsx%=fZ&B=n&xC zG+=C3`Mn_-NBuz8UvNhoFwU3$+-F;z4+QvEDg(Hb1%zu`f=eTTuVB|4>;xY3^=4%N z&p!R$5gEYal>jRqpyW2p|3>4$RvUvit^?j2q`cMv!_Xcr(mR1?G%}}0AVtKMq_HHI zfUTl~Mdko)4Hv7=+|JD|qBNL_n92StFqK$wARPwFf|L5;u;#_#ydWbM!NYc^^_*7V z5ipf?I$4CTBTP(@mKHv0!Txgz1$d-f(bL#JrRsI9?_^}J&?)93I1NWa^^Bob{|=a1 zYXoQySt(xjaH8+=uz`OX&N>-HLnMat|4U&zJ^98-kl_Y&cA&rRp`VMHogf| zADkzw5l@h60yK=@m`j@4(fW!eaWM(CcL*+FUy0a)_#u_cdh@Adg>)4>ud&;8m8(dF zHh7Iy2GeG+Y(_d zHvn5LYb-Vq8{OO-xm<#s(8Upy*J_<%4a&t>yr4fc$g(cP@|tJl~N4Y?a9E7hDE#1av=N7C&(u z*f`cUocZMAjpPA;^W9Iw_0fj=^y=EAmBMLgk}<6=ihv!d^+L-Cqje6Y^j0t@3lOKF zcoIKD^wOM`>P7SZ8RkMqilS{eHAJmxXbj{Yx!FhVpv4=*jfFZpM2<=V!@$w>eRKoL zm7zE7mwRo<^cmssNe>%+hGVXH$DP!p3DcUL6N?Jo$W*5MwhqioOf}M{&w8L-f!Vvp z17V%ypZTGaabn-VbP`qdP)xGO(HJjq_*~-^2xmIAVMZ9JRGu81I{hl&VPHFqC#A*5_#2TNhlIU?iKbXFvYa z$1v&rA;4}f*!iKs{t#g2-#AcXp4Ij4`ho5N<7ZQW&yj!D&-^$T2=Hp)M?d@Y`b4mc ze(i`D;D#dLC$0XkXhJS+ei{_{)~oyXUtC&}?pFL~`hhP;9N3pd2YjGG8sB>717%r5 z%O|TbRW9obxR_UJW6&VNHB%KjPUpjdUh7r7EzI4cpl($WWJjT$gCqMZED0w#17+}| ziCWAuM($)QNJKat=!Qm6>B%B(ck1TRUCbWJXiLJVkY8(iSp19&xW~vTc1c!e!_j zZCsec5PcxEsbv$N%uM&@-VUqvG4+0pk3$c9hBO}O^4jG7!zIvp1CV{f2FIfG?JXXm zwOf?M6xQWxY6aK_L>%7z%W6oloe8#9+w<-q&!85bG&rTJip+IP2MDe!SXplLwl@il zr~G((Y|czZw(R~217q??m1)vs2dXz7e1h`&>+Zk&>D}-D;T}?YXb7-h1{@Ct9^3UX ztOyyqS-hK&|1GfpJ;;A@2fAS(z}nZp{@#Twpnaatb(Wxyf&ag3BH+ijQX7AAFb!a< zd_Vt;JyjgonQ6ccb-jwDz$foa}d;ok0=vLrDvyo zVDJ>k2Fx{*`mjNFU(d67@V#%)U^sQ9HqS*f%I@apYD1XCn>Er-y zImVW)Jq<@Tmp)D*nqz{h<*%lN!NL;Y_LC120D<{b9+*}|tw67&+N6poeD2mC=&bCC zM~unm6r<9&+Mt|Lw9sZP)~Lu-MT;IPoD4yf{qFB(>K2hvm?hnp#n@u?Blu)Ucp@g# z_0~utwfi82_GH4_w$WTeu?4_9B9qCb3Gn>h>3p%k~GHAWY9{T zgF#k8Oo1nG{3-Vp4w;qR(kk|9F~E_2;3D$Rb(Q_WzrFNm#}zVw=SOhpHxLIVkj9ZX zFhkt0Qz;zO0UwABKL75!A9k+|_~u)0J-d5LHUx^MwBdg3$<_KbSmrFS+4#!+<3K1r zRpyWx-lNh`!r>nH^-}mO**=qxcX$8uPM{;7n1G~S@)aPM8&Wf|C!A`{LczHDETQbs zr5Y}ZyUxQQ)~QxHb8`3`D<*uftRT&BHMi9V#%#tEX}hzK-_cqbS`x!B8Z)}R(kac= zGK+!|Od&7Lisw@v99Du&w7RL3E)5XJzqY8WAJ zM~Sn=(3Vn|j>!RQgoql>VG&5%+|vig)HG0w4h5>Ap%gU_RgVAC8YwSn`QR`bReP{< zs$s%jlFpE+Cd9dqW||MB_@hpv#Y2orHK$HLjm4<@WD5_g?DqTsn(i_>NiS~|ir%MI z=_RR*_I!=fhS-Plezs1bj8WJs^xj8|(Zvz+Jib2N|NXo7|M5F-db6?aP7x?R%d*2{Y#kV168<)IXB^bLpYtafh-0 zJBLs8{U^`QRL|s_i37uA5Z_CG^6VJljq8B-SV>2Q8+%RH!}9+{dH2yf-(2`H6zIAe zLR$fb34~hofy!Q~?I47^1iP--O}+sUgAFt1*1-DMQ!>9bl*9$2^*|b`75?mD4z-=j z0-oiwU)yUL!g#%?=oscCG;jj9!-3PiW>T#Ux#yPAheX3|1}QZG=qxORj5Zvcr0SsU z%CwMXmbjNIif~pCYI$)kjIoF?l@HcCs{Bys!KwOaGXF~!7es;2Y(>U20@DGUJO&BL zSAiHFq7-R-OT$q0v$ng++koab3pcw*1sm^$>3<2Zk@T^E0QvH3Q;|m9<8XZ6HP)iW zDf3zA1C$LMVsb*^SWQfL7HO#ofyidq8sW+CwH4*JBkACDrWKs0BafUmI%-{JX81Ylg{2f8{a*r5ZB%jrOCRpgmKfD2ea z|K_tBv4Fl`k-!(t0e*mF0RDCN?#sKcy}YO}?LhTf9N119uutQ`o~!2Ap9ZwPWw$HX ztoSeOc5bKx-g^B{-uX266o3_z0y%hlMRH>k-h)VM zeK;r>udi;Bb9YO672<0UvwdTiu-j~J$})13(4{&x>sOX@yW`5@hRZpF&K!!OnG&MA z(6gwmc7eKKzJr|Fh!N811Cx%?#vDa5s;cjZstNjNahNymFp&UL4KT6eFq)%g-fNbL zRd$_zd?h&;i_4>#za^b4}LgL-UE6LbIq>e$LhdW#xhN5awg58oa zcshRAq^xTNCN3M-693eacxkCw#XL;)>pf}OgwiDas(%<2wm$yxd-uQaD~}!m9Io{b z#ouoE0zD=aYz?I6Di?l-CXbD)c7P5&22{-Q5=+2cc9G0`GFsiJ3? zC=gaTKWEQ#|IRnxe$STPau}hKrgcI-Mvb-8xTHl*qIv<0Zs}q44XMj5i(uI*3j za+ocPYbgwqEaCR%h^R8vM^+DWa-m=RUT6bz^(&HfflypaAz9eMjn)R_Yghemr5-AB zYp9ti)$D{6Wor4;n~N)T+v8~9vgdP>#z^Cd0u)@K!Xn|tc-m#^&_l^PjmF?zuJe=x zJa=n#YNFT1{MP??X z{80&Qnkmm@S=t;2tfPReac%YK@6LW=Ef_uHhUE=7S~&NZXK`a{y0!m+ST!RlqT=Dk z*%mD4)ReKp`dg}=!jZlZ`M-E^|I@#8gCT&ide#l>x2Z2XnYg#M0p$UUPagcycv=?F zneUGu`|Oh&^kPT&Ki3jquABorzQ?>F{Qu~W|Ll|VI^bKxfvvRxJV1qivpV42slv|O zfJY`3>*EWa>5l%{J71GYIELlNudV5hqzedV$@CIA(^wMb{jf$_>eeo5`ACI@%mvUG z15$pos=D&%NuTfFr^IFq^meM!dThU=gc5Wg^x>otTM*&Bifn7})Lgb$WV(lt71%aB zSOUjZgMtYeh!DbYe_eb5Ia$efz7tg^I}AA--Bwd>AvmmF*j|RWg1&jQWRFQsu%bR9 z&2@FwoDj_(unp%SNnHlgP6x_1E3uyvY~79qlfkX>CmxOj8Dxb=xjlQkG0JhrniSSY z=nCiQ+#wrRcm}e!Qg))ufgbG8vp-90V(D3TT>^wrOcQ7yFBYns76tUOwb|rrLEHo< zFzUG}4_r>*rd>{s9F~s3;r?Lq))tgaZ}#gR66I3ta$VjJvjS+!e|t#FOj*o{V76+j z84?&e5DxaAXt3GrY8#R-zC+8ac~BgidRO^_V+#9KX-1^U_zgzu6^5sMcrW$EH|~Dz zxA5J+J}?9r7s!9lP5^q0CiYx$_Cvw;{Xn;-8RKj!@a~T`gS|GGNQZ(B#zick|NZ&L z-;12eCy4}pOdWiaIlz&w;E8gY<=~I7tq=wfAKc%+^XzNA`k7Ey@e&B@9awyoxc^L+KCDzGD zejsZONNmQ}GqyTS(`BIF;o~v{uZpCfCMvS{eq3 z!HPGIG7Vg|@Vh!I?bLA1jE2fhkSRSJ{dDk4jY)XmiRgy`GdtaU#!-={JD{P~FLXz% z>9VoU^rn<8LuA!gh+`#EL+r0WOWSHGa4Nt7*LoCh*Ij=y4YCSO79X7Xftlb8POJY~ z%jCb{2ZObtkXN_c)BtpIFSMs?%8j!geZ@{mxI1)3$ckqw*LlqEh|#sY`qfp>oA$dBf+z!^Hwb}4!l z3+V57|Fh3OJcMdL2A+S68R#SG=I^s0_{gN<@X5LV@WnZdeCtP>I^c6TVi(oWn`QSE zI^fk`!!cgaPXBO;_F(T*uTD-rdi#gQm_k4sfHFU<%5u>B&UxFVl(t-ZxF%BwjNMqX zHBS|*>eu{7`yMe?z-Y>!2S zR&Qc@F49;*nI0wpIbK7vRv9apc-?X6%_%hpXhr>JcHUSyWQgWstU}0Bfi>oak81_} z7DH)FSaqwLA$C&pP0v*m%T#Z-#0I$%tx@5|eNU=-rAcnoL=khRRHw=a>1>6po)$ad zbj&vFJT+8qt=T5l<|vJWxB?{XG9Dd5hG(AHw2zVv(jste1mjnB^s$>gW?V5evu|Nz z@UnW#Vf!P)CN12!$w9l#I_yhXF*U7mj$G!tQWPBP59#zN=1?)(*u^P>kyZfh=vaiP z_879U!r-}ZZSR?yI+b?c{r3NX|Nd7O4gsz$`qqO2j)a2E1aFb5p@gL_VG61V;t}tBZ0sLTp#wha z>wm!be`V%y?BLHB0c{=mC+~bx8)Q?7;oSHHp&6ujTUgDzl4rOE>l(bvF*g#vUeK^1 z4*^~#=a^wN`Ohw^6_a)hq0zE${}y^WtOl6vQMyshFftF;qM=rvZWzLVU0Ny9;pX^LF+_DJ=Xx*RPhQ*mp>%1k z0JrTsXc@^vsn2qnA;2@&cizU@XUa#`Rvdj8%xFtLjtmQ|&z{`yciaC^{j@roYdbqv zG6s@OQYzr;h#(KAEPBO*2c`fDk8zuLZ=*+1thLw*$COHr!Z0*&n`=9xxtA+sM!Xdyo_p(>} zfgX?o&!yQOz`y^avyk#x7SL9Ge?cPHPdxwR8dUzaW}sK}184vIF>?$&!D~L|<3G6$ zcpTFK?;G+Q*8z`J;Qun?|LtGEwqRh5?X!B!JIMLiFar8uXdQ#K_0xrL5XQN9$LDw& zE!1(Pjv9_7u@|+ioE2U1LR9A##t-$9UZba4VkWEL$$f`=;%PQ3QJ7&!@YQKGCVjO_ z{b(;##u~6Et}Ub0C!WHYSy1gJO+cB&S?b$vA%FJi?!+U{xQbXzv#u5da(&w^&ky+q{Jy0unjx5lpN48T{ve3WntQA8ysGZ`iR9dxJm?1 ztEkFqzn}Sh%!bCmnJ#jcSa2SBtdaAEMsCy6yNBGqYuEra%^D=8l0A=EiC};7 z@}1xN{A)KWVYixui}3Hq1Z*9L_MgrV^y)dl_BWq>^x`a`(+Y;I>+~&D)$ESC^7Z3DES^)A=kIvDGyNXe8_*zV_lmA%I$+ z`m%c+`Y1puE3`2;I)+7bD?W@34r-bRPHymX{h*|!#=Vw#b+{=8c1BtXFviq_tv!+f zXol5FOVYtIf7iM`w-g$}l~gl|5H3j{|G{fX3;LsoGXANELB%|f{kZ?VfL9FtY zQruJRN^auR25+cjn*LD%dhbMCADK4AP8Y+pOj8;~v=FmMEn8{l!r@&lbp!0K89}FGv5xo4k4tRR~GveS~UeFmL&{$Q4?f`y3fxms9(g1vw zp3&JWTK$u%hR`n`5-4PceL1=fPLFD&u-fSpVQ7$4{GSvRC%TWijI_ zZlvL_mmj3YBWxz*Rn+z8kp)z##sYAJ8lF=ocvg{VrC`R~x^liiQwt;$e4{+ktE}w4 zP7Of!QnfS&o3^z%z*0`JE+j`!I-7XGS{qS=Q8RDXB7JGo10@}Gb%rH4^gAOnaP;pl1mkFI4vf80JBb>Cbmxx;S;#C_+C(0n`K3yqXYDTRd-&mhZW^VL3akwArysL}8Kw}T;ij1~!FH7OwcYZ(YfYu6A zVwaI}pl-Ux5A^s1U>ABnn&x}(N2~8R-Z%^B)Bt?^BxUX++klJU|C`7F9`h$xdlnr& zW6wT%zVl$5$MtWT2fR0k*rPulg#V}4KhF!=KQl*-fR432exe?Z?fv_^x1W8r|8=JB zLbQ6CQVNQJ=IG15;=-i)XD+pV)5#Wc$`yppXSTMuQNod$B_0f;ge*s=D5vJMQPofw zvZs@$(SBU7fV2b}#pY0ys!gYtvIjD^Z%WW%bQ@@;p;t$cP@w;ajW?{2874(S#zV!K ziMP5NrM^uV^HiGaCe5KXorxd-t0XkKPE+$~tyLLhr zr0P&92caFLN=Yo5ife@eRTUz&Y4vlkUd5w%vk$@0&^8(Iv@QY-%T(E~Cw85R`6!?* zYEQCJi;|Cw{u5EU_6f++EK@5+#Xey6-$e&s%atF~Plu52IXHpY+RNpv09XMn>WU}? z!?OBRSx6>n8)EG>{m^<9Hj$t#&R~a0stE-Z9Z!2MCoHkJZFE&kjvt*tq;FjT3(%PM z3U4TgUTsHRK5U)5)Ar!P7i0ag)VsBKaf(7$Iujj15r+lH+SF6`1c)h%U72Xf)vtg0 z%P-#lYd*USl^@4s0N2HJ-D(c-7&!ka#s$|6Kt}3-UmPz?mFID;KE5Uoc=g{~M4%lt z@Rkt}&Kdu&AL=)AO*TV4pgQn$Ky^lG%mCS*VH@OaYQwwGEs~kzByE*ri1QE%SG4i(Pq$@P7{Fz zBjupV-Dng8O$q2uqOi(Pu}DNoptE$<^dfmT-nDWLIKSg>4*_F_wa} zz)SQkq4{Vkq}}{wv$n<(oWx)_H8&?#p0&e+S~R#a{4`bS)9ho++#gg)8U<}ufhS9wlPon>cX+oye zRui9r8JC7g;C<$T#%S^^4-tic#_yk0!fmcWP6OOp$6@@jQetSz*A&TuNa-50Vu_*b zhTZA+F$93E$t92ID%%KAgd52!U;{5p%cPPS)l}yaoqj-?~cFyyEP1c8)|f8`R?I+eI1sp^;(t0Bz*B?)Kjvr; zw*mJbK6xJSg(&zzQ=qX=-8o1}+A{#X#t7&uzRWo8=RR-0#vX^b=jQAGqlmPz8Q@*p0KiF_M=7GFJKex;>e<{iM!QT z=u|>!4p@pHa+V?5WMFpLmg?LMD;rKUNnV{_A(krWy3n`~&UO;2yqSXV?vxR1_bX`m zJJvvi_!%`qLQ%j`py(1rMiDf)3f0{fD=c=n5qiRhfwg;jT?)p{$Ouib3+qvX8^)e7 zG?Cz{ugLL>BDG~h=`?Gs1SsHCdM+@IQQNRn9g{7KPQj zWrkDJrGm8Mb^_<**cE=c?%--UX-%-Y2U)^*dF3v~F|i_)$Y!vGK~REpsnbIi>n;jj zebbz!fPx)E787wfRu6n_xMj2;&7KvVc^~J93zfWJ%p%6EE?I6w0u(u)jcdfT?x)Tm z)4_N6K%+T^Ql<@vXEx4ydIv1a7M2;&DlrTK#%qI5tZ%y(Zj2h6dQsRH;cg=OP+c(8_DZMW7t zsGt7chyT9};Fco=JnoFG$AP`Lw0OPzZC5Qpxs{Lw9+mU%6z{&p1z z-;o0QH&>;=dx$=^SwJ|z0@`RTHs2a&I+>%%0Ctjp>iNgFq3B%qYftI|bgPR0CUIaF zbv{i8{MDCt@4Vb&{_ycGK$~sAHYk2L2Y~y5WoHj*`p5^2fL7o7pb^lyKk483p|`&w zWkb|*Ba!TYOc_?wwe?gLE87}O{Ao(O_{j0WfHAdBLs-W{XdOcl*;5sXta}SK4Ad}P zq^ojNn?l!rF0@wHHx}CXfY2IhX2`0li8&g_R|T;sjc45jTuUm=%mJ=we5>@zc7`>X zSgd}cj0T)`0G&1{F+c}9r^@6mYB*+k)v5S4AHwoHB57Rl;_-OMblyvOkdNjeq=#MNK%;8 zM+oi?R5T%+8xOT`S9e1!V4>FTzvI4?tg%HiaLqEj8rDg$BSRiLlC|UovPRa-wO#9K79c&}%Xpg%Z$>knNTIr&V4KsNVEiqSb^n@qu z5|@jPDXiFb9Jo#(Mnzo+EZzrGK>EtS+AB>6>qVwU8TjzhtFfLdfNw z(zwuBM3E`%2d>-}P%x*c^AZUZnRWKJq(Mi|^wD5zY^ zQ+DSzg%iQ0s_tN+4D@7X-KALwa(e5We!Ct3PWOw|^9Cqm89SVm$q?EJJ84Hm2U3DS zlSxDP%Cct(e4P@)gp?p-xHgef{U)|D&`W?h2f^Ye9CucfjLpunSR63Lx};}7XJ85H z4-B7`S!4$hTQ?Wm% zt%h=bfWCB)u_YwfevmZeLl;WGCG06QP~<7aQ(;h6{thp{_oaDJMmBh5UR5V{%n!!ut;@i&61A-oGatyG-N z#c;V7Bnzo5JsMGnhHApqXHw22q*Tm-E{7#r^)rOBs>NL2K`}vQ?)yihsVut`-Ir5F z8}iayI}2N?uz<}p7+Pf*=q@LxcfXr5qo%a5c6$}S!rYgn&j@~&xytCy53LSX?p~k> z7zP+7mhUp?f*IXo9m(3N_}nP?sG^9ew)M1Sb9XPrbxVvc$%C7j>s=_G<#Vcq{ipPu zjlab)H8-A+tJ4`|g-+*CYlA_$9(`Kesh8eKMRi+oj0Tu5#V)a4Wf>^G0w%VJP^G46 zA&V%eX_W=&1uulvPq=<3O^g- z%ocxrXRcM;?3$ZyI+YZdAumdfBunF8qv3wJ@}r2q4=Ahd#NUzWjYeGyHHx9Vf*HPv znW?%F#Hhp_+)gj>*Z<@0_x^AVoF1Fp^s}mf3#7nf8^50>06YNv?-72+uKmpoSwIJY z?!$yDKa)TGMFa3gs@QADFjuql=45Z9Fy!-RK%@tVoZ7!y0E*~cV|nTY(#XlRNeUh#pkR4Goj z7V|~6w-0UxM2m-&9!#mmNCegZL{%@`so5#GwJOjD6T>`@WaF(i3T}Q*Elb%K6Szal z!b9u7#^gb-ia(&FY=eTQIl8GRSkPy4ly4sCWpbj)q;$+1$XEygx8-5PJTB`WNX=up z0z$BtPQwvaEvB@Nz)IZf7@mp?n*JT(hw1rpeQ$L+DkR!s8l*Uvux@a4dxK<#0c!qnLGY13-#_4e zBcQEM@&4N%nOB8W*p;(oNi*o~dmbQ$FchquM@P_g6VwPKHB6!VMUUc>ds3ELXx9Ez zhV9etjBbWMgwP75^l<;KM@;?at^o$ijkR3XmB3#`Hv5%BcOx1)PC?n>Pjvs>6ec__E@>ixw(gMBka_Kkdn*PvCq06 zt@%m40sCzh(~jlYXq7utp^S-ijn-+j3P_Sz*Y21`F_9GGwG&cG@}@bFx-aQ5F{dl` z3uFk_l9yYmH#}k-Yc-?ZLeqNF?~Q(=vp{QdcJAc-KvM3%SntT`IYp zIwtG+9=)3Cam;Nomf0{gINRer@F#!v#s6)Tr1)}3f#(7MoByy^yM@{R@jtOEjqMLI z&J_K-W}x4F^_B0uc<_V_eAp zIco&8@>8C1`x)nS1vn51yg}ex#IuAw^EDYTq(fZ_7s8Y+w#pc`}1 zMfKnt6Gm#bk#l*VE{478Z%B5EV0r$YXcUk&t#0ktSo@f$=?GU(K091VZufF@=heBW z79_i(f<}k$>zj8o#?SR9eF`&O)jdwkTdvgo;!DJyA>Gb0)*3Eu-%p%28LV8_@~m2! z_9VtVbb7Q>f@AHBHIj|ZLcFb3Q4BE^f-?lZ;xEcpVnHTMtA*6sD{EfrXgBn*u-f&@ zft3Yiv~UE@^s^}>mRnsMR={I%R%+&#J1uzALT}b1jf4)b&Zp(Yg1vPp1X7!!Erh^V zRb3_s??Ch>6hEoiaB5mQw-+#U%A4OjDxw-5ELVral@rVMILz}+C3I2+Vpv&){hXuU z=j|V>;vHR}ABF(q0L9_aQsASt?=FIV23Wp|1$4AYI6FERhY$5g_QLuJ|Cu=r;9zBZ zlj{8JDL->CWEMKb;s~8oY?Hbsg_=+^`C>wX5fY0=m)Um=mxz z3Nm=8L%(FO{NhPLImJV9tkk=cHix2u$b1X)3R$C>i8<;5-gAY@(m%qm&WM%~R~J=l z>sQtutc@&IOQ}kQ9ityTd=j>G^NEbbx;1Pp+gq1-Z3HH6ooXtzvO26h>UyGN<$^B( zz}hF8CqE84x8jQaucHKl2(3yQ${pe zARFB^D;pO~3lLh|ns%nj6y*%1s2iA>^#Gk6B-RvjpGm#XZSc}^r~Bp+FMs#@e>nd3 z@6VL}k3vo7W?*N|aD)YP*8cw@fd6cXx33Tww~hoJyJHjl{PPcQay4$;23-2ePelH? ztqvGhe!y)V@Yy<;YeqoCc>(cOO?-h7(DYa5%W>@Sb`CZY7eoTDjxUZG0oB*1ubn{A z5;)f?jaGbCk+xcGV-3=tfn(L1p>NIWb>g&F4j+aclvPH;A8fn3*HHKsWiQr z?08B>UzCqv^|tnMQm+yvb@t*ZX|6csr! z$82ow0Q9)8FfRO~lldMz!MSgXvw+4g8{eqsQPxb50u)0{pVCe&s=94n(;8z9ME!i`_EJo@qS z)%~yk_681pPzns!ug$5zTg||B?Y6>|#~SDaQ3Q+1UE2p9a*EGy>(MGC`eKX4+I?$1T0vNm> zHZ)@0sNq~Xhlv);Q`{^}3rt~@W$6-;{=_AWDv7P4z4V1s_IH$@L@t719FjJg$fQoS0iJh*2=Llx`+p(8P%ee zo$5$+y|W53Em0#Nm&1n-c@i*ute^oK>pcm%HWT&5@g(noj_-PIzy!mrXmXflYkjUd zrb9wz9xiI5Q$L{IS^Xdz#^a-~mO{`1Co8}KI*!}!b;ZAkz1xlt3d;l2iIa}@G z)!!Pgj?_C>OM!0^2yn2#d<+X{qq*B_5)MZK-^dK~fAIb{A1MPk+w~l8C$0n3Z#A8G zGdkeQUo#qjBenGvxnSI3>71PdoGIVe3io41K<5V?2K-Ou`!S!;aa>QlGAem^(+{6L zdv^Dhqs2pQp65z^j54jx64U0i*g5r-{H}q%w4(tVQscoaA~7bMiw>v*)6UpTHNx1Q zS{&-6os}rBhB8#|#n=loXwyX+<2x=Cc$WSOF@CHCB31LS-LHb z+NIuMve_|D^^E%*YQSyVJXVN04dt%FyGHiV&kf0V#Yit5Nuz*0K}x!&NLZ+j=yd%g z%&`>^&=6=RpbxFok5gmNkQ5bAjpXGtmhrBo-pbQmsj+7EiMH@D5n@7aMre7Y*kCoR z8bp_-{i96~FsBa;gPd{l(x>#j-ug$`7-sHp_K~=mHm!klW;Tw{Zg>hI(1#gxJYwE? zX=0(ON3*+7oa2-fz)0r+qpbHVFXjj=AdLzfK>G2Jm_(f#f!JI53ep=vfYQ`nLoZ+* zrj=9x7A3l50>jyQ%U$jMOX;?Mieq6Jc~&;KG&5-CQ7uGe8EDXIdvS+I049?-axIP< z$>c4d`aYdLT6#+BQxhv6%00I7S(dB!*MD>O2mkjbHcuQXEmx$#JI%oUTkMMgjMZ%UBOC^Bu`Mx<^v3qzucswfD8a!dn6QSsLL5JVZn%CewE$VR?I6@gjJPlhna zPKYMLth9>4v@1n;nGe*yOz5nnMnI?(>7~>TVNirr>pi+4`AfCLD%MOVu-x1gxly6s zl(1q%?y;T-GkjEwMdoN>DcazzU_534J;OYObV|i(d`F~4H%3sBDP5JmxY%X^ji@3a zy{-;7WT>;HVU^@?EEMT z2#+=V*-0wce38RupnFCC`8>6sfBwN0Rp|}D^6R`ZkF*3=RR3={5BQQ-!!zE0^~F^c z{Dq@{H){m60{ruM-G9Unl$V~dE1W>T`1;0MA4b*}k|V$g{}r3~+TfuDYbF$xy*~r{ zON=}@2$GJ2GH1)lyMRXvZU$p(BmYYVy;bEiYQ^M*AWGgLWs{-R920j0QcNxzcVJiL zk(y<7Y;taC$uilDs9`BZ9=3HL*|06wHflkviJRd*MpbPy+KyrXbT(%hdGPDFJ@gp6ZgbdTi~;ox^(io|WnA=M%>O)FIgMZZA}h&@m`kV3hB z!5VpJSy-ilj241?Ps?dDn^aC4cl-?kJw-lFx-g;IoLZU?8A(egk-QhC!A^pkQ39i= zQk40G2bDeikk&mjSl!mMB_ti3uBZ@~OIg2o3f~rmah0MO1d&;93x`l1DM-<7eJs7T zjVqs5MEd5)x?Zqs>ip((!l^fwy4gbF_@WS1K2|~4Tx#IRw+h?L0S!}b;bFBP<$u*8 z19qwmhPGfa6DoENObaxW>W&rlY(p?1 z1O`%);SgOt9__2leBtD=We6dwHENQ8q+)TPYw=+|X|Rb?Iy+N3A33u)o$(YammUFs z@JIOW-|QARms)<Ol=}}p->XEwtVTeqUBnHC659--gHE8l=re99D?WVd{eW?@j6{@S zOARf!QsR;Xwd4qySZ%{ukioQ@8oLzxSCiq!Mz9o8Cwxgu)l=Q`@P;SID7nm4Ob1q2 z<;uf>Wi3s@C)3Mc5_%!HG81`tPc=Wxy;=S9au^*Lsm?A4wE%H-FW4oLoc&8^Kq@p4 z2|CM(CMiI^g*;KoVR0x6uVG074$?WTlCZlD0mGf@U0C>nbMa{u4q>vR;A=zlA?GWO zShLpDdfsOIc~o(MsHfJVmtZ->8DfR*){=b~#BP)m{I>9=83;8OeoWkJQm`9NKdg(4 z3z%p>nZWNdZpq>^&l;-7O`45R{#pFFe5NyhKoT1STP0=ckm&`{Lz@Z{@+>zDngxX0 z07xYz$*B>9q0UVGQbnOvsJPDQM4KVpeB=_7_ajrys^bZ!@C4P_r+;oVr&$+M9$CO_ z>MMtDdG41}2mvmZE0Ab>7+n;i56Xy?CIxE#sae{R%|%TFRcO3>k7waB-&GttAACt$ zj25MujQkI%@vl|uF?B*UlU3X=LLe%Gld_y80%h|b$UK6HQAAsjL3Qkrk#U=1X{fLa zx*i%N=F|Jdf4{o>jo;ZUPkGjzW^4xnY!3&B?*|L$+>dT%28y+w=OCuNah4vw{+iEz z=ku>!M$Q?VjnBoQU}tSW-vIo7=_uelPN0X1 z{-7*M{s%rPp6j42XOzi4IlGdykpr3nR`HpVJawNzxNB9;Nk25ZL2 z3Rzcym{;Kwp=0Sv;|6uyu)5}LyQ{C8U=UWPdyV>;{TxRnq8iP=^$lyUm+a@Jl zutL}>D%qV&jRzrk4?Ag*x*Vh}qr;bp$f-zXQK8|25%aiDLJ)FxK{WG{g&+eC6{Xgu zlw1&?!jDWb5rNbUlrktmNsTfhHuIQa!^OA)%kv`Ss%4C@j1bV}!0Lbmt5W0CnCDdV z!r3!06SeL3FZlh0rdEHxJ4E)U$W14+)KFJOT9jmT7V#=>@bdUNElrul&E~KyZB-7<>X8%`Z!9}p zW_K}k7}SX@ky{iX`YQGHVz%Egd!^WV#ZrX3@BE&LWOl03%K`zg`zJSL0qsHZxa3Ed zD+Dex1Knt@4#@ys|H8MQUoHc{qkrdyLxwjH0&vA=xlX3M_RDwg-`EHUyPd%Nqg`&y zULSHvcJD#j&(3dtf1E%+e*0^}xga!JM%QizK_CY5EXKQ|j)VIF(_-MkfPi8!ZX?8JzG?lG|)C-e(VHIM;# z5|Ff?gt2H4gjmFIKPXJ@E2=tHCb2z^1~CZH>Zoi?grQIzfxCqKFgnaEdw$ZKv6MqW zw94av%`2MqHG=}2H2#DcgN!W_g+vDt20YXZQw%%Pu7_SagqpVGH9!#>f~JvO!H}Uz z0k{u6CJ7-)0Opg4EUgmzUD$OfKSvdnDya(7yULQQbxvy~z~l1~q1Z>y!z@d#DdMii;Oq@ud(SjvfcS zMBCkk;8U|d=8Z0G;_~s636yOOX!s3{?iU?+c2vv%I$igeWI7E91yrz9unAy8?0gFI z4kQI4mku#FhV~4Isy>S3YV#MGOx?yZ2@|wNCR{=9jJw)HV^C!L1>q2R#e{=Vr{>uRt(BnA^ zPsRcw&O!3KQM(tjfL1MVkC=gCBlYaydB(S2Jf#faF{!{ei37WBV}M(qkOLp&{{7F7 zfzwB30%vOd?blhE1MC3g=OwvZ*8}VmoF3@}dUjlJ_#DxMz~F?EKB_o{3c(h5u&jAd-F0B{vKzpzKd zA4Uk_w!|U$s)D)-^f=0!g;6{%HQB;MY$4*Cz6{T0rzUHCv{QIZ2AaPH5hf zfhOF(m}M*zoj~AOo>}1N$a1u%;E*;I1;D^bS5l_NO^T#T<$p+@#8R5GCK{!m0`pFf zF^4EOqS?-8K-PDQj0heVW%-JULau(7SPxu|7;fecpMMrNWHmT^KP>Lw~K!69oVnD zc>ie;`h)fQ6Ezr5lm~o}m2?Zc();&5KWqea72%#d&bdEZ@$WEyj>G>)q`+I_g(Hrl zH*^C1^eb;aL_Y;PKH2N{u(Lt7R2>F+~?=kH&QM}&M{=wdvEhTm$m#pzcbxBKI z#elWI>W&urQxxoF0vVxEEOP8@vI^B4RDkMIvLb8Y*Kc+guIa42DDA)?CViX}f`bAwG^Q9jn>N9{?nIlfAN1etMzZyNIV7n|3ssJD-P!P9N;yg$osFq z2_vB6xcD(?FZUt&vk3s>INj(R-5(bh`bV8W-vYn(>>HHoC~FGQs7g6ZwR+)jCuVrk zCYHTo!KuW&GfF2AfTPtzX71%Z1efOKZivACatvG|WUODqK&n!48Wi)A;|bsuQw>nL zCIQB>%phy49%5wSi9OUZIuO9J*~uLm=2K{zWFV2oWr$HlEJ`#}Rx(8nDucfi5sRE5 z3R&D$P;3PW(8e&)s>J|>>TP-=O)MqjGAXG&Txqw(h(H<2lvhsHVj;WkqovMx7&(rr zN`0BZ6hbI;o*0gl_#$+v5=9m@VM|S7vXVu!P~B2Wb1e`7)e7b0Ygqq~`y1Hs)qX2L zL&pjm6<=1dL`4mjGEBijmE*&+Bn_nkhDZgV@xTZj>uBkJ$&l|V_oXryn<}x3(S0AK zyRFQFnuv)r6EV=k${9MCrQ&0~nbhytVF|uYb9MZ{X6F7A8lFz?{J*bFG%zfm3DBo$MMq$ix@u#!>;>F$X{$F1j7SPy6 z{V!z!og@7}Mh38n+2g?YVyp)+?@S5e)cwkfZ(Ll+-YO34F>`>Y)&W0VS98S>V5cm; zkrB}93}IUUu!*Lx(&!JB;7{NLip{`y?tj38PM}}>+Iw$((DHUNEwad%GF+~SzbA$1 z`fIuJaJoi#xtCCn8mvQGp^=a?JtV*!`80vmM)arykm8-fFA`x}?a1=lR`BKd5qX4E z2=LOs_Br7)mlLE1$zqrcITxbpgQV#iDLq!d_QZ;#V1Tf_v#6n)V~FeiQYYN8O|$76 z|41c4&h-Z+*Hu23hzrCbwkYWob%GQ~Y?X*q-e_($0c8`tUawkNDCg|PK_1g8j`Rb~ zp=T&LIXV_PSZd~*$$2&sy(a@#1Xt94+Af)eduwQ6@fMVaFI4eOHPNn#U@*u zRZ{_G`*wEaWQGkZR} zhpe#2pi88$kR6#5SjvT%5?RdltHS;)&|$RTjOaAQZ2@EG|MD~qov-Hxw`ETGNC;L(1dJm}l=7&Fj)529UK$>U@IzkHSjbX^sDbsO-cvxVyp z^0+1FaUJmCld!D=K3Z7gfCbR87rcNhbQY4o9J9ZH6X+$!d1wysjkn$}0t}i<{~(3O zZ5xv$C_y6?%RAEOA%%ga8ms=$_CW|%%Qj{gLdhuPyi7eMN7U>%ASk$&B^2pkTAVfm zL#Qzj4IwMrpn}cIWpfBUM9K`P>CG@4)WhtD28g1`FDZyBJh}mONQOScBCd+QMQO4Y z4Zu9sftOk6B#kag_FdeLuR`G{j^EK#VDi~+fz&is3u=uRnWO~GH687~On!DBL7-7+ zh7512vSD)2^Atm%eG|!OI<45S!y05Qog2qYFJ7jI75zO1CB!h22I<|WmTv4Dc%@QH z?vjw_B>Y++QYrH-W0}Z)TX+(`pV*y`rB4XB16KHE@epQUiI2}8}|oX@5&1?gsWPzh6-H$k||z=sRr zA71C~KmRfQ_U{f9T(@HZU6u%TuyEVg1B@H7fR1>2K9vmM*FXQpo7Mq8p8sg9OO7VRaiY~@4x+C zu_P#5QB%Y&wL5*yH%N#LIb~n=-OwIgJnFj!{DxAin0Y{~$pynw=xH{SY5u5AIu%7^ zBx?HVhM}0IPE6oKWW&?NQnkqBFqiQLt0^_0T~GLK-aBF=%?B4o{7hRGFU56LxfOTS z*5t{O*af*XdVR?q~Ai0bhRTCb^qsA8f}b$7I{W!(QtfhoT z2@ho_Yc6f39?KT&)-A1t$Yv{rrLx~?)E=mCri^3cMiof`4f+=q1Uwo$uV~fHu+ONo zFzIwzvmz%FSF$dw!6?xx?Mj)#emd6Shj% zf!4Bu{zMPg22?Z`<5Vz%<)m)WRLwavY=)f2)fThI4eulGwsgy5O-mFcW zax_=Ff(%JzjG%$T#BcwfXG;H@v4D18nY$w3IpY3^D=4p){2uu%HOPzY3PD>PsG`AY%xqMacST__!iZLdfeIO+`cfE6yr8o}bDbkC>jXq< zTjtgVw?NbjqY;H^&LoC|mghMvM0gDAc@mPY7*6|TGp>kJVG5 zl&o|HCjIPH{9SYT>W4Pug~k6?%ETI+5M5~Gb0gSfgRbxyp+6}L&or0HSYC1CwZ3&& z;7VJ9X*qsLxv^F+a#U)92@Dy=Ryd65vDIE6I6@fhg>^AqGI!0h3X#4g0V!yhQ@icw z{S7GFrs3)wc^b>NDuS#DAGr?S$>hDicKUq5MR7z&BI^j0>;Qg|Bw^jpI(Byu9Y-s;Kvf6X>Ny z{6$Wn=#CZ#i})kBJ`cRwJTX{5h7aHRYSrasfnEl5_MS)=7q1NkYN?2ykrZy&=3YVo zp`z=XtmLpLbs_f-Bio2G`dH0>6*A3;$W@XY6TxXA0~^bBG_heZFPL`kie_3^mOnvd zL6U0OF%)^d`Ap)qI zXNdTh=8uBv3l}<2gbuLU5F@@PD@RHer1TtYmO|yu8uA#LJHON~%utFU8q6`8IF69wYNuo#K3NmW*-QlZqCzP=~y9S$ifO*cbmB$;^cNaLg> zEl0TtIjVs|pD7caGSxiUi&iFhIE|*;C`1xe946=@42~XoRlx)qYpp9FD3d;{tnp=o zzog=!`~u4QV5BrSSG5ozfI9JPdq9y5*~)&X(!8zc80rgA23wUGP|!|}hf%ylY1QL# z$fRtQShO;jDEruSY$(AA%Py_VPdPMX;_grX9Dn)U1Lf6Y62WE!9os{ORlV#*dWcuX3=>z{6#fqpr4z>g;aJs$qQt!`oW0PvMpc_j9H*b78L3JZVXYIWc~GitFnI{(Cn>b3ksoc}D?mpZx5 zsz6=*v=nBa&PTZ^)Pq3A%vMb>CzI<9Q4?fF=`f0`vZoYZJk?566{2V><1i}2Qu`g9 zO-s%K%SyWx%Bt&2m%LF)1nH`x(O1E#i+blSwn~a=e^Gy>0AFSs80Al%RUMi3=_7qu z1V|NqgI4rGOyM+_t5g7zDneHUsfDKI+DlsQDI zIi~zuwM9kAY+IQbPEC4S1%nW9g8$Be&WRopT$l{xyh=9z{!XIqpypcxBl)6*Q z+sFaqYbm9MzL-{@TE78lHH97|F(X2wgz?y@{!k-zQljq0u<1}#{b@}FcUMbwZ>0{{ z0E(EaJR1BV@qDL8>*>9KwyN{3P_4Bh?xINGr!oV5GcthnuV33T0(vAs{-xCc<90{# zMvQ=-z4!fh0zLBmvoE;i1bPI{-}_CTu@>F_pO5I89^Uk$ue?P;ViS^KQ&L6n5yJf= zT;zq4LgCxjv^Z0PIGWC|B7TO%R|d@|5Y;H-7?7Keo>4~e1&}Sa`@-i|XA4X;RQjf0 z+Q9sGeLsCID~~uzQmTQDHe{4Or<@k4k;EFoBX*ezssh!eC00#vpc8+WGB*lxh&5sr zED?@*iuH;P26t3jb&3^ypEIzG?w64SR6yNn3G}@jqR3#=5wEC1s4-KfdoFtXvMVI1U81}d2a)xJORb?9us$4Bse5Kybx%)2P# zb35X$(@<_BKJx~q2=FjSW%rQ1*BVuWj`|(kh#Dd+1=GyM|n9pGF+QO zB>5=LRUEF~1ogmC6-*!6|$%N?*S;o@B{-r3* zBE||*SJ$Kh3e!d0DYMjsB6~GU7;F`jWJP667t%??=uX{KwazcA2g~|{=9Yml_@Bgl z6xKeqo?7?} z9ViH~pwiFOAPNwp7pR9Ll^~MINTDEx+lB}Ss)PHk;y{YfnGp^0yXiQSJ&d@#i-31< zvV$xGAnIL6H9-$q4T{=dam6I&IEW&=m!5gJ;^6e>tVf+_28zmFO9>D(qD_ApA_78k zwFlRW35n(w&^S%qN0HSe4l09Tjg==V0|}I9x@?pcP33Cmsk8>97vaLNr!i+h%QY*V zluF=L+<^iSg6c?f#iGd*oZXihe?>Zp^k6Y6OR-W7bGvI;7-~|2C?uC~IGs>^lW3En zCCxinpq-hgmQNY-S$4`9uU@SsG&EY=wkSbhKCYE0a1B!CXo=VycYpR@@!h{URO#?Y zmG8f{nRRth5%(A~&`ZJa1?ElN>1bX%@&ei=#qW~`YnAb%CeEr$`UeUt?d=Lc#Oes9PHlcdr2viqb z5?UVxwU8G}kf4GKmuG0boty~C5QZU~5I52EdT>%jDM>Xmj8%p~Ck#upsnlu_j}-%n z0QxFJ$WXi7X}WTbA)z%t(%S5#a#h|vbW$RTtZuFpdpMMWQT1!Yza|f7`KWgu(It*#*1M&t}qEPvXxN0(8$e!RlP(dwsUq*)K6 z?go|mUDj9)Q(*ltg7%#7MIg z)~38R_S=-!(9M@&K?CmK`g=!MK#$Q~-XaqC%stKv@u)ZXj|3G>tB93 z?tbUZTP zWM*vnT}AUm_vKF-@d6~FvV0Rd&(zq;6{Y9FB;>4+J<^v=sk22O5`?zEF^Ef_@gUOG z90@Na3597__y3ajE=rOl$C03EbE`4?rLgks+1w#3a1sr^^vZbihxw!N;|v0b_NQ!l~4)= zBiwCot|7>@xyd|LY2#1HL5zuBlQ|3!wjgiJ?#CfumeO97PiS~AQg8zu%ZMrVD*HPq zp_WJ(&^GB{S9%N=7!y`R=~AfHgldf#BCyskt$wdsUlew~&NuhUp^OufwgI& zYLaFl)@3@HjzI0QM4d*9ajOJ2YksNqsc_>>R+j!ya9gaJUWd--s552ui6kD}ut3Zrb#u$DXt1SDs4=DdR3MO>)K zJn#(`lP!``FJ+^p3Tz@M5;h*x*=K1M2P@Z4HWtW3odPsyru3EqUwsB`O}u0QaFq&Z z0;!is!SLgD1blv;wN6iln8+;b%8rG!XjR33UD-> z%S*r9AfZ!)&GUWCxWTYnxS1uKrX9W)NCmSRz@+3f;Ajp|ulMK^y|MC^8e$Mi6lcy9 zDCkAz7t=eIut{AwL@U)y3W-q;s?a22VYBG}9GyIENe!m#7Zg>v3@<|E*+^hFGwMmC zW!4G{^GV8^mX##dP&BPCqPsViFioH&y0l=iTv_P{{|+)6NVq$vp2{jn8@?k@LWqKa z;+DhWq_YBSN7JBENHrh>?{bF2Y()zwi=(R#$3$>PnCP~W2#-aozxCV=u_GE|n{M)0 zDOF9T-VCHV>PK*v!`Hb%J5NIX$`CI^^kI`4k^x9j>xIb`^G)bsdZFgAumccS3w;(1 zqFNxhg$#STx0WlEN0&BpqIdY10AxU$zxHr@|Lo_ad{fm&h;GWD-%xx6C|M;M!9}%U zhI)SLg;o_IMR{hIs1_h)Ma z^pGlO{NuZyJl6^I`aZxJC(X+TIXi)#A@$F{GtM6TZBYQ1euYy3@SVO~sN7_`run~y z8#LO;{z2FOq6pD5KS4Dm2qowB{lw8SaSWCgyFnv(xQLau=&hX9rfv%(f_N44(!d%_~|>YD7=`IH9@b7RFYy zLtT&%>|?~*%J8>xtDsOZRMGW>K1yBO<)?O|Ah_J##dwtjG(|A{8e4LS-6fb%D~)}( z3&2*i4&P6!1JUYOTf{y4PFg=YperkB%X6k2VRaa%jRV@PFv*XOqXdM}7)(6Fq)@ir z^eGuv7A#BcCnx>pW1byP z99tlOrNuM{{8ZTr$!e2gofNLYIS6c3`DyQFm($QP_g*%Q)SA-bZMnFHL%ob`*K_hR zx@3SJX=JQcR3_H%~a-Ex0%2P zWsxo$rwF4b=Gm%DC0t7wvSbZo9zx(fmM?L&m}9IIvwm4Nwm4?rN9WY%&+edJ6k>Hx8>Y%Y7Y&&`j&pI zqEjPx3Q%u@^_#~VV&;qMYkTPi-NLOa5O?l3#1R61bAR}Yzg+RwOR#<`M2Z7upmSS* z*f#?`5({wu7{ImP=vWQFYx*s(Fa9szfA{^fk?f-!GoNY%bPxT1|J?BYPv2cq0X@eF zbYBR>dq)Va`XYCD0X-xN;N08(`4``W#H^|w0K&m8pmX^4Ia5?!ToLmA8Ro(rNXi*m zrx&?@y7)=@84#|WJGX~eN6-!Q zd_eSv5__chv^uF8t+Tu}OLEOd;%iS*_w1!D7Fc^mPn=$gzHTaqVcZPQ?J`{6rf0Wq zb@5%^8V1MAdzxe*!Pr!43Zbm?O=$E?I33UHY z&H?Z2+z)gDjWhiBC3JoS`adiRU~lC2NK)99Q2^(@^`F20+LuvDELuagPHnB}rcig! zaEqH&-GJEb_&G>$nlKSO8duA9I(NV_2%o>XcpV#Np5x;NAsT?vu;s z6Bm}--8xE(U@o}VBgc=}yW`G$-|kv^oI~Len1zcgHJ1zVo|1uga8Fznq00v8bZ>G0 zi08oFUIpRsc6IRKBtRFD+8tv6=dRtG#eppka{cH3$}xc3F!5~@z&Atci*Nqe z9DpZ%ox?wU_ucpLMt^v*D!8~{eu5}~OCNE4a`1u5=k-JX_xE4!%v{|%jNxhUJKzU> zyXP)BeU>~XHEn(up7C)7GWK?mSV+0J+_lc3M;_nMd-m#1r3V~?03100T(PtFlmG{| zPWeALS0wC!9~?M1JaUoY@sq$qg=D)+b~y5*NbW2Q<-unetLES8Ebu^?bmQ{9s2_RH zH6t$7f{)mAZmM*i_<1{9!_|kuOAqr^yA;nqST>n*jyssUU|jAUJp25eITJ7c^}n56 zYwj=u-K`mL2m|t>_2;c)0K2cmu`d;mhyy!vX0|{7<@@g*u$3Py25{`J&oJt_?M)u* z1bXCmn-S2i6X<0J9*h*7r7`F+tbAz^=|0O>!R|xr^Uca4Tp9p4e30ue{*!m{?&bX> zOE6s6U8Vrb!^mhKx*q&B9zRdK>c>3xyG#7YGq1zltHJC8gZ*EBS^b;4tiKK~mLE8_1kM&jyxTtSxGfuw^C;80ahVt31)wf-PIvEZtGO69*&X*8j?3$1lXk9d zWD+}l#=V}|>fDmc=l8WX_{*P8fIC;K$MFih)c)dG7oDSH0L$0Ju`z(#Ya!WLv;S+O0B(5M4N(9`-kf`Hcm>Kl z_Kl8LFW-Lg=f_R}*9hm#PINmSpv!(&+v52naCGnX-?B5Dgk&Q*oz+DY@4XDIQS27PI@Nk8M{mRXvnfF%>>lo6gv*R@R+z`S-3C;!1G3;XKIZ5#{e$%1a3k6 z2ZMnRev9KH(RDIE76AWgjew57@`3ftHD~+f+aK+NNDjTOToNQQkESI`g5v(XUYvs{v(|E_(Rr$NiDbQ&@YHzYhm z_VFC&cnvH%{M>N`9#&>Ci{`k}a*NM@DJ1PX;5_%eJ3u;Xz1IJT*z*LOib#zYbsO_$ zr^tN@5o_3Iw}s3Ypz(t064YS5BQjw9DUfnglDp7&(}gPv4F}BDSPtVaN@{Tt2y!L7 zUrH6Q8aw6cY#V{y&W^|g$weDvE!){%48+2VC{&k$s$*$Uv~7l468+HEK{-aCWkaB| z9m!8&1!#0m3G}x1l#dXYRyR(v81{K`Hu^*dwcTi+?bgBU(A6L6H4TLQ)eyVv!`hi3 zb7y#tAei3}-dIMET-OY_X3py&*R%=#+fR>e;rL7y;c@iahVkTzdbH1ptn6`uv}x4tIn?h-Cx;#njca zcsW8o>l}}OFkurbbi(F6)D)#>SJz}Vy0@Prq<&lE)cOez0*k`3DlJ6w${pU~bZ9ux z3|h(s&uyu6Xq#c$dOK)XE!yhoGQ0Gi=NS&T-Q1kY&8(3Y@o653y%UWKImMmhMOwgH z@gyGe2KRue9@`NVh707g>%PgPw8`KsOF4ZSLF4sx zz2caZQjN>rlL?_^;30$R=bsHds-Hqz#i)j*(C1DU%ypa?+lpl8tn*!&uR?FHu=+o{ ztj|m?WiI*%h=2-Z;iL||X!MxKfGe4Zzx?Y<*z`^r^;?Yr>{S9h@Gq;AemD;7wmIMf za-i2gKLX6Z_~E-ZLbMMA-w%iEM=Hm7b0^RjzI^k;MI?Gp6u=WM>~0jmoCStkb^o73 z7T9;EEHJai7O4i6R0;EmZgN?VraPSqFmS?YA_YV<&s#npb(ZSfFj+nWbP4T z1^~umgPk$mD^H5sPW^*MJRqZWEN|fz$t3{6z-qAAY0HN2_7hiBbF+n4@TPdWLVHi6 zMwtqiCz39$DeModK(PA4j^d^+KGikWxP0#|Zs7O7Ks~XbpST~a~h1iH7hoCk3?{D`u==V=%NTCY5ssQqefSNf# zaSfZ!)hW#a9x71xbm1K6J;+lmmL?|>>Pa(Vrk%Kh0NEb)KcMBIAp3BCWs$#g5)6 zl%5atUGP_b6Cai>w$E}5;7mzyxwmi}%Ez%8;xp9u#W~SAv=52!|u21|f8 zdpOh5>shh07<)G-&VF!zXuWi@(QPoQwHUNPAz9^t*KG(een$aV3wTu-5=P97Zr#dl zWoR!oPz;)KR{LOYG`6>~4#q%vqnZ-jgSx{<511Ve7s}6%Gh(H>iX>PS15VpzHLGSX1)rC~dzI|ln z%#zv=U}8$rtZiv$!_0dI5W~_1+jKHi)7Y)akR>3G0b%3B7@4_Ss-W~Mm?h%rl43C<%27!oOev_r zv5lsorq2q@hU4Jz&=>(uzw4mum$fnL%#>ygThj%h+_Z@2AZ1=uNq{Q7g2KY*KTCZ= zmHStwpkyS>C9N*3yO~DyfLg|lDhs3OQ1$Pq7Pc}88@}HX z@aSzPW*e;+XQ!CSx|MQngp#xdxy3n6`Q#EujfCI6&5!@@-+zZ+{QWh$?;~RXIMxlg zNNdVl>bt$@8s;E8j<|Mx?TfUYt`J#r&l1>EoC;NQ#%^!oRF`R@B0AoZQJ z{oT!hhy5<%A^t+Qv_W?Mz5elk`{LUTfzQ`(0|M34m&Sxaq4tzG*G7Xf%pu`Me$j4ZbHLAC(5O@y|;3?JH;1O2Us< zc(HJ;-lUIeW(cM3-vqYPg+raLS*o~G$}wp`@T-QBhD_V#)3FUC#(qUJP}DJ3v~9L- z!mG6byDr1Z@&PUQT4Q89v*^0nB9qXRQjthMs}az3;^v!+CkNL}@& zU1{txm9$1eMMxunVLWh>z^G%AlFL84~zkvO9MDoCtR)su8I3S zJ_o!D;vbp^e7*y4C-A)iBIBVi#-qOl9(~LQeiz^Va272;5D*_1!OuMUk>6csfgQ2^ zxvC7n*)*~9$9$Fg=qK;LisT$884G-*EyEy%qY}cqFwbe3rLjW=>46n%x-o_nezUl| z!nJ7n2NZd}0Ywf%??hbs1~4S&u*o@8fbZ)rcv8ZQolDr$bfnErL(3Q~&NY$9W@i#b zsY?T#n^0(M>mn{l6Wl1|0Mi9g7GBFN-e}zVl?2S82gBqyfBeQTi-m$iEWH847^b|^ z3TcEbMSfgjDq;LbeTBi?A?lOt%P1?40c&NCmU;x(E_PyA88RMP8V}%2wy#=U1J}XC z(s$NNQvXIDTcf1yK%3) zvbY0jZIwykP!0dy{)BcK1m!yD9Ya-@Rgevn&mCx$mnNii;Le;0V=n|!Nh#^~p4x_LH zRa^Z(O4e};j|Yy`Y@q8VPy14?+M8~($`XW3JB$TXYRK2mJT3H;CePT#M&XL#m&KRA z`rAG3`HU{*x=P>*oQ1OrnQMXGqZ~gEpv7n80l!|6&({d(Q5Zd*ISTyPdSiNV&H!8= z1)w$YLq>A1{*^1*2)9%+l-}|2iGqhU4gT!iR|WS>L98}aJS+k<- zE4E9i!(xtD#2_~rrfID=awxSn1Bfw%piOFRkW8;K45kc87%C*SoC0tbMl!udB5RH& z2vWH;N*(xE$WYU#av{&(h8DKk0i#hs)3;zybAaHkjd)FD51H$eFQyVE3PC5&<_Xe_ zs_u0+d>II;+pkWVd${m9p-OdQM3IZoPD76VZd~xVHDu0XE5NEG%@+SS%PC3YC|I}ylHXzO4JN$$O)8rZGVk}99 z>BA<*Jt1SYlt7XHGlP|5ySNxj&OKEyhNAJ;X0VIJhZ`|ssko9a<$8+2^Ln|hiM~926 z`CBv)q76Vx$8@{L#%)%ODoTf}Xdt?wDCDYf@_ZXeU&^v9nq?WqP$yyBgg^ev-~4Q6 zcYo>_050k5&&&bGdI0wjj(^A;@SElV|Md^w{I55i|2>R=AL^<9NctaF9{&v`M|T3f zfv_jc)ctZI*zqi|nMZ#{7TBZpKLoNX8!+|3*c4e3sL4_vV$HwF4YJp<34gadJu3VX zVeQBN_W~V{%cci7F#M<&C^%r0gQuE^$_BD~4>Dn7b$A3o72`TSdn?6&SfodvsNNwX z_Azv~c9oeyjQS$I?YEL78xKUPlP9KrL+GPLB)u(bN<|GfWR(}vN=c2}065%kL{i;> z7(O6NP?%hzg-LbF1~BtjrgUEoX$)s@K)?DZznc}svKlc0 z)(NO?3pE(LHHuiBMhK~bYD`#rkkztdpI%7%V%(ftvqKb&5UG^F?(%P9YH)NUT>}UJ znSzj2hc&pMi4o<<02}#`-XlX)Ls5-@GG?uAhq6Ig)af&TyxT#f(2vdB7{t&LN)13C zagoWd(>n0G-{bFp`N`4%E^y>~abRb`8gG!m-$wu6GXrpx#{c2f4D`Wbo*ViAkA1^G z87I(hK0KVczdsA?dYpZG7TDv$fX~Q*;)YNB^Y`y-ccGcGguvyHjf^6OWr5#KcEb&E zk~Rt!6YG@ohA;|i+qjThSWeo3Lm;r}P*fy~fgz+M(BTCtYdB=1P-RmN`{lgiP(!QN zcKMEs<_1zao7R13e5A!VdG0|e+e?5B>)|L7LjnYr24Tobq>9>Tasf`J*b)aqdbglVeoBTy84z(>9oAH8o|KT84|ict z(?bw?wITO|6nZs(TUI)16+gsJC?)oWGLU-zGAMx^M~y)bx0UVNYmZ2uN5Rd^_RgqR zsW@r?qHN=BNGIv{aYx9EbEGA`>;FXL%|1{vM(o+*5~e5-jA`{03JDV~T>>JdPAmWo zmC#hv!#qjBQ9GsYBLE!&;HcQ7-NMPCpW?D*3l$0JSCvKXQ1T@5WUJc74GPizseDAr z`C7-x)JUcK!Y~r@ONP|Y`FIU2;cZAUttqOP+Wa@A#S-!zleZA3Cf8k7t555oF~LI0 z2BG8~nME3<-(>qLw`T(_Wbjl_KrSbw+N`@v)L2&KkEhs;kx~$-BhS@${Oi9vDpj~P z4dAkJ<{~P*Dh}*QYq^vw^) zX=xnFJlBT6bu|1_v%s!I;pZ!gyTX7E{`m@g|L)7g_OuigwV*q}5K?p&sfve4-&5j% zGK2u=s&fp(o1xwrRA8zew(e^x8B!?|CKf8H3S+>FOusm?#`}hHdMMh(XQ-s`X+21@ zq)XSl4XmRo8m1sz=VyguB;BhA;te9-2G(^Meel%ABuOkpKh$dln-=tR=5L)#x9ku{RHUgD6ZH5M+?TtR7*(N)TGU^cNx(TRfJ< zm&4dotLtWy%uq9!?LLP&ToGnT4=_z*f%Z&mf-QQ2lRKo8I;%@vNKHS0+v=YnBrqPl z^qQ*98$=wFg(2&-3?R*#8P6w-W=9DE-eF192buv-*->Vnj5gyBHx7fs#CjZ@RWyuO zmpS~}Asw?4m+SoSragr8e;IC7D=Ba}-r?r3A)_ME=m&d63w*=8<)!^3tFZ*F`BMx9 z$w5ndCA5K)95~965NXhK|1E!Hq{bf~g?f(4%L{0^>ou)!jtw3`mc!VD6fJ{27&;`+ z)K0A)hZN7O!>ph|cS0y_kl7VL%n_uCFHV6FBF@R;wu$cY5CJFcg_YQhXpXr~!Vj>dN3WfYx8 zU0tBXh=Io>hjTVA_a-&Z#?Wmb6%1V1(u6s^hqC#}q{%>ns((aSoN%j<9H~woToIrl ziV2^--~f}SR)xk81k^yI;&c+=BYQb&o0v{8D9S7K5ier^nxujx@y9{)MwK#vIrre< zn`5Iz$;&NSR!#*iP!u&uVakUw5|BlZDV(*0&H+S7hHDDln$p1I&q`G=8YWE1M%$jO zr$Zxmhdcxc=LS<>G%||pO%ofPurN(pr8$r&NU3w;R%wfj!+@#5RX|9~JDdGLAtagylWIv4MM_!9mXH?yTf-<5&0z>q z0cwccU^E~%SV>=i;w3bT{Hi3~-el#mJYG-jUpUxmZhg)k_hk_e3Z`l=80fhLUcG_z6R2{h4D7k@b}n zv?;EGG`%S0xVU%WXFuP;rtzRLfU6`X_s4<7HMsxG3vlQKTsk7(P`d1PUH;!6zI{77 z|NcI}lhU{zOaDKrfq)-tfDcE&=%X<4B{X~^o4%I?_MqD1+E+d%4EXE!->EDZIyI+O z{*r+-wmtV|C~vjO^hJ;9rA(X&f*p)~3QXz+1KAVu>lTe8IWQ=%mXceb+St*UYira? zV$^UPV!3u#D}g1Y5vP8*a5MpT%yWPxPm&K)%2dR;w9=wPJ1m1A7-wud`9>LM<`u;e z6cSdF{#i*HOJT087LQV^iBkiejv;$E?tks*UTq=Qp z5IP$c{RT}DNSIw1J_lDQ6}B8MjAafR2Fmi31_R(ZX*#f;KV^b^7Qe5tvmsKF( zA3h#2KrFq&n-B15k}&}VuC|Nv)rr#4&+XuvRVte}sL%@Gznud%l+ZEiJU+w{wg&)@ zHn~q%J_0OMUIbh&o6^Rz*bDsYZ{pX#xx$@Bu&MtyE|KeJf$xoRU>9+G zT=~i)Z*{#mow)fO{_2NsZ=}QDSVi-|_rL%9K0~v#i~{)j4YI&)p}-Ghfn7elrGd{M zOBnDsuVKJSw~}t<;J`V_dv#k3$zDODgoaz;NSO2}Dr`TiojoMIeba#SC{uAqhX4%4 zWKQHk0fN;Pf>+V0C^z31v-1j$DW7>tj(qwAw)!=jhlwlhKD;p40pphFI)JFrt zoR`<2R5M~kWMG~(9r;obI#Cg{gon~%N@Aq}&`ugh33wo(zP05K77vRDsL9VGG#-Hc zjs`6`pouKnw%Yp$l3u5cCZtP1t!OMyeJ)n3@J_0ZNRd`xus!o^9d$PSEMV@$ zJ(V+ckyzL)naTC&HopAb-yf4C;D93N{ItON$l(Lj{sr~_4RgTvj0o=l)yqaeaVQsT zD*(QEBH;dnPM~<)N8H(bxZ{+%5zv#ez<9hla7{+oeJY^GgaKbDTJ9;OzI*qr&eIxj zmbfcw1g!HT<`LQ@B13$_wbv;I#a=^{F=0NX?9eiY2ur&WyAM`cm^$gtyXDyQnRNnN zdSq>*;vUGtqRxU!Aw#-XD6o(=`q@o<4SXWLTfrKB>*p_w{5F888`kJ0E* z6Haj^v4b?ujc(#^M0)Ldk$z|_yASiC|*B*Nwn7#=VyW7f2`g9Z;)4GHV|B=q+@u}Pue2-{qmXf{Rg z8&5p|=xQr9f(e;FW?0;KXQQ>XGDcP5PL~z*rwJ#~t7T{<;~C1O-*nZb54wa1W>{=W zIj5PNPa9=2=c`s^p6slqTc|0ZnQf;Zr>^hZ;xpDO;O6E zW1pK8dz^BmtuzJ&XK6t%d@!vZEJ?z!n8BD+B>Uownn#5U6pTDHpK2GMA_{dsAdy`m zY)QQkJ^uzfM6m!Bz=hMFR${;~nNAg#Td0?YG*5TcutYOk(e!Vf*@dXS0Jo#H;D9P0 zPhK_@Kd~H3(WmMp*Dm;8sRnw_4~qbK_}nSl>SXy(fw!RJ3VX`iqnjC8ap$}uo zGM7F&!&i1uBB9UVmQOLFEVU>Izg)+%OC|wCrQ{W}CM}QrJVa0LtWJ zT792EjVRV4HwLx0%^7I4-6eEFOBQ9B3dygMbdh8~Q!M_fbv_X6oZ`0}$KzJ5IS|MuMZQz`!k zMgd&&(ZdMn7Sw(xR=!e0e>Jm?%f-MwU;Jq0;G86nzwI~gzA`zeKILZIpS-#UV2b~D zN_tTebYq%i>n|2>{MFo};cU02HevR9j52Zz7}=VV9kdpURvqJT!eFXyk@USK9AFkN z92S5jlwaC*OEICE^zv|LMG!D1tgMZi+z;zrZ0NdNBpbYSqV4qZ7uk{_rI?cCI+Ho_ zWlwo!hB+nIsh=(}XD#M7bo?T(WZeN`cq4=y#6z&^(Ml8*85guZ9H#rjIEiUOS|*DW z5I>yyhlUwK+@=hTXayQ{cv;XxHO)`)`E)_ZDsF4D3>wpr&!|>M zf)GQ6Z6!1ZMsPK|bgFU^Q0SjtpfFo(kfMF7!peRfrrWdZDbI`&69M(5YR9l$OSqpI z!g=D+MBI#nhL>eR-;50jNq#oR&agEl?|t#H(KL%HaOe#LF*w`oQ$;L<&{(xCu?s#< z{~AxNu03_Jw)EY!TFB(~q5B-xnE4HJNlL%rn*Xh=Lu)T=cSw$m(_pN568u!?*9g8czEvZlJG>>BCYM>kXFh5^_7q(=$WeXNn8miZ*3 zx)M>&x(za4IYON~w^#;3MG=d@Wr4_=Usbc|I^<$Hlg!%6%Dj*?T3t;OI?33N?#u!_ zE20lBQPBg~jOLTNb`BLzc;|EpMi79-K4&=-8jFj{TJNZ&7TKugr z0cB_Gmi)Q4VHByA2s0eA(j0${|fCPzu74_&z9_v1;XB0C_ibyI!$3 zjT!=m&V*+uUK_QqMO8BbtPk6idapnFkMHr1|9mAbI~xaf1-8OjIy~-}13uCUXdiu` zCfWVa^F~0oVa#po{prn4plA9epXVQZ#_zUze|&X&81T-0b`_4l2(mwQ81Pyle^NfvBI3PH1)tR?NEt^85M&(Qg7M3;KgzWuD~vn zfBIYle11Aj$q}UWXTp4SLwf@fX0c(!;l@NCBc%zfGJ^vdCUNH z`7DZ}rxp=K=b`pA)U<0tEtp^uN7$m!f;e=lM-v*NM(iP-9PK*Vw2<78*6tn2jH=1< zhXfieGLlE??$3vQQ2!O^xRnZOs3e71HZo;mysG?~K@N_znxJ=7-TjE>W8Gv#o4j$* z5cRd{&WG8uZJm#gOTo{tngc%gvSZ@}51s?Q3IJX;NqiqQ&D*^>FGzr{0{sV1$${GB zQ0F5qv_o#E|L+Z1eoO=8`Y_;wO#kg605^f@z38qd9m72+|6nD=r1hpR=qb%aII+v zEX$jmOhj`+1dMLcy_rD|Pj&kuO4y8gQV%2`l3sJnK&XWs6f@fuKxtQzx~%%;yezCH z$B+@cjFXE&nCH}An*4WR}{&5=oZPnI>L(6XF=03Qr4y$q@Djv5G#(kC^gWg$|O)=5g5T)1P;`pcpj zdD~dt1VD(6i7CzUfo+c1T`fK{V2Ty8A)^>2Lu)NK$?OeN@RVeKpv;k7AxwwN7o^6E z;(Lj{W1F6@RGMayq&Bm8XKRDA+9Q;@6lUM6-oHs=P|^#`a>sqH*tUhS91kyFkP^dt zdepRYj9A`a8!rNj7XT|@+oI>vDmG_N+&Y1S1R7hOWIEFtq!^{|>kae&{g10eDc8sx zZ~zTIa1MA+%6~By>y3?ou1H<@o2v?d$C~cHC8z!dJ&NOl%f}7|Uw$}_O0R;>pGO$* zWdk1^nlQfN3!e8aJ^mHGeR=Q0Xw}T-HoMn+=2EazO?6XKsvvr37KTsH#|*L zwhJlTOxS)T`=Gdi!U^4)Odw){t7))5rtPvAKr;s!E<&YZ8YG|+ki%O)ncToM7TS{BH=$)T;iJ@!blqSc0QUw!jmP{xTRQa|Z$OE1ju%m_0p z$M9@d5Z05Ipim^#=L5?4)&<2Nku^?Op%(nNio(*`TrVN*;n@!9t6Lwa7K2X=~iL+)610G=~{`mH{%k5vsdq zs+odnRw7TScsr$jnyhQig*vmS`G%|ca%qd>2Tf6^|)NuHOr7itJrm%WiqZcYF& zvsAi$&Cn*Pp^>p4>#?F{1q(!1mt;Li)w|cYJnOe4r!9?tV3WEsJFv;5D5ja3BZrVy zR#y8MD*tTSsr-i8O_8=ppC74?v99~lOG3HS5tFjkL9> zC-oFe&J^Wb$d<7hHLE7Hca%p9bQ5$6NP(lw97FsODZVGHz5#r`fXd~UcEScB&CY`v zQV$9)@_5gRF<=UZRLc!#AWMlul&Yzu#wn8R1DR6?R^n=lU>#a&H23w>_dtku>QK?X zFp~X*ob=I{_Y6D?iMvd4S1^>`KzU>tES7%sW>yIGZ7(Jl5{tkv*$3STh&|IOW??;= zb0hNDs_CNQlW@5%vnn<}S?auQPR2tk3wr2lv$=w5tWB?CxEJcP--Q!JvTS-}LGl z;O`E00REJs0C4x4KjW61ev0?RyW@`d*B=g#yxRl9fbZ^0T=bsZsZaoi` zrVP_L3Yh}&w=5TsGM7}C!TGz>xZOG0) zz$YN2cD+;r4*-Xpa2wDu%~sy>BOS+@@bwJ=kp;2LYRojern5yYlAReUY+$6eLB>vrJa!oXqHEA9b{2Sspf^^D$<48 zRJmID{fA*0)?~QqYLKRy)h;Ox7;|RQfcx-p;nt(6EmB<9#d)ZnAm$8(yOu+k$n>0K zjc(eh>(UW3WHQ-wp9}9XTTb+P@sFJ3r&$Npv)@laG;bhRK`oYM!1;BU+S?3mO&2c$ zG+G@<(L_Nk`vHp&q_h}OJ-M;Ilq=AvQfQ<*bWWG8RcGvR$@Rt!1PKi8!$mM%P*Y}V z-mw}Dw@z^l&C*b~K8YIMpwYusjX|pVs7VJvANg8_(5Fhwe8`fhQ`JXSRNydW$`*5y zK%o0Qc)Ty98W{`)Dt3ZhhEj=Sr7P7p|F?gO-~9G!H1tM!z~^Ng$83DA&g42?OWdF@ zSyni^C+g=PzIr;_eVZ5llcE4VpGL%yEU>SBc=F+2;jy!P&GEQj4TQSIhllrd70AO! ze))sGdH3>y7qot|B)EFqEjUrqwGWE-b(IEU)Uz4t5W<<3yB#bmCGqssZNT{S|G%Iy&4kB!v8l1cLo>rce@HRVTucQ*YR*+l66^O?YNyL{ z(tOO78q~_ESm)3vQs49pe|Vm(rj4z1$+7a~9|dsP8lGysG)AXFD;4p3!p4ML2?1bw zBjlArO|JAnTfib~wTGb57c!9TcUz75Y!5(PWmM}xL(FUvnbTraQoM5B&4P-whNF$? znC(#6Dd|;i0H+6Dxn~fy zBJ)yWjXA|acvPC3411iS3W3tCnAsf~f2Ta2)Es9O_30LpsUFpnCH1PYo^cP=BijSj zPp5SPtO#%-ff9A6kBRaT^{~l)Kc3BB{?jp4!V~g<55i3Df#!oiKdv_dI;JM#l}!L1 zKLa0s^asBD(}yoU0m6PNbbiSA@1qXsjw~>I_2GGp`$4>G3K<@s-#ywcxJv(Xb>OD0IwFmK8Kyp^^t$tDhSCsbIZEWQ9}$Y%8hVlZGJ5ViV$2 z5)MtF-kiR1_!dGf?RVzEv}U-a z(Vg9F9ep%c&lh$eYt^lClc>>bsK2%*bXn$+MHK9AcsjO=35QMlym~NcteYBt6E>KV zLTaECTCJ~Sl=RL3n$2WTT~rbR5~d#UyOsvLC;_``YR=D$0V7F*vr?5B1`y??A`iI@ zTO-{4vplf?8-^BOh0K>a(wb&M@5}rW|^GvICC z@S*(*cLJS2DxW2N0U4k1pQ|RJk7o~`{gwVNU%vZFGzC!9sC@uTZ3mdlJH*}`3x~?w zf7||~2JWFs9y35^GaE8ze51Lh3{N`VwJ}S9ubl-8_xKA(dLeclLcn*oW0q8eQyYjP zG_ul*g$zS!bf^4mYP2P!(X4k|ATK-4pk6;pfFjDhpAFika|^6JL4*F4e&FhP8|kDA z;umXw6YW@-Z}a*X?zCReiJi_kkTO`x!Q`N_lI_G$O1g}OXd$Wc9)LTk1t^rU=d@Gg2X1az1;+qC8MzqLEqy za5F7v=W`e_kz#pPK>>X|QRgu|*qU=dU(Lr3L0yjARV)ht-mG*#-!wSSnqMpBzE!t# zT+L4$`>ji$l7~AX`<;ZJ?~MUm6$S8#kl@yzk~$CoepCTH=Mn6Uj^t*Zg| z;v;x`_~B|z(L+WlzI^$*p&;KRl`7Jfe#h2hYcqQip{qd|&T?zbuHYSr7HQ%RnsEzD zb}Zdvkp+kPT?<_CB!i}Gb_5+zlTrFIh3RZl1|MTl;O>z!RPbPEC*PLlbB<1*!El*v zXe!;e3|TR}j@KZt2uU;c-Pn5V;M^_ga6t7>a;B(UcGUp7!Ab+jKG)SzX4K8ab3u*B z)g;wO@1C$8l3GPomxcQN(&$Q*0GaSD0bEZ|W|ZemyHwW-4wm8!)VdmoE|Gc8fM72=1QElG*`kJ zFX3sg@Eb^MD?zjB;eH1uxpaHhwf=7UqVVDWFxDAOKbCoKu_y+j>HgaYta{h$`o`#} zT{Uv>-lZ`zHUCX@Ga5rjDzr;WD-yk6qNKuT;XxBz`gWP_Wj32@5ggt!Djk^?-iyL7 z7KMC-5npMP#c2#0|KlHbzz&W{Ty8*uI4~3XR3jig6k%@!xJz zpmTuK*j?GuIY9^+5Z&U$)G37#HoJ+*2}8{CI!3a50*4vOtP2pLu;x83AY{%`9pzae zoz&1zSh6u2ijm$zvlS|mDWsdpO<vj8f0^qDECxpoeJ)sEjOI^_6K(# z5-Yaoc*3{bOq=c5si6*}8Y{=eH>Q%pRt-WcU9R@_F$hD1>6SPdI?YoMLlc*7`sAeZ zLF+J-!=m*D)8MmQeuk7PwD=_FNmw1S_R(Q=6N=2Pm4Rg|v9yQ5I+vGy^Ug^9#8~UrpJu4Q<_pT(EM$mHv-} zayOhr_GfwmQPVb4=D}5`EcBkRN#*vSKnDWgwFG|o54Qp+Tu~?Ru+h+BAo%$B@7Y7W zqQ!A6Ncg&<M{DyRZ>0rik8$)ji%;U5H~yx{fy3z^N25NWFu6qiOvaZ4OX3 zF}fv7+tT1jOU2gi@|m7-dXkGy&lgkW%Q0ozS;}y^Ue|sm^dqE5LiwX-?;VZ4Heyb$ z=t~>ZsL}+OST{j_VO0Udu)TSehrHMWNi{EQcUzk|WXv#UTADUg*7de`OpI!%*kRfNbBCfk3!>Ae zy9R!3a?rBh0W)<+cSaQRB!j{}`AokZxkT!zsoJ8I`rSa)(6Gt02Ou-K? zeFe-;{h7|nYUFT@#0%_O@tvmaXr+-}xHjji)4L_aPT9OnlAt{>J>%7j2N?0*YG9pO zRg?x7rgWegPWWSGaAFHmrP;Nwjj(xAC>CrhkVu2z=)9jvE_re8fz&;?AA=aEL~UmG zi&&Qwz2k)8LfmI8&HzbGf8b)X0=jQfA1+3pUeM&TJ^>vKQb#Mlz*XO2T45yEY)7*? z$@)VwgiVU)tqx}PUR%(M7<>KOKmF<$$9D`&o%0L2c1ZIPMnJq61AM%?h&Ofu{rew| zNq|0W_SPT8pT~y*-)N10_5tH(pV#YKdx^^RPTit~L`ZGhiK$oqd)a zm+Kj@Uu8FlHuIL!ArK9psJg#xkSTk?YM+(wr9XX%*;0u1g(F?KPdxz`22)R*F`Wuc zG-w7+^NCC8t>Q~++(JaRrh@k1{G=M8z5d-5e za8q}Pcp~N%Bg#WjZTTx3Zdzb4<$;M?qySGqu)ihP>dYzn?bm%ewGM0~`n1I5xCPPu zYuH>oxw3oU)ZoeBsFA?ELb0tI2IMtGusvz*fh6Z%OctEwHA5Pd>t`=*bTd1NF z?Tpqkre#?Z(K&tg#k$%!8L4fJR5X9wTH*<`tY(@&u{wnCT1zJ&%~bvALk zFe^7l8AE}MBh-+wB%qcSDN8QSdk~c5mQHrZD8*| zmi__&o8wh9@WbNRX%GE4TNs52T%%&s7@MS85;3;kEf(!sYPyA50BNDd41R!y_D1g= z;*=ew%KJ?JNYg3pgEY)MBHJizF^WlgDLRF#F4q>8&Lr% z4#-xB!1{eMwJoFAqm+`H4-uSSF$pQDlFwoOwSDKzK}Kh9Mw+#U9V^u&Edb!3f3*u|iM#RC#rJ%m z5zro9zhw4*3wV6C6X?eqrg8wD2X;Ss7T806@y$g|O9>DjA-p*_+(!l*zj4j; z#mkpz`G&=H1hJThEcx<=L2VH&@>@*yn%IVP+|meQ*`Q812ABj4W!}75Cz_-HIyg+< zrxYY^V6w*k3>{yDjH+z`$Spv#9 zrh7`7vB}4k^JSD?roW}P3lfh&;vGh{B~I&H%a0RITE7A?2(ErMTgqn*W>cdoGS|)R zkr;BavNl1$22xYrC(^E;Jl!NQACmSb6@g3Wg`@$9xbK^MjB zjEJ!*Oyh3H#KiYR-o%E#u_obLmejCf)!@V;6{MrVJOYH4rF!z)e1Y_os7M>u;w+*a zI)g&Cp4)goA9+?!)^I!N(>egq3}c%+Y*Zbz-TC=kB+H+<5R&lb>nK&H+G&ZD0O4`a z?ArHvpb^k*2XmDZ=v7|+cb%Vq&;!0i?D83jA<(lC!H29=oJ>O(w0<#p+ z@na0Cr%x)2KhM@whG|*`22$k>bfd5Mogr7C?EayO^DRmV18A!a2Xy$i`sY<_psA+| z3hK;rlPh4t^35*v1kPSCFiw}<2U#+eg1*R(%PXVJPign>r2TdDu1NPpg5%)h%Gym&&#fdw8IX z05hV%vUpETQMFM<|0RZpml?y1XG?f^{o}@s5Y8ZD;!dP>D$FS6uaxJdo@faye=UJ3 z`fF3foyr5bJ5h=ez+CPbmDEIe z%wWi&?^Ent>jb)cZ1?9>9X;}Y<`-{4w0|mW{WhMS4-_or8+`HMZDw1a2jyKp zFi$id{2~|L6X)WnH=N^+7pER-kTv zSG7wo%#c*$Jf?VZvk?+3Lysu-qMpL*0Ipa-Zf`cu=1XNTYj7CFth@Y3C3?#J0>!!8 zW(ezT;U16Uedzu{)~3k8Sg=e+Ds4JXD>QGbyx&n>ol+!kouGjb!y7E3-#Wc5)Lmcw zk=!RpB*YkHAMM463T%~W6p$l{dtl|9Mx=BVst$!@YD08HIj+I_zWJ3b1=lqABVmHG z^$s-$u$1OvFJ(qfqZBPfi$Vfa$p`Y*pcyY#1u7kl*WTWC`A(p6B$jBRRNeJkFGv!J z&Btnx{_azi)OBkAs(^u~Qq+1>bUw>mURek=OY-P2^Atdh6u`Pb$x38)Z7#hM%vqq_exADV=!z@1Td)Yp8=2;;S4*VnyY`fAqy;yorce|Y^mga^)u_s~o zi`iaReTA=Hz6j$g+Yl>!@N!^ySbXr9u&RVAY#tW`g(@q-KA1D1BVP+j>Z&6(%rEl9 z-J<9`xHUf9`aOjO=xfeU2g|%H^7uk~_$OV-p!kLiRbaMmOAdonZatQ7|}Ukonb8W z7Um<5luE<0fX5?|^rwI_6xPksNaQEQErZSHsf~|=mQ*Zt7eNht5(Id{gcxF>)9fwF zA=EtE$*J{IMFCW7Z5kC?#P%TWHwC>i_+(kgnloxE-NQ_=24Zso+BOMLjCCP73Z*~# zYn#etJTcq23&tGOm=j9uiAs|b8Xn!43GxuNKoRN$LdB@FwN|3)S5)H=9>Oal2Goa? zo}(*81#@i}OGuu3A7ig+W@%oAK9c$rkv7{a4W;ZLjLzwHQ2?z(Q#u8?bJS^9CVp$o zdhqvIZgI;F<=!2|cO_vCWVwN{H#M9L-xDrq z%u`z=)QlyGu%QGkOPV$qZ;C2C1=GlwNo zqI;D4<~CXzL!p6!!ow67p1hUSj;Qm8#$9_WJ&;3{Hl-uliYt0{@sL`F6g;EbMRuG} zrKyOT+%y<=caMdGQl5_fR}Ok^*N6fHM-784mNqb#HykvJjv_qCs=xWX=f{yF7Et`9 z%Grma-m*AdhB_8lK3)wG1M(|%grLbPM^OQ9|A96QFq1S|oFXdN0(tXrwQSLbGwS2A zn<;$>?decF%myg{>I6eJQ(&1Zbv|`uZ1zZ#8m4aFS~S$oY?Bb`ut($+@F=v$!qD3? zAw$Mul^a?#sKB9KLJl``ou zmozSRP%s&#VL|awYdrL|Jh zAKIKT3bM;BOxgaa;_d9%aFM>Nqn^nYV^Fe;)R|N#q_itq_<=LUl(RFK@~I#hZ(2R) z94;iP074Sz6oh+~Aw6SCpN3&;;A?3*3yGCLX8%QG@|M_3-dn9O0XE03MF2`Rrr3pgZEzYlbi1y%aoyI$lFi#KvIOglBF6ZBrYKAmb5OOIM#ENISOU*VG+;}_XZ2LklBB&nP=x- z##HxOqFDLnRsdUb8KS3o(P=*Q8j`CoyF<#!=*CjeA$Y^_s9ve;2j*o9U$yo6YGVfy z#h3Flr-79pFThp+;BBGS#WaA2JAvL;23)8^jyD0WhywW4#VCM>U#L$~VBC!OudVVP z_?6#(h&TFkwUmF)1N7|s9}NOK(%hKH>Km~B@lXZ(m#<&G%wQ^zQ`k^?bkvlgf$0!b z4b&{$iKMH6u80ckaWxKRH)|#}26N;w0yJt)SA&dH8QV5D*(O>{E*st8nW>#7u6DGc zuf%c^k5FoR3@S?Q3g#T7_59VfB~sk(uaVwD@`4f(T6QQp;i9o&qk_Um7a*Ovo;wR$ z-jX`Flk_;xaH+1qG3G2qw%H*O!I(yDQ=Oy)GbFqe(Fr`;<3&U?^dV;dqxdF<4-ilQ zg2qa=kWx?!Q;7!)n&%E{z0EsZJ)F$v zQmQY`-4A%^7bcos4+hS^`kPfR2ZD!H{6o=kB`?!ch+As3mh`^%!TL^WO=jsBlBw5R zl7y@92XlS%ShIxj{pJm8Soy`QrzDS>AA*%ReviLHK^*E2rJOFr~4CG1=2i5Gz8QU?c=5F(E8^ zSihwa@|ICdg9L8gZ&i#A-xVl_Y=}|akMau@^E<5*GQWVT7d78a*}kBGWnoHs{4GBdvEUXok4|!jD0he{ zu^|a4m&gPy7&1{!HzoGdr)Mh44vk(W24KGH9FO(XPO(2OISMuG6FIBbf0Gf z88N299as2NF9w4ogNsrKI?JfBuq zz2xvcfJQhP&TE8f`>EtA$zQo@0Qsy*glVy2I>i!VyI{}Ni$M`rNEGvMG zvSsu-3U2*Qc4T&j$be0?%Pm3c|0v2vbky651Ny(Q;XGj@Tv~Mby%8Kbyux`%pswF<|LuB8 z{$O+98U%m86X=b{|4C5lp?CQ8MHiqqI*xlQaSlKKQ|G_fgN-+H( z!k#xK{(h=I@8iR2yLTw5b|y377~-l|TyUrkXK^O1u4wPczHide@C^NDYPbah7)3Q* zRdiC1#;mPiWK3KhR#%>TKy>HMT8NIq3o!PR*7ir8p=G$|cq3f4>-Dm@NNn-L@(T>h zfj02uT^KI0JB^#?ME;h|Q-RFRA}jWtPaRhcpz~bYdmmq!XHqn6%5PoOuvy8@ zsWNOmNBWot{bWX%dr||6jCCFhCuIv`VfkOT=<=qNTVPe$GUoo>5@CA*!}$iy3YoA) zN_$h?U5Z8;(HE4EF)QyeV0A_22L$IHJrgJ{M~*PPwdIkxlo#B6tk}!>s_N~4e4)#e z{hQw&08n_Gviq@4pzX57tx*8S-jLU3P2DAY`3>K_F|K{UXW>&EaFQqxh!7+rJWI>tn#_`I*o4U1rMuT5b2ea}cd;0sDY*jDKt&ZM5U5 z0AQ!H!wKIoc{xpby)4M-)IN?B;S6?Fg%zEO40ee0)assyO7mf&+Y zJf@qL3+4mUmqIflTWHnJ-l*7l+}evZq6N`4s*d=%=$@?~BqZ%^+$Kmzon;eYGbGlET7Px6} zdGY5Zet3y@D+Yby1Q2@($XG2Km;u9*mQg}EZN?`NINbB1LnB+L#o2-@h&T^dV%65z z1GiYfID-5^JLlv2_|lNV|08 zGc7n)DvrE#UY#6UhiJIF#o2McORxlLerb5*XPotCyzp$2^T7QqSm4={V1ZFw)f;Ga z@ANFf8aY#|!N-rsz&$3Z&Y2a5oMc&Wk~i=C`WNnfmxw;S)0zDo9EI!W;00}4jPwIB zi)Fap_9*fiXHcNe94;@&I{M*NP8ZhA1-UU6jd17A)J=~LqM#EXuueg@0<^@cg-~PB$Tydv5(pUcbzkiGayN+>xEVeob4<8o=aN#{~ zjwHMC+g-{6`|X(m;IT0JGXdp~jRSjT9|K=}cn*T+;REEApL+LCqz!Qqc;i|Cqrtgdb| zk7>RsSl#>kQ8N=!(@Cl{Q3M?uEfqJ5ZZihq+M6{47%~v<;4L32UyFI0mHG5#n%E5MyNuC$*jzweoB=~JRj}80;PehP4LrHx zu1b#<5#0|GXO>4v&JyVb6=4kzc)2e|M6f?*5(qa%i0`eUt=EPn9_GS8QjdPkiNlK) z?5^%@G^mMrptXp;ls*VkWe}U^j7jmh&n-{Kq%+6ryMUQ^*N?-Qt;LCi$&V9i=RhBA zf=|a=kAks!`q`d1KuMlnZn9lhY92B&(06h8$~_#8P9?8xfjwoyx*n>50XOZfKHCHjg?7k*v4hItt>K0*=IFR_KFL5fkm{%*b3je+J>< ztU#ahS))>u|GSMPn)znA5iOB4d%?^#&EU^*7WOnx1N)>rpDa||$pKh^#q>DaDroKp z?ClJ-&zj3{mf2Ch1W+qoM^>0J5^T02#QbJw9k6^2_Yv0HCL~ijG71D59o?!fPfSZ6 z)5@}Tp`~^9!091gwj%tOa{a?JrHusu^qHE`rrrvG&jcYp)&(f`f$*IS^YKQ+wOL@> zGxk4q2H>gZ^|sgFUF^K+z4O=ue*Z}E&jYbO7M7YfJNCRy*6+asxO_0DmH9p1cZ@UQ zb|unvsUG%8Ey6Yf0k+Ldbl!e`JIq1CFE6}vZ@(JJ@Y zvoE0;c6Qa&3EB#P1jJVi=SKbg)Uq+!nsDpi0F72&G!N~~ILXM+nC0oZfW0jgp16ql z9CET0GPj%QK11UTpwrx8L67vVbcy}Qg%uWHXQ)zKTArKNftc%Uc}!GUDc_M`6DqZ_ zXu1Jbs}k*{dH=ShZ_ed@{jZM&z_s*09uWm_{8t_U)(^ea8)ShU1+%}qrvvajIvj8E z>3GC@KCb|I`2>1>d`>1j2j`M+_{ICarmIz0JPg#P&`}7DvW63`)=Go9U~TW5S7l#Jv5Rkac1_NpEN)GYh=-;kgRX z_Dgfij;S}n*A9Sik|aTUjwJE6Gwqj_E9QwML+RhLS_ZV1Q1gn1 z7Xnia=N%L*ex!hEHT}XR#B&L`s;E7&$jcfcH4@~c*XHWtL&JfmVU|kLlA5v0%w4uc z=~3iFJ(t5aNz98|7`B*aXKH(`ojJGYM!2!#xg}Mg30knlbGM4D;$T_Us%CAom?rB(aU&WpvcO#_q+ga!+3)&CPGN=)$2L{ z=UqPW0F24o-r*`O5Dpx`qqy|z&5mCG{Ncm9&jv@eumz3N<5>BXTO1+toasV#-*eeQQAoct=PkBsrPY92 zVsbJhGHECc%^Q{2==R#yVXknK+qwBv!b**#_PvQ>IwCW^;C%K^n<;qqDQjg*C1$w9 zVKGg70&FinxIub7Me|8&`(^jgbMZ1XF^J{FZi&Y9sI5i}VpE}WiCKw`Y~-YZI>cHE zCerBF8Hg|FatUhVvXErEuf2;c0+W@4X^FdfAIcq76_CyUYtaeXQc?qa?KZjKD*vTv z&NL&}@7gwNx?KxGA}g{;M->*?5-OQ@3B2HD@>615f_ttW<7OcSbsM!2t0Fic(@K^@ z!8+`M(KRcB$sb`o+yB&+-CB`7y-WAqG`ZgYztr!fRRCK&G&d# zIKj!Jmd`xR)%Jb1LN;d_{9WEfs;`5<9s-3wPb;1`E?4e(`*(c)H+Z|*S?n3&Twm$l@zclj z9KLw@O6b3Yt#cRJ^5G}!pOkAN1U)_NE0|E?KK9aOU$w14aXXaL$? zveC!{E^qLbm4#@75IqDKCd;Y=HFzpDpVEZj%5f7G*svWNG8UOrcgY!j`^zkou8I)L z5z1*ym$2xvas1-PD4-1Hh5Mn|@D>Rlec*OZH-L5)AnlQ`_*T1V;K3d#&_Is|NQ%3IH1_;- zN|Tgrxu{Tb8y}wRioA-}a%GGdtkMQ8R**97TnTFWiI_GFaO@e9Sd4%F{W0eAllrhc zBMa==VZc{>yY;X9{-6rza|85$@&(4rk#q121b;CG0w~7g`xpj4%YPEzfg{-fiij z>A`Efk1Hl=g~&V!feFdY zo3w~N7VITqO_}Zx4m)v}CJ+dnnqZe+U`YvsV7~=fwUOL&NUFHaIB578&<#wCcxC}^ z(>tTyyup-{c@~C@X7ocGYS1AbPV@E_s{V*uA&oX<#m^Snd)Bw^5xfcppW@vSiWSzP|}ZzfdG{ijMPx4cu*Bnd!GmWJnp(#bW_V1VfFr$L3XIGQBI)<%Buc}=)A%yyMQ zNU;T{_D`o}TxK1zqkLP2QhmKiG|(YLtV=;0%yi%lB}o^8rZ}JsYrbyd$Z}0i5|+lm z+ee&!WxLc(o)H$nD>xE)WNi+8(YF%ntCU;YDMMjEowG#KZEp`Phc8XuE|Xc&80z?V z5i_J4^B z-us^LV!PHJ>lxIH1z<<2cQ~n!zi)&(O3?r+WD*VY3=A!0f#cKwH4g)=&Lq4wY!2W5@JtMIBn#}?gx#3n{tY$50T6mL4EW$NUkw|7{o#H5$^5|+ei4Un zqQ`!f_a8ntKzvQ;@1u|QKJCza^_gt76FoBm{I(6`cZk~60)-85d} z=Gn%mp%`PsPg@DI4Gy@W%$e6eO4XwRq>)C$?$_^SnwOzRw9H^->*3+R=gjkkSe`_L(Ye)2YEQ zVHUMeH6T=>Hx{%UdXpKO-~Hik^!z~R_dIeHpV@m}wnh5kawOHKM)S9^^`C=A=$-+M zi@(dK4a<^mc!r)b0enZ+!Q}&Z_wr81DwFYt4s$viUd#Ro?2zWUvXqb@@%0!{ zvCZK~Q{1pR2?J)gDd*4;N4TLKiZ5(L;RXOCFNzv2`V#Kqi3-S4nRkh9t7?m85ns)8 zW%#mbBBLLqN5z@=AfUFPjWmt2h7D1WH&a5)vn)yQ5AcWBC~^2A1oXZSrLoj3(Mc`- zSmKys%XI=Y>^o_;!5E^aLhgZGh?>ydh;xA(6hPSl@PK1X5*O88dJ5f$Ju-BGthwbO?LgQ6HBE&=gGq;Nn!2M#am5^~?`b0dn@GO1#YWNEN!3 zB}m9-2Hl#5wUkxUtgMB~KERE1TD-(7T8236NTTD-lT~8-tH>C-@`~liLe%*$2yZgg)Omlsjc8o#vYz z{@8a(Mi(Ql-~{`0x)@E3E$MMoH)Jyuiax{1iu#x@l55V%WU4 z^6-gAeW(;HZ9rKcE?m-w1PK&*R!hFHheE8cP-82nFKlULI#OAXw4OY|)M}`jdI%T@ z$L+qmQmtu5o)`!$x z1kYoXSz2qJWO3Uxg_`$(rd)@J)+qx%*qm-usW>tEoNofKwU37AZ}jQ1517L~7L*mz zB^1l#8kFK#Eue7=wK|j~e^Dy{mLu4#*=^3iOyZBtdxwCm##!g4G|>DG=8O=D;V7$7 zG3v7VQ(H^))N`blKTlV>TE=~7M_3D;N>PI(NW&OYkT86vS&{PgRj#yICeSztFP zeD0bCzDcljyxt%_J!}5ie%5C)Ui|)Z5y4-wALWxi;8?~d5DOnJ>j~OizH(8Wl#0RSgwcd24qeEec0BF@T5HeG<6Kv(sBe#kdj{C z(O<^FasWg@ZRl+hrYKi^>9|P!EN>;2Fol&wlq{eouToE`1|`wQAiU7v0D9XOd`V>s zo10APP&|W8D;h|KGW2R9+v{8RMtb?6$9RSU8b~TDOC$p=g5*MGHN?!G8~2P3A27R4 z-6I_orI_5Q#ksf48qWE_DCBf1I){Hg!`;xc5aQIEAS*Wl8hufB0i>BSifPrvAZKnw z!;x~N{>%?u(I$=3cY+GB!xIg}cs0ilMyNJ(5ip+`ok5Ytf$rU)%>i#$bljIGaT4-y zYe1E!iI^en%J#*m{8cH30oql7f~~0{UO&i6Re8|@!X>6+kK16D@btWD(WjqAJ1WF* z9D|MsNn}C* zfZ5J-yPct}9EzA&6gl!;({c!*@7dUQbMBPuIZ_WSIdv1fFd(zptRS>xMd3_65{S2y zBMl_WjtD#pKmn`jTE>jS`1;Ig4Or3>3M^9EVKBH@rNR(-__QUoOd3_*hMFk?FN8#v zm$ePp?Bx}Aan9|fI1Y#tlNK$eWU-JB@llmQS&9PG6aw_j$A_-aerBQLaAN)q?Y(N64Gr^Z2oG*%Tz*1w-~|iFdT!GEjgJ z)uHb8;`X(m%5+_1Wmb|j=Q^Yyvv3d1^*q#S1pXhzWU+S}rLo?^mue`sblkZiijn{# zK@K++p~kSHO;V~#iZ*r|qK4&|--X6@hMI^H1%*OICq?274FZ#Xx2of1>4G~O@1v$L zORUuL{gm|VMu0Z|n8U6D3?+hi2tE1$MvJHhbP_n3^lV#6@7^$KD5~rwN+}m~PyuiQ zQ3@;y^IIysIH{wG|8H)f;YDqU;)n5(^g9$MN#7{%xxoW(1&Q}I?deqo4#b#>uHmba zMMhbqd56*AQN^_R?C9-g6*XJaPHlc*m5F#hg(-hHd(241Zoc$z2P=0L*rehaiW^<@ zgJ!!kc>z$WYvc1#h?vgUzus565{xI_Z&cE%cUdu6l~x@LWXN4wh~kGsx3y90-%2%v z1Yts%wVVO7Av;OA+z)jt0&(Ob62cV)d0p-(2vIO2eZWuBz z2yy?}$Q|+KEKn#D%OT#AoZP=zZDpgTt!jX$SkAD}6Rg5uoq3mzg9M~+G8Fd6YGFu| z3PxhIq*1<&)+2A}HbOuO{i>jas@ttyT5Fvjuj-44(A|zZOoSuOLtO(9CNeh3i)wg8 z$x??X93k6SF($D)wLZ~05)RZHy2by`-rM!+nq}8PbL{RAtN@B5EKr01kqd|fl7VYq zamxjNfjTbtvx7{Chm8+|2&~@H5=Nx0M z^}KtZbM`rPPWL&sO4W7tem|aPJ!_3Q=9pt_R*UV5uadF4?wkY2If!WS0f6+w;Kc37 zxC%`?YNQWobf`$dl9JnciQIQyTDI^od@aZL)!y+2AN{&%G{tc9GK&_EM{cV26oNbq zU?6KuYYfeQ>cFRN5fY<$H3Cb*^loiaPtWg`fDpI_jVc!3bH8AX$nMk8y`oBR(ka6Y zE)}*8*CE(sv5H*W*@@mrl9^*S#&5&6GMCkssCCnP@Bx}z=6P_0IKbBGV$U2~`m`wM z)nNy^X!S9q-8g;FYS5Up>X&LY9RBFJ2nFN7gkOX(#)K*;awF&p5$6{!Ku-k0&!X3U zS-}1Jw(u{{vh(%d^v(-D^=f~@*UkZW&8EnkhSd17Kfv?wSBSLPgE z?qg$^<(QE^hc3Y5b3x-G+qEzTVvK!|)YZj}C?aOGyUpZ6&?$^L;7Cq|1zuME4i7*} zP2*xH1WMI2VwJerM0A>rc|Ix;r0Uk}oNpzBA#g#;;q3{9Ni~?;@j-BVd#Y-wfyxiD z!UKg^9Vb6EE@;au11<0kIK=r%AR7z%Q-TywPCC9Kj9yLr3##TTw5L*+jNUHsNIELB z3-?(i-Mxp#bi$&86YDtsh#2nY458ISvQ^=s#91S^r|xa$q48x|IdZnl?1>VZ7n*E@ zmUvlqvGmr;&K<)jUh}WG#UQ)e&G7f43UAzn2N6Ccu$8u$X?_h)8Jhl8cbMC3hG()_ zMWa!@GFPm{vk&l#UzZLSOv%VjGeCkBMtANOHj5Zfs|?R~5?lX@Oxg5hvGiuq0(SXF zkM->*#WiV~Zqk2+*mB+Uq3ihp4J;YG)iuZOUJ0J@sGopt*=FH}QIQtK*HB{E7+c~U z=B_o$hVWdlQN4#a6hHZ-f6H?0XAc8@<!c>l+spKqY{6&*9* zyp`v3eg0ScFb5lNlTRAKN>CX$VvL$nnQ72aIB4WEh1BFYRWtA9so)QN za~N7VG4+cnK}*OFu`&!Ea*2gkHrYwRo32S9#2~FuPAnoJ)}EIq&^K?F%%1dUE!B!P zRUKq?}Kf@M&jLy+KjwtJ=3fJhq&Nz4@$0f(C0 zwr5q%B!^S}TdZ`aazw|HY{D?O(8mV*Q=I~|0aD|>^l}=p%oX})jWo1_kIVq{+MzjJ zvf1nC=?|7|=N79Ny757DbClu=N#v|=1U6g4vNg(diWLdhuC>)-(isU*XTCkKqz8jc zn#dN3xx0V+@7}6R90y`q$p<$1v&Os7bbmTRWQ{?KRg16?MQRP-u1C~Io5C1{6#jr3 zF=&LxqvZGd8wPy$clo>+6Ho3Wyh&{P)ST`}!ZP9_EsJ>HX18$D^7BtP2Qq~Hd^@)nYs&+{&0!Z5o85~?49gKQHTuXY9O5B;; zU>2K8mSIy!#$MMZ@Q7-(myERPki8(9H$2)&Ud*R@$+lOHwrw&Bj;$>rMDCJiz7W@U zWKbLhO@jlOX=6xZ9njFNMBJUpH-z9l3XRoMk`dde5e!Q!&?p2h-`tynD4pon+u2yU z#4Xg}o<(mQ{AbYSo-1W9$D6w#?tuzwyG(&AUDThCw+u(A36j|Ox8bZrYgLP>qTV!@ zcxbz_S|u>5Zo=AN5~S@z^BMzSh4w9(<5qT2#y6^X(%A&D;$Rh@H9wT^D3(#)!9%ME znO~VXHnB!a>aL)(MYgodH=&7mW%HcZjGKCL1@i3pk$9e~^p+tnUi%e(v{8PMGGBd8 zpUtPh==W5R^E%xBtCcPf@xaX?U&r1`kG|NM>|A%GqD8&P2~WvtS=gqm;oIQ>O3$h? zIAt!1Kuq9s= zrP)UQ1xht`h{ck!EgN%?Q8J0@GZ1U~meNtMY+MV?s<449MnI(>nQeSnG@IH*w&_m2 za8Kn{Zj*QhrH(5jhdLj^CR#}kS-mNnr}LB6dhJRjW3T29EBV*qCF~G^kbS2Jv^x-m zYh}(GFE<&~vqcMUyCEZsm$1C;z8d*Nu3y$FwadHJonXh4IiPPx{v~;-24Cy9Dq660 zD5N|dhi$aU;O=R5eAc?xpq?c8eabAp+&0mJ0Wi;Vs=b44(h#@oks^A7x zBesejP-StMCtRr?6h}6dcXpeVHUZKd+3bf9lQ|KFrMsXsV$bO6qmp9XOtDcy zJ$F=t1-+6z#|&6`v3zGmg@iIM$|iz^UTX+I*N-{ePjTQ9>#$@P==KZW{ob3$rY|M* ze=2kKdSKvfR;lPpv4()O_J7VERO z(Y7!()d`odF(Rq7M1}QVN<82$G)Rk%+u4T7QYt5Dg_Z(6i-<+2YYU^1w0Z`b^cZ4U z!MaD$ej%V37OkJjQ=0TK!gSwR;m5an>x&tH@gef4k;NtzuCj== zYAjz@jd@sz1r78Uluq(qwc#nMN~?G1Ob8`(EDOhkUrUrj$(@bLIanm+x@ycTQn}U9 z843xaV12F>2&@H-dM;Gp!IdA82*#tPGz6>q71{GjT%NlrsNICZ^o>uUs5XUhIn-Y$ zDM9tBdq4sQW?|LK?X(N(jCNVuGA9)%VZlU~j5=glM0NfX)%2*mUr5U_I|{W)bps+V zcg`=MYZTB@U132~vRz8;gdstTDv2c%Yt`vYr-C-Nlngz#oM=#Duo>f&F1FJGF#>NT zRc@jEe9DP_cFW`w6yBuFGAWbmvA3LnipUQrAA6j+#}^GWV#@KD!HT@OIJS z8~xpv$C$f3>7^x7uRc-DcM9d>?Y`i9RQ7z?JpF6D?-M7IpF#Qab}r6m{M4vp;pxF1 zJ5&cowbKx938o8k3c<_T{C2o&xKW++TQYAue6LpmLR~>i)@ox1l+J9yJ5thiXzJ+5 ziAq2RH&xJY=F=e#rb)1+GaXhPz=pHYL7-x!+9g-j04dH!5!V<|y?HI`z|2J0N(?hK zkxn=)iBQEAFJ8BzlWyqb0p(L3>NpRx=U``@AtYl!{kMC}Fk3gBt7L%4SxQ#sFw8`>2Omku^UYSrld1tPMmwK+ z(gx9yE3D7nZKO=5gpRr`3zA*MiOQK@pVIC?sd_UKw5rWdB{NC zG*$r#(J_G%3EV|myUVC2(H^4b;vVn{XE*$5(@oLa~s%F^YbPYS`D-loUZe zT9V6|n%cg4q{IkkGk?Jd3Du%H-Ix)5iAz$!BxAG-BO-$XC_!bEU}nt#TX6azp!$QV z!bD?TA#3YhfWA}g0aSF@YUyWcxU;$*b?~}KEd4B(cB#QMQ(4rWL#w60#ASVgfhyWB zAI*{kAfZmLM#V^yVHGxH&N1uTeTHIgWw2N5oy0z}>EskR`vf$zs}Yhd+|ja%76^9TAIf4QU1W&9;iViB*lDhR* zi~;*zF+b>SSHV>1gr?P!<~5Ao-RjZEh73!%4`__Cj4`0soIvq5l9l=jk|_*%8$gnp zrhODmrb3DZkf?(wv(~BeAuDrEwQyy}q?snomS`>k+gz$_a!`#&QrnO2QDzmAO!GG^ zM|(?krQJ(+ZDGAo*YBZwDds($GZUaBwk0){&PYfF6MNP|Q`~AGMq=!Fo{w&=+ zC<$M;!(Z5UD92PSd5X79C8f4ww3Gr1xz>zUvDS6`Lnn~|pWYOiQPEO_&i?6aBa62* zK?B*tgXMY1mOw-21e5DpBV{`2i|#m=dE)|0C}$58x-30FF;&C*yXTjy=gl?2X!_VL zlR(-u8X7gX6;gXT%1CFa$$ImeX5tronK`M;JA|=I2 z?KabZr71`ek8~G7Vhz$zsB1<6+Z1_5=lkfWWOW4ui6Ml+E_W20##kDYwsh)>r50ww zOjtNkVN_(*xh_lsPIz}A`z`1}3wCZmdljNAZqWkfoF7gl)slQ<qqFH>5T0!ViwElQyW-Ru4)T3rPyMu^Aiwz1rlD2|k6A1f)_ z4AqL2*Ba0o`7!!Wic1@NMm*02jTj_L8yGbW2Jv-}Ff|s((I#o0kwHQyl}l@svM{X1 zrA3T1*;D<2oSgtV5InTcc)Q*ZWo8XjNVbFUKzT#@DY;#_k3V{^c-=Sb4apA>{KuWJ z|M2Ji{qxZeK9aOi39YR;UiK(jj&P>DSvf`~vSyMet>x%pT2h?-SPBxXvnGaw809g; z#;0t3bqy6#gvjltB32Lej3GpsapRj?A{|{5q}r7%`n%o$5LApF;hPCm?b#we?T}0; z2>6OVC)2Y%S_RTpeEGf67`u7D_L3}awH*8!ScUYv9{{ybMK>PS*Xhnhl%VnU8uHb14xC88^;Z@0(nxJ9>$rt1A^P7c8&PYPifPTPpJ*Ua08negn1rm+d^{ z3AZ`mR5C(B3a5MyAyzqV?PErwXzWX!!C{Bg$vjq;zw#K0RVpNEs`DiQ2NMV7Y&?BxKmE-K8M&(WDq6ulHioQ#sS$y{CH2fB27&KZ!s4 zGy;zUz}-6Yx?L(c24Z+-M1Q0 zrx*3LNX-vxj;z$r%YmU|+snwX-QMc}O$QKYLSupDX!E(2vp337tznsU+|J>e1nomR zx+R?AURujSnl@`1uBc@x8gke(MD|hR$3kP)Fl(s9C}s8KbCPh7#oz*JU@Bw6O$8@% zW6N5LhX3Jze2^($wk>2igy#%sm}hIWqP#T+(yn0+g`<|uYFlumu2FN{NROn=X26UG zrPw(_BEnMnqW(U0%f(^84DzF;Wp$}^yfueHdpx4-rwW+aC}Ld{bWlM5o(Q@EBYe-8 zNTtM8c|@RZp+&Zeji_XzN)TRsBZ7>ly&XY2YRWTva_7t-UZ?X7G^0;2fJZkSAW zX)}Z(T+7D@vj60aeHUxpRIR(%gwy^*nM? zC|p7$t;8BBk(<{(RuSL%?pr$c-&ua0cs_LbGII+b8V)}~e|T}n`DK(N&yKM14uk;Q z|MP>-KmGXAk3F~KbIE6E|xr`^Bq0T+aqQ@)!PFHPUZE%MG1Ik*Z)&wN}^j8LdQoTSZUY$V5f|i8OB?hU?`vE zgPtR-l0`|;t>p`?r1ZHZ-=B3d7L8%!S{bm^uuodLTB;gl z#<+~uORD2xT_{JNq0iAhUK>>lJ1 z7vL$OX8ID4szv%k!bF3TOvjpZ*Hzt+GQ^-M)S@0O6YNZ{uDDtAEAkR(T-sj<5N&(y zVkrG#7q@7$;bObl*J$Yw*Z$iU4GghQv$PeWog${6vjDsvJAe#`RToz+`*l*d&1z{k zRt?9b2%rpdWyeIO3MBoyMw+YPw{Q04y7l6{o}mDEV-SaU+wXYqE#3-}`!TEv@ZocR znbpGOXL+wa!1q4+ew1Ynn)K@iXI>)AB#zY2-%wmg8fHibUVN&>a!7}13-hK#rw&Sq(oL2-Dl4E_Vp9uH z3}0+aw&g)>sMG2U(@jUyU(qSNP%Q_V)ypo0$QNF`!~+Eaagy0FVv#A7w`f14YN>;s zUg?%ee-2Kty?$i&VhxEFxd~9Y|Ip7SmWD!6_e^2wjxZ8)J3=(m7vzep{z}_Ng<9g; zhY)sM0FK`85Z|F4&r_~oVRrkzD%ME(M7=882_K!j%NtCzb<%OY7D&)KyVPfN(2~mM z!(eE$!y#pwtKU%GFPYLrbxgG&Z5U`3SP$`yp%%vMare##zQ8Ae8kUXUR9opq7U`cuS!|nkCs z>!(&~HNquhK3XKOsS4ppfEsYp5aymMs*aml@gsCI?}^~9psM32rF&UCNSni&9Q3Z4+E;R5U;t&7m#|CV@!U(}D+Y0@NqOuS5z?but@RG~q zN9-a#zV5&M!va9#CW&ZR+$e{RdXlYbdmxr;W5>J)YCvBklpv{)TvLjAyQbp= zl17{A!Aq==c}#|y56VaC4tuaD?k|#nVImd<@+FA(3k^aBAth9Grj@mCI;8dECjqIO9{jgt4#Pnkkbs6-8FkPvOrF{R9n z>OED06NQ+aTH76x4!jC?o`ezQZoaP0RLRsLxAzh{vo^=E?bLwHFUgJ}?mDDe zBF}>d8aF@*$Y%IxNmx}@$!Kb0B#&Ll6Roxd(JslIiEbw%a*Ky+n_4xcn^U!HT7sXbQA+QQ|e& zu`D+s*gyN$YlBTbGpyn3IQ`?TqO_MwHGYMkj}L!-)XRe(i|_WVm+A0S{Qk#(q+zlZ z0czZl`Kz@2C2ii5TLU5EQbNdfMifR0Sm^v^dpM*;AYART-E9@!2mzcr?xIEz_MuQ zwj2E6<$f4QVMov$lBAU3H1{ZJJWd*S6!1L1$I6ej4Mt<0upnBIRY80b zkM_A0P)l*0;qmFAww>yhcl!ymL11-^M;XioEj4BO$c!2G7Iriz55MmHx~fZIukg-| zMGVj$J^JC(9`vn*6X`;eox_wGrRtCw@{lMeL=OX4)Kfv&7Rm*V@uV=VRsa&&8ub> zDQ?Na!&HVC$33iBqt0yCune^Jk5W=@#ZZ?$v{EItizT^K`Xj^;05Myiw1%a89!d#S z;GX9l`Rna#y3A;sSls?!=E>LHy@?sUy8Hmhh?+<`Mr<6ZF+l& z=z_!mg&-@JX6_dhQgxfeI@08uuwlEImG&B(7|s7>KT8VLJRv-a;&^`v8F> z8kGIyCOaBm3nxYgEyIP__NZ81E|wDhhSQup3lqYIMB9f&OwrSlZ&%jHNYg9zb#r*o3}ivsoatG1O2W3)XW6n$*B%N0x;^=JSP>5w?! zJ;c`?IH{2gqjwIm<1vvk=qDunO2`M^x?J>|-*t|dz1Ua`=66i(Ovg7IlvUz?Y4p2r z*Oas|Sy$R*3)hRqP*H7!u0*mr$SeVO^nAA?IbFGg$PgPl+mnXuFz%&b+Yw7?two35 z@fjG7!`7gct1=%xY^{4D_4`kqomR#=%fL%Aw>uA*n+Hyu^tk_^)$5Zr(UzVt0`v8u zg`ph^-m4u?emfV8dY#kQVQLj;#bx(`qt67fI6l(!7#!2@eEqP3-_oBi<$d1^@Ps#b zEkAS>o@qI}JZgXbLE$%647_JG#&7@0KZ}`DB)-%RHw9Bzjy+VEKoeWSTe}V}#}2*q z$;0@3=Uw^eI<0r@DpoSM<+s}E8qwoo#-qgyA+dKMD z9Y@oH6&wU%617620p~hB9~yo_0H``;b4o8Sazqq75?}QmASpq3dVTf z@h>=4W*f*DV3cY(F965#-(ugE=#|`|_r{$|H{i%qcjUCfOOpbQFFSd8dedaC)mb3z z2@qPmQ)f-puPH|NhqyX8X+ZfO_P&qRwp86W={zW#d`N6~u@72l?I{{yQ2 z@aKt4{|f!A9qu`s13#XBzW0NV{@|1EoMC|zI?8aCJd}n(xSgwl9QN9Xll42^E@;DH z{0Mf2GiIlr8!4=Gq@6lbVZ;+a(E|d9F2|_~G$Wvm%#{Nf4BXip-BJ)c(M{=%8-;iV zhxOSX>Jx!RhQUG9fU{OwZKzw_JR@upAz%S*JRSr*ETFw1Lz7utL+gvxsTUoyg4-X6 zBeOd)M&kn5%FE!eTyU&>u2}{}H{%K2LSVnI}bPO{LQak5OaUK{Pj338yqXN5sw~o)z;3A_-tB z8@#@gE-tcC`}c9s5B0B(r80&S$K-d2%Ok!u{X6dF8HiRlqiIdVWVw@X0%r4pCtNh@ z6JoHgCN0NfiwOrJ(y{lU+={)!{SfZhRH81aYNyB7BxZarg_7lq$RJivDS5i7?y z)NfaB3o8~5i%i8zZE$K6E!?3k%}U>a3oot&PsPXp&v$fYjY_S8f==gL!7TY~IAOf4 zcIEjeL>m)4c3iMuYM%B{-LuUO zWX9YdJ=FPZ8FAhrWl;aR#9E!xU-`B79E-o-=<4y;dD)x5i+_Ij^E~wzzSQ@61sxH7 z1TMv$Kfn5&--O$OoAU8}*$axN&?maFpokny)=FX{vsXKI*?1w|+aAGY^+~p z3P$O5n&vp{A&%$HR6V57Z!<3yv~xSFt;B!K{Gi6GuNGF6oKi z`knapAAf-RZxkxMOYeC1xO#=ZeVrfvQLG2}CW^q9_yG;+e1#W(&lE==fA+~g{_bxN z>Qu%FdAd7o&c1(V%*nw4f_Wam^o{0}VGbuzkCX~dEb}{kFzAUU%ID%3h z=E4u?gcAO|uOyyNac+~%;o>j&3aRyYMJ#)(Z|z zq&d6jZNlV9M=_?tdutJh?b0xJsnw}d`ExXrntoALYrhC)<#S-EaYZU0hM2eh1`OX~ zgR0yKayp(qQ4ToaVeYH(LP&Ky{oy4Uu8C{zMFkEpm2sH!KJM`x(!aRSSDmO0Yz4`F zv)p2KhFNFkytoGN@CYHyE@|HPWBtImQzu{>Q(}x*k&Q^Iu=Iyt_w7wE@JoO68-Mosr(?27TIT1Y2j}l=P297b*fk|M zRRYdrOLp$YVt0O)@7ZXj0Ass5yi4D@P26}DKaP2YK5^Bn$GHH(k(G47toVLH(3rEq z4J^@^nU-C<9pMj@w?UaZ1;eu3ijh@$|Ioej)Z(WTmX7fNzjDB&`Y6lmYC?n44d=j~ z>M+T@1JaU_V(&LVd|WzU%>6l2;D5xVwWHYR8GDOa;pFF4}9sQw2ij zfaOW%0W0%h^x|ImmkcUxFWpouJQcA#?J{+1c)nhAJjXeA+L2U{J-spcHm)*^ZchaI z#jfKMQ^Ynx;6lnH)K(ch$0xgRxZ-xl_YJA~UB_nZ*kpL|5TPyDb}|W$syh^~^U?fU zFtz{!mm+qb1Lw89FK}Snul9iptG(wF+D|(E?_Y|~Kfgv;uL--}#A|+l_#ZyfJN^f+ zcctG5)_;Fq1Wzot{+~bmH3??tk?GNc1&&KFc6Q*Xj;2jr!QC#KJ-i(UpuaVuY0ev-cs-a&5(oFAa2--d z`N^2$jt@q|8TPAQfp+g#;8(V)Xj7fmDBGmldd=@X&8Co_@phd(c3OZdpaA5((s!d#DS3Q)tIin= zbPk}F@R=Qvc7}>>U^b=OGciEF)};`id-=;lE0Xf$ctlBa-x4m~p#=IY`69;_2vHtf zb1DW3Zhd~kKb2L0@RC~>Oh(}Hq7gB@uP`l#j+F{E;apbQc)Im(ZOhJwkf$e$Ug5wR zCK!z%VwS{NnRn!4{o^3=gkSYhG182ccNNo>AH({sMXr43yZEJFc{9-Otzkx9HxS;b zPmAZgkbM5j_TyC>@Rfh>@nGqvnEX8bw}zyLcVvxU?sCQ3>ni;E_rLj#kN#l0CI_Wt zo5@po7v8l>(TUlGwcPs|5O@i(Zs^qD5frxJ=aVyE4fNsYjj|6{GEM+zT`del8pdvYVh zv6SPxVn8AX?{*y_Sze_%nPm|+maZlNVS!*q!h)wYG;zR?AYhB{66^v#x)Y$WolO}G z>rf5O;QVR}^nxejP46G^VzyqhP}5qbePp2oH;%0d`CZh5N6aGJs)EcOF!8*Q;!Ojn zDjrAwRQaZ?Vd6mE4)ghiV_Z%(Uu`$c;fS^p8lJr4O1g*YNPX*in{G)p$}Rg*mBrIa z?rKh81-7)kuqFj+9Jr4~X;?I`#xH{Kg9xGk`${pFqQ{LrKADjk893t1rnd*%Ak2Wke7LrATgT0h*BM z+<(i+y*sic2_5{^^@LSHvdj(=<R{}j zh|hNkW| zzpyc>^AX%Oy-O$njCi)x&QRNtsQ-==pMX~1QL^hM_rK?5?Yp!N3`>aQ%r-0Esp0-l zdU=s`sYkE%qcmHdauU%KfN5Rp-8*4ZyY^W~4Qdm~72*2KFaGDlH^24p3xEGH;Kuhq zaq4};q)(B^^XK7rgV-7(Jmkk?4FV1_WNQ5uU%n?QD=E}*bxEF-ZfoSdKw({ zk%1S9sklzEQdX`IBArzf9*S{*F&M^{CX9R=|{w)KZX7pf3uO8~)Ho_}mXw=+Kx@?_hsGdEMO>nNp zFu8o%BL>?@AvWiAx;GT8)NQI5)=!{7G|=D_)NK@J|4vhyNse(uTbuS*7-V|bbVK`# zGAw-zcKhiFZ9Js65Z@-XH;kxUI61kPVV@%vTCY#;$*^+0AZi^_(swbJ2Xr_Q+`R0oS*Og${4d$fI7O$2E?k z%O6z@E!(AVw}-GIsacILfE+;{^lUH9A(uT47F^h?J+ckB=ags&o>Nq}3kdoIvRePX zc)P#zKgV~z_av4be2j+YliLDM>=Jz7^`8$_^WFYFD*y-pbFqGds&Cgv}_zcvC zm{XS!YL6Z~fZf6aF~M?l%L6tE3x^**1+i&E!d9A!evC%l4=gA=W~E z7_tm$Y-r}MUjeO5D6m+4KKq&!0!vg%%h!^`Vvs&fRF?&6*OXK-afmf0w&!ZN;0zfR z1la8zOU6{6V~*gko{Nio>8AFnya-1qFfV=Wg`Ch%1zK~mUc7n+eWQ5@=#xE;-bbQL zi*#Tz&4{(DV#>qFdsbdUQ+r&@gmnvdngnHMmFo{9cpd84D|J2g6g|TE6-tFarX$o+ z!ZxT)pJ)|rSWWmRA3gkyzkP~(c?{3Qs61a82EG)({Ufb9f90#lC;any-|@$<$K#;p zNYB4frOoxO<-hf`(qev>FV7C>CEoXc{KhYS`;+eua&Wv9iim8|of{cZWy7#-DfPJq+o zCP;^)RymYYiLi^HmlKRBuGvQm?V*2ATk}R{*cnQ6Yh}8=rsRN9MQAUK6cmNjfp0`F z!Y~gV;)luy)&Cz=K;<7`zuz%@#P2!oiG3NqY0NWRk(7ioj_9Szni7GbA>$ zp~#iNz3IlbTxz)oT6jXup+fIUTB0b4ZmHC=r_?klb_ZUWh8;t;H_6I0F&ZXj=qouo zl!#$ez`d<$1~%v9T}VSYqLkAkKc3ekZKv9&&6y@aBC^# zVgqOUjvl1EO*6~3=tiJ*t$0isu~88GqhH6*|H4zb{MUzOZ#8+~c@gg0Elb`${^nc! zUB1l!d>8uwcwSQc&MUm$%i@(PjeFgLm-#$+t}pWU|L8aV&u{&IC#qt=MCu)l z%(GqLZbMMcvwKXBAReaIYN6HQcjXKo5Yd1R{H!${(f&Pg z#s{;m3XAJP+C}jYGREn4icLoE#JWP2rWtKq*ATGGj=WhM3ojZFtX=m8ory20H9*gDj6$;o{v+#k)H4ZZ`@j_W2E)pjerIEk&pIk)L(l7fSbk=;4y zT|0(|*5>@Y3xS5^@5A5zyZDFy_zgfXzRV9inW=vD65?5LHx*mVkUveQG@kT`f^T02xNf)G;@ zYp4~6_8Ma5@Mu*8bwPxT`Ks1v+$s9n@)Qg12@HyfA$OFr`Yo**XP=?MUkQ;x9V(FS z+mgwQq^Ye!(4<|^&=Tc2bWbb8y9U25rd=7+*tgX+jM=`!VSbdpC^wHRhC2D=wHS=+_QL{6*L+XZ zAM+eJx?6SSZc;D;!<8OZa z$A9fN|JTn-;&JY3o>F;L-@AJz2Pa{Ra7F%>^P}@=YfM+7YM^7Heyj@&gGxdKk71xP zBkvrE@W^K=9ukD@r4SF{qTE|a>S41nh#PdXRgcqM;ov?awwx&&SG`IJkdKjm zlI*xzmQC%H=qqBgS_a2WhOs$DGVvW9S-| z++BcUh8OpfSwL!3aXr*a_|BnjUGV=BmA*hHujw)yCE zA{=BjF4~c98l)82TP8zJLw6Ly5Xvh@qEP{ykHuzUCYwUf9CJ)pE1i8?z}K6R%HSno-JOa8&#hU)mk%?azYO5(z1{nd-Jg+@ zekv>mE+&BUpVz>bPX*sEC-UKweTQE1;^0m6#eVmrZ~qtnCJJU6} z7nLpsUgs1rD9(LkA`t?Er>hahW77L0ZFmVAl)Zs*IH+qVfQF;xqho2#ZA17l;QMCa zt!iu`$&zRnm~BqnI!stv^FB`Lw^MB~4?Zv+FAbLs?4pINaal1=F4>I%!C-|WU;q)o zLEfPKFB3@6baAI1l9zfk-H5~`QRNe9jd*zXCSog5tt^XZf9CUF*`#5W|ze5{YS<6AjP^me{vzy|TAUDSK!c1i=lo+|DSZ zz$htTzQJJMG2O6&{lQ0TQL`ds+T9t4t`@dNvgS^PTP;m0Xtb@=&WO6__K(3I+o~LY z@ae;U^*8aq|KbJseuAFo-jBU1JN^<_{K+;%Pwh_d$#uw=T`IgGN}g}*hu>z$<$21U z`*0l3D6=`iw3nijz$L`gx;1s zogC)o?sX2kHB%?!l<0IQ((o;F+)Ja_;1&F+i&_(&6_c`vGBhGV{C-b6pm$^CQ z>;<2+$;Q*kDNb;Bx=k8LHwlnj2ztkZZsD`-3HLrcckb$Ua8 z#S`?}(goIc3C&7`I=EW0*=9;HQv>IbMl)WDFdOVSL8K+eIyRsK1-FIt86W=Jzx(iC z|E>7`pFW22ck|g-MQX>*5N{J^z9X2PuR9w1QWijOn)`oE{LOdnu0A0F;C0J@3pvnb zuoqu~{(swJ0DKMk&?ldN_OoCA#lQAjKmW;RpN<=PvoBV15=Hcct54g59iC|^kO6bV zavClKhm3lnsCFAa=O|1|8mJ$%(v6o zYYNM}3wE%ri9!6~kVCt%=A&gbY1%2G*{s{eh<{WwIp>Wyla9EOg#@8K=a`)6{$=$F z(niliwbC;5l13@p4yk>LnXekNI2A?2SbK;bok0oOVYvlnT{Es#H3aFC0x>V0%@@%8 zat;R=qB3*aX>1=v-+L5#CHUCp@5vdq8b_!(W_!*4a~mXhhm{Nu#YPLU9NtILpX`p>(+aGRz=^oYdzJJZV3%({i7HypMRh~OETa}FGy z7MU)aI3Y`~RoJyF7?xgz8G%-z)7EJL4kSHKv9nz?rZ9sXqZ$M;m$>@y_?=SZrx*V? z^SS@Jelw|0#IRTPG3p-C^Qisx%^u&JwHm9!K^Z2gw+QcJ;j`zI6Wf?>T|O-dcna;_ zcA|sjkGgVk`@|>vtJw-;&rw5{49~z9GMxc#?Z;7kj#P4;B3!A=DF6zre&Y z0C2^TKUOU~iA2BG2LK)e`j^`MXXzolR3Y@W?|{N6wO&F}wVIHNrYQ=0t@lsk+8 zGwh#Z_O)H{XclX+E0%ZK_jqkaw&X}W8bTeO^wfGZl$*&qKsucE zSC|tgXn~U((6~sP&J^}GFc>^8FeJaBYik@mP}f=Z)$SxnBi}-xaVV8v{1%!Fn<&|4 zBTxweb@Iy53qO!6AQVmCPfAu~$(8-8^%8P~6bY6IVbup4F^cW1tg@=(!N*i>(RA)! z7~)fpPonmem_{VMQada=S^Tz8VapC1PR+3qfQQHAT1Am2XX`SY z>%R6gnjfnDdVw4chq~iR58;r0JwqCH&f;bTi|5(*T~(GuE>0;=^;R8%;Y82{TW%*SAJkUDt7 z32r)S%-sT-%rU_{h%&<+xz|G&+lv3ek#cgvSxc1Iu=ueAYAjSokDQg5l8H^05+@5x z!92sQdgr4@-}|czTkHxGu%LBg2{{)-1Q>Kcshog8zRy9*$L6P{#!Q* z1Zm#>_J(FeZ$j(T)R*CaM+vnH_4)%z-V?>DQz$voq%iOOx&y~L-#4A1WK|d}afLm1h)s1< zzW!CeuCl zD4NBxpFJHs?fkffTDA^Q5)9I7;Du?(?Y{IB{D|#IA1Al@H_d5&T6gG47WEPowY=k6WGIH~e{|u&E#W;~#wdtKa+mU;Xa4{?Ye-|6_jY zG8WOF7Pyonl~5ZH`IL!}Wmjy%B>A@VFC4W6Wxzlh!iilh>=KHIls!~;y)j(Lya1e> zU`x1{wI}qv&Wf&TFlV*pPS z;o!{N3!JGqjl=2lEY8= z?PQD7us+G+0s_!zqN+y{_aL1;`|S7O1ySD$`OFU9gmP7V39JT~eU&`I90Q~IH%fcJ ze;1o>#Vn0-VaRZ$vVJ+!@s)q;Kh-Kql}L9a11OB#iWZmlvO!=sSB`>QrRbT}mg?d? zqYT)>#KHwLCGu&eRX|gfe|vUlf7nwbHRceA(T(ystKg}J^9HEPXR?R!yEhO`QcJ;1 zU-|Vo+PDJTBc9zefB^1}N24~F4B?xd7KFIIy;|)fqDaE}wxD%>7Eae+Xw;nvAiEhP zbdp;;E)LeXD|4XT7)cGRO>wljmheXVR+|}cNc*z;Ty_)nT%$1L{js$BMsHn3_g!lA z2>rKhgOh_0UC%RhVjNKH5XMp%%lp6{-Lk2@KPN!!7G7~NvR$4<#cmy=Xvkl0? zny_*>vtP3aw`{z1^aL~vn?n5!x7~L0FdJyL_1$fk`CK1)S)X5gtDpJj{^(!DC&0lK zmRfnvPNP2RG^=Au^Kzp0DXA#aL&`V}6Kt4-fbI1GJ-~Trx9Ybvfn}W?Rq@jwA6t-u zQ#QdsnqSQ+rE|o#J#Jb!_tVn*_zk)K0H1#ICuqbinyd`%mLp`$l%`g|xCX?7ysi9t zH%B|BgZ;8oa>(j7x>%WuHT&ZE6rL+6p{;Cd=Va>2IT;Uf*g$O@q*nI&f%9+w?DNk* z{`|8){ruDKefop%fBMO1F9tPRoN3&%nJRY<5}H^us;o_NAaJg5Y;E0+UVYN3nSGg4 z6nI9_MTirJOMr-;0>BOM;^~Is*cPwA;T|nnnid-mne9GG^<&KDix*eq_ms zj3EHFc6~I;z!-nEv%5a8&SJN^Ngk#8j}s4Iinzkt_ukfKT`BiGhv}_bf2m7zgR7n2P3>ttou^}9u>ON9!G5?i8U6wY^JCh z`wKx+;wC!Ba0-n9ooQZS?)}+Yo^(To`4fho%-4WKR=Z|)6Ag;YFQ&CX=8e$IvvT9e zW_r&f2^CV}t?&xG*PKkFAiTNoAx#@Gdi!taLak|s-K!hUCs3$`>se{N_SVSs=0{KRAMDIQp z(Z_Rhr?p%65>Wj#DS;(YNGDGSJIgl$g{B>*UUqrU-j=!LQ|=u_?dVcI+<-8BH&tyY znmW3qSftXUR?iQqP39vYF>q+Wt83UKCPbu(;icCcnM9Au@z8vpm!9&RRymi~wf#Ay zkKWkRNo!$tE%he$al2-Fr&e1hoX`YK@6yWLp=H&Z<&Qf!6graQ81t$3>KTq=gN z{Etl-Lw=-p7GvUTTqpqmxkXyy)+81jg7&8r^}Asr>5M4GU=6;hog#w$Fsoe2mD38Q z)s0*xN~H`M#JxT5Yz0Vel@Be*T0(G^{G%&yh9#X=rCMIv;3QB{Xo^w<)tl;!Qrnfyja|XUve$LEQ(`mPv(}JDyZJQBUU>_`j8t=l zQNq8LExkJDM%&r+?MMk4)Y{4k_}iUEp2DQu;CjwVqVDFhEyJh{wjz(!tG9fTWJIBx zp^_qCEztGoj0^}ysmG|1QTcz8?Epz*uFfQ?S;Zzod(>yG&CW;Q%5;c~R+mk&@gC_V zif-RMDveG`iRjF|HfUXsJ8k4Zi$;q{(-{OBE#%36xp5)$W7cZIk{5x}f2n1m`Qp4? zZ^Ha)`=J&klJ-;C4?)*eJq8k(7&0)7SEH|7&nY(5Rbh$hlvXj)*bRVXD6T|_nw4Tzd_K&o%&cQ8QxKDKOeK0NK|#y$W^a4QLAeUu zS#`+m^4uQp+rcgHs2E0N{ChiJ4TUDMP%O_0{paQDXU9xJUi93;S0$~zQiGQ?kB54= z*Mr;?X`R(T=R>ZzbJ{0>P?%H)22K&THO4x37tLechH<%IS=;0bBbD9D+$lOaOb{wH zxHyk%$b!!nVwhf=g=R84Q{%eWAij3pfF9wcz zw>dl;Bdm2JqlGKU#|H)gX_c<)e*2e)4zI1_kupF_3DnICFdkbOHKjSab|6ueDLR8( z7cHsMf>@&Py6pwTIHI$MdfW8+Hi6n0Cynf-0+6n90{XMkh?0xuTNRD+L%|SIb}E=V zxB-adi7% z1zSeWRe_64@6(=0ov8wxq>Zqv}sg`xI;>hh)L=Y4-Si2j! zGIeh|6szW!3DN+n-V;i8+SDV4zf*F5FnG*{Q?56sg)s6~?x0hh6GQ>MNy5Y}#Vu1t zSh`T?M}U?@m}!KlZiJ8^E#JwJYRUp_hDr3N`L6wGyAr7xn(VIBICLdQ+W1G0K^J~u z$D-FV&Ea2ylK$1MV?9k@Y2mAi)jlJ7^hv0N+YzA18VMkR!%|p#oP~a6_9JgT%kP91 zxCR*tfX7t7_^z`|(!e{N+3!QnQuZng4f1;H!MVlZt;fJ3eMI5YycQ~>8~qdQa6nqW zu^ZFL>Z~unR$X08M4#o{lwEx(Tozdm7pTQ)rwSpYhgfs#kW<(fr|!Zmvo2|W3GKPK zWy-0te!3kNI+wIPz+e>{z;Q-Y1wqJTqD4|JX4I@66KfE)(XsVPz5axISlAM@!Nb1b z)O`#-C#R<6!bpo(wI23@qu_%sy(`x8?460)>RETt(*&|U9J7F7`H<9)WlWV{)BM)z zwuY3aH_0E$b*k%OKV2adKu8!6pg$OitjdBw?fA1efi__@9!M?!J)zT%Fd5XM^;l#) zu{V_lwG!6`DnVZ7H&z==wKV_)u`TR`+aMT% z3SuDI01dXWMx|8NNY{O~QlE~o>BMZ8an_az^TNq}L-sh!C{@cC%RsJ~Kek}gtVm_w zBIO&g;zob?0uQ%;uV+RqNmvlE-9}j2I!bCX!~ea$kj49s4cWOkAa*Z$v@)^2bc8^N z#*qmfLGQk400HWVsVf9_g$Ab=v$xP5>>yyi_5^HLPgbVLdwJwh-)-Ktj=DaAX*X9lE~9(Z zBu7xCHq|@q9F$Dm>IsNCB=$r@R5JzDZoDCWiq#Z~R9rMT&{s2iR0}20=k!Y)ii!aa z8-xm5#7Vi!4%T!k#pqv{U{J<+V|?u!Gnb7pyJ3{3lX;b~Of96dCQL@{5;SjE!PTk~ zpgJJuh6yJBsxmy)xaVMu6#k8qAoT!4?8FvgYw>8ffzxf{fpH3bc^L-ytx^uNAW}(F z9#O1wb-g!RrdgBYLLs1gp^;o5m2RbaB>S8rbD1{mgN-lIWcF)?HxUkN;U&F5Dk%va@IVT20O%%-lYtjcQ*(%40zIiLpB)R={b zvCI^{5gLuNuvDiFGdo1R=htIi%{1+$uXdUYmNchAIfaukHb~jM6(w@>ie%3KqOher z^H3=?LFFPyG)^u63zyfisI^eCH>Y@NgeMy^QT~G^|IDYhmQ)Ktku3ti(zTjkNfzOY z-~P(OPyYJ|P6!e@>wJ4H2nD5CrK{c4B@|kJqH&+SZ`9d5JY3=P-V1s`+wK-@R-w!g znO0W^*i#AI9%<=4(7TCDr(F-&LHER!BNC9{@!qWqHKg=Z7lsR4tSu zF^u`@n0di;IgMp8z~)NTxf!a0+2ZohYYH>RT=riJNUTx-BG;?J4v0OQvivy&*bM{S0%JxaIh-YX#20b@h7)&Kypd=@}o#|L1;?2xa(R*#w?VEatK zRsZlTN@|@Q9#N8S+cXyX7*Y5PTO{>u^?%hBFIhLL<&Z*^j#&|TjI?!4e+|`~659FY z{sGzdu8xV}1usN{nF5|{5&L<8E8<|hh2Cq}mSiSuIx7ctL}_OmC}-JB5U%Y!MQq;B ze9;_$*-jQvK-m0*0xYBqsZU*WCqE!`r|-#BxYm;u1_N|kN1e-XV3d^iJc#*y?(NH25sD;zAvPwL8Uxf#0%X>#wq0OYn?NgY}w`^ zkv8mtZVe)5Hq_u0kdX==L{!KK4LQPMRae^Xog0Ug7TV4Ri|w zlRa}$dbf5@lQAnuu3(XKH%L+N3VOH_8{L+Mk(#Pvht!N%gm=PJ5eQ&VA$F8Qcv7ei zf=Npe2RdWYIMSieV;WVuL4+^pQgAp*Y6aPspjb=#;-vXv7N|8&i|%g>J*N%OW6YF5 zXXm888UVOwHv?8CH3M3%_QovOc!V1WZqy#EZs>w|pkB~QV%2B&RcIc~YU_saQ%ca6 zvlETv{xa-w4v#y7jxxcW0<5@|<}fXpGcYU#2T-j-QGF@g3Ww+H&N z*(0XMe1J`M(MrBRY&-D$j$QD4Q2_9832ZQWo@(|4+99+r2!9&K^8sv1k%(h00-SQt zjIgxRdE2}7#BX}9{4p>gOO}N&A%s{{DDwf?f&ENX(j15pg<-QI;++HAz4d^wRaCPP zmT;hh+t4&5sOHMEC>LPiR2|3l4WT|8Vb?k+;)}3R;xb3W3#XO*JVo#jUNO z50X$-2rrPFKa_D|jF1z7M_b{f_S<&WN*JDPFHm42?0mQNOr42H+cAhwdOX+Jo%? z*0_K)`zk4=a{_%+4cnKLgvz*9*apHV&4Hc2z7N_i9Wgpnaq6RDoJ|%>>Y9P*ivddK zKem0cH+x+Uz;0I!)tSy3cyMsonuKsxvROz6m*wj;w=^gz9%EY-RE>G;#_oD;#6g@e zB<#kGy#($Rq>#B7Nw4D$ywV9VBlc@JSUeKeil(>3_m=4Fb?q1(dKOQ@5$YA|w_AE~ zQg~R$_K=XH>`Zuw6g7oI2+wrCjtQN^M>k1e6kE?H(FZZ>P2nvBDUrOU5+x0 z`%I}9V=4$?ikbseCEOl$d=7`8*r7)1fF+$}EhXZZs(LRFI9SM}#;W zl!xt=Z>Pt)dSD1`C%XotC^5S`15gg`Yf+1&FuLV z4Ts$Zgjd0$soVCn>W*$b2W_F^EE}*ZFHVmbdM9qxW#9m#V>a11uD0pF%sEIr$YhVj zmdSAv)mZa$0){OZ?-UF^0nL_ky)nf8x6Wi8c)wKt&q|F9GX42*4Tw{DdUhakj>xRHPdO1`H*89VEw z*Uw3%xfE^NidkoDJj9fY+Q8~25D1Skh(WAchf|aYzKa+DQj0c>{^CXqcb|Hr4kNr* zn1B71hoAiE(YBKyHMCwV!ddLOJ7P5Eu+Le}J&xAU@#AU)_$bnXT`X9RL~I4dPVkG2 zTcFSQC#S4j1+}z22_*jXAk;--~Z5g|u zp7d27y95HUDO&>D<=tv`U{iN&&)AH#Qo3_oI$I17&)(5)!cZdZ1kaSEsYW~wtc8k2C5SNr&0K!S;c@$EV{T^FEIK zmh*}^3p>6Ew%LzE({qHkaf98M3UM7O7!u&wC$Z1Z82rV#AuGoK4v1&dB@VvhM4V%k zF~iJE&x$P%1cKXCS7}3-s(bS`FP(`jP39-Z<(hh1Rp9nUF1k1`)Q?6m( z$v1)tupl12)pMTM>zvq_L@Q_ysMLB0IFBv)PM9Jz-D|g7KleAdy3&$WaNyK9nUvtH zF2>)YIdTl!BcG-@{7VcOUYtZ?gU$3#=gyGYV8A#;kM#zO$qnO|u@zBJmJrt`tV%HU z|5tg}ivobyH&9IN%ti@t@@v8Ae`fm#&;6sl7a1ELJS8PKVb%>_`d|kRvZXQ6E2s{W z{=q@r=*tvagMz!7X`DC2;i_&DlB+G%&es#-8QU37?Akmw;=ms5I^CV)iK~{JCDQKo z*a^;YBSfdl-s_&YfTB9(IK&m(og7_An`pD=(Z|P*$C5iwsgaP<7#M4Ne0*#S1e{mE zwspqE7Bdcso!bN2zyue4RUD3b_!QT!6tYV~>vfK8_qf<5#Ef~N&KeP%Ho*-T!G{_r z0dM}e8^qW-ssnecO`wCUvz22wEI-rS(M!IQR#Tpc8A=9@kp|3)Sz-Tu)(*(>)e((hxs;((zJZz?LwoUvGhe&lUKczOj zuo;cEq5XqbS%^(|u#=dxv@@xd7Qi#*oQFyeIGn<83AHY~(fQnzkOyI%i5AAQf3a@> zo9<}vr-_<3+ z)#i-A!S{kbs^ud_xLTh(XE$vvcwlBt!4W6*IA9WcSoU-A9oUxyVygHtu?%qV3`d5`l4TgR3X}>4{_Av%-39#WlP>u+co@CwL6dR7z|+$Z4M8#E4voZSLcYBjZ&n{=+aLWxqaA zq|nK>fori%Zy$zcFfJo-I(xWPOz~UAUo`W~E3Cf$2jkmm(Mlhyg^~>5_q2QtSgRX zBoEIQPI{#I6koJQ>@?x5%5X)3+CheUEJmNUUaP`5? z?Nb^g|Fy_bjsw+i>v@(~7WAy0a8 zpCyO`(%mgwR8blGDS5iQ;6$jG*Q-zClW4j$T#c=>{V8j)$#zDP2i87~&&u8cr1_lnC`<>Hv z|BlDY^F5;QJu$<+q&o-B}k7V4d<&MHFjiV**9Pn{ctUXds;^KSpbcXU^vv}`J z92eR8M3?yT@^6ozHV(Xa>@7DujpLZRD|c{n-uGhK51e-fUf`-D3CQy;jysG=TwlpM z`ysE7fNgnfV-oidwOzUvBOC% zt2JIQ4tp2qsv&=MYp(VIoE8SJpXjSsj!8&eA+bYcezk0Fe;(rQQFq;5pK2co#|&N| zfaB9;;m2|B&ymmI2>`|EU3eEa^O~p_pN+bO-QDKUQN)Key{%^6sSu8zBrf4K?|gAy zAKSigdAG*UFJ)wH<&9lkWS%Mz&9I~8$XqEvbO+hQ{q%2&)9usnm5Uu=e_Z$fiPM^Y zVo6~6Q0M!?xZsAb7CE;2&h7igA+lxNHvJh|dSpcunqQEmg8Fsf-AA>5hJI6c7y0oX z2gU=CI+tx@$K=KN91zGfBzyvFk6-k-faf!Q0NmyMzcY zp4lsq2T43W%JcU7%WY+z7)||Qjuj61Z87-pTgKDVA(2J>3FXsZdtSzVII%ttxA?f3 zV85Q2k0-ZVd91s5a`U-jQoVi}PWT8s~k$F@*%o`byL zk1h!X?#~EgyQKXv@^F9m`$+j856s-e<9-nr2kL1b;gnlY%K=-ghpLEY$(Ln@ZWx6k z%JAjLxF8*AJ{XLxZc#k9t?(GR-aMgFiWro4$U+|Fm4_POire5xNkyK(*$C&|?qhEv zoCo#=)+7&*j@#DBI00z#@BwV2gyZt-o5Efxf^TriPQ_MTT;a$&CBBtCu5Kjfe!U$z z6MO`&Dy#84b|NX|lJJ_0gVZD#r#~&hHl-sm#1y!$+j(vgEk(?qNr>b3aY+1hxWqVLIIfg%?Xy38N`w z;H(6&m7N=~A@0(;9`S15y8gSs3B=t_2=_ZD2MW(MI_GJEN4UKC81j-9#LhPF>LwhR zCTy$|&AMuGc}Eg~l3hm}KnNdMNUZ0_G@q~)o*s`p7OVR(^tRQkAZMQRU6U1p@j+gD z@bu*NKgO)Z)!nq6jkYs@8*1t}=dRWsLcaMG3m(o3Lg^CDZL6b-Z*zs^?mzJRb;Lg>Nu^qO1 zuSuR$8!?mr3E!77NUaP_=f-I*(u?O~Dc|KtG9DT+yIyc!K;1WaC?0ghz^21-)n@Tk z#1kujuBup(tl^M?2R+F)_}ll22b^L3yIK&W*JbMwY=9NsbE}1gI%%kLA=FKON1kws zZX5&qO$TG}LdmyrHkT}|bt?$+mj)F=s~OiS#dI69mD^h-HEe#;9FNFss2v#T^C&}~ ziSax>1Cbe8F|y?5RwhU9ILY$vgJ$AE-!PrZsQ2zrIm7zoMem3h({&q8JeOqa$jdCZ zX=Gxl?zRl0JHVVvhzx87LNLPHx<7{zEOb2!OV_GLvAcFJuCT&Zt-dLo9q0uEt`ry8 zr68<6jBN;g+0>0N_YgZoO;IN_8U*OCDoVAufSwaoId8R&HpaQ!-G%9KnAnCro zIrp7L+F<)E!)9}*)(f(m$n_*o1hAWucI)7(Jw99Ryy*O1_b_SQgR=&PyzH|+sx;$S zsxlYbh@0Jy`(q;=v_hJj<}e!GFdlKv?Jgx0S*KAb*%5?1J%ERfjIMULhoE}`%8H`y z#t#tA6k~g@a|zrkR}L4`5qTqi*xi+-&xOozR*PyFMpvuIH(6<(=3mx7AA< z4um%@auZxjn)<Bsy{)`A;{VPI z?o6W|=kO0KCp891tSyF*yjX z32#4bJr?R?slHIVq4-MzNL^pLMbjjRbsyM0#x2meF+-Vzhj{3(5`(P{<0!JpM$} z6(fj2(hW&cD}RLZ8%sUp%j?8u^DKV!8VB3kpUOEZeJ4AmSJx1tnHDtNhyI#a4UVO?I(R|&NEcp+9SEY)It7G_^s9> zs~D-|*di6UPCg#e5@uK28)0+zGZo@)Q3IAS65H?g2 z{&a+50Qm8shq`w8r~#I=4j$(sJ05B4blTBpZYkiNx>e*Ntg|%gXK5ru`2_&S$cMd; z%H$RZZ>tJFZ#95+wFtvtRE6H!8>H6aE(aP4W>9cs`3wR!c917)UyK&h@FaSs)ceW{ zj{Ii(pV@fTJRN88#HbSWu(rg1)l^v?L*Jicc!{*>Q(%`yfX(xD;e(K-#3(qoXBoO6iBIQpN(7BzS40C<}j0H>a`&d6@G zf~s+6^fA{|3pP(e+N?xX$*ix`S|+w{oJ>s(N$)=Rz}?fiS0L6Y)amtfzh*!V5(Ok2 zZqDJHAT7F&QtHUulx28#b-{|PU_8teTtPEfOn3{M^SyOG$BJXF&5XMvqEb7xDfWgr z#t52DyLpsL2W@$o0--*zEO5*Q6JxS`Jr=pwuyZzPvSfAvJ$qs&kHvZ$P9f_pUx{d} zUC1D>D^{ZdDy(Tp#4rX$GA}p-mxr4lM;nWI(*uLu5l1)HboLH+lWIO7Qvbm?ZV#QoLUfkAB zyb%~%|2<9D=1;D&{ zT0_@y$YJcw({w~zO4Cbpv^FQfIqAmX>%`}P9zy1mV_xVcEM-1A{kAg1>8{5_eeGfC z`vO9ZSF;u!5u&(&c_5NQUy>c3{$PevZ)-mv@3kw!&9pftm^AnmiO1lf zhlGjUJ_+=cuwEn8Kgp6)sd3SE2(`o)R#?C;U585N!@V`k;6yb|Hp7G>rMk%LO4Die z5FL7vNZ!mkd(mwSr2{s`n8H-G`Fr*_BrCF6fMGYV*enPZ+7o!I(1h3MFtxH|7?MPb zGzcHsp6jF8)iL*iY)Z{E?=VUqc`x1NWhkvYRfD?Wdeh;yttOqy+EBrsaX^dryycz< zw@;|(HyldEo*2D&k5^*))TB~ep;O>tWbk4RKaQA}mgOamc$mn6G| z>k+M`2A%a_Rkx6x5+Pe04PisSnG|wk>iG|yhfJJ zyLWM`Fbt8S!pt#PDBTKTr%B}^iONzKp5ef zDs11`&HjL3n9q-nywQ&;XKrtTW5yu08lN#sRAz6d2wxAmXY;yw?R&Ri(r(t7sAgi~ zeb^&D8l$aA)qP5o@z7j6hP3qa;;|RW4bH}H#K)o%YUy+JOSDrp}WE)d4bzd~^_TEC)b$i}E+=3B>#+2$6I zSuFZAg%rwpG`A!zX|F_PN|@IphkP2U2=0a_UB{B*Za^Y#9u9?#7?tE2>^Ouh+T2i?_; zLOMals5qq8rcj|(FE@A>;cRZFr?8REYIGSAi zvf9Ws*Q1J6Fv6wN8YygJ_l?MqG*GAl@3wcYlD&>$tsG?17CM!Ld?K3r@7~H{+|_6G zb|rkoE?W(&MUw52rKqb4T%U*aj3-&Jc*0u8L=VcKC6cW6xAf(hkOb6L?1*-*vt^CM zX^qS7kwr}3vcl3R9U}@0ss;?ha97$qHl09i63CE9E2vk|Q={jw$?1itseBu!zsWkR zOTQs>Y9U8<*RA(osLwzhkl}_vV;*;5vOELxA}yw?)7%ShGq2#SHN1|9Jgu+&B7|EaP$W}qW~2Syx=+WRrn0HE z7VuPE1QD%u5htBMOmB&97Xd}8SO*>XHg z`?Rkj(q-fivJVvc_z66+scs`&8k&1cJujdT0#%#{;fCrv=d!*vX8IWeH3XgDHj$=# zHVUN!p+G`N*@PnNmO@%|p~z3REj9{MJV@12(h2<=>(>#{i;^L_YsN<1MdZ*0#?`7w zeNk!mD4rgrqo|64wBxxoFICC`)6oHHizJxZd>C3v&bl*6TUSYnIr`JxdoEo!>p<<6 zItyMxDP#WsjJ*q%CCQB=YDm2Wbk9OYz5m5E-c*Gf34pXH&77l_sxl+)b+-=*fB>b1 z>@kpnNqN8RcZ!Rf8EP!5rx5u$X~@~v$69FtzH+#A#a-xW_nEy;ArNg#0viw(B?gIJ z)KypBu$W83S4UsB$bn4#9|0r&{z;%P3`GnI;otq?m9VksuA2Smsyb%6#mu_;CMclV zcY`*jBJ{_H_*mC0P4V$fS%mz3P&g_xR{FX}K>B%ts&$14?Jw;-L;y1&^GaQ9=BP~@ zP{*c@ZgW~_!3cV1VQ{CnZc7BpamQv49B!|hfHy(1Tjwq*8Y;L&4>jlNmd-u6M!)#0 zpZxG_6oGrvI;xj5C=^R)zoK{i&v*2Z+7^YeAvwXWZY9$@x6mn=aa8f2g$z*jKvRN@ zi&^0!LqED8Qk98^(!cle27Ow%`6{-0ytta5?`>|VrIAw<`qw`vV!7nPK2 zlmd%^5%kpK9rwcTCgqOlL!JV9=s?_^E?RY}mxKd@fZBuABfG8Dg@;S6apwlF*yL+c zc~Zytm}hShU)53QGWP;JckG2d5CO}_`DuLx4!@TnPS3^=S8ROfiqEQ%zcQgThto(V+zb2`X8l^9>S`|0KPaQ8o(o|GwZ%)!%(J)tY6-il!O9o7+vwv7;> zZ7VII5j5hwRCknF@KGuS#blvYTQZU;LODUaK3oEYEWym*z=4t3mF_=$Si69E$aHAT@Y6&gKmw=G{KxtZl6t=ks00?Re?h9Hm4N(GqXEKImFYK2BKIiL1+o6}^K2SJ7Fi>{MVOlj7Sz{CD!QPq&)3H?4b*roqf6>i@7k{2-2iGKp8*8L>D&iw|zAvCKV295h;lm(43QgY|riO)lqVsms zml1B|X3t_mJTXMSQx3mo*#w{4ZazsYe1LX;hn$~?y2R9w5WhzD;VAPOYGit``Yx#v z@tG{9<`fPg&Mw6%dAdWv1u?lE^J}6lSL?TCeBf>e?Q4o_nAIRNFth9-K1GFswkdQ2 z?lNlZc`X7j%9%h5=eq4agq?2g5r%XtJ@%C_R~)CR*p?rulU}Prd-Pr{z*_5AxRK4m z9>dgY{h{^9m3wi{zwqDx6DE0Z?_tp}phxXV_}{oiCUk=JXa@tuNyN^Xx*5CA{3u?? zB&T~O5dK-A+GpVtU?P3AQDph(Tr$zM$51v>e@Oi`=(tKfF) zZ&8aWk70BOhvGymtX~Gvx`Jip(2vI+L z93t9#0n*0byA-7}5pOtkDe7VX&{W=f-QPEEt&=_>n30ElHR{j~SsM4A;)K{)3E)!0 zH{TCwg?FQHSC-zxWjfv2zA6w{w#^+H`MemN6?D9j%jfKRKDSpaowJXsKcO-+;&`Qkt{`v*h};)ERQ8&*7_3EQrOj6*cuF>83Y#G z(!!Uz6ndOd4}|0M4kg7#1bxQ&B4h1nBo_JW_UEcX1uR%W0@9w zr*5NkLeb|?try`@X9&l+_*az2BRilQUU{!Nnn?DAE$6bB-pQM6>_OKRJd({q$v6%B z!VNafu8Z6L+zlU|@ ztDz$b{CD=IgIf;x|5<@gSVSRWV>RF(eS$T>=Scg!;_Z$y0DDQ3!u~)fO zbe&DzXA*Y$AV&{d@;+-dbWsqj_^nCBYX@@KuoQ(>&p{kRhtfc{L%kY#ZP3s-u^;f7 z8P(({i75uQ;=(_IB9H6&WP_Cqk#sB04t4d5V7#HD9smcJy*Ij>7mp%ncmV+O;fJIS zTa(N-M0EPZ*YXvikXuWy=1{J8_gNr_Jz>;X?htp)P#~bM_t^J_?E!+CFgFstE2e6B z>i?73b!8*r>%S0`8VMRTQa=}2NXPBvySt&TG8oMpW$W-l=^LK%sv!OTogZS+U$9o? zNK`qmcI95W-EpC!2V6n+H3o#en|(Vu7I=Ko8m?{?Np}JcKw0RW-t>?%7j~SeADvo| z>akN?vx(Ke#@drhM>4I|!iHd|IfooikaB`{=-DC6mNkbvWhSCR%vs3ssSI*L&qtgV zV8eKFTT!l`iV)XRPOUC-R`FH?KaTeyjFuIQ%ZU}knXHnI-D@U)xiOnsvN{&oz&JRi zb#Eh{pvyU9*wj0T}CZRr&i@w8Z_lB@|B z;H@>FZo$h7Iq)r7Yrk<%N`m}(NaZv5aAu(y_&J5?ob#8431zSBn9}9i{;``diAh!-4PU#6{ z@PVliU4_daf6(24Ud*=9_+jeVhqTm%xWt%0IUDBr2JoO|v|Sd`AbN*`<0&CL6k8{& z@)NJ=kB4o4!(5R4;tjM)!&G(u_Y@fz0rx@4IM#j!h;0WS3Cvi_^B4x`KJEML8o{MM+Kbv6C2Y7>B_?aBYEbtV0bOgi`;BC zvV-e{6^=e};KooZ^xMJDad;MMRnnN~rbgJ+>J^@aEtCW^2g6J}yv;>i%SL46&KF!6 z+U_2Y67LO8hc@a)So<(m(QtN1Xu~cvWQ-B_s3l{ZWCC(i6XRjg$-*<|kIOqmuS3d}*hK)g-xA1x0g z8OUe^!svZ?r+8|#mLJN?7`1M4>J5M0dkDZUJ*3_?_?#Xg*%N{o@b5!Pls=*JhAkHIS!XNULqL^33Qi} z16FWtCg8cm(X2bY&<~^me+_raLVn^w4B-*j&C#rHuSgVb zJOiLOs-hDujXCh5Ei(>hEG-P12c|v~kw}7*5VaN^3dA1aTbd42olchDE_=wnuFG0L zG)3OQs-8r9k{m9F_KlGnvcR+kCV51bA&qpb(Xc&mn2yC)RxN2NxE#qlX9^0X6f{d^ zAsWjUqqt->h&_&NMkzdF4ofn4n;KfVSWoP!~58PWzQD35Kcs@sOr)8gQ9 zEPWj2#Px0@AqdLRUP zV$s>A`iK@_5FI#5$T+QaYUMfexm`WxudB3~F0W}n1Y*!zJ}IVPxkixzF3XfF#9(Pt zWhvf#l=N3j1`cgR+YE1;Fj`|qt5b3pyJ~fI(+eywQvfxYh}lfqIfFA11NhO$cz3W7 z8X;{Bj&Nq8ZuXa`fXQeg>V>LR<7X>CTf0DaVbC#f9O){6eNW3bp zq3XX@v}?Bz}P7ecfiV<=9Lia{e8TV>+|iKhw%ff#N@)6FRAEZ~xi`>|g%UXDJQf}l`{&u-Nw8;jz+sVR z$amB#TaXq=T$@Vol0yS@W+tVH&@iX1+8iCDitLGXA3~>7qP`{)#yz4Xj|^Fr3+s@m zS0p;rX=6nzQ3+K6X#DY5z#BkdRc{<1FrkvcUd9?7*sH+;k3f8G0x?`z4exAwcf+_H zZui$R4<=sFsws6zd+XR!N4KuHS1cx+4_*f%A3 zhFlF;u%E$x=@M-rhBPx08YLXgYM0E8S zVv42r8+5p6aliNb*9?H`&4;$nkj_z#pIyg)COK6F{RYw?rMR&BChlDs_23zQz#AYV z+BU8jfq$O?NYBZkSD=B!HWs z_jql#1R%~EX!caJ72MatqEa1tCD^Yf<6GzxdW>b*HLKSw3`j+ShJ;=g^Ud&cRPkp8fw}MW7VAPD~AB zg!h4C`2&Y3na2d-*kv;CmF7r<3Ck*dLdK!ePa>ABQtW<-jxa z^Rus;ki|03{VU3G++}1!gsaANoszP02OX#x8dO?s4wtyB_p(c&Wbq=v92{35b6ZYW zB6;PMA7kO%>c*Ii7&r{HWllwn19{!o04_a3mLjPQo4VH+adwAHcdW5841@EF0g7SZ zES*L?EYDIL7bRp04(_dRe0~8|_F{_J?En#&=`sN86*5OR1}HvB;dvsiTgyf5FIDLI zy}#iK7a`G5JV*cm6vsTVl3LuZf25-C-G4m@gb6$k-Qa`sO4 zS;~i%ZK?HLd15PvL%4eez~uHI)^=b6><9LA&N(l5_~6AIE(o^>Z1GxB$Qo;JUpc=1 zMzlnUpJZdeub5f}EZ^mQW9E_}@_bv7z8BJQ*470KbyFU9NXgA6M8!5io(N+N7vfzU zVk43GXc*3@0k}O$4pHd(cL)8l9yOR{5*N5*xul|geKpk!UJSDy7!SN(K9{K(wSrp)249m0Gqdi>KB#I1gYZ_ZV%w0`*^%OM6=z918BL-fnZ zwbK-C>oy!y_G8F{tR5{#+!cle7*m ztTK|lTi9u9{8s(UW)IsZ-1fgqT7X%OFPQGCkikFPQg-0**S`IiN6kcrR@h)dvz#9c zjp%N6&+Y;PW4P?+Lk%9ST>rFUb9{9{^W^$UMvs&*H)Gh8ygv;`;*q zrK@N5lh{PpXIxDOuG_&_U5_FY^WaMH;MNlS^5XC=S>FxYFMZCz*xd^+@LNl1g-*PS zM@f8#fI}!9rr(U=KO&Q(wo?P!S2~aL^o$6<1-uID zA%@A?OWl>nT{tIl?3a#7vALA@)0u~OVOP=d&+iVcz&5}JCagQ%%r2#Nc?|!43_jm} zvPejozVQ{R3>cK45`G-3>(F$n#8DI(FhAii>V%Uqbt)mQ#0KJ?nRwdzKvE{moYIL?3_St-7XVQ}uD=E4hWsR(uwFeQbZM6w&X*JKk->yqLI@qj((hf6PD5`OprwJkoDjK!@iF>)QQt1<9fAxM2@k zj*n$8|LqH>?2y4PQ1FWf4~CRS#zX0I++s;^{8H7sV@P9jXHpW4&yAJTv#)<$gY%xz z-F5+--*_^B_UgNFXN37->lC>3hy4v^tHVwVmc-7gcqGlw-Jd!>-ZBKMHvapOZ`67zse)CwfB^_2+R9VX7wpCtFT3nmK2mhfxR)8-#fbb6qHAYQ30?&i6(&e z7ZcAPp1})u*r+TsZ!AZVtvieMv}x`!_g}y2jOZ2FY49gKV&r| zrS}Le-nvIj^(UWUETc8)Tv&P_R0J|^fF~xn(ffQLZTThimr*ZU$fqJlpI5W&m~#mF zt2;Rz9e_>dM(~4H4^pO$PxPSFZAF6sj>O;&tB?9zcG67p0(LDf-PDbvt}49~x^K)q zHST<#9I){%KA~KaUP_J!f1aQ7S1n(7l2S?nE{Kn=4o0tpS{=WD#BwoPK4Cs;j?XS} z!Z}WymHDa;suJM4GW&xPk14_9F=~gVtVf0L%CZ{nnNbruV#WW68=T!8q4}86W8oFrOmQsSjSkHSDYgxG4j^vxyn= zlW-$8NNG}H3raL%Ld!IwED31FP?|vpj7YlC@x{p7BGGU)X!;t=NQ{_i4Cs!=o^o5Q z*oE^C4wtU#nB+nL2^NAda8?W;XGB`|V2gHN%F@Jld?}X3b)GGg;f*50Wn_0fu$%}5} zQ~UyPT_+Luk#$Zz$iZcr-u=@S3$61w6=}#zaugitYjdj)SpF?QA3$s~2HTXD9PDi( z1iU8GKSxC3yvR+Qpa&x&AOLn)zBf|jv4M_|m4@(1?L~_K_W%q^YPrfEm^Z|wKM+1- zuF}NsPr58~{&z-*^7$oVfOP+jaUM=>)~5Ixi(xtd>iP4y_tTr0`vq|x?{RPx0Z#(! zx7&{?pZl$}DyG4uDJ(`9ftefV-r+x}ZJwz3vfr_4G~)9UXQ2VGZ({FGgnK%jb{v;x zej|=?y@f{1;p{NNhc_O}(7Ktkc$Km-1Jm{lYXLr;+Lt=;27v*K-hX+HaedmGT^U=0 zyWCk_;_l(LrSpNmtjkY6ul!x~aje%Z!A+Rs9VKv*&cIIDOdXEADyNb$nJUa~CgX)@ zG54vX;xEU|a7z@Ej*6e%tND4(EmDC^%RB@LOEl|xU&u%V+<=zWL2EG5hANDa-X4J> z;;&=s17K_3J%;~I{IRfCu5=K6eY$uSd2 zp_NUT$iI|yLC;qx>^iW1PFi+`6g%e=XE&9}lwGXwp`=PhS(uQ|1sOP+KnU0hG6Zd; z7nz59$KN7m{kk0R@*IFw^?W34=gbRQ${-pJSoZ?3U|6f>XT8F9vD@;9##s^nkeNh? zbpVWuUOUGK&SR_xXaA7c?)@;pqMi17W^SS@cc~{6-D9Nh=v&*w^cZ843hON1Pi6^v za%gvs@OwFx*rjsZ9$D{KB)J>w;Q;)7rV5MTH3o9$?8lrC;@0>_naB5-fF@674gdfC zpJOFuaxla`_tPs$4C45A#0Q;H3dN2t zf)Yi+3sosLW!&B^|Ahhw#^nA=Y!&o-=8p1nv|kJ$#Eal(b=IT2V(6 z5b(w0vMVhfS`e~IK_+@*Zx_eXzkd`49J=9^iPDg4`U0l>L%7u`PAWCf?~ALc7w=J! z^k|(qB@v{h$?73WkKej4?nmFi&+M)xAfr)isT_~%pQf;e&aqq>7kNgEw@$(ve3Q9c zWDxB;m`ZU(q#U7i$->G7gjalQA`vS-QttXrcV z&piPd_(%`Gw}0ZV#O*Bh?zCK4@@}4Z zs=h>?8Cr-$o;K6nu(GQ}dK}L!)NiB1A{em!=8&?e7sLb#t0x81M`IF@aQ85s*yXY? z=Aa@r08}WUm}poT{ukYzmOoD6Ip8fDjOF@}+zm>eY#PldWG|>rtj7Obkr{ zV}kjm@IZ$3EL{ptLTPA{nfof=;ix>% z!*N*?=Y2Y1mgugBT;$H1qoh8B1s`S@?)z-%nkIlD97?&j>iw>?vp)=`kp;p-7YkRQ zZkNQer15wrKOG{l; zssh81fRl5h`+f4=f1LNz8)snV$eet7@w4@%B9kD#dBR@6vntWrt^RMeCJefCEoC$`GWeJDdq9v#QSYGr)grnDDY|@a#=rJ3L2wS3=Jb;c4oE0VzQ3~;;9w(V!Z@OF$~Z5PKs$GE?jW;-Oe!8r2*1RP%}aXi`a+UE%V=c%2mdGFwvV_+)FzX8PQvpqRC}ZiuLl&) z!&;ch;Ve6Pp2^%ZN0Lrt_Cn;ZIdJc(v#fEMTx*18M&Kw`A~8Z-;od-NNCZdwcdSGX zf6dtyYq^QnSKjP1cen>{FWa*xRxBmQ!|;E_q|(ge1rwc-?<_Cb#YZNy0pjXD~!oeBp(&c%6JjoV<82xo6QoERXTz6ww|K zw`Nlf_hyJBe9c5Tugp20NSYlNrai?YaR4he$>-uZ=RN1n0b}sNq2uf(c6xbp_d5Vm z2|XL>*Vo@aG&vcN_ez2#+bm;UK!A`On-5T zK6}|WVQIW+J**wLkL}|;wPb1a!F}*|EeH2;N$Pm)KRCj~&c!bW9e*Xz7Ws!u1mL+! zcq48vEg3dLXe`2yuwRR94r~qf*$d(qO0v-GD>RPnxu?RJaHf#~rliXfSCFZ2e^70(gYX;Xl3*A8h|x zWkKKaV}_M;lX{df@h-c$Of=!l>GG|h!fyYX8)pFaW60R3H@HX)6R;nJ3eK;f{I=0X zR@t8`K@Ak=XVQE2g~Fea=8OvFGh!SN@}qjF3wP2{or+CPKp))j>%wMJ_Pm5SlfxKt z;WySYGG_c^$Lw7#IJTITHO)FYX`Lbd#>BLup?txSGGKXPp5)<<=B!bntcD>&KXKa9 zP4eWyaY!C{T>TOQniDm-*$tT!ac5|Hk`^ZJ=)XZTfef)M?N*a%be-f<3;M>bi7;xU zEG3&G-dyNoqMx~eb*MLfL@g54zs0;5*YFQtqdZO}+*^dOjk#RaIw8dey!t92qV(@b zj$Y<>@-bRZpG<`>a!52on3n51z;6I~7LiOigd*lTqQH)f53ncj7QSd4uQgkke*Yy$ zAs66nYdkntOb2uHDM0Go@Qr-$og2(Sy6+7-M5IT1C_ABEn+pCK*; z8@0l*gOIM*Qwc+d9(yCubRJn9Zu68fgMa-Ma)UT#7t^}#!4C9%D(E&|W~obZrxs!U zL~Yh#v&x})hzJ0RqepBLoml6Hn6a3L{YVIN2>l7$J^g^ zyMj+T#gU^GRwV4;osE$g)|VDIvw>pN&pdnFS>yf0DyeAmumAXLKqqhdS!iI#gde2p z9tSV&6o&{*ckv9`<=M;m1<-xP-M-~abfx6^m5ZNKwgOCf5sW8busldSHE=dChxOkM zYwE?9I2y3;PFi(W5W8GFAfG)9#81N$zJrOZViBzU6AQcw6FGYDeAn3D{&_@5gbW2? zS3W;RWJ)jfDDoeA(!r52z%f6CG^BJ8kCq>enM(Q#+Xz;c^R6B8I|y&-Uz;VNHt7JqwPn+_Da*J5j}XO zi>c{zULNF7ik0UdB6(rRtDljXApKw!l&gQ(L!R{c4)qt3I#{`Ao|AFeZpa*}Wd4qhe3(t=gzYsk6-);^#gvD|HU1FZ6@KDpHF57 z`1(9c!tleX^(7fSyCbPNCGfRjPu>yVfBp&EAp;3clxn}IsNYJDfND6~DLnqwsz*w6 z+zG>SKYCe(t$h;C@(Ct5lzq8)pW*>W&5LJ#+0=B>p&BkEOxb|4f|1u1&k8g2&Jy{n z;p9xAi8v2cN;rxMgp2JbKf2R#|EbX|_jV2gB88ZpEs^)M0kRdtoZ*n*`Y~o5~{=YS@c@B~K-S2y0E_q3*{?^SrLv>DIO>gjG#!`9T6hYefwPp(nYnC2DCyqH|a@El>&zzU#4$2k6^N6vLqB|zCUL1OS z)0HG)AI_~L_`R0^mLSqqdBS(Sfha1O3<>6>(RLuO)vT7p%b)qvEJE-avee1omw(Bj zIJ1|PE zWsE>k{C?`sgVet>xIR*{#(Mn4tX=U+0r2V4xS&w>h_Lv69K^A|KroXmx8fDg9tl}$ zkAjc+7k_~pHfd{e^K+4NiE&fYdW?Bua$Y^rh%&8Pvt7qr`?-MUkL9E9D^;6tX?kZd zH^_`@8T)b7k*~Csd(H<8!lfd|Jo$Fk7yfxnz+nQBBiN{|C2R(5;!??Jnv#ezuHa`d zm&*w|v+1M!^g$hwd8_Ui9CK?S$mx8j1y}Grn;zm_37#0=nr|bii4W z<(R^|G{i5Yu8$V}g6O|)UY=L)<*JQwqOM?^)qBS$wPWQY-(3$b{2A+P>DXqB_-wcF z>m$Hh19XOK+Pi9&^My5Z#<6LB*Y(;u!*;FjB5q=xxVb-MuuJ5FnBluQ4rfyx)>-a? zEn!9{O`ZYKFkq9G1md8=F57sR7!L$-_4dNARq5;O<_11sj4yM8AhboMOUXGWi)kJ6 zIhzN&jJ0XFg9|zQvmv`CZ&Y0Mfe!ifhWC;hw0SJf(w|TLgVwC;t-SOD!PH2to472N zIj6#4Qt5xpt737Z7(|HFQ@!)-!(*m1+bV)?Sbwv;unecHljn>~LT*AwEZiDnjyWTQ z@he46iqL`cjjxa`9x95jO~pb;CKLjLlBrS#MsvF_yqMQqgAXRoDsy?9f4sRqH=>_K zvpr9mFYhvN7nRclhLp?m3RvY4MYwSL>l~PU0P1{|6da@%z1BmRwXE zcRfE`8Qd$9Gy1xrUGNRdWJK`~e2K5>sbTvu+~EW}>T)!v2Ml5hI*ma&9I#9B@O;t^ z5pto>5T^7S0(fVzdYM`D<)8(KU*vmC6X*wez0$uY%qvb;DZfq7ucb?XBTS?mH}jnR z=l8Ma2k}Ts-aDgD^Gk=R_+(nFc;Y?Q@ee*pGjiL)XZLpeeE@92G)JmUzS;G&UTS}0 z92RfLG|pC}JYm(D*!#?=4DOWB7z4y)dpZ1*qCHJwS1TQ^Q)xU~X0jZvF%xzBDb(nA9cBUaP@(*Sf4qPbEvDkhbN%_; zdiq=3{4|Hac14XGXq_9e`){bQwv*-}5tPOJ%OI^&ZDXGyt{=xL81xs0w-n=2#KUsY z503C%65J~nZK`E{@dV{J4Mux5)C=2;8-^i>#hXi6#9>)wq%^+;BSWm5-{s#PaLk4D1!Uq zaXKKTx{8SBBSD(R0#JSEj^WC78exk@DyhtP;O=o}*DbNIReZcV^R0r9>mXvkelvkN zVO=-m8o|qQT>8G(wiyz7sWDokB)Pg$YDR8C2^4I!i@8eBp>)4)GO?=bjnGv^VK%shXLU5wp_q2ZLqni$i{WK zRfM}m(2RTtodpvJ{+2Pk#!u8MgJY}8{JD?4;(Eo~_Bmj-Sf?S~O(i4$nl&>lMjFbJX_$T?I7YG^8$^_SHIa37k3+ciZL(kfJ8Ks9ow#jD+ zck!dG7X}@P>(AO^#ls-`EKR1lp)*YkahqLkq>J5E@$Bfby%NQKzlw#1;W+M!vyC`> z&w>#@s0ipYV0P5`i&}=;$%U>_a}ww?u%NDojTJCxXh0yjA{0@2VQFG0 z&0u;AZxitX3#{E*ViB?K&&GBQ6%At%A`Ks~Dy6cRJR&+h=F1FBN@8&W#>QdFTVg9; zG6`|x@|JTal|pOCtzWC>IUelbI885fTT$$?l3?ZT4!WP2Kh9B(VITo5NGVG)H)?`0 zW;zeYrB%D{QhR5gn4Kxv7*FyHEL7M=zy>G4|Z0i9NkX`B^Mr+?hn zgbo(lDbrfRw2#Ias)A^0lX9Nx~jL@lj!9JK! zW0$qxdXsQ3&>lmPl?nLI+@7R~$54rhfY6dAlCZhsczvX2H432yZKzQ91F4AY$ zxFPc!u<^Uh+*^9-a;+=IDZ)pWJid3j!D9PU1Fgas4Z(7^Jol|HhS^ap zHK%e(NJe1%)vsnGXkE&I0)3_R)M&-H zph^rT<(FaqS2_8Jn|dLj`ldmxz|Q6pb)sCIW79{aJD{U_i@PG2`E)1D*lSFe3r$*R z@a*|!noaP_jv*lN0Ndn`4)%BTGZ%>uR>0rQYZ&%~hYyYHP`ads_@|s9y=5|s)^&^; zel;xQ3x0DCbdKRuLb(I6$mg)B&!+FbTK!#|FKAF?reuxoudAh6Tbe^Qo4dms1R- z2eY%@LU^M|Yo(YnQcvm#8Q{~+#bmbJWh;C-$_^GVx%9lk@5f~D_4Kag6%pgpOa`JT ze80j(n5jf^uRJ7pNV|c(Lr8x@i@BV?M<;7ZQl`1~$+rZ5!$5OAH>GvAj{aADZYm_`v(wfQU8TL1F1V?CRT zOftCPu$vI#adVm7R#(An@G4-!L)##Ug5*kT63r ze9|*4P?VoRGJC`^c!t%!wB~P+!hvA5A~aS*|KfZ7R_<@-ulgOS?#rGn7hhyKG|)NA zT)_V|SPb?VIw>(%92N{5+zPF+wJ_`;=EDf}*wZ0ORJOYn(Cg9j0gd}5we)GfR1~Aj z;>>#1b~!8;cz`6IsucgD7BV}m1UIn4qzktRi^XH@iKrFR&q1Pd+;elDF$(CME?I#6 z<$W0<$5|6I5cZ_Z5HMxJ<{Zx<%Bu8JfE-Ltau_hAR`1C4RI2`+8{ntXDev0Ir`MpS zG@oq*RyTRrMra+(wVeyYDY)h?6Bn9o12VVNOG(nHeRI}i7eFy)c;1sW9IYcC^FfEZ z_!A;G#>@ypm*zN&%yx?imt&Ni3&SY}d0)&LQAwxi-<~evZhXjrpU=sDbM?bkZ7=>} zd)Fc8=r0WQKf6=)gdjF>E1)1QW~f$SKVDN`vE0I2^U7YrvM1GWf6V``ur>y?-`KRP zs^@^L`2pptF?t!%`od}^3{yw=O~GMp)(d`hjfNC2qqWjfVWNq?4h?;2Z{- ztI`<|_})32T4g~%9(Lkuo(q5R%zg-LUSo@a7ZlgZg)8>(OLf!_Y8`~2+P4h)U#j(0 zPca*wTRcEOZ0h-dfee$IuSnEMakfhu!7{81A0Ts3Rc+2zecl=*q$R{F0fl?lnlUaD zlrb>^l*kcO^f43<c<^5mC(%0m%AR1bYN?s z1z3O->a)giQ>aM3`Gye3=;d)n{P(6U>k5Wl)aMYQnuRmM6}4-H?a+uH|Kkyai4pQr zHl3s~Wwx_G$5T?5K`bLV9^HL$K^ucvZk6H>*~#1|GaZ2oGuI>VXT*nc1Td>}{Ij4%{li25Wh6}Bsf=M@xI73G_FmrkW%IVEH;5%3M71D4 zrHSg^qU`AsCm#48c z-n<9OLOw7-IKAp-4DwmS7;)ybiCo@#rh5^B#iDgjD9}wtX>#n-rpz|P;Pk$cFideQ zf>->?<$TZbvN{P9IwHVLV357su7u&Pi_tUddmvU)$Bu(e4srOp=_ECVff=03THq5? zckrYN**?btH~xgF;@%M4O6|YC5|PDFopYb#l1R;^LwUps{fO}(_kClN6fzQWnA|VB zq^mGnZo0=_KPc=BgCBizIH~g;u@>UG>}Thefe1h1NmAr|Ii&HuQsSku^=p*K024zP zM;U`<%SY+?VHTuB??C7-IwtV9XHSkGUwIBr2v&~)a=iTSZ48KjSKysP4F8zQwn2^G z%QGcQtzJ@_9vN&3f(y!#BJUMMqA~JFUrVi38Z|<|4BAVL05hT%XCY)blH_n!N2;9d zg_5q_ym=?^sFIz8HrIa*&n3X8E zg1(G!rhQrHQY^&$8;q$Xu18!9ooUQ+`fiakB7xp7T9PoJscSik8v)ATXs6Zl+}Ay) z801$xRlmb@qCO<;h0R{>k?jk=%myAW{1_LGO!qpVXVnaxtAd*DgL_2FoLtsdcBA(! z*Kyz|H$n;ABOg}}U5`=*H^rMpYLg9J)e+|sJaBe+smo^f^J2KcbciBc4BmaX8dWuq z0d20~oV!A1D4W*leJ*`YnW%D%cKn>hlrGR)a`pj)K66=>iJd#pzw>;dRBV$pE(Olk z)UImuRH|^)HnFQ7nAn4s@?Z}qNpbhlO7%1nVeQZKbGdO*e!;jhRjAT!+^NMDcOBS5 zNaaRow9OarcjFio?LQG2Qt!g* zbBeA62+2yow{h{u<|+Y^fzpjp4{`$en0ZWIL!kOQz#Zmv29m?Zh~0~F zXc6twle*RNx*o~5InT*6a_lL-7_T%o*0du!2u$a;467ZIRhSnYTBx8z@pmM^_1WA~ z;TdgB0RUZ1UX>SdRPnJ0vlgQq*RxVR-e@{Ys;k!Ld|+;6!_bo~y*2}X1I!+-Cm!#V zIVAO$fpNC+TLG~pL1Lf(fZ1BGYB^-T*zGiAJzdc{TAB4}utFVAprn_Pgt~d2@uJ4?s``xk`D12BpAtfNcT}+TmTB>uk zn)GYbGh06FKjo&hw^!u%))tF7v7lQFu6)din!5J&)ySccp1=`XJ$FkPGVZTcM8nKM zy5aI@oi0o(h#1ai0EZ;XpDU)Nu^Ezkk6OSirFzIL5;T~e_%cLW+z16M<_%f2e*Td_ zCi`?fax*=C{@gGF&|Y64Ad}m~gw-i;NG+J41It$4)UT|b@NaG=$sq!}EhR6KLR0(P zNAn$9EasGSCln4r1zK6)uq5i9Y6kLt)-yoAP2tm@xr$~2ZEE-T*HpbbSzjEHP3(%x z3)X%HK#(qSk40c)jRodlI`pc^ZXu`_4%{N53w_dRuL9S*l>3=SMme)IzfY}K+21J-!S4NW4|zRi3)+S3@K9 z)z$R`_2fc;aE1*K-(~Xm;p>3S*M?oNAY~a}sdXE(-rFKIqUyxRv^fY0rT8$`sakU_ zep&v%1^~l8Mity=nR@n0`wfXM;z5btZcBWg(ijC z7t71KYblx~o(&>3z>#+LAPuk)d|)Vi>Xy~c8dpmIs6M~WjpA*Kj6hwx-&ded_}o9u zon^{n!(nn(qfxgesK45-u6`Ac(kQwXJgp$K6%VPdE;X*HXRD z(;q7OpJ>IWYC7CN6$r~MG8(}`D9as%)}T6@uN0z4sJ`kyBEB&ejf(rd^!cRP@ajLN zy${_O0#SX>=2EZwV}q;Iw((n}k`F{!w)&|{2qt6ySgo((Vvy2ZKlK%Q1s<#Wm_(R@mGqEg%!*?jM0I{|tL9?@G3PSs()wMc2F2)`Ahm-~9{UQXcxK4_5eaK^ z!fKE@1ox;PE?1p#_`_o4JAzz$S}+zwCVNEtbeSRH-;}L|(OnepH8hwY%alj3Bd1S0 zjgZR0f?Cv__KJrEjZ(8qsh*pS7J;6Q_wz_#4I=yNMhqWKUn}Gf{aDr+70^b7kn}_; znZJ9q8AcRi)i2|UU1`CvtxW{%WgnVyMNw>0pLmn?_czHR!NuFY3+Wh&3II|z-wNz| zy?^c=2b)U1R}_52wP~IoSHzgn!Huje90oP7AUAq*HdI4jby;NRp=v1s*nJ2O_M6gw z-je@=_lhq@^}`<)zz;A6Vc|F?PlWgogA`|Gem@4sl|d$7BTfwZ6g&q}O5+mO_bUI2 z2!+gS+zsSyL~bd<3&S;@DB+L(GZYIftsYGQbjS6ex`WSg=u^iz;QG_lw&JLppE@k= z;jC~KefR5Fs#|eF1lFdQgN>L_utB}1_yQ)oy6qe!NarD&FChLM0yf0;o zwpE>gfRS`(i=H~@=ih6tDhZU@8-2~Y5ikU|E*3{kjW|M;#5O6)?JUUF_5E%>@#mOu2G%WMgi zp78d5U5DSJpBg|<9Gj!RO+Gz#k3^aoRf~F#_F{z+qOdKB=H=)djVR=+rHFjbW7)9x zAo$LGQ5vu#W?<^QaEUN@?<@Be|BxD&R>ObCcmX#s$u>(0d9PuE#cl~A0U@oE7S&Uu zsE~AyN*$w1=)TX7iWgUE4RXGJh*{BpB{gVMU$Eyyd3m<(D3!-l>D}dZRaZ)un zj0%=!+Zp~(d^uggNS zr2(c?K4wj>#ks%;R*9UtBktjBjP*%feS)Xmg3$z0eLY`6EG}fwkMw6A7Bb)iks$Ftc4;(4 zvM1O6ceaznf_ax}hUi}0_Oob$aJ5|;fp8~;FMIA~EamCB*Z&Jdf4_`{_ za1=?X5CC9{vY<9|#!^cb(k8wjc9C@N$Rcvv(~g=nMZ7TyM<$H9T|7bR0AzLO;(SsmPv2tzaT~3^ zYGnitP89HNhT9Jlu#qSp!;N{&dBi3g@WGAJa+2E4izupLg_=^o4Pq~qo;{*zq&^L! z?D-=PrV$hXnZwTNx^WLQ*bsk{0I)ftI{-)7WbED01j|Q3Qpx4M_%7m(d!qbw6wG-% zmIimGX*xuG%U4R!D234VH3q4~49q!7pjHoz>$u6jCgl|$vtCgVEp_U$g@d3H{IDT} z5MDs88@7O#u)LkGeiPv258W2Y)3mQ}h=jT$ezNQqx)+Y~eU{H|}IaVnN>k=sTkG;D1t*e4v0i=64E}33sCgd0{ z_VMB}-%cpxl&R=$;vFquyv6ConQl*As}raDvzUP}-3a~S!4_rp_g({v&Y|l7zhm%I zI9>HSRKN=zxkebh^l;yY6@j&YO<_b8p%ixSB7PNtLq)(ejVwfJgEo1p>x_2*7lK0& zQYw^U)u<9EfyiD7-}6(MEo?5H6eY>^|@|f)MiHE=|G)o+u3G z(HOKYW!f*0tj+$T1HKq#QKG?@pyo7wPMjKlKp$u_v}D>`LZU;PSAxuLP(8`0vm*ts zA6g_OZ&l}E$ajB}I_8M-je`KYRdFi>35j77q~=o!e;7#h%*~emyd>h_j9lg#cp${0 zTFWPsv(~WG5oG%Apx*uX*$!;zu%Jkk`u55Ti)Af*vcO!H-n2nz)v8_x9<(5qI^CsY z)#b0g5*c6df3Hh6geM|^ivu=?(u`0~NfyLKb96tl2Gp=pRxQJj&;j0$f<)|>Oitc8{8*F(|L4nQ%8Ty4t!vIld}|l6dfIo;*S{a9gS~YP^t&U z&7ln_B7k@RMGRZbbF=V zWBU&E!bV#zdn%I17G~U`xx<*ZF9=^?Blku)R7j`pjZXs7qmq3?)W(t7{hmy{>CDXT&6WqoRy&X&g-hRWM8iJ4(B0e&Xl+1by z+?zZtMyL#9dq~yRXY({~;eXCSIt`h#Dw~#+KwU8h{Nx_ug>`Ep zNCrVK<*SYF;t+tz<__Fl>SDlBP0>xZ?yc!ky&hnHZs1>=fb z8O4SiV=Sm;JQ~IB9t}nGHnc-1*iRE8K}=Uv4ybxF6dJA;W{BpmVX}(J9If z&?>c!+?7WoD1FbNjp$nMXR4zT>=jY2(TB1t&zhN@yurYd$zgkc9I1$BlmulS34{3uN=I~>p8*Zt?9hW0!=cx%& zqZwrQ9;CFQcPAt8^-@)U^>wQeZ}JPpO?`#-l}OcuhwiI;Yu*P|Lywmn1;kMHo|XMW z)xWG*OQ0Yaw5%D5^xg9cAAfh-G76(claTavTvN-CA=#=kYRFAozk9fpr5kG4_X8+C z7ODVLP3>g^P4MZ(&!M@1-h24p!mCR=!9iH#^rHWi%l597`a-s?+rd#8z^`{esS*lL zr6rI<%|7I1-#LgolyI7~mb3f&PBcMRl_Q0ye)K*RXy}TU=3jQNWONZIZUN{y-QFdH z0PlA~l@(3hCKO+>e4p}%!$3w`E=G!ax{c$gGn85!!6cBbMUf_kY*}rcPSDBsubvlA zslIUZ(t}Rx$RuXZ-525;88(-Q5lMz7)_G;`~|ZuZ8Z> zo0;w)yT2lJOhFEiTb{%7Tya-C#C`NMrP&rnD4|OKw`0<+UX=$jmUNgAiz|DM#*P%oclz|OW*76x*Dqdrcj<+v`V)!KX>}mws!|gd1?)o6 zSvNw(T>+O@RsL7!Fm*@*aKY^@_RteGEFt{eV?86(+RR#;Xk8sX3Liar+120mh3Z0$ zrQ$5=l2>aCpsc1L632RzqWk`KJ9{i1*=N-=Q&3Fa$o;P3&m@-ZI;4B8q3&CgN#1+6 zR>cN2%!V$kmf^Ce!@l(opdQqH61?qDhuD{a&WW(=h)Tm1&tE94;}pcZk_{k0`lq{k zY=)NRImB=dFfn!)QPdivxlN$vCl5Ur5%rquXe^%nKxXUEU#!;()by|f?LB{b8+|t$ z=jD$m2YlN9UV9fv^efyfsv*2{{Y>N`d|k6$^gi_PDpzl@^Bue7(Jr?^YkgRxxj~$8neVrKTL5HyN3Bux zRgM$Gv8sfDMJH2>pc^6DuYi*f=?3r5g<3uIk@@rw;gkH`;WVyNa6n z*V<~Thp86W3O3`>y0z=o+C%hHmQ-j$~r5MJaOr{?UKLO84TFcO+I+cE-G-#Z6|iI?{z&r_|9b z&81)CsISO4CykH9_7F5TRV7};nx&b#50Prw>ksc%^Iq`i5z)pUnNj^XP1{irPawT+ z3dXv+1epNudaH=0hBXRG($P3HdwT(%^2#^y%AI!VsBWmQ9ALcXH}rfbf*{|xR029I zag%)Rf-Kh%J2cw260PHhjKE$#udBX$39_SNeqI@EVyjHCT@!G`6GwfHaFzT~7S%*O z6w|*E0qsgpw!-4tUJ86)1RICBLW=?_cYxw90e1B|pr@no$`{TFyCji~Ud0veX)WUVD?+cid8#vD4P>*jLi?~Q z77Q|wgJU}JqhkWsUWyh*tBr){kH1loW><-$cBQo@FZYS2#2RDP-*c^n+99j7^48ZO zEdzD96*8?glW&i8q<3_)&;Z(u1{>v~n0{zF?bSFEYz$N8garisiqX@PErIYf zU+DvSqF7ppBV?PpgO|X^oNcN8D97yzulo{-#;1?s7GHm%1JF>VHY7UA&BhDP)Hx7M zUs6|{A@FRNMn+F=8*g4Q7o;dd8+F}A`|KTc_yal;P23jGMe$EVDbn>-2~LG8*ubY2 zd2JANTWR%Pueh1p#MBJ|_C(v2ml77vT6(i$CedNiw_hQ&G@?y-)EFkkB=%aEhLr^+ z&K~WyfN~h97?+kbHEpMcid5@{Q%pQWP^?34teIAlYCNaxG+PHPT3<2Gyv++cQ}=3> zTZZ(Np%i?s>|CWdDKD9$2}TeCl58ffx)cchU+3pNg5-2o8xItJ`_XEwGKEztwJl(` zWpH6}!P9jMmFQ1@y# zvQ-f2dYydbHzce=1Bz+=WJx01*-G>~=4{!rlUCwDr~S(s=^hGUj(LY1?olcS=C`h7 zZbDs6%JR%J)?8#K!}1~trkcyLjrL0@tmBRC_EjCokk~<89&ISUTq}FZzGz>V6Pe;x zI+xzq66oOr(8ZfJ2sGK$762D^hSy0wIwx$v}q1!SB65T$hq zbRfMhdZj(fLA#YcUb$f2h?UKb#l{zo5bBHK7UpD%_nkQrP0(EAZz{`Ot#*N;AnJr|Mo zbQ|c>6qH7An(Mwc+m~tODG?nCb%ABOpg|{^=QNIJX+NC^#6s{^O(M>MG?%PbK&a=p zf?6p3T{(=?-O!A7ZX0Ea&m-HowuvI021ZTqph185Aeag~815k+s zD^IQyM#YJ@yv=zLc&c}tjWCvU4g%)0Ax)IF`oL2!WRBNd3hq^OM6RXLS9Yz?rh(8q zn>qk{ujMO)E@z#))FH-9mw6Y4xsWQE)4XLxZ<%Hcr7mVGy=(glKftb-(fFRTu~oxs zC=B7w=9H;F6+YCUoZimm0>$#zyP^YeXX8ODQ2+W+f6(*3;!UPJ(LKp(%%n;#f))V8 zR%Ug6WzD|0NTH>kB5nRk;;VP*bfh1}vYI&7m{oTPkWnvplWZGm@ii>@7mi5UZ_`=c z>1DQlFB6tLA3dmehs5giQ_n{WX%(aOUZsuaGzCOSXR8C-rZih`AXA}oQHs@Wx5H-N z+M?QmlEl`t%|Q4u0cejLxVTCozl!7n+7(nR%I+ZLb^LKNE^SxODf5eOj^iLQ1z20R z2S>|-l+;1;RyGvesmB*eJ1FDyH3(b9V-0e)+a`nm#~W8?u@0*EgZRQ??n#l*$-r!NkByQ z9VRGp&oE@Ff6s#xNaZakT^8}wfs&_s|Nj7sn6YfO=0efFuT%62I2DoD@1(|9aQveaj z)AFwxx~ar>xt#TEI6WJM_IHsEA5_B#Dpb)9&8Os>$E_K~x|^Di1GN7MWQ$Zrlthu- z%Nt*l+*fL2`6y!m3OWV%mqBZSOYL==p{Ci;e8P$Q)N*P;(W%|e|z?`dWc>3M4EFkG*z@<7d4rxZr1anH8DawnMFF> zLmZmvh4%a)Bq~nyGU$k*i(k~lI0!wi#OVDH#syL)?s@(D%+XK=Y*>?8_$H1H&Gbur z96+QS%cD{Z>tgs8?Dg@pF)46*L3Qa&L^NcJ`L2xTT6zC((M}?uJZhsIRfbTyD%gt#} z`wD*vv+@?vC)Mt(ERybB$+kU07^#)KnkR-&Au|{S)*&61(Ld@c!_k^~an`Qwj*@qa zvVdY9T$*JZaoQW|`Nl`J>JsU|Ma-+e3>x?j~aq54QMPp#(q z`+zlkrPx}(uWJl(^ojIrPm2^p;DVD6M-FQ{G%p5^Rx6hTw(zEyY=Jycal^8Idu2d1 zY%i0)M@9}hHGpjrPYHH`xriP{ zCNJbgYOh$E3CAE+y*FEcRAVi2Sjc?59!{U-3m{#ex^`-`E>#W;NP8)ZdD-n^eL^+4 zGehhnaekdeg&s0Ks%h!Glka7ys~@E0jBsEP??6gWIksx;mYDE^fYgFCx)BK8lOOra^=B z0Y~tJo|)=Ng9hGvO5k2gXxSlJU*6pnkQvDJqS&JT`zsF_pI6;=?MwrtXp+=8Js>(N zLT4%^AGhIPn<2>XE!K&oce-wtYb1I^2HFqOsH97O+@B_|t_F-OD}q{k^vo(F;X(Zz z^&wJ@iHjGbKxY{-?O=d5RaWy~jieJjEEYY*Rdh_z>S|Y~61~b*h5fgf)o3Wp!BVvh{Sy0_vK!5uB=Zs`>@oj>YJA=(L;I zd_j6D+8t(Acy=~+u(U3yN28;nPxqA(hb`c1bp7}&%EuNY)H6c9Y zWtq`6#R34(JQK91gZ3Fxg6p31%F0SU%DqXw8_KJyG;TI)_;p$Bm*!zOtyYiQoo3>aJ$k`i&}<6+?jxP99C<0w5#x zfN(~NKSVJlC6U%Ai=^*Tj2Vv}N@C}HTr30d9Hm3KRv>r3tbSTyEIYTV z1~rj55jKD6$3hM$l${@XeYHVm^>6}gf=9Z_P17Q%B0bfKP#yojmgV%Hw|1_v*v;u; z7i#*Q+s3s=g*+m7y*;zvY>e+HcZ}kwz;X06S`>?x?^RPR0W1ey!m8}q-bw!3cu1E* z>6$p!h?Le{P$@uT5sy$*R3U~=Vuc9=yMBU9{0h@)hHJx?19hID& zCrTKFlnMvteqUiEnx5No2x{p?=b1pB0}AYq<~gSqIHZXqbgxRUb6WgYnq#Y2cr0&N zg?R<2HuX@z*rDRT8b{PXqZWEcY_jT=%QH>SAuS=#F+k$_R?3(28`-ce>r@6Z3S9=` z1J*+vXyK_R~$+b&2)1V9x6<-=ROzmE5!ekGl5AkaR6 zx*@ByCLBbe%oA!eq?ZYrsz9`Q$I1`bP0&ENp~n4qXf}lMB&Ahw=`j_(({x@#P-s!K zbw-pTvpOU=f#VL(X2PlmcM&MmlnA@+`c^_yNUp2(L|mbpC?mty98dngdvdoi$2ks2 zcH8dFpOu5h;tTyb4qT+<)i_F>X+ZMmAR3?3@F=s|)Oh<7%3afLd9`ii+c_pRJK`z@ z$cc204v_dXDgDC>bmJ%v^j;U-w(kQ$uWbfLWDYjT0Ljm5qQ@QJj>R&W%j|$&eE+mV ziYgb2+LDm1v^~|2L}-2Hd$l225Tgb~^BV&69zB7j6wjDwRg>SQ2l*>oibo43a z8gfUzD4InYZ7a2i|8p%=l&Ki3UH*ANq6}oLxEEO7k!)+29N;1;&{P&4JCr$b8$Yt) z^#U+Zbr_2UDM2|a2c7ijF|k8u4WZou+)}BTUbOSKRk?RoN5uo-{n0Z}M{vmmA0Y)R z@~*&%D^j^)sP*U3COM1p?yqV0OkWBFV$i1wD(OF7W`N^`L`q zdRoHJx1$zN6y=TYNvkx-=v7dL6sLK{R;vPVf-+zKgWlhC;>8du zag$bLNK~u(^wj@dc+X>Ej%JOiMyg4Mpk7mO4Fb8HQQ643uOyP$#T-X-TMapCJ7zVt zr~+A_H1mN_b_ldyw?C#J5p1>+`3u!Ex{Gz3<+J-Y(!X9BhoGwI#SmQBNv}Qy0@55^ z*hStB&8%O+m+Ei({f( zQA52{w!JRfMabZj1H{@^Rs zfmOONo8X1mcTnlrrZ@q9e!m17U?`dMOhnLoX~fsH%LSf#nmXe_vv{8z#f~pn`T33L z+0LQgWi9bW8{g*JEnz4C`?3xLN(5}&ny8d&ozHUDRE(wNMVjM6Xh%o2!}MbZ$xy55niKQ!*()_8pUj);V^lKqH7$ zaUi{qV%I%Qia~0@RIe$a7#K|Iy66vqqEUkt!IqtVB71VGnHrhspQ)ldnQ zh}kg z;)t(E2m6YmUtIzQs9da)QxNzo2P=JIw{x6+gQztg7YYj6h!K0f;S694lcoTs!h}oh zVwTM(A$^e~6M5KjwCVK9wWVz}o}=yMoaow0zgT-zj-D!tI6*BVT4>jn30^A$g3+dl z>cgTk5%8RAxPZA(Rq@_hZw@_!dTj8-phyT{j!!A*z0bK%jJERrKQ@;SBq?tP6*F8>V>huCm%>p?3=fQ0Mgrt9`ld}FEWebh z=!7kIdPyeaON}|re#y}i?+?2VfgLP<53~?E7W34;;@JC>09-%xg0nrXnM`4b?kqtT z5-xY4crdYWXeMj96P*0X(elUt6H7>~UF>w0Oj?QDz0Bah&VT)T0i|&E>Q`nEIrgh* z7DsoDp;kNr2acsPAct`=^YOP_YZVOda?)&a@LYqs7X-11&SAE3a-RX{HsN?TIU?kkXMa@9`K&q z=^zA}YdoM7E8f@7F2mXdwUV;xagxHAI|>24BGF39oICw;)6BNyYa2R~+a=TP{JwES z${0D04Hfh^6KgSOhiAyOQ<1%$HlyTs1yn;mfXqeZ`Qzp4aTQmL06F#QRn_E3&zw~T5V41ITeRHZx^yzRmASLRh=<*YvesyYjK3a&Hnp-U9$wk-g7t+ojCJD5-B8S-gU z=hQ`2h!j0~#f@SzWkuj4X&Zf`6 zco!Q%m^0;ZY{t6E@}>=uR)LTgYZf@QNG`X5@ccLQj@b_L@!ex3c#Q#937TF_2O@QO zFdlWIl6t$j#@TymZtWHvxScEjo;6=cscnD?nAeN@Vz@X*A0T~MhD^n)BJ|<+2%>I4*tPfdJI504nx5WZ6QUqfw%($ zZbKR;XnhMuJfb4)X-}g`&LAK&)LS;{`G0bDo?T8mM~K`g7K9uG+H;TOMa+8%PYz z&jK?qs(|y{?79AQn^J6d)XxpuUHBL;SYTidHI=ISwYxYv*UNEP!mKJ3p9T|x3fck1Pkq`3-F<~>DB>D1n}S|J<6*O?>2 zfqUV34>GF?oMe;rd|uGjvry!*x;TM+D9jPsEyTmbK+7yQ*3K)x2S*iv4YQ!m1B_dc z1CUNl&U#7XxY0y+`=PaqamK_x@a#{HOHqeTX_H38?E_Oh#x^lrd49VAy@xI#AGNn+ z>mk{H5*GJ9+t*3YZXENOmkJiC#@IEZHDZz~St$m(2PdNtbh_*H&*0|~dxvrUp0kV} zbT$0!YQ|2R4K}w`jD2?5rHt@-V!A!tIU#lCS!(p)oAF-CaUQNE0i@Ie&M)dg*l^H( zi(*@HT5AT37{zzY$c1u=TjPWQB%Rjv!JM*WrOBX?WA_efFplEAs$9JCS~Pk_9~<2x zj8Dr`WB{Vh?q_j0E~BN%jB^5KlV*iBp5{gn)=t~7k-1IO+W6O>9|pkKD<;Jm2B6av z$R6NmZZ`_v=cJDL$P6=3od6m#Cb`*^JsMp7wvZGq>mA}2K&5kg$>Lew7{r? zbp&Ec4{^>A&~A*W%3hA`J)A@f0`7tYi&LRr5q>Oh=#2@ET3kpzx_I?vW<)ALWqvjy{V3F7lZ8&nGj!su~2xPtPDBMq8wTn_TQScIuVLA&k-0%?l>xR zg0r+w*nj{$n5FaDZoV23%9l2E*!Sn&rmPvsK?{rRNc`;K6da7`op>IW=ba?Z2Rlx_SdT5 z3WvNTsfopje{giOv#NO5toGnBVq+PL{DU%N$rD~r*i^h9*=D{hW56a38On{oGo(!F z%7RUkiqUTfwwL>Zc0duBbBWoxSu_nKzsn^6bY%|KigR`{PF$b!z%|ZO9eSpy;{gxD zt7p8l5rad{ULz>ML9Hx~0yyhgrE|t9q<&~Q!o4tGJ@=*v{ zDlgNoin3m+4oU>VjynV~cs5*S_IPJZIyFs&jdlo&gr_Jm1v;ZG8HqCWWJZ<+7Iu^_ zN?wru3Otk+(PG)Uco3V!+19=Qx--$zon@TXn`RiDnT-d3&i~KYyC6!E@ZY)Jc){WVX(tk?nd>=)TCP~5Jr32@P4{0P_ZT!Y8dJg`QsaI^Nlxwa>= z?TnTMlB_j7?XgLiUdN&?W}qyK+jQO0tp4REu&bHxTfOmZ1E20dQ}fGZ3i23LhJJqV zh828MA3Z~Fnvkj25F|WYhh^)8rJY<=Sg`Q-)cfw$`+HBSUWsFFY3%Iz=NbZ95cHt8 zz)7hmFDNc4k&@Iai-sj}XdN7LI(EuW=ca`%bDcVQgbDk6b35%{eIrn5)*LrV^jIYF zqzTf+xjliye!dD`e0vNU=Z;>^395CBG`%+$NsVo1CcuvsLGL*6?{nyk^Xk+ny)AeT z49Kc9s~OSYLGm;M4RY5YJ0@KXGnurE4~dQ3F}e3Y-1K*LkubWTZ^SkZvf$+Zinewp z?hBIa?XKtSXT?p0QF{;F%h1J^Cw8@p{?H^z8AJ0g!KhdsIs9eHV<%(E9CH5O?@rlh zw;YVmLA&hAMI$~3j3|%LK~=JyW_(UWLHm0lZoqcG)q6uqjdd>E&Tg`wGi0=V_x7Nw z=5;bA4JR^~ zRno@oOOG4FrlWYZdEoh zI{Mn32><+G%77xR!+}Y+LA>r2z%z3?#Ynt?O-Z4aA@ifUsr@pQR}SLpQ+P2Y+!lc2 z%sGdgft~_~Jg+8r03X>LC|UX^jOKR2VauBCSVIe;8nR~EXtE;Q3t~r26*xb2^IP>p zQvhSSLmNF>Y(acW(J54phOBdxlp+0UKBtC6 zx59=m#9bCI#Yp#AJ?M1kI0y$a1$yONa^$N0O%nE&8ipi~?rJ-A|ND<)P5q0WNueBp zm8$O6tUqgq#ZO-}sta_p%eY7Wdp+Rb& zD?d~*FOd#3cG0hsa!Gsj{ZGH3QbSB9p)wow@;Hivv7!CTLEWOK zaWe~yG}k2)4Jy3kGchC_82Um8{j$3#6maPD)=1>c6?&9fG^u?b?pK9Ikla@Nc-ID- zw!M^5Zy9JH`!UrHqOALng&-Bgf)q~b&@pf!%2&h2%Pw9pQBZd1H$0>VwK2UU}I^_1|bkbAz-sL&y@mHMvfZpChzo*Z)0DX-(gtK~ajb58;Qr#Aav0#x-u?4~)@+Dzr&lW4g+NetL!_!wjsw^QH?QHvYzg5UC>`!!*6 zS3i?>k@ai1w4EES4$Go*C=Vb>YaTm3X~ZN=aG@k~ZW8LjNGJN>x0f1ZE6Fy{jxyp8 z_k3UQ8lE^@|s8bZ%|$z?5&#}V9@5XRk<$}vh-k|}{H zt#Q8#Jra63%xR$75PmP-+d*9S)_+iXjngbEKK z2Uak{h_gezlqgKlCn?~=TVi4JC|Z%0Yq{JYCHe?ufw@mCp`@olqZDjnW}{$VrL+*1 z&2?%o23W4vIG<_>Udr3w){k*Y4JPeWWg(Z{4b$L6*d}4w9l?dcw;Em)V&C4)0^nn3 zIPvvi14X(Z{s)T1L7X!wN%a&#Kof~<2Ci}zkF#l3n~mE8QKCgpg>VmCWX*FvDxLEk zn0vQRf1n5LMWLOir?L~BCZyYfpq#uM*GRe2*besAQ4~|sd86{QLQUx=)q>1b7`!Ew zV+`jvN;U44U<=215;UOZ9g1m5Z!!kf5!ygxci#lv(fWM5adeGpowR8>xgRY2t^Ga#`nW|yM+)GcIx`SUVh;@cxsDpvsNL+ip%!;C=tL6ogWFI+`} zV&hlek9~^>xF;E*&gQ3Vr`1alwk-g@(5HeYsn+cCFhVk?`}ipCWJ-!*+#=^a_2~cB z^z?Mgu2{NpJ6-W*1nD#Ar2UF0B zgk8Z;o;sR$Uj|*+Qo9of%?7q0Li2ysfBn0{b}7{t8ehSH?aE=Ns>!tIp&oN(JO34) z`x^EsoKa}RQVWEt=|Sgau{Ij9iAEMPy8G*x$zDbXV;Mb_EMEu*^B#<)sbK`02)Y%Q=|B}i8V_S z>kXyBH6_1{V!HBRj*!{-2&N7tXRv|vv!PCr!=5Ic6*M_nc)jq7G>};uH>EVV2)Y|h zk{}`bR|8dqbV7ZQx zBg1-YF~wE&O)t($`=~fKpt&_IIhipzbmy%|2J=`Wm%X{UUyT3W7YNMZ$&p8i7;8YB zfpoJyvk5^b7%>unHf}7BsnP%+HKc;3L8|&rSw@{S4(SN%VODgoKVr9yH7OFzA&DLg z_Ss_?qa_fzAzf$Su7;8fhUvh6g`z7V4HeZxtG~B-NT2Q!wrO;fXTZMX7`Ij)tQwFqjpa>X}Lw&d{7#I!zCgL zeQ`)tN9dHPB}E->io4zNcf{r}rCh5o<*EWlxK+UeeNZ#1ilOPmzW;|cB~$Y^tVghZ zWu@_<$FfyrktfMrEa~FL;mr|q;9oQzn_oTLzhM)1>7a5zGZ>P>u=XgrpXL24pBaD( z4Rpjb!F;!|OyLjv7Q7U0i-j7eRMiE$xnsGdBFixcl#RHJ_&&)IRkHyQyAgtE7B`pk zvP)W5x&I{(O)AZ4W%$A544c~5jwv#vh;|Kknu4@p9#HNL@NU(l2E&La90PcA1fzyk zz@9&29#k+3d+|I$mLjz%kRQ_u=7T>>oWj|nlemWS6NW!>xxbv11vI%%MRfX{r3c3N z#&DSM17eo2FY~>;txpAy%J?cuy0yJ%cMF5F9ibEtO?KbP+(n}pFD_3#4G5vJf7i%2 ztpd43ah!TFi)kZKki2Er~KF zeQbEEbf%!+0IFTTjTGp&VsW@#mEb(`f0w3g)O&z!Oa#C$;@M`k?x9G-6jKih&|gggedp6 ziHl;%a8h688s0@(uM;!E(nC#jBmh^)eEXGd*@b7H` zC#wy^sI zhBFwq?71+C?Eg()F8-Bk^Lt#>__H;tiqLNUuw|E0nj?PO!VoRN6Eor9b%4OTD0 zfLMoX_HIL5%j1ob0rBTg#YCT78H2ot!W3Is8RTqum&Ngvp>tV8+C;{J^41I|-RHaF zpa-@v_4WF!hyA@+#e@MgknqOLEXFn?uBSikTpixuK64*ge~bSPwuxMQgPTB3>9fcP zdgb1)J~SGBl|xk?g#`D#ggDhrXQnlQL zmP^-Bfl|XCmm{Mlv_-D=D(g0UKGGT>n|I2VM{>DZ1U>6RP}@+!@+#wmK}1I^ zBiGLaty?hIwJQOSSwPo1(a~IA%?#B?_bvhom`kk(R}zoNoM5^tT{)XKO^#41D zK;!%`ad(MkgJW8ILQ&Hmb|;`EZ!ymzK_-}C;zN-EJ8YNSi*cY$g-gU9ZsQgPht-xg z8H9~iBUyQR(Wo?I(en4yp$uc;S?2iv{I~x!0HZSvT>;&n!Rq@pCuCoCwJoho5t#`; zY93T;lw{meqte{XTgO)1l|M*4vce+B<7I)ZMbjR}sm$pbS6nKymBO2OIP(lbw1WwC z*9`sUMgor<9&LJ6F+z*cMAY%fEZ`aevg686 z4b^``9>Tey zW}K%nvAces;`>O-v8N^^o)+)nuDnd|wb%2NmDLyOGT+7yPn&CC>4&ZcPE%yMQP zB31?Q^MI;Mi>`=AfTUj}3NWrnd88HeGoIQu0UwP^TM-S)E}fqx9e$mpOOC|0 zL01kmKNx>*?|O%+&&EI%SLK;CGocb2$SUyOnu~WmcPN~!n5c3BZb{XR)^H^*LQu@f zv<{WCC&11)NdN8{b%HGW5L%#lV}yc7v1>cGGTROg><=%1izxOn;(@Of?%7j$X@a$EZ+&9a>wf3i&^L`^+uP z9!H=y%>>{m=(892_G)h*&nuv^T&Y zSayYX^!yk*ZeUm3PI6I#nQb7q(4@6Zg<|CIQK+6Pbv-~j`9_0^%5;=k=F>R(ie*&{ zT&&)#tcAk8vedWi&9zj`aC7}9REf}_RXiMof$HjJL&I+%Uqhvomci;(AiQa^5TMYy8A+oL(s>7R)p+p%nghY z>O~zipYSUs`2mnE@ahuvJ2Z$Bj!HPk3l922fyb@`n*eURm?x9tVd}im!e8o)n;hbS z!TW(?M&Tp*8?J!{H>{LH^tFg4*XcCWw1M$LaQfk&loT9;6-tlddC6CiAJq@Ze~bp zZ3km5PoC;6x@yU0o4Q>TiKi|xrti03LuVE0tiB5QEG5U0PPhesB<)U654n$dhrobE zR0f}DP2EMk`7X~N-!gn_D2ofvS^e*vd5ls#Av}i_vYT}<96Hcn8+-}7Vb>vz?}32z z^2{Uj8k=W$(r}$m3v4Sqh+`Ec*Q-ramxgY^bYeCr_`v>EwUJGGi^CRQkv0&E_ zQ8}}08=OFfbJWt~Z!+e%GzUpCo>I&Vc`k*6WUC?c#^I8=iw(HSTv>KD6}Lsk=$Htzlw zx7;e8QK4d%P1izXbf@d#GS2B@N(CY~ZaEM~CB5i&zbE_2!lK$48zi&E^jRi?le9>< zZOwucpCT_<-Npe45agQVc3npn5;5FzlwxuL(i|VEda&vmx#ekEHIsAZNGDz}L_;KI zyg8d{Jcly#taDR^iA)<-uGK$wag^*k&hS8NU`GlDFxB=Pnt2aZq6t6XTzAgqO0aG%lnq_~fI z^xoP)@rd;N+POOnsc`$RVpkvNGRA7CpQx9lcP?zG0#K|KKr z7#X`107DUNWEV%jy^tgWc(Ot@?*jD&KmYU(0|0M>IDzNKp@w-dC6RXx!WaJvy;Dy@ zsKk;Ob|h9eH;t~g$<$Q5DPoZzE@>@`=TgA0BrxV#u+;(IF>x0}Vv>N^60bL%$}&Uj zNdao&8*e8XWf6d4qFEDqtX;B25cr|6dUOR3+|HxOQs4N?0OZxH1ntH))r28NZa&C| zR7g_T_gq(tU`ss(4?=v6ps5x+G5%}8TU-p;tZf+aKCX2}Dm_qhd@w~^fxZuNNWbRU zjM9&zd~y#tkM(sC2Xc)r+|d-jE(yR>&>WQmVm;8NBMuv2W2QL^r-n@Cx{1j@cpPt( zo>(c;X;rIB7bZ^Y>6+n#90AICjcxujc4xa*33!KrMn}DRjBGlGGC@Gp8F)ugV*}1H z@<|^EsGR>dN0TNWQgb7#Xkm#9Sm8Ho!13&tYD&cn%k0qIm2*?S)qAG;&`(u^ls59I%*4L~kROq%Q(C zOu>2^y3ZJ4OlC3_QbPzk+M&jHh;^sUOFh~)uP*ZHv`;%*^!cA%AT1aHp>hg9@{9tg zUx_fvq}XB_ndahC?6jN=?S;(%4Zv9ouV{Tu6|uJ>7|M2&nh&_Puri967RH+>k3)pj zPa9%Iu@HlCsXZE#l4bm#CGm9uLL`bB0WK^v*X^kacxj>JC}0u=8q9h;*=Gr)Ju%gC z&!JuJ_-kLBdX#bqvF6ZANh`v1SF%HhHEp=d7}XWY)8B%Q4nuik^RuU?5{z+FaaxCM zqm6OXP^J<3^u&rD7T!pkXZh4-Q(JDkd{+$kR&q~JrW>d_nY7ZXA9YaP)6*&nVZ5&@#7JkCVbalDlrCjrc{$Urn;^ zGK722G-H|cf>yWLIPuV@SZ-o3FlVxY)KY$2T=ny<0IA~-%QY}Uo)@uCj-6riP)3ER z(v3!#AuHt*EWw8Y&pLjwzUwFN?-KrD9>>{N#-kf*X#Uo*vAvTQ1jy&L=q1BIIysNM zT2yJs=(%29xHp*0^tPN1gDJ)oOni7E^wC@B)bhEhp_5L?GvZG36;jJ8<@X{ z^aL)6@ViCPF-b7ojI0HV+YHvfvORA-c;LWQgn17kETwQcqlib~`ni2x1gv)vg2&Os zmGz#ps6iQ(m);2Zh`G#+Bq9{|ThPGDrZ^sl)w+K>q-0&|EW*fB`r>&MtabOBJ|_hgLf|Faesd#_3z_0&(udS0V>ID(VDljnjlI+-TR+|OhV zxdtnpf!ynL^*GA7wrItCtRhwadb$YM?6Zf&?A}4^3{k`XH!pAa}c`udIBL zDvR*1PrGrii#=QQ`Ws6H5B~P0UOf`eWi+0#0L#2`?eou0?TRY;KUTUes&Vx*KOd#3!W3##r77I3p0`^Z!L} zizu4$7Ztm8!dT$vdNHg3DAG2Y2eSfLx+wyOLxV=2gr8jP^{%}U4&Z?hJ8`}Ec0p81 zf4M=1Jng|esmN{f8pdr9jBaBdUG0ED7iMsuOS#CLPdgq<@Rm3)g;pr#{Nx-uvO%%s zwfjFm=DGkeDuF5$pf*-dE;aV>;tz%WK2GXXNxrOVlYab+Kb2QWgJ+l_d>)mt_oJ>xJMROf$3zMs5`bz=e z4bz;rbkd{ywY5k`xG3Ibtl_aR6rq1;;e7bx4@^%es#re&nuQ9+Oe&)no-B9cLwKL& zW4NsHimf1uUEjRCG@E5MKi+Yimcx#cPf^bgXX?%}Y;*uy>2k5_JFYNmeJ_K!$(mmz z3mX6fgS*{f5NvFB)@IA`1|$Oe@Q72&tAeM|`GgI)#il74(F=P*sj)`iazlU3q6F?@ z6|c5P6jviZhT|GQ=rphpZ$O+${ry5W>G*X7fz@JIgj(RM>+;TFYx}rAT`{~JLdw5G z1y8F9#h3=mun5lq3-L@JijFG3>^x9U7y~-G#vOUZ8kbFroy8Co4Gdd?5B&Gm+@*_! z)UsP^P3v;^2EtNY!7>N?o;8gqOC*di^?lKA;7R*2qr8&v2!dx!>>;$I)0Y7{u*;~` zfFGerv!2VrS!}9I$A>(G-cNjD^Dx=OLV>3qbRIK_BQX}b>-XdnSjmvrG~g0P;}6k| z1@rrnvGhw}0{_*und9THH89o~d(@APJ!73La2O`S5$h{FZGLJE`FP5(mQ1#Jb%jvp z9bBIx{Ha7C7mrY;!6(WMTCrI9FGfPKoNDtAlnOR5@-H`{&*yvwq^%$vDEEo~GAAqy z&}cE!$NE_9sOu^OiTOpc3phpX3>On@5Ku!BhOuUCzeb8`-`aDp0GnFAM%%^h{4Y&Vs0`bjI;-6!aiF$b8xKY) zg!RoQtWeXvG!J|$GBJLy7-Gk_BNj6~hUu;jqswq*K@D25qjg3xVE~=e#CMljZBwgB z$03EjCog_>s=7y*ziopW9q$tGJ?gi#O2N`iZ*h(=$22L|wi5kc|NNhSPr=g*T!1b< zZibTqdxQZDU-z@S4XM8#7KuN&!6j2O&?P*Re4XaS>yf=^Ka3vRL@6>vgjzpVn!~)J z;_x?H&cNrGr(|7_hFMPwY*X1kRF0U1mxHPOFyxnju-S55?ZRm8NGBiPJq54WyUo`q zlGRt}xNf|Pt*#sJgU+(F>w10+)(YXF(l#d9PHx4dr<*T9qOmFXek|O^EA+$hr?u?J zI97N4xN+y`jx#+q3DdoXSszi{wX6XgVjKC%{R>O7qN^&mVr4@=k$vXyD1@`1z7B!u z(^Dgq#yVsMFFa@JxZn}H+&W$CfGu1gj>E8}MvWeC&DI=r8Gb|+^9?auHz>1Aayo&V zC)U%PXkHUJ-i%1M7~l(*yW7$qN(WA=7K>3)HSEi8>MNd&uq^Dyc))D-Qd((Am1Dl6 ze3DjczgI=O5`RH^#@DQA?Cgt}wa1s^$1yGod?aw1@)nOi3J-?)S^Pk&aJ=?Kyx-{y zo?pt9A*laNjfYjo7!p4YDL+J<=?sInG7EO*BL}A)SX(UQ5ZwkF+N8u+QbBXE0X&%# zHdenZ$30R7%PU^-tkA-8WAD~>l|MX?yqkImuY6pPuO{|i^?(1J@W<w!CBii@rxF(W8!i3=lr>Qp#%IUtxE~TXZq#SJ3Ky%uKtq5$k9OJ8 zm_anGXL$@Kc53s`Q;)?7%Kq@_O3ZJJE4(kBOwHv`uwgx9@h%Xt$TR2zOQ}QHka+U1 z$Ef+~(9bll&WFe1xNnxsC2U%@&AqK^0W`S<)CgQBky#viYM6;!Q*_(>y-RVR5|J8I z>{_ox_?@u4z`#?nkwTHOU>A%nqDgkm$UTS^wl>&pTQGmbWo>cEvGM;l4wq9RoORe{XjVFVTTi_T-n-uJphp-uR^}OemTnpGgyqTr zUesj>%wFBveDWLogqmY!n9qEH8%(D@7UT>Sr8E80@O)mfuhh8Oe*Vh)@j-JPJDpm= z(X~-z26SgxY}cRD?+d%LIBo{w_SYVDFu_B;y$+hLg?>HqC+_AE!Oz@Hz?*xVC$p(u zwkq@r=SH_Z~CgOSps z4BkR-EK*8N_=sGRpKv5Vcvo*z5VQPTVC^-7Ov$1u(Y=`fr?_i z%54znl`Gfg`x}({a?wpC>1fmp{^YObr~W>(l%k*4zMVncuRv111u%R>FYpP*KfVQC zn|Ygd9=OXor|ZL7rNb=0#GQ)?Kwq@n{D&wdF1;w^U?^+Z5s|C+YK2Xm9GFmEWzIx9l}6Qe?3obx*T(t&TAXGwrW3Q{cz< z1;?JoWABuk<8dHOv+kS~8M3Z@Ad!!c!Jm;<&xQoM5YC}BMY{u5!~|e>5&L#NPZKsS zs)~sPhP~5d`YyG-+@$Z+i!_^{jGhcl?!VdHb2;}m&M16cH4Wi#U~Cn(AJDimlI$ds-`g zXe#jB-QYyBe^g_Sil5u%;W!p%F!bxv6%ap5yD1+gQhZr?t-2Jnw98 zQFb-9r3$SG9Dcq9?(ZG%>Ie1sv0Sm3!ME^Hw*I&UrvQe}76tgr2?p$;^!O!u*#T_S z<`eMa+#BD05me8qfEs(emiA+1K~c-bK~!V-d7O?uKO5BXXCfcuOjfWs>(J5o&S!dm z)UL<3AN;*;`3;Y$_l8}s0ooH2KUDUY%Fn`|?7cX;t~2z8oCVS(`z{+Iv3%ooq2p$z@<{MWqci3dbS z|4jy|jE}*&#;`4(C=|XQiCn)L^xJJopqL%XFKI?Y`?2GE?Qtyc=gGi1ue@Cz45`YH zzEnIAdv|u0yrOt#eM4>}(%1-VmE%v02#zez3j3y{?`Y?;IjLm73n@$2pWb&B{J^ee zW$^v?|Ly;lzxhLKCw%=L$flgA%R(GC#rhZHTXVrS;NI(Zr~kqixl}!o*~{2;?8@N& zD{}i@V16S_^(Yz6m3bV3iyz*bMn?R0?AI&hEJ7UDOP@(C6Xw;x%AG!!4O8q+K83g> zN^MoL0A->8TyF|I3nA86w{p-)cwC;?eG2RUTL+iv6BayIi!K%JaoCJiF*+H>)9`Hw z-6LGEUF1ik{TAf2A~t*kqp{&86R5vj#N@o@HdvvyFaAFL?twgBR^FTWkhy?jWNgy2 z@oW0kbrG$5&fdkVsa}v2>WW?BwGj=#s=($WZ&bBSyyZ3aVZqqOocpQl{A-yx$Bny{ zczTF0ONZr2ULhd=v$g08ol8v4JTkO2A?*!q+WLg?=4m@0$?U%3;we4^<*1Q*$M{J6 zf_B9FHvOEbcgtaz?dw`!Efz02_>dXkdk&I+;cfV4t5~zadz{gam9vosV7?=stM%22 zd}OoZFuF%MAG^aB?`b`s*Q%eD$WG$;%M(A~fmp68kfCgxKW~Qf?)1Wmer@;BEM_Zt zh;wwCuYFIh8b1Pjy(?P|E<+2^$~H(l7X1lPfFyN6$V-Fk}) zrbw;9-6S>aMrD1l9$DwH1Xw#wRN|B|)w((w9NHMx?gmSrR3={S`f?1?Yqi*<*oCru zZS5eYd%KM@+>2no*de{7?rkEU16{S%BD1IWNIy!<^M@6G>4ARMB2%8axczC!1b?4G zgR8vmhB;sfaMLebt7X=b8xV!N)sdW94~}X+Rz0KG1zxCGVn7gdg)i#FI-KPRk}i>HZB>wJoH*{oNw}?A=3S z9{hfXZ=c6KPZq-+Vm7k_4%e2)GtAN2GATW^E7n z%Jhi-1GZ;}aSUOsH$0-mS0a+kOXc%(C$c@qgWSfLutkVT?$F!dY%q9z6?}4w6GVBP z0KB8Bj5>NfQn{U*^z2@Ct#=xJPK-a445Yyt@DGsjkW2D!;x0J_bS@>x<*Li(KVGE# zepGlff#kASi!88#TYaAsk1=Y9d})5}mLD_}b%zcDt$S;1q{?i4v5_*|Iuot`{wmtJ zYrs=R{CpTW19bitTO0!gENDbJN|N#QCq#l;JiN`d24$DHrx5Vnrr#q%^UHpV30L}y z&c4pC5M3|15A=6!!B^4T|CXCKhM^l=I6zyg9KbN2g1!Fm2Z*@&L3jY|3^15Gk~kaP zkBj5A2*A3ieAQ`L#=W4Y+>+g4XfcO*^RnupF&kOVvXE+NO7V%#q1j3g%7u4peJA^| zBj~U#=zaM51Sq5#>Iqy*JB=lsa;->7+AerC1NfVdF@K{Kv{fqaj>U0|q$dIAH)xok z(@Yk+E&vEs-ja(W&JQ)C9?KDxV2h9Sn88lWA9;TMldv-mmVZ2rJ?0ag0JnmO_wJjd z37x;Tw<|ajX0Ya0a`WysYU_7H=(M7|I5S_FLU#Jm{ zY_`;rX8U-7qKC$bCFRlmjrRazEyAroln6PI%VDxXjwZqFLO4$Lyoc8GP4@q$uOa${ zl)Vo2Viciz;^->jWFiz?GAdx=6XCoh@LPjZy5@0~;pZHQJ<@J!3W}Cbv~vTAxd3bn zTFlh^P^~Voib<$tnMT=T7s{W-1DnXUWy7&AwxbI!f|vtXC27Pej0q(>yxLn2CCZhS z?tV1&#d<~2_=X9=G@7fgV0HA$cHQ~GAG8(qh`XN!OG#HdR|)>6-dUOtju5YW-~Cte z_LzUb54r>@l8~uQ3{n>&ag6d#N>%Q%Ms{rnx!QMn86&6F{|d+T%nkSev%%o0^U67P z(m_pFsiZ$mOPLj7pJ5ApJofLqLt>=#=kN%b*??#2y})yEbJknH&=JuZ8+(}4Gx2;W zVN$$*NM{Wt_8~f!(bmdE4D&RvS0BY?)9l(9ZZm$<5qsbh^fSiD!LG#_jgWG=c8FmO zQ_gq2j_>0jl60~~(X?7cfDnIZ0b=Oqd z0G>Y+t3r1!VY0(2wa3nL=}P?Q7*k606wrsLtV9kHbjPJ!Fh45)acR!$l35cOwxyhR z!lL`>4G$sdyBnbBP)=2tj~jeTCp1* z10*Wqz1)&K{3|I}@0wup{b2Ox#sL=xGk(72w85%Cp6>IcLDcj{aYb2_26%%SL* zOb`P@C8 zud8M$HbK)#(~)%`O9WFSY@zSR(RZ|s>RahLFcnnjdcy;Blq*RxciombD>(OY@dwierawl%k1Us)%PC{)~!t zW|Je|Z@lXYVZDdR5Z;eP4Te#g55)FLOUzx4o|LN}X&4xj#uL(e-Rd%ui$DeP6-wR( zvw5ESTJCpg!-!;nGWLXNvpQBw#PHIO@dld(@>?4@kHR>#gl9W9{z)@JNznAnO2M2*Dk66oscH^S4LZ;drm`$ld z3GExN>IA5CcWA^2XU1btbiQD+ung(10YmEW9MDlT;z>uiDu-Xq(CEoEpj;W<$O8`f8~q~Fe+(u)a4f;nlTD`Mi}GPs z8+E&Q_{Gl<^<^y$2?yj8^rPVGjit>)fL@VLZKxd=^lrrJ<4&Xw5Onu4l3t54`3o$? zC8ZdGsDIS^joaMq{Egho#~3nLUD7WQ3-wc^b(rbl3okL9D(r$AQq~Wtq#afin?kAY zS71UXH@S^_I9ndHK$VW@0?pO6e&izIp%O6T39Y-m$66|Sw%HBi!CFG5BDuRD2NFqTxcw1 zz!xi_vE@1`d}Rxr;;pJgn4Vn^D{UV1vaZ2+o2+7+w1Zb^l$05>obp3N(NB6mbC(Kh zfhsW5&B9B-yR{fWrS~us6@DomCO14eFoW@lTEuU4<`n z8fAd5a#DDKbl&Scoq1q9tkt=n=^W$kM)&HS0pEc`>J)EU(d!5bu-B&QG=hxkRED4>xwB5*BvR#u z6}GTv`hHuTiCofAd@xNSE%*S^pD>I&nQp<_{|J7`*FdLTIh1Xp@;tVb^eC65jQ(5_ zV)LTsKWo^$Zf6#CA{tYUTPeZ;+XP3F$OB@KQT7o?1E4)Ls_cHBL?q5`lKI(o%ZV5V?gIgi?vn zD^Nr2&`eqb;nQmw9;61EAeF!9DrblQMuDEljn@=vWTYY%L#dI~z^BuoR-fK;-5bjc zK2M*}^JjNho&&CEEcWyP?AJ;CsxWd%lT%YN^p$bYy=$E>LhCnNhy5pE6l3-f59KS& zd=8EpRE}OS5*#lasQ(!QEJ@llrdhBVObXTuT6#|El+NOyOqpOCQlqQ*=pj19fUZTd zm=Z4xPT%qP@(f3~4gos&!9`k@XCs)2w?eAmZEDQ{v)yf;rY-23O9km!D(tE!+9w`VKx#-;FW5{$6O-`AeCBCV>B=OO#^TSpCluvs>&2x6@i^3=0k0$TTVD zKIS6xj^Po0XgBhz@=6S_K8O0blTNRNMsQ?{F;b>{mPrM)h*ySX5=mX5w9*QWOYZa_ z`C-_i!jbSMU(R+&txN$#+&BxwCVb$+zd`lJ;+1I9*MyI5rp-;p<|J>;6;u;0NLp17)Y+E@Ji*ME{G z(BY5olKx}5OUlqvG$co5PS!G|SYK7E=m%&Jz5;Lhy@TAP4_DT3>e{TH8VD(!u9yEn zBfp^H*BlA?qiqGJF-0g1fW^&2p0mSNbI>QeAxui5Jx>mXVlz!@c@o@XnVlPcEnUDA zl?olq5+wjXHxjlI|Fd3b!+bSbuUIG4nGH5Xs+88}(Ki&qGvXXF3s{XPlR!KsWc?D? z3DkRmoimg;+H7+T;=uT6&h0o?h5pj%b09Z-+Ya122=}^Gw_Nxf2+8uQ?1yU7#SUJghaD~**27Mi&L-Wa zlx(i@a6K5!UWaiHYi2;&@8LuXH?b4yg=zZ-P1bdRN7+BWGtQ71I|YUjc)V7Yrwstj znDSOaAL>dODS}}-Dd+$Z3i$J~v@Aw&m92eJ*A}yAz019HyhWo79B4cTH0 z*p!Ru#3;`PePw8u3k+xp>F|!2#tFOzVm^ly${*$px9a$wvaWQh$JECut^m(Rv=k(g zW?+Tr-=G2Sv=P2d#0V4me%2D$Gn}xi-1JM|Y7kgP@qEZc4u5<2H1UOTMCBbIN5t_A z`u=lf2u}5n+yA<<`3o@vWz&r#eNDy4ymuciYe^v&DFsF(#i%fn*B1U1hGNAaq!4WC z86xOo^lCR3C1_%l=}KUdo3l=@%h;d)i#t|6jQLauI}9Qi3Qbs_9mW?T0tSXe;%0=C zyPmQ+923t7p?}*gkZuEy3trlY#rcEUK&YSvN6;lKB7FRPx|*n-SZ-y^#6Tw>PB{XO`W5=& ztG_;QaU=FW9%Y{moI<(_`qXTUr?d5`6k!IvKL|%lo5WK02P|VtZ1#vMDr=~e4NQF3 z9-9x0I5dh_@h;#%7E6<;N_w-?A+_S@9FqEV!gAysZq$JaI*yH?hi+>izz~b zXj}bC0|2IIQJOuPT$t7-QJu}vn2752{~R$$jWc@gLR6Qa4=CHiN6gGIc=v zy+QOrNZ0E%jaGGj`+Bx-0@Mou-TiukCXj=g-w)%ajhC}3`8q>8dcgu79U!$NP3s=1 z@eqzF4OG!79jYnWH@26I)j^%u3>NgG2|;G6nWYkk)cy;|LFHjKejOSMR|b-t7I0s( z9X{a4{=I4jV8T%ZB<_rsh%gDoMNeo1|Ivezr0eQ@2Cg&W6^)j6V1ZA)DwU0t5!h4J zc|LF#%Xb(IXuRe7H?FFKk}3(&Hpx08YlywazY*`-8g;oMe%)2s0y z7sfzB#0IDMrYg960$eCQYNA6joOZL2#d1GT~mQ_Dq@=q z`hy-V+HavPzic02-T8P^F~;M< zzL<_P`onV9A!=#Kh694V`5<~wfWtO$!vZapWDXyePapMH`(F9~v;|cwI%uZdg4NMw z>rx2Muq7~!3~qI<0#3j~e=!IqeATDtrfrK)VQa3j$)%TVa6p(Zn>3f&G?b}`*o+Tx z0@o1JyfQC7NeKe8nBXrwj$4DHoBm#3l;~YrJq58Xg7>oa;Aj~XrAZ-QIh+;fGNXoX zon(m3>A(&=X4t&m`r3>ci6jsyEX2%h&W*VLk}e;`1TVX+$Py(#m?a&$!O8dPZ%YAo z)rf<)d_+yCAth%{T%D(ZvwmooGdu#dSEf@pjwW}-4&PH^Gin9ENZ6)GPOpA72XZc_ z%|q=`L^4<4uF_777%ACZXWkt>=;@}RZ01IX{^2r=J}W@6YM~`F->^ zP6x1?d$J~KqsQPNfHd#z1Ott}@9RhidVPbcN&@`o1Z7=8>0-M0o_B}CnQ)YM22tu`T#^yaOwtltp>OSgTJD^{oN3n0 zs7Uq&LD(v{Z?B=C>1kKklQXoAE>wEclR&NYeL@U2YzEVwnb$S~JCQ?hjNkxf8TZ{p zDm6p|c*HQ%73m)~uIfnwoBr_Rn8RHxqf(n5?=$!o@hvZ$ zekV}NW|~=Nam<0xrZ>Cd*Dn1|cAPF&CNA8DtkEuc2w_VILq>Q+2HyZmGG@IbeI!gI zzB8uh3j)LU83zo7&ty@^<%6@NaW)O}`aH^i#DPehe@+9(o*G8;FjwT0#@o`ql04>wwZ5!dSD+FetlK_Ig_ zrZKw^J-zkW95H0*67Wcl&O-jw@Mj;wtq5G(`K@BnLvG*8(yS*G@{c(rHZ&`vpFIb4 zuMnQOE*^&J@Zw#t;H*=90+5_6J#w3w#V}(TW7!l%ok5Zp3lWvvXK@l@ZE<6Ar)`88 z4qAy>+(z3EAYp9@eLO_0u{=aZ9Ae-oQ45iIToDBSqeocWIZ3FN2{hZ=`%TgBhZhqR zUHkU{X-#7fyb2&p>0^mn3P!~22PBIWI+MVg+43!Lp=Mc^Poqq~+`&EryszZ?kda#b z6gorZ)Hlxi)96^Lfc7-&IBFPmQ}}!`Fik+BhHi|)=SA!+HD;{ zI1^IjMG0-BMC^Kjn2)5*d84*GW3}WKq>Q820s24??*W@l`U(wbgAriq72SwlH_)dF zM42d4wI47=;-6C7hH91@1TKx18-i|V`5aZ7z4RJnt(zwrfG8V3`h0(W@#HVY$3NhMN;vHxBfk91YQZ3!i`F z*8**AqE=Zpm2cuoj{Nz9Uc-4LnNjx~2OV*=cb&0PCeIDWcWLs++&wQiC{hGePU!&R zK;SVJmPEpyr(~B#CJ2|A6cTv_+>Lb2Pz(#1c@Pxuy7Qx2}6A z-FdIek4epYhd5jNr>-pGwThS{mSN6FQ!1JL)1XMY*AJT2k@oYx43HU^QKpJOAhIy$ zaGi~znX(&iC>dYPnTk^qPNQc;VsKpjgT+=4)Y&-r$WzJ1b39%kS9B_;9qmSiL+-6{ z0TKu|u`@$+uUM**fY3!1SM`Njzj_tbv$2QKZLopu?O<{~7~{>b{Njk!U(aYWn8yRcGgLPe=CqY;Slux1nh>F3P9l!6uhh|3~`Fh7m3l>;y2w zeKDt#k#kc0I8mvUmv7g|>FEtGQN?LLAFavyv8;hrlBS z?uDxf$8o4q!EROPmyX{;4@X{W|8T=BD%9PvWl&Qhn2E62{=#yak8SFaPQi_mP$NB) z2R0OejIb!@W3-TU2=*@FSw0I0clY}K9)!%Jy4FFHX~-}Q%DDvVldeMB{U<7y`{ifO zU&3OVbuTtrk)r zqZl7PZpVu|lHsmj@)cSoNrumoL|8nA5qyfr=COFqS(@AmmijV|A@(57bwsKD%STR;k`;Y@8X#(0vNk&MjW6m z{zU9uWh<|?>r!A!^H|c8yyy4h`eW%thNay3sSBHtF2rPh`9y|)8sHvHkSgCNNbEtJ z+Vpg|h}?OTR2Y+QbAo!|Qi|6rM?q;Y_I5sF)*oD|Y8CqA4Oun-DTn6?O!!`V^JZo1 z4nL>R74Q%vsa}(&WeuGDL6;=~>P4lnm1<|3;=e-&?~1W8mNKrY%72e;R=Q`)@Dry^T~EI2MLV z*J?Dv)Ln=>yig+?#jc&wa*zpy>4xi_aAlWEQ-n1MdB#H8;7xwlRt9`eDMonUh4RBI z&AKNEFw5|zs@#7UlA-5ZtLPM#aG99`l;0aJvOaa&w*g#843Qu7?QFG@Gy-|Y-2HvD zZmRgkTBK$v_&Gd}sQ@50-+C%CvVg|Q@fiopwZ^R)X9orCL`%4gh?YPE!)x-Q3t>$U zq7`q=hlBfXw|ma&DpTmg*OtB+*62d?yXG@Qfx`dOt+y;?3U;Y4zH9~9Q~by%E1_6vqp;m+OMa@~3nAJ?jWt~Hnaz3N?j%CNpvR@*MXZ|a zxv?h#$G!~(%4NAoIP(I$IJ1Sw#%A~}2}y+!ikro??`=9G&5FA(kRKN^+>@E|-Av)f z;gbPJ!D4JV4nDwwsC}!pK`H#j0orCFEx^<*9uuy$LyHzlU?&yA{R{_^C*;H+TVIoq zA251-<_!tVF>GXu&1J3TUl3Od-PL&!_X5&yk$33$CtMia;3Qn#WDZ=5djYz`rLL;;aP5dwm2Eq6$#3;zFEi7!N z)OzWIXApjS)#KC{{Y(!VS-KJ~yr+q;!9REa`L}{{JoPR^8%sibUmJAo@t?L>(<27v zUs*()C4JH7FOV;5$`6=6ix3qn)|+*` z}X39vc?eUT3??yjtPiMKTTaPK3@T>8YZt$_Q)t64JGZ zrR>nq3x#I$Vd_l#EgK}lOJGDqIxF0w)#@1CFrDh+dqBNIq=@LV1>o%A+oPvdZ&9mx zOWv>yL~uxCIb=-;PB-<9H*&Fh&mpR_jk%{nlO!Qt+ON7bE|7k(ylxR;`j_NJ&cN}uZl;lb?`g!0(fCSaUm{_`U)Y_bG0+` zGHSU`N{}AEdr)ZUEKhc<$v-b8UUpF4MIcC*Kq@5!LucKo77E#BT&i5g0NN)NS6u>P zp~|)`$IHgM%t7agifg|!(KI1!x}g`xqS67i_#Fw?`vF#Gz-l0)jfSe+cu6xAW9GzjAm$`8FO0wLUn&Bh7LDXI*b(q z*zJfU8hRWTCSTO7Iq&yioBZDHSnmJ~0MBwNVRZ;b$Qv*uD9kZ=Budo0sAzqoJVg%f z!(4V$Ax6Kk(Cr7bmEHERof2?eO@SDq33EBc5LC>ctrPwTK+%+DVq0b#hS5roDm;RH}XS?Tm=&=%8@! zWiYuhzcwv+9?#5pR^h`EdGNsHvjA;x6UC-wa`vs7nezV7d&-C6syj&UXEmX2OLi<{9kMW}A z$5J{9ZeYBg`IM^-$Xi1jo|b09;>Bzb5T%J!7!V{wqcG~LcCNv^_f6CPDIovD00e?q z%1;j|@2m$*`M`P9>eyvk%WNDCjygJX%~VH#eDdA5KZj>D!fyb8;qjD zMX3pN3)IoWL{O24A80X_$&0)S-^Kiuxvdgb7|^147^&Ps0LM<(Frt7#cXMPS(FOdQ z$UZo7QB<2zSyXGh06^$Zjo!34Iv;DdniQ}>CTFan14WQpaD@|?!8Z;;n!!itLFi~~ zhJ9~Z6NLPzhIAFMCCvf9&g13IiYs@Aop3`fOZ_4=6VI&$)=41GzTCJ$@UQwK0cz?z zFGJLm&I=UwEqTIt6BSf%UYs0cVMvTV){*0&f1o{hX&65OT)Kbz@i~rrzXPA-t-$Grs8s?nr36IvrC(VeP47DCQT8S8XbP(xWr|9 zwPfuYWSECZlA##^zD|z7Z9Pon;kjXh^rX>8^g6X-n(+bfett!a+nOAXX!|6H4?VvG-R2xpsJWDqELC5{8b)MIy1Va74Q52&8lu= zx+~$X;V`voLDdfl0p66KvG6Vkp{H`hbU*+4K}Fk@T}10YZ7vZkv;4*ozRs|2rjko$ z+BT%K((g&jRAjzwV&tdC8@EH2;5xSB_h1(*S3Gkn8*dAjWfo)b3}6+t3tk>V8VcbP zznX&kLUb9AQ5-Qsjsq}yuI>i>d-iRfiTi2)-g~q{^f%DEz8CGuM-glS zFNV8D;H+ZuP@{Mauu7+hwoS40uN>bo<>`Y1T?Oct=2^3*1cw^ur{HxKq$*TP_KBhN zc#n1<=Z;VtJqtfU(o5m7O4t8Ajt_@SANm0l zZqD&XBc@)b)ceTV4m6GiczI3ll|x4of(enRdn3?%E;fj_<$hJl2wVYs1n}85GQb=c z+lJeWTUWFh?`2sVMCy(4QoO!f0%+nnGUX!>$UMiD%P+3R$iD<=?K{`75(yQL19Tm8o2&=cwe3=s=Ae=fW(g)a*q!#e1t6>OV68|Mmajwf7i!>VoUiuCYhCQ_Dk)W-d?3 z4NRSx>>8zt|HZorb_YK(IXt(cW*-fW%Zp+)g}>AT_5SV6fpfTm&dUh(&-3t=kq%1e z30^3fmpcW^e*XS*YD`~Q44*``(C<->L#ouvpB_IquJEk8>*g@UKeb<1I>)qOqL5I< zR66?)_OC;}kN7}P3|CgU8>?JF9w{TsUX^FdZhfWDVKFG|L5kg6(TEJTBjXb!TXcMR z!7OWg%NQD%4en(P=E3wB?EEU#q0)aT<4w_fn=DNTKZ{@AqPFjtKuwDQ7U9cU!DL}- zNt?7%dt%qLw9ohrVJsQr_rG)Kb{xg~DG) ze@oh}lXO2cD}8y#3mh<~E<&MS3(^CPxx~O1kk%Ak{WF4jBHeo+=$mL&mj`~jRG*bb z);vh_{-(92j#YzsyED-Q&2gp24WHM&oS%Hx1kvZbw2}I|?9A4Hb4jcG^SAz67xTTg zF)j|wT|*m&qJK|ruhP^g8gzsW0a7499ZfZ}XnTz0AOyz6+VSdo3grrFYbN#5*anWLRLhv^H1ug?izB+4SEa%19d9j5lY$SUtc`V7CD(UOg&xr$$z+cD0k1LiN)CL++H0X^)kF(XN5H4TMOMx&(1#9H$r`qOeTQ~QxW|d4Q^nK==8ah zU#5Z`M#^WcaE~3$!gc1p%h2nyCrx9wbwhb(spz%rdg|K;mZF-OX=&%%Y)#{zq})Q& z&tWT@SUL?(Amc$P<8L}Ho)eQ}Uz9ucFM>BX+IklUU&pyM+X6zXC!Nmc@$5l6OzS7!PAU8@&YxyYSM2q(k z=PeV;=W<{&FH2?u(jX;~2LXOwLK8pW*cYm_Id@f~jS9?P=cs(0-n2$U_)h&}y+LpD z(?621$LvRX)r<^)0|Q(%3GjC8d`VXJMZ`{+`0<-KIu~+~gNpq=V$^8OVZ0Q!4b@Q5 z=OsbfT#N$wq(OZC5>ZQOUOu8%zZV!5bU4)}z=sil7gN@Dsozrw zYd1clbLd;Q**SWTK}H#RRv-8-h#>-gP7xh7D8lB{S5sLFkprS~j z?>{-07U*YHl!5Zn)$XUI0QKr+CQvx~EZ+W{+dVi->Kwvvq=3OL#l?mfr~xNh7oxyY zf)~LF;K-?u31tqMMU8d_{urSF<5lE%2%gX`(o$j(>O@ zFjgsV5%DI%x`Bv>-KQ(Ro9vLuG_e;N6YthUspAchn~uw zpd{G@fe?)e!%@P({{MU_hU$h-uCL!5wxjlk_aX-aKMdGZ z0H--e;kT*?UWqXt$4O3qNfqmjEsuWT5=X&6s~BQP{ac`BX^S1XG0jID_>}hfQ#y2A zu=t;eZkx61C5LLSRzqx!kg zMXESg*X6VsiRDG}BZ>~?yhefi%@B(Z!YtJ=+wc_A*)m%sNR9DC*);YNOZ&0OH`ong zmB4h~@t!uDu3P&>(dYDP^XOl-FfK>bB`%f)a0Ah$d*tp~VY`(UqXG^k*ja>&`r|t( z&gb~SJg6pAhrx9}PUE?95bjW-c2SUUo8abb@Fbrl;h<#F=CuS+E)J#m51L+8ce!J+e)@d_ZqfT7p6+4tq zmla$TNx|AE^f@?R?o=};N%}G?7?}0CZ@G=z(~D84T?g`3(-WVp@vM#ENIkrKO~#}w zQ`2C%j)OXfv@Q(5$?haBG0BxfJ4JFv=a@e<8Er|Z|GA#9(C@>oRwF#pld|H6K1RMQZgW&s`Yscu5y)^FEd4|)T$3PGkP^r&M3U4;PiXD;&Km&KTf*Y={kO94- z>ajbI$o1Vp4&e|%A|zU?4RjZTNUB)|4^`%fh!G3X*;k22{zY2YA$E3ivGS5tDK2*T ze%A;!Cuhd|y8DO<{0*Zk5D+r;;7S;aHOqPX%wLmyH=T-+ianKe*6Ncpq(j3IL1bDM zzy#Yk%`>l`312i7vU6b6cX>PHYa(13r&v5=W`MV4^(u=Oj~E;9e07=Jplnb4Q^C1B z+c;o+CK_QtajeE%cCLw><2p=*84*wnQwzgd45rEhKpGN5MUEpc9m)PPE21BKW5He+ zVtisK+hfW_{XdN2Vjj!&xanh9i~IP~(u828kLi?d`2?U#-!xx?$jI9gJrNNCFnJU` zmn*p|+^0D#M}=vlcf<(?M|iSM1L0#MI?F_j<{B~2lxrzgemUVWtc=yeSQH=XT$(KZ zFp`H*`QArTu>M>?U36>ODW7n1R`2F-9dg#<6hx~brRSugQ@LMADx`J z5%gmBx=$p$1Zmjrp9xX%_1a@CQi1cvL#U8b#4tPpVqbCa;3;b9v^mQf22Q-3b|3E-jZe=~k$(Dzk+BwF&ggq$QjMwU5a)1c zy;wnnDj=h@oHiaYWPTF>=bx-Y*E5a9(ErLY7b0!Y=(NcVzsf^{qxKL)uhoEfSQ&A! zrmU2q`lOyZi)s^lyBbtfd86E?gBr+2J0^x~FUvKpW)R*%ecrPo^aB7DwgTWuE*o&0EAPZ(wZ{$B#$%+);jZ3FFg>pL?#oc>d@*EMb3qk zp2(+G3*22caDgO&RKSNmc1AS9d4DU3lTnm97A{z~)9ltTgrC)Fv5dY<%X-W23)R)7 z+p0mmiMypXH5&~ur9fn+#s852!6zhU&n;lsG=>SkoX-yD@B$;_sf&qo0xjZrR2J zqOyR-f`c~p>C=FUE7Rr^xM(K^xr8#yR0Mu1#}_bEZ_0$nEd@KE?z>{xn5nvnt&-(- zePWsiOqv2IIGGl3@D70sk(g09s`VvvPI6&oJ*_hpqH(QyRI#c-7*VruycRK1Qk3JA zSWt;YXh(l~E>M*GcGGr|pB^I}NOANwI8Dmdi_u`12z1P} z0zk*H2AlbB=3~h5YyH^P(kLZ-yIg3qx2U~#0ZuF0&VuA)G>(;n!mWmq7RV|XB!aLe zqoe>*Ww#h212%F*cPfjV>*%rRd3t6$q}&l~fk8zqgAd#c&E8OzTvAp}xFULSCEc({ z2)_v$eQl@urh_24$Tv7F7T_BSeL|`R)=XvAC{bnj9irsjWk@uQM(+;6UjsPa3eR;*zhV!=C~c>PS|)y|H~t?liM< zRpFCs67KdnkyG*#yXw5ULBH09q0~j*C>)05+IANmsP2l#=3}@3V}1<`yP&?*u~`e# zm5Y>c40ujX*EE{kM=zD`t3f@MiSKT0hR*GR%d+;3>7Kr$W=INbMYk|HJ zRHhPrxI@l9Vc?Vyz%27EIE-O*ED|S**U&72hRs}gHodZ`MaupkseX{`^mbHh%He=+ z89_!g36x7(f-St7(QHbyfxAGLKW*ZvnoG1eU@B%|9WMf6qK}uo;XG{~iHkOtc@*W? zZg*@>=v2E)j@dbPK+*rIm#A;{kp&U}hk#|LEWl=iPKBjvh{6@?0hTXCn!nVaU)Ne% zUSTa0?J*hMaGebeG;F?|*1zFk0Zg@t0bcZ4D`baqRGR7%;y876{F6m@F@KMZ!F$N^ z+C#jos9><2mYcbn#<(dP#*V`(dQu`2-BZB@MR^EVMALM^Q*!Ud{grj9mJ+~3+-MFZ z)Rw{OR4c`MHx8vv`-gD9;s{DVpCdtMwMP;P9X~s~L zvGZ0SD(+|vgZdNqKj+ZB;4Vi^!-F%<^$Rx@xibM5=aoG^{ULNPj9bV7HID95sj`1= zCWCh)a5e*_?V$OfxEM~vG91m4vh#}zrAv@0oIW8m*4Nt@n?zAon^+rDB_(P}rf=Na zeyn18Bu}r0T8GGoB4w4)N)v3q2w%~m*d&Oa)62n0Th(H-;2{mF#$ocDVyp~(-RDKP zjm-JiTI(y^k}xXmU}{KM0b1Q_%v!TkUYTB6=s{O`N}}+YN)CqNC_pQrIAvN8Ir=Mp z8{`r3{!l6gr-u}!NKzd21JDPmjOe?TPqHV!OG%REjgmq?uDU)WG}W{L0y^PICv#~t z3rb|@6JChEGIyM0+GF}?!%YaICg^A&w9to*?1SlP6xKs=4*}*zN=(IF+(wD2gfpSq z@R9>6`{Uk75u4GWdMh6kXvcWG+F4`fOSU6??6j{`qJB9j5Lr`v<7;+|FDV_xXu>oDJ{%Rc!z?t82rBhdC zgeyaW9kYh!yBN=pB+4%{$an$5U>Z7oA9HJ}1vi7>Q>no(q5dl$Jd7E8p(0mY&#y7l zFV~%A1lxnsW)!Ij);Sw?Dc=Tzi*gT}px<*BN;tLlFmP8=blr|ngH$a6P?R&*Aue>+ zhA(;p#`)@^ix~fBlhbhV_b1Q0@y?+EU|C@Y@dx37p7q&l-9}e9WQ!7;woGi$U>>J2 z2vv^7$zOY_V0b2ct{=dV4<$^}yH&;R(rcUh4pRoH%)UvMA?(Om9B}o~5`@KJy$D~K z5SOIeTR^s3gqbw|evUYb)@zMEfcev6SSDNpEt$z~$OITf!RgTG3u}?lVriQr8B7>? zhz9ALukg;F39ni(BUMm$lPXNfoX|#FztUXG>90>SNOH{VLLE}0Gnr4iPK;j4lZGRf zMY^9?3~Ep&ASXvp6t^rmZUhJ!)ny*!v8yo5%g2^g-<#-@X2!+9sUhl*9w3+&S{jv7 zmO)}u#1DYws?)2k+xBDRtZOsPQh*5%C>XB2QAd{U%kdBh(KO;0hzPG;Y99BuG=jY> zk+9O49SC7XM=tUqN>c>7>e>u27*i9J#1W|_W!%x1JkM#;KZAntbvMouh7e^l8}wuU zJIJIq1F)|6qcK?o3xzvpVs;VtZkz+$a&X%2;GF8|AvaEU>1N2y&`>=iS*|P1##F7Q6nuTGqzthkpYgnl}04^hLY;Y|9r8K_QA9&7*yO}KE) zW$JNj|FS=#GU6Df0A+#*!nVT-K~h&F#bCaHb<#6K{2<_Dx+jo!=w!C#%C|Y;iRt7Q z1Yj|zbIfbpCAke#!<9bYFAH`56Do<8_KR@Rw=|VCSg=oc_1_f8rqod34)cqk$RgU9 zJyi;dFTrl!l3wfEsa74e2WD; zmI98-1*3WnDhs=U-Iw1U>lp7(ogV*x?!E=fk}J27P%pqi zM4T&`a7{BOfJ)#%HG8IV9w;P@HimgR8+eND)ZA|A*j-^o)I*r1ZIhf+VYmSO4h?#^Vr_YMG)D$cn41U2=2 z2$%%~=*&_V_K0QCbFrReB?c%DxmLZ>pQIb^jA7$m!#%|{nf>d#K#*)XJamfd0q6!9 zd;urVHJUVQy@+8Jx*DD~8V0Q>Aem^KQgsRnP%F{l6k!U-9;!P&I7GgzC9H@p{Z^nqXJ}*Mcg=h=e!b*3eh(+o!Hj2aP0gEmuejW zuDuI2fQGK=pf;Zihc@X~&zMp;&tTAI^iCwu7qwMO3nD#Nnw0ebNze`ab+~|W_y`6* zlnV%JNpk#}jY6l%QGH@y25-OrxZj*Bf*W~`P0Rf%=x_#gFvH_1pkX8y(-J5q3frDQ zANtbpJ%3Q*N;rG}>t63e4QP7Dz82-SaAcyT{xU#BdFU+x%&-wUk}Gf9$TQeD92EVX9RLHwzo7_>AxU{4!ULSPY?*GELjX@(|2cF5w_7lff)ll)c4 z4hE-Hl~lN<{hqpR!lw>@N?E}$KTMoH5;WF{`aqq|UF;P9|;SGWO zvBbV&Kd(^tnK7Sk5_v(Yl*kn1%f!dbgwVtrb)Y*AFHzrg@omHY-$^b!xINT8be8qk93mf4$LYOG_@g8>el@N!7p+%n?`{ z8lFrnd}1{7bC}M;vF53|O<>IwJV*ATe?a{?}F%X8l9*K2g&+?vI zy(1~Q&QSHqV1>^xNA#ViQ#_4U_mt$!B2rL<;XJi}aG zY?_7P<{Wh7py1pvdiaSHM0h^9i}tnF;4LKHzy1!;b>PkL!$rNvMoI zNpBuu>_m|!FD~|f_*=k3&=IaDy+VE~XZf%{p6Qpju||2ghqBMfj5sbYm8SZLlT+8AbAW=bD}}R2yGxnjz-9btVGYk0Z&onm?Y&3j^1xTU zHgIvkIEyvK%;p$$MLKd zs&HI2%nwd5^EwMufa;W_P(Eh~pgi3W;7<$@x>T9-M2{jxV$Oj9g3C;Ecn1`3vN?tZ zSmr5K82V%^a~L?&RnT8I6zsV$^+r5ikkZv42aYWDUS;>XBMPi}j1+;vNK<6;)6EgV zO5ba#cadb9zO|s%4s%?fF<__KJWMX}p=Yomabm@^RF&x&BF33d0}Dkilu2c+$1|-M z$(azx0Y4ecnW`5aY=)bD;agOr`YUIDi9aCccVloIc{nbQZ%CGYB&s^Ro-W{KNi6grF7Vk**pPO13E2k`QX!ZRHjl?BA( zG$_JifS!a+eb*z{tPz$u`gm`0YiGZ*7%|={!$@w*2UUtjr+*AJi+XHyF{@9T5Wv;U zq|NExNbjUEj|q=MAJ>-ye!z57!p;SpzjqqbUvXC>Tyikpi7pX4&ceK`+V9;YOGAFv5$=)x#C=f!ZDl zm5TJJfupjXya%!6C3*?bVE4#@t``HH7Ec-N;!u zD*OPvJ6+xfm;esUG;Z*co<|bSp*@${`EO7eD5SM}pdTVxUM}zuo3O{yR`%}{+Rap( z`vrC&G+OiD|NXay&Ch3|N_m85sY9dZx;(u3g0t%&M-HMScmP5ibim9Kw&yw?x`nIN z=%5-QHt-_SH5ny|1#O!acDN6;FjUJLTh@z>`^&NCM+C&}f)?_n6f{PQA*KPs%o;JF z^fcq408t?y@z7~X4j~bOV}&Q@Oi{-)gSrEZD%+zdNV|Z6fO=d%jYsz^o72;CRW!q@ zoy|}8gP0}DEV#8mie18_QG(+uQTf@#u$%HsWMKTaW)K`oE^)@+py_DMvap0Byx213 z+3LEwpWaHycqUrH>6m)T3+KfinggMSmMfl%p znkJt$6-4QIpdIR6tYgl0(;X7MgrVNPG}4KskQ#}Grj6EnLK|hqDbOl~2VUl|FZX$cMN{4Y9-SzedqyDT3_A z+%!JI=sQ?UkAxm76NJ~~v>W%@=sr=RrHuST&ubq};6Y%l7BuL4NFSLIG7JF8&I7`_ zkvAJFn#Zw(N9nzy+*Hr%rtrSyiqu9^ehD2Q_ZjoJ)28a5f@Y_(ZK{y73WT#1K*rP| z!h&ZhwepB%XBMIt(iGprv6#s^5WI%+fHouWAcOD() z7@Yx{IP~Fcz=qf}lpT6`E2c}5sD~lO>ZZ-4 z&DUbKpjo2g77BBB6o#C5!2j`h&iCMh9{L5+-mOF2Idvn16LiM&&=X$VL#g`sA-Bz8 zS`b*JO0%MS?LaE3NCtgAxok@?q;%l|GUF@Klpm)!I0dUaryh#2UDYML9f1uE&(#6Z zDLgYwqS&DnE zv5P2S;`PNzPp7`bor|e3ksWCXIxvO&P;PqibxvcN+*I!0IYH2d0vIS0H~35oSK@5;tPsqSc&*-p=KlX zqeA;4LObuXxiGh#7i2v?Z+Ar%L!2T)12?A!6C%xgk;eK(6HDRj#suALnmEj`5!e9> zn54L$oa*fm&Urdr0K2n$CpF?M~if;b!Lnz~!ChWq;U_lp}8??ucfLiE?)*5=1fpC<1 znxsS8BE^{={p>`Yj&X4m4HkVE#*p%LSM2so?7QaRoV_JDqL4p8SVC+}4Az}Jfay*- zH}g63&l09i&7~S1hMH*d6zx>n%hE5-22#?IoxA7Ld+OQhJl$XMpoa6s6u~j4yhDs` zH=Yb(C^;3G;TXM>DWL~a+EPb+C~c}|9#xhT-{WL)eGLayeOvH&opEY0KQVR_42a^d zyKE~EFhf8Y$)a5M8gQ~s>MQbXr8@R$ZmB~zJ)H)Yhp8!@_AsA6+wWMSei$T+F*#FN~96kbeKkW*jGef5^m;`ai z=@i?i1XddxI1f@aLfuw@p0`R^v4IZog`fm*ciB_o=wuPP32Y0WmZgi<|(uYDG}Gvt<*}+n==-{*qxarb$0K`ft&ht z3fOKv1{5M>m;PoNgIDyvmQX7FrX?(>@wCA9u%t?VTYciJ^vxl2Q z59w}P0*ji9{rPP&!x`_~h6iqbb|V5aj|gNE{a8PZDy_8mEtkQmCni@uOfVD=E;vmK zJbsl%27}T^p$imlQw}l=i_xq%6QzFbE_!__W*-!9TrtHJD{`3O5#6>@au>d~X+xwB zr@zrynB@jmvI>nhKV)K_x`T6Z$iLf3NExB6iH5}_6KD9{@-q%U zYG|JG)Q;9 z51I-0o1YF>?9r(q26d5}%Zn@uLFV^={hJN=kuFPA#>NmhT0=HwA2YcSW2xSQqpcO9 ztLi%EetA;lC_K~RGH%s5X&3e@7?GasZh1dSBhIznul7xi|gGmlGe<$GWRJMlJUyD`2ABv|^hl@0lFOOx8qpdZ zXf;y;>CBGpbBt=$K*M9iUjCfzk+oJEjBOoPlP#Oz}LS zjj*aM9kg6#GN?;J6WW(w4<(*6236Ymw>) z&er1)(hBb0?p(mZzsCA_*4p1d$Mpxg^Qo!00@TSs?_AvA}-U*TBENT#Le z+G}+3LM+j_!cpEerw^`bI=m-@FSFj=6teY5AUSl+r?JGC47WpolFmy0$3tv@a>VB$ zpGX=^+>z#O%RZ2&b;^3Z1;pLusbC<|h|ze=0ZtK39z*`tbumW|9w?^9oi1Z*nYOoX z)K-#S^7P!A$(RAA`DNEk^PWe-(6*G*(Y71P2&qa0Q5HWhtW#<%>f~7C*ukNB(8sJ$ zJtPI19f#I)YV^ZJD{pns*Ih^3>Fcya&84EEHK!->Ptc4!gBs@qp^PeriUu1$sWGv@ zd6Mbl^}f}?pk_8w98wN54A0aY9ATx~w@2~>5KP7N@PPe_F(5>#D7QTOnkXBJ;f(ck zqS4WnYb9a|Sw z#+lj$VYUh-5ss*Zm1zX#yrnLFCeDI*gB%=Pqs(bGGHiEVz5R&vn%3x|!x--ac)9iaDqlDh2~Jb4q`Z&f8L{Fhk{yDuF|un z#Z1_PWk+alz~Rw1HBI8Ro1&;I((T!$#bLMtp*+>3%xgIO><&zMnTd(yyEEgkRXOV4Y5#%QVh&& zN1Y~Qcq7)hCpnSsB2AuK%1G!`su&`#1i&_&frjty{CGC|gL4gZ?b0A;qe6F42Ye;oB_+x3~$(5k*+)1b!6uf_wHQs)hgXrw$n&{JB( z>EwD2*RfjS^Qyv+lEhJC$0?wuQl$W*s(C`0P$;q zrO(cEm7+P7Yq@pp$I?P$lTS>h*v}2q9n0IbbWgD)dqLD*bJ|UcXa|=eEp@b6rDS2i zd}B4~T%-~hm9`w|u)xz%nLyIwqg?Dxp#>zfj$uBUy%gmPnzT+DBfl)ZmJ~ZEK@6nSKqtk@Iib=7GLP!H|LPz0pZ|nJq@IM9 z6=3Lt=F>Q=87=8Ev?kO8PL|tK+KNY4G?yLg$=RKpvAt3`b$r$_{EP19{iW z``Sh}_DD_eA=`QUxXtrr)&p3sQIbP%hB)wWowBo0!BThF!ic8SRa*YrSS>@^wKDTg zb9{&LrQ1AJG&m^D7#{^Qh8t;Dy@IVause208(?$X4wH%N~dusgEnFgt(Z=-ngC^@S9Mb zT{3nNfckgzRniPF#%e`Ra_9x-w;=Tzn(Mv$-AFHk`g3q*_ckeq`$Qu9)4uCq8ytYtpkEv!Ppre1%oMQ0O1nrat4+G4po|wj; zvhNr-Y&;1lY1Q}Wd z@7{R=W@38yy@%nBfLdtqig4f-Vg&_Kyp@tSd)NhH1lDp?xtX!JSr0)8M({QfxVKv6 zH`VFGVUe7nXx15mtmim?Mtg&a7wUaS^=`sM8+7#`^RRLdPMz4x;VA1p=I90_DoLue zM9UN?j>QIrger|0?U0h4sBhXR@V0<4GE~rjWCyFddDL{!xq_!QnBlEu6O`n%YuYH+ zl92uf2{2(gFGs$5O-}SwgfQD>8ADQ*I)#vW9zqutdf+YiDp$*aiOhiZ>Wrfjkp>|9 zf+e7iu;-PRFMBhJF(V$q$-?u$=>ExgHq#WgELt)%t@_|PGXvtZ9Z?!RVvtQaCUgWz zBji`aL~s>*Q#IX49+Gko!O4>fqRtYw(9h?Dn;Ev{o9NsFW;>^yxpxi}uHOF9P(W~s_y7)=}l*>+XIM0(0pBE#o_qG<9EwHh!g z107B?blhOYscBGlNO8lBHM}FpXG=4<6~!TE&{0S9je1si+&0-yK($U3i~-BMW^Nd@_(siS0@@4N3l(jt7U0qpLCI{#?!+qv z*r>{_Rq1ny)m>^VS@I_J@Cisv{n%~7LGMrc;cMwG020O!Rc~==vn3LGtU2bP_!!-O zfngLVbxJE4O3)jyIYZzE18#gj-4w04Qro`OghRuwVcv^!_~8EBoDc<_D;*E(Cb?l} z1>hvpP*G=v?Nry*7cs@UtGq#ijZOEBCH1gWx|AtYEj>xukT8389@l}?z4(bCRTHi~ zq;7}ll;P)l>7)jw*DD-6f&r=JK~#<(&D%$oCsh$;=0FcDMG%Ooe+3`Kpl4b|1Q+sD zIqVqt1iAUc?#eUPKagZmrZ9 z7%BHET>#))WwwQRKU^;0HA#dPaHBRBYbZTOal@uorc{}fygZN9D+!`5vBL-=)vh$8 zBdrU>OD7QpoEijhlo1^&TXeZLSSH?)=Z0%ZbnSNLe}~z!A%x($KIi=OId}k2sq8q_tOvm4<0GXGLI|Jqk(%a|8n4Y4r{zcLSc4ME?H#W%O@spTMFFZf zz~dUzgo{gy!}9ba`+PK}l$q%VT9X`iDg&=nWeZ^jb81{@9IZS=*nWVO{slP4TU@p- z^Nr2Ea)Q1KWVH{Y!&kM-7ai|9;S8}{Rs=b5J6{<34I`W(E;eVRs-X|o2HQuZ5f7ME zAha|d{YDhc$&Qei8aq35S(1@$HqC0S;aB`@QlI0$slUOsSCp^oPn?O0!ds|s-;2l|3Hir2zunL8!m zQb%Qw(H%S+iue1V#WTwHDZSrvUI`Lod1IX08y_VH&yyuC8MtDG6}o zYegb2CG-hcSsW8u8weayS)Pm*+6H1xGoqc-%@X{CeI+w!BrtMLP}`IR(L?=Yp`^kg znQk!mgAMK)(iS~)?UdoH5z(A3Z!;W-Sw!>Y9%NsqEUZfpf1`#vuQkwI#j6>j2NI`k{Jv@h#MH4cVjNvYDhcFnrU72-V+Lr@D`2=Zw4*pE z7u{Xu0I(9L7ZN|<;wr5SSxJ9#frYhdP{Z-GXt<$2_83hh8bBkLogG3ES0*|dlFz!n0v%*?$C+~swxD;_>c(B6a2 z@Wi?n7f@xVDD6LqN@Yl0m?|682siHHI*wv)6Q{Qx5v~JCfjj)H2ux~IvNvbXg=9c} zQ)2NmnR8L`Wxq(PgL~FMwsF-0;S!`@Y2j`H;U9bSJV9`FM2YUE@Fp)52<(a!CtXEP z46RO)1%uh5{PA~xp8&9Y+Je-{6&8omvPmul)`j|c<^OC(GH(ClRW+|=B@%iB!n}Q{ zoE?0!cm@;~5UlqPOw#m)^hofOP%9e;_0LJa!q3I#Kg(JmmgME{k!1Dx^(7|t5-O1o2OU4 zscDV8l7qyk?)Ei6J6`9Uw_<3cRa~16cb>6PNiPgH(azQ8SKQ8uavnBPT@%U&D|tsU zTTXh0c>@%@-*X!D)LJEzUf0*_7*p_QLl+cx8pmo>N!~MPtdV(Xl`=M1L zQ{j=7Rb?=$RTbc6VUi?ouXRZ8ytHbys?hui3uBFU5$=V1BycCWaj4wANPe?PkF~Jw z)IXW^G~;(VO^OohATtF@nq*0mLRJ+gKVh#zEVfyPH6Y#ExwRHHYVVa1Zy|A z5xl$@YMa{$9+VVO8!{3eG4Q--dO!*-9%Wh}qogxRUcJF5o77tbo@$Rz+^EU(DFH^R z2f`$H*lY)yA<^+eI{4G$fS$ov?+hr>{{gCs@+YbO~S*O>5b6lqJVYD zlUc5;WI~VQKD^G>T`pg}utM=^rfJfW^)DR@`^_ag7N3*ezOHJCN-6V$4+?k;H>x!L ztd0r#{CDH^ONs}~>@k*{D=Cj9{F7{SeE91=o7#}>1Z=NZG_0OV5QDShZUMiL{B7z1 zIC(J^#jKKO=TciAOxT!((ZkSBbxBsyL!;A-T=Gu!c(XIVUHG|_!4lVE^FT`#ljoze zdm3$eQjK#w&U-OY9$}6^$GEi_luy!0wb2PvgufC}uqNAbEc31LcVBv;711sS5kN8& znRJWw69yQ)t8hLEulb;UJ9Gk}4ab;hI_G}TF8Z;RrXMBIIDGK zVd(Z3V=<2_8}qCK{KuCnlb%|K%%KGTMmoqf;ct?|$|uSa?(YHG>1r>>wAqV(BN1rf zu__6jlx&HTSf0)>7b*Q#*3!Q znuO*Xjo^*V7}2y6vFYCI3G9F-s?Q(R zV5Z4~CG8UOlBh!eiYPM9p$1D;<`@btCVK@mNntVfQeWv?-kIq{zDB{A%Q!_`T4L+r2VPuNjfeYUa_ z0X_emC4o4Wr*sN~Y3H7-mWe?0yw;N@cmfmEw&f(Q&7!I+i`{^PPWG`DOA4$xMIf4- z#nfi4i{}OqKvQ)A6+x1c?bbK60JTsx?T4`qU=WZT=KYRyzQ<6rE_+xYlQtfw?6g22`YmzC9Ux`3WDD zzM^Q=3H5=>`Pe2l^QC47b?!AJ;;1}&eD)5J+RF2h$Svarp->l{9puZ?5P_l?Pmkq!-tu6W7~>RR$)MJH3`UK_5PR zjH{EMMopcdQzmG5Ut_v9H`D%a@&vm;GN6`_JX@W^KOu!D!|qgnVSA`?=>R( zQ2A{CWTjCv$SEjYXP06Au#t%L-iJ@b&q(bnBomTJ-;v<*gidHM)`!%N>$jWz2DKbS z>l-ljlGo>*KR?EhkYe3#si=Sqb>Q6YTk1A$o*0mdCnVj2pFOj+o6O4cq9zO+dVX2l zs?c&R%$sqjLjnP-Qa?luH>CBQ+{}i43IfRaKt-Xf$-$OuJCBhuf90;1dc(1u0oWOD za@^uX)mtD7&(bD5dald}cAr*&kgX;4bZ)gLD36p;4{gS6wJD>Zym~85QaE*Q2*5zN z!bGV+R7kvGB@4C38qOp^+Tg1l-KZ0$^SYdqN_`4ll|(Vsx#2^V(98`foz2>{s35^f zFjc_m3H60T?R0*>!h6q#8V3kM+_Uwo(e-mvJy4i(C;4-t7#zSBM&?u7*$@hC`D#Fe z))Pnm1ja*!Njy&i^~6Y)<68%1AfpzO2zdX@T>L@MEz*khfRbSf^O>A#gQ zycQSMi_2ViagLB^^(XmtN&64`{Fe?4)y)<@1OE7lI#?FH^=}r?77jnkVE47FRxw z^W%Be#owukzwRN0E!Y&GGoY{(=x#S9X?gzsIicCyWKNFzKuIUp8M01Fz$)o9ByQAs zBfH3`Q#&xC2Q4$~aX$a*n9fwgd!1>Q97{7j9EBY-`%OIorr)a*4ccRRX#ZQ$*K_i% z%dBGiE+MrQkzB&Q!YNVY-35A_AO&=BG8F~yS0{Po{ESc7sA5i3T(i~tLk|18j=D6W z%>n6EJ1EV`!SbE#s=!~zjj<2%CcJdaKWGU>O zf>!ZQNwUZNWfmqSnDP*eqsoUyKYCm8OxU}s>xy<;X`ITN+XPwY5JPmv**-9nM=@2i z?t%0eDJs@YO0S60`HW~i)WU@{Hu+)i$o#o`tN}OWBBe|?odf4cm5!y^maxR6Ot60z zt-_(z`BZR8cgVcGfYb%{a3;4qhs}ni>2a zF!OMgCYD~Iah_6?gu4~PG+_ZW6ZPbRP!hY$RU9QdBcz2dzfnJW^M7iDDsZ z4-h`f9KzQ{fY4AbsA?%ESyK*0`*np7Q5)H-t#%<%$AYbNtijXMO;nc5eF(DvPMg%` z-N`k*cCsHkQsI+me2!0Gojm5q(0D$mMG+2Nf>T<2)kBx8r?Q6UOfmUfR0qAHQ)b|^ z916sVo7cB*RQ|T4SkGO@H^JPro5DpAn#D|f=vR?-r80jXK2Z37+LB#*{Q1`uOmv2o z)PVEDUFw|!VU&$y6=iNlk#XR>c}%?c3FAig;yef0fx{mS!*oFj^)ybXE>s>F$4x+|N=oOV(ILw~&niV22|4#Fxf`8Q7& z45rOXFCK8X_XuVVg|$L0<#CkA&0G$~0AUZbW^Zt+5S%JjC+WuG4JhGR zrC=X`#6d>6BQz*HMIAHA)plNxOpT-gRhHYdtdwyfG98lx?|@F)X^Dg}cjcNKvLrSY zqz_e1N#>}P=<{9<_s;{X`)xu;n^Nm_WuSP-cnZ^uo>Ai7s!iDe3!jJ36E<3tea?Dw zptr0m>a6G4Cg>S3f&=&r!2p**pN`$A4I@vWWeC#6(?q19GiEVx@ej3)7VOce{OCwz z+O(Gbb(p;mK%2rng&+hBlrG_%-|X6^rf?U`3p)0Gnja9jz-4ALJzOBgZklP)#97Fw z@LB1k#o|%O@^f^}V11^ol6Pc;DTZqWED{1zvi17w3w*-64c4qc>|u<%X#xnNqEYcE z(98$Vi=l7-(^pbAi_~#_<)(3pq8- zol;M^HD}*3HdX*3bVN_PO(?~KScyX9{r2Zj>Wp8m+4jSIe3+{+`PGO> zXXLhZa@zXnz@1Pm&NAH}&;Kqpn4;bSWZts@+@S%Y95aN`4I3ps(Sy}Ij%9VQf6Qv(6d zfy@w!%$YePU)|$u);CV^f^23$i$U)~ptqXMhKvH)Uu{CSA3M z#VKjI&XGbZB5Yy!q_v|9K%U#z5!6P)}k;%L+w_NY%=> z7Pf~?ee^5HEt>vQfyj#p&K0GBf)mcqk^HqOXc8!Qj0p1RG)U9^ezm?%0~(2Dr7D-}W)5y{&`hvV{u~((OZr~wM(h=@ttdzQ zY05%Z|9=&sY#A$?(x7_mPB-R|PWug@A7gUk2Av^n*2z(1_GC1s3eR^SGj!WYf^6rD z*^jOH;d2AgZ8wbl)z6e20O5m6z}PL~^W#c^;oS|INyvVtDy1Q)nXA8{cN1^U?L4HS z6MT+V5gZ=rf$R>y%_S9Q)@C<|Vo4&R_M^1HgLIpjAS_siV;kWdG=a1z!b_eJ z@q-7`oFBA_Iir}F=MPuG%x6$Hw+N^*?Kz?7PGpd37T#;hg@BmdvCKo>EM=!rHr=GE zw0WysPBA|b;vx}zMsufWJf$|mp+{!HMX`5!a=#cP%^uX94i0ln19U?jn6;1KNJCN~ ztU^_FzOz+&WRH@AUU|aJ3tt8AvEYTtMh*kL(l+gad$757?UJFRPSV%M^KfnQzX*>)Kx|G5 z2PL7i=JYtl%oqVpNJURZ_)uw}R}^fD-*kQmrJ2jfyDugYTDRc%L7C16p9!AI7o?A( zP-MZmN};FpAfBjUT~-Mr%~thce_ARfn?F6lsmS2~DtS~q`biTsKWeXRiG^!LXOznT z3`dRWa;H;8aoh~$?oP#}@AAIVyPgi3ec zx6{l-6DD`Efw;6ZZNcXc$L1KZXZG~)tN@E@*R0o*r+OqFI3#?bjbRQV;Og@X8D$Rs z0NG>DSD^}QzV_balt6jV^i*FJl8Z3h<#UILYetBYrJIS7a?XJfKn3^yPd^f#t#W{o zGNF`MAPbp8H6oByC7Nf7wIh8+8PK*I)f<%N7$xQbl zR+U`_WBnqk5T!Bl?XG7}=MneF<|RzZO7}Q0bLex8ucRiJtxqpAm^)y<#pVV`+U=~N zj1z;J+s*HO5KgEJ67!9Ee7pjwfS&NBU4NuRy0`oRU(hsZED;$p;~J}=o4XTI*XZWH zhuJ-Fw6NJB*N_I!NIanDn~d-L_^`$$>G?Wy7y&XdhGbu1^k|4X*HQsbqSE<4F|LQ; zd(aL5RM&A|Dot>by^BC%`5{fi(!-B%&-3XFzxD9ATWlTXHUToz@p*w0pDLWKi%W!uvbzSJ6cx!lBcH)FLe@Hc zy@FR10RaM`T4{=4SJLC5`x|vlQ-bB;nSCiN&Z$+Y&DlAgK7ahX z-;;pj!V(=Qq-~v74#Z0S%2^+5=G5SB7pn94k#IsT8e?RORrEQ;JA%UMS^F?^Q<{9( zlb|_OgtiAtp%>@CofboU42%I)b*UGA1c~iH2H0LGpZA)pr4a^|1r1gw>i zgosM@0Ncz*5X*Hq&7-%xG!^vQK5s$8$+Yx?9;=reG0P%4y^g;Km?UAwoo-^^`XX}>cpPVS zmCCocr0*)oM~MG9Ku?l{j?Llohf_eyiUJuii4ffr+YfB=Dk1j5e!p`dwRMAPDXMvS zdV%U{4pujivAV-!KxB`$wNUtq%M^nZcBD|&n(RD3GwANWIImT2ms$-aOzN&0oSo5{ zr<|t5EBOqt!>7c%O}NZbpj9wHa5?3=H0~+*p8)OiO zuGKCxxKD2CI(VwBvn5F@g-W8gvY?^?bs5vmpDc2Q1oJkg!L`e_ z${iLhzXGkAq6-^)yqtl=0e>;36C-DX>G2_r&80RFyi*umfC{obu-&0uZBVBIY#fbJ zsYdi*L%V|!z!I|I*D|5`e5(uCu3c3h<}&3P5zKk7gKtA_B}a0$j?MllHn z&Zj6OhFyOeKO@Rn%4@{;!iX$F0Fpzo4UmL@kMPQZnj<~6a9R&|j(4_GH*;BtOMnF_gI?L!N{EF3+H@pg-_7E8k+frkd?}wPBEA3#o>chsJ>~q-s7~MFhO>&w$7{JwdXmt%lBY zF$SwMsCLo)@QWQ)obk)lijcvSDM#RD(xtfxasfgn7TS6*s2IImvggu7;s(p0_OOd< zpcuAVZK5phwqXW^2nDl*gW2|=G8eKYnquZZQ1(Bhch$`vpr&BoYKh^`iiM;NVCrG$ zCltm+6mpiYg>i4!I*r!(dGz4Sxc|68{<{JArx&~WiYXfwP^8r90)2XmrchX_7h<4|uqv;2Zspl6_r+~cXBT*;-D`dyANg>c67eNb0(Ov$Yl%)NJE zGK?I2HO4NrBCJnIY@JDSYMA$O!$G%GzzlLP`LwsCADuS@HD)OKNVUmHAS*t4JG)|q z!y&5Sp(Q|{6~gHBX@%wDG8CWr+`aV zc$I_ta9e2`;Fjb4wP4!QO6QRsLo=+=clt}0GIQ-;VFcpV=+-P1V^C?O?I#he)zqmS z9RVtjBlbc0>TKbI6zHu~7>S%l%1x^~Rvm`X&XphJikOYZEn$T$jKl6aZoh#&TLNxT zEyomW0&c{TH4j9lX?qdBhH+Zt0Wul$E##kesGGZxl0~k;UC*N@bcW^5%B|H)W>oMK z3>1`W1na23kS*z8dlDbEA#2JqLXU4F=>%>JCQ>g^Ls;^{ipMB)h*WDS=s)uAEBTjf-RC4!ccR{=NZ3c-fx4>k7pkUT)l~5ua zJC@o9(uF(DhzqCP21j<@%L8Emm##Gg)z2AMgctwa0Q?{AOsz!@QX7SCXsZnfj)Osn zE-f&q>1JrM+155xkvh1XrfI@-2lE(5zcwvQD`%@l!{5n>^?7wA1ukQGXRM6M?Bd2^ z3PNmdqG$(!+2^^!dqYY~Yl}Bd4*nYLle8?)2MrI@sd`}Y2W(0)bv1Y$zSqF=} zrDcthl!j`s;3*`Hc2O^SKDj3Y(8`rt;eaq#Q0}-Wekdd@SihHzrB<4Kn9=KrCB8Ad z3m3MqZc`(OOO+XF6Z@QuT(m`ciCvcaSEVmli_mvEU&l})$Uy~jk6xG>u56Xo(DH=_ zK)Ybp$B(Fg7HTw!>mX*=c;4;pGaRCF?i>a8m^8PTPHQD%b zS!tlC#6?`;Wzn_fC`XpeXGYU-;H93H8coD{)_0Z*`)R{yQ$msR(NgJJ&2H8;E{e5^ zXbn*ra~&k!?r7p?aF4Z-oxB7x-ex&t-h=&gKTE@DBHWy~stWl+9GG)hhIE< z)Y#fdS}W+)iF%3mDxkvm@f+cM16MT-p9|FL5E@pe_W@G1MniCYQ@|dPV*(D)$PQGY zRqA-K?g}hI6qTE4(be=SN2#T0O1bEo?zqEJYAo%RTIBLP68ntDHY8N>gLli79PmqB zYmDWF1x#FweL7%c=T7Lx<^SZtaSICk8Ug{x{5pX#zB<&QkMp+mChqyO=Tt=5u2a_aW zOKF)*M7Zk#wCs~h&}ek^usX1*hI_6oWwZ&_5{`HzEfL{ZIivLQWKkY06GLYQjeDV% z8%B?SiOQ8Mx|MCw0OLT#bvDYTk?RZfkw{e)5rrA(3QL#>)wjT$uBdGGW)GC2bylToW`@qkN>UDMp-~ zmiL8`4+G240&5SY*PIHqm^@ZaAs#!#WJR^bK7VvYq7;bNs~>xOv1n|?5ZwALERAC5 zN$r$#61GyacO&5fvm{lH)jQo%$Y=hppMjuqaK()vRER5;Ku_&|iODapY%Gl=8 zJo-RJ;v4^P0g5(q`h)GXV9+D9OX3pUhnW^OUdz~smqijZtyEiHwMblZmRpDIga}-? z1mTp2y*6D7f%|6=3k4=i3Tw_D_2L>}fx2t7>tD1NcYlWJEd5*0K!Zs~kx`w$1s6_r zsy8gZ>xS^T)XnaOx-|3ger_$#>7if^uq8@Yt>j9xC70rDwUoGFOD?I&LwQZ`&Dl04 zW}(vvyz1q+xvB7CK^t+L3m1+HPe~kgq0C)1b)aKUP!!1owNRqx<@D6*UmhD3J@Gf?Gh{JX*oFzYJr}{48>)* zVJ7Ja>#!=L zC?A#69XDvK5CW-Z$AvFyuPy~YD1=MFnppBOdd7=VCn$ahnz9%`fe(<# zkPpL!zIy{nk<uc-%$8ZW;xXSi#jD>P5hE0nmx~0|V z0B>EyuAI0Jw6r9t^v)EZ1zD0x zXdkaZ;#;MJ=`Wdpc3q&4=w0MJXL~aw5NwqPYH1-++05QZ^ZQY$o#jRMhMafZAYVhT zV3*H2ezKan@PfBla>#~@)Oz4qPT!drZkXPgfhR*F5if^`(#<#dlZoPWNZC}TMfy*w-74Kt; zYmt9(rd)LR!Yj;^fYB8}Pt zQP0fVLR?Jra@nWNeQ&7n<&wp%slMDnX4C1X;_8i`%{D9rtSi7Ih)%8vo-7=~O=~q| zZRH6p2Gq`^6?tDHxM8LN`5I&}*V*;fQ0I>h{+u7hGJ5vK*5!KC+ts&oWQs& zauCYfP#?=%3O8OuN@ro?<+tkpLL>MG{^P%lpczElOG{xa9`kDOmTJ#jZyR&z*b}C` zQywlhj5aNX!j7w{jaR7BQjKQj0 z)a-cK#g^$c*1O*`J%$PoVQ~UP<&K0PQC9*&41L$64JrSN?9feuKvtF)#M3Pe|M&}E z6M!uzGA~FtPd3q_x(i7Pw7W_knxqF>V5xvPpngXjRNf z;ey4$Rc)2;f*qIsA-SZL>BWVc`w+C1d97D*yFcJ#gPqY6QhdB%?NV4@SfmjnZ6o?i z2BzU>VfavQ#Xt65*4u|$J5D4)zZS!Cb6;L)Aa`08J~s4M<`XWZA+G2W7CnR6wA|}> z4Ozi!ZzDQJ&+GH$u@oOUkH+SrROJB+1csO~Y{(KB_vXMObN57b!QD9ouVpZL^>186 zF|0OZ5hHOgO=4s>&b+u{nU+Im{E6H0+e97OY#ia&3>)F%(nyGC^2We)BPLuAmURdt zx*7v){hSCyl}298B*DeHotz3J%P?UNEY8k$W*nVCM;r` zZS8Fb`GKu!GgwF_eH@a@#xw==xHM?kkcZ(K`@*`PbxrqNypPul9Cv&O2Ir3XIKo`v zwJV2H#WZc=a*6}*?ZoX`G2|^hWh(dWorj=yAs*6w8*#lUJh`6peKd+?_l~4%zCpln z*`#W6M0y_M^_0$E$#HjZ6tBe#al0RL1>Bp~l2mcvhUcb1yySOY*A^U7U+sPF>pOys z%Rp&Rwcka+m7s5ESny^*c^i=2u+l#J76}Bnmqn{1yd0qgxAED*7-16)+SSP)!q+;WvsElg_@{E9Cq`{m%iOp9Le&O1@- zLQ7+aldfYTC7pU1VVswXH@ybV_n;3 z)N`|ePa^e-TD#k;UCX8mQ6k1Bh1C9EC<)tq*(MQ@{c!_F@k(2BUDxCE1{A!>LQ65Lh?b?-=79~%B^^vG&hgyLS;0&5v+M>N|F z`f}Ro@F641Je(D*0b5QF&R79eX}3wgtatudb~RU?4sH+-->TMS5+7cAHxlNmy%4bU zof@c))qCL|Ix4a17FMv)harPU*HAz&FFx9-f2P283XwonB*0Kg4QbY?-04)#@ht2?FhXI&eB3U2BRIAhTCurd9&OY9%@ zAOGh<=etj(FeYPw_EJ9c{XD%8*ApLFEf5xsqb^yD z_=rv4n>1XSR=iMpE|)R(z{|N5w@<;eligk`uly~1LqQ3C8a}l+Rke=Mm&50qBOyQ+ zuG?-eLEP`{3;pba?)(DLRlN%L>V0iouBB`kUh9ZJ@~~g`Z3!54z^M^J%ec-y{V!cVKQfUJAX-`?|Vf z2u$G`i<_U@^^MdG+qDGgotAO`R0KZPSXMUZfW8){H*;o#ug7$k35U#PF6jZb^`Q)`Rs@_p}JKlDwn z3+Rq=eE#?gF1vn`%VZyy$gQo+zWGmCdd}N@@z#c4kB7ICP9*)Wz1)XKh0Dpf*YVEO z+$k7Nlf2Nz?wXA~*r-+7z8MJY;o-WWQTIUJ$b71AMlly52ySyw-1qEp;Nf?#z2Ee6 zzS}=|$K5o;B!qpeAOCY9OfMkFiFsGL{OxG{Fi^vd+#-J+Kl|iv!%`oriY@5B1{%KZ z>{fZHl(3qrPdAg$S6;A? zZ+FmjD#G{ocrg#Vab91#FK?96uXKF}TpSnp(=*|{3cbW2;gaxsdDQO*1?p$J5P7X3 ztw67!u+i}FJscA#+UNSlL(;$Pr0@Y0#>ewQAp^cn1hwSHONsXFM+K74^V&8TJ3o2Z zcpHFzkO#wt;rAFU>YPCq#w9b@r7(KpM z8C7?3b$;$O6yBPUE70-7BR3=>7hAV|!$1FeM8NokLtZ1sSBUMWr&aZWgW=~m(N7?- z?{PZ(;2nSX7Ppmp842PefPRHQZXa)vUw?+we*T5`zp!b!_sbA?!^Cdwlk-*YH9hX` zw?JKZ0xxy#hgiA`TJ&*rcBhQkO#y?>InxhC6ZB4*m4+-WK$Cxcldoj1L5n z_d5so%L3o6;#VLOZ}ZMu;rjzP|HWSURdn};%!c6#ey}qm4D~~u#7_qw?^QZhnA$x= z@%{3375K+W&SI5nB`1FtR+a{VUEMHN>ws^kMb^r{Y!Z9~Gx1|&ye<{q`#9s*F2;)@ z9QC8^i_bUs>+tjw$c^{n2;TvJFNea%2a5atSn=22Y_==LjSqFurJ>LKs?R5KC~nt9 z&QDt-^F-cW>GhR-;^F*i8_RdB_lK3-_q}c&URU}7@S{`lN81YDe2`D~A%3_szQGEw z#qRCydBL+^Jo2wQ6z|Z+k7|gQBND(>2y`W@;Ja0D&o{U&68xYg`F5e;hl~Fc3i(-~ zeFt6M*;=34&atw=$1?N7=e?z;-5nKwcpB{YzKz5AGf};y=3_@c~q=suz>TsZV}71bew(p7+@kfM5RyKb>ZMy!AHF z^NW?l-}le2KIbLjr{9IoN5gHjf**jU_{5jOM_R&n_!qt}kbbG(z=yh#g%6PA z-?eOUyYIf+FFvpS_KL!{HRQKQ;H?>XZQ$@3gTRkZ#urlW$2a%uK+$Vv-2I{9yD{e{ zN8cZus2~33`>YNhyyxEp2DhgFyC&p^|ZGJ>Se?~5Q?XZ8kB);Et_!grY#S>(l23AwS^(p9(PGn|9MMlb=Am-+%s(jv@DM z0Uxp4^;uqJ+&`)oo`2K^^e@zE`0jML5Cng?EUrRR)}O^%@oVIt#oflQ){%eWGyd>Q z!ViAYpJ4;w*KXKv0NC#elV4eEKRdqu)@B0NPVIeo{bwr`;IDnc5AYR!VKM&l3;Oxm zz%Tx=pRW!4O{?KoKHtYUkJtLcON;8qH_DHe6aM@$ z@&o+v(*ysd7lB^{%<$dH{-D(PrR9!)$>EA$e)O-3hEF5(3n1~ba6Zj~*Biyp7YJ@j zr|He`p}=Ns_)O{W2yYBSQG&Y6S6}RQe~wKm7V0{p%MB{?e=b z3IFw5wT9Y&eufV5>zf~c^5y@jKZ{>1uYUAyezrzff7?I!cdW5L{Uh-wE{wnRpSNj0 z`029yH%u4)|NQ4Vcfxn|(l4L-_`!_-&#!NMgW%v_xJaAJRX5h28X**5R*=Wq`kVYko@r|C#3c#~m$({<-l#@QnT)Kkr}s3-I@pH}&uS*7#rW8U6=;DE=3G4gA0Ruz&db@OOX6zZZ%4 zi=PSq0~_bBjL=yB>;J+3vIqYE%=5wj?+@pvEfW5{%jMSwM}O~I`a8ZV{vBWYfBZiC bzXA*ZCyJ{~H}4tQ00000NkvXXu0mjf^QN!L literal 1508000 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

9Q|G<)Pm!53N5sb^@`!1285ZK51oh7k+ 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 z z6R&j|++7c60)bKVjuW&QsOq7Nq}arF1?GqAFTJU8>3 zCQ!N2=3x7x@}9K~ko@U}o#o1aI2~CPm?KJ!3}?l+=7Bo;+?>@a)PNr2LV~RXSf3&#g7^dZe_YiQ6ED64dkq{|TJ`(LKp| z#rM<8Ju@d@ZuEjg>wZqX*T>UeS{|tEUP&ovi3|qv=>}WWM?1k5E$}ZT)?;8rIB@IL zWpdK1yN#Ic$RGH}!^v+VuT#JBlp40k`|vJcJw4Uw-T0q9LrQV1uv|NL$TsS5*yMMF zUEd8-9nckJvZXknc{ZH!p#V*`!=rCt1Zt_DTu!UM^XU&e5CkaXly8onbcrJZ!j z{|YO0DXsilH)%HdO)_#TWC1KwME#`=e-|%!M@)*lNrB!yR+tRpNq^y5Q*Pb}!d@}> z?CE;S^vGMxu@guE@@aoV|IKS}%5f9aYU?G6nTR`ljksP>$vUt>dbW@oV*tBGBkBrC zuLEQFhAIATxXf*%9SU6L%LpJYMiZFnI?0E*=-uoN&<3?1j-lVr%LCuT!z_tlYCGuw zG$-&eP>l`0ZUh4*#Ah?Zlb{jxg__(uAbQ*zt^b6x>XFRprnGmd5!wF@Y#JKMzE9x* zJZ-QO8VYx1hyH_g`Xch5qfKFvYnpUq*eah(<_Y0ghCeDUC!T)?t}@|j_vbpu7(=xw zF1d8(1^(E;l^UDB3M;2$DnHg=HkMuzPzQDiwl!sOg0_JO6D z*0qqen9_0CYmAVPbJ$VGg5J_G zFnC&yfV!PhmPo82=?xjG(6st~{yUC2IyayZ`pSMiyZjc~;f+!p79)1)qI6Q+slx>w zQKK_BQyNRDO9V;mh>~gZO+m`rsK5a(jNx^#7?zV(Ef@`MgCv!G(vUq*`nvB%kG-b6 z{_YPuNi`C6bp(}cA4@mh#*q(Qkbi5)={tJS^9cBWNrTJUA3wb0tnziEyp*9auhK(@ z??ysdv{68`=-$uLVXWO=X9lH{gkJMW!d#|JiLJU$02OS+Y2cnW{WP!{$|tG=os^-2 zhY8m(f}YB}=ErA^WTn*_SSjNY{!q?LiXqu*34=>mgru7hYcVsm_~6md&gJJ3M*HZs z&-s;^g}3-cR>Thhf;W=Ell%t4Rrw>?@;e|avU!v$aBN^6PO|jlHMs?GPxLR>ALPWe z<8z67L4UK!qPhgee2b^l*oK_>T3!jE$IIKEubNv<8EE6J_PLLmX}Jt8wFvEO>dT)W zhXpBe4_7M~d9Bn#>C zv|VBG#=tKH;=Eh=EbYzj%X@nH5{4c2>TXX&=E^)17PLNt>V%yC(+5tcN5BJiPXP{& zjSc87gbM%p>i$QCi_U?Mn}f_jSAMZr0N8gVfZ>q6WnGX#sOOK-AFSxywXt?xeN8*o zbR_CMI^y_yv}k|HvvvNJoB-bErQhT!c~tG^@%>iX40DHsgW!Si2ep)s@!z9K*G|?Q z+T2|$O>D&Iym?5@+m+zGUOWAEjOE<fwig;JFe-@L z0k}{zZ@#0nu5F~9qmo!c=W6WPHKEGDU@sNFUP|&X^}^LDY&RtqleW&>|GW!!3OAH8 z>jw&HJEUPWGM=ek}i2hYx?# zdhOA*RAPtQqRgtc*u*aWGfBn6{mWQxHS9B=5&j_V&CBaUDCzHj4x;&?j+Xa1LHvz- zwEaNMa9GG}DvQkCxgC-hv0@)Y4SV(n#YmW=meM>Ij_FoEEVp-yv$>)A#3M4ri)1cx z8hiXE!+wUt49|jhU=`4zpbR#TVU!07S6oL(KWp3P4lzR_70(a2`?A_kVeIeLxtQX& z$80Tcb?Mf4gSkWr>5_P(5?8FBEwpby5_i8#!xAQA9}(@rtH6x2rOdf&d6RIlz32Eh zGUgx%N7g@0x|o6r?jltTw@e0~#C%^rgdH#%{Vjy)dAk-fLjIk8!FVq}g`0`k^Xm#T zq*(tD?HaTbbkHoC!4>ZgUO5B8tzq0ORl0I;NE6U|eqkV>2^{a6t)ehp3keI%w0K21 z{%!QS#XBJwOoEhK6bxbNmQ7w?~Oz z&_6(Hw#8q6wqYD$Y@W0tK?7L`J`>w$78trcS}2%wXG=t}7h2|F#Rc8F<*!*&{ksT) z!;g2IvRpj(*Su8B>VeRyT*dHP;K5nZxp&6A$-%3+3txG&)*UrCXPZtx*ZQ#WOXqN7 zO4>ivI3fZSFyKhyz`{n7);21k6a~Ia^Qjj4Xm4t*s3W0l*y{A{>hkF+tRxcS!nYgO+3L_w`NpEG zDA7rllijRT~cZ~8wL}`Y`m@D(t!!ivhIBSI93)1)Y)vd7LdOjYN7Fg75f-}V}VvG`dEV>=rbH6bT_ z_&1BgEh+<}YVmlM_if%+$2YITsdSBZz)U~fBYjxCL~ShYX2Zzqt7_TEPRB^5kZ9b{ z&~kCY6P@9G%lqM?|HWNu)lmlZfiFUSbe(dZEOItHlIFm*Keu*U&@jk?m}4h5U@I_F=_(01@|@{8&izecevIi8)Y_b_eh!kT-2rndCF z*ZF4xxo->8e!ZC;AG?U{LXdw*%q-xqc3o*5EiOtlZJLx8FTtM{Yiir|vnP{i5s>&< zFFhqOXO(%6W6;yuV@bNgdn)k_@&0e%1nolKNSRs$e~IxbbOS(W_TM}7yt%)_aO&#! z2f(3vt0)TJ2?r0ZIH^pw-;h!KSlS;wZSFK?SPUK;{s@l(G(Ll-imnun@tfIWyGODYc0L>JyqJ_oQ@hkE_sXTX8bxserKaci256`RuQ|iVJaz9PC}iV)>yD z(I@uKV)0Woy7S>nZhPYeWR1x4m5kl*YTko;-G<(yMw@d=abo}u$F8n(8o@B0$MCPi z1nTvb(HZ4|NWBj7Fx>d27rCb)?-P95BU9cnBMjJ)cjnZ1`&|j2!f0~fRjgY|@g)X4 zi@Ss|Le>DODyH;N{J{VOCWm!Tvb*X_M-&>JxB44avX!3JDYAo;;2#q;d}WEetqE}>IG7mY{LMuDv#-++7D59tbX-iN~u)2Y3w z_#>bMly=24N5~Q0ET`XZtDQUrs%`I`L^KNb)5Vq}wS=B-@trz}no8|Pv``jlNYLs% z6S))YHg$oZM6?MLnrk}F_Pd}D z+l?Vjc($+Oj-0NA1ev@$UZ;N7W;5yhm_fa)$k&LipOizE5`R zLWE=fN|N3Ew(6`yklQfUMgG#HOw!{ADZ*4W^z{ejagft`5^(d2EP=)0M6PV{VHH-@N&cZr4gmcj?@= z{kD^-mM;87s9R;G6x&UY1q} zRKUyGV?AwINQY)c)w>Q^ang1ckE=1q+VDfvRiy-l%!FTA7`E5xmDK|%3#^YNi{RDH z-*l7R+Gtf>w+42$v+%GG1?d*9W_@;pT2+9YUG9HoE`~)?D3Bs$ah2B%%`L8})ddMH z{~L@_=Oq7kdjNqu{;$-<0y1Yv3Q$xDMaSN)?2(&{+NSpocOvm&1{&#BXLD^+vuaCa zeBfc+^29CwGtb_X43pt=p|ZzR;|=-9B@9Zcgoj0niNit4$7UM1Re-FQda;^NNY_Aq z+n`EA3S>DJSZ(~`dEJ>uyWwz(B)9gV7kUsqjPecTH>fdN41!}@y7*e zhdgZ%oQ|)Za~f_GigAU{nlUr5>Xvpe-^044U$XvEMesW#Y1An*=sf-?WA#14WRu7_`L`)7>|mV3|f19U&aJ0NW82*pwu}@@OE-^RJYXRAFMjtQ;6e=$KxyH zPBFIl)Sp~!T9=;pa@5BvaBx>#^sZjIkf|ALZxj?1s}lQwYZX)87;?w)u%B1a{zueY zSm9&?MaY*5!wyr-cNk11kNUPyCae#j(s^k*7p8=@yxeJlA=fm$;;Svrqzse#&mISr z0XB>1>gnUIgr?FyTI|TDJi@EM+QEdRp2Z$DzK_Tv}v>n2m^lwI}?mN%as4 za*Vmjh#|0l1p0vnUJ^5)jdJLO`YUkf&dAnjs6#*JOjp#$@=nB?JLNO9H&W-;!-ea&w&@H&?H#j`{v3;DUUEYtOE^?sQm}@-J5#xG ztKVGhD$w&NTB}|(S8jiBEY^r$Yxh3Dr7|LVJ7EcQVv2u~R$xUmXlrmH6GU!sqB~Ay ziK({>GO*>k8Kl(BGr#sl0?HRJb}DTh~7po8V)OeCsj2%f`U#zYhVNtQ_HEYxaFrITjUB-}oA z7$u#rfU2DPl!5cZqjZ>^|G3i0ohC$o3HT+xU*$3*L=>i!mR-4pslT5yqrW`N)4u@A zO$xxjNa65F`z&84U@ti7iIBG{D%R*L)_M>Z@ZkB!bRD9`mOw zZ0^wJMfT>6OCrQ|)XF}*tB7UYd)fJxt8LV6#J{NcZKG7{4I9*{8ON1k}`Jv2cr(>AG@v%Nbu*Jh8$1uLH@?-g7 z46FVi*CzxL7lBQkw8JE-2tEx?JZSgDyn$d42m@5UWTg$3Bktg_Uj|J9CJ*ONIm(VH z4x)W7SPM4h=l^F_n9Z)4B&^hOXgsPE4whA@+7*# zH`+w-B0rq?dDr;Ol?-%Y(+#W(JH|xt7-Wq-2DLY*%n#^jBgT_ZnhH)z2( ziOZPhg1U9d*7@pTz^mSYPr$`_6+2%oH(ZFBd{5_FcG`xv8#J=Y4wBvMQ}8Qcd0Dm4 z)kG~$(WU9Na*F zGQ4ynKQ6@Ek2HU@)XADj2bwlCHt8?Wicd6tyzCL{lBJRkC`A*GX-7Gt9{A{%SO?@> znkw|^E+cySEdDk$xU$AV@s3^RFgea&d$E?FP(IOj**htI5RQhWw01ojiPz@M3CS<6 z1^s>KAc?cM2<3IKpB;bh_Swd+>#a6)8c1K z{gNj&8+B7CdAp7WWBH-z=3fc!UxoA}jzrx%CpxwzhcXI#DZMarMSWkFCqrAm_L(n* zBz8wZ`Om&B;}%`Bd8~lJ;=aO#GiE&ByN8@Vw7wlK;g*iZ+{_hEKwO(?>{MYtkckVp z+Xz_cBx|$I_>mwBD$lM%>O|j1jw)l)IeXS%=`*f7?KYK1MVvcV`7{<#*?P5jccE&L zqkuw?f$@|fOMFgU&%;*Y+hbES(_P*u{v==e1eh}%HLBe{2%SG%e%30@bNtoa%VVa> z=GKz+Y7E>`EGzl`8h1hcu_-ZT2$3Kt=;`(=&rszWPbFVf!8kB){qg;g<$#w}+7#_| z#J3^pAW;*#Qi^f{FH_wUbzH8+a=PhBnil5uAsJfTgdt3LEHvliQROx^xQpTAMwq&? z{jVqsy(ePPm!7w8dBZ4h>bJ3*z#0=ZfgP0e!^YE%>yke)`K2 zN#IzZ%^2>-ybBkluwq8wj9wkG@qp4QKjA&`=Pt^w#xl5o3uku(DkJ_YHCw6=wr%m} ziv2RN9vR38UP!y9U}aLF$faE(3tI>8FRt;t{a@r@wHUdG&|)oyPW)SPR$g2@Oqr$$;U4kTR}tm1kYfjBgp!Uz$BRv> zmMBRA*5J-H;c&?zulsQa)sXC z;B5Y5Sn+l+cL7Z{2h!n7NFHe)#JxcwWf0fYX3{2VYy(<;G)anr>vc--R2w>;Jf8BOvG!c%6@DLBK; z318;Fj{mh>(kI@0*G=Ou<$mgDjYyEWU=zy?IYUE^fyr4Vt+$tl{Wl3lrb zID13ZMdwK#3}8p7KfpNx;49_urt8C+_eoK8EiA+j0Q)uKK*YjoJ`VFlhz4DRu!_D( z?P~5ivX}nJw4V8+}`I#uZDm47L z4!0hxVOf(B?Ud$LxuZJ+FYr*%^=;*?z3@o*gI{{w=?bij&y^YjSi-t@zs&y#MVr|g zDF&5XtQtj6Leg5ui{5*Fsg#o;bJzH+Sd82Dl6aDXnPBW+@&K5odDMG+RTGJ_uo0JT zAHp@8)H8;m4Sz?`#@&nzK`EHPER6f-Tj*K!m=c#GHN@xW@!)lMh~__CG%_ z9qM{8ZiV?`-~USITDRrl=cr=ke@fBH&k_%EVz)U3rOw|KL>hhG zv|@$BNxEX!&WAyXpUwvbDsg{_p?exMZO^3t)9 zfFrdh5>Bq#L+dfu0?r8~fZNx2X`NI0=<6|5chP0P!60PY z<*H?7*J7w4iL@JweKqYf-^6fVQ%p}f2U|!+EwxaP2qtw zGQ59-7v0{!5sI3Ne%=NM*8c2LJU?QF2%)ghNOiZ)eSvmvxY3f^mt-As)GLx<#;o>x zY2c-IIvZeBYv5`^Zf!;b_}nlJy;EHcO;?IX*p20t@8B{++AEol>3TwPqtmyzw+ z1`fC;h@1ijq4cz;_z}3h%|(m%7^-JU^rQ|WFm1=RRY!68{RhZvUp=8CHG*;npBZ^K ztweTR%~8s?fGH>$=99|x{L}ZYW2o&Z@qn8P<-_M36My@c^CJxgp-WHW`nzAFBE0e| zoxYTHiHS^_AJ_{6wF(%CN=Y5Qhj_yQzb68DlO-4Rmq2P~=YzwSZ$Un*)SGx>#Dkl3 z1SZviO~~)VQM?H5w&sfU&!GUc!CVByBLobUPu`7z%%H2)pe@8aMM%bWp>hRl#f2L0 z3wVsC&2YVyhW-BgUK!ZoPAc&(os24xZ=`gFD~OK56aprS8lQz$f>gVT`OH zl{K-P^eh-|T|$36|W^uFNox=T9Qgcww9 zf%@LJoq5?LM{q%$&>)J)OI6TY>vZ#42=+x!0e83zyjXs0f91r}TU($)z)!r$VAr^N+Y#C+ zk!L-w%1c=h?I%8uN@&NeeSeHsm%gjhHes>*m5-|)4DCocS9|e`qHa3Qzwwbdvu4|# zFOfrAmuSChv^xH-5c(sf``Iz$QL6UEA&)Sv(Y*AKvA#IBM==ncLEy;q6#PB0uil?N zx~RJMl)7-g@uDZEFI`!i#k;j+HiU&cQ}hD+F*_a4hH2Vt(wz|O(M38$jbpbIucI9< zN2fb^D4`z4?6lWntO8~w@-(xWB0rJ?lgusXBj(M7Hgbjgr)BHZgA!}HQhCEMPo_2~PiB`TVKQH5+w?a%AlJV`qc3*Q_iQdm=;uJ)Y*> z6~-Ji2bN6r@%f)lxWYhA8T{S5&;jJdmcYrLvN>bQlr#0t zEBf*)4hnX%$ww!W_SEt0m9nPs>=tF4aOv{X+ML@AGxz#E=)8qSuO5y?SE1gKt8TwZ zTL;K%AYo|nk!9va`~5s>@N6soN;f{@!*a&WoRMQAdBYznw&2$9p$Edm_AZ>_umj9PxZO)UpQeDo_wxGb@TbzMkn> zU+iZD3xvR$DxePA#V5B!ri^Bnn|0a_3_FND!7^rkKR5!PFwY; z_m+h^-*~nV+aj4O_dPkVf$X~;4U74c=qUn}9~9AnV6duoPSa_PzuH7ep;$kXsYRjvnP&($L$&+mU5v6?wf zH2jCwR=|Gi^p!_aGz^VYJ7PKH;b)M}oEYh{GQ9x~dHL2rk478~Y+YtM@_R@WZpQQ} zeCBwLP}DYC5429Y79?MCU&xhvNc|y|m^S}|0T_Q0I8S}tYCP#5;7;lNb zKs(NT;^wwST8lG6P9Noo-JyQw2|H{S*3PbcZSjX@a;k$b`ZS^1o9F06bTJcO9DgJ- z)|+C0UV|5KUfu6MN06H$Ed#_aCC3)Zdj2M5rBB_X3KGe}Jcx-GW>Z*{-&8CZiC+)* zxr(&FxjLjcXC4?T#UEFugcx%iaQgPvj>}hnyF;rZMa{Vl;es9e6zBXd-0PE{aOza= znYhc`viq79Vl@8YT4S63MZpigTxb#1FZ0Br26~`d09W?#%-dnXqj7G36u6LepW2R#yepN@;HbZ-~NoZg~|A z^tGd7L=)PgimPABfECE;_Ap45PI+rujr<}BTkhWasqkh@mpNTk$aH15Ngx~wqv69; zFXw~FsR`-(9#<1K9QFLNT4H;m+=Ro&@OpBSy-EFii?> zfGQtJT7!wt0UM{?YkLfx)?C8g=n-AxTPOfu|IoCXqPfr!`^?q(PUKaco3}%oHtEH{ z2QzGg-Jo_+@Q`<^4tux0{8lxYd&F3Zu@v7yX=1IO*m#9H1UBrj-9U}T{>cA?35Bvy zX&XGnaUBW_6W0JcD%bxbX{A4y{2Oaa{lA5^?LWpJQinMi|CxEP8P5h5{@R2}j{kKA zCk#Z+h+l>K4~VgxJp8d1rK07|qM19fjatWf9*l`z+$kO-br1$D#fGut(;BPyGMhY& zSH~{ul}y7+CMX-}Ig}&HMM3|wx>sE=?Y{@zc2V9SHKAJLc69-HJ>K26pH2CaQ>`hg zXd$MdoV2F(dSi(0HsVZXao|_t;MYi^hKfFHxJapYgfsw*;hisV>ejRKPBU_d{Azfb zyDj170`ci{8@7dcVJ`M7km`Y|w*P7j^B)eCCP_mfn8HayBa!@Fu z^XIYadKb@b!-^zm3(51MlJMV3ddcs9eKZXQP!yqj;H0;>8+Hl4`6I1nwbV3RjrEc} zXrpRWKCpVL5?9v~{bmyLFXq=Qj6m@;vRYMyLViQ`YOoy!HTyK~+EwFU-!lK~Hk#Y4 zYXK9ZjK_efPV_Ep#+|2DYjd9LH;e?_ceCuA4(U!UaWk(}E9i`Pdcof}6=9V2h$PaJ zM1+n-?I6mca?@^vFQ2haq}Byxn$dP$9x za$~r25aHHr2Heo~x|O+JJUBZAgZvl1!DcRh?+4+nWap1((WgE?f(~?3rDq$3nhWnU zW`wJkxK+)cKxYj0YfclC>kkR#b{X1y9zp&Wa<_&uPDh%_`ACnV(WX|;xPlc<2%3so zT;Ou8W5CHG!W8W*_RW*DE~_yF68)@*&Ss|F3v8@<+V_^bO-;c+sV~QAHxL(y$VTlp z)w&&W5plX`S6O$KQ$8%GSp+v7z5!di@-?2OU!~IRfDgBB;(-gInU?P>jG~YEt<1&- zRVGknf&!zKmXnJTs(`Sz?7Y46>fi7vxYCPpNUxF7s&w>S${6Byh-Fy@xL4G2!@Z5- zX|!_c5ghD@qqLLv-z}|h27T5>7KvlTbp;&{fN`3epm!XngVq*S`Y-PPCJO}Wst@dd zhlO55>id2k;r+;pmCfW!^6jYAdt|jwOK<~du0Lt>m}-KM2hrz6@kpY;Be3?j-R-HL zy@6HM%GkLHxb-n`L7lSlq0_THo0L>scjQRge^~xn7@y^L{PNA#Y)(zNgjx4SPIQ(r zLvrv5)T^Hb%U|OFxg(xd;m7tt(YK|%PN6^#!Y(WCi{Neb8$;^(ADE>Dm#f@&q^Pqa z6vkpj4;IAG&EeD4P_aoZ3$hFF916N zw}BoLq9PJ^+cg6EV!)3>(fr81JxfD&gLgJ5URV$3J2S%=v0UBcJ z-VN*>g6Ax*;7fQ{o~%T~bidF01`WV&W%U;KwG!s;i~q!b&))U^puAneT;FPQ2cDie zTWwi?uXMi=i&2N*4fqVgHEnX&2lP%Z_GJqXqvzGX3f~tveGMhS+-8P&1@iIAlO>>3 zOzguQR-WzD5gDypXg$Z*fr><*R6HtyxU{Qv+`98L%tOcrzuFE2et7Lmn9Y^$cLqDS zn{MUVyf7`Q#%uGKQ(ySk+jehPAk&@pL9K<4fRnSqgXGBDxh%?Qs!GTK<;*taafG5) zMa9T%J!y|GXNJ$trU|1C+6AM+!zAPp$=UZhe|U7oTrz88Z)ExwMYb3EKEtJ%hfmd-{6cApoTJ~cAnfa& zc(z8$aW4V)UbUmHCYl7_l#@}deZ1FMDT&p$Jq$8qsQb5i@$M_fq#SykXMxTW={xwE z8yncpjMuQkKP2T9U{d%iP&cs$f4X5x+E`RD66!*N43K^+uU30y<*#zVrv=!bLCF4E zpAG}eoI%+*s%%s~XxDb-_Soz94LZtNI@j+~w+Q}&UKtgepdr2y>VKkxyrVa&U?X)l zc1!sRP*2XM0y)Gf~qz8S}fIIpfOSPh#R)=g14 zaQhJsC*;ijr|qxDnhKTE{}f{1JG_>R5>O6bBLmw|H>=hVpuOMx-t^clffv7Ve7{~pPn z(5|^G>=o*CxJlrMUhv34JRaSy6{%XBR<56G*^6yRHDOWqzw)-TtLW2E)BTWmGazi{ zM{Or#o$tg)2gWk*&`khIJyblypWOuq8n?-% z9xuNhbrd)kx(w5j@%+8EK*CroaEVI#5px@TpI`GGFDn%`9KPGyS)%eWRpD;XM!cdS ztcR@+vb!~)&9o|a__F%NTz`cloXvDU?6U3(rIW_mYGOHc(ub~g4RtB%bT~@f-`(ECLt#=Yi6{>{zF}{A9 zK>kxDEdBNS-nV$oC7M82cF-B;OctK;4mFW^UR}>YEdp~ec9>5Ugxe2vjdDE2p}MQ#G(-wMb>@N zyW3tyfV;|51@WVS?>2VSu@Oj)*lY#NthvMaqu+BegXgb+EGi}W=Gf^5!5{45C1oQB z_p(Bg?+5S!8@Jc94nJ0t$15k#80#8b(0gwM%ud{&oH-9i-lp@J0%q#M>Y~}C$im>z zd2wdi1dj{uPAorA=Cf{f$+894#F}4Qg;#vI91PydHil5u{NdQZ zLHM=S1JC)$D=Gq{Wgx%BZa-L;oO9YiaM8VTv6CJg>+-Yh~3b=Ldo$1Vi`qsM95f){!h z`OCp})pJzQ7050lnsZ|`^|(;8aiylQUnTM%lepC1NnGIR^^!BDw(#K+-51J}-~VIF z{ezSC^Y)LWLnq`1n%0FQ4?~+Vg(voZR_~12&vP7*UfO~-hiwoAsi~5A=UXUSZK47e z-XPy+NR_PCqTcjg=}A$1roTcjuzKB?%&Qa9uatn(SI(<*9qnf~i&D6Cg5=i&r%yFp z$yL)?I%_qTI{>4^5%+W)L|FpkjaX;!wqdTIqu1mODjL#4Nuw)L)us(*pS?|W^U!^A zO-mG6ysVlsjKBseTed6-Y0fn`cXnls)Tz8eq#szM%$L{O%aX5js$q;yEYTNkV;5P!2!aco8y_&yknr~Rst!a$ zS|C{YH(6Je^=dpX8d#9Rh?3Oe6KQ#NVzf z-mfb(9n*99htRng(n?i!K~x3sw(??Sj$ikf+*}-SDNfMZiuadfGS*KX-&G+sLpg>F zdfaqo=Apl4B=o)TWi;-D(pTXhny&kx;o=nG_|pwr4{#lq=`~Arjxzp%FSY|rvhaJY zNVyG7&oV$I6_#=A!Wkap&qS{6q$z0OkGH_V4jIZAbr?`|g$@^(flt7sToN7IfkO?P z&PX^MaR++Pm2Uz*`%+DZdy7n`GI=e6otMS$RLoDk97QNy)?Dqe(v7ZZXfL`%du%ngi;Vb!Hpp<$)F7!4#o8Qk+Q2e{>>mJzT3H~Vo#bxY2N zF?Bue!~+>=cIp1FI(g%?OX&U9`)Y3lQHNeiTeWorX2D-8L=s?UEf-qd_Zk%|6&|ke zl9-HYOg@7#t8ogO-Ho)tv2q1t@x9^oNUjv~0jb`p`OJaLID9iws3QohHY6N+3VZ|h zgBeH$Q4(jNTMZfRe9e^hy3eE?N-omzZ*_dbq`$~m7z~C@u{IrLkD z^0efG0hLfX+S-h@I)c+|{a8BD3MXmhngO(U_O<2?2U*`7%sSs*xn_k8_T42Of&V0| zjA^acR5-r^^!GG7qFADA*_Wfl@VQV|d8PCjkbEb0zg>2f&wZn^(qY;j6r<>4p^^)8 zf_)Y!c?Ed$k?$KL6~HOBpyZ`D9PYy=&7Xx=H1Kmqex((_oLbnDI=^(mvH-#XAXU^@rw)Ai>w|9Js$bWL{i4nSQ8Q&hp=??g6Fsy) zZ=;W-@3&~(C0i6_zM} zR}(vSeQuMx$%AFegP->TzWlFuDTXeWjc~8N+TIPNNQy?soil+4q;&8+Zu9fk6dbIS0 z!v<*Ur{XhERJZ95w#z`7Y_{%)%)Km}^s7&0c+=f5uCW46Rt}F?yU|kZ90^x3-z3%V zT|HkqP5Yix+|s5O^?z~Nm9dN-P9LwfzlL1}T8z|fXbBt8j?bCITfI!#~W zO$*#D+s;BU($8Zudxx#8&v(sz52ZV0tdwAYvWRzhQ-SM&1>E4rYdbCDvsLLkh0k`y>t8 z1gFw0*&z;;98~v$h)NvArj#{yX*Uq!u};o#>rjZe2qWV+3V{1GmaEl^G_OBvmML_t zIj=Cb!O;CM{%yE@$Y6wKLixHZc5*oVTK5uWbtB7L1~x9n&wQ9@5Eh9lyCeab5WdU#>Wlu74DY z@%##BjOMZg;X_kaoDgEzME$Ll+ImVDBD$HzIPPM9KxL%uB{o?$M3H zpZ^h8KeWaFrK5S`)%3&yTe_NoCY*}P5@hmC*IntXB4|5Vp2J*O(p-ycb$UD;oF(!w z=8En~J;VHaR@sUFq*eCOf7&W*8Z`F_kSDUY3g_E6X}qVp5@T(wT-m{t8Je{?-bDN` z3;U5&<1|)3;*_UsFScrb@@MMYPb__F!IGX;kXr1uc3zlLW;$@d$bH8X$l)6q7>R80 zOMj6tKnsSLGT}S?`NK26UR!sm!YmvZ50B5pQ#2Osw}Ef){lA%Ps;nidslvo?|BeML zYem`4Z-m;fKOB#}5^h;@ByyuPePLfCLZa6ECbCV1{3j*51GM-TNS68)xj0DWT(kWU zA}H_`raHv@;I$)zWV(^b-JBmX%I-)l_Mn*k5$>eC+iXWK%Cy)acgt<>2EFr(_hA!n z#imKen!cQeHwXB7Xy-PCJw00zt}^%*h3yiiCFQ`HI}P0L z6a`2L+7#7?E;*H#0E1L&f3^W)wxLh_kJ)7p^M-wYx62m)vdikUOr$TOtmW_GZu_1I z^n|CGTrLJwd`PyOe-Yc_I9Bcd;+7Q`59M;VHBJOl(^`>l0abV>R*x<1&UJcAy3c0L z6WuLnA3Z)UqHN*F%yejW@MHan==fCeLRU5_Qkjix%5wT{y|778Anu$^qd(T>Q^{xfl^>u@eJjMi+;0Mf6yjz%;4M|8 zvKYSrM!JH^WYIF;E0XT~m6P?Uqr7rgfpYE|p} z>l}`bWGy;P_8&GGl(yK3fZW63aMvbuH7F!Mtam&$kIB*FVNqrR)U4sGR?(!!y zy>6Sj5~4tFZK+GC*W77MmDN>^i=@+nL^VIfv#C0v`)$#dSFWWoJ)Kjha;{aGXg}Ym z>h(IVp$27avjfwX9HKz!A$Cjq*+E4$7A_HGgZR1nX_f^JW>{)&#gg}kBIyN&dZqf4 zTZW16#92(ZdHeXCj6y%rmMin8_b1#A3WIi=2n=?+OG$HbiX}F37yQ5?%yJmm-lc{ zf+uB*$ozS6!Z3bZ+Bi7)`3pNhNNgq7U_UUXPJoAT@8GTYN6c<<5JmqZT;ArDMAE8r z(gWX@&X$wh($(vIgyB2CDehEnoOZvQr-ZMk0Yr}hg*vFKz*^3;%e2^1nb}k9rPrS6 zkhjV2Do^`6D}j#yYiaWq$*2kB7WKv-QvU6_e+z;6aOkRKLo=d*5G=P}U9kGEz-*=EF9xvz7RZmp z25`LtIBA#(rB%#@P9%wQTg4cA>E?DxW@_xH(6Ze~4gYW0SvNLC+kn6(j}CTx0hR+{#s1^o%Us4uqB-?jX)88?n(5ur z*A5k_v4Vp7V|8Y<)*nRsI!BU@ba%;;r5CQwPh`OUSr4e6L*TDmsn9z>ocFG2&n{qV{(ex=+4;@s2>i+r^h z&Iu^nv2iIE+1K4ng+y077lBTl+(=LC`ty@r7jPPo7;Lx-ez$4~ReY?e`>_()Fl9}2 z#{+xqQ{o11SABj4^-@Z~JAbNaNx9W|(%;jFRB}k#G=8|UprZ&`z~peB(6KjfWVYCj z!)A)-%#%1TW+rJ5|H-00HeP)F0?X>PrDwc}W7TTJbvspXqz+yf`l9&e5Ik zHI}yvFW`2bwBUr~uj843yOzU`o7vg4odd^kRXf8}vQaKsYj`d>^d(JemOdR-96|)z zdj%gLKA&sJJuEA~iO3~Xq|Q5n(CMSpI(ucJ{4e0z-i!qt9fuYtHsOS14o9)KR-C47$N2o*!||$jc??aZXN0_be39;o{_# z1zv^Oylu?bWwz$GTp3YXB;Jug@y!&Jn5))v25rL(e;KgAs~PgD{>dsdJOzdjB6;Ww z5=7uPh5Qwqb?E(Bk4$fP>|MrX(ZEbV;HjO>nHy zwI(8}&K+$jmAMcr`dCk1a|bRaoWW$@LmZ2jblq+$I`8Es8xe2aMqjnyxP=?SoB#tp z^kMjEUnzlfwbgf9PuKU`uw(t#W9}({_p-j|B{~+Vb4&rGZ%ASRJSh2b>X4_ z{x5}%Zx&>`e8KgUH>IN23bj?#Ew`Kwsxc)tUB6_E8#|8%aVGwsMhIL&hSbE5)yA&Y zlhZP2-v9wh0on^W(g8DESSl^(&(Zrh!cq#}+&=Af;=ayw0*l3+yqN~#4h|44G|Hf? zP&vQ$+h+#Ao7n-q#SX}gT-LqYuIZ8VQn)&N@#=~AoWMN5yF)_4^`l-yLWlGlz-XI$ zwQcDDvVsAgQYbOo93ngbj9PJD(~+KG;iKe9v9TRCQRn#o`53LoknN0cm@=0JmC{%} zpu%rAg3ezrtc2BMVJ}tC=^fC63+$o>@E4iMsekr2mR_s0YdydFP2o-6OY-TCO6{@9 zkVlGh*0wV8khA*ULV4wB`KQ%KfW9pPPQITlmAiGCAL%D0SPRz5_^{82iiKhC+-VQ` zPb(^@(f$C!hHz@diYCQjDlfEKJL%-hw`cfNVMjDDl)^U>@v`7=^wut1&)UY!!k1Fv zWKZ87VOO%Tbvrlr=1BCN(~1xZJ<_~O6#gkQZPqxlCyqpJ8QIF0Dz1A(VbYed%eT#& zP0>C}K7xbUFm)*$?@DlcJSM;;eAx?(G;cvC8yefv#-v+Kbj-2|d>wHQr%7D=4GA~N zV%rF8%7|P|bip^u*a`byychC3T5sohTxX~c2Hj=T7waK<3`eI-v9jOO%-pt)Vvnoi z5S@Zu=Rt|#xcbyxjp0jo^9Z+R95KC=H+su~la#fU*sSf{UzIt;I~9>~OtMBo6DOEj#q z4_qRdN1{Xgmz}a2xPR($gEn;nbTk$(NW#TL@UM#lMG2@nwJ547273w=+@r zsaZ}C?%qumPkqTIO@6$5O9h*PdM^|nl4+a|DERq|Pmsm)9{}?USpHz{!U**HsX1Bs z^LRB4!Id#qV1z;Q5Le#cZTae?6Zu;w=es8?nMh^Rw^;J)RcBW6OD9iUpVZiY-e#JbQ zB!A9P`B6aGnLY*Xjr<5FP*Z=#|B(?#1K4mBfmxex#iyPL;(5f*50k5?jiN1Uqg2## z@k#JP%{P3{NHoOtd-NSsfel&p;Q^rre?;`?=D-cf3vei49dMnVd-d=eEJ6WNMRs1} zXR@%b?mxT$-nO2%WaswGN+n1y!0i>Etqs83r_ft%C19C?%>*@lI<%Fdvn4U!H7mcy z0%3T6rE^sCzqC$u38EXYqE zj%B%7zg6#hD}bG}&G$V{g13?~PP=dtPdpT-yK+(n@vfrP67@cxfV@y_`SH>La=>Bx zdr>0iYr~ds`vDB(+JC+_qSCIp7h0wvQLO|t%PA=(%KO_w$EuC9oTAWA7IYFk9Ski% z-JW)#7MMp$ywu3MY)42`|HSh}w{V(>8nc2B5?5?6&5vbatDXZJq05GqWab%Mm>D3+ zJK7fcg)D?K)H!D_JSJ(0oWwOy(Vl<=HLvb{6%;l=+_&!>YE3HK<7&zB z<@>6&^j+C{u{C8pY^$2YXBjifN^Nwo`;{Z#Otk+)&Z<@&(p#rM-d@kovgk#RH)B=x))jJ)ZZlAy1SC(%M9~M7R*@Q-hUZ zl6&cZe%Lwj2c(4UfpVbz-sM&4`64GMCa_+linM~&RxMXQ)IrOOm8r8*xQQfEV$)~F zO>1UNbduV{{|dr3J1}2BW8%o-;zndTfg7@*!@=5%5Xo4LVxMHV9p@rU>@o4P>*O(S zkrG8~z=r>|UfW&2ytY(>Tby75=AC7Kj;lIOo3GwnxE;E5CUj0Wqo>DUq zE%WJb0}RmD`)>|WSc`i8R%BRGIGarq6=1k%8dNv~p7`xL;IsbMVrr}CYp$p^T-;9B zppIUtGVs{fQju}k%kYceTv_x+I0is}B#D3>HxDsO2%6mHaUwsyKQ%{%zU z4`w8F5ggI3F=j~>JoUHapDK9zvV$dmJ#lSLf*@1t$2uUos&EM3VtS<(w|n#D^$#X4 zt)vc<6Hk_OSgkTM2uf&uSGU(|Tgo~-X}q%W`YRL=R$-)~|K?HZv`_05M^NJVri`AwBON#^M5xb zd%rK>y1z&VdW?ipb7O*E4ZjZkL(@oOtu0R?G%P|}&O&0J)lzfusdn`1{kqI{f#bj; z)YMbK$@UbFd$ZpFH>LLW;??yO>8(Xs#wu}8ZIOgQsvJ~U5S3-H7b=oJz>>GN;`R6J zzpNM8Bro_b!!-fF{PAuWKjDPwmw~D!hvLHvs*!B28~@;@srA6MkiT=@*3{q^-n0L) z@%92*Pv<30+y(nM9;t3uzYiX{#iq9d7f3D7s>DyMA!qCwsPJ~6EllNpEKttIFkYS% z)wspnHChK8l#$IAt1|UAt_okHI}y!O!*+2x!jee9ZN)=y!vio@sSPxe6<`P$jhyQ2 z8UkkF+hXi>y~m4o=><8%MYZrF+baC|qFqUQo=xPk&hszt8LjA#OXhP%LWnm@W{IiH zM_RLr+k*^!1CmJ#@|VP&J(@$uaI&+_t>6R1QOWIgkVKuyk;pyz6AZTGi_auQ4Rfq4 z+OQ?}UzN8XJ7wNr_W}+(FR~dZlNa-n(2If6QNT2JwNBleuGfB|D`#{2)t-_sWSf6r z=>@{_v?Q35Tte6Y>RHWif>!Vh-7V?wFHS{(<%i@HZR}zr_n{PzVwM7Lani$AeAr{U zH(9H?^&d_d#=7nrJ-3&fOiDAjo|GUZ@Fad1#;Zojq_p1NLh`HWAa4?p{b7M zp&`60n+AUfue&^nid8kb!*T%I5@8XpoecER72F7FEb*zpIxSY`S1R|2jLMJ0bHS&+ z4QgHA%q$CQyx(&ys@9Do7bkp($Lby3S{@ftJn9Fw#D%Cy`RsZlTO*8A)@PadsTeBO zjNUoc;_Nr;zih|;bgZLPqKlJvWptnVr?MBxh+y&|!WHZN)4Ph4x|-8t+D=#cE}tazMg3C zhz{eeSs@R<7zeQB4{10&UXpmsifi2Va6mI@_eSSPcxXtb9_t!+vFb2-NPa3BxjAqg zO#kpndtVm6WXpy)*0+khAct>?W9y{cQbeyEIg#UT8R{YO=} zUH?#pYx}3tzQKzONg@wyGQ(sjAH!r~Io0p*`*s9TuCd_`PkMF5m5zxMJkMuxh{~Y% zXUjK!6H18QdsK8aParl-nPcaO&x4&_J65eRlYJ5euTg9^?L^tRw{I5*vGTG}uGpBn zKj5+)WA25$FH7}6d?_iNMPr`O1XUr00G|(l1(7{IkgEo{m9|Hk0dSxfJe{+0zl zIP#EIoJ}k%8V|g$=Ff1)ehw-8UmkUBctPcF3kuezUs>Ss zuP6$41u#5c3Y{g-YXpNV?9Ca^fk?!}FJMR5D~a zIC=h5Me-`=m2{`Z$gU#?@I}J+?UmTZ#8Z9yo39c?g5i4O5dU%7INKDaaLv&i0@vx8 z;E2}IW^&NgIK6HKFpeT6jytUDtU_z;`2Owyqyeq~Oc#7HaXPvS-cPV&)b)VwMu%SU z~M`D%!j|I(J7mPKO0e$4ZzxZK4>*k zFj2U2rSg3sDo_s_wN~+QM&V@JNa`P$I&hsRR&3xtyW=VO0JIY}<5I#H2cQ>z8Qj;^CK_Xv9ZlMWh_kJx#eXzt_WN)(+gW#B2Y zU3_7(pp^>z+!^z=hBC|81PGqf&7!e0DZhWbyMKMWuUDeVhUEPx4JbUPeqQsbhNAj& zDV?b8&fK_cS&%L#pTAEqv*5@f8X4ZbgIdZm&07#T?+tlY@kXOAX9V z&Q>hsHW|OXCrT}T&Lut&8gkAxROa`CIYmwGH$4ouFZ2)k{pL&jc zJ%>~ilCEU9rUS4B?of}x7vopT z?Gn-9FK`m!?>BtHP~X`AR3zh)?uu6v_{1cW8#D~;a6v;FhoV#Te<<3I;+YxpyU9Df z0)z$sK#%J^U9A9qQWgV8bjE8&D(G~{bh|NW&udZPXW8*8CACr=XGP8!;*NP0j+8hE zhIKjdp642NkH&ICK+`hXeya52$cW^?+4| z@bgt>;O8xno_fcp+#xJuL<_EXdPi#He)HaWnl_8QL5(@qM9f&MTu>$xiC0BUC%yU|N7mG}iTP>9L!&SEE2UMbH`{(pz$8=FkCF0()n14DmV8 z0{)STmKwE_i3@=b$I;)27UCujz!TRF;F+?4mEF?{`n-;x^W=s*goPN2pkhW4^bfYo zti!*ABI6Y}(c4@hpCAy14BEdq*K}`FoTukfslL`&&k7i$f8$xkPUsP`Z-TGt{#BU! z9eOX2cO_^vKGznZTC!FSxAIJD)kgA~l`Z3iE7U5!Qcg(c_#WSj{Di-K2CGY%i=lK& z2KKhmSQ*7pSHyZbpUW7)i~1+yyTzh=6Y3r3sqk9Fxpw-k-J8kg2exx5d_ke|kjHlN zQEV9VMp-tpYr9V!cEX4X1GLj{M8SOH+~v27KlC4)*fDF;1x|$|Tc1~ONc2E1F|%xt zmI|&hU(7gTws9wHp#5?;%DXF5*sJCYTU+sF8yiJ_a9|dv8UEG+?yTY3DV_R*1oOUx zc6dv|O1s+{{ul}dTQjK>L6gn6m{4oF9UFq%!>_B<*5+ty3A@^yU;cPhE5h4*d`fST_Z64FeA^gc>MZh&X~H96E8NjZz+F4 zZQ*71uBS){AXFE;1 zId#-gqou`j(?uPT)6=$DP8Y#!lHwU$L-$y9bm)bJ>vhn}c1>KrnrF*`B*5zE+H~5V z6HFH0p$7nsKR>lbIv!$`PYF%97$%L=f1Ds z_1kq5s3nYOQT=}`He3Ov+u}S{H-euRu`t53koPqkQC{h9 zNqB}_L;*W@t&_M1#%Y|He%7Bq_DRHjldMjXYM0UHN?Ki<$cAuWx#rNt2p@a@+3E{5fiI<@zh$R!;zD$(^m`x5P(D80Tq8OR>YhZ_KAQMuW;21Q4eqwKltFy@ zd2=xU(zplaQR+8TM*0LcQOfB_M#gK--=l9fxNt<-RQ*y*U$#qZB7A}M?&eqQ1oc|1=+>Ant0%Fl;E6ZL2yGXtAeOgP*I0+f( zM$Fn1p=t|{CWvcGVf%`UXOMni;EXWTuJ8fXd)uosU!GUr`)X#BXs7rKF~`+NOL~cP zwj<*dbcHuP>b9_C8-Y?qEpR-O6g@e~t1d|>9ZFss!Qnv3B$0Va`d+8|vDs;{<Ni=KmVI? zi7q%Q1ADy*++<*U1sWvH|NhqfcOzq^aI*hoZP}s)G^pzDl-nbEgcmN^88Wf=B?%Xj znDINTOF0NE{qH4p59e1Fezoulw9&Kfn3ab1_h8?JNU+drKgY?!O?esYo_DkJ!!~aR z##A|;^^hsRIN6Rn^#-{{kBhT}VxafYb)p|17s|i_iO2;7$f=wyhm;~2;seotEYfI->e9!WdI0Xzc><8({ z;K4&PV(@TCfdpDod4%x$O+re2}fHBFv~m&%a*{KyPY7-=h+TfH-A0zZcNK z`bP6KnnrvE(%f%`!gW^h+E#R#Ml^cY30gMBGa8OiT(6nwJXq7Ih+to2om!q$ouThc zG&DFlWn8E)0}XLkPD)=FFGK`DV|gDaqvSM-Jg{@_&hibqeR{I{jn0gZJ#%~A976zE z=HBOTSo*7vDvGRXB{1ZwhN4W!&>{+_<%IEg_~#&@B+_f87=AG+ixR+q7DW90NL%se zk+x>ooB+*7aLb&a=@sAOXT%)y1@4~M+Nl_-s_pd=&(Hs~+Vi1S*sRG}NH3mW&0M2! zVQTp9-Kobx<|F7G6u0!{Ok%N>da3=(>6!BVC-p9;Tc|sFo>sTYjcmG>BUkNUYM?W6 zg#J+!+0Pp2?lAqa$muaDyA!%30_ECzM3AtIuMBi}G1qz+&Mb`APj}rG+tU*`XL}i7 z5DeFzZyp#GQ!WmEv0*#+9CYQ}V9pf9A;g}gdeHj`DPPHnro3VBJ>Z6v_d@sez2e}u z)|EdCzULx6Q{a1awIB;I#!7wDUj|sfq8Usoes*QyR^yWijJ|#%xaoPSxGdg|l@j~i zVzbv?zAp2(E7wsGdz83t5dJP+&SQAe7B1Y&5XMGX-7!#vYP|;GqBC*JOw2r`HYi?S zzxUcjj#hMK7+fThGiD=qwi`Elyh82k2tk}=tGW*v5}A3{&Vj$;=BurB{Em;jy!gWb z@Y`9xyY|V~u8STIsvh-y&h_RduY1_uSW}_{szXhRE5wNo{a!{b<~xFevWkq1UusSDc3-9*}&U(jSqiTGcHgDzc%JriNtsPP|qkh9!{x(ru(jI`XK?& zA`8OwI^|53ZqjuFgsXqXhOy?ySur=-aR%bo6xIkMuMd_rjvMO1lLh2;Xg&OI7!2jr z{E9$IJyT^zMR5PPc&U)M3#{Lk#ZA1FrIhJLD-D+>E=c_OqKR`?eODD-ZA2MlJ{jh^`Al#*E zmRIlw$T{^c^(1ZK$Rj7#hs_K=orJtH?Mq@^Bpk_oR)QB2ZK=vW2^s4CIKdzhZEFn} zXd$^tktzH6S+&_3>|8}7RP$DSFRT%~8Ayn*sYRt)L<4iV>*qVA}*zxpYi=XO~xD^pXYB_VdkyC#uiwwsp<7M;4BgmPapxkq%!xxq%K} znlRJ#4R9qGtk|l#y5H&II51;elz>D$Cnh8((S$S!^w)>6qEi&Li#!!}>9zpBV~{95 z{GPAYCIbJGHLdnhC8|dY{(3mUtLzB1wULIo^5!6W4)O)QNo;7CFUIQlFhR#uEN^Mq z8nwsJSj9;!-d9j3_1!?k6?Au8Q5G2Fl{>Rxk+609;l3HLng4y4cr`FxE6(lncVLld z;J_rQK>+raL$Jl;HQa}A9i6}GnR$=erNy{tGE>zyF zGURn*j~ya5U=q;t}nT3n&)Pu;Y8T$35s zU3-V4#FSBpfZq6?vT5m*xXky8W5UftCb ztYm~&Fp%H&um@wH`9;)ln7}w#2o&NSzyIhl6W3O2kTUZ5IO#yXU);Xy8F z(0sO#;7>cZy;?+Z*syhbODY zmNAN(35jCb=!HZw6n=lP=coPY@E>f>n1A7)2UYASV)Z*_RUB9%mT8FozU;O9cRzSY z3nPhu!ZGYo3T?bz%z6CuogYMZ9Ru!~^bm=gWyu0B!nXhQ zx*CRuzQ)G%3yZA?*W7(int#Rh?kml<#cuKB)|UqQZUn{!_1Q|GrJvEY!i5t~O5q~0 zPLEMWbj4W9@Knp%EhbX;XX$XylPApdQ5#TnGwvP`+uZ?`%~DPgC!Waa`?rrfQu&!F z$`3eKzcJ1pQ=*Ec_2iyQr=hyD@f8S@hj+35rm>+zh}lDbh}h)n_;LMuUx87{efybO zFHpN?(rulJl;2OH95)tlU!MzJ3Svk<@=I2{pgN%a6&`afIgyQ47IpwrwFkjVq-Zh~%M$Qx*PsXp@7Wcnqx z*sHro;?s_yc6{h0b(P}S&QQ#R5?7gbaZ|z86~C+v%t}er-~na0S**jUkz`Mda`FmH zT~M5nit$dPP8U_(7_6&*ctEj4Xv_OPT7<$5uLvkn+Dat19(ufaRtbg2Cz;DlC~Nk* z)dhc#UT0dT(e1EUGLQD?BstMKNw0z2Ez6C={A20}g*`W)_(4bSX|$2ft-PC}7y?It zxARN1k`Q)SIO&MU4tUn=*$5Pk46JFc#9{!B3PW(o=^S)46bJ*x zC_$fMKsaxmfnsj{^q~ws!CN5fslm+JM&UPiu3q7EXdEC4&CIc~@w4Y6nm=Mxkdcs5 zI+*Ss$qCmspe50o6+b28+U$|I`_k>2~3*@lmtS~GeL@oe%`$)dby zb0hcmHYDr9k9)%?qjlY6%Rw9|-qjTN>Gm&d zxk>GW;4tX5n1cqli-j;daY_X$%JMnD?r~(n-?@HplSY4*40N>yxEvpj3KGd?+Fn{Q zoT0>TZfQDtrEe@lNVdXN1$vKiyJ-{qrdxddWYbZ#7gIrUf@ifAyDRMwaj4aiXYJx6 zD8~Xtzicu$18sQ9{Yt^XuGoiNTq8TAeT9xZ^sVKRQoeV~zAFFDe0Cd+cocljcdz6p zska7kE5(XNHrVs|_*qa>!}S2Hk=b$sefZ`V2AqM20R-X#M#E9lA>pDe!e!Y&@+i#t zHsGsy@g_xw@hU)q;{!iQ=sMa|ZHl8t)M|{%U4J`9@e3#(D-!YXWOY$iu%?(PMtd13FLN&PR5%yGYeRSHmREj-S z0?j>r;?n^PVQR_tS2_)Dnp|-M7(P(*0u+N;EchK33;VNbLjk}X?Xc_Z$ZKO+Zf^jW9gW4?7kys-PJ(1 zB}x$>mzMep9>eM39?3(wvd@(eKXL(Ek9kqZtxg^{Ap+dsIV_U82nMU3NvI2yDX|r& z3E(>maRRXRpq~IXLSONR;epwZ$|2uNC_#65Zv48?w;G47UQvx26*-_~mr<-$;Sf-! zO@ZLn=w;QeQ0AuEEg9q6W#TW4gl=CAyy{fWaVyk6$J_Mf6fb}i$xhL}b3CY;g+IhTtC1)dGJ500tdF-M9Sv=~io zz*o|_bN1N_V?d@sc35$*PGK6IR0%A4_-YP>4Gi~+PQtxruzPVi5gsPHf9TI~sJ*=E zfo(4tt^!8+|D+l%X{i`SB!W{W=3gBP$^8B}uKe?HJVLK0K&StjPPY=Rv#E4%ZoH!* zk@lwDHSOvXm5JLf3Cz(ggHl4BsQ-lXt&o!CqbI#m(1jC(LotzJ!i4FVElaxK-Y{In zBlW*9zJGD+J}CNlo^8C&y6L^M<;&qXF3vn;MOV1OUeOsR=}}l6ZvADXQQdE+u1R$9 zD0XB2ooI!(MWbeDdLiuB)p1fsltV=cn@yzRP(?q#k99MGK@s;s!%Bi>^EXew8?iRf zUg*K+BoWngK1^}|h34?1pLB~q;rjJ9Dw;O9s*Ibxg8X6Yz8vz$aCIbg%^9gNke^8>^$)M^PM7uojGGsA$(;ThENsXaTV)b(y zc*4H!eq?A!VQwk?* z)DO&V*Stwg$NIbVm{gbc`+MNi)%T}xi<4VXK3Is|Mu?iXSk(&{O;U6CwBKnfVDlgviZ}0OcsICDc@FnFLYe!`&7BXY<$QCMoIIe>B+jBAXLn zSbHWuB!llw=Gu?`3RKzlozjn}zDH<}aUM0k^3=A%f#?J3!1@V_z!uByiP#4gOe$w{c63iTZm7#z%O}I?z#G zaPLB)s}lSR31q|Zvvh$4YvftM6!+X?*`%7Q!x1@egnaJ8m%LcSOgX)R8uv-D{kvPV z0Aq~#6g!W3&b;eHelCTC1+C_*5(e9LMSJnY4ybN1$(_n1G)mcxU|s9Z@U)j`=SikV znHzIIb`*S0T1p>R-E{gK$h9_J92~-km-KLn)0!jq3N_;0BS;Q2U42jK9iJ|rJ!()( zz6E}C6NjRQL@H5=RI5=S32!9&K>tbxvK^tX6*A~yX%* zq#bp4{$k`qq1Z;-50lfTHzp^J8zkc4qus{wDwW7IB;-nKF*Tp3M%)iy)hZbwK8&~o zWlt^4kTvnOvcM*AirP_DxmAtJqx7>nZ+%XAdqn z+*P)xc`oyYLGAM&UE_HE7&eX3o7dU9l0>;L$S3c{u`Cyz|yP`n8C= zL#LAF02sqs7P0~p2#ntb7FvJ0NmaL^mLHUHjDS(%w34JumfLmptmx4pcRx6F?&DyE+i*tzK3<4Xo47hA{IsHS%Axem0S zR2;N-3JR9%m2S1eI*L8>Pk_naV8L0A8l6N`<=!6Eq!YZW8~qQ=^I#AV)6T0qDKmDO zp-M0OpAhci-T02CZU;O_xGa9rpK!LKhg z$sb^0syx%_9dwdl$5|lCJ|;29x3%V#f`$9mi={iE5a{l~cm`$TX;(9rNdB2)&Kt$Y|qUU|hwc{_j)-NdMFRB}UU{N0Xr_&D$E~djH zw>nJq)%J4f5Ym^bSb~^JXXX+Tx``S+6pvk^x%n21i9L~HH(6by1^Wka@Te}bTj~w) zo#GD|ihPm`hh0abFy7&}by|C_MrbyVHOwo2Zc*8>g3g=1$aQ)-l^A=~x!|R6_yNV6 zgwf)>Bg@{^TO7_m9k&XB60uRD`Oo_!8 zLVBBQ$2rTr%ch?|H9U2-?F42#eBC%V@~=X#1N`mji2=UT@WeAAyHLiH<;4B!u`1$3 zng4~Kc?Gcep(%h}3)TU&cI|&SUkCrnjtbwnUZ!CH%1~JFU}O6?O~%=^zTDCCo+s`e zz87t29JtwAa?*4}`x9wBbqL>nobw?~u)LDg5Mc zo~K>$jmuWtw==f9>e%-h!52qrf|PcjSf4L^e&l}2_6-7jd*447+oFT>}b$EF$Xx1d$%`Reb6SlToXo^DIOcM!@%QE|I~q ztWX80lceJ>ebb{9e+ez5Lq9CNQ*T{@StjZ`LQf*$Agmr~JH)(8RJ8XpJbUlJ@Yv@w zI+vi9)Bx8Jd0WeN#7C`&4mjo1wf1NHD8y!-3WKho-_kK`%2Z__uecpY zUI#p4ds4stQO(8cn=wxRqjj#ClhlIzap95dXh#St%$ zEG)sdH9|s5DS6@r!Ab05}IbQ6(USiOqwp-%I3{<#I% zYP}W2fxDvt28ojmEC5TtJ^RVqe=S?A)`Y8iRT_aj3O5IsYgCI-SJKvy_o%VC)XIFd zd!tV}Kf*V+rDezfG@Gp9yvrJ^?hqzPCYH9*YSRxHyf;vEu2}=dk@-xoIkOM3Vy_iS zfkkDLn7zUH%xe02sKYI%5prj2PO@X6lfyGrx#?y?$*Zo;b_1622`#y^oYRq>qOb^` z*|C$zLKG?=*1kluCEnR6YU2jNSsdgWlS_6JweugiV$a#*;OSbuZ>GENsZVq%{*6YK z;_b2n>&Y8=yQ~eim_#nwzT0&#eEAt_V&OO{ZF9@dIxVK=5r<}Y2vLFQ@J|q%5NQDi zM#MOI)d*9=ot~IqV&KQ(D%qUSos*kS?DqKVbGSOFhAB*&dXbJef!R#xPubZo;n4U7 zdqVNy`IR$F9m2rdw~|d)OrRIeX3KN2{#9wRv=goRl>=(6JlA702gX=3SKnzpSCD`1 z!9D)^a%n3rpgfRvdOCK|#JD`^&D%yR%ZD3>@@6sRu-aHo$f<&LeKF#Qe>a!vWwl5w zj6I9q580b;#Xd2y?DrhnbJ=8I!g)uV9ZS)3OE^%E@aO7(PTL@wit+rAwlhlX%{@2N zGWQW|;&r{over_?G~-dKso8BEa7H^|Ky8$))^rrH`q)GyaONZM`k;!Y=8EcgtQA~D zGtQ|CcGsjA&(zSFa)*_2EiJ8lN07i)+be+l2hleKyNSOj{ z(hBVq$I&(&9syhTx(?gkS-?rY*mRXw?5dKU?DjLZxE+z2?_Rv4P?i-7%4g`CU~&QW zhwyuvF%Pu@nF28dp3G)f_}hn02)3Z*Sh%&{JP^7#_o#BRoa0}Z#SR_*$O;|K8*^K9 zSu5kW)qCJz^Y*R|tNAy~zcj)9>_#&Y#YT z#%lU$C-CD6uN%#6FA&-{-xA&Vz>Q`@j=z_G=41RN!W_~Tnd-l8{D~EFa?tIQ>b;aZ zHRfc43V{B64DkLT@b{Kr{9IG%tReij)NFZQ2LMTPv3#M?GHfKLQ849;j>oHkGipt~ z_h(cM)-v6MJyN2F0#`7}5yz^hK3qLj7FQ39-E3`0PZ7Q2_c-q88-Ouj#&b8^6e)>4 z5+ps%@36SoYsL~bkbmTigaZ-PFohnWQSkt3$v|EVr-XqH{{>4h8UJ^d;DnFa`EUdD zHUn8W?R@_}CX3Kww2K-n6M1K?CNS0d33U)k1J3>N=cedgp;~&;OF?WW*sk6?MQOlv zR$|{V%ogp3)OI9yPwtALF0e;$Zn8b@&I`?RGoI^%@w4TEP7lv(9au9UIPAT&_H`ZAnF>`o`Tp$6g4{uCrvWQ?{up2%Lou9cA-pNsaLSWje> zGq*u+Bk=XSI_`1coz+ym?>?E!c`w-Vyd+}%ir$2`@ExuS7)nR;w0qROiYj!#$>V!2 zqd&`Cfs9Z+$oF5R=8iQHnqUFo5DmX!bwhqxP{@KIICpD|t!3uUR7}&6tyi?&;|Cq&CmpGRMRcICI;1#g)+Wr}%!F zQ!IIMU1a%_ho;U=pk4#eKQr@3#B)c?0j$mF<*vJarbO? zr)N7|^iU?eUjE+DiE-Yb0Ggb2Za#UR{ekx>lvB?BTEOi(N*m1v!_fn&2dHG1Y9`)y(m&E_Ji$zhlGIsyxJ zz4T0196wO8smDgbS{TG+Mc9Bk?FF~I;+cLcx z5i{}#HA_UqlIr;?xoS^UYH{a7`jd#+i|?6DZ=vy#;$e)!H!0AjqI5VSc;W);g`i%| zd#kU9UjmUo2R;C2=M-$ck2+(5uSoZH#lRucwi^_p!ghiY^(pwpm%%t#;AF0vtEEo3 z6Bv6u?~~PvlXcI)^o(@F2_JLHqH-*k&dEJ?ZSndcbbHljQNC_p*=)>!zdTH4N2JZi z+l@4(S?FZKkN8G``o@#J`$0&>xK4K3V#q?@N+v6X-J`KbcWo>IKK z=fWLi2g8Xu_8fb^+YpuQ@Z~4k0t~!C*7quIHCd42R%2`*9HTc2`!9)v$Cmxc$Fu2O z7#olS%`GuE2XJLs;O!IB{jMd!X!*V(ti8>h5ioNBNs5U6V4T*{HA~?z@Ya zCR*1nL7V88rDLj1i}1j86Z|QUXWMp4==ObUjuiVp#VGtgN-JajLs~iSzi1Q=`0p5n z*?*;#eYqJYSyQVkSAdC&sJ&FNEL+AdT{m`brqDGYhWQ>~FLSJb6a5C=+SIJ+Y?=htNB$z{Rk?PwMg`J#)@5bgZUI1rgW$+NQ}V!RYjz)<=?CYVi4RU1Sbl!p)^*$rqI(|6al4E<^<>J8 zhA#Ij;I?(VVPOIiwrOnC7YEi0gkLZY3_%HSLO9ZhvwTTgo&w=w2R9VyYI)W9wbli% zG@awIyOB=p(=Ux`;n|%IKS|G5&g{vUox|eSVO^>gSHwwy; zX~`O>_~&Bb1xzzZ(8iNumDXzlnGC>BQc{fA=V4f+>@H(7^bUAiCF;6J&d%H+@=EQE0E#d?tlF@}>nBu~_>9`8V3;0ezg~;g}cobE^eigbGN9X-xuz zEOux>Bg4~6w#N=6(rBkD6_M)(pL`eJ@B!amLgsjHf-$$%73oFk9AOlSicYy^*@|1* zwy48Kg-!lZ6xUYG83+B|I^%*BrOv_Nkn1-W_XIBrvE-1GeNSOR4)APdfxnM_$Co~%~IGe_W^|itjT?W+^6_kFi>FUcZtIfJhEe^|CrN7+Q*Px zxp#er1CRq3FmLEf2(uSD7p&e5jMv=LD|0wgzdv$Q2LWp!*Ktqp|hJhP0-DlJ=8t1 zsy(qotq=4RZN{unYCohl_1VKo()dIzHhPiPIE-3bX=*<@7eyLu?t`bKKfN;8#3q4g zx|DRjF}J+$D4WcwfIj}CeHdt{HH_cBsA#e97QL~pnvQ`p$nzJWd;i2deB4)WloSI`aO<%)TGfuIWQ%`UA$?w870VE(V4&~bIE*Ctq zNpy~8fFK#Dkapk*S<7YdsBCpdV_>0C#oLeUU+&nBc{D`Orb|N5n{Kf-%e$!1D zQ2yMQuODP_#Go?DQVs^pzV^%tAOFlHcJFoUE%o_Kf?=Zcx|=6Y1&X_;k18$doGLxP zBa7SSt}8pNiaX8U|LP<|hi&wD*U%KzE!XZ+hUS}l^-)6cZS@~@@8Oqj!oyb*=!TO!Xr1HpK!sM?YB92TU5GJ(O~M7GShnNj$vb$Ef+^gJJ;Plw(024 z=~+dVSn{x2xW+`@hv2D!HxEN%pbjzxwy857aG^VCdKA{4~?{C>}wN?k0XF{z%2(J{0j0o%G(ouwUvJD(ty5cX}juQdZ%PxB3 z_Cx0A_VHQvG2d}%k*BB+?3cu#Hn(F?c;pOWeC49RG9ORROZP2(;IOY~E3VwBM+CYF zf3NU_nP|L~zRIW)Ps%~ze8+;>l64s$TK3lT_HAI?=+fbHPUvOvJJDYl%b)9QUzuknjS<56n1!s~WYk@C0@3 zqXaLWX0{&qMhBLzQ$ z73`N%iv8NK6{AKb3+Iq+uC5D0;gU}>nWsdxTjBrr1Hfs$roN#=r&E^D7~@l>ZF`7m z9P~&h1D|>1MHg0(ta(?pf`MfikkH#beAjshh}2>|23dl_8)=f zLWEJyeCRAST1+}g-0vja_)6a@Hov88GdLwQI81Q-(#MQNi)00wvC@6d&114{r4BDY z>J%`2$*5_wn$hXY`}t5EhU`A-JzR}lv|nKETa_E$;0 zq+)77z|o%xbtBMhCQn=helo>U73)y962u7{FXxSRhY8QQtcRs%Hp3Xa<=&hldt+;ZM^4rl z`TG`Fy*sym!U=a-?Nj6ySb3uV`k(R4m|J`2Z9;@71{8e5__Yx?AH5GV)bZZyCilS+ z5AS*?VBA{I(t*~K--jnHeVjj!$(YXOaJy(tKcuQgDZpRGG3@8 zp@}cvGhkQZ}4t7jYWC|BZ$5 zv9B+sjro^*onPvai9$IQ_b|_^j)bEMJzt@RiT#h^QgBkn!g`ez%PEoSoMDCtZBhvw z%Wcg0Le+k6e=-aS>Red~hccl|2HJNU@SKEaE>U86@l#zlTLWv+MJ0}Y@9-KnCeX&K zRvXsa@XD8Ncua2tYkzi`vy$r_&y&g1u3NZ)1LIW~rjvm8ttg-LWv82gr&2*fy5dRR z(yWQr=_PKu$#4wGb@~G7U zwD0h|YH`FTyma&@#aTmr0^T8ezEQ{jG{E7cA%w=v6}7f3B2r@0g=T$Y_d|TH=kIlF zo2p&=np05Zc?2;}X_tPAO2xbwzA{oqjM&XA_`^{w;PwxW;#+_3D1Pv-9K~Dy_c@A5 zYj}O_z#(35{NXRM&vw*&RP^Bz;j-uW3tjD`i|B{UblDTzyH*-`J{gMMywCnV-hAe> z4QGM3&&HX@N@XZrxWwrk9p-~nMMmh~JBr`Kj$#({w3XP#rN!K#gz{3`VzkXfNswF8{Mq@SGt*=^trhL2;Z1V zC@xWiH2j}Uh$X#)^~b!KZJgLAh8)CKM}G}&Mi}bO<6XpM zr+m85&W{q@jG019FN0w>YV_;(iXzZ;c>ntFRZSFB1gHQ_(eq5(ca}$cB0ecz zz&xZygPAO$x52j~Tj@?k-^RtlTI#=NT%cSeRQRVZ#IhGZOK^!@C;FMHGCQ1|OE>b> zaI(PhKWOG;`dqs8kPXyshv@IwU#0yh*Z`R_N|>-|CKPF202rLx>kYmF*U@KrH(=;B z6ZJvy1(1%KUP^C3tvpZIlAdOafQA;>N=}U+(_D%Qkb4 zK1n{V39ybnc68^)?Kga|15}pyNK60RDgsI$!agQkS*)d_WDL~j4{J+)c?nHxUxYUb zo7}tBK-a~>kH7oLAn;V+P1jX}T<{7yt=T#j+U|jr9TvlP>mhZLUC6`voj4Ue%WhBJ zb7n<|B6Htvir+^?X&Z%A_~jbr+qSI2POlV<1~)_7QdEN@vy`XcF~4L~KPe948wJ+$B73Wa;kb4Wocq5FJt2OhneleE zzNTpk@6fcrRkFJ$A_l$0EB+L5sMNI_@^vi(;ZE*Z%qI!zu5h_4jViiFld2?CmW7Ce zPneUg-Z7kAb|D;orre^jOVtRW>o}l?(IUmEHVm~;)ht}*U3tg5IKNaM4)2|r zjNyi!*8Dk|^3Z7^y7ESyZB-gp);A%dRa`%Kl-}2IlTr^|E47sJ%yV-!83lr&i8y*C;QH+JWkmaX>*(EDuroE$y{9myabMcV9QX_3TtA{stu^;@ zlD>dp?;hAHw4d}8qsA{7v3dGkZ4y=4W~KfQjd6wW-{H-a9R?i-<)$8SPfIF3rQU<> zyKdDmnw!n)aW{`+;5OF1IXzsovr?U{n7(!4(T<=F(;)@TS=UgRdb{daTh3wkw@RM1 z%+24bl}t1q)tV!#CojI88ZT+~6@aL&Co~+b!KwTFIEzNOGqu%QN(AuG6rz&XJSzku zA_&|6E3mM-}G^CH=#Ge z#IGk}x3hW~dd65}1@8hZ-V$vmoEaXjI0&Wue~NF8{0F|7{8zqt%IXq5mSb+)*Kqj# zTV#X}ufC?-4-Tu4&~mDqE=$g-eE|hToeZ=DIA%N605cCIA)PA)E&2VVZ9pO`156Ye zKL%a&+*Tg`9@Qyxhn>bLprJGBFGKAjYF`u?ig3i@22itpS&+ycH9J4EY_Y6Lv66uG zZpGtn>8OFFA5&tB8@#sbaoK&|d|GgmRepz0I5QgvJ&3sV3fxxw*&yVW%jW>ecdDh7 zze$CXt5s0no`X4qOV!!T)_flC!^bQLB0Wh!S>)2qIbg-IsOC#=3EYq$# zFlWcIdG7XCBB$$(&oS#SxOa(JOWCWtXs*Fs-rYsE9ylo(nEWsiEhy{U-tvZMjnvgz zkKs;s-*zmOD(A-Ue&2}Ic)})T>V3YeODFi8t1s$c5Pi(Vft=Tu7fNN+W7K!~MMm@= zBaNwUT5}Hk>OV0$Km&dr(_f@7vrgg%MG$9_;j``B=W3ERT>;3I&4D$-><6eTpjs6E z02K!+QHL&Y*$l*K;Dl~~&;O*>_{ZOAjoX9&7!qr7lVq?4KXdY`p&|HyIoXi3^Hr4i zw`Hes!qyTTQ)$<$_WHGjpd{ugs^*UDY}l?BD2)FHp<3ZTHXdjA$!1&Ya6J+;g}|Qf zh*G57!=pvC{)rAV+pW#hzdlle z6Me!b+oDjYYwaaktR8^{P3QqO?A!H2%?bmfs_|H+>uv6r`>&(I$aM8Lz)XJ?O5UrI zMy@aFVPQT@MpjBjbls0w5+a+tkG1@lR%73kzVdO#t{LwlTz8@OD|EUd{IZxtQL2AP-&)vW3boeLr)m9c0`V5VdyC)7T2)60kkIuwf^_Zco+!qN2hZni1nzV=Nz3CFKY|(xGO*+Lkh`a(Nqq_yoUsq$H<&c+dG^Wc zmH*XGvA)(k(LX%LTmGw_V{g8eLdbBj%F(jo=~}b%*jhQR zk=n8Z7_DV+sb)b0_^9~J%rebe3wx18NP}a67jd6hE~VQ^5s02Yfac+AGsXyl=@aoS ziwVM?m9tol9a?F&XllJu_Q&Mqg)=6WBON&KJN8}8r0hA~uJ$h!D*2T{-$SnINO1>i znuQ6pPes*hG@70;u)BK(cTji3N2`}m6=eT+tn({K{lqF)PA33v8w1-W-o4r*Ci6ik zafy=*hqqR%{!`Yu{9m%pxBic1otOW{I#2zLb&d@1zfX?~@SVx|JJxyKzh|94cy+`Z zuqB}W2;TAvsQUXOd*iQuX2TlWK}MRGUyqLgyFJ#xLT%(wg-WmL>9q=X$G&R1cGvPv zy9U(UYEmlpKX3|PQ;5?JpHZ#Aj`16g<U^i+tRn6bgQj+_H&F_|K?kO7?$+dS21L zc)?K;m7$-w%_Z)Ry$bM8sONw0JvMIm?|P5RzJI>6aT7J+u=-75PVCR8fyLz^W=jIA zoHW_bgP$8|T3ii*lo| zXE^ky;7IZenX5J{@zQum^)1&Nnqav&_cE~;kuqadmCmcZ;fNOx+o6h-59Dc*% z&WKWc%J44bxSSwd<=*iNJiS=KhLG5VN5;S{t^?J$FCz6_9%v12DZMOg2d@Jsd&D(C z3#5GwFb*V(i7hXjMH@(PyT&P5J%5Y~mz**b6G44gLr4v_0<>MP&ya5(Jq%nEQ?ea> zF0>Ssl_$l)N!{+BLJJs8FtCQI5TX^=!tse+lORM(6W1nA_OV*$m`!(?6&rl>@Ou<# z2Z2|M&CI4irfM{BKgj}aD3#3;0)0^xy*Ujb&744lqBTHl$1&XtE|afn4Mem)T}Wus zbSPQCAT5dME0fM^dsrivPto?y7Pu(r{jDb9467Qx6{1-1gs#Sk1#iOte#O`D>&+@S z+_AtKAz&#!C|ctXbM>`3^ZLywc*jywah2sK{SP@PFYc@iuJ+-~ly6u)Q-jRf|ddV0@)HoO6P z{01|RaW4s^3fwt**UHbeE*4BYM5%%^asd+rZe}at_=I@dHe*2W?d=IWC)Qn1cIocM z;mj~!bBtVNH=Kc1sjkk~s4g+>oRLqY=Psgq z1nvkG3z?s{yGdFTk?qCVv$T$0Z}OttPd_#g-x?y-fxPI~Vq1`wCYblX*n1D4ruu$e zTSNs^Ktu(lL`97aQ9uzPL`6YG2#AVE2?&CSbfko`#D*e>iu4kcUZa3?2#E9&AXF)# zBMB{pKoXL*zU4mqdEWPZ_CDX)XU^XHobNk(#u*)l8D$dw`LEyay07~dnYiEdqu*Kz z;%kOL`8H*ev*%WKqV&6STU7n)cm5Lod{yYP44{AimIAE%T-@txz?t+lyy1K}bt=y& zGIl-d_?pooc4eWVI`$;Y94GyjA)ia=<=W4ubcQtnF=5XWEDR-9WxTH3GAvS!yR5ti zY&3g5j$H~wphdIoo@&nY%48mSIl-UWKNyMv%tX0wq<3lbw>BH)Pm^>q?3W9;ZhjV? zEiAXK`K|RD7KSy6I4bsj^EKU8o(?-j0;&W`G?px-F9ScW)Sq8#0&=qh00O#TJ9bf_ zXGRKC2N&2zWwSBFiJCx>K?XWAR)19iR;dQQE=WvrS4l^F|uJE3or*qporqUW(GLUI~cznol6HVy2(*iYi^2>ghH(laK{)r28YV@Q{%v2C258sBh^b6}~|BqkslkZFHGML`^whPryu)-r$p z(LeeW`01TS+zAZ#*DBDh0}cLV8))wG=jb|$HDOfF(4;U;(C|j3JT5tEpwXo=sn2Tv zUKh_EZ0s`ypJCEDAq76`SSApPM&KK54^a_riB zKhK-!crnf7mkC?-ng0Tjy2Mip2eyQ-Ni0#^cl)zO`T1fCjU<%+7m3MaoBzvdbI z17S9=-Hp%p4}~6og}3Zx@U{${W5bR_4WGAg?kN6=W{TtH%j-c2 zn}HK-&CQ5VAP0H+8=(g?ofOQhd3)tlKn&XbK{wnrMZ`)Xz{UoJ-+sWcwQzPh@_EwOAt=5k9ipq8%jnNB(}jy+W?V}C68+w zZqJR_Be)=-Rhu;7Zw>#j>cc-k8Xw+f8rO0^fbG2#Ych=TjiXIKD5!8R&?xZZ zBF2$b)I802Iy^%XhTMlSlcKh*_dzb-f6s(m{f{PO%`qweZZ!B+lshs&SyB4yxqj_$ z8$)po@EevsN?DB!RSDh!C+wZgwPMKKw^yYu@>)7RpTF3rxs^#y4wCJvN=`a<_E&0U z@)jFVI=!za(rH?u)D$)263%(U#h-yb&*^Tu+xZf*jtLKlE3LfRpW=J_C;u@+p!#4G zOXW!QY0-?yq?N1_)H3eO+tB}MH*&)ArS4VU*~~0^2m65{&uHNqp zg*A@94xjMOKqgJ$CvhI5uQ~V8J>}FK&PyPcqjNcJ>Pxh2j3)2!o>|E^xbE*K!OIUllfWb2 zV&f+JtNdi{x>y^TjN!LmviBp#-1L>rk>HS*8k>s-D|IUxhFg4tgv~d#X5xm3@69~Z zvfK`DnbY+nrI{|()0)>?w%V4cUlp%8x8V-MyV(EnS~#rOM#q#oeSWPJ>p1x(GYym% zKcFC50??=jVlOt{FZ~*m42J0AItQ<3GFyh`W^wEi#ZQ!BvsGN@P{kYO^=4QhAxF(H zmf{uXbv#5nutguD7$b8RRVthoC4l%GzFHLpR)@-2bB_6+vx!%)oP0>|B?AprEBKO; ze;q>a-28W6iHDfjwf7V{ZR~OJPH&67`vN25-ajcox|aGXs0<9=Gxj)>kSm!U=qvq- zRkq^(p?P&PHo7gMTsw}20cW2Fgr6$&Ce5mPtlaay5rN1!}xavJ+27Xx39s z`?_*%ey$-JYl~jdKIW>sZVf8WoM?J8#<~x;2Q)-Sl-(H8D>{undrS0IEbc#uE`v>x;&_PAEtq7`Wu2Ox-Q6=b{M!_K(m8IW3 z6(hrzFItE9DjQvp&}jRsWzsfZ)`Dl;^9Gz8p!x8G zT-NT4XBVZGdF)u_Bx&f5oYr(b^ya_mlB@rwOMd!~x@0l2g|#-~8f-22_b1wL3`_va?pHj_27wiZwL*2*1UY{-66&!bzFNzpHjvg4#FEKP}xrt{Lv ztMg>?>^$BA;r6KZA6vLczP{_BaImbKYp?III`{Xoytj~JXpvwP#(Gr-xp@F z=MwhPt_t0}UN5}(iT?)BkPG~F78}(Z0uO>J-u9t~0!{Y_n5QSG=c0Xk&L4~$QwfEC zKR-Ox+#A+>pgarhlAgF`gOfQu64}dt>tB~8pZtH7CFlRo$&wEwbY;y^W_PNS#vd@B zSA6T8*^BdjSI)5@&{(8OFWf{6(E;8ENuSySMm9Qxp`(}IL9c93n!`UM8-KG!Xc?n| zY5rieXCpq>PEOB2B>$h(cQM7SO94~UNQ>b(u1vr6b+|1J0Oz}k!jaQ?amna zq;k55?17vSgI~9+iLwDV);#5%nvOO5Hd|hv%;wX_`%dVLiudD*>Gf9bd)Qk)At#sI zxz89BQ5S373I7dX80oV=OxF2FaxDwq^xM~_#lP*eGawlf1};y*x_ou&Ft*L=g~`V)bj>Q^4@Y{)Qp7i3Ju)GN%}?3DfaNa%!bLigXRlb1q&o0H>P1EP+^ z40*Lfv?sgzJ6hGh`58H@M)qQ^zyK)| zoIr9tzN8Iob-6?()&Mf9clv{NW`?r%9v3Hj?01gJjBZk|{FGEwfYl{hmMf;e@ zgYTXRi?)uP?Q&v2T5&Q#H_&xXmH0u0977g5?O!)1r~MDj$qB#B$!YZRR>U&0^bT>5 zh!J;OTC}#hIz!PHQGx4SYClAV95%+}2?*791p#{8go<~|2ek5ze)=jb=yu`SUeSW? z(NW>EAbaj8GbAPC-hI^#ViB1PlL^u|Lf$#d{LEA<9nZGaC;?96r>Y~+;Cge>2jGW^ zF;OancZh4xj; zN+r}U=y}qVD)zqEi9jkhPiwY0oen79{iXYc4zAO7ee(v3Psrv0&yv9h@N}X*j2Ze) z;=#1AhW#H+Ve}Y~u^^?vvjrJM&3 zV|#WV?!E%v;ku`u^N&}Vp|5tg*D+^>_5L&}&xw-QrSFpvr;4}pKPDS8j2dtalg-S7 zXP1ArUEN*Mi`lxesm9}{F4$``tqYRXxvs3xsxO8=y~-vCo{SZ4M#7olhu|?KzWdxw zfezb&#X?;$A3hs0(}J;+r_WO!DKmqh7CQex>I8o2YllrOx3Q;eD(s@W3pWzn`Khdn z*l&|7Q|R1NHR<+@GxlYpMwdklDT(=D3NJN4AaBXl@wG@?oorPL*{F{h{+Wz??@?Ie z^S!d4hoe$_z(L|FS4zXHyha4bMI_lcor3PYKCcrvLb?C@ac18Hzw23BKbLgbOaKYY z^eJ$}kCd6iPNfjvlYwIZmh{$d0xvRk#kbQ^`U9i~+0=t(5cRs#Cv-oOz}~?tQT$rO zoX)ra%T=wb?g`Gpr~Fqub3;8EYZi7nCKmh>CAbl33PZe2#k`+_;bsspG}b zs>e^7#+UKIq;&o4t(xe#oSK!yk`NkW>D^L_t(MCu$snvMP_(db0-9|$0ae4!JQP7q zTSW%zGoE@Nyqgy?Exc%zo6L_s}6Xd~|W#-TFz9pv!WK)rX zd}d#MPJ%VK#*1y`zRypUQr%(e{2&k=Gf=cVQ3>9y(mGW`3wGHDl>k0GzTb$lx_PLr zc)P%fRj#)e6}+tB>yxwQlBIzmo(1{S3eOFNgB7C+8E`FcS|zpdDN(Xr9_q&1?8IMw z_~namU}?v0Ypp+e7V7MGIr%r&qZj?qOR>aBVD+!74}m`t{$3$tN=|;{Kne`R`Lfm0 zl4k6*kIYTSpRrKBsuk4P`pJ7b)p9W9N`!1*uo^AR0IAK_yRBnn!%!n!G4>w>C#!>5 zrxZ?He8`nZ+Pn2twU$~u?-DPaz04cv(p+}DUUaD$nwfTjF-$36cl774`j`3Y2d^tI ztqZ0;zcBdHQ-r%{P#S|S$Vta8!CvK@geQUM%X}(0MJ*R;JCvnWc)G2d4DwaPVGHHy z#YSq4ImxU7zh=HB!-D= zT%+i!AYh)d5%_XLfulle^nl)W&vyS3GTCf(7{!M+k%M5~xJGxCuoN>y6~cELGB@zN zq-#r3km~9x%L3r_&RQ;fFmrGlWqf}}7ISNYeVrpK0U*XDZ&-M+=Gn6_bM@o1?Ke^J@jJiH zQr;4K@QQ;!CkuPR(h>XJuhxExH|+H45ognDLK2qAWskI(@FB2aZXgu1t4Qq+YN-4S zy|9Sa5(+J1Ik&J7u=W?deb%Nwzj7CSrs$s#PX|11TH)S+)Fe&MelVKj^V6{3=(px&HI|8B91o(|URU=gOz@(y6&=Tp9J3oEq2} z3EdvCYzf}gA(sJS9L9%$j3%ZNIXCGFM#Y75&6C6~@oIE0)(_V|l@=1QvJ~ccSPC8Z zBc87$UGzcnYZ=rhTP6!FPw$Q(b`W8DTTNT~o5R;KmF0>2W^_N?TZNQ@tZ=T%JP|Iu zI?w~E&PfKLZ6`E7Bh63@%3OUe;MAiO4Y^T8Q@|6!Hw|`-CqUiASZ)^h1oJU;RPZjT zVxgUa_zamVbleXZ#<6GRsYQJ{4@5YiF!}k<);s( zKhAD{9WGX)uCW85sIfF&#$0c9;}j5^9b^y^tdHp(&v=wT4$$hqcY1^B0le?&I*Bvx zj+epp;w}n0>Z}#^%FPq?+wlVf7j9t{NNo>qFeHkabwJVM$bp%A&xnOXE8G;!V_VK$ zUC-`m!b@8a{wypL-WfIk#GUu`7#>lt@YI0RGF!3sX**T#O^=7IO}_jixJ0;6PBVkX z2)y6(U?WiJFJ!&f>FR&xFoJufHJJCEpp4auRV6HUYI}pKL;Ab6?M;3+{S^IBkK_{8 zK+$x>vB>c-#E3HeX|v~X7Sd$td-pT{i)I8CQfl~nw=w2}9e9`%c$b^sXm zAkd=Cf5-r?3w!b3u_b&MjUd2?B6fSetX(R|s%BDZgk->NydP<0*XweL{Bn;E*DZTq z1~P_>C-JPq;5Gn7n;|N!sdQwOBnpJ$-Mt4m=TUY|G2qVJ^6lH2IL~Ij&2}E)hJMRR zThtC4h)TedC-<`i%9?-c`UID%4y@|UQHnRczQzj~!@T6o^v5~|{bFNczsm!Yo%>Lq z)V0mviCLG9ie8QrONBSU=-`#rA~-H@(A`c;#7XhS@SArekKV_>3_ zx3aW8wJ$szR2FWg1>n>wvyf_JD>rKIHOz#>WC4C{;DrgQ->!a4%l{JQ9+Up;@5!Iw z-d+B+y&xJ*Poh963oN_8zBj}F_TJp30iMRLj4p8H>tl!4c_bCIdQDu(b@_=a!->83 zeDNYe_qA15gTi$_zn|9L4iUn)6u$dc`jV+i`Z*m580tBf^%< z!1ToXs3_b0H(<7SqvWp5Cb|r{#Z9j`5yYkgnOyq%7h4Zz=5~2sxIFc~Z(6Fm;sVJ= z%6kf(#Ms2V92vba>DOz~7Y@5Xx0@Ec!ATT5jjp5&2yUEw)hzY_5D{~L6BnX8`;iV@ z>5C1!Dh~o;bmaGdtlf8*P8mkrln`Q!P&laG&%#$&CXEv6pjX@X--YeVL$Hs3oQlRaySQWJ5$_)HyD!20GuwKRT{YC5Jr&o5^Tt_6^1g|q3yWN=Wf?P zm-r0*M~t|uuXyPWjHFSl16Pc{#p@f8AA+vBQZa(Kf8k67*Z#r89az{SSCC*){9qE6 zEz3iKiv0C5uu#xT1fCt};V6Uo332z@nO5dbahPvR zZxor)fm2+hBT+MJo`ZCSaUl30qzKk~Jx6yZB}l_nKGZjv$QNiPoRc?A%ie*qW05#v z(Bo&y5!_zb&S;hDPC)a|<(2r~Lzg#uP#Gvd1jvs zq^w{McI5hCEQ>-8Cd$ ztgHm$%t`2Q^PKNXLB_)5B?bXV%R#8q1%xv4e0@KY@qaKu^gT5yJPyE0f~Ukqm6KL~ zU06_`{dr{X^PM&FXKMSCoYc*sQrj{kd(*j{=FbN9D6ATUkSe%W_{x&qc!R3H#mw?r z{RjINg_KJ^HGjvo1k-o$x{e$?5jr{0KAbgYU_Vli@YJ0TxGsp^iz7__fc)tPhP^_@wlw?H4? z++-Qv`LziUkw8^pve@G+ya;}`r=+y--8#r!Is@KCY$|>D1j-hu->dJyCV@NQE!i=I zF_48M+vGJvo6BTF7X>i1_=LEQ;%R3SYGZi(30j%|58UXFFx>Wc3vi#tTg5OQES_0h zw|Om`OSa^{2D}1-KEUgbN8jgYr>?m+Vy{kC!WeUOTfFo$J|*>kla1Nwf6d11+xqmf z?jA{n24>QvxF3{DP0}HlE{0l2ZBICU(x-5XTMO>H%a4cNm+KFGWZkO;N4ibEfTkx% zH_-g@20)^}wZ@URQMca)0lB?djS=XWc@H?Wg#zyvU+|N0WY57=wH?YBvmMgNVwhUB zu~%$Lx45qFUAYIERnDGMD*$&GQz-Kfz_qzz`gDA;ceRSso#Rfug^}=WSYl@I1MoFn z%O|dDZZ6*S&K7oX-%Zl9P=*-p>9n)DzfTNJjg81EvLAQ!(95;sE-X^YWw5%QR-Rsk zHSAot#yYRuFOBn^=x<&4;Gbp8Be0BF_zxNL`03{qwhRC%aHA2xxYWO>dn8=@bFg-| znglR<{U(Z_pRf399#?0J8O2OacAX^(2l+icdC35fS5|#I85RAGobDp6%d535y_RtN zZNC2{OSo^=!|E-6IORJbitm~BEBE&CcIL;twF$DC=IPOmp-)))SH$C)!hmyggVVp= z%RF;<94)4&77*L@rCHwNK+;ZZ!c0xO-RD7>Ud>;_^~xPxG8pC#ypG-HNX8k47?;p2 z)KT!Bos=bf-BBKnG@qY#Q0De`OJ}3`C8xm4V6TOyl(`;%r4~PNr2k6^P`&AFe%|L^ z{7A*B;i3K<+!xZy$kLNyqAu7dTkpd~pcHK7stOlVpPluy(%)o^r7+ONSJikKqkYWfciCv^%8Dt> zP$mmT?+Lk!?_rG5BQsD)g-+C3Q{|Jr3)rB~z+&^KRjn+I4CLuSpE_RaGu11={uhB; zir_NTlRzdOchT;-3^cn^|1EV4s7*r{IAqBKUx?=?Y)HgZvAPe$Yvak?7sv2c0b76+ zWZYYyMc1)R0q|p6yp63S$?J>AOrrs(DDI`w{u#_bsHz#`0hPTRk_~504uN)s6)+)$ zJ~&jg;xvZutR>GLUk(hFy)xwD%_LtyKd`EEyoK8yDO}m+*ee%~zD^A65f6vO*qS*4 zhlh6H9eR{Z;QwWNMf#WmGp(&K-15?CAK6t-Sje+APW~8x*D{yPRQ_r8fF~q9?CU7F zoOFC0*fpdKx@9}YJCp#hu99xVQxk0p08{1KReHfPi)MRm;;&0;GnPQZ0T9?jEwKHeQd8((1)-HYS^b& z?5v!+K;{4K2=irFXLA+!_}KaIe~6|T@sFD3nVK^|J8U9r7eOKB`ufL!MV2<`HmSe$ zN~4hJTG0|lXt)vgaqE>C>i|jPP&g~`8ZnuF9of(6_cpB^;g5y$O@ zrMUJ_S7V^l65;k>xRR6pcfVb0tea--Zb3hGgm>5FmaJ*(A$zVu7o)*4 zr2gSIZO*glLmkbz%~zwu-|ojhMR%udSW;B?c9$;p5_FLH;i1tvH{#0P%2Xe^N*h#f zNF#?GgzkQd^E%jBFpU)%?ze;UIR>pR&{HFB_uPB9R+DGOE2(4jjboVb2xyPTC`{q5 zd3?)Kk(_&cpAFP8x+~sH%~HAZ{3-#zilpF!d%`e%L-sQRX{#qp~8#5 z7h_nKm;NCgugj8wbt>Bat13{l6KhYOH{d9t9)fz5=Xdw;XE&Qe#TxJh;E}ZM-)Lr~ zccQ&yLuz&N4_sC5fY^ioSdy8FEmTeHSpF%yl_v;?)l)P+!iV`P^9A}*xec#mDadL0 zK*_2TGa0zHDku8*okSz?$Mi7usuX2tdHnF9ig7V8Npfuq&?JR8I==c69%&4wpCFe@ zp^k7dDGk28})G05uZut(?otg5jIm8VcXcQINnx-#DY z?T6Iu_=IJF9{$rBt9PiRcd0yc;H7fE$2cHH8OpX*gzQh|EF+_B`mZ(!IBd1cyNuk| z{f3Tbp+i2qq4a-i?*(2Q)(~9+v>xDr14w6hDv16my+d*06F)OC%p6dL`87PtEua$* zD_PVs0ytyWukm78G>*oJsBh_1OxL*62ZWbK)YuzKuEjm%ic^r97IN{FxS@ng8M`>{ zJ>oh&_Ugkr!JUv)`+~A;odtMPfg{1rVqH5IB}b2pU@b8$U&Mr0PUC5|gZB+XW&PhS zL~t)SAHer-*#fqQ>QfkL9Piwl&4}d&8M7cLM680bw0S_4$ z#p-gi4AduEJKsw;{d#NbJRzrQjiMX5?a;-(298tAe`%NK&j)ivhu%8rVVhT|XvKDn zyoS;{462YDNj_aPE&_!RdmM=)a|1Gew4#)k(qF3hb4a`yBB#uMn!@<&up0H}u=@14 z7g9K-%EUw9mOCoo2K6R*@O+Y4I+x{jPoG{K6|J_%@0GW@+m?S6Q925)}l8~>+SnF_8(?Y z9{*T8_>VNR?JogZ)-459OXtqYrU@2_9cnSsKgDq7g@7NG2mC-O->wH|*~vIbb~f08 zsPV6k+5moTL^GYNOmw%q4u1Tvqvo_Xta9@BTO>=U{~ ztS$t+aZA zU1X>2DxFkVp6I}hkXGg5WU}J=ve7J;iz}-~;mg0L3Dfs6nI~w*YHKvDse>5>G82ab zM3BxQ3g(wLz>^Fq+q^&GuI9B~%_bTvHNZ?DaZ-hg|LbGq-6wzEPVP!$mtQ~>PvWW} z7WC-zkv2Mx+;e6+ccENZ(dIZ(>V($N0dE`Mj!l<0&)58DD-PaVD!cuX8i?uX-#u85 z-pn%mg%#AmOx{LXjmz5whdwZ* z+7l4DQSdko(`_(n)7H9FCGR-!Re_z<2xZam5rMMH-odc zu2+A0)Q0E15w#KD8N>dnb`;{j=U)PJ&=Z!CYmZK?-DNJgvk!qG;8ta5!uAEYRT2Lx z^$JI+eXEkTPYr^xnustIv~`$>Ev}GyJPw?=<3F4t5jVw@s}N6?O08IA^1mdo5Y?lfo;Ew3_qvm!?9*=HoKQzK81Bt2v4{PlH(36 zZ-^}|UZ~Q{j45p$J^s045i`GE8v20dvb-&H#ig$i=k;|@9YCCHo${Y$({Ll$i7$(d zj^>pyD8T%hSyI|0p2lBhRfo5Va?n`ei`}!S+YmZxa{J-Kd2EwH1#6Yp%zQ68ewZVt zb#Bv7Bhc->FxQ9oDV+5b_^L-)oTdXL;?MiN+=B=W_mKq1VCZ=%U@Y`m^?EWfzyALa zvN_o3*f9NVD993ps(OJTH1jW~b+6!`r}g8p-zdK*FMzVr2zzF$f+fVFYE;MF_G!}^ z_1xx%QgJ~HnOa$KzSm{>;7@7aenx7v{0-`%Zd)IW>0q54_u#-rh&wCCl?c58Mh5CG z2BJQ%aS5jFKX%Q1YnbkD8*FyG#O#-K>%k82(oQigd``}1Nn{Wooxc`qCD0$TqoyS- z6&#b(2Nu1wz;bAh--e@F+7w!t4B=iA#ujMsI@&2aWL@(>W3&R_6s{`OKS9B&A$AsMxZz>w0pamNB zD&`DJf)~vVO`600>S+Wzh>U(W?lfm+gY?nIhKIK=5>F0zG$L-WytwwLj10eT{^t<) zv#|;9je!mSW3e(BcZl&{V&(sQu`&TyzPuC7?$uyPU~#<|&R-Uf_5yz{9yil76o7h+ z->MIqaoMShx$uKOOn$Af4-U|M5&RBk5;T@1RKF}ZNUICVCc zdaLP#S>Jth5FSsvin-}W2~8@EaiVE^2n{chIPDA=NLEAbj=K4h7e!Tla-#MdOt^P( z^G!)7)D4KU^)W^jwZ93#KM3TuV5tq;J8ga=?+ zw08F~xatW<5IM9C1B;tgXil)N!|(!CyB5#{sND-aN}9%J9GM$TQBqu;vyRPJS&gqF z3Zesj?O}&qA}z)Vd_-@~Pb&5kG84GvxA}JYq$u-4XjE>fHb>&n*!!`vNT%7tBCl#~ zk0Tv8n^wq`KD4MHJ}3++jt(!@Yr3T)EK=c!cGvOBE9|kG-9J zsKYgU`XFb)C@csjVJ-r9HN4po14S7U{jt%Quhq?o#SPvgZFsok zy2|aaE~3~qOib+6ZwV!3@n#BWqeIIBWi)e4X_@EO1Uq&S&h--Nw0#o7=*-=@G#yhwGqwPRIfv^|7V3kU6wEwng=-JXfFSP*P8ZUtum)K{=qq$ zJFtEzz&Rk0x4>?Z!Wyl(i)@x`G0_jr(~hI6mOrQAbBEUYASF+ifsQSlK#Rm7Mu=RmG)@Cw@%%7%=0AP<2)W0zCe6*qB z!qmbDt3Bz!xJJNO^op$IgZfi?=Garw(i~)j@cbhuq4im z-k;-s3>p+eK_h(0q>*$5uSQ}sGQ|>GM+~OSewdTua9ZBH1>|-3KGjC88cz|{S9}7< zb9xO*XVWVe6&#*&!eHLp!K4!(C!EnXavt@G)n16`-$`m7{douu3&Q<}8moH13X8GC z$OR;Du4(8}gajvyfr7V^b>Dr!yOmsfP*t4#Yzba-QST~8d~D@wow1Xy=iK3WrnX;9 zmHo?!>$@P!T0AiMjO>#h6FWkA2~jtO9`a>PEc|n3D%fauB{LQZC35-EOA#tS%U>}( z`#&+fTQ2~%FqZM2!fT~-db<;Kl&39x@z={uyG7quMYpI+0)YWuJN}7!*498l)}3XO zqK8H$s?Zx(hnBQ4R%5_M*BkAJ7q4^oZ99AMpztAZ+b<;5&G+!e=UO{JRgHoJzo>&F z`&KW=A%+z&K31yx4$qy=EyLYc6r1jO`rh#1I!2Kj*H)^0ENon5-#c-kbpRYb9#-Ek z{S6VWa;H%9OlupR;F=>4;}rlMSQk6<9-t6o0O6+j%8KjxvE0kh2{vU014b+#5VH}j z5`nCHiIc>1Br2MxQ!j3fIuZ~xQ_QE~ex54Y&s<+ks>?YDc1=}o48B3MC#RdMo=LF6Itg0X)UUk zP2sN-i@1oX{A{?7V+;<*)naF^Cie0YFd68Z@Y32C69wQ3v80#w|8S+<^aFl> z%_*s2f^9BcfxV2|?v*UEyI~h|ESvAW6^64e6kZ&Cp=$0O>kQx8cu@f;PPY^VC> zp`)x`IsJ!F?xe2w{b(oE?DV+P>!@L&zDIobufd?0SFoNOe&2GkX~J8;8C=`USN3u(3QrQ z6gqz|oPJ-<_i>Y{qSbo!^pOh}v(D>;^NO%|u1XmDiHGsW(;fnG zJL?7x0u`}E(->v}{Wb#|Ep&KXQ-1wh}bh=O1tG zY&OQvU!mYMe5CUKWDuHgN9w;o=zj#EnSoy6r2VJw^u5#^`n6Rt=@0L~_$~S>%xUv5 z;MA%wTnO^lVTIzK!-~mqVZvI&0=owftm;f4%L_XgHe=TOb#npJB1S(+Y7SN3Dn%>Q zRfNY+T+UmrvKcgnXKSjPi(kIlg#4ukcbx5`-p_k58JbF_3j)!{_l&%h{y=I(uWwnW zjm3vuPP&^@t*jHF-WRN=*BWgmZ9Nl^Gae(_XK~}lo^FMtR0~gs%?;rl7k3232H!Yh zFXT3os6oGgyq2Nxx_=)Vf&0xuGv#*Axvz*blcvb4PKKf#W!w0Mmwtyz|BHnFzlntI zq}QqVQ-9YxKqeG$^3<26m^E5C?HaC#B2ahPI7%x~G=L*m)9z!4S5p2Wt&ZDAh zLuro}UmK)eFu5uYgvZBfT2I|(p8cU=EXe!BDFyJ4iZEQmF)Yy~Qt-mV!!}MQ*g6_p z@YTZ5h1;XjZQlmdeIragiYGLiLbWYcroK6y6RtOG3f4<%zdu{*Pxk-NQ zUze~cNYyY#WkOEA!gDkyz>{SwHRr*bG}NS7>;R8YKCHppo=w4iGN%K?lgeERB5`di z*@Xiw#9tWd+W~OW_ool4k$aifofZU?eE;SE*Gr@%2!bUbmE3#=?NCq{T z-`a55@4TGu>@OiyRy}0*no!6M0p*z%L#kux4sV7kJ|XdDU}GKd8;3@a!;)q^N1!La z3mus1IGbGY zo9Hovy>P2ix6{hPJkBC9Y$MLOQ^Mr#U0EBq}-mBTYj#ZvCDXE-w-P^V4T3YF8H2Tdmq?z+ckG}4CD*XXdxo3Qf)VZSl zK)~zb$b+)JYrZ~5BduPO=H?PJ36Zw8r!&}Z1||$Ya^x&89UCab!jN@LWu#G?zCcy`-sC5N({y=M?90zp4MLa9x*nf9_x8b0 zeXCI5ZFj{unugBeiX&cQLrK5&&HGu%o|H$WDisxT@ebwM_2VmN~*)w|aqg9y{t`e>97Sr>lvw=*oB zB$%E{Mt+=5r%A!f+nKrySPPK~_-K>@MJ!FUBm8Kj3l{nAFIg&NNuY#+*P7>(GLZr) zRG~5hbJB+9i*58{9CEJ;@9bXuxsumW(B2All*M$}O}6MeE5+E<^XOgaUBvE+Ft#%k zF?E=Ggm+_W(e_n8zYQ709Qt@GG74_an<<*46c{zClvj7IiZeGhtCN}TX7}WsCahH= z#Lb@xb~v!K#kZ8#LwX{FP5l$Vc|nhl2ux^uh8W{x%&h8!rbW|wr1c*ALT~d`q#Bi? z;zgx2q5B2bCKvgZqD8~Dov5w^q?BTQQBr*Lmz|Q((P&*yoY(LVu2wxZdea-2{wSM7 zQ_idKD~rw-Vi zoA$+77z=%oN^z)5@sBGU&NaU@p{wC-IJV9AGjSnILSFVhAnnbA9sI7+GDJ}uJ7!3UmFciP&k#FEBRy`q z))Dp+%0{!XDp#x;fgxfz+UD9Syb(PSOVjQaPghX!x(3|l^0(G}x$=vpVm7!Gs5Nap zax2{_17k_-Ty5rh_iX`tAMTsyM2c)VTWtPfofYpkwDjBD+`(EgR9wsh>4*$-_@x9MMlp=$+__aiN8knIzN)#!HjqH1)eoiiTTe?=kN@69x+cDn~_Q-SfpUOM$^s&Qpg$2<_t}mG2N~zEQ?! zIC`d~J=#v~qhhkmxm#*G?T*~B|K$5|rr_|6fCt|`cHTQz_by#%-@Z%tHk{rczuw_f z%EyZ-b&}iJFJ9M4vd4|?aj$W&9Jmw~lNiN*V3(#u_MTp@cf(Jc)6VvMCHbKi82;Du zdP0$_kB92rD713~zw8PUZP;F6_!eOdAOwm@3um%xYStBY&}}m%bBtMOrpe#&-!H1L z+=_qk`QL3t)I;v9mg1U`2knYr+W3`jg|$=dxA?iXsI!{_9yS9jFex^LWjAn4P|;_? z%s`_)CQRge-CbCo2(Ci~4&1=x&bk{@m~uT^kO^I3PkdKX5}ZFq&tj)Yfdcw{1UOlo%{TRdaI}D8Kndcn zgSK(x^500nU_OEQoSg-3#JY?oaZV*38@1nc{9$L6*M(e!JpR|3=PiU8ZW4}n4ZK^l z4(QJ}i?Zqw|NpvKnkkomSuOWx5jkvXBNCKy`tk?rfsbTm5;$dO<~YK8A=2-!^XuR( ze{2eU!O_S{ZY03M+_AR7^3`YX?gLk9 z(oX}?%~%#3{!5iW-B63%1t`mSCDvb(^lDiofkqidkvfB!!Qe5yPr#_ zuOHLgr|S;aK2*!gA^z>U=}v<>V1Jy)dX)^zNR!zsTE{BY$$_89mkd4Y?-%Y-{9n~g zQ$~^`+Di}p>$+(fWfeiN(INH`;utuXz-Ozy4v1gfQW=tfrili>>R5a&rURCLgA?K> z4x1)~CAZ^q0VP0>KbNytk0SZ;LQn51SJbgn4|sUi1BE(3`}g!syX0iBu=E-2n*$G< z5wi;0O8OZDyXRjg2%Tr`zP)2j-x>Lioe@eKmo1MgrUsx>+|v4Y*D1+n!!*-JP(E!m z_zH)-Vx`xs9)r{HlcQaw5MKi^4o+~FJm%_Z4vYwJ2xA5Q@!CEqy$4-GYi@}d=RtE9gKdS3?odBI|A#e0y#uUfPW)aavhw@;XnK`#^N^icg+~~>B9msiI<-b0{(f)-cE}Ip<#QlcX^LXzG;kZX+8D~lREjGW!HW5 zpcH=G_9WC*0;i}KUykC#9uw$9eUe<@Y1yo9*%{G<*h>m!Cyre41 z9>eNFFNNb-w*Cxyr=a4?_yK5SU(}6+N&&Tn5{>#f4W58|Tg!%CTc&kPNRm)TMezC8 zBm+g&q-hN02FCnQ55LFI+w*eLi>fN6XKvPpEtlP>n2@7+veFzFp^K6GsKpDp->9>bh&I#$^cHZcstouEl6!aMz0 z`4#Y>2Aoj+$(m0^XrG#q30*|g_F-9u!z}&XaI;=Y!id)6=&7M!S4V*uy-wdBx|w73 z%-dWIf79R6=@(WRNI&0m@b%A{JR`LQTv`s9=_mg-Ra4V>YBvlcSY(O=t9T!G+>Qq>4x?BUrz>q~kd+VZl2&@u#x?ZSQkO#uRJ+ANJletjTp<*B%Oj z4NyT*L81d8VgZp}LR1t~gb1hz2muuV5rTk}P+kEQrA0+SDT#nmq)Cwu0g)z1q)QDD zYN#OzBq4dT-!a#k9BYm_*WT;f`}@|O-`?wwzx?I#V`R`@ zPx@+wDIrO>dCLnn91hiwkAe!Cs~x!rP_86qZo?|KkT@O9H|3qL5tdy$3i}DO!95_W zy*ug8)NI|8V>tb|_VbwY{klkZX&I6eQyOa>dS@>(y% zX~vche45HiSTLOa>SHpwUwwEr51-rHx#p=E>=Hmb`n&JWl>yC|^+qr|WRcTGWWqrf zis<}j^M(C|_2oS~n80^MudX6lv-m*7>LsLBZ2>b}!;&&gDZQoD{#nZ>aLVwsy-WmumlosB ziD*L>0Uu!lrpJVBK3@mye|RVGk68EKp}0`}*@gabuULm(rLEl(8eCj8Ajj|M+ADpO zRcN8SDXc&XSW(h@XMELZvT?zQ5!TA?Iw0%1(m+791$g}}r`jeN8QKa@QFsNVyX#up zq5K>dG2JNf)l!O`R&DS!haE>lvt0Ud^xDeWKB6`E3{cFfYu-#*h)|Bw_>_4J_|zz_ zk;{qLJGJBNLGRE0C+inZPuPod?Qzq3{9}@;`RDylEc>ZjDOT)+ zvfr(ifa@xup(}L0wlvT716Z&@!8Q889SyVXDuh2ieoymiDf`%T(1o!xWA6cGc$0<- z8<)7viVZQT4gYbPn=i#vKzGs5Y^4U`IPhVo?V6A6{7Vn68^bXaxw^RbIkJ2Z_X+99 zli|@JrW<*wQRa}O_FH?dNmrl3LqD#i>xl2?**W=#Z9P^Zai7<^(F|c zWyZ~Znj+vA1(*bsMgUh};=(@gKuk z%O0Iy+0FGkH!<|>4Ic}*OysT7dxokX!VAVoQnv*fRji*bQt8oX?`8w{pewz^(3J;< znPKYo7Osuxw^MQ4h<)HwqB@HWmKm{U5ya z-K;&jg|vlmi9h40vcK$o$6MvyH)RD(Lz7VTV2-jE*QO5Mh)JvBzq}a`QED>tUAFOk zQ`V*2$|KR}N#cmg?D>He=8(N$mabAQQd4C6w6tHpoYbY~|DVvTANsweDC(#H9?RKK zVb^%K!>BWR2z&vOG|b| z797LJ)qOFRnTDk5fdLCi;2dpgV#{jo1af$?%Kd_WRu>sB`V7IV z4H}#yOE{s|e3IcxDFA_h%yIm-?=-2AsQnmvNMfMJI#ad){E3w(B&);`eqbLl9W9kO zahSYCCj8s{?Wn@x_=SGc!C4$fHJRs|%@#WbLZq3*Vg2qwLB2ZILdjQkvjKLHjj=RW!BM&1kKJF9vT!-vqV%SPhKkP2QgC+>M zSKr^#c6%gt-~~q?%8Ve&vWWZDX-YI=v$emf)_8~J(pl#C1Kwz%(9ux|qThI-(8gtT zbQ%7p{HP7@x&Edhjn3JO4a7>B4D7D)ZU`IQ`7wWpxKo#u%Z7I@p5TYEkI!D?=RzVu z8=3`n*Yrc;lsQ$boA?Ik5uYSf5By=5d%R3t#d=tfi#&@q5D(Es7JF5CS#bea#1`#c zPVQ!|18vNI&3BXj2l;N&zn|~k`X9-6SJc3TCgFulizQ;~>oUE1e(d;!g1K+}k8XUX z9upH(`k$5WR{8hx-O99FpTK1}$R(^ny_=Fh4>o?SJ1#KipkE(`{|mX|F-?AG5vs^bC&YvdV zf9}juI^h>WEIxu+QrI$_0(c_id{F}fFE}x~nrfeh-F+ZUEeTLxE6IV4vp&8ZtOl$h z?<@fV*RA<{b~r;yol^bZI%Rl75@KmP`tw zNeZ#A*2eDKpmRwHzBGZaS}DHubn1&`Oy!r}-Z+iCb30yItSt96cuff!MrLrHz1`q? zlQcYXCoL*e-9Vk&d^tf~@0Poq5H$_+1AS=rP@Gb4+{jNC9k|1|EmHZH)b;^qNE4Kh zq`^kfmyV4hH`bXrQ|4b0hkp#v)3N=&S?s)4!Phh?>Eesr=IziiWj^7XSIrsL^S^h$ zhOl)1cZ9wLOzNQ|pwz{#nEIoyY-aAS>Lza`S?Fne5S#i|r?w=KH12DduyexSFg!Yr z+isl|Nqd4@?za)O}ZoI3f_Q_s8k?TOA!FnO~EqG*0AFTy_M3aOfh06XuOG!lN) z8G+7Mjr4xxTtw&nh&aK&>z5L+){zp97@%I9B$A1JtuQT@@|XG#gu=X8sbzsisD;_Q zP4^{KD%|NYNE!bbhCkg%UWDCFLpeJ86Tz-70r&;;@{r;Q+BP2!%?Ke*K<0Gnf6$f$t5W&|Z)B zD3*M|pX2RFHaeO+pZKbw5Z{D@K`?y6u!GL0FeBd1A`DW`a&TdN4E^+LZ@`En_#Mry zRSG1L{?tc*N;|S%X%HAyL9-oTd>$--or7r*v~l-0t9JX$T*z23Zxc+zUii7`4>)!k zM}@gsl)e&Bqs{846PKOyGGf*Euj3N3eF~2EhCcjU4m6`$xC$Fem%?}po!YE#M>^l< ze0Wa$-uC0rDbFmd^ew{i$KaK~AtI`H01hh9^2nt|j}NLz6l%nALnw{=0u9yC@ios)hc)|+5RU%W2V5u74EV!F zSH6edd=&)WPXVds^~9T_{l$5&`DQ3V{!M^6}l_%flO7GIZZPWTBf}izA zBrj5FfYlg8e0sERZN~>(0*oUx8y&kc_8ezuehE zEKdo*qi^Cy|3m5aqT~h{zI2vZJP$zXf z5NV43+^S-O>XqwRHZbwNtu?ClY{$@3KsCR{pSw7|bnk^Rw4=2%WYZYillCj4GMn-G zdV*=k-Or}w-%Xf$2o$7(fuZSO4mT$1Gg=gOkib5+q1)d6yMOwvrg7SrV;d^y6S zpTwL0nuDJ!y8S>FnF7z}u+IEVN=ZXdk2L_M!#GX2s`+htls{E_8|dq7Yz@I6+AKd9 z#a$pvV9IqdcB{rxsM;!_JwMa%`kJ)`yX-VB4MZC8G+nD~s-86^1T3e0JH)cvI^8MX z;!>DBmiKQ-*=GMCQnt!}my}KZp}yP-7)*&!BNSD(8SGraWWpHqJp2iDRx>h+kj&OU za>Vdv^b4-%GpA1C$DoWRJ!i_)j;{uQ#6K%1TX|AJp;?{u?(r{NzdCY1*xdkAu8Fi* z(->e0M0RZhP50b^(A`fBqU9j3=-JsVPb04DK~-d^ih+snjw1$@IA z^c9u@g%>3oJST94t~n^E)zPdVWP_Y!Hn4Mw_3|9CdR8bQJ^lv>t{SZa$>wnR=7{I}ZY6HeQ~w1%&z?Jb4+| zjm!xl)C?&cc<;A&&z1xHv3OocfMPS87~n13zb>clr2euw=A;ohtr zcG+YqT4p|UO?y8%=#r4_ic%DW&CWR+Y3?)Ksjm$>+xBoXtp%9yJlN9_^R+nUhps$k z`Vxr~3JF1cIMC|-6Sq+8tx)v{IookRIFFV86h>InKq%?mw*yUM2iV(pPLf-mPonuI z)=1wmv0Y{kY}UDSph`t61{7@0?C%|C& z5)m*stwIDeH4a_lieDVv8+ovE$l-UZuGE?6-xUQ)MNEj>)e%oUzCMCIVhdb!pS-`6 zF2WE2etk$t@_mK8Gx$iwkTzw*JPNL2_x^>Mt-IY$>Hv@y-X8x1_Z{9Gss(2?qe4bTi&L|V!xW+EdbsjVKS%fiLU_d`=@8b zXed(;AM7jR(m;g4MMd_p%)wsR7_zf0=JrXur*N&g**9{}>pT-bdj-z`7c20;`uPnB<4UGahBM=PBnOXRQe;we=k)MF415=TM#CQA+6ks#& zWncX^Xx7pTv30NUL-Iiv@aLGzZC)={v`Hc#FfbSfVh zCCsj};zos-4@)OXES8nhnRgHuxog>No>5v;0|_&VO1+#NMIp%i)fr?c2 zVhN>z;4?P4iCk%)UuiR7i@(2w{@`f@)~D>Be_&Qp;`819#JI{WbA*^)o8j~pd>xH7 z@0`0h4rCAKMpg7_m8H>$bpYKvKy4^$XtYmsssgl`XaGpJQ70GN|Gg6i)4rt8nyzk$_Hvle`W9G@_>^8@$$*=KY(;gXqfcVBwhp`W+{$dc*P$%6K`4~r+jkF42mXy&5s z5n)bTdFp0w310HTjuwq>;uFBiIF}RW_AD9k5;?O4(pak)eAe*&0mI!gDpv8-+5K-MFc;uX5l6G2aR^;!XJy5Xl+$TMQDBEb z?h*ZVhpIXP+N`fMXgYFFzu9(_0fQM1Jc`-JzMyaF(P0*NN>MB2w}ALLFH4-kN&cIM!rqtRpeIJb(#HyX zsB~{ksknezRdTz*Bdt9;U|fhJ2iX61V>yqh0)srqH+y(c{l2NQVpPDn$eNpc0P07= zhsRMpvg!xr;J|$2cj7duKyLs`;i2_y_UQ-WX2-P8T5x%6ycXEuWo6Nx+eA zJjV$w5$8doW<^)fVbF7yTaITOcETX60^82KVZ{s`-xPKfe6(NMYR#g{^VC5ZxsxHb zC;b&VVi3UmuNk&Q<4y);58o5<8RGCxJw+DjlMHpdi&-#T@FoAImIRau-`ER1h0Q~J z3S{I2%(N{J_M$0SON}>LL#veaX;Up?%n{#F=H+g2=Mk+-8~v6!XA!GP$KibgDq{vH z(WQm8U)tfIb~Xx!2g zquoD)MWNjEw&?co?Y&^aR7f2r(6!!aBa;CfK*90X$h;)}lRt0Ol?2y+3nsqK0b{E{ zbU1N^*DG_^tL>)FyD9yqZAr}Zm?`Hqn69At_s&(jDMas7=@5M?lz!*mfVJ(wM2pMs zeB0^im`u2m`0R!XH^cWkMOlebHd3F)E^=%#ZI@p%b-10yY(rMdj*(6L#4VL0V*dB( zVjE=JMS+u(Y87`Rb?hhP$@OjMeHI^p&G)}UUSx^jpvuw%%^ns(pei*Td=hDV@@yt2 zMn;=v;xEfo8jvo)j|V*l18cFbDAg*!FW(;=&xzd-l-y&HOufiIF@)3YI%9j7zl#8U z5V;2UbmCIqGN4c)?$(?VR{;}{5eW@e%~0;C<(KKu+-V7E40qNWlfOozV2=gCkh#n| z61`vZyJGb8k^~)13T7Blkd2(vz?gG}P}^z`yTAjPnMMKF4%iK`F4o}fOr(DNia&2( z$DM&F{`ml(KN|6QwM89-JMj+iL$D&{56yd$9$!^z0LJ*L;cd**e_Xf+BvM$qP5gby zf#A!;ngjfUd?(K61>8MIWd2%4oAeGw>u@zd zs|sF73C3q#Xv*QTSAQt+XMkBae}>E^v;LM@`IMGo_g9kOY_JBAk-x~zA%O8pQ|>M4 zyZ5`DsC>o1S8H~@yomH!pU zUc7|*|6?G#pOS;&&4~q$H|jA?@I(LZ!rrldVfSbbb0%@XDu&NkBU`I)u+;$y-)xP{ z4rT|Xi(l^64>>Z2h&~o8E|TEc>oY90PbD@+L^9Rwm99#)Q|RxTR(F4DB~TBYDWdT2 zBqh}ba#J56pMXzB=y#$wIbu|~G;2wiDM4KG_HX>wso&toO9LdiM%jZRfDM_h^im(y zGv@o4KU4N=0?_t*c14w&ZfXee>pC+++XJ;UixzT?O&l$~dA|=4T|kJK_zG~ow_S8M zw=e5$h<;xpa!r!ZDt}a!e%nWtqdyryjee=_Pa(k_^|Z&0_$G0fG4eF&G#v%z{v@24 z6mOTf2nfa7PdZ^(w?P@k?X9EPQ32*?*}5KX3rmTsHs8p$8y=Y>p8($@t+}Ij9zR&E ze>7vE`fvip^c`!s2JECrpWXaT)LSg=?axQdnh|l~j_RPXm;{N?HD5(xM6$R>n*Rq* zBFW9zSmbV28gRb!$l8h#@|L-n?;$7r=)&IVAgzNB_jqulkNuQ77xM?A{QdV&w$sfu zBWGACj23pmhRYHV7vT*(_D&XHe+YS=@NZNq&?7x1BO9=mtY=p+0MUlqOu zQJbc?ptJPiQ<|HnW`vU}H>P59BXL{|867)CybL=luH4%#2e`t7M(?$LeCetfUm@0+U_KNhTGX8Vzywrw0sBf_>tih z1E400ZNGtv=UfM_hO?o{nA?Pxm&uxk1t+yD)~)yVUIBgw@y?s{8KV^?Sa*ANL&yBx z&-j|R${hn9x zao<~Z?*^NUVR{}c?0x|EXXWga z`=$T)=CoC3E_M@I+$>m74VIk}&HoN4gK~V?sHJ`){T}W$#U~Xh#VrFGFL2u@g0Awk zpdkcW(m#g3o7@XUYVR*8aa7naXuI|^Cx)K_O!<&#gxPd)_lz#%JxmcV~43))?0K3j1wO~yp1n8*gzbEP~=@WPef??u|x_WBVooA z)H%yse1By~O7C8Q8S}x9E}pwS=xLklg02VJTAVkcm+TSAGZBkd-dB$TUHB8}tY=Mr zGbic=+p^&S>XJ-Md~O2gjjsDP#l$b)u{Ul7&q`g-21S7Oc8kDcaP8HgS^}=^`Lobo zfvkZq6lu~uztU{UWhIHFQw>?&dvWefC2`z@iSe6p>LsDZfi^+Z5(~znC|`CD)}xMS zqeqZrm;i39bb8QHK+{E$J|(ud0PGrA)xW%`&{ILh;rUsM7D9Y8pQUX*-sGQ|#PxgK z*0;Apj~#>LI97wRVD#Vp4_{JijC zvH-DMK)b1BC+Dzw!Tz+x#wmvnS~jjNoOh|`gCBnm+e=j;>^u4PW=Qj$V^pJZyGc@T zxND%FCeS`Xy-3RHLXX4FULi}CP1Iuw?sN<}bI(2o% z2Ss>o16m-6&iK+zJd3)@|HP5V_HBVtbP zi0b(ES#(2BfJ`oWC`b-bHi}DINN^f!O|#a@re*>yg3T@Z3*>U`=Cmsw@7%KGGl9-2 z?UruG3})-l{2Z2Db}E@XY_p2(7^;e3UT%TLy|UCyODSGyLHj+VD_iUyf<7{TR-+2D zBnc$tY^c{zVzp~%4zKdo51)ZA$vmOvd-ywBkmB(<##2aGK4$oLdX%p$&9zMyt z>}WJB+s5>IseEd+(qnE?q_SymvS0Uqh|8^;(&2`#B^X{EHonQuTP?W`Vv(4kd265F zkAaoS>gSNJ{HpUvIzfGMQnl(aTDASyEtsD>AkEXJ3PB zbbzMyHm2ZHUb&u#|0DpOJhfG^m8;_XqC=$2wfUOV^j=+$v*=GayRgxhDhV~avzL=` z6sLYcYU59uj|db$e76D`deBacX@5M1lMeko?`YX_ie}I|eh4XB(siKMCv0c-a-|@D zMD^r*&vECt`$y!0V)|o6(`zg@B)*1TRoc1c(7kSWbIB1yisv60#;XAtQ>AUv8lPIZ zv#g)-*;y3*YY8rTOQ_qE$hD-zlhS1xP22<0Fzjo=nmc>MMg`^Gbgb5*PcXQR;h!>Al$BMOE%; zA6#JwuRSOP%-;vjlb_%#pMilvU=e<&<8KHUpSnYj16Fkt%DQk(9R1mM0Z-d*2C2_( z=pi^%O+%u+>R!T*5}aBa)}`FV@IfAu+WB~el0S*eX3_Hk+_7TUJjJ;KOX#YR_Qzrb z?s`G8f24}Id>fdD2aOy9nEby#=Ys3!d|M?K?-R&atL9Dk5P5b3_XH;T4cunKdBX{j*!e4r@%{Xxz3~h| z7HZ??cR?sf-L?Pq5Tf$mAi9GtU|(%66t)Wk3TDa6=&l%iEBKMJr2zl>biLQ$Z!qnH z%&GyRUwGpAU;zmMqlI{b6wLw|A7tfj#3jd;ce{Bt<--kOI0CK6rK3Sp0#f2jS;R^~87 z%AM5)3zhJAEjnfZbkH-5e9Cw57#K&%BgT;_Q0KN}W%n{>Eq@f%xZ8D!fJ|Qsa{$ie zC~*nOn!xR=Vt2++5Vq^wh)*zTdn@YhY~Bd)PQf!UoPVOZ#XN0EH6aUO9!Mo~-H-W7 zlwVuQGko6#+O#Are?LX`xM8a0@>>@i#x`S}TbWX#()K19=;=>iEYm%}AK|X*OIwPU z!GihYg&AZDDUB=#?47^0VnuUKPxZ3uqIb=Dzbq^MhQwiap1T|%!_&04$)iN%Io@)x z=>bwtG&d)dDCv~wtUskimfjFKd>(`m5f19k<7WK%Ns%YB9-Hc>^`Y7IFy1i6pM3y* z@@cE)zGi{rGM}zArB{KDXNEa|bmH5$+m48o-f0l@z4GzA{CVN56jg$y)9HJa#GEa zyLHT3C&y!C6~zhEpLJ1WSH%2d1myS|KURE!yrkrRca@a|M=S8hOIuKTz-F2?e)~uG zN16M`EJ)X^y36j~f(&q>4{`N!#t52IVznH7o`2Wqavk8@EYAIM-Y*n&acK`PVOF8m zzkm2?7vc43QFUF_2+9@WL}4G%m3OdFseT-?mQzuq{6uU4nHYLvTRcEp^5Uo*j5YD~ zO&N`;-ZUIiBfcdA-%&~8_-#KkN?2Q!rc38!aMrH<1CLHheh^$f zZGAvy_z{Ib&NU<7=s$8jR)2^60R-$H(z;Q_T$1ztSqt@`{@pb9 z7_2i%Tv|DWDtk+)=mEk%H0GVUX#d{6CAf-fKkHfTo4pwc)oQ?#?68~FH_;*bdGm>{ zU;6XD*UJtl&;O^v#E@I!^+ylk# zJv9@ap`5YLoAkQu;vs{J(`9M1|=IySz6O-uUJDp~Ba4RlDA5lji2b>n2%2pEX)@Lq`D;-!n5B%=X zYXtrzz7(6h!d;y0%g1p$Yo(u~v?KMG$us1+U&L8-(##1+kT$MHNP)aAE5)F$T2mDM z_4XUvlWnMCS}TS45!Td}#Z3&Q6^am~grY=?O?Xc3cBunuGBx7?583C~f*a=xjwQ|G z;a5l5->053MiYHYh43jc(u+0vSRnZix{Ujch5? z_7M;*ei7Z5^;AX6I&A)or&RCM#GwfzQsmfILaKbQ80>z2GrupcgzG8q+9i!`YgF7< z=ukdVckVl@_fTvZpnO?^+E+qs1cv1x7Xp3h6|lei70T14qt}IgtA%KZKSHi9%D6=; z#=c@Nu42^bhHdd~<5v=ElMjGSZsd-bHIB;$srv1CDh*G#Q{X&PxOLtdyX=d=8=r=i z4$`MaGuI^9OY>hA8gn?hyfKzoVn5Z(f&*DRKa_XGBym2$w}H1#mvAkB_-g@sGHbu8 zOH&OTU+f!NKkP??hI)BP1a3QWZNY~Z@^@Fa`uf$qoAz#%xO$toSOP;YnVq{dXlz=( z_x879+h+#a6#PNf?DTA&E2HwAX5XXdq|RuwNlykdaC)N5`Non`!UIR1Ds}wG$o}8= zC%)HVJL-jH#5Je9LB^XvPCbb2{Yc8=f*zc|`J{k!V4%sKsC!?8I*(f}+o@=4sX2N- zc=1uVINC+eF7)C~m#f6c_>iG53I{C=wwWGrJ9X(}wp?p)DCe7S(vgqVhwp}s1Jg8g zWJnk8PEltcstXs7A`^`fRFaob5!WBl4q=OhU_&^k<5x{-77y^YV+3hh! zgrFod3(AC92PA;0_4u-Rw^A?^{!e3$$MXAe7Hq?U_FLHj94I(-a@vm#})NUTc} z#-F$-#KpM6DFNCWPgM!<{iI6uE(6jAo{qsMAeL;j^OrDVab(7+!KZFX>oiJ;XrsaP zgg#6eN?k}lEG;_{TDO0GchZ<>*dD_c()D}v(c%irF}kzvcom`#^~|*6`#_yM;f#rb z(`ssW%)>OdEaV}4HWXt?Kews1xE!EAa$=sNp*b``NMRxcDpdlj?7UOKyZM8}ZJ^yp zTLz{lW*$6{)tA*SUM$gY1-pxKmtEE)ju`afAIV-}>c9AcZ`vS?EvNkpqX#`UEAO*Qx2ics` z|E{edvc9d!dh)NCSbj0(qegR7r}Q_;m*Q%UA&R941+>O5tk2a|1;>r%h{Mw%^HIwW z9eI~eR8#2X%m1sXZkN;MA^!oUH|al{>8GrNdw&iXLzv!EVHE6(( z#eQCpe$Z81zcBnW#v%?VpplnR>R=;d+=+95g?tYQNFO~sDFL)K1)f8dV<(9NI2-=( zA4=eP;Z$NKU^BXWJJXHBdWs z7GZ-+FYq%F-tQ36y<_}Ez;gFq^sk>~yV=_=f2%r98yT1yFfWrf3UI>+Ukj|#)ycZ} z13jpy#72Hjyq_K+0`_|k(Bt&FlV)7hhOQBa`|)gCeAT@A)yr=D2ODX9exY>6Fq^xW zp$_CET_1mzghMUFNv%&pF0pzrY#6{21{gUQcJ|+0(IV?t^tGkTytPj#?l4Agm{BxM zU9q-RSKqzEY!LVR9?i2A(zq7bw*16i#f~w(l+p`Z&z*@okS4u{a2YK&@NBA@FF|gchMxNf8qnbSJjR@{#(4%e-FP&X=rQvGe+8eKi(v>- zKT4%Tn9c-no;?i?LC(z5dID90O6F%q8g%v9w2et_79qEl0tlbCPq7Pxvt{ z5>ygg4Y-Uj_Sa~9MGU`VNh7V4zsEk?YSk0!C;xl>&Nz!l_Q{{SRgnUiM;RD)*5#D% zFr_O^S5l~#k|eL*k$E0iZ8{{y7`iV@;yQZCFfj@5x*7i!@BXiN_y3c4_q7^`S4QTD z1Kf17swjHvzo?%6`lqeY`ff3VwvEW{1qVxb9G9~CcH~#(Ump`%qh3z&^-A*1ycNsm z?s4b#tv(ZaJ+tfnte-VyLhlo;EHuN+_tL{RNGjS&gyL8w*i)|Z72Lefvruessc3knd0&*j zXvs(X&Ayp}>RH2VNfX^n_y*4|GnD4{%PUIssXBopa~8{}Fp(p?L!iQ?1rt=kmXf^2 zBh7Mv+?zEB!R@H+sh3B0D{lFjXgU_UR}K0^M>1k zJ(yBy-vTD}mFaNvb`L_p@0_4wHkpbdKm%Y{28I!~ra?#AamA96rz(7tkx%$msJBEa zdTF<$-X|EOl&!v7n<6g~DLKw*Uw&Q+n&Eg zuKGqk(wDg>8yVM9*hM;R)CJ3cy+eh|roBlWBg``I6+r5uiUVL-5DwVqb_E?~9po>^ z_s~dS9;Pi8YLnC^6ET>yii2=>*E}zuoJN+hw-ZmHpqe<;&RrdNKq2Wopod_FKi?S6 zbyb2q$Vwe$a{ODSQ7f960|Pn}pZ6^9%g@9M!=_{zf}~Mj?uu%!&oc5lrng~eF7ak3 zi#$s7)2WVMXjoXfA4a!9`I*=g)pkqrl5k06zzx>rlF0YHG)d<~iQEKs zmTKE>D5G39hVC?W_>MYy@b;c3v$wXB#tDg+z5wE*MdGCwMG_WxcZ$YZR08*EL-Ast zn|HGg{lVSV?KTfk{P?^8{0&yiFHd}L@{*mJC34yA1TalLJ>{y(?dz7#Mhfhm1kZ!L zcKTAbCIZz40>qKN&t*U;&i3?dd>3J)YSmo6F9-XXv@){%sFY|7HXrc$Ie3r-FL5mh z%w~D|k10#mpr?2tnA9l}M?m(LYQU{;uaKB|M?~~%`VzI7MpyA%<`N0OP2E4R%d zi2dfl$i*0}SzVRmAX)cqCbD|FZDf zwsUSPT$la!$Dw~l6RQ)4L9IQdOBUF#Go`{x@LcQ&YG%;c`zb9_c=iQe`XkWdtSS2n zEaJWGRKum=QRF6U$0}xwaCg8O)ZmzR1iJ9$K?NJ#A8ls=)^u>!fjA4~0Y<3$-MQ-@ z;Sc&oX6L*S=IlC#zZ1gLIVDr43;U?Um{#!vdp82;fR#&L<9-CY`if6QX51xFY=MFY z?r2E#u-MtOP5+I7|MnbYa9sjPBsl2xrW!(d0#xtl&M7>xs#K4LgP(w@Gg?21T?fv8 zPMsEe73K|0#f$F9+947nQn>S6i>dNoBJ zymc&V*k9-FamW4hO@?mo(aVxTkL37PNIK1p)#xw;!!7;4i`*_Wnm2@C;B9%39y?^E zC$)P@`s#CJ-w!kQj4`o{+T<_5c?4Ww%ygsd^rphN-w}Vq+(z~aR6w(CH z3gJ@^zkuf{b$Rl?dc3Ma$htAce^WA^N89e`egAD1`ML6(YI90qkRoOwmehsQ7b7ud z@0jNuOwb-W@wkKVz_a4>4+7!1^RN`xC1f?8uU2I+cs%ZI%mOXWxC&c#GRW%7rRIhy z*1lHcL$@))u1b5>)SV$0u2L7h$v&#_-WNko=#+eWOK!`>x8l*i6GD*P>4F}98WCe6 z5n(@j&fK4p9THWHBV8eNCKa{)2o2CiST5)7{{GzJcVmBWVk9Xk4eB~|ORp;V)}x1H zGC`YmayP+67l#0^5^I4pdr2?~Uxcx!z=pQlhP~E2=;G%eZc}D!0^Rw%m92;^dR8Vk zUUu5Be#~cE={1(Fd1d?2TiOqH^kv~KAsMS~W@=LIDr0=IuI@GuX0ZC;J;=JFe0qId z83Ka-+*x1_$-*ykNPnjF_*Sh?QzC9$t@Xu+NWnp(x`d_R1Em%)+&^k@8d z>0&EP-L??C=~u6TeKojNg6#l|R%OK=zL0Dtew%`HNK)h>2IYu+6=f%wx_50G@LdXa zlmg9QyTk`G6gw-W5DHvW=f!wj>BVc@(&2D&BhCeicYkp|&isHw!E4{e+}94gU5mz7 zDmh zw2rL?2rSRw4g$2R(a8+vj9tD2X%c2RdWvtqWKdCE6wE7_uim?{2z##GE%*v1T*m;u zw4p>ZaL`Rp(QzDZ&b|98UioZ2Ux=X-6{h?a*&PA>2YIymmFVOJ?nk+5ZorM?yB`;! zFyTI*zOK|T0;NI@*dg8Qxbigw$&l?@7;yXCVr6AWg~LtvJ6fY0X>!t=eA2OKyW2;PuU_IVcExyo zK0h9G{6WR{rg-{YasE9ClwYCO;jmNXlzr0d3!;_~mPh)0r^Ohor9_frs`y$b71S@G zBy{!`RB>?I86|rN`X1z|A7A z>VQUn_oz2qf7FN5CN%=b2)rBuH$JcCneK(((rkP!PT7Wc88v)$aT(3V33T+m$7?*c zZ4TP8Z)-p}lA7|8T`A8M+q~2GV(6s`*t^!g|YR)0~wAR!nVZymc0K^ z?AP)K7av~my8LV8>dyg!ap;Wt^vR|P- zczePM_j60AeSPPzr~7>7HpK-*cMvndrqN-o2lJebb>Rvpvpv7Ix}TUv-;)$w5P}=D zi_gs_U~8~hK|gl1ave&9403WBfZEjm#@?GoHMM5@yDBOooo-ZAn%EK*AxbMvhzi0+ zfq4&X-q^wL|Q@mCV(Q+2BecV^nuVNKp+XpT6bAz?_E`U zpE|Yc-n#WacZ@p*9~gY%!@Jgc=bX=ce(d)5(ea0lIN`3k^XYt}Lrmv+pF$AcB8#2Y zgT(c2sKpabqeBSifU$5m>C0pl&@uuCR@a34*JpM{FeY{&(4Nr>i3(A93oKqo9_*8=tnNxnCBd zW+89z;paUBs)Gy>@>8@Iq*8f)`zS4=6aQ@jj(kspyPCSN&vG)*4mjd&&7j(990JZu z?sFV|EWGeABUgqOA#=HR9J|_RYz}XTf)LFSO}u;2E8>NjZ>5f8(R(<})9eO&c9jSr zm$VbfR05vPH?kZ2*{De1MuH7^94nt83=%L^T_5U#8hQQ*qyqrUJJ@#$&Qh&3`@)+a z&BiyVJD1Ml&=<2(mgu)ub#jKz8ZdWF72H<%ZP|G9kdhmBioEPc;Y=g=vwwJN`~J3U ztoX@>#{WQDQX=D_do}Og26!M*K95e{LS!_O7{MLexJ z?c{oi>NeX&hP&ko@>OU(SP#l+-Ie-6jRhiExnsDR`BQ8QHyu3?kd^{e+q8I#DP8wU% z7~v-m!yB1(8S!CFPPmzqKxFr~=?fz;vcQW@pHuU#1xFLLW82Rc_lb2#o$v2&*Q~!> ziTDD@yH?h?HX3_;IM`IsDNYuiTprCILj|M^p#rGSsf{%vcNUCCJPXu>R3YuxqV4xU z_VClta73)PfM507z;m@5un%~@Ci)>`?AJgy zJq|G`gp~cB5sch2q_Qh~MR-2_003up^QEajgVBMe%s}*;Wqy`z^XDzod0**W*NdhM z&yc4NI|}mpfbEu&`NG5H_-DNOwMiefyq@;`e7J#d11_3{*r|wTm|2P;!tY6oMb=}2 zY6SGP==BS%u^b@@2$Ez_i=N>hw>2jr&jQLN7YBhv%xJJSs0dYaqWR%!RX3rgH1z2( zS}5quq=Rz1Sw_*z7HoPtZ5X&XWeOLEI4dkXvx7G}M*vwD=y-t{7!1Cmp=*FlvROsK zY0XEwRzh0#I9St7b-bNqd!>c4H!rKB6+iGsm7B6HhHbLfFD_JHs=-<;c>CMS3-mB$xWr%wNP~U;pfL|#UU>)!LC_HP&7zx zT2AE;rWZAkF_*sbEZu05hs#pV&%VdtLFqs!bpXeZAXawI$Y`@Wf7QTBKkzP}mxktW zoLtJ_B$WUAnUdS;-!3!poL-&s0efJehd5D&Yfz|3&=_44E8-)S^$yEDrfse^D)q|G zaF=@Y^t0$tdfiIJ{Ut{0;r`hX)b7TK8#WzOS*7)R9-=>+lerD|D@T4ZQLwSVeOsdn zNStw=tpCIfR)!CnT{5@}T8Cf0y4(ZF1C4dTjdaW;{3ui%CM#P{(7E=?QLHwq!uIHdX~o(?!;xLkuWukj>x{VWhc9m zMN6iPSo0p}iJU284T+4+ zP!guhN?7VX61wrl{}J^9_AzF267dXQb0Nh};EGm_ygGaiThX3dNqIP&&mSF>f`fOm zL&edl^~Tw(&igc7Ul%qUR@hEyWN^|>&&X2bzqwLqSQ+V{g-*zX@*<_EXU7z!+J6qH{SinwudTDd+= z_Z5RjR8QsTUO+9Rj7CJe75T>DpOwXMH_4QW#hzss1G`IR%&h3D{=ZG%?Zce$hN`dvjuCM>i%a>#6yN{1HVeIy^~h~`e2Lie!xH;U^^lE( z(fWmZ`75Mg>GIdn=Zz~+@pal-uDG}TerFTYMyUp0Lc2#UFDuk13zil`8 zeIb}Va6aHM#o+?6*xZU!cPD=YJ!FfO-nQE#OY>UNeO$Xn4fQCIW&xEx6Cuccuebgs;&#tQu#=*O%6*=>d>q>$YAvV}ihnuBml=x1XIaHH1 zzkGQExc$E)^WL`7w(ks>1(2x9MH+EWyLwo0(+!syD}|{=e{1^H~0RzBI?O- zG#ABbz_;Z4`g(7zJU~6glr$3((l#P_)drj%(oA)kxV1ihbA_?bf*@^J`veqq=kpq1 zaWS16J~VATABYc|Y`C3R*FXuA%&0Ba);p6|G$sV8T?2DzwIZLM-ScmtRk9L{j8~Xk zV{OngSJ`i-dgh}1SYdq=T#4)61P>4`Pi)I)#Wil*az!iNXh#M=cGP2B^~ffucOx1o zSG?Xd@D6pimQs&QzKr`q3876rpO)eA8iKts$VW0n78ulZ>CImAxE~!p22aV zHI4~tB|atQD@|aV0?s(zdQCDXT<-~=dO{z)enUJn>7EFGEFdLJk}3?BMh!MBdyFLv*gfpCR>GEH$*nU7w{|h z@Kaq7f-7!6NS2I5sik}*Y%Qg4prlBH7t%lz61Hw3UCvpi(z~t&=UJl z^L)O3OTa&#E-EB^GV&8@eE2;=wL5HK-5S$k2?o*e`PL8krPiM2bUzxYYNM}|*IlGV*c zQaFvf$?6-P7I5p>BPt@Z46N*d@$wiuBXJI_Dr=9}kp;S7NXntpVCaC4S0g5d=*Gn~ zI9g}%ysP26=@ZJgh@)A{X!2>`9lWiUOF9HC^bygP>^+fIl+K6}-rHA+;vDf9x4RTl z5uAI{I%(Ye?5KaljUKN|NAbt9_r3|=RUoycP1B|}>r#iWvmch_bx!QS`#de>UCNr| zP|NS)#~LUu%h6of!`s2=T9*h+%)(RX@inx5f49|FSUetpk+b?(34rlch$z9vymBV+ zWq==QfqoimZI{pAy*=_}32gppH&Qe9-qyBhmD+qq&1$kDkweE)fx@+$0`lLgf>tLMZRoCBfDII-a{%V%Nup=Vhbs+<(`!qXZG z&EJD`>o1?`o%v0NY{7qmV+E1HAdKMbEL8G`70ZO*x`pufa zQ7tW7dWP!fS9e8jgW~o)`3#lo5}!?4M#>Zayy9E86iJr79m6>jDDTR5opeG@`3NQz za3424*Ssi*_W2B+sXWtXDci{mN@!#GYMCYuYs3X z+n;+MvxPMvt&18-VA5*$?7;+U*+8BWxe;`k6xJf{ zS16dJodedxSX6`nlykOj<_8C+w31hTxKs5>N}Rl)#N4u)^z%`6SRNp6S95m4*h{xM0O)Wvk%3@t@O)8}r^hol9!eStFYdhM0kdc(+c zWS9R#`y165IElsXXZ%mQtzR^MU;D6V$KI#H-3%sktt`a%dcphh&G18x?1OcuX1N=< z^Bg15-lXVI9}m7G7=xX`HKzE$!%fQlPN7)J9xYL|GU*1gY*qXD^Xn|P)4v)X6B|j- zSijKobtZN|?hSDJa7{;L6||ih1kfnP;0w|%hwJ-NC)g=jMuHgr?tA_6BdCSd%LUA1 zlZoFDoHYG3Otow0gmEq*Y8cTYDmgU~z^e*LfgYc3@S9sTt*oih!>Z;BQZ$9j^Z5wh zBK2d@eIJ8I6UxhOM%$Nd*GT(dbk1#oWikdar_*E0-rJSGaIkv8GRM~IKP&x{@bF%ItrragjxyrEGF!U$qbVb=5CVV7@Thm$D-HRkvJ?l8mxIJ?Ye~X;ADM*iv=F_s*;g;Y ziAT5@>j4j0r^Jz~Cy4p*9);tqi+=v}x3p|~$~<~ZKNN9WE%D3yAgMQ|_S@AJS{#la zIJS3t+dKa@zkKrxCy$+U620<4;qaHwd#+tcKiqtLBK#X7*?fI+GwOiSH|#{T%l=L4 zeUQXG^UrGI1uR>7QKxp8=adI-wlt!4S@)*kWzp=UUjMRnr_Z$gv@dDN?%qWluD|rB zV+M9z!GMXk*{#oy--kcm*8GJ%C2n@D`^a^Bhfm~&k50q8*IHe9?aFK6BOTBqbECYU zWbrQaq>$c8&9(RZFY8PzKsR&e6(A>h(1a6Sk!>jtDgHxD9k+;z;aeOS#bk^4Eq#ev`Uqm> zwfl)#)Y>-|86B5m_nwk>Hbkb3H7HBuEL3#dZVapeZ2keNo)4VxHExiog_?&cTi2u_ zYOkl{lHbAG@Z~@pzKuK)b)CC}e*-)4#Py01E$838xo_|KHX5&T!K0;W-}y-!bi%%i zjfn1ZZ76Qaz5%$T{6v0pUk1G`@krQ5Quc?FZMj8ZQU<3s9g6kfj08;xUvoU4h;+gT zw39Qx)F&swQ8xagH#Q!yTcs6|YdTr01mz*J=E5Bk%Z3pSiC1C4+c~0q9?6U*?>Wh`y?^2(3L}n zKa~@>cfj4>gX$}Fbt}Fp?&GW0Ok9rYCru$g?{gZRz8pc_k+SLIatotY+p?gYyaDx( z)#I9F|DOWY|5iO-BdLl1hMmokYcKeVdK^JM=<59|yZilfG;so2mcsBZQih_T$UmI& zL%*H!EqZK4*cwh8_a}p;-Zf5ggsB4EB`tTRoc4=_FHRCe!C!-7RgX#ck|MKYoXd3H zFGs5S!7-V4^kE}d%mqRX-J=ewODTJEp#z?>y5{uP=GaPhR5HN57^V4?)dN+C#S-k~ zfWO7tV>ZT8z>8OL`VM2~*hfC=S+5f$@QMMlb3y0*x2q|{Vdaev+RPjJZRes1TlD;8 zK>zeAt@xWo7TkkHQ@3gZBXQvsQ;mjL!~E`kc-o(T&1#G&TV0IG$+FbD_0VkLEdIHw z7QFhSz5JGGgkefR&WU}Q6vB<`av@ciQ5$#29o=*PLsp`~tt*k5VT-4!U8HueIIgt7 zxbJokB_4Y(3mHRsN8z1ep{xq?ryc8nROAC7lfqlbX~fDXO^+h`%r%G-L2)&YWZTzL z*=3|=ESrN-Vzoz6S}4i#={iQTc`hGHG#5s4fAf%g;N8^(5`1zqYHV!d4czle28`QH)i?7tA}xL=6%9*46bHyj?~i{-=rZxQPs z{wcA3#E&yYsPMth52ORb6A(8J!JR?zk^x$D)!!jx zA-L?{3RrnEuN}9*BXh>c_hxl`EN_IKNIzT@e!{ANHkb1ugJJp3En4z;&+$J+t~39c zmwb>|dDmp2Qx4{?N;=slsG%@Sk@r*VU{>#aB%+#)Pw`9m~8{+%s|@=rTds`DeA{;N3s1B~L_t!1G_P9bd-$#y*Od z4+%kZ8t2(8w+h8^`hE9>xbxGmU33}#)H1-G1o&}!f*J3o*C{n88960MF2%b~TzG|H zOln;TBLW8fcb`yvE*y>H?c~JARe5vCI@i46L*!#Qw1IGF&BBM;x$c8$oV09QHbNSd zjNacyM%@5k;$s(G!}bE3YjcLk)1JrJ8#aGT7oImUc(Pl0cEzXTm(!exYxGuF(B`aS z3|?UDUO!DRXn&!NdiPcLr)5H7vF3P6mm!Hu9oJ>hG*r_jXs0pbOVa2fFCQ#uja38I ztr>k>zwtRBvC)NB&?dRL3+cj_J^p<>dud?N>jLe;_= z+rb``;97YcG4oTT*zanj6}# z!DaXbX7~P3gUVWU?S0E$U8R+48nR1!@Uh>!np+L{t<$^b9dW(p_~ZPP>BS^mr)pxc zi(lyD@pM<4_o%-2-0)`nw}&1l!T*$?Jn=U{c{$h|Q4Z9|K`LO)`8m`uq|Lq_jA>6K z$-V-`7{Tw6k1*`&GSD_9eG}S=Lxp$4J^j_9_?>WOlKtB|Ss0<|oFd{Gv>(siKV`wO z8q=&R7W^;_XsuQPuHP|RYxjs3#oM%~=u2rJ2bK*08C!-jfr;$<{*!0d9qMpnqrzb) zxm>6lX0H%xIofb}p#0p(l zq_&{z*B+!d#|Y?w7VR+$Wn{<)@rNa7=_9{hT+RY`9&@EMNf z`SG=YgfzMWo5mgHka?=Z68?$D>N(`F-DfFNHAk()VblD;*46Kopf1?U^AZ@{J?X}F z=r-}<;x2a%ZvzLM%332-w=c=Mo^1-*nu4CotcrXVlM}cC6@75jfb*r>u6CHZ(w{Y z5$X`g99DYNK$)e*q$_fx*+&hy6;T46Tn}#!PO*?B23!z0&r{mTdT_WT#+)`Tx#Ttm zRB#Z-0S7PEaky`kM>+(wQw9{331={C@9ZTsJ~&~zeJkoKJ8@LX7s_NLp31Ui2KGGb zYWa*<)})m?pa+j!$t!(hFLjde;R?WHD4hqCqa9Ppeo^l*<`@<7CL z!qi)b?*T_StMtAumnh(~PJ*MZ8k5FDG)GU;%?2%6zlrxTvw?2AiJ1%GtT@v8ivP*XVgg2L}#BJ}>@BEtFg zB9d5*1U@a>LG~1Ss~g~=ExqIF!Rj5yx_4>G-ObuldOQ_5oYQO&p?&A+3lG}_pcoud zE%3w~eDGleswy~6H~_5E-^A`bZpk7mN88Uyv!%%s2V(dL_U`rijffl>57~G8Env{! zQtguD{%!9?-0rUa9C$o-Jl&1sZ(~Tb`IA&T&_fBj)h*JS6kxhURJp(!jnNZ(r4U=J zqnz9R^aoTe&)!5n<@6>UQ(?rUC?nrlI)LLhgd%L}5j@Ri9~p7LOI>)9x+0(mcm}C| zZw`oVy`R-m;dWQUd4@KSDBWDFz((Gk6+{|)rO8j_q6>9*%(z7W?lp31n(M$?mpEsH zBG^m1+pvb&=|dUl8RzDL6_2-ylec~tq1wPbkAVkOqgux61rt2YdAi!bd&!}N&|}*i zeBm+efWq`bN`QT5t9}l6i?bMu@k|>+Eqj-jR2ea->fNdG3ca79?bGztcdrX#1mD}d z1?yI64lgH>+HTEmThf#q+aUzi- zKXtftYfGmhxYF#}$ZqiywZ^B|wdSAs?dOK|x8JWl@RZ@0GqW?a(xRXVDI|Hs$+5vI zNB)(}Lli6y&(7};y#$(WXt|2sUdgxWko$i46^B}u?9k`L?JRp2MEPF#eyKlfTYZe7 z&fGJZ@o4^|m6vKM9aKW840zjmsYaE*6FVCqnbhLS3iSFugp0o$fw2z%em^pvpNCL{ z-eBr^NtinABR?o|qZaa0vjID7llZtLpaDnD4xOwOO~6>h^9$MJ7j(6x+tAR|>E&mf z;fDq9k!X=_oA7gF4|CW@qj{<_;R)vT+Q1HQGdo`Fv5`o~Yt06`Ckt1oI2|t-L%6*f z-b#gRC8y?uVWLBFx_Q1O?3EHI91e_NtR$-8f2Sf3P=q1}UZoq=-j6if@|E4mIlw=> zW&V;|gE^l&r;k2jcNd;d8En5B_WUTRwA`F35Un>}Tns5}i4ZDP%L9Cl+4}#K1>OIn z&>S$+V6V?fZMFPv&Qo=DmConR2k&jX=MR`N?dBcqBxhYMiuwq?P42n;`7YaSX%WI{x&SxzC3^055;Cno^L_Df2Ml6{ryvU=Li~lL7jK(Yg z2JQjOSF@ZybYa{!|9bFuGU5I9n*c+n9NfAWy(jsh?U$DyMRj(q3UyHR8f8syhD1xi z7A=oy2NLZU&OLk@U@E;lEsybkwPZ^k_EH5--dY3hM|}(!ml&h^R7VC$qXFJCJWJ(+ zeDg|K~sYNY$2?y+wfWP6~#r}qKze~rhGJGQkUTV1MRjce(RcBfr{EDKI`7`v> z_sB+m?fzAQySH_ok7n{gr#7rWbX%M?_OzfvbxvF=&UR6_NIt_mKbCaB6x%u4V8Ssg1fj3 z5!W-(PW_>zO<>Bzo<^hIqyt1-x9Zv9nmkg-(1jyW_-{2S5d#gz8n4Pf44|;Imn3us zGO_S&ST|+2x@Qm;%M+UP+fKfBknQ+$D=`apoI97WD351df3#ZEU!LPdnB-3F8S&SE z@%J|oPZ`x5EFY0LZY$aLBV6Lx&L`9eK5j!d9Z@UN%aWW6*ARXr<}-d2J)YEwXoT-k z!ho_lPf8TJiBvbo#T%yrQou!8&6?aTX9YoczUiD0RoaqpI0Rub^%*q1T{FH~Z(vJG zcu!-^XbAtx6Pn3sRl|22+I?aQ>(E*_Ftvs96<2Nb4OZ1qK7Nj-Nh-FbFQDN}q+#Va z`~uU1P%t9-U^lnH?mRP)_>f1!v{OBjFMzL+-{aU~4-&^k+J>Lwe8MhkHFsKtt2d6+ z&Fs%^QrxnH&7C;ScMBPR6>W8^AVf6mAQCA2eR1&TLjWz`j#P>Zje8D*Pgy zwd;ZOWlE^(ZxyQuOeliE6egWG<&x#w{rjta!IobO)*bu?%%Tj`U*PK!@_dJOW18^x z1K$bHOvLGCc5~~K2lOt)q5q3@N1(^w;eX!n2++0~VLlak~QLVa0jCKUbXV7XzLA@N!@;^sUVpP=Ry=D?Pv|9N}=>yXJ=QzLs&x znE6y4!|th23OSxT{uCw9xmX?q^S(lj7;egOU~LT6z;cgZ+x38$MA#b3z1JMR|6#7i zoT+c9n9V$Dn8NJ*NT&Py_~!xz9DmT66&SJcOP{pRTU<-q3rzcPkc^e!M2N?_of~w% zqhDS*F4Q69kCpv-nHPk0JuNmfTqL{j(5(06%rl0EUWvN8`pb-1aP#1ssUDQzu_<~W z^tDewiT&&4(fe)IUs*btN8L73a@jsA;Pe2O!3l9c=L(v1DKhQs{9$i-4yQ#vl z3r1RU03(V1hcMxexC%?oJ6WY;I1khd(iyNde$T?{xZ=Xu3jO!7#f^gp-?T8XGrMG= z=NLZE=aQ+E>`ACMA@<78dY57w1>fg8*%g$pmj@&IN(t)sz|zQKLu@^!Q`oB}1XFXU zhcG3ip)U5`2s&VM?#7K7TzQ}F8;$)-Ze?f}MhpgvGkWEK0=Y9E)jWs76N9Vi8X$=O+V?mp_YYYo|b#lITO1&`t~+fyMqY*fUx5qP0b9 zy656V_-UKsi@|Wd`YGu7S<+in7lm-fD0lm*f;c!|1c6dw#EoVTNDgBp3kK{9#*&K8 zZ=v^022dl|0(YBv=}(p{=}(Te^s(Ekt|ED#} zUof$SoP=xuY=HYzL+Bj% zh6LYXU;&v>_=l}|dem%NfQq1BIU@RI5*PpK)D4;*kbyx%D#u*gjFMsj^B z{()Qq&)fXnj5tEwI+a&=jX^Bj32C7^^Rk98^iefG6epY1yio1E&z#1@+@MBT5)4L4 z7ox7La_o@Oiwovyns%BBPRbXqk#4$h6@BnS1zSk*927tqA5SZPA@%AWWq@i#H~3sR z>DNBpeLKuCPuI3XlqJBykC~G^@p(h4-f|@hz2t@ zdO_O*E^qzo4=d{7ucInS{=zKp2?bKZd9HDua~<6_`1P=gKg09rxX`7U3e(azdZWS< zM_VGXcjh*x7CDEPI_p|VoHy=5pN3-qD}1&&nOXJZ5XY`t?ASTAGl19NxK>Od`jSf5 z6W(*>mt2q6S8Q)~Z_?_f#CR2R1{@bK&;Q1vLW(9$`a$!D&`2T@oqNLdQyay0;~3(KmlM|8ZE;y zAji3vVSGWppNSeQR04cBpC3?ko$d9p4ELX$`RW6jSe%VOalwG?mW$Vm!v9o_@fZP5 z=v^t+BTe95J~nzXYuDkO+BYPQ=t?%2j8TW`tGz!_Om4y2^@sO9AtW0Uh?~T{LQa(3 zxV#nGl~-Z`MRsSnbq?gClD(ow&yvhMeJQbL2&9ZzSL|kTDWQJ4r!9D@u_5LAz}4pT z_niWnE>G`b?ZBMo{MfL6bmh_KSQFrA_V`CXvu`jj-A&dTtsagH~SvKnQGi$Y;bkkhYz=Uuz>_$lBg z%sh&(Q!eq>)B5A&mU{j={WmoDjNyNw@g&Pxiv9)4QRrv>t9Wx;ni9|dg>(P#-*E1} z`h1`8Bkdk{MLIG4TUm}ZDu(Jlx?10SmkcyLNafi*H(ES z!xdK9b%A=f{wKbFYsLMhXDJtR5+XUKH*B=yS2?b^bz0sRVicOen@n=IE6HW(n_%MIdma1) z(y+Ei?>m+GtYQ6|IhkRSXI(P675^^29U54fL>+kN_CNCN)?-<#$`XLqX|u1YN8Xh) zQ7#X75pn@WE;irD@#3jX14q#boaTH)*Jf({V7CHx0d`U9=`EQ7i=6qn`Ak3>@1BAw zMo9A_=Fu{O+Amf2zzf*VmkmvYKa;>q7}rI&^&hi-n9(&80ooDZ0`;-#{r;{0y7S!W z`10L!uH-pBmrQW~tMh#D@0{lwH$qbw!7StfHBjikk43cE{wqWI8N(T{68O{Deio*= zvUg&pQWIkr&IqnjMmRJJf5nL3na`&W~pz^2x~tCtZ_fxypL(Z-?`z) z@x9`({(KzC@F474^U!b;sHOLD&p4xZVCT}Y-H3h^_MW}g&VAGBnI-tEDi*HT?8_ai zFM?iSkh8xPeAEVy#Ef~#b9qZ~V zh<5Udpp4V@!gu#t+H=yLs;QOV2gy^s0=_gm37HE_+}|C_W>(Ygf%_U_Ab`^c?#?O3wu!|265k zT~HuCPY_r3fbJukLCP*z)Rr?qNj|qiOnJ&dUDDxJP5hpGAcndzaS({<)!;@LOLD`n zcc_kJ2*kJrg73_f;U^j#D$SDfDF^cg4t7FqjfbxMReFy7C(`rjbIg5r(gtwhM^gnQ zQJSMKu9lBxzj5za@eZpum&^>BqTJ{^ zrJMo}byrX24YisXO?-T(dHV0+_Ql&(#dbB)xUA20#p#ft&GQINH=LL2UvuD4;5;;g zVPiqzKfJ8le|=eJX@g(^xJU-OQ4#mnY8^WyeXH25$u?E%VX^#a!^|@Fkj>`x-0zdX zmXQporZOm~Xdnt2oqo3EYAxnXDrRCY*rgw*RQZS+%yVF^5k|FpTzZ{zUikA9!wjP| zu~?zQmTE<_<2^M<)g6P8oQUeB-cpE1ZI7sg9Cmy}8v@7%gIbaKb`ToBy=q zSzwNAxXPrlZ&-4FN#GNa&2as4?o>bgUUv?1;-Hj#9#Hc4xiR;P^uGZ-(0lJ84!5wwk)H7ps`$#ff(T=zw9jsY~VCy+H2C(((I-B2V*#0U3irKI9W=bbe)rg z@GIECG+6aMMQt{hD6enMp@ZleU8AY0St?Iz|2gS}J%Y#Fcs^p-Ck``?z4L)s1R$hb z=a>%m#uGGi3C&Dlu=;s)=ss&~j<85g+Y`WyPbz!5u*WdxK*9&{bson~?vVW0J~$|T z1mq4MV237$Ub(8ZdSeu0-e!b4j8M82VW%h)Y#F5xRT zL*c2WQ2vD*##o-orI-~5e+a*nqh+QSz_qXkMsZ|KH}^huJ9350k81|&$uJI7g%-)Y zVdzw16K&&eXt#;sm;!$37|c5Iq!iFPS%=UZJ{RmTyR=-C501Yo%J;9gbAluUoPMkv2Cr%Cx)aUQ>}kmRw54f#ApsV&$>vuCZa10t$(L{B zd)O~~;wwFaB*hlWOMOx}$I(7FBS;3_T@qxGH^N^%c?=+t|kj2=Ce{5lxVu1>(e17Goz?J48fq$zwYJc*sFl!fz)(K?II0PUB% zS;m34e+G2~adOMvf;82#N1y|_bj)&rUiZ1bgKXpvYmRI0S8wP}2A|qvCPl&k60`py zSWWC5fXmiiRsx}^^ok2d^2lbRd93Rm3+$G(pS_ZE`{o}W(8Y0kpX$X+Np@CP-g!PO z=VBN+E4N?UZqCRpL*c9nlRo+rsl0{dsAWZWt*G4c?eM+!TMCYo+34%8 z!@N@6B*H|Dg)PUUZ4YzMUrB>Y;mkz=O-Z4#`c&@sz4rMg(u9{kZ-cZyt1O}V4kNCl zmQ(-D=JS7@DxVa7{(`zo{rvX;{l0NAmBe497$H`iS@=vH2T zzUF|Nf*lj%U8q9V0aesyd({qdq8kfyiQ7HhH{BB7C~nsLimyu6Z>x7`sY95iz*vcj zwOWO^)*f;Mu=?f7uyQ?QuwmW>f2XK}KH1w|#mB0a9Qpc9$fiaeArH9-RBo*I>U?|O zcAJtxLSgN`7dcUfge4d~@N9AKVVymYemHbxQxb7c;;Sa&8)6%Q2X8Q20B>#HjQ%L& zPz+7ZIMKj9;mNA7q8K|y?e)eJqKTI>+}ID_+))Rv+gMOWV4NIIt&#+uta4p&2pKx^ z4PW);fCY6-+iZi9MaA`|!3gAA#LHKgLrF=3g~`a`?WpMI#57PWD(%F(yCNedO&S@< z0)8j4v<~w;bTJHg8XCn_L|b!x+VIz^fiG4E+)j@I4CCT>G~#hqd}0DqSRH1~58)-o zX@^e>g86n&D)e3h!dN5Ka+v_?O1uhZxOk8}DFY@03E<#Fb*>8Rm4V?iHG%vI?3gf< zx#CpTYbI4TCD0mwFNeG#G3iA?psAjJ{ORTyqcr5CN#8l(cC4-(l1~a zZnX;1O0N~*s~p*9(8nujL?o%=0zbOYe@uV=XQ}ex_Rlx7%(yu2N2@dSu|QqDX@`z=)MTah`98`>%2hCO zg)Qe3aS5i?57nt%S9BW6%JJ}c+|c`8KJYsdo}!<@EzL$uFK%y+9O!iG-Fy7$_9tC& zr@-gbD#u%&fTw4V1bQfG9w6_HmQ&_FotxbFvaD;o_UpNx9{k7dj;Xrd@Wk^=Cl)>H zgu|MH%1>h573jWb8%NqEa9p^5knHlYhaHU-&+xb4q!3Qc;4&R$4lR1Ntu_mp`_f{^ z(CW$Uc2$KtfvGyK%hB^rv+O6qR>M@lxfXl)dHMbDA(u>F-H@4DTL$Ed`JWURW4b$yfBKmI%JHXB+Vf^MF53Kb0c7`|PIbLOQ}?x2Y9B4ZM$y3?E!~ zf!g5tfMKM&-XPtvnAZsQU6d62*fM6|YKMdaU!HxH^JYH)R+E=iU6|T_vW!lCjAKhg z7|^Vx7YpPpA$$b4`gdGp-_kX@w6Jvjr;y#vnZQ2uF>vK@Jg2SG-}0zG*I=a6d-BAC z>-5N}pMqX&EGpI8giz6&n=E0kx_J695SRYMA~eJt+c|8ZL7h07==@>(1KH=;^6kT- zGTH^Z0KcHZ=)LlUWx~A!(e^>q>FL++v!Wdx)l<2_J)?UeWK_iToe!0`9@l%|x0GU4 z-;B2V?#neIpB?E!O|AFn^OVGH-PHIWCiEKQQoZ;u9g@3iSlu^k za2yZJqA+C|vy}XIRJqvj)d#DDcJGxdYlzpv@=W4R-#mCF zwAPm|)JLqZ|C0Y6>pG&0c*woa*nb+88K7G5Yp+JzJ9XYR_;G)LlM8jgTrjr|!?NJ- z1o0iMK=~BSAZzS_ye{$EsLP}fJ8Az-o>k%8$)o!wCEs@DoJwJ0IxRkyuTCB?ynW9Bw&oMeHb#o0Tk-xkbd1aT0{)9rfeR1kWIcTok>;qr zBYEY6v;{Y+(bDV|V7x{NRtVNYQP@3J{ac_nNWa@am+u+&$m=uc%bInQF_)~rY7tKW zJlv?!p}ZZD0w_7n}&JP9doE6-LK;w1MmuQsGZKeye-_ZMb1uf(T@>?CWuG=gi!lT=aT6yRue>bFXCT}6DEy6~S8fbn39>74b z=g$t4jKgGL)2!@K}q!jCN}!u>3bUd4lh<=#Ps&3M2Vwgo zkE}+Rtn_vMJ4O1ZtLxeH;8@IC(%Z5)`&!(IoOF)ky^H2(gEdN%mAX>Th91}JRAiff zzY&Y`lRVm1z(1>CF&Zwt&tad1XL6J10hRF2dNg=qz;nuf<_M~4hw};=8*adFz3}sl z+PwOEb5wYBO@H4$Bipd2e2>T1TPexJcVG3KhUpus41rC+Mi#QlFKyd-wp*$dKRJ{V zEAj%=b>^e=vRjx|!+?Rv#ti;s{>+CFT*08EhSZ|KhI6aHi;oL|-fPGK>tt*vsqbb& z+bEhl<6~UX^J}dnbsvtN15W^Bg>}k@GmsmaVqC6lY7sFKGe8H}cYL~zh`}rm1$>hl z!nhP51;wOo?JlCu1_q9vJ*Ryq&NTuLJ0cX~E$6}yV~vgTeVX=sCbs2sTbNlI;Nz9o zO1mjtUl5m)?3m#>J7i9Q>T2!>VWr{53)n-pALlks#zX2AznLy(3 z?he&DQnet?wD=H75hzF0vYq&jXsznklQpINM}W2tI@^S5G+A5GiGbC)vxURBFVNOg z;8i{@Mc###f^UmRY$YG_wO}VPQ_2fF$&-;U-XO&xYhaGz`t-|ls2ETL8X{-dj;}9j zbcVl2n&VuVkzhJUI5tpNekhr%d9imc(2(vhaQ2;BD)utv+fqH>=esD_d1L1cFIqzM zNTJ=M750L2(A;%IZ)Xc<(Ncw(12}z@oVmIAN_??CS^gUfJD)R#?c4qi<0Ckde%ZmTl>~R@7`AWfJYlbx^#WtymTy(3LsQ=%kTLK@mG8vPZG_GN zyeZlv@ThMhrk4@}tsDl{37&OTi^46OPWYcb3q8mxWLgN|Nf=XIbc?#vrP3Xp;ZfKH zLCO1Y5jIen;wPdyC<{@MsNq;x5y(s@7+t0 z?KrNtTcdq`V3_cbbWmQ}rI$3uGXrZF!`+2(o5M@Ksb;sk-<|a$sP~2T4R%S;OF(!{ zd2aC)Llolu1I|3_8yTR19<*gQ!pM?uJuv-yGr%d4U+*winfWYBfFq-~IEqv8o=H$u zN#@&51bNsj6d_-Ia;lu#aG-H+pzJwweKIMe{g84>5Tn)(ccWLf&1YDz(q6jl&}1j_O%KHQJ4j{*Yohw(9{iy4)RJd4`>&3 zGdn>Xm9i3-=tpBZfA6JK8lhf$nliA={^k77C;jp;<3Q2eRggl?5&Hjsm}phqvn;zEVprfFs~4);y~Bc)p3(%61#0I#rxSe4dc; zSNY20k)TS`?g^}TO=e1rhD{M;TyXY3PbGnr_Rmyyq} z1Xn$aLqoBK@EiOLdb z!nk0@?ldN*(pxoiNDHucH>GPa>IcAZht^FA0!~U}b90*!diWilHKXlVVZrOrZ6#+X zjBPbI+9emW&VYvm@)xjYVy`nK^5kFNvE)1DlDgp0Y~aj^%|I%~Ge1LY_xrAS_}k$u z+uKRr3@xk8RhcKZ$m>sH2bg0X`mYgJS29y(-m=K{o|De?f>W%{APR%#V=l3P@-*5w zwU4LYw=>G^Js=8wjJ0K>`ZnnQU+leiR8#BPx2vKe7En=9DN#{l1(7B~h#eInA}T5+ zC?YB)G%2A>rAil35rG5*1p$c)g4EDE1f)p~5Nbk8LLdproM*Dua=rWPz0VonIOqGm z^PVyG7z{E9@DJScna{kR>%M*-dw`#kqa==1s5x%-9a^q3*^X=pv8J93!Wo#x+OGUo zy@)XI81bp=*K#5`UdlcSy@1m!8oM>a&;7+(<~x`2%b#;;Wr**Fwq;&WpzSiX_3(T@ zt)0uB=>et};XsIDPAv51U!GA9|879Gm-Lt|ewyL(BfPqz<3bXcH7O^_8$yr7Xr7X9 zGJmH`p)(O$-d7FlzQ}>k*rNBcUhVe(I4j(6`xyQ9pWJVjaQvg`_b&Q+7tX*>B~S><5Za%;Qck(9XCr7>$e6w z=XN?|nY`1>ug0oz=u>6fN9~99NfT*S$Dp=6`1+U)7$inLAu-8UDe{4;a_Q}6#i)@e zTmH!21~HvTOev9WxFWAG_B^wyz|vN>!bSV%)PN&zJx8nW5~EkECZ#nB_S`4Nx$XOz zJ%$zU?|M|{B{XPsfC7vJ?NgC->Q zw>P;dzg{y&hG9$*L28Z~NE-3ms?q09?QKdMaSAO+v1km$hOdrnGUL>-9LiY9;V$|8 ztx+QgOHC`B*LkLt{($$>lYg=*p+?JbKsCh+a)o9^ff?XmBA|8G|Gs&wnw{^|=F3uN znTm^>>lhvx0j#FdM;ZQ}O$QQ_jLOE!w@10$)j5|CX;YP{Ra`U#-0ei4w91TcVE0r6 zhTa{UM{~DbIXK&K-z&VQQE;$yD>tREdFOl0x9G90hWpLt1QR;+%K8d?NoLQchkhd3 zV;4FD(%d4!&({@sHGEm{QI9}bV7X@22WVPpHXAq?4~T6Ka^dwfGJ>Y5v>v5_fj=4h2u7vB_E&E4;|j3OlSpINOvRqg}Y3x0G&^+q(4ao_%}Umd#m z@BQjK{yX^9FSO*zr7o@5zGt=&kv#IQYzq3NQ>jv_oLgFRHOKj+qhTN!Y>%wFz&ij!r~Z^CIz=fZ+PyLZHVOR>U#2oU(PgMrm`s<<>_yq zbR^K#uDal^6E7)~{;Pm-ozxkgp-{^xZA1d^Q*@iM>qIc&6iR{jdTjd}5ic*!t=21< zlY|wF!g~&oN~}U9RQ0^y-F=m7{f~hf$1;vavF2e5qLEB#)%9D`uesDu$O-e18sV)W zm)DW1V~zX4_5%dggNcjcmd@46Cs>g(-w51vjo^=@3iKO<;#`u+0oMz{6uWBm6q2O} z2NtYHY@@6njvyF=^%L)U90H*#taUE+9|Y@e6U=Z|Px>M>BmuD1!Q6kbh4ub5s}~wA zivy;TfMIDgC=E20=ed4drzcNsHrCngsN58v@qdM)dxt>DMb*GhZrm(-*EyAa8!m%7 z9I2zQ&3p^H`eMnWSLcE2VQW@{VJ#a#*m3A&5K??!&JkVGU7c2$MKD7009-_`5*9UCHSV%wU{VHX`(zpzL zruD8K3#8XOFR?`*v>sp0g8L zMd>g~H*+i-NcMVN%OtW9r6pO7V-tL7;lW2aivo3SYKuMV66YA}wlD@AAoNiZ6P%9% z=u{cBxI%#$CN0G`&TYGRX#9$L;||0?MEts@H)cS|!)X53&L|Zv`F+Z7>{%t}GsmfU zDp&Ojhck5fA~Y*wOt<%uRq-4oJ7WCvol_o80K!KT1JX-CF+bFjw`4vQ4OjIMe8>7k%c+xT#p^E z&Ek|0XLL?z-qiSd8<=%CGrw>MbsOVq%<+8EDqLgAZK^dXuUZ7#TRC_`Ks)^z{(Gp!>{c81#~;Z2nQ2~=V3zj)Rsesckes{LS21lWQTaM7${sl&v=iRtcx z2S4i`Jgw3$aa_wsN!4e5v(9}h%eB+;XCnAz$ac#AP8j{iC26oVRi3d9del}rUMwSX z$F*~RO4gAAaCaZs8q}eZUjmQl$>Ro?0T0Q-6F0g^uCM$0{Uq!_< zc{*%%Ic$>EmQuAxnbEN>+}q}LJY%!;sda8H$n-^S;%lX6#-5|=Zcl_JHH zy@VA=^@A{hZz7IAgS5M{aFL@y?0ffaXTwcBDA?X$ek$6#;-lQ`g=VetKBZ=%<0<-) zVXmxEg8K9Q`<}Z9PQSiU)ExD!)OYs$L^S*CrP9Q=@9ND=?bZ%tO=3%dF0#BRu8ez| z9dX>dL%?t|W0UftFJlftkMuX=ee_IwT?cmG(CZtu-`4Vwi*(%-4%8yNg<4-eiiv*! zrmyNL?L{1G9QB^$F<{5}@R!+IJG0_bgFe4};I`O%jVsBkWaC?*Pl0mVzYtV7pTX2E>>E&KZ{5Ur-27DLoX)4CeVONB zWa0x*dkE7SJ&Dy$OS&EQp{LOtRT~k#jnn7|PcSiwfyT36jh%j)90_4hJt-fn<$LFS z=7kJ?;)V=n4Lh+h*?v3KVLNpu*}jjm>nTBc|$*y(}~2QH1?Duudb)(aG=k1qEm z^KE8=LV93-*ZqP4BEVk{RUUo`jog(K+>IF5h7L=qd_C`Rl;y5;N16u;2W`XK`|^ic7c9~+!sh~aNR_|ldT2OaXE-)SpwqOfs6~>0FX?}o zdL8|LRz4{hgpO3Om`c zbI1uXHWgl^vs%cn$*C!vE2BxHttA#mE_|jaAL*pBtMj%u`Hb_Wtj1n;=Tfi?4268< z>PTw1vgli0G@kBXhYU6)7H?w&b@>?FT<5t>RIetjc;4bO20P|mIEZDmKswG*gl3>19=lPY!92YC&f%tm|}2SHT?Drzy3=L?>KFEZZclW7mOvUT}qu~9Rw4eV_dT-Z57 zBk~RKX$Dy%JXnz)TGRw5aRsv1+k5*u3@1hbX zLT0We6b}Mzgrh0k=QZvVM=Mu0WgtD(q&T>DnX&xWTK4M{;=b46Z{2&w5WSfJZUFut zo7d6*x8`-SmiS)br`(yqxBZ40uI&gE6jBadpH+M!O1^8mupypr{a3OcX+=LLlPF9i z3q-JxCgkzYb{VrxzmEWPgIx=!IOur~ZRUp=YmxIK0h$*ZNBZiN%OWlA|1cBv(_S_z z-dk~)Zs^^tcgo>v!n=!&mL9{Fv^>X>%XQO{Wlu9#Hq~Er%I|)|QPv4rA$C_nsm)4T z+5A}E%Bb3#ZPCu94MdTxJ$%-bAaKdSZu*CVozMNB;9wX2dk6dCe;Wt;Pu6SzAXaV5 zt1m}x6O7!Imd0O;jxwi_mXqE2-E=s?G7X4rXMb&r%8x@kLVFNOrU=TM;*|>dN>@cj zL7N>jAY$^`drreUXk@5h5WD|}G-z1{PgezwUPTA5)~tGO_Wf8W5ZT?A3S6G*$hEfb ziN01)&pL!j$uGw09nz+BxaOt=W6X+2=56Wc=O2t3+RPq*c(dI#msb1#0iQ10NGoyF z1S_V_s2Aa8rGWU)%PZA!+%Aa|{ZPv9PR+iG0;;f<%okE&m+w3<_s{3A?azLnzlOS1 z_n1LV)WskyRQb$UP}c;thIX$ECU_tDC8=>BK@m5o6+B{}e2OduJxxVBomPmp8D+C8 zi3`sSQGwC+LR#1+z~zWV1tQivYKGr?`Ts4bZs8g&a6f0M>^VY_KQyyHQ_#6+d>HaK zMFWv8dk%wzN^0AL9)?6$!8ctsAGU8kD4QLjc^Q>0R`6I8EYl(nV;g4G1>a+U3tov? zVLdWD`xZ51!f4`Yc4lH)qbh<+tZD$}H8t*@aKydfX`axYJ0SM7_J~}W=;i&Dj{?%_%Vk`< zVt7$eR*l$7T-t$hHSa8q@-s&Q*=v$tW3xQPy;cVf5jEeBA+(;(?U3PYP~^Gtl2s<_ zxzWs6({Em9u|)S4Cdu;PuI%k>?RvqD1ob&wexI28YSDHn@Ppn};9L1@s;w?RDr$zbx$1G^}hHydllyD@XG;-3A__qA1NV^^^yw z5`I>O)Ka|T0$*}y{%h53oSy5{foYBoO79^|N_&IgbN)77=!&B89D zzw*A^cyQzZz>)_>6rpeujI$qH>Q?^Ohueq0H!ZULym_La3CFJ>EpGMI!!v)Oq>k?h z9h#|myyfbt`8ESRd>Z%->j($Dm%gqgoD8l#DtiAb>dEz1Sy59L&-+6oY2MFQ>X#z) z3Oxj+a|M;K3EYn7dx@(zK=fI(<0YjiG07`54nExC2IJ~$WD;MlmIT(!Npdu_U#&PJ zzZQ}~+}Z5>#BTP*VnU?EOms@o*SL+Z=680Q79Ec{kc<3v%-Tl*(5wb>N)KymcuTI( zh+H;HZH;OZPa&+qeX$9AkL=_c<#i+@OMuN!8|OUuNxaU4$?2YYm4aIA+{{aOmp_cV zgxP#|e%a(K#zklhhTwljb&;L5PIp9YPJJ6LJ#bbu8GK<1Ct*y}NdbBST>*~OA*Uyv zry^eX3C}77XK#zVwhyLiv2KejcaJ6J5lr?EnhJx?uIf{7Wuz`A7s{pLHxIYN+Vj>A zU;D_Lv?!T8Wb4dPD1~=~0dHHm@Ej%62)}v!33<$rF3}DPfWMsyJKJ4K|vUvbDl*VtyHW z#EZX=7OhQ}n9mP~CPS(ZTYZgZOOkeOVUYb15N8=S#`&$j<*antd}9$lI5{$i8Y|$JW4L9wZ>`<>R@yV z4G{-Rb?Z;V|o?W>G9=>%cU*^iyD&@)7003;nN79(6xXyT4cB3-_k~8SQyKag{p* za!p{x&P(AsvGc0_K|^=-Lmm-)rCYEG^aL$ZStN(y{#Odjm$xA>Ywc z4O{f4HTm<*+VvMtz_Ju3%JngYpU+Tjjjei{DVK3P+we)gYO9Np3T>ZsZRpneat~JR zrsyEdlkvf-nH+*k8KD!aYSXpHtDHO;(?=tj39kGhX#e_$p#9!~|3!j!^;G1dQ1jQf z1fG-xCIu~WZ^ADSxl?;WXW-}>t;nbJgN=(B#OjS(z&wDWMA=j@yO;%@3vOS9x`e)` zjfATILC{|97ptY!b?X{m{Z)AwoXhof*i!y-N7Ur$GNtcBL`kxh;$BoxWX9!(HX>yv zFE-bR*gkP{6A1^vAD6u>9wptnEq=P9UC24g8e>Lm`*BH8nmx*;z=UZp`5lIRuO0y{ zHz8pT%JlB689Nw5&Rd(j>&l5UoYwzu{vb~W&z2MTha%Q72Bt#=ed>h#L6eCy! z^;o1iKl!s~FX@rcUMMXH40BEA|8Ja90dKIXiRbb4zg#ujjjj7sl)^FH-EZz&YvEDA+YMbwEF9~xoCC8V;u}7?VQw87< z&u+A&XJ1bIt!JlMmU;9q29f8Dif62g`7_*W|1k2ogt@OR`%BztCMPq4U(_M9W3`#q zfMr}_oCSG)5i{-ExS?QPb`kqJd9J0K96r>^n>=)>m|2h}}Z3T*AbH^~8Z01ci zHb(3KP5p#T6gO%II1F0=8wB4FTcN{7P8gshT_Q)X7CmCIz(1SQuS(qVK7>Y|BdzKC z05+;QO?~mtTCG5oZj%Z;I-9t<6`qLHQHFYddB>aCn+}PH6e;5R4;Ej=^mivCBVBUJ zt;&kKgz%iB2iQwq5J+pg6_$$wnTVtZI3?&_&?()(0jedvf7W34u!!RcD=&vsxikO? zO#D)WPe=>QSb<=e=dr*c080t?8YaRCpq@YP%Dja1p$FBVDMY`5OGI}eNxUt>yyIVU zIb$um)bZDjn=ARbd_oWZqTqdKL}a0QBJdTV&J6)&T|EyFl}WdxK@t7R7D1HsrM9Tb zLoZDyY!cEhYJZUm& zf6A^Vnff+X!qCUA@uXP4FkaHD#lf#du{yiu4XjKr?ANKcsxmq=+xc|}`t`LgHb_c9 zkvea^WKN{w7LD4X zD<)qEBv4?8!3%z5sLRR4Aie>6Vlnp<92;R5^aday-;q;cZ{6aiF#khqPmDgme?lgy zN*xXL`Ci;E8T_+dkZ5~e_;Lwn=d9Ec99#=Kv6O;o7a3yG>E}?fj1#A`&n-{V2*eQH zdYiihsN!GFw~`F$j|)vM^FQ;IZ)I*v9NPCnS)(VL(96OuG7mu))w(so(`t7{Nptr{ z#taxSTcI7;PlcCWL-0X~CW9V^y4=dlG9gD5E%Ia1_PhIWdRdoVFo>wPBl z<;{LMHQsv1%clzvp9vYtPmG0P%zN#Uqv(By%yZg>v7+bFk-^Z<2qbrD#tvv*bR|NE zByTY(!h!*boAmQAtJO74{rawGC+e>5-Sr=kN_KCE)~J?py#*5MT_0VH*lx&KDRh&m z%=>`U(o&xj1+V-ZzvR03p5s>?@vc7_|9)h+UqVK8E$dNlThS)n2$5O#CP#C}W7G+Z=a{vlOc`*!d2@7_rLGwfW5 zHrNSpJ;?N2A?aVvioX4QRV%E zDb<97r8C6{Lmz}CP5~B(tRt3gfKJ~Wlxh0jo9g+-#O25E**cPr`TT<`Cn}l!+1aeyJIXn>1&x9bFnRjN6t*d)s57bo+lKW@<3=Ag>6up^A-74EqC2r( z_^#2Eus8FpD7ypF=)j6b+L`djzGHkd%y+J+6LMI@()qUonmPS=7Ei02@`bnMORnUvE~c0l6mg&SNZDa_PF-8uLC!E zPE)c=87m!Av1}{CdCW=h^ceRcSlbT_bIRR)o!iTqGS6D5Ntcd=pDF+o=T`DWL!E{U zu@d^rH;hU~E(y}b-p3n$)7^XX!Z3?})w70MLz?MGua*mIk09&atW3RdAvJ};JPrS|m1%>AxY~IFej)uD5=(M6p*f>UI6sim`c@tL>fjSy}Je1eH^)myl$A ztxNu|0g^5Jf1fbyiz&X@YRciI55_>LT|IVZD~IPJB%f27MB`Exn#KT~?>y@%rwC=& zH`2eyj5ZIjwP!4#QLHe8Jargy{g=j|*0Z{uMdio3kdIYe%G?xUc2MdOHeOtDILRq=chxvA#q`4R9cOfxi z%qnC7$C+KkGHl**jCL?!MBQ|ghMo%;`en~s&2`!WIChQP>V6_)u(Y4hxVaDxWk4A$ zjOP~MIhnwjBPuScx1{GKh(-{d-Fx__P>O}Rt zB@kOj_HacD>X-1OHLQ}o3;I*kAFG2d3&Vym0sM)sSi9hH9wxTzC@}JKH!4v}$CL^? z)^yeNKjXOS!X9>uu%HsbcYwXkI2L(Cvi5auC3*akc`w!laRa4s;0ESb7z@Au);7m* zYzwitctS^uvo9~`Ewrmh3uQi*a-Apf!s2-B$5ZHSscq!;q9~p{^k(#c;Gpo@`rOS6 zjp;os+b{%U{%xS-IH9=C)s(u=P3^ek! zVWD@e)T|?=7>&0*cfYK6#BS!jg8i9~UmwJdJpsNYfnL5TaQ0YK*cYrgVi%EjOl)xT z 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�j_I=lY=wv99vs(89C`;F4@nrtY`l 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

t)fw{JKe*j7=#giLoZF>Ei$^9$xMSbHnYw`k}v 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%0DU=*Mz@cA{AxYQFhBZj}(`hxzuS2Qud$lK7Dse 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%0Dmg5Zv3txzYIH_ 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

E@F^N=_7Z0CvTPVj_c4L`x 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�h->75 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 z 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

v6v^uGSs2eu&`%l(tc&H= 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

7uLu)IwZlnM4YK7mG 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 RQrRv8U+B?y(@jbu3#5H$)7f1fUxfv| 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 - - + + - + - + diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/1024.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 0000000000000000000000000000000000000000..f959168df57f4d5b39c5db1752828d39a0bc5932 GIT binary patch literal 505131 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

mPo|3!~H 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

iQ4g?M+*l|#xcDVieX$_-dcvw_-l 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

#k1#m^|SH8INc55-_6S&HxmLaO&@4I!iqQYL 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
o(D1LzoIP*iIFjW}L6 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
nX1ek-Be*j4%W+L<#lV#Wyccv34BE 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%0Dj{EsZf$n-Nv3kP~<*7;B!~ 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 bzXA*ZCyJ{~H}4tQ00000NkvXXu0mjf^QN!L literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/120-1.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/120-1.png new file mode 100644 index 0000000000000000000000000000000000000000..fcdad3ca425d2f9421fea281eab19afedbaa3a4f GIT binary patch literal 12866 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%0Aen^SC&bx{%u7q~B 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%0Aen^SC&bx{%u7q~B z3^(P6BmA0vNr=*V!w%fA@nd)F?BFgIDaQH{a%#6bXk5zPaVz>g&Vp}43TD`Fj}LY< zBo-hg1So-jRJO7_Y^Wf;$)b0dv|6N;xWc)s4l4EhDqq(tZwisZZiWtc6ZVa!SkCsl zGMXcHA`9PscFVJJ7XxD}=fb=6Z0XGyY#&{ue3oSrXLxhYi^Jlvibl;EZwk*DoHWQ; zeSmRlpz=QTc5?i%dm-NXTsS!ff0%nPGq}l=&XO8NpXinO%Hd6{GqPqYyyP=OaIhYkI@aoBbJT?&XU`H*;5JKWTk0YC|4e zEDI3VIFqVh_Yu!x>d1mx3RY{f&5L`_#PMOXud6gpd_2zKB zYSA>&#J<;$7q24v$R0#dPNd3lCpeWZ6a!A$B_nO z9aXJCe_y}`;5qCDw@5ZBvaNk!%oymWY?E(2*=-SgjDCGTBJPycQZg%eI%p}I#tKZ@ z8r{~i`#im$;x>6eID-{?x+MQ${Sl=~$dpX%s6I09dz;_bq2m;*#Fk^tt5lbc%Kmnzul`P5Mm1XduS`2U zf!r@F2b!?$pTnu7#>M#?7@3YhbZsXbw81(;Ggn!YMtgEw+|Y5=Wbv!X_B&NVm3d>02>HMPI^KVAb*F_z$W^*)5>A(wt85u**3>)yFugDVey#Xe z|J)er6o=l}$;dCaFX2`SzOE#Lo=rXaQ;(dlRS^t!2N^LW(~@yYE} z$?`sb!c_eT;@()u!sYzOORpKF`az;`z)-Wi(n8nPRkxnX;zL@Wasnlz!{Eg@$%{-eb8p!01kA=Q1270Az-xnpQ$>p(Bdx z)4|nSvWZLZHeO}-Xia9~&Uk!_NT4b3X6=Nk9`T{kqjsZF_Nk|U8gTlHdeCBDd5y=H z!xRbi562|2k!n7Go~gnSI*OPVlS-)faZE!x?Czn6Am8(hGyJz2UoT8McPX9C-E+v{ z$QEiPRNU*B4uy}W7S!l|0pm-~4N9$*=dwsQ)|8|F3AwF_C5LEYV<0ZO^4xBiEP4oH zM4mRa{|$6QdLOLY_0bq zQM+B5t-Jd95d%+{{uMerv;>yIA0ycUm&5h-zM;G7byT(D7Xl?V1zY;MRYxncH@hWNPMlghwi zucu`)uE>+A-$+_fIYaPdEw8skP1{yt(Sx%nth+_7r?H5_DsQnT8nw~eR!)V=oPBtD zHUyLb5LhHJ5O~AhR7~j-@}qOfJF+6X4i6otfV4RkP#=VTU9B3ziTS~*v$+s!;hH}) zhtq(1PSU`OKd4&vsxk7dL6%@_cw&VjYNqK_zx?Ip?`j;A(_GZZ!&U<;x7?ECs`Tw0 zNKYT&;Zgjtsq=6=IQWrVqP!O zCd3kJpuon*F|mK3l463HdtNhGw=S1=5S25G(o@600pk%7<|<7Xr5WaaixB?ybQ@p! zmUw43(XIKsL3JaQ`uoc>w|b5lQY_Q&Ea@i`Cbd*t2{Nr^0wiZ)BFp~ch{p5hK~qYt zpOXj(jt*dC0*z=Ycrcb z?ywl-?ET(enP)eXrzc%6b3_#CNa;m1l; z3+kplpa=_&HU?F$46`vUq3Dy2*^d_++SoK}oe zA*etBu7F=xl@LiP@M8}9fDbd_vN5g+G~;#OF<_lL0ShYc)XYsy~~Tg^APK>K$)o=}n&P+x9W z6w;eD5u4U&#$ttLIgxTGl+rTYyydUa>}a)_rIClfH{m%w(utG4=^$)4UyKC%;`{f0L`8< zgkkal>K2oa5=~Fo2{OHO$Dd1*vQOTLS%4CS_tN+{mbpEa3+8@${WP^{Z4K5$+$8rh zT5V|IeWK?hgm@Hzrq=_LZSG^dJ-|*5q*gHG=wP(aUjL;T`Hlv}cT0VW+aRL}kAM=% zO$U>zGDqx{o(yS0<$(%ZesLW9$g&T2(U<0s#IY1vuJin4V83ZC0KskoVdD2Lq$Vb$ z4s=L5eb;iz-AkU=1U&CFPvoa_ym}vpcI@~lW~c!+>3M(gKmh||ssTKuem*+{D#$z8 z8`c03YaZ=S<5DRm=D{m?ncy+{hppNEK5a8Xi*hiQl>?AFXUVM>5xzO8_;FDkpseB} zi{O}Nex_rE?DiOC&iWtmsqe{5w}~WV2B>p|-|YnLQeAH+)U4`?NQ@jJ>dR#VTR!&~ z*q>n8xDFKn$Rc2>k&IIl14qca7cgwRihcPk1j%;xB4c8V!>D!Dhq>CqTw69R6dXN> zc}1}%E$iE$Tkwgwv}fVvjHN(GpA{hJ(T!p!>L9A{~5YBK_^c-d=ktg_DjAZZ)ydRn?GdvuOcl?)0UMm~)kuqK5`}IPU8( ziD{0>wbn${9XeO_Bm{qq9f=RJU)hGoKCp_m++EH77~NJJ3Z%mE`A*UUhPF!sY$r1q zO*k*Kj7VsXwd$CuQ6i+VxbuE44&u=pZC;?&L-JOwFSz1wmZ%X83ccz=EQF_t zYGjwUvkn~Ny?+5ICI~JhaD#+y!O<(eYC!KjV#r|9>{iX!xK3J!f!%O^JR<)*(YdPr zHz27K9-9@OTq;(5>nbu;P4L_Afwp{F@`^tJHwJ}pMbR=L_l|oBi}56}p^Vu(X@=s# z@M~KVxYUD5gqDnIq8tz`;EnIqm%**qwgZ^xp8bp-R8ylhY}D-mfu5kYl$aQwq5L{< zkdKI985>w?PuBx>zTmIS&#}iFePPYdp}I*U1t_(kM&9c0F$W0eDq%63aMIH84>X~H zU;&`T2_1zNP%E8dBbDUR$&vIVR^Kv#d~7TZDE0|T*JRD)wZP+bSzv2YlIA9 z4_L`}LF=|0O{zYTAu3^D`T{(P8>h8`Gc zwgoHL)8BJaNT|iEW9V$dpoPfbja~iySnT@2Gl(zpaL-3@1pHN65sw02@R5g=GG5SC z1QYrpM`Y;sK~KL=Y0#8#tA>xOH z@IY>c`=bAB*Abw~r3s=M2*ep9;JL^h3jww)&I|Y%$LmqLx0Ry}!|(ZHH}2&!%0ImT6cK^^|V7vlu zb_Pb4#!e)L#-`>rd}LQ0-DD)@AU-m6b~$D_I}u|ub4d>eV`UF{6(bKzBOr)OfS-id zjr$)1Yhxz^5;tor8%J(8KC=Jf%l)tapJ^sClK&!cvg9NCUrK4n{Ui~wbucDjXXIco zVqs$^;RG_WaImrgf%GH*W)?0cW-cZcRt6RhZZ>9a0D$DbAF_Ya96%=AN}}TbE$iQi zkIc-;$&Q}c!kVDv8@CglGE{^z^@yP*FN{?mqA!NL4rPzr!8 z|AYs!3yZL`iHiw~0=QUM#DGG=01hru06QyCTm%3R2L2CL%Er;jz{bejr@77l4_X+p83EYtu=MNG%`Hd6EE?x9@kuTeehX9(FTwS#V1q+V@le`6DX$;t~VqlB}*6YN&iqC zjeP;WkSA0mDVLXJRSXoXXsX5&j>k~4#$YRN2!=tyC4hm$x`7c9`L)`*@{Bu8O?Y*0 z=3ZW9c`}tjc{#gZwjby4n3j~LD)_$6zmIf331DEr6@OjZzf|-0zi5%}e)8lOZiPnV z9_h8(4t9T?7}ULCp*=Yec~f?Mon*e@xDvzoSmZv0Z5Qta62ILPbHP>0H&i`4^I~Ml zi@iS^UHK8$dBWB5`u)hdeC9@bitciI`QxO=v);2@mm%vr;DWffrJ1WgYis_jCXPbh zT~1hW;x6S2B9D>xI*6s{4=30%e=gtY1f)fVbwuw7K4ed7K?M?edeqU( z3SfB4Co_c0&|!5HY#Mcd@64BGlH%ne;%F71MSRL4wY1Hy5VwC~`M;6#(6y~(MTP7# znzFm{JnRgty0`4II@oIW1(gDId^l{&sa3BYKC=@izdfaWG7iugwn;%TGIn%`cfX=i zze;_RFCij@=}x%7B`%%LQXu^#rQP%>PK`k5-%FCW^M!}1J+l)$CrBZbewI1KMA%Xm zcHu1db!g3{0_$zI`%MAi`kfodmG^#N_b?!TKUZwWVLhu*>O*HU)9H zd0u|bdMoLM*(6O%X6E9Tu$c@JInZw=Ek=J{0OkB#F-A-fAbE9ga{mtcovLbf3z0&N zec*Uta2f?`D`gkBbMF|{Y?iG3Xs5CZ#muclYG*5whhyTr z0bCqe7N2pXZVV~Hj|ttJEqP)=q403nMGnG%snPA3)sl4tiXaDK+R$DR_CShAHpIql zGDSY4nuVrL+a>F$0zwaK?LNa&&dklGpVm>!l%xk4dwa*TP{g;lqk?ze8`tutEw3r0 zUsY&XP;)CQkywjr0y_*R)szJPdgtU&V@p1VF3VhL+-Fm|6Mfk;SFABu-l%Q{_DB(b zl2I_abw?_k&m~K`f~}i7z@Z!Um_(LjF|Y!O<(FkbI1TDS()4!6n52YKtQxa+pL4(i zFBwE8qt2Xyhk~@bUG2$797bQ{rL}@DR9eUd*Lh(!V#4F;qCw%`i2aVM)knjfwwP18 z+~1yezkq`xT)Jbq30aM}TL}--ES1e+K9VCSp^(zVfp_kSm?>-}2MV>bC9O=(OCC!1 zoV`O2C^9j=z~WJAE=^!*8tKaz^KoMQR|-EV?F$~S48Qy77!oIZAkS2{9FpjwliIxd zm_*_hcwopcHiQz_Q+UbG%2ien)8t3(U+M+AgsBy~HOgh&B9r(_5jbEN*7HjN^%*M8 z<-lH`%*gz=Z}{je%W29|o!`@5?ObjXZ0B~xkMEDguBSmV#*@6?v@IQk1KKTGYkbsJFNzhc8b09ktzJ}5b*19R9macqz(gwDanR7@Ql)zReGp>%fjvNg z{`1yA=wmX@Q9sXxBs}bkLGtk;F5<87uP6FrFD-&N!(vDo%}UmTes82WLughtV|QH1aCfuZz?)SZgyn`<~=(!{Nq-<;@ODfJxydk=|Bu(=p_ zsvUOpTe6bcd=~7ww!26=C%+=xfh7FjlY z;#v~1F_ipLjq71ylT<^`XXPWxyD|!x+z@ll?U7-a{Lpq7(4*8x^icjJay>+?Cl2JV!j$>lUR1c5>Nrq)}Mc7;=JkwCp+kx#PRT*+QbfiL@IPWpovY8chz zjLVpn7u+ow(g-uV$}$8+s717`Gm}s5Whi0K<3+fJBwl|UjYeIV9H|4i;;hsNu3=FzBlI$1P0|q4l{K=$N zznvCm_=cjE{VG)g0ERa3O@>G5_%smNV1dZ1{P=FE3m#*&!DA?VR0Bq6uyGsB=bpF& zFMy?A@_CC@b~Z8Aylfbl5ex8{-s+5t*Kn4GB0P{b^sp5&u#b>!WWORz+_wIrjM^eg zmD3&Ev-W4F_$TL|&{qV4^G)FfuMzKoB7DOoyQC2}sav4KyC$UdI&7f~=i-79siVJD zxEY=`)BIuA&#>_08~!ZsVUNOaB=Jp z){qdz=pvfykNdE4lfuW<8|=fyH}LaPx+&jynPoNDieVOE_9Wk$Hz`}|SLZWN0OrJ% z2Y&R6!Xa0gWvx<>&uVIC(_&7Q=wpL_6GZSw52y>HTicx!5yW{qs}{WsmCQSLs=fL$ zI~x^FW@?%_CJ%V40g zB7iKbRC4fHi4bh=BhthOWdo7nbyWjlk%lwWrDr!m%Xq>3KOFENvPfNy!(g)Bt|wM- z)wAHfck)5=W<{OXDi`#iD=L7;N*X!0NGMnFnB)@5(&iDy2=AVXs&%j)T|y)g+o{wP zGs0rvl`(oqM){G6#NmJo6I-q$GNm}*S0w3?K9aR_B2;Udt*eDLrapqDOxvjm--!tI{Am*BJ!L`?m+u3zZX47?G(h(wvuM$A?*#9kJ zS!j?Bf}OPE5SEb!Dh=~Ih%|*9Zfso|q0YeMkIl@Ft+=6{uSia5Dq&M)T!LUM)o30= zaW(TI_BmGj2GB6#ipje|ntqz$xl-I%Fi-U|ZW6paj>^$3x6?&hFt2%Gul6HFwS8kl z1|tOPFWo4BC<IL@cX}og zbjh#&(79oV1Hjg~jFaPVIoLE0Pw=C|IHd(k;9dllMr<-v(Gds8{!2&8wG+Ahnaybt~aKM?Q z8+z+2yOfY{92;SY@PLqf&n4CmJVSyjXR^o?fC}9~o6KHW!`9fqzCy%8#K0X{+Aa`K z{2WA3$9b2YQ+~q3vj=-7T$om)C@D_r8_$xs_;m~h#p8x`+7`1k{moNLGNK-O_&2;d zfEjL=*;q_VjD)8oY!wGtAVz*bAZO0iyW)pi-%2i`n9Ui=2s=!Gp8hl>gSqedU##$# z5ERFpHro77nm7&SArMadVXTQ3~b6wZfxca2=cO^+l&}Q}l|R_=Su8 zs;>l-GxGl>K*bl(?6|tD?}~*!G#r%dcr*xqJ>%_`a^8_nE4u~;t`Zj(j9Tckp&i|b zo}J`o-l^QjMyk9y_>dA>fcAEDG_0h`-nUYT9 zb*fIU5I<4a7=etZ-|vo@iP8%PAt$7vIT9cSPVQ0s;!=UGxnAAg1rDzrP`xrEO94Zx z#MeWb9%AM)+D<)sP$dtSFRo`0a5hel+YN9>SMteHyG?5SlufR#joP&IE?I@`$D0Uh z-Th^eozIcqDcws?Is7QQF+L+`(rq!7Bm^!X)%dPAPi(~V9%CdSCEw~-T4~akK9GuF zj;z7G0I)VJXncu02`sf zSwbh$T#z$pEQDBt{YJm^ouV%E078QMwZJv2Z5AI5E>IJ&XURZc2eT?B9Jp}u#mryE zE2lmHD6-c`Cchf=h@G(>1VWlEo#>$r;NXI7OQOqQ=5FxZs|ImXKqj~OeQWS`5L|5} zo*QHGt+=02z%>1d&(C8n5YsUWH5^xn4)3xIUjUn&7;7_PdJPfFq19dYGLo36yuMhp z%Qy&3vXBRm=fs~QTr@XOM|Qf@Z%?6sKK1Lr?CLvse3=vRAP1r#_XvK<3V%U^9Da=W z_<2HvjL*9kcA;WOQQ}as+U)s54!M(;Lcmzp8uTmd=jPrN8@5+=CjcZ@u+ z9T;8Ow;k?tPfE>9&A7Occ$FrvN4`7^_ExX<^W1gFM54J!#9q@pV$|6g#%xGMQ=Nxw zixBrm^Xa23bdtKzYQlrUHdP=cwi zdB%Z5ICBeA!!jzg|1v@@&M1iS))nSBgjDN8Y#?!y4a!Kx;z7&DW2uqavO}%~{1O zF40+w35_SWO=dm{n#KpGRR_;_fSusqeFk%M;*MH?&V&nqbA+RT`}w;q3Cx`ShU!K{ z!#^e*+E5c4w!%(@0<3?!SSMd8`ar4^=oaS<&_+fO3?#kpFJ$<~pgA znhrMvi6*qCIATKc%MVe3IR*MdZ&HXQ8t0EEy?`xqCv`r0Y{SCPv*lj=AN{b=Oz)!I z5aiW(bA;*mbZ8Hh4Er*iQSAAfrLc8I`%@x;J}>v`*M&9BRsJU%txmwE_x|;x=e(b>LYk?iQUP*{lNAS?kvUe+sYz$tz@7?h)wqjT2A z%Ha*m*yJ8F&xoF-#?h!(~_uLZ51U{(CK z{HWF-w>Yg(k(1yq!|a>5XcmQLG$KTU{a5=gb8rjFBuxVPcUrPcz^cq6NB@JFUHtm0Ba zr84<_@7KefW$eWm#x`){V|Qz@<8B={~fLeN%7bmFcDgF)Cf1m!N6K-0)PXZ3Ha;d4!Sb-bS!1~)Ipx4GS(`!4k^nOq>* znA^V1;DpIJx>S9ivc@ObU@8C|H3%+(uiVJexs53%20kV&&!#{RpmqUu@+NaE_sbj3?fJF2_&rqEA!4Xqsny zFf8+>sQxkj8%E{I?qQje^PfwWa|C#wr!JE_8rN-F^q|M^Qn5;M3ylzAZ<5MA;{eUp z(Fo@XW~h-gE7<6Bd>|O+@e{A5v>(FUAtbU~Kg8F}Y@v4Xw*dfR8OCjY3w0HZQ6)A6 zx;^FFD*QuKWCz$`eWbWVwYaz=Sip+^OVpZxdYwqjq7Xe zGI>3e6KqwVNq>MQ%0C^-&jbpBbC1Hv|GB>=*HQ(kXGX4_=KXuDURRb7**vV-@sDK4 z-!d~Y6Uixx?+!5DZkZuHB)I>!rF)@Gsb=NoUV3C7j5Bu>I9eRp+(i?iQPUOK6!AEH z>=bvXac0YtoU4M-Yl;jRj}3w6gI^!YX96#QrwU#dpO&sioa{RZ`Yx0yS;8G$#tnYP z0X520RgKY%r{Tui+Qt(YXtED7HmsX%(d<=!7*QnxdZS&1bZ;(d#7P z<-DXz-Hk>n_�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 sF&FEFn%!@zc z;;UMtx9L;C6d0OC{655%(Brs&B#HI@4(ij$Se}5zwuJKi3%SZ@NCE=sqQ{w)Av2-o zefv0N&U?R%z};J`o~P#*(%cKRMi+$;{a~=MOQq7vpoK9m#4?KQFf*F@1{gLP6IWjw z-#DC=RK8ZmdF{4b46)z@fn>F40)WGYeD047!Ux*0NhJRFPvvk8;3wn`gJ=!u|OFCR{fOtQ{LN5 zQ{uPQhatzOE)3{qk%)X_DpLby@pyr_0h}aJ7}y9QBf|3H0h|8RtA8g=BT5IOb+!}e zfgz}S3q_%UjCE~%y2Ogjgpv@TWJv>s{lf^rZ#WO;R(OG8M{rq&)5xrHTJ!cTik4ksk+k(nqc>lmlFLoaoD96i7D0=+t-maCbF)@j=#w8n> zga7q=A@wCF6L zeqr*silEcv0;AP+n$87?DC_~KX4*WoOB|809n4IYLCDJ|51pZCoTWleb}5-|w1e4ZwjmVyNCY;C;@gM%Fp1NLSH_xApT+1qar6zgF6>p&Q^l7$sN z@2=EAMidH4x+ox7EP+dj@dk%wAqEC*_Ey&$Smnh^@D6{egBL%dwn^vp|QL>*&&J~DdHrM)&fYernq2AFJgbMqSwQ}22VyG?U{aEA8{7puR6a~ z<;(V1x5y6K{1{?LCR`XIz<%a#upOTO*P~+-vJxZ}x@}{b*sn&aLkOhmuwfHZlR&pM zN>ycgq_%=KCg?=_|ZnOfI0Z(wf|cpH+L zl?L~X`S%@hW@F^^`^}^+MYL5Ju2py4D1@|%#3*y>C4MYCq3)ry0f!5zXjTSvhiafK zIe9xWRDU?PUOdA20uo&?9{PHlU7UJwveCu9+3{=*GxB@IqkjkhDr3A+S?@QCr;+2A zr|FTWuh#V)M=zZwx`>EVxJ|Q35#af~^(t<6PIJ_uZdkszx(!9M4-tL<| z78+f19HqKSZ(rv6kd_QDPSG%7Dx^qCLYJHT%?@$Hww3SqIPjhli>b19CWS$K!hW+`wb>cabi=?f>Ow*S~)2P(fY z<={D~tPAxk|B~cKghs-OC?O=EfGljkwyW_udr$0MzwB!K!p7qt6Usn5{%dbH>OyG1 zhT7&Ik033-l2EAq8#au+e+m1B6?UUXoa>*ZUsmNmX&bU@k)ypw$0FA)x4e7FW>qz;L%AsVs#w*EiCVj-n#R1 zp!OH>Hj@M=p~*Q+0&NBctV=?1?`o)^U`3(`%rJRysJOf|ihSLCWP{GUU75vrrvlNb0ql8DBuleB_q2r1kbVRfB zVnG!M;gF9$u_8tsxoZ_TRaRTUNL7`kkIZMFB@I_V`XON@-lk`h+Sntx(Nl;;eaEvA z-jmr9U&~P*=oN|Ty;O05(0zvf2FrE^>c3Z^H&P8fgmg$#u3KC#S`OD z9W2M|0_KKR zN2k>dmuRUtE+usIhbW>o=zzLVNvQU7Vxy!vBx_-rdj)k%^OLnBX16;_^gxdFGW)DL zKF^@9o*{U{W8-+hU*_wVLCJw~CWgj^GfzD}fzJBXqv&ZkI0h`vLhl}UV|)t*Lx@0Q zNr~hGrY!D{soh~c@9P9xqrQ{{t|v7s73ywGNwX>xrmha`7LT9$Uhu>>8T5FM# zYw#B)5X|de*4t?1vKA?{adK+CL4m-^@ftR2<;93PhrSU9D=*rMz}N|(n&wae*A#z~ ztd@vr6z&y=;fU@Nq*51H=kj^)p`;`Yhd zIxR>Hc+_JQSif+?oSgOr(!pfxGVqfT?CAe z#DrhJD!r4a0)WFm#x?xxdsvt%H!M8s-!@);jpXk)0UAJ95>xK_3AR_y=2<7Vqrr9$ zAl8@j7ln_P$=cFavQ7nr44|fOn$Bk>tMk#R5bS)>I_{1K1QyTDt!Z1NP;yK#zVfJx z5uL1Bc3uHA@=M=OtQwpdU?RS6Bz(mK@-)5;XIbY@Ii`jANM6qZ{%3vfYnA3N<;hEl zGaJyMH=B0b%ueM{Pn1iuT%IvK{8zoKqCms2+}m{~PK8U9n>lpvcdmp1Nsk#g2(vJ> zEVS&l&NfCoC46HB^0Dj<_N8U}n43+|twy$2)ac+wFyB;s?54J5GK~ zD_nlw9&8Q&{U{tMx=6DRlMohBbwD5282HKcGSe&X?f7(t^P3os5xs7tfwvoJp{D;3 z$G;jS0jjNIz8#VAL-aV#>-}i3^y_B*ije-X$v+}3wVs?yn)@fd6IpP8PX(q$B3Se{ z9a4K?l1Xhvi3nDsdO`7-V1BEP2nV$pC8F zK7lkFJw!AQtfc(xMi~VZkV&TVaRrB*>jxbb@9IT4up;9$H}iApV+-?E;O1*a`urPT z&f2Q<(}WF=yMfP9E+Oyj_J!~D_T)4X;7ioIO||*vc0N41qzNT8h{%|7{GbrXncdYK z-=j1joLzm8Z(!0kHA;Uj0mn)>;QDe4`uLl5Nwh`f>k)~UTF*`u{4SC;h`6U*X$#k@ zd1|cM{kT%Q^H=ttKpj-k?!Z!Q||kv;hPhyZ^h~{M&Z81Dok}*=~yn~#r{G8kS|kb6RIk!{5@k6 z(vk{zBs}MZRQl@)5+A4Q?Ydg5;~H`-s{E6L-VB7~S}8qitLy+f7ObRk9wF^i;>sPA zJjEsWBmU0{VSfqfk?K^zir<=V_U8~AzG!x!O!i)+rihUMAXhPc_Gb+L$FkaA92}mn zw@;(5gX`JDUT=rFhcPwXH=~O{wFTwM+;WBKv+C9J3nU~O#A*yvnAM*{yu*MJm6!A+ zuPVpM$>3$8u2I?GEFqyQM5lfdiO{)%AQ|6%{9XiAVX%%JqHholmnoFVm2{L!I=7h_-tFg6i;Gb)OO9A`PjDJ^A8$^ba zaQ{>RWA*}FR6p9g=-Tsicgf@4bqXO)`K8HBvw-kN9VsxRdJn@NF4RljP)wdQ#h%mQ z;RMA2KYrw_{lT*sVxAZP=o8u~%g4&I%*4NSx3k4Cg)Gy_j`kxY_&fxKbGfym?Bfq71XWa;U89zro_?iyB;Y-19-6y z`|QwjVm&TqnPSHLb{;Pv%J%H3qoR|G?cX=quL+``2%4YBfI!uGQdyxNZp?1T-ZOkT zN*~Fm?b|>%ufktm78gR!=x-XT)mhKoqlKXtlO>zhvOz#79KD1n4`k^SMar=3O67+G zmkytgozD1)P=o-gJBv*mhl9a-dNuKy+K&72tbGKrfV0e27g+z8%L=V-g(6RrS66xe zbw3z3-m+|aia@ihWGCzyT;hQo)BSMCJtqRmMntx5fzIoD&{g@7K5y$zfjltWctpd? zAcNP1%hyuG1dHAwD9N#iw=bha;%Hj9+p$nr982R&8bt3PpEy$==i0+I zpWDHM%SWW8t8x;MyLIQu9PgPUnhgiVRGmXA%Q#N#YU~vj_vei0>;Ce)(Tj86!yo>) zp-ZhGX82o?_O@($Xr%PKKYg1WYDm%5%om^9eD3FWb=$-2I{@Lz0C$M_jxh;z`oHKC z>-fv(wt568bScjALlb0gD3vCbc0{Tr5c*-@4jNw*uE#uIXT60A3NE=ekHgu+Xy&I< z1X7>L7KPOu*o~H%e(r)f2Il6)FSN$&XwA^3WVEcCFP~c%frB}xS~zLscvA^BrsNMj zcT=1WL<~_zN(=PO#UzYXD#$b< z6b!de>F*B@Jc)`IY(BX|^?kt$$0oOVx*J-ooyJ$f4QLwAKbZnn z#iwKw-9+cJd=GamMT0F)|LXS?wzJn>=YY>38#>Y+OAe8eFaJ^x7HzJ@6<-0viLbPfYcp4Zz zUe-@ERl<-luE9Aj{%*tE>lNgF)pFVP8Jkn!=TRtcpJJwW($COuIJxdgtKuQtLz1H_ z+ETf@9vzPg$V4v#2fM?WAF4CQH=iOghTrL#%tEX5R&Rk4Ka`u(6Z&8(+3)onCxyjs z8aRMow}Hz+VMGm-a*#{&u$nxlfB|h<|#Wu!0+Kx1%VRdOk23^}a^Z zj?MCJ)I75aTh=IqPyPFKEj@(#b!c9CHKs4({u+m+t3)zYZQ|dII6>5$p-}-Sh%*^l z8`|m_#q36t5ljlxtb^*5js^QumpFXep7d>fwg;hUQNki6uUZ@9e21tI?J^1e03;eb zZcmQ28_;W*D`0MLJ*H_CFC1g^-f&ea@_W^I1Se!cb&#?=yd%3*gnzBzn_Y2HSyz6K z`SS9)HfO(IM6a_~x5Q#tKtw^OBFw+6<2$TCea+&Fsy&2KV9v!HsCbM^R)V0J8u)=< zbN@Db)l&Bm1Iobo;f?}Kj@qc=wawZk%UG`|*YluZ0*sT?c72R21plc1bD7)`XNk|y zXwGGWax%NitWY(w;_x~;-4K|lQQBU}&nd6t^}FirwKgD}@T7!jilTT^)IRZK`pu5; z7Jw}V7a4jAa({fVIhxoheK^oz#-0LMurw%=S0%=r-9%M#qB%8({9A2R2Lz-tDB((8 z5lS2_Nh6N4iq6yiu~I;65$d}wR$kT)D=IlthfP}0SjB3|IdFyZw!NzUBzbU2{kZh2 ze-i(!@UcFEj!D92aK~ZfZv8CS+YXlah@nRTaY`iXuB;vSc01<|V&GgfvcpGRVb@RJ zly76kl+g}CWAwkdTzmkX0&#JAC<+tV`U6io&(J)@JBwv9$R-6I6xUV&0VoEgM2vsz zxxQa?{eFz_!6$Cignql>6rb+pPu-`Bj26hu{=AqxJEI?dGKy_R{33c7JbfQC;i;8i zRSx=7#S88@J7L6}ZM^DW-tce%vuqM6QiUGa#cjEqBP8TcNJ3NrdqndZ#OfJH$Pm4s z8mZi0l-(IW*G6w%*YNH4%0ABeFr(1nDY0ZPWWk)H$~WFI)SnfG=;%i9JCTE+W37u< z&ZE-L-lK<6v`8@dDX*dJ$`s=v!^g*xX<0gA?S$~>G^NTrlGuOyTsh~{R)L>4+*0cf z2F3Zy9-?wPmK`_!U>9`npnm6ZUNT?vQzY*1c_&-n&&XW6a%l0C1BM^D;tRpY*S%(k zf9Qvje&|px*F`+m-xE(WwS4vtMZaqB57(#c4)>n1-VJt~UGSTfxXa02_O^7|!cG-x zK_>J`M{gb8zD_l|emQ6&X2X^s4E?w_(%bfMcyWw*8bl`qH$oqbQ&y273fK?i z^WoC*y6+!ocEq0&{jnW$+yfp+{h=^xV8^0lt>f_RZE!sl@nu-9;_LFYICc+BXp z`DVJD-Zu8h$Z;}DulvFYuM#N#b95^nk*Ik0HCxQt@r$p>ayKO4oW5!wJd75xk9jzp z)9B^}$TMXyh$Z~JL!6ljt1UPzFq+#=sz0}~MyFQK!{|i<#WEqYij zIvJo-p*Xcd?runvOU7)`9~3(M8WX|EN2^rH3$OREOw9)W4Ni zkD8bz(VbH9%hpA=?JGjkDLDT5G@Q5sQdoXA7Agr$xMB9s%zju&dLpv4Hh zitk+&29drb9IW*(^G~Jft)A|EV%@wJy_=-S+@p69DaQp`mx_0{XMg^>uDd9`ciwV8 z)$aN{NR)O?Tu5+mOx5Ug@pQ`51S5NM+IMj8T&iVDUbJJq!6bVk2Q+RPpYy^5* znTdSd)G2pn$^W81E*?Bg2p!L)w~Am^_e7l5;EeKV=5Z;o^2f*jc(~~_Hv3Lo-?N(V zyTfmt%(|Gx4C4`zdX?Ea!}wxPpWN13-akqp(VQ!FeWr6)p_Btsj&hd%`Vd{&O~l2B zb&~H+;Nno)`c5$y1t)%7jzKdjZ%e7kL-IVlWi^{+dS1;hYprMMwYN>l2*>6C`<@V$ zeDneQV{mTkgfm3`VzUP2;Ri#n9j4Q^E46l5xY4EaT#SQ5EGjXX_i> z`nPKkC!G$bE#n5pUsQ)}tZ<>#W2m`!sYi*AUtRK*`QCfnJselAKOMdUfz5<>a^(?3 znV}Pt0Io|uWs#xiKvB-MQNoI^7^+fgd!kD58>cv1vbD+OM|f=7G=qbKLOmU`Si0u4 zkW9{!i|o@$vTpoYwVitCu(QFaq8|j%WeZ$G3L;r^{4c&<3+>K7rOc>KTdlP^9Shwb zJr@`89d7<)ZQWeBop-3m?+hl#((ZK^Ah4yr;M^&9Gq-;^b^3aBe}>)Y=uN3;MV{)} ztZ&tWh?_a%xr4ACD65N$v%k`o*9Cq*{T-Vhr-Y2^LkG^3YRS5s^iq#9~$0sF5!^C z=YWdwhwA(}5?bBrF11cym%+Q(CgvUOABndQZ0kWx4Qop*zA6K$0Ws#?~U zAF(P9mDcv3x70gb*=z(tAok;ayslusvfajxU!5-XM#Y?a%m&8n5ImjT)RvAvZ)=x5 zJc~^Y$HdmP+j6Ye^=M_%;=Q1?r@MIVb{6j&1iR%043V5$>Oj}`gChMV@|4|qB@Wtg#Wh#Ud>&ET)>Q){1r6g>7moB&x z7nqevYB4uQTZ(|LVH?ufX8wIuC*})($9MsYoKX z`j1lu`o(H`4(p(BcEeRm#F8|?f+WnE55)aWmB?sSpH^P#$4;E@N8dUo_1*=ia*`#O za0+KI<8R}4&Fxh@mUhU#Yj?44f7Z6tEZ*;nr|e0Le|LY}3c1WBU)HY_`L)KN&N*&I z(%_^wE!)!Na!iQ^7mWp7gIzlzrJ*tdU=$pJ;#fp>Zkzz>vsy`lIvthVX$(s3M#Z)Q z@z9m{)DrIDZNow_$r5M&RQo;yuH@Ep-|G%@@(In7e@r;qn_~nfwce3&u8$5L?W7<1 zBaq#GE=!rW8hiRYkCp3glzwN8ub5mWA{1{yjHcfV%&1g$jYXtgy^T!U! zcPF)hw~9Y}Xi9^)ob202dMZ@T(PAXsMgeVg6yHZ#23Tk11q96cD(iTMZg(#F>=mjk zeskYqJusV~DyWvkhP@*4HR`(4v+3-Vy11DViJ9h2Np0@jq$jFM6e6TIL+yvxhH+zC z{rSB)%7A^dv!&~HXUt7bL)t%GN#Ud-%0Lr>$W?RfF$XeF{-$3}`yDQ6klhD{?1|2k zQ5@1>n(m zDtp*ots&}izO`ilhu+%ePjg(T1xQMdl$Ef>vUWLhdefbyl(4UcJJOZ2CWl}btsxh5 z_oU8VRXSN|C|j|e0KNVJrge4ON46oI`J`D964mz5l;s<5@2mNW5!4BOPKdmU{U>$% zj&$+NR^I3M$;|esnFty>Be%Z4mSJL7aRyncg7m9@E7XSGcg)CPU1HoW7D+}nhpUR} zt}eGFpmTXs9nXXAV#Yu!8dv9p^i-WFQ?`Zr7#CDz->6j(53=^)+cjJvINyT98E3S7 zvONXn>_VLU0JfZ`vWYs!)T4FANk=U;N>&ZCSiyKC8L5De`L=0wyExyl5?_75-0sB3 z>HUu8peE?wKjAGQOlf&;ZssAM+CRvFR9b%2ZEWihPnV&8UX)0gGM%Xt;PKAvl<_!R zZ+v|H{zwha};9|YftX0)8)Kkviw)|F2vkP{uca)d}!+;oc>(XN^YnM z3c#tdq$<{CC!T&?QtWUY$?i?+=HfH#n|KmJSmLlcOwQ$&3<M}4 zfUK}~7{e`x0CS#v^EMw$+mAgpLV*f+2Id)>hjz{*vjy_k1EKTv;V)0_yV~_6b?n%` zYHM-$qn&PNwy#-Q2YFRP&LM1H`)4%mXu4tRdi~j3KlHp^?TH}vCzyU&WgmM8-kGS( zRr0IpXSgIinO1@+#jO{H4IKbi2{-~2F{JE&M8GSxuF4fMa~CmCDwSxhxcDSlEw8_d z`I^;VeXjoYitD zBFRq(Bq(X2sa$F%Ta(kOTc5;U@^u=5n1K8%tgaQesX+?qP`1lhf#kgwJZ|f~zoe4) zXNx5`A|rnzAE_-c7mo6?ZTi6|mse06Q*$K|UGR|;DaHuj{GWfsH|{#KKykWKx-Qv7 zTE43~sj~;M}DYh{##SUuKGE!QK*{Jer^9=GzgAa3W1Y1fvQzIXFrd}8|h67VjSyk!E*1|(fHAUbm* z(iCJwVG(^5{L*wb`KSLXCm&ho!zQMh6_OB*pRZ}ac~t*+@A2bhPfLRsd$M`_K+Pgm zA7W0T8gm$0)acgZ;lYzzkJz1y3nj!Yob)>NLUB8SIEt`21?jt*f{iDEtLqF3{6r>` zv2H#i+kb0%X67px9FDyoYpEq^JhL<_^k3O+3}3u9uX(TTt=@X4{>Jl(XBx#%D~KBP zh|-}{Fp!t*<6llM-5hFKI?j1i$83wLwios3DdCDqvdommQq+pl!pbVYvg!+n4{n}y zJAh5lTx=^NigXO;$ZZc4$Wqe_vdDG!+R6}!9EzA=MP|xtS^b3ajYMqO4 zU-6_7pZ>h$_ZERRaauUQ>H1sc%}x%S8CF2BCMyF2sn66|>M#F0zJHLew3&hzH7t`1 z)XD`0{Is3?^XbKt>fj!?O>A=M5Yvui5a}#w_;5ypP9@*d?Gx)8Rq9&{HZ}!!i{_QD zV&jY=P{y!TAf~9V_jDB$vNO$8oNaXZpk$cK;u36%X%!12va73;H@PsyZB&ZC46kX$ zVPhhYcI2hDx+|>J5(HA()^3megZlsa6PSJoLsK=((iMiHle!>e_#7E zTs{N~7)d+gCR<6)gCH0!A8#_9UcV$nRIEzM>zQnW23ww}x|40HVyy^}40WbURxto$ zWZvE3K8Xk-Y%)TkHYz@86eKshSZ3R=1QsbH8miml*j;tgzR&T>7m=9f>haajzra_o zJCSv#U0KIbD@a1kZRB74)9LwJh?f2poJW0OssV+>(ujPju{LqG0;ZGxU0A=A!A;4l z6~qA?a3NgsAwVk?livrg(Y=2Ko604x7#2(PY-6m}qJsTxx4c@^YapFRcXCTelwGds zWd3u!aG*kl@u7?s44QsuqMHN$@>f6_3NE}?Shox#n252Oc_H<`(VB(czveplkLuK- z-k3wq0dWM~iI|~K*o2+U=+eeHGO88sFVXOhcqC+(8ehaZo0J==n&MWuh84FSBfwDL zz5EEXaNfUkSC0xF!yZMos?HkzvFwEbg z|EPStSd9iuY zXhKIRTh?c1Y^|#pG6Fg#FRiWT+n^;_OAhC+#ciKD&;~0|#oc7BXTPS(f=QDa zc5MSD#KTj?m5r1ImY=?6ZwYkvvx7Fzx0osi@CPSb}0Y%!PU`a3Asj5l6 z!2)p5up${CZ)SG4v5SAKo{+booKOjxITYSmp>#^xaUb6?MN>h zqFCzH(sPzMD=R1?8SG)aoPsF)Ym1^aBN<2u&;KBk)GOG#5Ijd^F-5XAL?I;f)!CU7 zc@8=z%G9Ulj4f!0DYU|2karu}Gv8S|Hx!YGWlJt)b5RSwI~Z5@=UTyR%@8p)(`6|; zq_wVI)^gI%HHjfwIfM!H?AfsFe4&{k+f8@6eL}HdmIfl!xLFZ3-_t2jJ`sn}3wzp0 zcLZ;|#rJk?6e{=$VJ}r!D1SiO@%;Ssh^wHn|w7 zKN7octHwse-zUyxrovbR-icp)t&sZg$_~QjEieF?Np-LM;cREYOsja($EK@^;NrrE%wv^bNk8fzZ`B*o8p!Anxf@4A#yYauvz)VlCV2(Groq%OWB_@n zK^<7;=GxS;(g13QWyXv}G73X514|6uVzxLIEKdTkP9Z@>BkX^#di|$dDq#p6A++{)71BwH@ zmgfEqAnC%2fX5N76|f1Vi83$QuGfMU;3R2e?+mauYXV~TF7&|lM(Z6cW1`n)f6=mU zedz>=;4WiPAX`DQmaO@kX>6ReiG%{7PzX<)e3Q z#4zE!NM){~d;vW3)?(vCP{+z~vux1oE%va`8hma6p+}ta82;OCCVobwOy*RnNrx1| z*|uOUt`^AfdA>ZB)~dHL;7iDLZW!Rw!+FrD7Y?xlO@z3JT*xD>%0s~x1p{*%?qqhE?2M=r>!r25BiA6PHCE1>CwQDC5 zGdg{Fd6ktE)4FSUBocRa74j_%@k`>t1Z7efC#l3{%>+V^n}QK9C?$^3 zikDav)kxjA;J6GfX#-Y)(+OIs7h@s;{}7L?q-uVIam_97?K?4Wb3bf_Ld;003_$x* zAK?#yQ&L= z4UYuKj}=nmqXpGs7Q!PSM?dSpt=4{QlA~5OG66Q=wB#%YEjFJ6``o#nJUGqe1c?@$ zu5->fi0W=)2q*7aQ&#oT>I))JQ6Wi5>R04K(!la2l_nj9%4{vBnoX zlzL1G;K;BtnsYSH*15o>OTSV+x%|3THT|XppXp}^iFG7x;1`RKha}h&DqxI0Ej~5W z!S;em3t5ZU%mLDfC^Wh>4Gzh#%{qvnj84AXwtKEs*$Bx!WoQca1s*5+LTpAb9f4(q zls9Olk2{@?+}E-Sv^t`DcKoe>GAFTWaa_?oAaPZUmY4}+7eGH=>A9u93NRybquX3;PK<6Fo6 zvMT|RUD}r0{F%Z*PD&Uf4zpl-(;DYm}bH${MlACgFGi zDS`ez^Z}S)&>mQ)IPeK~w?7}j6%?bqh1k52Z(bY;sA~nt7UQ*_djw$5RX^}9w7pAcV z`JqCQ9w;Mm+Vz6@E8nD6j`Q%x`2=C26)OSX=Ua-G$z5SQC~?H$#mm_LjhjETxh8Bo zj1Q5zYt1wY99lwCAvlhm6DP_OAdLjY!e!$i3PZk0R16LvFjCa+I07kwf51Wr$GdSo z)L9B6qD#;q_9=N0lp%0={$w_{1F-yz% zgKN*dwRb}$9L4(r8nI%R*@&ZaBPl0&`=&rbK+o8T3R#iDXr=&gd3_)$-UwkLd^{ab#w1OzGFMpOmMNTwp zO4wX~s*T>sXYi*s*3C95x=qgw0UIu(f*Fr0deiEEA7w8b@Kd48*hO zo^DW!;iS{-RJaMPT2x<*!{$3&e-x?`&9oRKym6_K!1i8&B>`>uRwiUJX$Bn_Mi*Ew4SamEk;4k|S&JbIbYSR`z{&w5gyM$ITz)ER zG>b`b;F>`$Ayf#72=G{uGaxYRl*h5U8Hz5q-olU;AED$phl*Cz*FsBZiM?Bq^Fc)M$Q)5)fF? zy4fhT15vh^t36!kayD*Fpg%CA*fr8(kWa0Au_qczO3L#pFr+iORu>N0R(XA@=n=q-264*C^~`)B?_J zf*=gR;`Cy$1{R_5c!>TNUM!?ytWrjDakof+xmt=dtSu;w42ftfp^MILV`Cm3i-ijL zyEl$$z{Z>*9zc%Ua$v5eV!sW78WrC9Ub4+C1tsyPTqF!1#d=r5%Ys_F#Nic&&aWc@ z7LzVGz=z#`@l!LVxhjr32PXr+HOh39mWaSb8*E909Dz~-Yr-I}>{@VHrzajb4M$Vm z37#4H8wIrJJL7K3P49A+@+t$9Q(s+?tiZYbrH(AmfVdV49ARB8B$omAEKqW5ng@N$ zz+MtM3ZAwWq9c<8cyRn%ra+)`KWC0i6l`3SojK4ba2^TjbttOX&3N)yZ&pTlQsWPt z7+isZgw^80@q7;K^RW*@Aa6Bks z2@+H0%p&!WgR*>>E*u^Hb05sCkH?x+MB=1wbW%r!1;oVt9I7Q$sAo_l#Yu41!Iaoh zp`@@g0finLXdQe=70RnJbHXMINA1ZJTscar6x)K>m70Fq*^PMWFgUA18Q>4%)ju+h zq`xLE>msLUV^iIzx~fzJtPXWwuCll}rXo46a~LGd9doT|B+)7SKHe}O%(7*}8uJIb;Rr}=Fux{_t!;)?Fs zKy?<@dJW-LlaRFf$}!|1Z&G%$m6@zMin-Fx#WLdpRAnSEAWx~Fw9Uw1T50f~^;C$h za7{}RIbre{(zmvS18^9OHDmvIGrYm5O3hX|FWp5iu+K)c6~dr?lj%{ch^U$d8(1#J z+kqM{U1NsPmR{DQ0uF?uBBBr(J^}49A2@TP*c2K?LNCn5H&RB# zqKbT~GlFTiPcTm@1SDYN15Y>+Ije{)I52_A$pFvEb3zO@0pywR zST8Y-J+mooI63W+F(u30-EtW`C{8LRN%dh&f=aBMSJX_{YCY3YXBa4#xU9~NM%a*- zaWy@uoFd9?7m@#>SP`V$^rhfoczULidwlfeTVb z{KUSSGi86RCDMMxlW0+^0I_0Cll;3ERl5+54QpILE|sC9Ob_Z@Gyi751NanD>)LYHfb zu-$HUfjdmCE9Th-;Ps&q$z>6d2Ki!-jvQ1AX=9O|vS+iH7&uaN5Em}N2o~3iD=&o< zm?d5{t{hj23ZmX>jvJ(yu@EHjxw#a795==?3`bbQ)HV=#C}l+Imc15cAfCynnh@mq zOkOaG9id7fM?rarp#DH!)1LE5$#{#udSP@{f<1(@1k11?(GC4%$F}jTWGc4a!N8)|v<8@a6`heIU{cuNtWq#R8TOg7{)s`vsL6;ooN0HUerUtl8bY3i+wN$!2Q!+#uB^~g#`^7+8rh(ZXub( z${(81E7~mRaeSu07GII;D5jl~5JMJ6DaFe{Ad;1+z@Ve+SDd-JiDSu20kB7w7c=ZP z7@5ivKO(>`_)9rp?3ohA?KiYpagLaZ_OEZl(mwXQsWRl{gKV9&d0gt)3T$}eAU{aZ z`^;b-k8foZiHx_B|1T>hGsN}4SzL<_z9ke!I4dwR+N8Y!^ftU!nXb zLHMHBR^p4X7O$yzNdf_yYGBHVae*Y`9B$YJCEp~>0ir%Alam@or;Pg$2-i#tj_I(t zp0^(;Fu^G{-D9`sHrzMj;G=K~Ep8*NQn0P9u>ukh5}(GEqZZ<~=>p1!(>uXV9a5-E z%s>gwrSfc&CIXENmWa;jvKv?o;KxO9A4RC+*n#+zTlSen?;28M9BdI^=qPq9ae`_{ z4_N8?K}KC{(*icahd=Hli!yi5A*L8+S&ar|u_1(nGFc2@QEsFF z1@7;#*|x_PdQs2Cxrbn)>CJvhQi9?>*P3@yzi%V85-DTL=#Wn^eU@s8;AL= zVA(k_cp((P^)&^Ol>|DdoOezTxuS&)R zD0PW1WE+a*0L^k7Fn7cPH#|E2C%8OpvIFuN9P|`?$m19QiQT8vpDVb`&=BUb?H5h~ zXDlrI35n`1IO9yCpDgEC3{oE~qo;l3l-OIQkGnLEpIP-A#j%dqMRDSeI0Rn#cgCOO z5fH;EGy#6hyy89C{pq8%bjA;ekN;33&oPBM@}z&_sFT0qOu$XV-f)8$Yd8h0raaCa c_Doh9`;{X5v07*qoM6N<$f>iR;{Qv*} literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/29.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/29.png new file mode 100644 index 0000000000000000000000000000000000000000..e667af9b311ecd2fdd232093bd100b13c5f6630e GIT binary patch literal 2295 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 literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/60.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 0000000000000000000000000000000000000000..a84ec4449e6695db772e75b7e15418822a37cde0 GIT binary patch literal 4952 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 acDh^papOSYnV4Vyx{UPA5H))4vHt_#+SHi< literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/80.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 0000000000000000000000000000000000000000..0a827a3a7bd5353a03a340d8b982cc8b643ec893 GIT binary patch literal 7149 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 literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/87.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 0000000000000000000000000000000000000000..50a463dc54202956ccb3cb1f9012b2770f0f0b63 GIT binary patch literal 8114 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 bLT~`-AwlVwqZgpRf6+Bnbyce2R$>1Ke~QBy literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/Contents.json b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/Contents.json index 9189bb8250a..8641b203f13 100644 --- a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,158 +1,143 @@ { - "images": [ + "images" : [ { - "size": "1024x1024", - "idiom": "ios-marketing", - "scale": "1x", - "filename": "ios-marketing-1024x1024-1x.png" + "size" : "20x20", + "idiom" : "iphone", + "filename" : "40.png", + "scale" : "2x" }, { - "size": "20x20", - "idiom": "ipad", - "scale": "1x", - "filename": "ipad-20x20-1x.png" + "size" : "20x20", + "idiom" : "iphone", + "filename" : "60.png", + "scale" : "3x" }, { - "size": "20x20", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-20x20-2x.png" + "size" : "29x29", + "idiom" : "iphone", + "filename" : "29.png", + "scale" : "1x" }, { - "size": "29x29", - "idiom": "ipad", - "scale": "1x", - "filename": "ipad-29x29-1x.png" + "size" : "29x29", + "idiom" : "iphone", + "filename" : "58.png", + "scale" : "2x" }, { - "size": "29x29", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-29x29-2x.png" + "size" : "29x29", + "idiom" : "iphone", + "filename" : "87.png", + "scale" : "3x" }, { - "size": "40x40", - "idiom": "ipad", - "scale": "1x", - "filename": "ipad-40x40-1x.png" + "size" : "40x40", + "idiom" : "iphone", + "filename" : "80.png", + "scale" : "2x" }, { - "size": "40x40", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-40x40-2x.png" + "size" : "40x40", + "idiom" : "iphone", + "filename" : "120.png", + "scale" : "3x" }, { - "size": "50x50", - "idiom": "ipad", - "scale": "1x", - "filename": "ipad-50x50-1x.png" + "idiom" : "iphone", + "size" : "57x57", + "scale" : "1x" }, { - "size": "50x50", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-50x50-2x.png" + "idiom" : "iphone", + "size" : "57x57", + "scale" : "2x" }, { - "size": "72x72", - "idiom": "ipad", - "scale": "1x", - "filename": "ipad-72x72-1x.png" + "size" : "60x60", + "idiom" : "iphone", + "filename" : "120-1.png", + "scale" : "2x" }, { - "size": "72x72", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-72x72-2x.png" + "size" : "60x60", + "idiom" : "iphone", + "filename" : "180.png", + "scale" : "3x" }, { - "size": "76x76", - "idiom": "ipad", - "scale": "1x", - "filename": "ipad-76x76-1x.png" + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" }, { - "size": "76x76", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-76x76-2x.png" + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" }, { - "size": "83.5x83.5", - "idiom": "ipad", - "scale": "2x", - "filename": "ipad-83.5x83.5-2x.png" + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" }, { - "size": "20x20", - "idiom": "iphone", - "scale": "2x", - "filename": "iphone-20x20-2x.png" + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" }, { - "size": "20x20", - "idiom": "iphone", - "scale": "3x", - "filename": "iphone-20x20-3x.png" + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" }, { - "size": "29x29", - "idiom": "iphone", - "scale": "1x", - "filename": "iphone-29x29-1x.png" + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" }, { - "size": "29x29", - "idiom": "iphone", - "scale": "2x", - "filename": "iphone-29x29-2x.png" + "idiom" : "ipad", + "size" : "50x50", + "scale" : "1x" }, { - "size": "29x29", - "idiom": "iphone", - "scale": "3x", - "filename": "iphone-29x29-3x.png" + "idiom" : "ipad", + "size" : "50x50", + "scale" : "2x" }, { - "size": "40x40", - "idiom": "iphone", - "scale": "2x", - "filename": "iphone-40x40-2x.png" + "idiom" : "ipad", + "size" : "72x72", + "scale" : "1x" }, { - "size": "40x40", - "idiom": "iphone", - "scale": "3x", - "filename": "iphone-40x40-3x.png" + "idiom" : "ipad", + "size" : "72x72", + "scale" : "2x" }, { - "size": "57x57", - "idiom": "iphone", - "scale": "1x", - "filename": "iphone-57x57-1x.png" + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" }, { - "size": "57x57", - "idiom": "iphone", - "scale": "2x", - "filename": "iphone-57x57-2x.png" + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" }, { - "size": "60x60", - "idiom": "iphone", - "scale": "2x", - "filename": "iphone-60x60-2x.png" + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" }, { - "size": "60x60", - "idiom": "iphone", - "scale": "3x", - "filename": "iphone-60x60-3x.png" + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "1024.png", + "scale" : "1x" } ], - "info": { - "version": 1, - "author": "xcode" + "info" : { + "version" : 1, + "author" : "xcode" } } \ No newline at end of file diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ios-marketing-1024x1024-1x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ios-marketing-1024x1024-1x.png deleted file mode 100644 index 54f3c12159b8345e79b00a1e6a1c220bf9681a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82996 zcmaI72Rzm9`#=6VhoX>d6%olQBN=5Jl_+~}4hdNy*_?AEdsWDYh>*QU)-gi%-s2eA zdvl!edwG99-~IjnAL?N}+^_q-uj_hV&+BDCg2|fFXSF;drWLh zyC>b&^AsQ~OY2NaKeX?8xXrgw&{XiYhy6ov6Eoet6LYwQ(4Dc-`W|M=F=m(cRxzhy z;Zf%G_w8cA>>;;fKC1T&sD4{j*I7=&unkWSM!RuqyX)z|FujPf($d_moUPTh<0M3n z_p2kLC+9^#jRMuX9 zHz-ch7^)YR&;Br$`@ z+iQI9+!!S%!oVYRlaAY`-oJR+$*P7hnaGb$#wv83aAx{+Ljaoo5apf~rPDo|yJZY3 zim_~_TCo8Z_X})#*9wwW-wgV)R%fXkSA6~EHa+;J+ND~=`cVmJpF9hb20tCqV++1G zdy<6O)FA)RjyCdAmYeEzIh`?>Oy3uBa{GD-{VAF&H`1Z3x~Hn@*?Y~jXimMgwT|QC z2tl}5we8|g2LmU+9%Z4vOtsJHpFK+p-@1kA>C>Yl%}f+0Q!( z31%#~9z~;1ap|d~pDT$3ghh+@K=Q}Xq;x+9R{yr;PvWq@-6&=;skOAkF=OB4o#i? zJyvsajVdTvX7&pwud9O1~$hldUCaFJ??LFb3(5ju~LMf-03lEXs83V_S4OgGTdiP8AWxmQ>UnXATZB zBYN|UM2cRvJXdhP^h>cl&o9+@W%6@;)2mqcz1?Sdv=rPUOoms0V4k`kce+Ge-7rrK z#BUtDyKuf6>BdA;q^nv{iP5oZd_hvTZrbU^v|HEvbWevbeYKTjO}HP1epTUT0dS<1 zC2n|-*xfSZFO;g;Hf#vka@)7lyHWsmx9?oas&MdqJNboM+`+@Dd+qyHz0?Fy$x^QX zoD|7~XYqB@-65mp7zuHYMY6B}S2aSlJDu&!!O;v%}#{egy^LovEtEUu_k@v4N({hP*A ziw$mRMOH0+pqb8hvV7F$W{-T?nVAJ%mHqnR#|uNR@~Nq$8Aq^lmnZhRAH7WU4W(HC zP{E(=zl6d`Mw*1j?fWovd0U60$DZqF{-VB(djf;8q6V_;7yCW}^Vf7P$IXv)t%L5i zj$n*Ni$LY%-aRRI!L{bFtKS57K+?{!(yd}|uzyf-Pi<@FaOImx)Emsv??BhKYAnU; z+?X?&*=EL;zb#LG+%FV-$r@W>h}1p5inO6juQCQYWnJ7a8(4=5Dt#S*kGNG%X#IruiHwmQC}lzXJ2t-!~7!b zCQq_q(8qIi-Zy9J58Fj^$&%mrQ=0KD)^le{q)(~Y2U>?n0PJaFxkqcly6+^~90ALz zJajDvj#+jvopUf|%v&AyP0lpQd(X^{dYv13F;+;;bK%QrUWY@Vd_6_W!7X-<9F629 zGP7`xM_L03Ku5r8x3awfaR@x{w=!a*uQwa`bR-u{CBT2uSA$XpUl z_2FboPA)%hpr8#pe-;^(7ZiTsk%n=lt=VW#o9YB{_Qe_7RNa36;dOFrsiEHLp-uweNwCZ#x>BPEG*p4n}Vw3yY256WBCdcQBy2yIuCHLm8=m&>5bF+#AV6Hj6oB);DO~jVlu74S4jN=(!FaGCv_Q) z3j{Zf7YetE9Z-RLse2cTV$+ZsMkQs+q(8BiBu-QS&Alh0f72uA?wpB`ixqer?KGbC zNG>07W?|}V)!K4pk&T4d-n%WUY z^wK}+zaF&R1Viqf@vsxpEM^yCci$mHB{%eJgz328SnRGy@@1>mS7y5lQfyA6H&md;TE4MLcMF)n=sX~?|DVI{@Wv~%1TcIdDzVEBn;pZuk zZ@0!_n6k}lWh6J%KiquV^ah`_p~i9^P_5zBu$2wI4Pz}S8w=;-2{X$q*N$6kIwfMp zoi$aji0`l1ndw0b|CL&KMeYFMEQG;dqdZE3aA`0ZR&ugu%!9F^uj+D~LIWc=o{ z9LtCOI(PI0S2U?fa)5~)MV7t5mSJvOrNM<=_GjsN<#T}>G=V;mg|Qs6*)U0t(685A z(bIkI8;P9mCWv+i>l9CGOrSGQDj@PbkAbH7quL|TRznloTo`I<*}h?uvAPPUz0CQo zaxa6g3_R4I#V^NJqpN=jK8uiq&}lRW%kq*m>`&LeAu0M!9ACcqYkyDajilF7vhO-K zd-NP4!~P_SR}|c$?Tc814BrkUcT$qu&4G_)N^`1IRnX2~R#DxPioNS}?2c}D{#8iM z25C}HDQB95Mn|yzxxuph@;0y6;{G`3nYeZSvc}iC%TM<@Aq}0uT`D#)O1D0rr6}uh z`|F-3c)n(hjQ+SegSN`F<2vhBN|tUg&>kar!^zFY8wgpEiz!i5PEFoToerugarlcH zbVTo!7zs!mA2EEDZ%U$GCyX>g01XOqP6Fdxy@`BDhJzgiStY&d#7g06#g!N`9igI; zoZvNtyfS0tx$%vecPn-G9v1{FQ}0pa>z9PP;DUKWcypzcpK@at-$f>)v_ykULV%35AHhF8b7+X4 zQxf_d9-f?4zCk93hecdMKBmI@M0Cyh1Sv|E=x6BoSqIK`MQ_o za9B||lC0>%(<|{U|L$7E@w*}iKTF{LqB|H_ult*RMzO_k628X4@B~Lz47a10H1e z9&RrG)ZYkyDDA|~_0yS(hQFw1iiSv@+k{m>eatimIA!I^^v(6ydV7^uDku*Ko7B?B zYuj*_7HY9guZ!2rpkB`(&+;@^r{tU;zNDQO2{(J^y?jD&I2Cb=amyEGRm8ph&88Ts zcg(FmaoKWXD)6Zkf1#X z<(Rtp0V6&8Ykt`g*rKhhhoE!DJji*pSm>%SdeSb*-7}>zQ9n`fSW%s>8t2H^-yKbp zYL)F-b=^hNm_#;4!rX$*u2YM!?j2dTGf(uIbHzOL!Pc#i?tv*8wIHrKGmX_7XJ85~JABu8+H%yCn_F zjQjRs?^(}q9Hzv+lLtC>sox(ovj$rt4D`⋙SldtE7)6g`EdRLegtOB}czx;o4k1 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 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-29x29-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-29x29-2x.png deleted file mode 100644 index f25055666d9e524419e35d2e62e2f54a8aa47c5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4206 zcmV-!5RvbRP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 A8~^|S diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-50x50-1x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-50x50-1x.png deleted file mode 100644 index 38a5814d1471d238897f9c872f58b15885877c11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3616 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 W|Igt6&m8f<0H`Qv%2&x+hW!tytgN5_ diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-72x72-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-72x72-2x.png deleted file mode 100644 index 06b6bdda9b130c608173abc0f87d2500bb414ac3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10134 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 Zm4(;;P2hcF0DB_<$Ve!PSBn}2{XZVI9`pbJ diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-76x76-1x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-76x76-1x.png deleted file mode 100644 index 3c234f6d497f605759e526a5047f13a83c3e8198..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5327 zcmV;=6fo004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-76x76-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-76x76-2x.png deleted file mode 100644 index 095acb2b3cf266466f2d87617104f3be569aab7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10832 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 viI0u~>p$MrLGYqY- diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-83.5x83.5-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/ipad-83.5x83.5-2x.png deleted file mode 100644 index 982751c5c00e879c7f91ca3f4e68ad3587814617..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11802 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 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-20x20-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-20x20-2x.png deleted file mode 100644 index bd4c8fbe17d648019acedde19d92ca249fca0e6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2892 zcmV-S3$yfzP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 Hu0mjfR&wBj diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-1x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-1x.png deleted file mode 100644 index bb2f5b4e47770a4e8fa6ade269d2d93d15d181c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2010 zcmV<02POE4P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Re1r`-GF$k3Br~m*4-bqA3R7l5Fm0gV8MH$9_ z?>lq8&)M#7_p943i~VAyD)P_n6Q@h^(_Vw>wHhFx* zhPhfb^A|#el+-%e_~_ydli7|KDG5dqv?QQ+Kk}Q~cp&+J6G6|5nM>5s45bFE)zVi5!FOdjmow}rIYiojZxgrum z>}i~R=$0^2(`K-u;uL`l@mPh_kJVN^ozEIS`Qc0ZpLoUQB$;?0F;H+2panS|ft1Yo zx%+pA!J4*$6&wmV;t1P_6O#JG28eHpC!Wn3dvAYj|4&~@vnpav69z?Cf=}TLv>@OS zQR^(+w5xq_{~FXJBMnJ=x1@0ZG62=oqP%1Cf1i8yMHWF!#OQkYADDp*+?o#(I_-_4 z%ioyL<%Cnz$cPt9c9&3v335=NyL@?!E7C6iKFPkpi5CkDv^RWTMVo(N3HiJo?#~Z*Lz< z6)z#;gf?MP;^qsW)k7zT_rK+iov&zq?c+yS!f8Sv!BLQIs70OSxqtfL-k0CGZZTGU zXM96`fe-%rkynpiGo%aa{IZ6= zhU5t|$&HGoL1QIJOn@w<;eBr@qBRe)`Jz)4=;S^G7tDpTF61tlYli|Q4!$*Y=;&3O z%Ck5L;(c7-NJa2UB94-VfYk$34$t}H=bNrf7SB)_9y`YnCCyPNf`d8~@hMW{wSQkx zCbKMe1i;t-I=%Y%5@{XPk44SIY_U|9cjwBa9p(AW#ihaUzrqJYzj*34GLIMzPC^qa zsN~VN+DAU#sDtJ6TL(KMjZ`nmCH(S&mcm-N9KD*^?=;R_J>1;rR~$w$d;XK1k2NnJ zA`9pjdPh5#TJy%Oa?41#q&GDj9t59!Wldu$oVCKGrNti)&g`jwuEZFmW15@xs+9_x0-RWdG}1dJgxNPJ1WT zjD;I(pFc5tWF-~^6ERF!D(N>r@%K#YCFi1t^~eXa;DmJg$*Hh)73w6!;7i5jySG0z zHTvRu-_))Tx#>EWKRf)PnIsdZh6x?#ANsq$^Fs_)#99s?EEXKu!kw44rbcCM4VwG$ zzUfDI-a1}7xeQC@yV>{66-4_rdBvPcqV06kg8$yT zEP+eOL<@#-@OM+My>Z2n_czKjBbI@PlNfV<_x7j8ODE@3(QC(|R$MwYGxFy1H+?oe z?x$+!L<|Ep%L;z?QTih1)zs8kp7{s&J#y&ntIA|LP!1ElWQbZ!zFwW38hvpYoaQNN z#ijTDaOJ^!9?qzFa-A$UlZjwNm1@U*{RACQOG&8m^mBV(efydX)%jkUwylvGj%Xr@ z$YlTP>wPnrCsB0i)Xd1idmc_`y}VHLE4snAgNXY`G;wE8;$LT~AGH&WuP1D{Qgd-4=kE9w8I<%5xMO7Efo001R)MObuXVRU6WV{&C- zbY%cCFflnTFf}bQGE_1#Iy5snGBPVLFgh?W3#jJo0000bbVXQnWMOn=I&E)cX=Zr< sGB7bYEig4LGBQ*$F*-CeIx;dVFfckWFnaY~Pyhe`07*qoM6N<$f>L(CMgRZ+ diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-29x29-2x.png deleted file mode 100644 index e7bc0877272041babc65863cc01e378547c35d51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4206 zcmV-!5RvbRP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 A8~^|S diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-40x40-3x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-40x40-3x.png deleted file mode 100644 index eb09e21036fe1e603afd9590c9b164cdc2414bb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8478 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 C$REN0 diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-57x57-1x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-57x57-1x.png deleted file mode 100644 index 4f1dcd273ca3a39792fc2c405a879c536222f61a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4130 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 Zjg{B`PvCuNqV_}pke61Gs+2Sh`X6LraZ>;Q diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-60x60-2x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-60x60-2x.png deleted file mode 100644 index 49c032f9b702b2ffb00d38803a66c338d3111335..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8478 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 E53Y(I#{d8T diff --git a/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-60x60-3x.png b/ios/Rainbow/Images.xcassets/AppIcon.appiconset/iphone-60x60-3x.png deleted file mode 100644 index 17a22bdf457418848a8235b1ed0ea0374c58076f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12600 zcmZ`=Wl$VVv|V608t}6U`0mW2a zS_1I$-&W9Bn*3UW>ME-!iMowUM99NRk=niw06>LhCB!s5mrpu<5)9|u7#{U)&s1aM*#laaKoz2j%G(O zpT!l+@A`H=6TDyP28#eF0FVs)00|Ci^)HVmlIVK}h*2e!Mg2=MQxrAojeWx|a;%HCem+Tg`Da%1^XAb`Xyf0w2gmQjG&W+GtC&lp9|h|(@b~QPWK2$7gE%2 z7_GO4!H8-h3xj4Vzu^^*#M{WK$(nOkY=n=a~E8&D5$mhQ=XPCK(r>iVuR>N?lMn!$ za9lP47>tg)(73FG_wX?xvW8vUQsE#{?jYSxuAl8t(EX}pp?dXxrX<$k-JwtzeGdWx zPS2ih2uPex0ut55AAZsyGb9G2B^hM{Fxoj(8NBcAa94HHZLz-;gCK!J!B~I{7@Yzj zcM88-!kCDjIAkqDk<0wkWa82KWkYsLckQQs@})d5s0>ka(Ik|NT%sF5Qa<>*CYD&Pj$<;mi>6Be3%ll`oCvCR8 zXG$KZjxbX96jg0zxus8Czu(cL;^)+&0YTpFa@y?dRYrE+&HzR@vrgo5*j>5;M-CRE zj;`&Tb%xo{J)zIbc<$tH_t8s3c_|tgntKQWG+Ir48po>t8yzZFj+wgKU%AS3f@VW4 z-8mNBBIZ_WF&z4GmPjLSYl{!X(*0@lDFIjCsr@$ix*ziF*^5aT=l)3?=kTA;a6PRl zODXE7uI)LUmVV0;k43nf5vs%!h=WvzkcJeVYK_S5Q@F_oSRF1TRJ*V4MafB zF!{Rpb|4aMjLaD-7NR&;C)(wuxEVIrTcpLgk%Ww(pd$QB-i{*0d16{-ai#)H-E}#P zedb&5Fs>R>>lNo;S$d+JgKdc*5CMbW11efgES^hPg1WT8y~z5P9PFf;2yop9^LJx+ zpn#+6v!^vA<#!(+u$XJ#L@_d5I`NKi3uF|_eEHqY7;qGJ7{#Vj7L+RA|4SHIZ$&Mk zy088Gkof)ibT@hH9;=2)7-4d@{{ctp)mR4I;i=@}G)J?U*{5H4IIY&ZcrNc~8F#U1*Tx-#8iDPDLiVrImY$ozs#9&3;Q1rWdLtNC2wHnkB{#ZYhgkq9$vz8S}y z``C)g_qaFUM)4LJTw#(p&QmB}2jzg3;#dfT4<&(r3Tlkq&MXF*Ao6IDQwMEjC0z9H+Tl!`9^wbXC@>Oy-ksn2&vsXyV4v+ zg>EI3J^@1@0#I8{P_4)1y}*OxxD=(9UeXtlRTI`XkLtgzpa1ZDyE=+m zxo@+!#h!ROf?*W{-taqjG3q!9o|I5RQ7$)gkiuaRh%lyv^mn&)HkPwTX}_X}oxbN- zycqf4oajRh-&)fsMK`~~u=#*A7Of6?(dK$rTZjAm_-y$Kq-_Fddygl^%|gJPQS<8k z$lwshfK;4}6%OXQhl`iuSvTh!?yOC!hnHv1(Q%(Xv0cNEF__=8tv4jd1&$H0QF3wk zkF#gTN8;TpQ?rSlCxJbBH)Y>&jzRTia@z zj0o-Q4UBo=N->~hWMCf*JR|()jdW7j7XY?#BEc-=Z}}%s@QKRe{ZRMIvLUsvrMp)F zeu(jGSSd0nkXEH4Km%@LAH$2~3~gW{=B*;_{=_ORnXFp?r6aS7T%-BmT$}5->S#!3 zpFpv(Kuw(aZxcjCCvw%JZ|fs${mN@yS3N(wEW#}nSy_uDzfdBV0Y3DApeQj&gpeF_ zg+Fwo(dF5Mmb|GWGhKB??O`LI_xRW&)>4s?;X$_H+1Tv~U(jbXh!xG%`@YZ8v+Dwo zvnnQWHD^DsKC=IZs|0E8b>ZZUF*H;H_;!zzF##je=Oo2xtCt(5q~J&elIEuP-!4cL zG7_G9L%6%UNH9oMZL~>x(h&kDeAa`4-+n)oBsE8^8pmAgn(A>TAbajqW8vu+dX0%)`lRmzefQsG;;Rf9Y~t-j^6@m zv{0M1Wr>k*5E0dwTn2)3Cmbb6HphDCdxpiB<@2M9k&f3~FKK0;@>CxHHLxX6tVb~y zAHNm$zg@Cm^zrxa$-zvJa*-lm1rBlp*ixje&8-1%{=~YtpotPgPt2d2&nDA&AFXDB&;$iTU%FW z$vPHbrd#yQQ|aV0A((431dLu+6Pl>^W691aW#@sYxlvW#9l8niEs zMb9bLa25Nx-NBRqlhTQ(2lWR$ z9bODay+ylL&7~H|0r3Z{5Lp*2Gdcw0p14?4!yH9u3`++U_7AEosP``OpO}3YZHh5Q zLYTbBJxM`<8e6|8_h~*^y3cL#AkDpXDKniS(GIpPAKM@Tw%`${WP0fVrk3Nrm!P`) zA6>9MD1PLLBLxF$(LE6y;R_KzMqNH(MI{wdh91p3Ns@6NjTJ<-@>Z-VeHIgO<3P{o zefJg8S#i_z>by`ctSPvJ3qX%R61$MTj2?kugq}Eub!(Tb(PmtmU@?n2^z!@nNokok zP$fJRS;94jm;Qw(fs*&=`A}L0Gte!E3d#%zcW#d8S}H{%^>=esuM<4B6{%J-4CY8( z**T+J$r8FCwa@RyRz0uKTh`9a_~c^Eewb`9xT()97LB(jeE_O#^Vya8tpIG*@EX!8 zT2!mvbJ}Jg^axzw`fn8npawziOwbY3di;&GJ1yt`a<426P7d%gV!uOAb5-T>YQp6( zqttX@(CL||cIW(hoMHd{=$abC;4+PJzx;&A41Cd?!M{4FWbs_7*^J&fMXw{egqPb6?~ZpYe)#rG*sy- z54k*9yGM|XHLN4K6T)3c>8yPK@~x{&G6V4N3!ZekMf~KG3g1D5WYahBJwVe ze7{#!PT4X964I!8wE(i2za!-_Va!fHrfd;iY1u1N)UcPxtfu{I)-#@w?=<5h+CQ1Y z@A;KQyO*|CRvVF`Kqc~mbkoip1z@X*KO!Xh*FFTzhddGHkCwz#dq(Ci8joc*IH}Ozrb;i)N#nEsG=UW$~o(!bCAIQWAycG5lc^?jR2dVpR)%+{XRn)RRtYSK|+M{>4B{ag0TDwE0*gntCdkkIxX4Ad#=~fauiF}fKr->)GS;l>l9 zon*+FZGed@qrp}dC=)c5{a+NGwy!F##xy-N=h?8<#w9cx2B4)APyURBFRNq7yY9L- zv?xJkjVRvA25!a;BDDwueM@kvMMTIbpjnHoGqq%b_&qg=9_ew~u;j?(;0;!9_Z)GJ zVc^!s#j4NOfp7y;60&@0n*aqPyYl!3$blFY3kXZ36@x-F41FQob4OMHm}GcGSs}Bc z8Wl#{cJqExrxiwr-WifTzd%j`zSfRR^u?EXZ!2S@YO+ZkO$Jn4U0Z#qcuu~2_=3{m)Sb)KwV+;YB=%P``MP8gU9~j-2TBmwS+7MEF1;5KZpy* zPE46~NP*VC6|&O+Jp?3O#ElbDhx@(f-^r-I*s&^2GdF<1+F2`#A`Vtd?fUZnbdsxw zv2@ZOyjZo5HGBpnahVbpl)wk<8{hrZ*!2Lnr_&F9ALi0;y9&C9eK;XBg@$t=| z&)~O-A7O#Fpqi4f)cGO)VGj6la<~xn-KXojemMU{Y(5Pxe_$#Xm7yY?<~IAGVDqcy zV`MN>2SIzfek^Hir(Cl(3O`(AN#}pRY-`aLQo&E(Kd6h~p2(%4iXIY!qY+&%?wObD zk!pmILioCAY(4-OlFXj8%8$$@TZHSd;g`MuNAW$1Ww`Fhe7E;6+oilHO2wWM37c&Q zbS45K8IqGQu~aO*LVdT_soc?#3MVo|#F1n?yXfX=5Qo*8`>Rbh0?0O{Y$R&J@EOIk z^qy^uZqA-m2uCO65!}N6`HC%k_G2plif0_yf}i$5k!0*xLod(M{m6={`%I^)(=Z;X z_Oyda1rwl^qlAp!&J=lyiHKYqJMax z?%@0D2Or+2`>3Fl?H=PTn|?v9yxQ2?~%GB!^a`RuP!-NqE_XYW9z?R?#Z z;n(A{$C3VZKbLI^k;4%72-31dB({uoR;Hq)=ml~@MABCG#ogf&iQ%Z7hvcSsKnWRjlDjWj&&#h=JMT^5;PqW-6x8C!>)+w{FdEG?q!t zk>}Nb=Rd^jy6=CIXOnROpg9p2{drh&MKES~P}@6MZ4H1V&e+RbX~{SSNq<#E>-|Lw zF5R!2U3fp*vKFqXJI?Xzo3VHNTHo9)9m4=9Of09-ugojZpPt_hmAEG5=9?22;NKqH zrNvw}hzQ>@f9=hH z*(|ALX|wBrLv$AEL;U9DyEWHM0lS3TRwexyfC0RoBO`a2CLLRW=ldkYIEI5%@=}cn zk@MqucF}ILII3Lw*VhqK&=w+z%+LwbO^SfP@iVJW*B=T)MV~Sef^_~?q@otk$Tn)B zI|?&d^3$BGyh2p;^43q0Q7E#v+yo)By1DEl^}Z>ZInB6ZXG)49F5uvP@v=gP$jD^5 z$`(=0k>wt{FVHkVgQN^lEbEpQjl)g#3h|#6Crp$-#6J^xmUO=LcSr#sEf~hDn=*tG znlnA@Y^E_>3$VKt-o2uN(PpW%TiKU{rtQ>Na$bYXZf6 zDaCfAkLH=&+QbK+yw@0T;JZ`mWEd|Kqkd8q+U63DOAk#F>yc4wW2X=7EmmG7J*!ya zu`;Ajl@a3TAD5RPstw|{c-d5W<${Sz_S(mIH;>rnCc>=+3ILEqexO6|XG&t} z4TkW|^`WJq;N$*8 zPe}8Ads1M3Y0kF6Q_aQ?i$CkAcUt82p>W}iv{&cdyF!E{1l!7+YX~1oj)-`v^bo9b zu|a}d-D1V?BFxYj-)_Y+JA=-jv=@A!Y^T35+70N-H9qSj5)+DL{ag9^FS;K~P%0Y{ z*6ZfJlgyl!mV|?nm}d6Dz8(9@f-yqG=_gxmRQ@y~jf~6VR)n64x+taAAm>&CQyCv& zOEW>@RH1n)FoXt(-Hy#pRncs1u@%SElXL-zFroq{MR${sFD1@Ke+bFg@5p_FT~c12 zBU88bb_SUN0(GZ8L@(U-RXH?1cZ*3QFH=Tgkr6})4+gjpEgw zHhNo!#c=qKMFjJ0k@z`+C4ai+Jef-@ZPC$lW&k`GP5~D1=6C!_@6jvPVL)6orK& zjDSES$hfL%o`~%<$!_-ZXWOJm+a*M3B-*TFo$eq%7WW@cy~b+HiX7(>`rLb6rHA3A z=NO6&v6*R;NvB~FoT!O^8%4dL3BmMnHTgQtFj%#FgoqeUQ0UuSaA7Z=QN8Nnx$vCw zYE=9$<5qBb5P^}(TAU4=r6DaoR{&n@Q}l==bYfXiu0a$VWNarw$fvSkzXA zL7^Edz7j*~mS1Km$o%3^LqR~AD5<9*!5-WYn^QtGnI1s2<+L0@Fd9%V?I~Z~U{zq< ziaBx|6e;2Pj$e|DXB7r84nf>hSqvhe>u-+j|7>_NJ?HiDtF-ohnN2uYUvqJQzJG$D zQdVu}LTO#J-g4{@9o|9HlgD-#{0B=W*P>X-GF>e$o_wt;c(K=omFZU|kKs}+i`94M z<~L?5GtC0K^?CBP=c(3Vra0W`c%U8xfQG_BUj~1D%AtQbZUsLjoOGtoGSkT5lvuk2 z{8TQUubov{Y0s=shdgKBHT&~0ly57)JSg(Mb}f%o@oA(fa1Dp6w{2FcE2AnfEYWVgsJp7E4pZ`t$^9UNe}K$ zSUnn3B_D4;6jLo1%l>affG~)THV~Ir{B0=%OGsn_o%a_YR9sJgl8k+Ct5dQrP<_x5hMl=TDif?wzVZ6JJ zUf2t3-j8z_ig7<+2H;kMQGZD1VxGx`MpGz=OB8DI0vHc$SU>V~w^r43l&p-O_rM52 zuwpET2^^%Lj`P!wAv_4Af@kRVyO_D9k)pG6H+Ot#lh-g*T9=sDn!=9&BS>}<{3htRt)CXRR#)Mw$?nV}LIdEpR8lZ@Pkd7} zSbMc1(Asjc;m|^9kWGs8Wy`hqHj0f#si2zGRi~L*#Cf}7x?M|qp)nXvYdtG#nv>CE zM-v{zKNWGMxAZ7_^5D^YW|T;VT6W<2Pv4JenwHtKy!J3f)ORH-u^qK9bzF4{_sRYK zdEm}?Zx~mS*6ZkQ=k$}vzxG^*Duwt+b;%=KF+&V7iyR1E7#Jy#tleq%Z|6~vCTm%c zR4xwB0smh?%M6OFFFP7@=RPh!sk0g!)ZKMLqJJ=a2a3o4fia8GJbrCIxrFf_FAXOLGaO6LmD}4x?_ht z{8)O_4;0o@_xhauFLnD(S4*2che20ttO1uH{5Ig?#-f{ppUoP4u0;Sc7p^i^`r^W! zDLUj*p5N52o#)2;*;xhz1s}7^v5@c}lBtZVQ(K|GOL+^< zb~dC{@~jH6J;0+BOsUU?e*X$>6W)-y7q#`89Ns~koUN0B)IT`~@Sg3quV4eUh)=#& zKo5H>Y6UOO$uB%urExWIrW@o<6d<~A_{NzNr7FPXR~`G9Pq`r~^0rYu*sO1uWPQqGC-J1(a6w`C zSc-NhV%aaeDj?wDdGhAisX%@yMFKNY@EgYZd&gsZ{S8=XG@Mi>h(eX#?6+6`srOT_ zfDen3(9~O7xgrIW_P>ka%@_gZfNglTo9gfq4wnFlX;0u({)Eq6-Zhfsk;`nI$EP5) zAGpVf@kaSCEu$Q?)}H5ff)U9S7-*r$w`ymT?u}GkUvgiAQ*#PPICWdO;}I=c9;?^n zrL^5nM21)h`((g*=eYDsDyjK5IM&m7P0HtkuZ7Y5!~DqS31&g0Mw#75-}lU3Mld*) zVBya@+Hwoy?Tm=YT(l_868>QTqr8``!7&W6cStM>P^^Rx0ltZx+XL3SuESz*BxG@; z!>1)lW5t7k^S%frtlV3Su-!jOH+a2hy;S}?B{P_v4cVmPI7Q2M<#>t{XbT?7h$XUd zjQJd=9iq867w@iM>%20chfVn6{0O~;Ei2R? zMJ&R=zDO^HACK?T3LzrNm{w&)QNm`4hYtF1?Um^2)xF3GswFX35i2qf8q+$Tkt5{xUHEA!Q1}Z!L|s~8T2od17Bq4j z)@7Ez7<3M7w(L+bNkASDu>XK5rTt6aR;bHwFo)qmKVbF`rKl`PA6Cr$n(!6nT~SS` z1Qs$A|J)gI7xe5cs&hdm9V$AI@y;}Ie|K&ib#|}CYnP*uAEbg@5yClVsEU9_pcE}< zeW<>mKoQpa`}$41T{u$Cm@!t$a6~N^I4JG7P7$4Iedh9t(0;O6MF&63kyLmy3Qxf8 z`UIang91pRlJ%R|$H-lhiB?=ycC9$if=VoOOnX@LGqoB!Lx(f2p6%8~ zZ5!Tj?S<6CWPYfppv_&0YPXzj^8DOHuz*ZL5Ex`5WO3*%g5OYg7kW!RC;z{RbG0qmL`%~A4F}b5i>)1CtuoyhywgAe#v7o29NeB zxZAusBIJZ%8syT2k{|C^F7=Gva~q<4b(k}w59DC|w%lWqtx+##l93gl`mO(>4*R3w((ID4 z_8T=4z-Qh21CdeDrI9%&RlwF)$&gFh@SvTlwIovi+RO2%E3#595G1hK4I4 zI1DdgUrLb33XlvAo{3u9e5i&|VVb=T`)`;Xr)hlDt&d%p_M(gkUemu^->o6L$j#|!rK4)ljHU;h|jL!w7ov>Exmik*s9@UWmN-r>!= z`=bYKzt+e;j`Iu!=dqrSgTKY_T6eiYK1pTuhf+|3w=6uK*@Yp-S7aS%~I8vBU)aG@D zzrG!45`#w)JFK6BBta22mls!vT`j#iAT=@!4i+c(u39RlHfk{|@LDK4`17-DKhh;3 z7^L|V+vCJuRV>(YGd0;)uj>7l-(mZ#=HP*X4@oivqxt&w%r41&E<@K-vJkUlkh1-K z+j9w& z0}uEq$#pVTj{rj0E1v@r2umL~eHLgGws10&Lsb_@sSTf22w@>sA*B4-dn$BZ`%m6S zo2h^5lGKMQVuz4c?@Ml`ew9i6gpadXMwsqan6>;vt<)>q!P6wi_y6(1cFhP`f`7iD znhnE>J{;F(-`MKG--%hbsgMH9)N~*55_#5(=swSZ1R%B2^xio|(7-)2X)Xl^$6$8; z_r1GLdC_%LxrQ)u5-Fn0fB#w0U(-z_Q`WMtE!dj=-EmWX)|c((F9lTnLN~PD%5AWu zunU|+Np8|=v5fb3eo~||FL{hfPIJAF|E3am{2HkO8GH9b0Hag$4+A%4l~LeHaZAVr z??&ue6PZbnO)x}>faDb?#iQia5q#TYJ%4so5`up5abs4G#}MM5P|znP?fdNrP?6*r z-o+#jd^is3OADRjIbnQD@&!ki#Mg5!93{(x=Y77@yhp&u4I*^sHL6Y)8I}_mF1@O% zsaUx-bxqslQbLYht7D%29ac1jd@q9j;{6J7X>v7g0p-8L>oT(cmR+AkmI|Zfzuk`n z)&G#3MH2w|* zLU5{@s-G37SDM7!!_2VFbk(Kpxy?b~sWq#2#HGkUxhh{Um8DSa_=J~2GhBu#Ss3Cf zzg|qf?5~1T!_hQ=d*Lm%tI(0m(7!%J&bwXo#7k++-w?(MIAkLMZ3v|QDRdXQwe zEOV0V9~T6qmX;2r0k56=;R}HH*Rv-yy^|Q%2LWj%ow_$h8gc~ybRg7X7c9&IkUr&-pW{%WLR9FpA77&XY!d~G&EvlE+Tpud{tnO z!U1CRsP{%~MuzRw+p%#f-z;bye>g1{1(|hQuRPsvt=3$f__;i9dI*L~XUp$ukQ|d{QAC6X@y3>v9zNeqH*s7-vA- z@rl>fd91@@|NWcxd+;C;s-h#ts3U=FahI0$>nf{lRYqJ<9dqHYE#1AgVJgx2x6ynjPuH+vZWa=3v1Jxqw8NQ*ci|{7n5Ji;_F4id zCVo9r93%dr&_}7_K2Nih2|dq?hx6wi$59pjhTE78(XDY61yi6Ma*%Ikx!Yw72mHHNP4|D8;riBg$3Kf`D) z>2R;k-d26@pN&@@%i_~rSO4cLN?Gi|+J2*md)d?QdiTxOmnK5kG7ExZT&@@2r`d6E zEvrz*{C=x?Uwi2QuVAK zC+bUc00A$Fxs(20(%{{1`5t?SGjUlE&FS>7KkgsZcrs-%>b^90tFDN?snhke)wM9R z7+b%4zz*DBfV~7Nq_2Y z+udBqTU*?TA8Csj`ZJ|aCipR*>T(fShgt^=iF%D^OM;u8xRS&MV$KW4R;lm*p+DTW zKP65nSV*(b&@PS~vYCq&b10YK3<#_yi8PlVMM~J(P1M&In!LN5tIB_0+uki8Vj5g7 z6I@L86gFnfDV8m>w9SHDz$Gz+_V#10S*mj?$IB_U-~FK9=>Dylx)}-p2GscY3rXzQ z%ak5HSkW-vqvCwW#?Ev}z1rZq`}@@|R1bCsxp>7`Qotgpsa7|YO8Lv^??B;7-fqnB zkct}Gff2FV%NuHc6Qh9e{CpHHm{iV1D35&r!$1&GD;T5S`RwH5?`2)@4ZxP5@ z2!UFL2X72Gze)v`<-96DPD~3;+)NLjX#HhVDW8(GmBa?jv(0GC+1l);i$ra%;~J_* zp+HMCNb+@g6+fW;>JXrNBbPw*k;$N>*-OUAr<%lwL*K=SQfu>X91c{N3iNuNJ;)i9?%ltE2@g+lJ`fZG( zx3n^Dx~TuYtZr`OqkxX~gqemH37mFpeU4RL7htVEs4C-W zVHah+vKhqFb4U49MC-HiU7^BCAw4dFW_sgXGk=^q$yUzDm&;N801f1%3@Kb1WZ}Dq zn>gZ?ChDkYlc$`w?L+L6%8EG!AisGFAY7WxTZ(+@!L8Y_S$ki64oZT4b|7c<6WjX8o2RnDZ6R%@CmbdF1c=+KH*24Xc+<32v3Eqb`;%*tIy_W2 z2R7v4^w;#VG-`3_*z~vqdZV-NlwZ~Z_dn{bev>EG;}hVD09Xk&G`~eAZ^(?Lh;B#jwyCjqU=Q@>)DhADp z`CkJ=gsr$05L7_~dB@-wD;!^nZ2eA@JY2D%)a;!y4&Ya6WiEht+f8<3D%p!mIw&fY!o|X%Gtq{%U?(ROLd1lVp@EN@ zG$5eJQvMOJL)DZR@zoc3BXd0&KNC2Xg10(p;bl<8Rb-qk!bVUc`%nMr=7*~;j3AOh zF+_x=W>;}a+1GTy7W)hOr?kX=dujJ8FOcc5y#h*0xr%ALS!j=VuB6N(7OL9ft8*?? zi=MB0&w_}svZryZIG9L(s6ZVdqWUh5+i_=bFw_*?$BDrT@YysO_8sdBMN^tt02mn< z`s&g{BOVm6ap8vZ(IQQ(#yGF3hw~d`Fo&bLc7AYNcPRG8JAGoGZ%n|+BBqF33Si*i z8s9#b!5D5DjJv%tPH8^ovaip0=bz)_4g`1OHt&w$p$GwxLrd%dA$KDXk_)e^$<)Q! z_$!o4#yf!%4Zxj#=YRa51OixQPj9n*p3K+5fHrq0Z>LI89uMa40742_A2Z&tL|zOK zQc>A!p^cG8nnwDt7c;WW8(g(g2pwh6)f$l5z0RZ8=nQ_$i7Nmu&&A8e%ToZQnhsM( znBs)^J^(UQY{_DEr=rBi10h0=W+1~$cVDDi5$|SPOW(tGD$CJRV8?{x@Bxe5y58 z#tYtnt3I8h(b$##>OU+t;7}r;*p6|L5V?o&T4eue#u} zD_(KI)xUV@h5cWB;f1%n?|B#PdfqcH8ae-I7uQdI;w4d);NFBO#8Xes+xmOSktD}+ z6zzD8EGpTtmDPCY=-znu{c6!2k6jYo^5o^=^>1DsUiGE5t-t?yW9v_2tHUe$mqs^z zh2MF3!A_kEpa=KhACtFJPb1J!8kuxGaaH;{kve56@$eSPeB83|hF7g=UH+pDtv`>f z3a|M~U$pbh1zUd*5abE&DVU<2+(ekF2?zUv5If}DiDNG{_Cyl)nQA<65>xlQ)ve2a zvaa>lp(W8xUn<387XY?QaCgQO>_nc3Fu2|$=I61K>V&yUB#9!_qYnN~l?gn5Re04G z*SG$zr6RHGC>Ui#@Z?Zyp7q1Sl z{L$L*vg>=}T`w^RmlND=;HaRDC6prPB9O?n*(%qRP))%XDC4Y>SBghBFAHyc?Yh?A zZ>dE)K4ffkIKf>WS+oe5Jr{{0Zj5;8(}@(hN}xz95+zOcK1p41QFPn?t_}ZjRV}{b zO9AZB1b0=;>>ky|En1D82=Yf)r1|Ik8(O9$&L3U9&k2Ti*7MhdmtDqD{hWn4OpBLiIxS6LLRYMauKm>Vu>XfyJF}VKU_xOHa4;~G1wrI#@>0PHCo|_u?JQBr z6C{B;T_h>FqconEmqq>W=KJh-4Z@WK3r-Hx6yV4bCu-V>V&!!wO9}K+nI_Roo>Wh! zq)XwyzvkLB;L1l zvT+FIWuqvRr<_=k>x3(b^;B_Mh!#iYdf+8mT%!#|FIyE}{XKsE;$~0{2o?g9T|R@% zivOqOSl&W*ZL>{&Qv-#=r%*h89F;SM(R0oo)E;>|mOTDu)Xupby(jHPW!*3(PR>e{ z#43SOWzpUU%iYXv*uB2CC`Y_!Gop0XQxj;h<^n)(?qA&qnt=%*|@o7~EZ@Y?TM z1Sb>hFN~KG>Gy#YX`a0Np-kMvcA#?DkV_hx{@vAkC>B8qZ$A@hk~B*D9uOQ$us<-# z&E2o*_Fd zE$I^VdD@s}f$XXo^qsd8#iipStqm8iMWxV?aTeOrdg9%W>y3B6kYH~yG7`w`1Nr&m zOBPvDgKCVP2M(aTX~YSGNMoJj;a7S;ZEjy|k{R&-;=ZOCl(!P>1tKhkobJ1$`*BWr zkIlOC@@b=}9y`=ttdr(sX=%h4)hT6?)C~W5@3XC-w31-Hm?t!jK%4q3FKBGRE1Mhf zp4J+CC0vTXpo+0fc5b2RFYoDNn>wD3!qF4xIdu=)8Ha5qr6qB4J!x|1ToT^=@fg{F zU_O`+PaT2}Pb#Li;LVdq;8hbx;pt;n?}yU<0g;6+gfY!CrXTy z@}&B7|01u+3hphT=X6R7nogP?PZ3A*iT_JHEwmFVRPEqHtMTAd3Fd=AT)`}5AgU17 zxa5#ND&gkVB7Ci}4$mDw8mEn%ftADe#lJI=-;Ecel?}Qd-GrcS#JM+wp3?@rq^Yz~ zkVCy{skBMLGM2wfc-MTxbkMt*pj!+gktCEoaU@Zlz=5zApQ>-f!$(iTTBh&?)0=R! zDRiH@WWrKMQ>0Z-8Q`K@$Y6$5#Hl-}7UYeiR0<>072X6sIG=x1p|GlwRaI2rU(*sr zpvc=3_HmRC#bHBd;oqkY$F(S>N%KfcSLgAp93wXZhscmBC}}d5tTLK2sMx{t_>A_i z1YID)df=$0;Ko)96mgDHn-+Vf4o3~2flH>2L_dl^MiwjVgS3pJ$Qwa<^JqI^#0g*( zX^C`UR;Y}nqlLxMZEtFrS}(z!VVo$T*AYt3+U_0Fi@+qasf#IYdwm^_9yuK^;;1$< zMr7@sxNMTr$)hMNopj?#D1|PaJfb&zEl{Mngp$0iujq?*zMSCBFbJI>sUl8#5u{{! zC|OLPq)nLNwKwwad;I7r_;uWy{(RT%_)5~)SI-(ku1E=RX>k&oK3bGNmTmgt9Z#J! z%MKw(L5-x;(C>Xw{%0ByCutLLMO@!nj0cRIjF(MsK$H#A#?+ISLIwybF{)<_ux%09 z&qz|1ywodslO^^!K)>qqG!Jo-FAtDyIxNVF;ZNJ#tp1O-5D5QUtbB zHu$(vv*sv*P8cp=%soq$HR>tfU%XVGq*Py&jHXB%;djm(IT62z`;yXpa&xCl$SiH4 zbm(Y1EyjlaXzH{%k@C4D%wc-t-OnWGKwH@F)X1pCi6rk8Nd#(fB2%SLeWpYw$8(b3 zd&KDRDrt&rx9I1yab$~4xX~0uh$Kx3lxvu!C*JeVqnXvq2z)54@Io>yix6BA3REw1&M>%6i7UA?W!b}{S<0EX+j?Ttr{+wJQ7hR08A%Q zDe^qI<)cS+$^_ZmWkmJ4?0s!vIa}XUuoLGJXpA&-@$_vy(@)>l``f2)tG)K=pI`hS z%3Duy&mq^z=!!V0v#F9wM5LEaNf;ANa`;JeIbPA&;0qA6pj2|}8_4xF=17?clyfDL z$Y}P&ga1jOG17F)OFq}!@siKA-rgQ#o4<%$#>IN$DwH&yG=(Kd!1d!fcm+x2Np+^j5HdF`%Bh7qy;un_3Pu#xhi(KT1T;%_< zj>^6yY136i>G2iGS{6uT3;558BQPBpS-dAJOmpRay|3q6YbQ1&AwPl@sNE`Rg4#OB%OaDA%}ujXiq0I6Le zlCu`Y%@ggE1;mIrqQyCx4!KUrZOV4|A_Bokv#-45^NpQc>_cI5ujb+{dx$(GO>pOt zcOK^*me?HLUf+NlY*9-Sx|WvTJOvYkZCN71h%{(%EtNtMM`7{E)}hR%JOP1`W`E$u zbj>Tc*#Dt`$O-Thr_yHSoLKj{tGTwYCO>~seN$&iCZ$)HN`%77DJRTEP6m;?p&)Mt z>YPO2SXT3P>TCi6BhCKg>D&4~#sy!=9K0!vhW^T=Xls z=wHkV5IL%P>C&=5LiQhNuF?`%Q>1kux3WPAPJkpQAd)8bB2BIEX?uMR8Kp}&*2^%DpT z4_FAe`1f()my0C!BFhsbWLy=H!55p$od6+Kl-HBol4+M18w(=I8&!8M(wwlV_->zY|K1CeFC{Y=Cdh$MxzBo1=6 zd4%Bs3&qp6_r;X-0V1+ABGJP@pZ~Je=Zi{Dm{gLfwODOi8YE>JEe(Q&)U0i8GCW`* z0nF#P@DL&aT1qyF{vPXZTea>J=D~;{TW*OAk(MIQLQBh{xzX@|h2(jk&kO>=uK^>n zv>557s?<3fe+hfRve#s)GfogOHg*-A#?dCEW-NvAfQ1Iu`~-U3;A#TQR@ujHjmj9K zOkf_OFk4L}WUI!~iWD`bQmx3eZL(;sFg#$P0nAS&G3=EbZ{y*)!}TJqKQ7K&mefqi z34^sF!rSC+B4HvlW5dOU2P`x|a2c^qhKQJzC&)EHgx(Z6Vfv?Afk80>07(=PX|9S) zktUym7|bj;JYb=D)n|t$f#7zcWjVA&qEjZR+hGg7q;zqR%2J2{t3>(Y)CfY5gdwaM z9&j)Kf__O1=`0HBy6T7HoE9Y2m(%e(Cg+6sKO#sI2-bby*r;N7z`+1E7;vJ9zjt*? zo=9b#u-Ul<`2u};Su27B5h!9h3KfY)nuP~bdR0oELwzR5>Kir#?h73PpWy)q10a}8-L)lMepGCbF2j@NUkh?NMOvJfE(-F$LuoUH2OJCl^dt2r@T;Tq zq@@3ePCM3|rjhaoag)J8`>|gj!ztJGNt&p6{|P;Kkm`#JI!VR551Ozyefsv@2;y_d z_sAF!0|AkT#ehJ7R9{#+P*wFdFl-&Mu1=C5zttjFlV|Yy2mTMC;?!!L8XVF90000< KMNUMnLSTZzZM@_F literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/SplashIcon.imageset/splash-icon@2x.png b/ios/Rainbow/Images.xcassets/SplashIcon.imageset/splash-icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2081b54bdfaef69e3ba55a30a661391228f50840 GIT binary patch literal 10296 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 literal 0 HcmV?d00001 diff --git a/ios/Rainbow/Images.xcassets/SplashIcon.imageset/splashscreen-icon.png b/ios/Rainbow/Images.xcassets/SplashIcon.imageset/splashscreen-icon.png deleted file mode 100644 index 2b71ed8ede32c9635d5cbdefcb7f222c8cbdb08a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4082 zcmVXN42d3VX!nD^O(LVLKDF}$-FP!a#?mj z%XgvPHNJJ{u7SfZncmYgvh&0lc^cX_q=2Y&KnI;2i8umI4ac!a6*YxC!WQRazCwc&H5EZLFiy$+?#qoG`<47tNda^i8&ZgPM@|;)9P? zP-1rcW^!!aQC7{YeEd;eECW}Om5G@N)01Hc@Ft$NgGZs90POpf8NF082cayt6DR_r zAIdOmqsBxaYM4AS$Ol<1tT5*oG}YE9J<1ocv|QFd<_MNtMLCFuZqHh#)qI%&q~?`E z`3pYtCaWD5l?ar&J=QkWQbpJHcNXbLY~?e|fCW~|64)dy%A4|1&6|UKMs7;U znrm{VKCu5eGg!PVf5xiyrT{Al1x4SGg{p!uKUl%UAFDmkH!|=O5jtw0<=e3Gz=-?3 za1kn4g0hQIrUwPFVv$VJp$z-HBIIi)ctyx{0ng`nF5#K8PpXJI+8#5n1|5}VVb#Ne zX2S|j1ehum>bF{`&@qO8%%C9!+bjztydJz|U=p~5Y@JE8NkB(i4jAn)+tX7(h&?7?JkHnn*O_$+Na$aniiD%}8qzF&zMO4S-vTOg#iDJ6N`^ zs=s!slHY()LjA|^9LFSiH~_Hd#~Rm~7<*7WT<_N7mCM01 z#d0Hf--af;>PXUv)zi2))Jd|)%Z-XU@##7vX#d4SbInK%0UY>+Sv?n+LjZ0-$7*^} zkXwOd|D<8G0$@~$_)fsIVWzQ6h;F^K4uNaHcclgZn!~ah&dx)quJskh|4_?&crLmM z*QA>+88ZPuusj2Bv{C$1An^he3XC$9PZK2*|L~|eE5L!2HUhv^NXwf-I0ae-k6QOG zo)iAU)$IfOer~pg5^f7r`8N9zk4$k9pAnI2_w@#RD6Ph0@1ITc)8zUF5ENo^)5=qEo zgVuCmwzKylM`y%LYR)I1Zg?YBKA$RSw$!|wz@rHB06aM*JAld%(V)Uz0 z*rh8V&7uIF#c>OTfjFp^Q3Ywt#EfCfwtF6SuskTLmr7I5p`T#Ro ziNM6?z6hRrRH|yt8V%$vI2OhM+{u(8V=3wNlaGPz;25Z>gz^~~hsHIOPX`eIln5AM zhPtBB7H@)D+5It%c$P+Mn#|4!WIw>$k^wyYa5(7WLo{E1+KJFw#UUm48sM&!Sy3^$8rCaZZ5qvBNk&?9Dnl`nJs%y=4)@0^eF z^~l4)57PCw@cE2v1T2aK|5(s0Fy(n5C9)KQS-LsqIKQVNvrPq0YrZTS@yl9)T$-XM z*^j2s-gp-9SbYIXHmaJ(m<}8YqiUlClL<6o`whxNI22&*;68G8{Qh$GCMnI?6#&72(>c{wx)S6=-#2dsl%)zD zwgnuq-qA{ecYSYp@#1CN!w4~u>0rhI?FKx3`0>!S zNMFy9eckP7J5!yw$D;Q{0-Xs^Hr^Mp_e9JUxF=%1_M_h7nKN(<7%t7miWg=!P_OOB zB>JCxTP-I^YEJ<7Sa9wIjul-xj^Tjj2869SR<>9nm^u?G)AA0(PY%FY8^Ygs5%)wKoBN;WE>51`fl+7|%yEs+x3Ns`(S7Za z@qO%Ef5bhYtL&bLn(1fLJ7JP%n7TUei4@m9GF}YlUO+!L zkjuyBUCHaX$5NCR(ATv^KJQW3tbewvSenE=k?@JUzd4us-ZfqDCGWxL+E)3z05t0# z8=NUk@>uPrTs}7MN)F>Wc;k^D~hML&t(QMnOc}o|4BEw7GksB8umFs#w zklxO7($jf99YBt@(SVU}pNEtFg>@&T@Rg6Ga68^B&t^cXP8K`b=6+A40Cirs><#(y zb$`J7fUI0{xK864G>}u3Tt{1IR>%E^rE|;s5?q_Zp%qS5a-0qHbX<@JRy`-*72u$+^w*Izs6fdrvyY|0O}c?~Zqs5^$27(>$*edtF;r{#L$qGmgP@eNxp> z<7h)qhc3^;xkGuZFbem4Af4ZSTM8@AH5x{_&-&Rq(>WSpssCOU7mH8r1P=AN$2L)k4V+|6gmZ30&fvcmOQ$4r`$XA`#RNU zW7P$aUX_*|14}PS*OPBZ;R{pQByq__uS$#eM3#1)k|#He%WVS(U0SZmTVul3?LK|D z6_->na$35cI*`jCQDef^?cUNok&z{D%TsrJGt(eZgIE=#Mgy^D@p#MNJ%g*o-F|zE zRr1wFXIi@_Lhyce_r22H;k)}jU!-{}5xU_qX!zg5pxILM+65ln@S*=b5t=PEFE8*2 zU!UZB?EYD!dX80^XQWDC4jdd|2vy4&A?;b1s*ZO^o6I8oQTd)?>QeeZz=9!+?IY1 zLwLkY-0z9d8R|Rdqvip;haU*ifza=s2tCO@ z1R$npwpqYq{V-vBO5e3Hy5T)(cSf^~tLMQ+XQCV4lXj<>ZDqXx5L005u}1^@s6i_d2*00004XF*Lt006O% z3;baP001XuNklE<%T235NL6Scg;Yudv`R<|5=KFSk`M`O@{b5L5l%2J4uMz@0tQ3) zW8*vDdprGpf4`Z1`+V>2-n+LuyYK9=_wD@o&Ft)NKlhuN-Pzg59CQsDn7!G~-D}N| z?J+|U_OUTX*@~GBq1h(F2EV1BaSWds^*0o7fCub$GuMooA?RkvK!4bd5->6VHDaL~ojo|>6MomfOhl?eI*ZZTS^aR4uhlsN7MHV2>wk--BALi@bwH&y7bW|rgBmjgcN&-6i`b(aFG9yzgZS_9bs zuw7D%%_=~1!H!XLwvFrnty&yIQ`mzt&l9~cbc}<-kW5`l94VtLqv1~jDe00jJ%8*r zvjmD*h3x_}Y|h464rG0%(+^0S}@NRiBbAmgWj!>RR||AYQwKxfSg zoYIU?r=?dZ)X_3N&fvXvUbV-pLpNj%*f~d;?!*OeA<;68f{pu2w5nzc5zGX)mtE;U#c zO-j@1@JK8jEg9k%%|4$tzX*7a5_uoxBPfGBl3)9d&dAEKy6MM0V~)YOTo3rx0=$_; z*1f9$?Ej8k3}vma)y!&)So{3oKoB87;(?t5B(#1446T|E6CNL*0?ETCgAg1b$uCz1 zd03E?jhzFP*?pXdb-@q%ccMQuwX30)zA{v~D*!z7zwMIYs<{Ez{IV#*En@EkA^^j% z5P>}aBO`UohB!p1hgLEhG7pIix-aZqkT$**-UqdlhJH!ZUA_fp~`jr zm7xBm2JnOT+ksv0n++qQ<~mrsel~oGk>or!m_GR2QdB~jr z^H!L*%^j%RqEc4SRjPCV&b-?$#C5$rHg=_Oz>2yHjq9!#-fL7M6f^}x6GWVlP@bSA z`5l}-f3kPb5lA?(bS{qvt}f~ZAj)B5eG;MKJZNqg!s6YIimfcJ7Ofw-G(DM1@3%bz zciHveWm|0GI(#@6-}EIw^86fpv_u}Tbew?WGk95nQK+ovmpCm%m_u0dBFe+(%V(G} z*y*9*FN;H+dN9aXkDJHax&=P!&i$PitHxR1wDaT0-iunC&l<_?6z=_>2W#o$*+kOr zj2Gwg_~w;zly~`(zM)S?S`tUnnBSG{kI53!@pAjc%bex$6sbafVD;w1>fMV|Ilqt! zbZ}6AxjHDKv#f*vZZE`N?-nYL)=VxwcH);GE#G^+Rbp&ooXW8P##2sYow=%8FE+`b z$E9oE54nURS0eMcGNdrVmc%7htXDv!i}?Y37sBd^{)(wVXGbjzKsLFvzF}{|ynsi6 z%F(=Ldl*N9{<_}< zZGvZg-ChKhZL%g7xiaK8cA9d?4u%d#X3rlkezlVeg-Y-_n35q!VY1jy>F9?3E zgA<_~H)Qc5+BCB=jC1fZ9bt-wbb#+7G`X8_%xM81br%f4!LQpZaQz;_Rh)%OhYOh4 z8&rdrQ=O09|Kg?rqom~UKrl>VkV$q3i#!9~A+62}Aw!xIX5K{9#qs!(J5>>12Pufz zec1u_fbR;x_Ye*R{Y@Vi1i-=D?Yh|7dyI*t$tPrW+v8wyI!!LJzq*bZ0Sq!86fZ|H z?`I?yv@&o6F^NZ5fo!5@$*wbb7vZ-MUr4X{W zvF&l&Znq!7zKP51L=XKJyQ~)52XH}q>t;nSE-$jbO38Z{yy*BxxV#fv=w-2&H2%2E zywquVISwrz_BN73w}QG+d`mEj`~S}B&C+N5bttdh$3bd?1lE}ij=OPW>}W;{ibvI!#o zvuP)2zC5vZh_N4tOpV~prch3B!TG+1G6>$g8I(0n5mUZ0bH8Ti z4-eZdxV%Se-wsDe0Vc;IkVFIfIyeX?a?F$3oE1v|Lz;j{88;eE%louM-T@gOX-(}U zaNJT-%5*|YV&JsypI>qwSBb?zsWAF z8oLc(&61uAfk1`XUrXR?p~+463H|LEfy>>hN%#L4@B4K=K52gOzJK+jr~?KXg}64G zU^Kl8<<-fu%DS>LnjuFRu5K)EumONjdgL}qIp}#Fq>JQ z-{(;UXnrXe3D~QcT0QvdEj&iH=<8KK1{prJ=oS~tY6az(RLa{b?1kbcZc(nS+c2}g zY`OU3#oFb9PfVX)d=H+U2;+35TZheqNTxK8PxDYQFa0dv<0>A6wM3=?JVeIFp|5u$ zGH7L(we(Jw%dqC+QdE?q+vl+*iY}&BNp7i`3xwCKr2wP+?#ity#Dwn9FWJTD z^gjpd*F#d&%3;r(vhfG8uzUo{-<#8ZA=2<)K=b`RC#!k23}2SFj6N)Rv5@TOpP`Jo zJWdJSBo+|UtQN!iJ%^fe8f$pRX7_)wmCW*aMWC^p*kQc69-TTUj{v}S2?zM0m6AA# z#t)lXSC)7*An?JN(h#6~3hA6MEJowHWwlE!gKPDSXtL zFhNf^XrkT+R7*#a)A?17 z6IZMFOiKLW39HB>73(IjfU+9BKF)_7FTni@$1KTccf7No&;nLRv6R2X_ta!qiz0*t zZv`8RqzwOwRdg0mZmB>_<0-E&dCS=tQgD4-jC*{ghp$luV?+ED0>7tLgrnIgIeb)$ zUhgIfI{GVi-uokV2k@EM(66Jc>+eZ!BFs_%oq)zPv2+?wD_0){GoTi4JnP3tZ8a=5 zHhQ6!iQjU&aV((w2+R&BCH!|d*yM81;ToedD{x#3xOZQ?4!F3Fz@*NEpvlcW1xu}& z#`#gOkAsB#YgB*(6_Jgpw4TrzM!cgRXCgyg?Dz$uBH-Hxow47Sx@2Y6Vp9Om_$EFA zQ;XKfS>Qx?E=h9=_!2)-^gQbW5JDxfuG!Y6Sz%K}xMtevsIDjE19PJobeLJ)4IfUO z%`Ws;fMdU}z-PPdo^ewEUw9cGu8ZuEf(01Lc7vQr-e8T#QkdhE3#>+)TG-6m$Bov%vT}vBVYv!XXoIP`+EqAg#(dHCzu3PZJm!}n9f^2P4|E@ zHvS{NwdPS3;WGa45&l+e+o6LU*xtn{jh(ozAA1h_%$M(Q{JxATOVufoDG;hZ3;k8( zRj2pH00@xqB}&bxmJWz8EOaSE^a^?mY9IlRDVl*mreX6SGF1`V@G(7sF%=CK5t-dM z)@_)2aX0>gUT){OGV7&g!u~n&)yc7TxSeWeD@*-Z=z9sQk|RDTTsMzL9?;NVx7 zP?QKyV$Fmd1ybS&p&*A}q*0bkN&q|I6Y&BuPt{pW$}zTjiWJC{VjT=Is&ps7yAgGq z+Kf4CRs}x^KJh4nqy8f3&zc*f>sz03*Z?4)xIp;8k6JoHLQDvf`U#Nuz0p#RDB)le z+8ENDjxP-(3Z>CcAZy1U7Z(I7+C^p~z}tXx`%OnxvF3t~^0%9refLp;JNvPy>h*A)F%3%-j?-c;Mjc1EubMM4?{7ew zUS&)fB1lO;4|tJHj*tl&8B5aDG75x=ya=ep6gVL+X|R4+Ajlr2=~JzIhxvBmTra_U z#7}luj%Ke)-)|t3vRWyG&wJl)MKCuR(I5JG9qBIt5UX1)Cri>-6AMT<2wVy@#6-T& zhj_JkjO0l&%spJN#mAx#jxR%<`6Hvk-hGi$bPY z2K84lD_a?4Om>6>KwOOF(tr{;ajr3CU(YwKOae)S(%&DXAsho-BF7{}PfOK=xCgIP zF7imq!NUD0eCMKKdon&~H~{&k)~gxUzSZKWKV!}Xe3|Hvc$sqD`#*hKr~d?1S;$WB*xJ>N~LLLoG_)$G4rUS zM>h{8_dcz9ob!g&~1{*|wo)Ax_cEnGv% zToyO9<7l_T0Y|ec3xIg~F~rtVa3OFoRsy7W)Rqa1Omd*HFv6yGjqou>%aB+tK;$W- zpyIjjJcKZ7I;fNTe4XEF8Mn^X42_$XbpoIJvJV*6ZS3S$%S2Um7BCtjFN90DA&kNZ zu%U-(f*QkGoB&0#d&;Jp0w9QN-lY}N^^YL1zPdJ(s+Yl86wtx)> z&pCj{Yg2i`(Q2(K3%+FM#<874ri3N3B_Jkb35x=jM5z^|yxO%okj&^UphD-$lp>MV zk8N(NRm(t*561iPY&S<|x0|_81m^(e?>OJD&F^q@R4JWUkgNVGdq-&f6gFXxetL)( z_DPx&C+Fki6UdNRRc9d5FS_g{YX(Q|7(xYN#MS94!T{xeQQ>yZIA)DV! z?_N%-n3z+lCY9@cN^EyE z39*we4Cj8JumA?rUoSYCO@KT+Vy#4*f{x67W}<|gQIozNdXM!uPae61P$I{2H7yPa zU}SdW4un4dS`ay3AI@vfNeH1F-`fr3l0G0Uptpiz(F96`CxKFe9Au2G9cB1WEhq&j z=koIk%@~^}w-~-O9?pg91BN;$eQ7+%(G)=N;h_?MXu$+XASG!4iE(s}Qh}0j!Wf(1 zl#B>7u@0rBtqtXxtyqxXvBLlu(gFs2(^ySZeix_fO15Wwer|PmWT;w=hS162B#oo+ zrvu3BZ0_*~O5otP{2u4*na|x5c6e2Gjc&%%e!V$AgsSo($5GT5_U!64?h#*qC#38r zmT~>;N3IJ7{*v zOmOH=KvUpq6HLtT3iEqpJYWE{7hTg|{q62Et9<*<+U0-`@4#UFYr)K4)Rbm?)WN-K z;Cb7Rg*LeC$Z|YoUk><|L3JGuEvGer!zWy|B(ioDx~&(Cy!g)9z$uLb)No(hgjE=4w-ZQ)gf3aB8`k-q|1CQBxcrkY!;9G-yM`qQmwo`|$ z1kj%JxnoAE@%4ajEd~)Yi%?uUN-mx35A88{vHg0~Yb^#8;lE>&Qb<<;IDF!o#im+a z5BOGd1e-dKgWgs&u-PugAM1L+w;KCW=&vgPFsAUWZ%4{Rc<1ZSwLYmfPElcX~$+^oREYOXx}q z;PCOETQTz1n|DBGiw=S}1#&jq6&TTq{-%&SSeDWOXir$Pa3mhR-P+p9U|N_?2YTEt zL>J|DG`C%$KhB0Jg|nC5-!pRjRqID=bsH>RS17L(iu0A=N5vnv__(-y4xwxGSBlv% z_Jq&RAF(6%VxV!p*Jrov2e#i+ybgb4=bL@zUg)gr^jEkA#0dAo;dppUH^NtnKa$7n zg@A8MH^N8#6$T)i+`T7!_9l#QA4NUFy<5w(o(@i%+?#MJU9G=Dnh!hlR||%t+I^T7 zbzZl#P)HN}6T1MfXhMIc>-86W6ufWg=avoEY7YZG&Xhgq+SR}&yA1F_e=^g!-Q1;< z584C|FI|069LJk*Q~4l#Q$gWzdl8=9ZkjIeQ3b&O99g>h3MlU(3^ry>MfV4Mp2zGJ z(7{94rj`DJ062X7RqJfc+=F>~!JGVP0q!Qd4s-SHf#sWa`pXqSSi5NWgw?lTqUf!- zxm?JAr>g;k{>)?c7PK6<0={Xfzuf+!2p^to+y(GB+3}!jR|AA^v$+e|rnUZZ18`*N zXKy|TU%S+$@)4y z@;;y5YU$$9+Te((9J|Xz3*Ir&{CBavV=4=li@JY8ig!5l$>9{o}O=magZ#7fjEx9VVJJb)`*B)#K#itd>nOv7q$&JMOTb zn)Bv=+bo-RzZvMw=95hw130|(ksHcAtHr|F{m%5Re8yB3?;3}K0;4zKZM725YT-J# zr_KEzv+_eh4$Xqq_1@pl}@?R`}N&w0WM9)0JcM!@olljoSrtdSqFg+iCv12}R zEkI^7%R3yU(%)fyubaPIa;-UM{ {dD0|0&w3m-@6XCTh31xRIJ~co=yJ(DrxxC9R(<#%Or;X`6HNPGs+OBzE);~dTAsz_UbKH9LBl<< z>0A3VxuG2NxZ@nG#ziGnkRm z_cuQ@J*O4Z-|OhoaFwcp^~V`0*PMKrId$$M9i2*+nOm}eT%XU_cx$0+FCQ{uW?Z|; zRF=Gv<@tA9R!bI;>+_8o-c$>=_VWHGc1Z7A=Gs$Nn8k5f=M3<3^Llz9*7ti?9AUBpLQbV(}NuOeHSzLT;4Y577t)tHJNCk2peGGpLT%(AW=aG=juwr002MRQH&g7n7$2m5?wYj)H6 zn-D;*MvwWvtJ4|6`LT*NN4woP;P6V~YV@`k{qa@{N4sSjaCo((_Y(rhPa&ZHSIBDW zJr{2+&8?QS!rJolQwRmEM*pdW|6H0|EfeW%TmbnI82%AWlsT_7KH=zHwI#3O!<5U9 z!0aWW#?1W_I5$ zdAwHi6OLvoX%^QMKz@78Mz(-A^3h)X^-sI)+3r}q^4n{1_!SM<@4I^GXA6C{J60JJ z$20|yAO6F+1poFLr&JX+t7T#}wVBEf|MA;vfgPt*6*a46s;Al%Kz?;{ss&CtA10G> zKHs!({OV+2$H}Ce&)02k41oOJE>2=a=o8^g=B}7bI+x3Gy-~c^Y2JnZy)jDW$DRW}cH=u7A*a!gIp@|Q zUdO}(J`dlH2OB%Ee;48R#sG*32VrkK#2x&9gel&@08@tGk{hObWM`PyXL=MtIS0PZ$?%=GT) zWb<-c`E}MyQ2p`M$ud3X1$4V%;cmmT+q*v|Iz^h>_N!GhtJ=>r^&GtI!uNJd;zj}Aodd?)c!_pbTB=q9fM|X%Xen1lLR_(+ zB-U>u;M)+LVSdxmsRh;_S1ic$rSVpE0q{1WncaY9wr%|-0NRVL=^uIVowHj#Xclr@ zE~8Kv;fou_Tn+HP)p0$ZxBccN6I6d(E~7{X@I-%~iKec<1iYdTyKoo1fQJrO^weXgSiV!T zQC_02U)n(oVuI<9i$i9$K3{SUEqGkByD}^Icu28;Bm3SsC*;Iau1p%-alpYoU%U7A zTB+zRa}N4{7zl=OT$wbq1AHT}R_yb&cW-o(ii!n{4DR!Xa$J)c%iBGzQyn8~e{@f8wGe?y1=xT7_h$3KPf zQ(*lzc5kfc1aq8N zfM>h89&fY7T?rFJfBXmxzrzvA0lwXQwwveiD%IhUV1K>x1tOePFo#(!Q=VARY9#|U zzx)DGJ0F2*^%TaF7F0{3+TQZY}4CQ8+F#6+dm@okL<96IQpFGW6 zshE-5@;e-z9y|)8znPUi<9_nA(^F`Y|Ml_S;bzKsA)h6Do+KJMxmj* zs;lnZ^ZWh2z0WefzV zZi9Djy|1~o&bu`(b4TL0#xq79@rum3QIs!JoQ3!ov*DyWxWpUhJ*@a3Y+7?0T-~k5 zaID2|4Qwj=A}#xZYX#Dypf6MGEQYPCkirNYwbQTs`II{iZ8^Q++!-*~Mu2iXK?@^| z!N9N`1GX6`(Q=H7KjUc9ev!;oSnLt-54e@E(`l~ZPDfkLz;7c=xgNCjh{rl@U$uAc zbmSHwxArT3#ct=$ZZzDvfY(`2b^7i}_X-DZYhVQCh*m`SM-sbf7Kt2VHXtyCWCVCt z%Tz*g75YB{{%Ls2-R^7{;avRAf)P(g{0e}V=4=gSv{u?YautB*F<70luKX*1)V_w> z1^}K16Q1{M-Mt#Rh6zX^4RHoTay8WqBoK(8MnGb{<(Q_?$tndwB8X<7<>gIfRjP+0 z;2(BJx&3Y%syGiIJ zEA4`U%D4*{#EpODmpwj#y|8z01%NIAuy~>(fYSgML2Mv1K;{4>!T??cL^(ZLCD6Ep zX26QN=~*KWfyy9Wi`9lebJa;KjzmWROXFp3683Glw?e@sFwn}56!lQ3T0(a)xXb^S zKet|U*F3h@y&0feZJ?c|h%S);4M5{Em*}$?MWPq-kuekr%%J5S7`nJjj(R9gKx_G& zJ6TprF4c@}6*?IKzY8ayGItG@#&5>3ukJ)gzho)^w>i?QzUbHNue)~whu2IwcdElW zS?&<>1{njCK_`?6NlZ`kyg5Bel0ZcOC?bKBUKjrYC~M#{JMb`48gbO1BIHb71r*Qu zSYCzMN5Fp<*Ir>?a9o2yJGCqWR{?l-o2q2_9ezvQyZ4SyVsGsHGJ#g!v?yr)Qbq^R z1RU}(#SAv)IW22x6-cDXk8*m`=&4OuLQ)5AmPhYQ%}le#Y1M&RftTYmSHShzEf}o# z0=)FLyh)-|p#ty><^sU7u|LN#k8?NH>;83Isxp`t48AXdjAaBJA;TC*5`Uo0WeEYgWQR$Lq z{n9nNHw|9D(~mv%l)DPr-v=0;q*}OirF)Afi%5)VjvkOAFBoE>aN1etyga8vFq~B; z67zDxPe^2Jx?9Rgi##ePkAckKm4{y|Ax$@59gR8w*PsR~{IK zJL@0)$o&twcR%$b_aS)Cv3$@g!4(9m|U+s#rOSO%Ig?PKr=5lKgcp>WiXI^AL`^`qf>{8J%j_sqSRPX?VH%I0?IcvF2mC5)*+Hw+bvXv=WB6^fff&r~l3PNr{-6HD{ZsCi`jqG0 zQU(m65NX9E3L-7b=eU%X&m>B~qtz{rhvUg417nazVFa2$D`tS7arE9u#uHNpY#zg! zJ~fOx0ydH~X`?){tP>@cVOu~GkCLH~#E@S?k$=#gh!az{;CKE~==PEU@CkSL<c*G|1=6s=k+X4irnjV#<>aS}eA<4(=9S_agUm_ZjqX!{GLE z=AI2SfX6=X*8yxd<67=zoY4Ad95~}`dJ7L>Nh;6Aau$o9&@n&}R1t(xQRI)uw=pka z>W31^3sKB!mk@MXn%c>w)~GR|0kIt_0}u8LY?HVZlYvsK0Rc(rAP0}hjXKa<0Cycc z?#;LfNf zloKN|hzZDu9D!3ig(i(UqIWe-AV5YyM{M%svT6y=W?+Q|@*I$Cgie?R0o5NQf~eX7 zwiZ=Qr2~<|393}7lpgPuJXY!-D4&{>(!z9j@|5twl=JLG&fsCt( z9T24X9$L#ZC%C|%bYNn6089=gwbYv$FT_eV@N z+-;cT7poT$8;A*n94ph(JmEwfDn?lgZ_q)SVKppg1r`D*$f=O|;7KKiO*jT72nA5` zhqQnh<#a;J+L+U+gCWWUp1i%GOgwQHEMAjQehu;=Fgp+bl>(3f3dt2Cx4vGp;siq_zLuLN&`To$9yO@rig%?NKb2-7!$B2FW5n4 z&TKlE4KgH{TvLyP33~9@pNVm+_6B{?qmw7rm-B#-w@2dE29p<|^cy{!>)p4}{R+G@ zShKVM#>CB5eAa)!*WEohQS>r8G+T<=q;5`PgBHsf6eFEae8~|sOc;+zL}u_3Jh_5E z7dTCTvL+uCfL|3+Mwp87MS2r#K{~HPZKEv3S&zg3b~Z1x!=%X)>ujduexq4J!Ey!k zA@ld+nyz#ApyMwqSL^%N+EUth)op%F{Y7^>fP109R#=8=K6Bz@3?qJGJiUy00|lAG zpmUc70Rku9@zg3$Mo2LtAO2LH%NwNBE|y~{P4HWuA~6jC{F{8FS$U-A`g!JA&10J) z?{s;#hw>KZ{VL%SS`XJxx!chbzJsa?2N{9VorPZYpZ(UU7u}y>|9nCO3FoX$@MeM& znVu+ukYgYkV`YL2GEGpSK#B}>R1jq(f{g04jCn^YBNGM142}YAx`)i$Nr|AJ>L@F5 zWh`%GD5DUfd=-FzRsOck|r-|GfTCEUj7+>{iOFh zF-=bpUJ4UA%xFz?PGU`Do7>1Bhcu&{ZlopeGxRxa@8JYgpRC8V=j={JF(iy0(iInzNeYZBsFEz<~*kAyxXBL|pV|G!1MYKp>~FhZhMCDptz$u<4x4xk%#lP^$DITP(F=Y~ z>&VKC$k=rmIKaX*Wf@Rtmz5BkIEXt?(Vm?9i+%xVD zOx%m}$r#rRq2Cu&C*?yqBBeuIY{zsSwu3aavnZeNNv!Y$(H$7h>Jky{*FlJI=s>i$ zB8UDLfB5dF{9V4$Fyltg7Gg#M5}IKo&RPqc%=(EZV1R@|FnJIl7F3#0ju_Id2J@^Y zEDBMAKsf;h2`#Td3q>k4c`K9mgl@$WhbGE}`dZ|vSnUmsW*d!=*O@m!i9)^1Q!I#v z;^ZR#m^&O_I=Bn%tiZbf>m&)_HJ|mzPwjVK!@NCL2#X!m#5WKSD4g_x1dcFc5vdH6 z2&UoEqBzP~5j&>} znu5#*lJSNNi3qkcuu+Kp4n@Y0(AGbM_fqX~U&FA%zExPr2qXvKRiE*j_D=Zw8m_U~ zpcDYbS&1Y)5rM&pt{;0ZmM~ozi7yU|3W=vY#I%*r6Iv00*aQ@4C}0tP23Dg*c`G3g zI3&sqD?&ar(ApS1H0vU7k%!z?PBKfH@>D}z6hWU^!hGIHW5w3m7v#m#EMjpo0pQ() z&z0PV&TLMmQ6+9jQUG54X@53eb@O%1!>0<6~8FXSRoRTp<138Vi1{|kQWgZs!C)84(7yY zvDJk%vuqbnUKxXE)Dh1lnzx50&fwVHnq9s47FLxG=Z&&%%Na{lU7Mf6sER; zut-3fT>Oz-5YP3fBtro7R(Ja;IcGRAw&VxMUB=T@|k|5#AtPzH?%ZM z*xshDz$tocztOlQpITrt(4V)3X_VSli9-Fzvov-9x!A@?W=wh8FtK<+C#)vjSI`#O zckx;>m^CjdfO)BC+zY%f*M!uJGZ1hBYGOv<2pE{~{0|@zV8Exz8i9ihVZmVXmd=Ty zV*@^`gK_YbB*gjxAAv`GvCe$AA&>>YiU(ZODS1l7eo!8Np?$G!V6eJKhn$t8CCx@j zPWr%-*DJxGMZ6+FUTUa{%$5mk#?k++E)^Mgt7G0C4gaD6_=HdS<&%5eo!&P#Yt~}s zY4U0IvA4PZv95DwbCPO?$I-B*v;-+1c*GZ35NjTrasvp{nDLtDOjEYNA0!IIP!CyS z{kgogb6RUnHuC0jO+Bg{I;hY7nhh}AS&Jg@$z$yebh3kxw@2cIvZlI4N$DnyJ?>64 zyE@z4Lkld*Ni5wS`3-*u?tnU1Q;zOK|D2*WDVq~F^qxFm&gq!=_Gn#@m8kJ(vXfuI zrhX8Yr-~C_EEEs2b`px!7+9=;Ipo2_SSXS*H3l`1*XptpV(d{UBbgu$w?vveD~$9g zY4WU3(v;yXllUh<$z^>-egwqji1B0Wh9N^Ma#uWrvLTcy%{+dK5YS}a9?3hbs_VS- z9sm6hc&YGXeyZ@R7t)|F3V^@y&Bo_^mR*eL)(o2H%wn=euy6+Ffm55oyq1705;o*# zn(X+Qyk)s1IWG@sVo(8cQo}RIOkna$9s-%pDw`g8I>}&@w>9X1pmaz+*2fHZgG`iX z*3v4FTu!3|8-`zlbsvU);he4Kdlv;*&;Z!vgWcO)-C=bwLlKle$M1Rk_Top-zKGu> ze)9-@2k?qN^dHCVk=r>>TPC&5bTl246s{}>As7jTCK#CHBqt|Ikmi&&o@T=IqZojU zWulp;Aa5C~i@Kt`d0YZD%Ah2)DQH7MY`>U7TPPz>OhM4Bb(E(1*cZ!FUTnyEc--tT z=jw+db2xshAWs#xVFEz}OD4L-Q$-&~x3?$Syv1u)1632SyTgybC2fJBuQLMRy&lKB zpB7-`-7sm<0s&FiIt@4mO!N$ed3l)W@w%$|&DIy>2_9W1Wnn0je4vv|a0OL447 zVu$81#;*wGVwpf8(6{mzc}(8)h+fbw&_X`cVD+j_qY2RfoS+C2+idzk5hg-h;9x-bmUOPj9X#bZxZ z2hBeCl`4)mi)3_AJ|^#Q=)9ai5) zcTVU>my)Z4OW~j5_app%f*&VNpF+>~mH=(G@+N;fCN02=UbW0$5@K&H=7i4!frBhp zz&7bk7?2bTw>TN5oB$S-=jB0HtRd=+RY*P(V{BC@XKkToJ65%31TeEv)(nf0HIP#Q z%MjxmdG+<6ACElG9uHu^Fl6q2y?}1%fp-E1eH6bZ@SEq!CrET9^c=veKknWS6YK4f zoWgeE1|Y}*AgWFH0A>RtnL{552JtszW^L(BT})Gtg(xO@kXd3pk)x0gDvb%{(qkH8 z8@WS>=^UhlE7;`8k&veajpB_l{5GJRFGH25W(x*1JOKMHwYNu(qsKqQkHGE1i7064 zIP`R8;kfr)yb9+Yv~D=}N~ke{AYzVQmQ>Atrj@r?P>SVYsZ4ntQwF{kd8&#hgHYa- z4|)SlbyJ>+;&CkHMGs|aS3wW>Revr^0qc`rMc^WR0(BaF(YHNZLhGgLd~fq2U5@Pg z*z%;*5Afsh?IHs=_PuA*Z1t!75%qD8<0AMW)=~h9yj3{4Bf3BWrT{zxc#w%@p{32^ zTb73(qCB1RS(U||MGoczcuc<7F7mR;+BqPO9+p+bcE&mzxK7(R8N9~@#bQci(<1=m zq!mAR!Y?LpoiW&f!2K8ep2km;D4p&`U)9wXVY!(BytiRG1H8pa9gj|lw@Al`hzBv2 zqFkyHERn;~Vbnm5a;BDaTeijyXsIh{qnLac_gE$C4rwie^EBHK<*0q^!3J*~Lr36#4L_b)4s!#kWI|7lfmeSFUy;L$ z=y-xj2a55GEe0TZGC>37@{k-3L!_d3yh)H)nt%!53NlUkFs@`lC<0bes?(Zb4A>I2 z2x?xGBbn)tXE`;KGwM+;WE#f+xThh*yQG#{xL@C19_%}xx)8OsgO0wLB0L0V-38?}iqKr8B%JPPp7Iwha; znaqLmGt*f`Y>Tu}t#n!2{E7^~MJ>mWSc1^yC3N^cuk2fb-p{{@`yldN{GOS==we88 zbrx>E!;e1xu=`HKH#X@e4X(A|eF-XhH&q5S#N*f^;K(DSfQjkcQ%jyhGY#bNgckJ% znWlV`X7z`mWdp>EC>%U+ClT9N1a6bB+5X0fcC4$127=1uqb>p%$GxLCdGj6gdGNl^ z%Zb1<%REWNrE^I_SC`NL?+pSkK^hJ&V@&Lr2X2l`EaTV-d<3bI1Pw_|JyuR4|D_E) zJQy?Hyc~iAG=s@A5q=~hs2qISsi4gCAXfEM(BxAa@gPC{wW#Mvqc7p@4e0yeftS~F zc^k@e<+E&tPnQGpmSbo6u)aK=Lvfe-)9V^kxlT=FPpc>u4a z0}mq8qgulbgG7*vXSQRSRmB|!(v2fgwP3C*oe`T|k4K;-NMoAzbeTMi7XUNN29;eVfO?#%Zz=3NprDlvgSA zNzZh!s-Efcth?}IvE&g!KGdM6hU&k-GSUVpEWiU}>3kwC8|}him-Q50(~x}B4>J{g z8K|%z58SBxTL9K&t)RsSX^_H5VW}FIsC2Y3tylz(XA?B?rpjVt0#a`(r9d86;5VYY zcWxEXqL(&Z^y!5rMYUW)Q$Io-7e?x@VoDV=Q3Z}b!`(6v;C%#r`QBifv||9T{5^jK zEPQ?(7QVF2aO>F%ZQ#E{mlX-jK(^!WmhEPJ^WBS;+Ii)Hns; z;1}|wSmIA6#wyBepqP%IQXsjVrPez3X3Z}4RuD}~dq#0w} zhB00rZBj~_;*$B1lD56gW_JYOZ{F*!0(dqOwB|7lkOm5;qb{@<3oWUX9-?q%fyfi7*29yQ?sq8%sSN z^t?}&x(97Fe%>>9^GE#X6VCrj!})cpK}bQWfEWX4pphw-VF^u`5qR;Y2}2pEL|fRM zH03E6%9vyhIwa4G^fG}E(>b51G+o>o1c)P^;xX@;fzhM~cRSCMSi0ZY;~_eaJFm(b z9znwg^q6Jg|Snjp6G6-^Y*~U&>+Obza`25vEEh`!LT&&&vb-&Lqu7VM~*_0H#)tnftS4@H@A$NX_Hq`khgSf zlW_(bBHk7`^{z%EPfI#}j7X1V7TZuV-Q;a9j}4fVggn45c@xR?Fl+KwV0_@mR?55PsOqzgp! zs05=tt9+`7M$nTtlnIvLr8IvLgt;D2sY?nFkWp$#e832Jz31uxa`FT|5?I0q z@w+vyZ2@@oNBkC4_&QcfM@KlA_bUJc1p+n807%P)^5AJH73t!M;z8+w@~klg@(7n1kmZ>JkjYg)7QfS?f-0VE1aRqS3&vLVosB0+Iv>XWL6R-&Tcg?nuxm8lOD`!L z0)o-IwfIPus{}9vs4N#b2`5mPMN)hOUNNZ9_?z-A49Hk{+(9U7jS6i83)E7+f#cpu zJ{Cwq6%IZE-o5wW3<;L6XGB6Tf$4{IA7-Uz}Y_cP5>=DPKK1wM8FU{RKpF4=9#q&MwVWZ zK`eQSQnrkiJWBZ|UV$*`F+PcDW4c(4$%BZrNr$@B3=!Sb<_f&cv6~}Rckjelmg{jr zzCE%6uM9gUfPKSX(+a{SCz_0HQo;Yz7qil{oIzqk$BtLK`D+O&dJvu<*UjOZ>REXpDmbc-4pexmePkDx^V5 z$DR=@08JB|LY4stNFwG`#srH5X40G9SIcIBQ^9u0F4l{q&g76 zBo7HX<5n-syooo(nkm2%g#b91?2q+HkpWe;SUv(;(&A^KcXfQBw(+u}P6<_;*+w99 z#G2E!@Zuy8<8L+(UwHz$UkOQ9_WORF4hj_%tufGAg33AYniagy><3ZE!Y&_-*N~ z_gMvgo|T?D1H7w(!luNar+6ilcK|A5cs+!-XgrM%pzHxH{$?J7N!ZsPXy2Kc z6QJ_AcW(mi=w}l$_bhDmE!mYerhRL$ZwA|r;CHm!Gb?}_jmFz_NhmZpe*s(oBY|aJ z6bax)Sc-t6O9V|oC8I7e5nP~1p5EHh5;US@z?APGj35O_N@4ya5=9h1Zs5b(_0vOs zkfY4;6wX~3y1OyHcLS)qFfMT<=GXIvd)xd37Ll94<(cO}57E93w&m|ew+qw$p!OxI z4hVeL^9#E@k2Y4ygOY=s(gx3}#{&aE16{eGO)s27y;@d_hBgp@)6xPsX)I$q5wW!< zAIPE=<;h^bC_lLkUkuzp;s6HQ*WHUf@9o&@egR|k!a{qgcRfFkqe<^@&b|bJ_c}jS zf_8S&#Ax3kvu}2to0olO^uT+ba~Hw8t`ty+sBomLWirz8yugbc_maT?rkw==mwR9q zp)5WREH-PgPE>^*g8D5G8)&0Ek!opz6T*a_SyU&kV!59tqF$ndou?{0;c{RH~l zUH|g}zO+yl@Y4G}J#g0L)HeGLyH8}l)%p5jMgaRp<1INjqhkYb1W;@vn4$;7WH1`R z1;FalodIYX`T#tw_8=||aSaSUft-v{o-~prOm1ea_B<_lcwR1@$v-H8%c#u#F}&?3 z(XSu(q+8y-r6+oOp_IqIHW7NEz5hCCUl03^xld--x&_L=|x?5=~yeY9JxIsm|b zy~}L@WR3_9PT=Jdns~He$P}Q7-+S+smr4U|QIFNb zLjIeQDSBTm&k>h9JdWmHi|;Z0WzW0uJw17JM9=H#Mg=@@Xmmr-qU(4ZyUlB}8(i1z zdjNok>WvFp#>|jso)Y5_J)xGgIsq#98PEl;;$Vd`>0mknI`Xgpbg`jK@?sVpyMoAQ z`st13-4XMn+b1`ROPk8v7vXiU#tw=vh3S2$>+)dl>se?GeA?)Vg(^uvp7tGfSHtV} z#J&drxZ$!31X6n4=t1dK<>}~MZBT5<3?Lc$$QY2=Adp9DjAs%LER_0|$qet1$Z(-xH2aMD*RPE)34kBPfV6m$ehpC9>ft*=Zp_~A zdTQSm03Y)~f7D*@&x*ipf)h;v;0QLA8SJnX{H(_;4k+;jW30C-=`ZNt+?LPl_S#FIQ9V*<-Ef|)$6%2j9!UIU)-Hi2s3lRT5u zMNI*;rj=U;FrWzr;;4u8AcR!oM-qxj;}V&`jODR3@|k$k z!>XK0wVV#}R(sIRI`T?^ZFt{})*6=mwxzB`c0grg%9Cm z)f)ibzS$QG+GfC|oAWTa%-KbZ09-L?AdFkaEFriUHTk4M-rB%y4BR#~QH(5-mKp=E zaZz*7PH@LSK6u{7%Ojyw@so=RUK=XCWGLxTqvtK>6Gu<>8@#k*4&b$)@GI~tnpbIA z3(VxWA!r0f(g3mmI>Jl5)IwkeKKWkB2PG_$JW2#|^S)Xls}cfK!qP+@`?LC3X7VUT zS^brWbwW+-<=F6;2+JyTq;GrX=>y}RcDQQp(tp(fZ<*wjC{wUwUM`#aZr>chLon2 z(dsMBmS>xJ!fM$f9P<_j3HC*{<&ddZoJ_iW%V*g)yRkpVywmNJ0~l~@F0Z%;Ebavf zq9AErH~=paQA)5CvPcI%O7yABO3iCWP?JVo#uKW@WyKrOi@1UNo=f+RXI?7m^V#M& zjxDh-*tex1p$zYP?#b2Cp7!y^ew=Ndtp`m2d;gjMrKYEp%WM@T$v{Y4wt88EwSk#Z z^rbmIrN;Qpdt2IMq*M};qh9{0e&Zm${t9kO6m*kDpRe=IHayiB z(A(?0bJ->bFb*rvAaV&8`ATfe0~*1=M4Dleidk-8CTKwjfQtYZP@}S-nPssS$(tey z=ZcLkY1Tpx>2Bcbf+Y%%>kg}Q8jM#SBp!Ar-oDo6J@mVXPOk*wbWqI2qpE?=q!-EMN-*!R< z`*Puvav*ri^0rCX7stI_e=wmF^B92ZSUxkr#1XtXxT4t!P^AL_j0P^qQ7D2FY4VwT z(55KJvrO!OagdR$(x#KU0?M1T)z>)AVu+?4_`D|{2}~*YVBeJ5G`%flSw7RgcqDLo z^A{^G0OQt((}f>`FGq0zU&s?|MhUPIN<*`Au$fm5SQM}$kR?q~{1}lQ%PclsOgDL{ z&*-H&{>|KH(db95)roAqDa(Q;SN}?pVfp4XM@w12IV^?{W3AakNCz-taXkBkqq9Y-HM3 z&!;eA&nGx))0;&5j-_Sa0ARO1w$E^iB07#-} zJ(cEOn8*Q@9+1Eyz?2R=6p*JibR&lVUV$1(g4}ZC6agEPigfXWVpWXvf%1}ejUz2i zddq#>GQ5B;u@FqLKCx!CHm4lk*JE{+oPBFY|DIb5#Er=b0<6ST1a9=UhCM)5F0tT^ zh3;Sr6!K3nkQ#FU9WvAtf!zvDDl$HSTfC7Qa-m}B3}u#916(6@0Q1rUU%H-RsJrzk zHmjvgFSg{;%Oq^yTCL&M3R*cHk>fv!3;A!vBuK9j3VOlSHmK|A`!Gk%(p-bt)I6!CL|VKZ{!@ccIy7 zhRjtScp;YICqD6&z=f#jr7Umc$USg?l3|ISvH+^s2$BqhR$lb7lqVRY96f1{PnFRN z2QVXM+GL~@93dxq;7$7i2z!O^x9Sb|>S2PLw6CJ`7&zsC@AGQPCfddt@YeLe0Z{U! z^rG~Z%-|P6DTf+5!*T;NK?|a7a)6r$CNq_g!T1ffmSzbAtlaP`dCHRNN6Cw^&B}fN=8ohZu9Dy!o@c^`ljW4t!bpZ2S&nXAq;F)qr{TblI?TdS% z-DrS{fEv>|xB_?yLSZaNvjJIigF*r=!Do0i`JhcvkcU31)J`DCNJwd;)AtI<4Nyc2!G)Xv7r+&+kGeh9@?^IafEQw#EN%PdOK9SZz#`O?W`=l6tesg&`c>#9l$Pa17jG|UP7ntfk)D| zua?j-avltxc{ZRnde{g$lEEov!H)$JYLyRVIbQ^H)XxI&P}csDj~cX#!1^HaCL32C zcp;`q9l%GY4d95Dg_xj{?coSu1%p@8y=(1My|$s@>g)09LA>72uYuu?#6$3Fu)jMJ zJ3n3uT!DQcc6T0kj%SKN8y$P-_VmBT(8KXdUN!CeRXp;Uxea)!-+Hu{_pZ~PynbJd zSHRA6XUo8AG4d6FF(N4hzxh2YCmVZDtK-hs!|&E{WiRu{ygs+=S}SY z$*W<^;YJ_ouBzz62;A$B!XuH}P}6y^>v;gL?AwQ$OYpV2evCqw>+o0HF*LR7ueVJ3 zsSDs#-!!qe{#tq0fY>hVc)Q%5uA5kn{taNn@+@+Df&o6i5?m__da{SJR)+Fp(Euj}+ zUw^^1%l1FI=Yod!Z=Lwr?n`hrj3+9pFeoGNuwUjLgO|{|i2gUL3z z>0ReGT;rOFA3pzPtd>?&MITp99kjR-nb!#H@I3i+4Z!?rC!h8JKp70OK0B-z%$sCcRx*R+I|U^#W&Wc{OhZau7z~AMsTA^X}ca8*1R}yQBf^w|!)I{HaH; z9Diy2cd(RNHwbgJ>O)}!cH+ad-dzds4y=8bEPy9YzVh;kr+@e{n0sS&fLoaKgOa?< zUk;D^G1zwFpmb@bek?fvkDs#rL|h8G1vg*dZmF4uq@tC21n%)C;ugnSVA~~O-z5WJ z-s(91-0ly$hW`N0DVOeYL8(F2kH+&>$Gz@@xG(twsBX#FcS!(v{FJLMns{#aXJFV3 z)dit`psCMw-0d#{cxB%{*SzS}4K#rLDOazXXiVPh8~(CIAL*(A-5-G+ejS#|H{)1$ z$=Y`y0qi$_WORT1ksBub)Q54Hdr0?ZPNi{CN8kZ`uj3ha1AzNsv|~xzci;fL|CH_L zOiVp;E0)Te7Il(UmG@=@cKUPN)9zMy-palhVSZX=AOdfH9N%=+4LG}eZw20gFllQi zc>CjBo?iFf3cSss8Higc{pPEWn5a+QhT9)6Zg#CoaRdh9R?7SEa)iC^Hgu=5@3d)M z`Xw}<%^jbb`g8Q_Wz+grWd~sd_-yW8SJ`(KTb6bSttW;~x#|OTSHA~$Ggsi9#lWQ{ z+me~rbYb6W=RBJoOSy#B!}Wg8?Ks1H;cOkN=r#hSTteH!^|#|#x3cdX6S;It=*i8$ zx^;YN&!3@RC(O~es<@0Ju+wkFn=$?j;H~W2hW$#lgdRWn%IoX(sh#LoW!yH5TRN7z z{Pj4?yt4vt`<5#WfX7eXeiN3=pT?Qy(ybcWH^&m@+~IFR?>`OjR`#98G)R81_{{G9 zryu!T!#B3iqhA$kSw?`*>^9uz0Nl#H9oQ^s0P_hVJhOX8b$z!3%a%dJo*=pdO|7o) zc4)6;0qjrz^~1-1w);-(nfZ?1Dh%2Pe9a$@m!;o{ZdLYOfNhfmuz%H+$4^Y`{R+Ul zc>#T^L{lAs9sYQ?-&OYQf_;)Zi8XQh_D$mx?mpb8QGvG$22M`JPCR7d-F?;0xjU9g z3c&kMeb?EI$;Q`V+?RK!dzF@?M&NFLHeT!cb+oCnZ{%o1AQZPa%FyeqoYw@OV) zBS7#r+zvFUvTqmdl7t85vbo-EGyv;0 zuahs`S)Fa}k!2TKEpO7;kL$eErNEwAVo^?F@%BjGVFlw>7xCw7-j(AnJMINnJMMXx z9s7cFtB@a?#H%-^ELM6F=_$}aKWDxbbb+6@NA7jJ!>Y3HJco1D$g}R)LmqO+;m3H@ z=uh3)&>pvZcuz|_hWv8S7X`q)x4F7Kat_Nbn{>64e(JLIyA7}aYj!L^yK?^=f(aD! z-sbA|$b%YUtoD*S>9D_X>sS4gfO_l-1MG^C=ME}2y|C{99zXf2kK@I2+ov~V$>)db zE<5q3ZfNtbZMsD>5N0z+Q`%;$OW#z?*=-PCw>;)*r#=@u9Uk01+unMoi=}Ub*AGP^b zFw}6hS3hZ>J@ZK{jT`gTkT$=)!-}uLS(5f0&L-WfkNmRRdd#1=GmpFzOXL2Xr|9{B z>+O-7uDTsFaOu4U=g@s__`(O>(CfeNvQ-mlgRs-q@$Hd!JHCK!$=UbN(P!L+FZ+~x z{qg_ZtsL3i=?E@JuIB*Wf9m%4FS)lzu6fA~UwpqC`lW|mHZow|cKUSN;oc9@l6rgO znq^P8i`V_3+jiXNaa=n-eMI`2@9FUoU%JlsHZPUq-fZm)Zs<|~ck2(5IfLBOV_?2? zo$qa4B1`9EmVe(}vhF4v-`?JpGsxXQde1yCKX($on9#F2x-kIV(806G!*BVvtDW$GxXqbsLQPvQFkkX=FyH z-0-El+|VTt4Bm;UgBgLxy*u=+qJg&WXlwMe9D{hHGh_!{`ZsCr;UZ!=T@3 zRXg(uH+r{Yv+Qnsn|HwPv^sOmo$kt$uX9H&e=?lnjKpT63u)5^N) zf&J!>jE0YE51w&r4L5Yr18(@2|Jh~B(mD?6)cEt3d%%x|k82N{eQS7V`C=@U|MiC7 zccVjl=RGuwCD2s>@2@{{!$5vq`>?%kX296tJ# zd(Ua_aHkyp)$S?nlcugMq5UaWubc2w58?#YA$@9lU#h8{{$n@tp0B%X_2ORd>$J07 zTSD*f>j2&d(T;(#@99VUKlkgK|E*g+`jbwFcv0oL=7A>~lQ-i6%HS9mOXlIXe8&x4 zwhNaI7S%>+RPNo)Xvo0WmrG_|8oG4-$6(*`-fYtq0FR$?)kVJHFH2*lb)gl9?{%ZU zd9SN&D(7Cg3nS2~;%>FCfzRBv-I}edd#1?UpwVpu2#dl!UiZT%maIW z%OHSv=t5lI{grR_>B;vJ&7LWD3tC%x@bZzrcbs@5UV$=LJ7>^ z%4}R(OP+VY!Q1hyth=iqTUzk4-}JnEQ^uf&d4HLK_d7f9|3jGvM#sF>vUz3`@_y&c zmD;{M=H(-ROCih~z!Qx}u7>wrSJuJd*=C-ws=_QI@U$zneR;N7C#+`a-k_1^bqwsc zZ66zd%HyCBUz{sp&~@G$aFfP>T`D@5Ddu$yywi{2*!TO`L6_3Lyv}>W8J7;+rJ{q` zcV5T96HhmIY*b3)@(wHAq_Kp+doaV#SZ2q*rL-^au;NV`gLa*FMmrUVZ7-qunjFZz zuOM5VB=2qJ?U76MIo@_GRbu<{-e%q&S*GWB+c8NyJZ%Gb|K?x46qk)oYDZ~OJb0>z z4<-!kdzrg6*gM^&P*pnn@~I*|n82_2Eyd6_fE)D&--A@Tz()eBr;6Gzo7a1;+F(qJ zg^vUd!c#?^j%r%~-oN?EEjV%Yx=t%uEIB@m&*yooFvke&@LO==s&w|{!}xrjcPWRq z09>zU?=9UR@ijPnlg7NxvzM-y-D+^@?912S@J$+Jei*+S#+wts{4g2r0e^EhD(jmL z9QX1aR%Lw+PT$6f74gGlC9^M&d-)Elvc3kVoA#X(z!TX^?=0IBM|^wal79hRyR+m) z_fD{u>WL%1J+h21pljD8^WmElz_@Mln)xVPbY8r-nXi7WLfa!yD*N)i&3yH16>J0! z3SfSm4A*~8Ez@9)T=@^x_1<<3#*dSES1S8ndD3-D@_O%VCOs&C8?I5Ry)!>|GIZ9H zv-P#2A2M1n#1FX|esz5OWXSDt zWB4`jn=L%%E+bQI`p7*(nAr$?v000LhNklkqm<$cv^hb6>)VsOz#b-J?Bg zgZD#jM>$>>yJp!FZtJnP_iQNotr+0_5`cRhfZH|u9suB}U4M-yQ~VMA?p!DJ4POlJ zJ6sZ1a_|m54&Yv!y~g$aBIi90PnNk-*q0}+hH8@sAGvarK8`cT*8;d*x9@=f_EWsP zkbXFHpBwt6htqH8TrJGp7XjX@;dOsL7i(9_r*!$KE2?^_zVJbpjg3jb?@tI7w+{( z;bUcIrM`n6&L&I!Qg#6MIUMU=f+cg$?b`z2{d@g3fEV?r9cr(Bvdr(edJ^D$Bf$G$ z-$!}UZ3B3dx9_Wu{IXj)vb*oY)1?ZZ9C7ZAZ_WB+-xdJ-%x_J7@616SdR=!fi+0Iy z?WlPOPu{*EJKa6e4s+LeyxZD!ojp*v^_V~Df!4mLd`aIe_2su&+zrzUQp{i_+aT$z$G8ESvicUYa#uLXX#X zpN-{no@Zf-Vd!6#?8XhAZMG9u{Xga{8t_?H3j3Dr#tndXKTlZo>zKD_Ql@hcTx{RxjYYW5J9FE-OWwX)j{d^TZBLX6@P4t^*LmmadJbSPo-r5mVwcxW zdup+pFrWH)d*s#g5$GwePv5?qkJ!=EA?UL5$9acUmvzotodE1NzXy+&`3>`y?x(0ZZpE;kdW!4<>Zd za{(By&q;pyJhb`gPWrbPGW)Pwylycnp0&;rET2z3{O(zspHcz9yAPmA#=ZhD2I%yZ z25F|Y)J`o8fIo|+^P@BMVbN$lefw@cq8tE*4L=L-n~Z(!y03Q|7j1I2Q}MD%m%XwC z$G?0HPUilooi6p2Cvp3Z)n0P1T>bZb9g_Q+B9 ziA9+I2d}aO_Fcc~pAO!K1WExCK4qJneQWNtcdf$Nd zkv@QNteK>J@hR;3`V{9~u}#^r&lj^PruXrs>nS!2pITX;WV;HDO5Fov`Mi%WT`x2_ znPkmp+1g}UGgCuWj=OAS;&0{0=T5rv#e|vqzi?X8_FXmdtXnbi+`@a=TMc&=znIY5 zs^+I1uSEB2<|oo$?vfn;rhE}IY5S(`eL36Vfs?gw4UIdpzmS|?ZMEZ)Up})#$r>1K zOWMB2mE#0fvi7av6O>8sp|kW)U_FZm^>)o~x71her0tu!2Zn=tmR||%tHtI~SqGGB(tGG^Y_cy_T0kY=TYzjo zM3c7f*zlfyj6uhB;O>p2?aNy!S9ILFeh8)x;7ngn@5e}VT1V3M9UDp;z!>zTFH-X? z^s-K8MnB}T<|2XNB%U7olH#xZc(0LIM48!;0OcoHe;&~VQr-9Fx-op2Z% zdNJYF=?3Ve?TgDuS<(h}%M%CikV|_Fn57Qjw1*F`&Plp~I0jC92|bqh5_&9c1H-)~ zy@XEvBo+oQbpWTmhfdxDH_|q+9&${0k-9wblUQ&cNdx%*13Q^k;Tw_D3IG5A07*qo IM6N<$f=Q!;%K!iX From e4401768d2b28e889baca5bfe4c01a1948658adc Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 13 Sep 2019 23:48:41 -0400 Subject: [PATCH 076/636] =?UTF-8?q?Cleanup=20new=20=E2=80=98toggler?= =?UTF-8?q?=E2=80=99=20animation=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/animations/OpacityToggler.js | 82 ++++++---- src/components/animations/RotationArrow.js | 96 ++++++------ .../animations/RoundButtonSizeToggler.js | 148 ++++++++++-------- src/components/animations/SizeToggler.js | 86 ++++++---- src/components/animations/index.js | 4 + 5 files changed, 244 insertions(+), 172 deletions(-) diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js index 6395e4448bd..829de30261e 100644 --- a/src/components/animations/OpacityToggler.js +++ b/src/components/animations/OpacityToggler.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; const { @@ -11,10 +11,10 @@ const { interpolate, multiply, set, - startClock, spring, - Value, SpringUtils, + startClock, + Value, } = Animated; function runTiming(clock, value, dest, friction, tension) { @@ -48,48 +48,72 @@ function runTiming(clock, value, dest, friction, tension) { ]); } -export default class OpacityToggler extends React.Component { +export default class OpacityToggler extends Component { + static propTypes = { + animationNode: PropTypes.any, + children: PropTypes.any, + endingOpacity: PropTypes.number, + friction: PropTypes.number, + isVisible: PropTypes.bool, + startingOpacity: PropTypes.number, + tension: PropTypes.number, + } + + static defaultProps = { + endingOpacity: 0, + friction: 20, + startingOpacity: 1, + tension: 200, + } + componentWillMount() { if (!this.props.animationNode) { this._isVisible = this.props.isVisible; } } - componentWillUpdate(prev) { - if (prev.isVisible !== undefined && prev.isVisible !== this.props.isVisible && !this.props.animationNode) { + componentWillUpdate(prevProps) { + const { + animationNode, + endingOpacity, + friction, + isVisible, + startingOpacity, + tension, + } = this.props; + + if (prevProps.isVisible !== undefined && prevProps.isVisible !== isVisible && !animationNode) { const clock = new Clock(); - const base = runTiming(clock, this.props.isVisible ? -1 : 1, this.props.isVisible ? 1 : -1, this.props.friction, this.props.tension); + const base = runTiming(clock, isVisible ? -1 : 1, isVisible ? 1 : -1, friction, tension); this._opacity = interpolate(base, { inputRange: [-1, 1], - outputRange: [this.props.endingOpacity, this.props.startingOpacity], + outputRange: [endingOpacity, startingOpacity], }); } } render() { + const { + animationNode, + children, + endingOpacity, + startingOpacity, + } = this.props; + + let opacity = !this._isVisible ? startingOpacity : endingOpacity; + + if (animationNode) { + opacity = (startingOpacity === 0) + ? animationNode + : multiply(add(animationNode, -1), -1); + } else if (this._opacity) { + opacity = this._opacity; + } + return ( - - {this.props.children} + + {children} ); } } - -OpacityToggler.propTypes = { - animationNode: PropTypes.any, - children: PropTypes.any, - endingOpacity: PropTypes.number, - friction: PropTypes.number, - isVisible: PropTypes.bool, - startingOpacity: PropTypes.number, - tension: PropTypes.number, -}; - -OpacityToggler.defaultProps = { - endingOpacity: 0, - friction: 20, - startingOpacity: 1, - tension: 200, -}; diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index 83f7b2b42e3..e143f4524c0 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; const { @@ -11,11 +11,11 @@ const { interpolate, multiply, set, - sub, - startClock, spring, - Value, SpringUtils, + startClock, + sub, + Value, } = Animated; function runTiming(clock, value, dest, friction, tension) { @@ -49,20 +49,36 @@ function runTiming(clock, value, dest, friction, tension) { ]); } -class RotationArrow extends React.Component { +export default class RotationArrow extends Component { + static propTypes = { + children: PropTypes.any, + endingOffset: PropTypes.number, + endingPosition: PropTypes.number, + friction: PropTypes.number, + isOpen: PropTypes.bool, + reversed: PropTypes.bool, + tension: PropTypes.number, + } + + static defaultProps = { + friction: 20, + tension: 200, + } + componentWillMount() { if (!this.props.isOpen === true) { this._transform = new Value(1); - return; + } else { + this._transform = new Value(0); } - this._transform = new Value(0); } - componentWillUpdate(prev) { - if (prev.isOpen !== undefined - && prev.isOpen !== this.props.isOpen) { + componentWillUpdate(prevProps) { + const { friction, isOpen, tension } = this.props; + + if (prevProps.isOpen !== undefined && prevProps.isOpen !== isOpen) { const clock = new Clock(); - const base = runTiming(clock, this.props.isOpen ? -1 : 1, this.props.isOpen ? 1 : -1, this.props.friction, this.props.tension); + const base = runTiming(clock, isOpen ? -1 : 1, isOpen ? 1 : -1, friction, tension); this._transform = interpolate(base, { inputRange: [-1, 1], outputRange: [0, 1], @@ -71,46 +87,30 @@ class RotationArrow extends React.Component { } render() { + const { + children, + endingOffset, + endingPosition, + } = this.props; + + let translateX = 0; + if (endingOffset) { + translateX = this._transform + ? sub(endingOffset, multiply(this._transform, endingOffset)) + : endingOffset; + } + + let rotate = `${endingPosition}deg`; + if (this._transform) { + rotate = concat(sub(endingPosition, multiply(this._transform, endingPosition)), 'deg'); + } + return ( - - - {this.props.children} + + + {children} ); } } - -RotationArrow.propTypes = { - children: PropTypes.any, - endingOffset: PropTypes.number, - endingPosition: PropTypes.number, - friction: PropTypes.number, - isOpen: PropTypes.bool, - reversed: PropTypes.bool, - tension: PropTypes.number, -}; - -RotationArrow.defaultProps = { - friction: 20, - tension: 200, -}; - -export default RotationArrow; diff --git a/src/components/animations/RoundButtonSizeToggler.js b/src/components/animations/RoundButtonSizeToggler.js index 82ca8bcb4e3..79bee18c197 100644 --- a/src/components/animations/RoundButtonSizeToggler.js +++ b/src/components/animations/RoundButtonSizeToggler.js @@ -1,8 +1,10 @@ +import { isNil } from 'lodash'; import PropTypes from 'prop-types'; -import React from 'react'; +import React, { PureComponent } from 'react'; import Animated from 'react-native-reanimated'; -import { View } from 'react-native'; -import { colors } from '../../styles'; +import { View } from 'react-primitives'; +import styled from 'styled-components/primitives'; +import { borders, colors, position } from '../../styles'; const { add, @@ -14,13 +16,20 @@ const { interpolate, multiply, set, - startClock, spring, + SpringUtils, + startClock, sub, Value, - SpringUtils, } = Animated; +const RoundButtonCapSize = 30; +const RoundButtonCap = styled(Animated.View)` + ${({ capDirection }) => borders.buildRadius(capDirection, RoundButtonCapSize / 2)}; + ${position.size(RoundButtonCapSize)}; + background-color: ${({ color }) => color}; +`; + function runTiming(clock, value, dest, friction, tension) { const state = { finished: new Value(1), @@ -29,7 +38,7 @@ function runTiming(clock, value, dest, friction, tension) { velocity: new Value(0), }; - const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + const config = SpringUtils.makeConfigFromOrigamiTensionAndFriction({ ...SpringUtils.makeDefaultConfig(), friction, tension, @@ -52,15 +61,42 @@ function runTiming(clock, value, dest, friction, tension) { ]); } -export default class RoundButtonSizeToggler extends React.Component { +export default class RoundButtonSizeToggler extends PureComponent { + static propTypes = { + animationNode: PropTypes.any, + color: PropTypes.string, + endingWidth: PropTypes.number, + friction: PropTypes.number, + isAbsolute: PropTypes.bool, + reversed: PropTypes.bool, + startingWidth: PropTypes.number, + tension: PropTypes.number, + toggle: PropTypes.bool, + } + + static defaultProps = { + color: colors.lightBlueGrey, + friction: 20, + tension: 200, + } + + static capSize = RoundButtonCapSize; + componentWillMount() { this._width = new Value(this.props.startingWidth); } - componentWillUpdate(prev) { - if (prev.toggle !== undefined && prev.toggle !== this.props.toggle && !this.props.animationNode) { + componentWillUpdate(prevProps) { + const { + animationNode, + friction, + tension, + toggle, + } = this.props; + + if (!isNil(prevProps.toggle) && prevProps.toggle !== toggle && !animationNode) { const clock = new Clock(); - const base = runTiming(clock, this.props.toggle ? -1 : 1, this.props.toggle ? 1 : -1, this.props.friction, this.props.tension); + const base = runTiming(clock, toggle ? -1 : 1, toggle ? 1 : -1, friction, tension); this._width = interpolate(base, { inputRange: [-1, 1], outputRange: [1, 0], @@ -69,65 +105,53 @@ export default class RoundButtonSizeToggler extends React.Component { } render() { + const { + animationNode, + color, + endingWidth, + isAbsolute, + reversed, + startingWidth, + } = this.props; + + let contentScaleX = (startingWidth + (reversed ? 0 : (endingWidth + 5))) / 100; + if (animationNode) { + // eslint-disable-next-line max-len + contentScaleX = add(multiply(animationNode, (endingWidth / 100 - startingWidth / 100)), startingWidth / 100); + } + + let contentTranslateX = reversed ? startingWidth : endingWidth; + if (animationNode) { + contentTranslateX = multiply(divide(sub(1, contentScaleX, 100), 2), -1); + } + + let rightCapTranslateX = (-1 * (100 - (reversed ? startingWidth : endingWidth)) - 11); + if (animationNode) { + rightCapTranslateX = sub(multiply(-100, sub(1, contentScaleX)), 11); + } + return ( - - - + + + - {this.props.children} - + /> - + ); } } - -RoundButtonSizeToggler.propTypes = { - animationNode: PropTypes.any, - children: PropTypes.any, - endingWidth: PropTypes.number, - friction: PropTypes.number, - isAbsolute: PropTypes.bool, - reversed: PropTypes.bool, - startingWidth: PropTypes.number, - tension: PropTypes.number, - toggle: PropTypes.bool, -}; - -RoundButtonSizeToggler.defaultProps = { - friction: 20, - tension: 200, -}; diff --git a/src/components/animations/SizeToggler.js b/src/components/animations/SizeToggler.js index b54b36b78ae..c678edf8bbc 100644 --- a/src/components/animations/SizeToggler.js +++ b/src/components/animations/SizeToggler.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; const { @@ -11,10 +11,10 @@ const { interpolate, multiply, set, - startClock, spring, - Value, SpringUtils, + startClock, + Value, } = Animated; function runTiming(clock, value, dest, friction, tension) { @@ -48,50 +48,70 @@ function runTiming(clock, value, dest, friction, tension) { ]); } -export default class SizeToggler extends React.Component { +export default class SizeToggler extends Component { + static propTypes = { + animationNode: PropTypes.any, + children: PropTypes.any, + endingWidth: PropTypes.number, + friction: PropTypes.number, + startingWidth: PropTypes.number, + tension: PropTypes.number, + toggle: PropTypes.bool, + } + + static defaultProps = { + endingOpacity: 0, + friction: 20, + startingOpacity: 1, + tension: 200, + } + componentWillMount() { - if (!this.props.toggle === true) { - this._height = new Value(this.props.startingWidth); - return; + const { endingWidth, startingWidth, toggle } = this.props; + + if (!toggle === true) { + this._height = new Value(startingWidth); + } else { + this._height = new Value(endingWidth); } - this._height = new Value(this.props.endingWidth); } - componentWillUpdate(prev) { - if (prev.toggle !== undefined && prev.toggle !== this.props.toggle && !this.props.animationNode) { + componentWillUpdate(prevProps) { + const { + animationNode, + endingWidth, + friction, + startingWidth, + tension, + toggle, + } = this.props; + + if (prevProps.toggle !== undefined && prevProps.toggle !== toggle && !animationNode) { const clock = new Clock(); - const base = runTiming(clock, this.props.toggle ? -1 : 1, this.props.toggle ? 1 : -1, this.props.friction, this.props.tension); + const base = runTiming(clock, toggle ? -1 : 1, toggle ? 1 : -1, friction, tension); this._height = interpolate(base, { inputRange: [-1, 1], - outputRange: [this.props.endingWidth, this.props.startingWidth], + outputRange: [endingWidth, startingWidth], }); } } render() { + const { + animationNode, + children, + endingWidth, + startingWidth, + } = this.props; + + const height = animationNode + ? add(multiply(animationNode, (endingWidth - startingWidth)), startingWidth) + : this._height; + return ( - - {this.props.children} + + {children} ); } } - -SizeToggler.propTypes = { - animationNode: PropTypes.any, - children: PropTypes.any, - endingWidth: PropTypes.number, - friction: PropTypes.number, - startingWidth: PropTypes.number, - tension: PropTypes.number, - toggle: PropTypes.bool, -}; - -SizeToggler.defaultProps = { - endingOpacity: 0, - friction: 20, - startingOpacity: 1, - tension: 200, -}; diff --git a/src/components/animations/index.js b/src/components/animations/index.js index 461d66034e7..8503ff0ca99 100644 --- a/src/components/animations/index.js +++ b/src/components/animations/index.js @@ -1,5 +1,9 @@ export { default as ButtonPressAnimation } from './ButtonPressAnimation'; export { default as FadeInAnimation } from './FadeInAnimation'; export { default as FlyInAnimation } from './FlyInAnimation'; +export { default as OpacityToggler } from './OpacityToggler'; +export { default as RotationArrow } from './RotationArrow'; +export { default as RoundButtonSizeToggler } from './RoundButtonSizeToggler'; export { default as ScaleInAnimation } from './ScaleInAnimation'; +export { default as SizeToggler } from './SizeToggler'; export { default as SpinAnimation } from './SpinAnimation'; From 7608526556c1277efb6576a7f6705e3e58792ad6 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 13 Sep 2019 23:49:51 -0400 Subject: [PATCH 077/636] Upgrade react-native to latest 0.60.5 release --- ios/Podfile | 4 - ios/Podfile.lock | 223 ++- ios/Rainbow.xcodeproj/project.pbxproj | 70 +- package.json | 4 +- src/App.js | 1 - yarn.lock | 2002 +++++++++++++------------ 6 files changed, 1159 insertions(+), 1145 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index d10121ad511..2ee919c8d18 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -4,8 +4,6 @@ platform :ios, '9.0' ENV['COCOAPODS_DISABLE_STATS'] = 'true' target 'Rainbow' do - rn_path = '../node_modules/react-native' - # Crashlytics pod 'Fabric', '~> 1.7.11' pod 'Crashlytics', '~> 3.10.7' @@ -18,7 +16,6 @@ target 'Rainbow' do pod 'React', :path => '../node_modules/react-native/' pod 'React-Core', :path => '../node_modules/react-native/React' pod 'React-DevSupport', :path => '../node_modules/react-native/React' - pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' @@ -35,7 +32,6 @@ target 'Rainbow' do pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' - # React Third Party - required pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0f4f620eec6..c326e7d4171 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Analytics (3.6.10) + - Analytics (3.7.0) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React @@ -40,87 +40,71 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - GoogleToolboxForMac/Defines (2.2.0) - - GoogleToolboxForMac/Logger (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSData+zlib (2.2.0)": - - GoogleToolboxForMac/Defines (= 2.2.0) - - libwebp (1.0.2): - - libwebp/core (= 1.0.2) - - libwebp/dec (= 1.0.2) - - libwebp/demux (= 1.0.2) - - libwebp/dsp (= 1.0.2) - - libwebp/enc (= 1.0.2) - - libwebp/mux (= 1.0.2) - - libwebp/utils (= 1.0.2) - - libwebp/webp (= 1.0.2) - - libwebp/core (1.0.2): + - GoogleToolboxForMac/Defines (2.2.1) + - GoogleToolboxForMac/Logger (2.2.1): + - GoogleToolboxForMac/Defines (= 2.2.1) + - "GoogleToolboxForMac/NSData+zlib (2.2.1)": + - GoogleToolboxForMac/Defines (= 2.2.1) + - libwebp (1.0.3): + - libwebp/demux (= 1.0.3) + - libwebp/mux (= 1.0.3) + - libwebp/webp (= 1.0.3) + - libwebp/demux (1.0.3): - libwebp/webp - - libwebp/dec (1.0.2): - - libwebp/core - - libwebp/demux (1.0.2): - - libwebp/core - - libwebp/dsp (1.0.2): - - libwebp/core - - libwebp/enc (1.0.2): - - libwebp/core - - libwebp/mux (1.0.2): - - libwebp/core - - libwebp/utils (1.0.2): - - libwebp/core - - libwebp/webp (1.0.2) + - libwebp/mux (1.0.3): + - libwebp/demux + - libwebp/webp (1.0.3) - nanopb (0.3.901): - nanopb/decode (= 0.3.901) - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - - Protobuf (3.7.0) - - React (0.60.4): - - React-Core (= 0.60.4) - - React-DevSupport (= 0.60.4) - - React-RCTActionSheet (= 0.60.4) - - React-RCTAnimation (= 0.60.4) - - React-RCTBlob (= 0.60.4) - - React-RCTImage (= 0.60.4) - - React-RCTLinking (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTSettings (= 0.60.4) - - React-RCTText (= 0.60.4) - - React-RCTVibration (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-Core (0.60.4): + - Protobuf (3.9.0) + - React (0.60.5): + - React-Core (= 0.60.5) + - React-DevSupport (= 0.60.5) + - React-RCTActionSheet (= 0.60.5) + - React-RCTAnimation (= 0.60.5) + - React-RCTBlob (= 0.60.5) + - React-RCTImage (= 0.60.5) + - React-RCTLinking (= 0.60.5) + - React-RCTNetwork (= 0.60.5) + - React-RCTSettings (= 0.60.5) + - React-RCTText (= 0.60.5) + - React-RCTVibration (= 0.60.5) + - React-RCTWebSocket (= 0.60.5) + - React-Core (0.60.5): - Folly (= 2018.10.22.00) - - React-cxxreact (= 0.60.4) - - React-jsiexecutor (= 0.60.4) - - yoga (= 0.60.4.React) - - React-cxxreact (0.60.4): + - React-cxxreact (= 0.60.5) + - React-jsiexecutor (= 0.60.5) + - yoga (= 0.60.5.React) + - React-cxxreact (0.60.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsinspector (= 0.60.4) - - React-DevSupport (0.60.4): - - React-Core (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-fishhook (0.60.4) - - React-jsi (0.60.4): + - React-jsinspector (= 0.60.5) + - React-DevSupport (0.60.5): + - React-Core (= 0.60.5) + - React-RCTWebSocket (= 0.60.5) + - React-jsi (0.60.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsi/Default (= 0.60.4) - - React-jsi/Default (0.60.4): + - React-jsi/Default (= 0.60.5) + - React-jsi/Default (0.60.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsiexecutor (0.60.4): + - React-jsiexecutor (0.60.5): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.60.4) - - React-jsi (= 0.60.4) - - React-jsinspector (0.60.4) + - React-cxxreact (= 0.60.5) + - React-jsi (= 0.60.5) + - React-jsinspector (0.60.5) - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -138,30 +122,29 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React-RCTActionSheet (0.60.4): - - React-Core (= 0.60.4) - - React-RCTAnimation (0.60.4): - - React-Core (= 0.60.4) - - React-RCTBlob (0.60.4): - - React-Core (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-RCTImage (0.60.4): - - React-Core (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTLinking (0.60.4): - - React-Core (= 0.60.4) - - React-RCTNetwork (0.60.4): - - React-Core (= 0.60.4) - - React-RCTSettings (0.60.4): - - React-Core (= 0.60.4) - - React-RCTText (0.60.4): - - React-Core (= 0.60.4) - - React-RCTVibration (0.60.4): - - React-Core (= 0.60.4) - - React-RCTWebSocket (0.60.4): - - React-Core (= 0.60.4) - - React-fishhook (= 0.60.4) + - React-RCTActionSheet (0.60.5): + - React-Core (= 0.60.5) + - React-RCTAnimation (0.60.5): + - React-Core (= 0.60.5) + - React-RCTBlob (0.60.5): + - React-Core (= 0.60.5) + - React-RCTNetwork (= 0.60.5) + - React-RCTWebSocket (= 0.60.5) + - React-RCTImage (0.60.5): + - React-Core (= 0.60.5) + - React-RCTNetwork (= 0.60.5) + - React-RCTLinking (0.60.5): + - React-Core (= 0.60.5) + - React-RCTNetwork (0.60.5): + - React-Core (= 0.60.5) + - React-RCTSettings (0.60.5): + - React-Core (= 0.60.5) + - React-RCTText (0.60.5): + - React-Core (= 0.60.5) + - React-RCTVibration (0.60.5): + - React-Core (= 0.60.5) + - React-RCTWebSocket (0.60.5): + - React-Core (= 0.60.5) - RNAnalytics (1.0.1): - Analytics - React @@ -169,7 +152,7 @@ PODS: - React - RNCMaskedView (0.1.1): - React - - RNDeviceInfo (2.3.1): + - RNDeviceInfo (2.3.2): - React - RNIOS11DeviceCheck (0.0.3): - React @@ -181,10 +164,10 @@ PODS: - React - RNStoreReview (0.1.5): - React - - SDWebImage (5.0.2): - - SDWebImage/Core (= 5.0.2) - - SDWebImage/Core (5.0.2) - - yoga (0.60.4.React) + - SDWebImage (5.1.1): + - SDWebImage/Core (= 5.1.1) + - SDWebImage/Core (5.1.1) + - yoga (0.60.5.React) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -201,7 +184,6 @@ DEPENDENCIES: - React-Core (from `../node_modules/react-native/React`) - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) - React-DevSupport (from `../node_modules/react-native/React`) - - React-fishhook (from `../node_modules/react-native/Libraries/fishhook`) - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) @@ -266,8 +248,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/cxxreact" React-DevSupport: :path: "../node_modules/react-native/React" - React-fishhook: - :path: "../node_modules/react-native/Libraries/fishhook" React-jsi: :path: "../node_modules/react-native/ReactCommon/jsi" React-jsiexecutor: @@ -326,7 +306,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 + Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c @@ -340,45 +320,44 @@ SPEC CHECKSUMS: FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d - libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 + GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 + libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a - React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 - React-Core: 8e0ea421cae5609d2562850f98421b15030476fa - React-cxxreact: 326880209990151a7182a813311054e9772ba510 - React-DevSupport: e9f10e6721e78e87622fc985db695c0c0168db8a - React-fishhook: 1f0e5b08449403fa75c3fb3881a0beefbada14af - React-jsi: 21d3153b1153fbf6510a92b6b11e33e725cb7432 - React-jsiexecutor: 7549641e48bafae7bfee3f3ea19bf4901639c5de - React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 + Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a + React: 53c53c4d99097af47cf60594b8706b4e3321e722 + React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64 + React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395 + React-DevSupport: 197fb409737cff2c4f9986e77c220d7452cb9f9f + React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 + React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 + React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 375843010be62aed072d83c9df30efdeb3c8cbcb + react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 - react-native-netinfo: 27d908bc7ee7b9f29400c02938a0b2a27a1015be - react-native-version-number: 15563dc4145a94aabfc1faab2a9af10174a4204e - React-RCTActionSheet: 9f71d7ae3e8fb10e08d162cbf14c621349dbfab3 - React-RCTAnimation: 981d8c95b0e30918a9832ccac32af83562a27fae - React-RCTBlob: 21e73d1020a302a75fed30dbaee9f15287b80baa - React-RCTImage: c0bc6ac0926517b6fb7e4c279b04843113e99d1d - React-RCTLinking: 1af3f3c59114bed3deec0107c62e7efad0932ee5 - React-RCTNetwork: 35df9de46e19cda5c56380be1a7759b9b8cb2fcd - React-RCTSettings: f580504c2cd1f44e25add10fb9ed3954f67f8ac5 - React-RCTText: e0f224898b13af9aa036ea7cb3d438daa68c1044 - React-RCTVibration: 0bea40cd51bd089bd591a8f74c86e91fdf2666c5 - React-RCTWebSocket: 163873f4cdd5f1058a9483443404fc3801581cb6 + react-native-netinfo: 0da34082d2cec3100c9b5073bb217e35f1142bdd + react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f + React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 + React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e + React-RCTBlob: 5e2b55f76e9a1c7ae52b826923502ddc3238df24 + React-RCTImage: f5f1c50922164e89bdda67bcd0153952a5cfe719 + React-RCTLinking: d0ecbd791e9ddddc41fa1f66b0255de90e8ee1e9 + React-RCTNetwork: e26946300b0ab7bb6c4a6348090e93fa21f33a9d + React-RCTSettings: d0d37cb521b7470c998595a44f05847777cc3f42 + React-RCTText: b074d89033583d4f2eb5faf7ea2db3a13c7553a2 + React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0 + React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 - RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 7a52c90473b5e81c13408d40d797b98387eaddde RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 - yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 + SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 + yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 -PODFILE CHECKSUM: 9a1477d30332ab86b10fd2ec7e7842ad52b5382e +PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e -COCOAPODS: 1.7.0 +COCOAPODS: 1.6.1 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index a0f4a92e61a..bc5d41fe08b 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 06B78001D9F2456D9C2D4A86 /* Graphik-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */; }; 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */; }; 0AB30EE90F554EE59F57DFC1 /* SF-Pro-Display-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */; }; + 0D83F39C1A368358BE63E551 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BD400B9F4BAFB66CCE58799E /* libPods-Rainbow.a */; }; 0F4372360E744AF4B37EB905 /* Graphik-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; @@ -56,7 +57,6 @@ 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */; }; 872630C5E4CA448D8DDC783E /* Graphik-Extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */; }; - 87808B52A9E224F3D11532B5 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 823BD6129C8AA3FD7CDD46BE /* libPods-Rainbow.a */; }; 8B7F7FDAB33B4D119E087D57 /* Graphik-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */; }; 8FB4C0E7FE3240F2B2D23CE2 /* SFMono-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8789D635428240B5ABF282EE /* SFMono-Bold.otf */; }; 91959ACCE81B4C128AAC8154 /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B98C0A69B3614C65B194BC68 /* libRNSVG.a */; }; @@ -581,11 +581,8 @@ 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* RainbowTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RainbowTests.m; sourceTree = ""; }; 02CF70769C034001B5CBC1EF /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = ""; }; - 069784542A6B83E8BB774757 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; - 06E14A994B1D3A2E1CCBA545 /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Heavy.otf"; path = "../src/assets/fonts/SFMono-Heavy.otf"; sourceTree = ""; }; 0E0889DFA1224AA48F1A5301 /* libRNRandomBytes-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNRandomBytes-tvOS.a"; sourceTree = ""; }; - 0EBA050ADF8AD8CB6B14A162 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; 137BEEE47D2E4F7AB452C0BD /* SRSRadialGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = SRSRadialGradient.xcodeproj; path = "../node_modules/react-native-radial-gradient/ios/SRSRadialGradient.xcodeproj"; sourceTree = ""; }; 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; @@ -623,6 +620,7 @@ 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ExtralightItalic.otf"; path = "../src/assets/fonts/Graphik-ExtralightItalic.otf"; sourceTree = ""; }; 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNRandomBytes.xcodeproj; path = "../node_modules/react-native-randombytes/RNRandomBytes.xcodeproj"; sourceTree = ""; }; 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Display-Medium.otf"; sourceTree = ""; }; + 2BC795CD9117769AA359DE10 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Light.otf"; path = "../src/assets/fonts/SFMono-Light.otf"; sourceTree = ""; }; 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-MediumItalic.otf"; path = "../src/assets/fonts/Graphik-MediumItalic.otf"; sourceTree = ""; }; @@ -640,13 +638,10 @@ 3CC4B790228B298400D827EB /* libSDWebImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSDWebImage.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D5210FEA8F00672599 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D7210FEACE00672599 /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 3E98BFA4968FAACF85C68AB5 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Pods/Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ThinItalic.otf"; path = "../src/assets/fonts/Graphik-ThinItalic.otf"; sourceTree = ""; }; 45B0EAA273D24F15B885A97D /* libRNMail.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNMail.a; sourceTree = ""; }; 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = UdpSockets.xcodeproj; path = "../node_modules/react-native-udp/ios/UdpSockets.xcodeproj"; sourceTree = ""; }; 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = CodePush.xcodeproj; path = "../node_modules/react-native-code-push/ios/CodePush.xcodeproj"; sourceTree = ""; }; - 50137FC674DB782F454AFA32 /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; - 50750D914B8810145768DC57 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; 50B1B80F51614673AFD8A804 /* RNKeychain.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNKeychain.xcodeproj; path = "../node_modules/react-native-keychain/RNKeychain.xcodeproj"; sourceTree = ""; }; 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = ""; }; 51E41940863B4B88BDEF48D7 /* Graphik-SuperItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-SuperItalic.otf"; path = "../src/assets/fonts/Graphik-SuperItalic.otf"; sourceTree = ""; }; @@ -657,13 +652,14 @@ 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Medium.otf"; path = "../src/assets/fonts/SFMono-Medium.otf"; sourceTree = ""; }; 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTcpSockets.a; sourceTree = ""; }; 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-RegularItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-RegularItalic.otf"; sourceTree = ""; }; + 776E95D621071668979C01C5 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Black.otf"; path = "../src/assets/fonts/Graphik-Black.otf"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; + 78E830C92AA20F78D93272D1 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; 7A19C32218BC469EA9228F2E /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNSVG-tvOS.a"; sourceTree = ""; }; 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Light.otf"; path = "../src/assets/fonts/Graphik-Light.otf"; sourceTree = ""; }; 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Super.otf"; path = "../src/assets/fonts/Graphik-Super.otf"; sourceTree = ""; }; 7CEEDA7A68C24426BBAA8D77 /* Graphik-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-BoldItalic.otf"; path = "../src/assets/fonts/Graphik-BoldItalic.otf"; sourceTree = ""; }; - 823BD6129C8AA3FD7CDD46BE /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-BoldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-BoldItalic.otf"; sourceTree = ""; }; 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-SemiboldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-SemiboldItalic.otf"; sourceTree = ""; }; @@ -683,20 +679,19 @@ 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Light.otf"; path = "../src/assets/fonts/SF-Pro-Display-Light.otf"; sourceTree = ""; }; 9E0A11D8843045ECB80C6AB8 /* libTouchID.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTouchID.a; sourceTree = ""; }; A014AE1645874354A732EB35 /* libToolTipMenu.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libToolTipMenu.a; sourceTree = ""; }; - A0BA96258CF7FFF7BBE552F4 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Pods/Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Regular.otf"; path = "../src/assets/fonts/Graphik-Regular.otf"; sourceTree = ""; }; A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-SemiboldItalic.otf"; path = "../src/assets/fonts/Graphik-SemiboldItalic.otf"; sourceTree = ""; }; A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-BlackItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-BlackItalic.otf"; sourceTree = ""; }; AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Semibold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Semibold.otf"; sourceTree = ""; }; ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFIRMessaging.xcodeproj; path = "../node_modules/react-native-fcm/ios/RNFIRMessaging.xcodeproj"; sourceTree = ""; }; - AF52B697F8A6DEC07D4A82AB /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Pods/Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; B0C692B061D7430D8194DC98 /* ToolTipMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ToolTipMenuTests.xctest; sourceTree = ""; }; B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Semibold.otf"; path = "../src/assets/fonts/SFMono-Semibold.otf"; sourceTree = ""; }; B86CB964E3AA47029988138C /* libRNKeychain.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNKeychain.a; sourceTree = ""; }; B98C0A69B3614C65B194BC68 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = ""; }; BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Bold.otf"; path = "../src/assets/fonts/SF-Pro-Display-Bold.otf"; sourceTree = ""; }; BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNMail.xcodeproj; path = "../node_modules/react-native-mail/RNMail.xcodeproj"; sourceTree = ""; }; + BD400B9F4BAFB66CCE58799E /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Black.otf"; path = "../src/assets/fonts/SF-Pro-Display-Black.otf"; sourceTree = ""; }; BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNOS.xcodeproj; path = "../node_modules/react-native-os/ios/RNOS.xcodeproj"; sourceTree = ""; }; C1324455238847F2AD5C08B4 /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = ""; }; @@ -720,6 +715,7 @@ EB48DC1D46D449759B9C61D4 /* Graphik-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Thin.otf"; path = "../src/assets/fonts/Graphik-Thin.otf"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; + F6164080EB3D274AC63A0D14 /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; F62BBE10D6534F74B2180711 /* SF-Pro-Text-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Bold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Bold.otf"; sourceTree = ""; }; FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-SemiboldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-SemiboldItalic.otf"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -757,8 +753,8 @@ ECF14FECD39C459D86EDCB82 /* libCodePush.a in Frameworks */, F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */, 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, - 87808B52A9E224F3D11532B5 /* libPods-Rainbow.a in Frameworks */, EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, + 0D83F39C1A368358BE63E551 /* libPods-Rainbow.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1096,7 +1092,7 @@ 24979E3620F84003007EB0DA /* Protobuf.framework */, 2D16E6891FA4F8E400B85C8A /* libReact.a */, D1A86E696CA24D4F9D3F7F0F /* libz.tbd */, - 823BD6129C8AA3FD7CDD46BE /* libPods-Rainbow.a */, + BD400B9F4BAFB66CCE58799E /* libPods-Rainbow.a */, ); name = Frameworks; sourceTree = ""; @@ -1214,14 +1210,10 @@ C640359C0E6575CE0A7ECD73 /* Pods */ = { isa = PBXGroup; children = ( - 06E14A994B1D3A2E1CCBA545 /* Pods-Rainbow.debug.xcconfig */, - 50750D914B8810145768DC57 /* Pods-Rainbow.release.xcconfig */, - 069784542A6B83E8BB774757 /* Pods-Rainbow.localrelease.xcconfig */, - 0EBA050ADF8AD8CB6B14A162 /* Pods-Rainbow.staging.xcconfig */, - 50137FC674DB782F454AFA32 /* Pods-Rainbow.debug.xcconfig */, - AF52B697F8A6DEC07D4A82AB /* Pods-Rainbow.release.xcconfig */, - A0BA96258CF7FFF7BBE552F4 /* Pods-Rainbow.localrelease.xcconfig */, - 3E98BFA4968FAACF85C68AB5 /* Pods-Rainbow.staging.xcconfig */, + F6164080EB3D274AC63A0D14 /* Pods-Rainbow.debug.xcconfig */, + 776E95D621071668979C01C5 /* Pods-Rainbow.release.xcconfig */, + 78E830C92AA20F78D93272D1 /* Pods-Rainbow.localrelease.xcconfig */, + 2BC795CD9117769AA359DE10 /* Pods-Rainbow.staging.xcconfig */, ); path = Pods; sourceTree = ""; @@ -1312,7 +1304,7 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Rainbow" */; buildPhases = ( - 862FF20A142EFD912DF7FAA5 /* [CP] Check Pods Manifest.lock */, + 2C90E890400DC5F7A5A37C7E /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, @@ -2068,41 +2060,41 @@ shellPath = /bin/sh; shellScript = "export NODE_ARGS=--max-old-space-size=2048\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; }; - 3CF823D3218F310D0024B77B /* ShellScript */ = { + 2C90E890400DC5F7A5A37C7E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "$(SRCROOT)/Rainbow/Info.plist", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Rainbow-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Fabric/run\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 862FF20A142EFD912DF7FAA5 /* [CP] Check Pods Manifest.lock */ = { + 3CF823D3218F310D0024B77B /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( + "$(SRCROOT)/Rainbow/Info.plist", ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Rainbow-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "\"${PODS_ROOT}/Fabric/run\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -2250,7 +2242,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 06E14A994B1D3A2E1CCBA545 /* Pods-Rainbow.debug.xcconfig */; + baseConfigurationReference = F6164080EB3D274AC63A0D14 /* Pods-Rainbow.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; @@ -2304,7 +2296,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 50750D914B8810145768DC57 /* Pods-Rainbow.release.xcconfig */; + baseConfigurationReference = 776E95D621071668979C01C5 /* Pods-Rainbow.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; @@ -2395,7 +2387,7 @@ }; 2C6A799821127ED9003AFB37 /* Staging */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0EBA050ADF8AD8CB6B14A162 /* Pods-Rainbow.staging.xcconfig */; + baseConfigurationReference = 2BC795CD9117769AA359DE10 /* Pods-Rainbow.staging.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; @@ -2533,7 +2525,7 @@ }; 2C87B79A2197FA1900682EC4 /* LocalRelease */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 069784542A6B83E8BB774757 /* Pods-Rainbow.localrelease.xcconfig */; + baseConfigurationReference = 78E830C92AA20F78D93272D1 /* Pods-Rainbow.localrelease.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = ""; diff --git a/package.json b/package.json index c73a000441e..e87802e0a63 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "querystring-es3": "^0.2.1", "react": "16.8.3", "react-coin-icon": "^0.1.9", - "react-native": "0.59.9", + "react-native": "0.60.5", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", @@ -107,7 +107,7 @@ "readable-stream": "^1.0.33", "recompact": "^3.4.0", "recompose": "^0.30.0", - "recyclerlistview": "^2.0.1-alpha.1", + "recyclerlistview": "2.0.1-alpha.1", "redux": "^4.0.1", "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0", diff --git a/src/App.js b/src/App.js index 1261da742e7..905737cae4c 100644 --- a/src/App.js +++ b/src/App.js @@ -176,7 +176,6 @@ class App extends Component { ) } - const AppWithRedux = compose( withProps({ store }), withWalletConnectConnections, diff --git a/yarn.lock b/yarn.lock index 7391448c001..e528dc6c18c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,18 +16,18 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" - integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" + integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helpers" "^7.5.5" - "@babel/parser" "^7.5.5" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" + "@babel/generator" "^7.6.0" + "@babel/helpers" "^7.6.0" + "@babel/parser" "^7.6.0" + "@babel/template" "^7.6.0" + "@babel/traverse" "^7.6.0" + "@babel/types" "^7.6.0" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -47,12 +47,12 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" - integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" + integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA== dependencies: - "@babel/types" "^7.5.5" + "@babel/types" "^7.6.0" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -90,10 +90,10 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/helper-create-class-features-plugin@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" - integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== +"@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" + integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.5.5" @@ -256,14 +256,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" - integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== +"@babel/helpers@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e" + integrity sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ== dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" + "@babel/template" "^7.6.0" + "@babel/traverse" "^7.6.0" + "@babel/types" "^7.6.0" "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" @@ -283,10 +283,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" - integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" + integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -336,9 +336,9 @@ "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.2.0.tgz#ae454f4c21c6c2ce8cb2397dc332ae8b420c5441" - integrity sha512-ea3Q6edZC/55wEBVZAEz42v528VulyO0eir+7uky/sT4XRcdkWJcFi1aPtitTlwUzGnECWJNExWww1SStt+yWw== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz#e9bf1f9b9ba10c77c033082da75f068389041af8" + integrity sha512-kj4gkZ6qUggkprRq3Uh5KP8XnE1MdIO0J7MhdDX8+rAbB6dJ2UrensGIS+0NPZAaaJ1Vr0PN6oLUgXMU1uMcSg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-chaining" "^7.2.0" @@ -437,9 +437,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz#c49e21228c4bbd4068a35667e6d951c75439b1dc" + integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" @@ -466,9 +466,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-destructuring@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6" + integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -518,9 +518,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz#39dfe957de4420445f1fcf88b68a2e4aa4515486" + integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g== dependencies: "@babel/helper-module-transforms" "^7.4.4" "@babel/helper-plugin-utils" "^7.0.0" @@ -590,9 +590,9 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" - integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" + integrity sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -630,11 +630,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" - integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz#48d78405f1aa856ebeea7288a48a19ed8da377a6" + integrity sha512-yzw7EopOOr6saONZ3KA3lpizKnWRTe+rfBqg4AmQbSow7ik7fqmzrfIqt053osLwLE2AaTqGinLM2tl6+M/uog== dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.5" + "@babel/helper-create-class-features-plugin" "^7.6.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -648,21 +648,20 @@ regexpu-core "^4.5.4" "@babel/register@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.5.5.tgz#40fe0d474c8c8587b28d6ae18a03eddad3dac3c1" - integrity sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.0.tgz#76b6f466714680f4becafd45beeb2a7b87431abf" + integrity sha512-78BomdN8el+x/nkup9KwtjJXuptW5oXMFmP11WoM2VJBjxrKv4grC3qjpLL8RGGUYUGsm57xnjYFM2uom+jWUQ== dependencies: - core-js "^3.0.0" find-cache-dir "^2.0.0" lodash "^4.17.13" mkdirp "^0.5.1" pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" + integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== dependencies: regenerator-runtime "^0.13.2" @@ -676,14 +675,14 @@ babylon "7.0.0-beta.44" lodash "^4.2.0" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" - integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" + integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.0" "@babel/traverse@7.0.0-beta.44": version "7.0.0-beta.44" @@ -701,17 +700,17 @@ invariant "^2.2.0" lodash "^4.2.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" - integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" + integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" + "@babel/generator" "^7.6.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.5" - "@babel/types" "^7.5.5" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.0" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" @@ -725,10 +724,10 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" - integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" + integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -777,111 +776,106 @@ integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": - version "5.0.0-beta.125" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.125.tgz#0e75562d0fd493d73f23d31844521ef6556e1bc1" - integrity sha512-X742o0xmcpnv9X5pXKdzTmPfFdmMjQ21iu7LT3Hua2vPa/o6Ve0GQI295PhxUh/YoWdyH95FO4dK9KkAtl2r3Q== - dependencies: - "@ethersproject/bignumber" ">5.0.0-beta.0" - "@ethersproject/bytes" ">5.0.0-beta.0" - "@ethersproject/errors" ">5.0.0-beta.0" - "@ethersproject/keccak256" ">5.0.0-beta.0" - "@ethersproject/rlp" ">5.0.0-beta.0" + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.129.tgz#bc93d04d3f0e8b7d33dbe7b47a81081f02af5a0e" + integrity sha512-ob+olQe+i7Gvq10nZyDa3XFGCdVc7ojG1VsfwwFdxt8/li2cv74fFueR4rjTpgKBhJuPM2bwTeHq6sGLsVxetw== + dependencies: + "@ethersproject/bignumber" ">=5.0.0-beta.130" + "@ethersproject/bytes" ">=5.0.0-beta.129" + "@ethersproject/keccak256" ">=5.0.0-beta.127" + "@ethersproject/logger" ">=5.0.0-beta.129" + "@ethersproject/rlp" ">=5.0.0-beta.126" bn.js "^4.4.0" -"@ethersproject/bignumber@>5.0.0-beta.0": - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.127.tgz#9fb1df7979b81c77a22ce4a2ca7e049d1c7f52e9" - integrity sha512-nt8lKya8dECXJH6DTQHL0H6HbfKbGCatPLzptAFt53ODgbb1on3Cr//5l4XvCZO6ZWn+DSa38PigY+ntooe8QA== +"@ethersproject/bignumber@>=5.0.0-beta.130": + version "5.0.0-beta.131" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.131.tgz#153b3676fcc6127e6275aa3ee95c7de6f7279673" + integrity sha512-4Uvz6XjfUkd6rUEXhQ1h9EB1CtmDKEmkKytCCM1iDHZw3fOs5rYnxKv53e6bxdGlSR5+/QBHH4vNB6vFHdJsDA== dependencies: - "@ethersproject/bytes" ">5.0.0-beta.0" - "@ethersproject/errors" ">5.0.0-beta.0" - "@ethersproject/properties" ">5.0.0-beta.0" + "@ethersproject/bytes" ">=5.0.0-beta.129" + "@ethersproject/logger" ">=5.0.0-beta.129" + "@ethersproject/properties" ">=5.0.0-beta.131" bn.js "^4.4.0" -"@ethersproject/bytes@>5.0.0-beta.0", "@ethersproject/bytes@^5.0.0-beta.126": - version "5.0.0-beta.126" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.126.tgz#17992dfbf4e1b8e972ad1caf04780d7d8ddc4ca6" - integrity sha512-MWBM1F2uypiDb3ROUJjBRtR0DGYvjAHqlOoaGBsTqq2DgF3swASF6Pfbqj+dS0zpY6XoO3w41e4+RCdjiAr0Jw== +"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0-beta.126": + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.130.tgz#48239f29f03f39bc18f5923a839a91f3d2d61267" + integrity sha512-udO4csx8EvRbbu1QlSOMzYXBwAVAMlDlEf057J97cXPyDimglznjDwMSJI89dQKl8gg6UPgBZIxVQGI5tTYmqg== dependencies: - "@ethersproject/errors" ">5.0.0-beta.0" + "@ethersproject/logger" ">=5.0.0-beta.129" -"@ethersproject/constants@>5.0.0-beta.0": - version "5.0.0-beta.126" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.126.tgz#cc3bab8269f085d0032730493433595ea0989bfd" - integrity sha512-wU1KhoSxxhCESX6JRVks/NAaB/WdIeMmEKDVu4tSsTG/IBogjxQY/jmVRhqKOw7eLvqOf6eTxcQ+11w/kU6HHg== +"@ethersproject/constants@>=5.0.0-beta.128": + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.129.tgz#83780862a357280876ec3f43aaaea27bbcab82c2" + integrity sha512-qOlJi9t/F7vOXjLRC3vfuOTr/ej+JXucJM76YZ8+X19e2VKjmPaMtbq0pj6pjOiePAWOjrgUJYp8njW2kdYUCg== dependencies: - "@ethersproject/bignumber" ">5.0.0-beta.0" - -"@ethersproject/errors@>5.0.0-beta.0": - version "5.0.0-beta.126" - resolved "https://registry.yarnpkg.com/@ethersproject/errors/-/errors-5.0.0-beta.126.tgz#bddabff53cb0a6fd544e1168ce3990a095f2b593" - integrity sha512-Rfc+rLaykgKaYgdc/5FuTNqlQNKzm6h9w9HNhkpGT8gE5Dh1xjtWrv8pKdUCbBjy6RCzMeVcmJ8COqLmsxPS6g== + "@ethersproject/bignumber" ">=5.0.0-beta.130" -"@ethersproject/keccak256@>5.0.0-beta.0": - version "5.0.0-beta.125" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.125.tgz#ac2bd7d20a411ebcddddcfc686ebd426960eb112" - integrity sha512-Vzood4ptHvWk64yqE5DMef7qLivEm3qH3S/60l66kWSAMmf5ISuSxeO+8Ss3o+p86zEGIhyipjpenb2LD6+/xA== +"@ethersproject/keccak256@>=5.0.0-beta.127": + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.128.tgz#5635a9f386de3692e17b2fa550807a30f9da78b0" + integrity sha512-dWp669s9B1+DyUSDSjxtU29+g270qQzBVAfJ0O6GbAnyuWFoyLfU4eeD/4GDGHI6g94iHXNt8yAQNE9wocB+MQ== dependencies: - "@ethersproject/bytes" ">5.0.0-beta.0" + "@ethersproject/bytes" ">=5.0.0-beta.129" js-sha3 "0.5.7" -"@ethersproject/properties@>5.0.0-beta.0": - version "5.0.0-beta.128" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.128.tgz#26e8a4cb95f0d048531f0a8da39773b16b4633b4" - integrity sha512-4ABgX2WmpQLlmbyR6EwxoT5YTRYxV6fGRtK+1nt48dvG2Y8FSkg33JvCfei3w432RjEEHEN5IOmTf+nTr9n6VA== +"@ethersproject/logger@>=5.0.0-beta.129": + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.130.tgz#65fb67819ef59d16fe3a45ca04d50a4f7bc3953e" + integrity sha512-mhclsjkFqah1Co594bTNYnJzYAbtp5lClUrFqhMAsRkqT08wMYxY+oB51JFigNBDV+hzjmfEURtFkQjEBRx9+g== + +"@ethersproject/properties@>=5.0.0-beta.131": + version "5.0.0-beta.132" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.132.tgz#a5472f013049e13f1859d7b24480e806a2ca47c6" + integrity sha512-u2ehvipqENk1dOlQkuSD9mcc+dbOi+FXKDsdhuUmPfLMK+VHirB8kbmKuDJnHyrcqJUzB8KKndVPbRcltsNkwg== dependencies: - "@ethersproject/errors" ">5.0.0-beta.0" + "@ethersproject/logger" ">=5.0.0-beta.129" -"@ethersproject/rlp@>5.0.0-beta.0": - version "5.0.0-beta.124" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.124.tgz#ca333bf52b03fac56ce94b90a701604bda526465" - integrity sha512-XRjIyOflY6VzSy62iBplESUWgRVJh9ImUwxILpMXLRxtTa7IGtu2Poe1L+O8LEm6gXvTOFd1uzrk/mXnkBoyHQ== +"@ethersproject/rlp@>=5.0.0-beta.126": + version "5.0.0-beta.127" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.127.tgz#b9b9ab962f7392ced7c5c220d3d617f5e9df5953" + integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== dependencies: - "@ethersproject/bytes" ">5.0.0-beta.0" + "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.127.tgz#e07848b92cb1b615a11d7289449312c069a234e9" - integrity sha512-FKQDBKgcX7Bc0J45TIwwT4PTnE1TvtDRka3dAkH1VX4odnj6DzpZ99QdkhX4mBL2J+6/XK+trA7m/HTDx+5YqA== + version "5.0.0-beta.131" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" + integrity sha512-TEUr1U1XWTPGEehAitqkG7SMgVspsAtB1+ESXdniznaYaMoP/D3W3lsDuFdvIIPWlAb97ra1w2pnCKxVcMmc4A== dependencies: - "@ethersproject/bytes" ">5.0.0-beta.0" - "@ethersproject/constants" ">5.0.0-beta.0" - "@ethersproject/errors" ">5.0.0-beta.0" + "@ethersproject/bytes" ">=5.0.0-beta.129" + "@ethersproject/constants" ">=5.0.0-beta.128" + "@ethersproject/logger" ">=5.0.0-beta.129" "@hapi/address@2.x.x": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.0.0.tgz#9f05469c88cb2fd3dcd624776b54ee95c312126a" - integrity sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw== + version "2.1.1" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.1.tgz#61395b5ed94c4cb19c2dc4c85969cff3d40d583f" + integrity sha512-DYuHzu978pP1XW1GD3HGvLnAFjbQTIgc2+V153FGkbS2pgo9haigCdwBnUDrbhaOkgiJlbZvoEqDrcxSLHpiWA== -"@hapi/hoek@6.x.x": - version "6.2.4" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-6.2.4.tgz#4b95fbaccbfba90185690890bdf1a2fbbda10595" - integrity sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A== +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.1.0.tgz#8f7627b23ed9bf67088fc7f9669e48c63ad421bd" - integrity sha512-b1J4jxYnW+n6lC91V6Pqg9imP9BZq0HNCeM+3sbXg05rQsE9cGYrKFpZjyztVesGmNRE6R+QaEoWGATeIiUVjA== + version "8.2.4" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020" + integrity sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow== "@hapi/joi@^15.0.3": - version "15.1.0" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.0.tgz#940cb749b5c55c26ab3b34ce362e82b6162c8e7a" - integrity sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ== + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== dependencies: "@hapi/address" "2.x.x" - "@hapi/hoek" "6.x.x" - "@hapi/marker" "1.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" "@hapi/topo" "3.x.x" -"@hapi/marker@1.x.x": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@hapi/marker/-/marker-1.0.0.tgz#65b0b2b01d1be06304886ce9b4b77b1bfb21a769" - integrity sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA== - "@hapi/topo@3.x.x": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.2.tgz#57cc1317be1a8c5f47c124f9b0e3c49cd78424d2" - integrity sha512-r+aumOqJ5QbD6aLPJWqVjMAPsx5pZKz+F5yPqXZ/WWG9JTtHbQqlzrJoknJ0iJxLj9vlXtmpSdjlkszseeG8OA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.3.tgz#c7a02e0d936596d29f184e6d7fdc07e8b5efce11" + integrity sha512-JmS9/vQK6dcUYn7wc2YZTqzIKubAQcJKu2KCKAru6es482U5RT5fP1EXCPtlXpiK7PR0On/kpQKI4fRKkzpZBQ== dependencies: "@hapi/hoek" "8.x.x" @@ -907,76 +901,77 @@ dependencies: react-display-name "^0.2.4" -"@jest/console@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" - integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg== +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== dependencies: - "@jest/source-map" "^24.3.0" + "@jest/source-map" "^24.9.0" chalk "^2.0.1" slash "^2.0.0" -"@jest/core@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.8.0.tgz#fbbdcd42a41d0d39cddbc9f520c8bab0c33eed5b" - integrity sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A== +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== dependencies: "@jest/console" "^24.7.1" - "@jest/reporters" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" ansi-escapes "^3.0.0" chalk "^2.0.1" exit "^0.1.2" graceful-fs "^4.1.15" - jest-changed-files "^24.8.0" - jest-config "^24.8.0" - jest-haste-map "^24.8.0" - jest-message-util "^24.8.0" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" jest-regex-util "^24.3.0" - jest-resolve-dependencies "^24.8.0" - jest-runner "^24.8.0" - jest-runtime "^24.8.0" - jest-snapshot "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" - jest-watcher "^24.8.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" micromatch "^3.1.10" p-each-series "^1.0.0" - pirates "^4.0.1" realpath-native "^1.1.0" rimraf "^2.5.4" + slash "^2.0.0" strip-ansi "^5.0.0" -"@jest/environment@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.8.0.tgz#0342261383c776bdd652168f68065ef144af0eac" - integrity sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw== - dependencies: - "@jest/fake-timers" "^24.8.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" - jest-mock "^24.8.0" - -"@jest/fake-timers@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.8.0.tgz#2e5b80a4f78f284bcb4bd5714b8e10dd36a8d3d1" - integrity sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw== - dependencies: - "@jest/types" "^24.8.0" - jest-message-util "^24.8.0" - jest-mock "^24.8.0" - -"@jest/reporters@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.8.0.tgz#075169cd029bddec54b8f2c0fc489fd0b9e05729" - integrity sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw== - dependencies: - "@jest/environment" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" +"@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + +"@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.2" @@ -984,74 +979,75 @@ istanbul-lib-instrument "^3.0.1" istanbul-lib-report "^2.0.4" istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.1.1" - jest-haste-map "^24.8.0" - jest-resolve "^24.8.0" - jest-runtime "^24.8.0" - jest-util "^24.8.0" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" jest-worker "^24.6.0" - node-notifier "^5.2.1" + node-notifier "^5.4.2" slash "^2.0.0" source-map "^0.6.0" string-length "^2.0.0" -"@jest/source-map@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" - integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== dependencies: callsites "^3.0.0" graceful-fs "^4.1.15" source-map "^0.6.0" -"@jest/test-result@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.8.0.tgz#7675d0aaf9d2484caa65e048d9b467d160f8e9d3" - integrity sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng== +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== dependencies: - "@jest/console" "^24.7.1" - "@jest/types" "^24.8.0" + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/test-sequencer@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz#2f993bcf6ef5eb4e65e8233a95a3320248cf994b" - integrity sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg== +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== dependencies: - "@jest/test-result" "^24.8.0" - jest-haste-map "^24.8.0" - jest-runner "^24.8.0" - jest-runtime "^24.8.0" + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" -"@jest/transform@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.8.0.tgz#628fb99dce4f9d254c6fd9341e3eea262e06fef5" - integrity sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA== +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" babel-plugin-istanbul "^5.1.0" chalk "^2.0.1" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.1.15" - jest-haste-map "^24.8.0" - jest-regex-util "^24.3.0" - jest-util "^24.8.0" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" micromatch "^3.1.10" + pirates "^4.0.1" realpath-native "^1.1.0" slash "^2.0.0" source-map "^0.6.1" write-file-atomic "2.4.1" -"@jest/types@^24.8.0": - version "24.8.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad" - integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg== +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^12.0.9" + "@types/yargs" "^13.0.0" "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" @@ -1078,32 +1074,32 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.0.0-rc.2": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" - integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== +"@react-native-community/cli-platform-android@^2.0.0-rc.2", "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": + version "2.9.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" + integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== dependencies: - "@react-native-community/cli-tools" "^2.7.0" + "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" execa "^1.0.0" jetifier "^1.6.2" - logkitty "^0.5.0" - slash "^2.0.0" - xmldoc "^0.4.0" + logkitty "^0.6.0" + slash "^3.0.0" + xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^2.0.0-rc.2": - version "2.8.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" - integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== +"@react-native-community/cli-platform-ios@^2.0.0-rc.2", "@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": + version "2.9.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" + integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== dependencies: - "@react-native-community/cli-tools" "^2.7.0" + "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" - integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== +"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.8.3": + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" + integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1150,15 +1146,15 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^1.2.1": - version "1.11.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.11.2.tgz#b14967f24a389f5a16889a747345cf0e5757a2f1" - integrity sha512-5NuYd30f5PCTrGUbZLnusZKv5nfTWvTDTRa/3Q4vwdMnUQrhm9sZXWGQ5CnFoQ7cE58EAqhj6/ShXeJF3DZ9uQ== +"@react-native-community/cli@^2.6.0": + version "2.9.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" + integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw== dependencies: "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.7.0" - "@react-native-community/cli-platform-ios" "^2.8.0" - "@react-native-community/cli-tools" "^2.7.0" + "@react-native-community/cli-platform-android" "^2.9.0" + "@react-native-community/cli-platform-ios" "^2.9.0" + "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" commander "^2.19.0" compression "^1.7.1" @@ -1216,20 +1212,20 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-3.2.1.tgz#cd073b81a4b978f7f55f1a960a0b56c462813e02" integrity sha512-A2qANOnlRDVe+8kMbKMwy3/0bOlOA2+y8DyWg2Rv2KHICIfin+oxixbG0ewAOLQdLkSEyyumZXRmIVl7VI/KJg== -"@react-navigation/core@~3.4.1": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.4.2.tgz#bec563e94fde40fbab3730cdc97f22afbb2a1498" - integrity sha512-7G+iDzLSTeOUU4vVZeRZKJ+Bd7ds7ZxYNqZcB8i0KlBeQEQfR74Ounfu/p0KIEq2RiNnaE3QT7WVP3C87sebzw== +"@react-navigation/core@~3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.0.tgz#73d1a12448e2bd71855e0080b95a7f51ede0cd9e" + integrity sha512-NLm24lA51R8o8c+iFnwtN9elqRzm4OJ8f1qPBCUNIYW1sb8M5yCD53vRP0fRcPFpr/6Xzs2TJMsWnnebwFp0Rw== dependencies: hoist-non-react-statics "^3.3.0" path-to-regexp "^1.7.0" query-string "^6.4.2" react-is "^16.8.6" -"@react-navigation/native@~3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.5.0.tgz#f5d16e0845ac26d1147d1caa481f18a00740e7ae" - integrity sha512-TmGOis++ejEXG3sqNJhCSKqB0/qLu3FQgDtO959qpqif36R/diR8SQwJqeSdofoEiK3CepdhFlTCeHdS1/+MsQ== +"@react-navigation/native@~3.6.1": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" + integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -1376,9 +1372,9 @@ inherits "~2.0.1" "@types/babel__core@^7.1.0": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f" - integrity sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg== + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" + integrity sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1458,19 +1454,19 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.6.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" - integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== + version "12.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" + integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== "@types/node@^10.3.2": - version "10.14.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" - integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ== + version "10.14.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" + integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== "@types/node@^8.0.7": - version "8.10.51" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627" - integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== + version "8.10.54" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" + integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== "@types/q@^1.5.1": version "1.5.2" @@ -1504,10 +1500,17 @@ "@types/unist" "*" "@types/vfile-message" "*" -"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": - version "12.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" - integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== +"@types/yargs-parser@*": + version "13.1.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" + integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== + +"@types/yargs@^13.0.0": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.2.tgz#a64674fc0149574ecd90ba746e932b5a5f7b3653" + integrity sha512-lwwgizwk/bIIU+3ELORkyuOgDjCh7zuWDFqRtPPhhVgq9N1F7CvLNKg1TX4f2duwtKQ0p044Au9r1PLIXHrIzQ== + dependencies: + "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^1.5.0": version "1.13.0" @@ -1547,37 +1550,37 @@ lodash.unescape "4.0.1" semver "5.5.0" -"@walletconnect/core@^1.0.0-beta.31": - version "1.0.0-beta.31" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.31.tgz#ce9257c13a0da7a52a61829b66c45a9686cedca9" - integrity sha512-EggZFGdQ0EMjWZrtqAn6PJslLDlc5suyPBWfp4PP0247tYorcXXz/7OSiek0XWBVQ7dakCqeJAOteuc/FaQ+hw== +"@walletconnect/core@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" + integrity sha512-VnS4exaqaNJQy6xc+HX+1psjmIjKimCir9xypbx4kMz1F8Tm8/m1bMv3h4c1Q7wyiZHsSTlMZmb64UuVhM2pqw== dependencies: - "@walletconnect/types" "^1.0.0-beta.31" - "@walletconnect/utils" "^1.0.0-beta.31" + "@walletconnect/types" "^1.0.0-beta.35" + "@walletconnect/utils" "^1.0.0-beta.35" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.31" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.31.tgz#097af6bf635bf4917e4fc6cc0cbd39609aed64f6" - integrity sha512-zscEiCUshvMfV9/yU+UL5gKZ/0WD+UH+Ar0XBdWA/BVu306maCoqNUWTV3Txj7gl+1L/hwIchbrT8np9dgK1tQ== + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.35.tgz#318d1d067cae5261755b502a3a5b27dd23c6a815" + integrity sha512-npRV1XicayiSMk84+he5JEASC5oFHkYsL2S9yuHfCVzctIGE6kIX0gpuBKUbzCxkve1yezIeaQOYfwVKlLRp5w== dependencies: - "@walletconnect/core" "^1.0.0-beta.31" - "@walletconnect/types" "^1.0.0-beta.31" - "@walletconnect/utils" "^1.0.0-beta.31" + "@walletconnect/core" "^1.0.0-beta.35" + "@walletconnect/types" "^1.0.0-beta.35" + "@walletconnect/utils" "^1.0.0-beta.35" -"@walletconnect/types@^1.0.0-beta.31": - version "1.0.0-beta.31" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.31.tgz#a35049a719042bda819759e4cd77591c5315a6a6" - integrity sha512-C6W4K+YWoAl69xDvbbhjBtQ02Xx2eBsfLyezSvs8eFw4toKkkJ5Uw5dp9C6qmUBDrKIIcmP2004F1MniLnnk3Q== +"@walletconnect/types@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.35.tgz#02577da82a85361c68518350fe6139dee4a43445" + integrity sha512-xlcSt0ZdEkiYmCpuO6cleLk1MmjyMPCCT5o1/z0zcRV15uDxfb+N9J/S2uVZBoLtnBtUK1m+11sRF3KrIo9FgQ== -"@walletconnect/utils@^1.0.0-beta.31": - version "1.0.0-beta.31" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.31.tgz#a73ea81325750208b5298680bf3f82208f0d4f37" - integrity sha512-cTZu+EzoEdvbkT36o+4VqBsD7ro5pXrOu9sswgcWkZ2xVFfRSnNctJkUdeK3JOu1wPnG25/QaRr3fQx4ZoIBrQ== +"@walletconnect/utils@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" + integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.31" + "@walletconnect/types" "^1.0.0-beta.35" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1591,15 +1594,22 @@ Base64@~0.2.0: integrity sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg= abab@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" - integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== + version "2.0.1" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.1.tgz#3fa17797032b71410ec372e11668f4b4ffc86a82" + integrity sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw== abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + abs-svg-path@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" @@ -1633,17 +1643,17 @@ accepts@~1.3.5, accepts@~1.3.7: negotiator "0.6.2" acorn-globals@^4.1.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006" - integrity sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ== + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" acorn-jsx@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== acorn-walk@^6.0.1: version "6.2.0" @@ -1656,9 +1666,9 @@ acorn@^5.5.3: integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.1, acorn@^6.0.7: - version "6.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" - integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== + version "6.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" + integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== aes-js@3.0.0: version "3.0.0" @@ -1974,9 +1984,9 @@ astral-regex@^1.0.0: integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== async@^2.4.0: version "2.6.3" @@ -2066,16 +2076,16 @@ babel-eslint@^8.2.2: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.8.0.tgz#5c15ff2b28e20b0f45df43fe6b7f2aae93dba589" - integrity sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw== +babel-jest@^24.8.0, babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== dependencies: - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.6.0" + babel-preset-jest "^24.9.0" chalk "^2.4.2" slash "^2.0.0" @@ -2110,10 +2120,10 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" -babel-plugin-jest-hoist@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019" - integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w== +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== dependencies: "@types/babel__traverse" "^7.0.6" @@ -2200,13 +2210,13 @@ babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" - integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw== +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== dependencies: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.6.0" + babel-plugin-jest-hoist "^24.9.0" babel-runtime@^6.22.0: version "6.26.0" @@ -2252,9 +2262,9 @@ base64-js@1.1.2: integrity sha1-1kAMrBxMZgl22Q0HoENR2JOV9eg= base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.2.3: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== base@^0.11.1: version "0.11.2" @@ -2472,13 +2482,13 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.6.3: - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== + version "4.7.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" + integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA== dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" + caniuse-lite "^1.0.30000989" + electron-to-chromium "^1.3.247" + node-releases "^1.1.29" bser@^2.0.0: version "2.1.0" @@ -2512,9 +2522,9 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" - integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + version "5.4.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" + integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -2620,17 +2630,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: - version "1.0.30000987" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" - integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== - -capture-exit@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" - integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= - dependencies: - rsvp "^3.3.3" +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== capture-exit@^2.0.0: version "2.0.0" @@ -2859,7 +2862,7 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -code-push@^2.0.6, code-push@^2.0.7: +code-push@^2.0.6: version "2.0.7" resolved "https://registry.yarnpkg.com/code-push/-/code-push-2.0.7.tgz#aa2303376552a15ea3c2092ff2f19e4d6666ab9e" integrity sha512-8cEO60OYPiDj4vaSBxRAySzShYrKLi8GXdxcbJhTJ25PAvMUkf9rC/IQxgRK01EqWcGwKvIAGvz+Xk9YJcMM+A== @@ -2871,6 +2874,18 @@ code-push@^2.0.6, code-push@^2.0.7: superagent-proxy "^2.0.0" yazl "^2.4.1" +code-push@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.0.1.tgz#d6d48b1e112a49148b2244b0213afaf3f818645b" + integrity sha512-UgktdhS47nxtUdGB1l4D6JBnuGB20hMT7QswGj6gQgQbiTjSmOBJ0MK/09fyeYzWKjUnJBEmUud08rC7WzKFMw== + dependencies: + q "^1.4.1" + recursive-fs "^1.1.2" + slash "3.0.0" + superagent "^5.1.0" + superagent-proxy "^2.0.0" + yazl "^2.4.1" + collapse-white-space@^1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.5.tgz#c2495b699ab1ed380d29a1091e01063e75dbbe3a" @@ -3006,9 +3021,9 @@ configstore@^3.0.0: xdg-basedir "^3.0.0" confusing-browser-globals@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.7.tgz#5ae852bd541a910e7ffb2dbb864a2d21a36ad29b" - integrity sha512-cgHI1azax5ATrZ8rJ+ODDML9Fvu67PimB6aNxBrc/QwSaDaM9eTfIEUHx3bBLJJ82ioSb+/5zfsMCCEJax3ByQ== + version "1.0.8" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz#93ffec1f82a6e2bf2bc36769cc3a92fa20e502f3" + integrity sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg== connect@^3.6.5: version "3.7.0" @@ -3069,11 +3084,6 @@ core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -core-js@^3.0.0: - version "3.1.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.4.tgz#3a2837fc48e582e1ae25907afcd6cf03b0cc7a07" - integrity sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ== - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3190,9 +3200,9 @@ css-select@^2.0.0: nth-check "^1.0.2" css-to-react-native@^2.2.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.1.tgz#cf0f61e0514846e2d4dc188b0886e29d8bef64a2" - integrity sha512-yO+oEx1Lf+hDKasqQRVrAvzMCz825Huh1VMlEEDlRWyAhFb/FWb6I0KpEF1PkyKQ7NEdcx9d5M2ZEWgJAsgPvQ== + version "2.3.2" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.2.tgz#e75e2f8f7aa385b4c3611c52b074b70a002f2e7d" + integrity sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw== dependencies: camelize "^1.0.0" css-color-keywords "^1.0.0" @@ -3288,6 +3298,11 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= +dayjs@^1.8.15: + version "1.8.16" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" + integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== + debounce@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" @@ -3340,9 +3355,16 @@ decode-uri-component@^0.2.0: integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-equal@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + version "1.1.0" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.0.tgz#3103cdf8ab6d32cf4a8df7865458f2b8d33f3745" + integrity sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" deep-extend@^0.6.0: version "0.6.0" @@ -3485,10 +3507,10 @@ detox@^12.8.0: yargs "^13.0.0" yargs-parser "^13.0.0" -diff-sequences@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" - integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== diff@3.5.0: version "3.5.0" @@ -3544,12 +3566,12 @@ doctrine@^3.0.0: esutils "^2.0.2" dom-serializer@0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + version "0.2.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb" + integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q== dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" + domelementtype "^2.0.1" + entities "^2.0.0" dom-walk@^0.1.0: version "0.1.1" @@ -3561,11 +3583,16 @@ domain-browser@^1.2.0: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: +domelementtype@1, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + domexception@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" @@ -3601,11 +3628,11 @@ dotenv@^2.0.0: integrity sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk= dtrace-provider@~0.8: - version "0.8.7" - resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" - integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ= + version "0.8.8" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" + integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== dependencies: - nan "^2.10.0" + nan "^2.14.0" duplexer3@^0.1.4: version "0.1.4" @@ -3625,10 +3652,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.191: - version "1.3.205" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" - integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== +electron-to-chromium@^1.3.247: + version "1.3.257" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.257.tgz#35da0ad5833b27184c8298804c498a4d2f4ed27d" + integrity sha512-EcKVmUeHCZelPA0wnIaSmpAN8karKhKBwFb+xLUjSVZ8sGRE1l3fst1zQZ7KJUkyJ7H5edPd4RP94pzC9sG00A== elliptic@6.3.3: version "6.3.3" @@ -3641,9 +3668,9 @@ elliptic@6.3.3: inherits "^2.0.1" elliptic@^6.0.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca" - integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg== + version "6.5.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b" + integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -3715,6 +3742,11 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + envinfo@^7.1.0: version "7.3.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" @@ -3743,16 +3775,20 @@ errorhandler@^1.5.0: escape-html "~1.0.3" es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + version "1.14.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497" + integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg== dependencies: es-to-primitive "^1.2.0" function-bind "^1.1.1" has "^1.0.3" + has-symbols "^1.0.0" is-callable "^1.1.4" is-regex "^1.0.4" - object-keys "^1.0.12" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.0.0" + string.prototype.trimright "^2.0.0" es-to-primitive@^1.2.0: version "1.2.0" @@ -3786,9 +3822,9 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.x.x, escodegen@^1.9.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" - integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== + version "1.12.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" + integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -3884,9 +3920,9 @@ eslint-plugin-prettier@2.6.2: jest-docblock "^21.0.0" eslint-plugin-react-hooks@^1.5.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz#3c66a5515ea3e0a221ffc5d4e75c971c217b1a4c" - integrity sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" + integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== eslint-plugin-react-native-animation-linter@^0.1.2: version "0.1.2" @@ -3957,16 +3993,16 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: estraverse "^4.1.1" eslint-utils@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c" - integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ== + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== dependencies: eslint-visitor-keys "^1.0.0" eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^5.16.0: version "5.16.0" @@ -4044,14 +4080,14 @@ esrecurse@^4.1.0: estraverse "^4.1.0" estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== esutils@^2.0.0, esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" @@ -4059,14 +4095,14 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-contract-metadata@^1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.2.tgz#6c23383e35de1014c1c00f2c8c787cd48d54ae20" - integrity sha512-2ycmqRQ9u4Tbpir7hwEKZ8Qjy1bc3KaiRBd/jkL8Xye9wqnYMpgaUK4UHPm1uTnCZZ+KoN0Mxg6kL9JILrYdhA== + version "1.9.3" + resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" + integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== ethers@^4.0.33: - version "4.0.33" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" - integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== + version "4.0.37" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" + integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -4170,17 +4206,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d" - integrity sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA== +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" ansi-styles "^3.2.0" - jest-get-type "^24.8.0" - jest-matcher-utils "^24.8.0" - jest-message-util "^24.8.0" - jest-regex-util "^24.3.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" extend-shallow@^1.1.2: version "1.1.4" @@ -4303,9 +4339,9 @@ fast-levenshtein@~2.0.4: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-safe-stringify@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" - integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg== + version "2.0.7" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" + integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== fb-watchman@^2.0.0: version "2.0.0" @@ -4511,9 +4547,9 @@ forever-agent@~0.6.1: integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= form-data@^2.3.3: - version "2.5.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" - integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" @@ -4842,9 +4878,9 @@ got@^6.7.1: url-parse-lax "^1.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== growl@1.10.5: version "1.10.5" @@ -4856,10 +4892,15 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +hammerjs@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" + integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= + handlebars@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" - integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + version "4.2.0" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.2.0.tgz#57ce8d2175b9bbb3d8b3cf3e4217b1aec8ddcb2e" + integrity sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -4982,9 +5023,9 @@ he@1.2.0: integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== hermesvm@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.0.tgz#4bfaf4ac682a2fd407b862ab641eb8deb232de83" - integrity sha512-GbP6dKaVW/V2QpB+DZPxcmhBhJVFa9cHS/xRX7FD1MGfa6Z1aHHD83VDCwo3SgcqNj5yHlVbe9UgrK1PFGCXpw== + version "0.1.1" + resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.1.tgz#bd1df92b4dc504e261c23df34864daf24b844d03" + integrity sha512-EosSDeUqTTGvlc9vQiy5Y/9GBlucEyo6lYuxg/FnukHCD/CP3NYeDAGV54TyZ19FgSqMEoPgOH9cyxvv8epQ1g== hmac-drbg@^1.0.0: version "1.0.1" @@ -5008,9 +5049,9 @@ hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.1.0, hoist-non-react- react-is "^16.7.0" hosted-git-info@^2.1.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + version "2.8.4" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" + integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== html-encoding-sniffer@^1.0.2: version "1.0.2" @@ -5020,9 +5061,9 @@ html-encoding-sniffer@^1.0.2: whatwg-encoding "^1.0.1" html-tags@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.0.0.tgz#41f57708c9e6b7b46a00a22317d614c4a2bab166" - integrity sha512-xiXEBjihaNI+VZ2mKEoI5ZPxqUsevTKM+aeeJ/W4KAg2deGE35minmCJMn51BvwJZmiHaeAxrb2LAS0yZJxuuA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" + integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== htmlparser2@^3.10.0: version "3.10.1" @@ -5083,9 +5124,9 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: - version "17.0.7" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.7.tgz#aae8591634b109c0ecec755b46c6414b0d743e07" - integrity sha512-fQn+gcyDaHb3qXIeahjCnGMsCeHaKveSORclang55stBjOL13oK7ZYxXVz1AaFV6p3SzOSu/KW+tgZcUuDdf6Q== + version "17.0.14" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" + integrity sha512-yEGSWX9UTpWQskPsFy03t8uhZh5wyZ7v9p+MCo08Sd2edTaFdg1gFA633dg9OqTxJ/z1rtCiacgOlDSBpgssgw== dependencies: "@babel/runtime" "^7.3.1" @@ -5102,9 +5143,9 @@ ieee754@^1.1.4: integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + version "3.0.2" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.2.tgz#99d83a246c196ea5c93ef9315ad7b0819c35069b" + integrity sha512-EXyErtpHbn75ZTsOADsfx6J/FPo6/5cjev46PXrcTpd8z3BoRkXgYu9/JVqrI7tusjmwCZutGeRJeU0Wo1e4Cw== dependencies: minimatch "^3.0.4" @@ -5114,9 +5155,9 @@ ignore@^4.0.3, ignore@^4.0.6: integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.5, ignore@^5.0.6: - version "5.1.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558" - integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ== + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== image-size@^0.6.0: version "0.6.3" @@ -5124,9 +5165,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/immer/-/immer-3.1.3.tgz#59bc742b2aab6e2c676445edb653e588a23c70fc" - integrity sha512-HG5SXTXTTVy9lGNwS075cNhQoV375jHsIJO3UtMjuUWJOuwlMr0u42FlsKTJcppt5AzsFAsmj9r4kHvsSHh3hQ== + version "3.3.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" + integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== import-fresh@^2.0.0: version "2.0.0" @@ -5270,9 +5311,9 @@ inquirer@^3.0.6: through "^2.3.6" inquirer@^6.2.2: - version "6.5.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" - integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: ansi-escapes "^3.2.0" chalk "^2.4.2" @@ -5288,7 +5329,7 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" -invariant@^2.2.0, invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.0, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -5347,6 +5388,11 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -5563,9 +5609,9 @@ is-regexp@^2.0.0: integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA== is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" @@ -5584,10 +5630,10 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-what@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.2.4.tgz#da528659017bdd4b07892dfe4fd60da6ac500e98" - integrity sha512-0awkPsfVd85bYStP99EqLxKvhc5SiE70hSZCPxJN2SYZ5d+IkX+r1Ri0qnPWPnuRVFrqrEnI3JgFN3yrGtjXaw== +is-what@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.3.1.tgz#79502181f40226e2d8c09226999db90ef7c1bcbe" + integrity sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA== is-whitespace-character@^1.0.0: version "1.0.3" @@ -5702,73 +5748,73 @@ istanbul-lib-source-maps@^3.0.1: rimraf "^2.6.3" source-map "^0.6.1" -istanbul-reports@^2.1.1: +istanbul-reports@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== dependencies: handlebars "^4.1.2" -jest-changed-files@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.8.0.tgz#7e7eb21cf687587a85e50f3d249d1327e15b157b" - integrity sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug== +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.8.0.tgz#b075ac914492ed114fa338ade7362a301693e989" - integrity sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA== +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== dependencies: - "@jest/core" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" exit "^0.1.2" import-local "^2.0.0" is-ci "^2.0.0" - jest-config "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" prompts "^2.0.1" realpath-native "^1.1.0" - yargs "^12.0.2" + yargs "^13.3.0" -jest-config@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.8.0.tgz#77db3d265a6f726294687cbbccc36f8a76ee0f4f" - integrity sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw== +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.8.0" - "@jest/types" "^24.8.0" - babel-jest "^24.8.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^24.8.0" - jest-environment-node "^24.8.0" - jest-get-type "^24.8.0" - jest-jasmine2 "^24.8.0" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" jest-regex-util "^24.3.0" - jest-resolve "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" micromatch "^3.1.10" - pretty-format "^24.8.0" + pretty-format "^24.9.0" realpath-native "^1.1.0" -jest-diff@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.8.0.tgz#146435e7d1e3ffdf293d53ff97e193f1d1546172" - integrity sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g== +jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== dependencies: chalk "^2.0.1" - diff-sequences "^24.3.0" - jest-get-type "^24.8.0" - pretty-format "^24.8.0" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" jest-docblock@^21.0.0: version "21.2.0" @@ -5776,247 +5822,249 @@ jest-docblock@^21.0.0: integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== jest-docblock@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" - integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== dependencies: detect-newline "^2.1.0" -jest-each@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.8.0.tgz#a05fd2bf94ddc0b1da66c6d13ec2457f35e52775" - integrity sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA== +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" - jest-get-type "^24.8.0" - jest-util "^24.8.0" - pretty-format "^24.8.0" - -jest-environment-jsdom@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz#300f6949a146cabe1c9357ad9e9ecf9f43f38857" - integrity sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ== - dependencies: - "@jest/environment" "^24.8.0" - "@jest/fake-timers" "^24.8.0" - "@jest/types" "^24.8.0" - jest-mock "^24.8.0" - jest-util "^24.8.0" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" jsdom "^11.5.1" -jest-environment-node@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.8.0.tgz#d3f726ba8bc53087a60e7a84ca08883a4c892231" - integrity sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q== +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== dependencies: - "@jest/environment" "^24.8.0" - "@jest/fake-timers" "^24.8.0" - "@jest/types" "^24.8.0" - jest-mock "^24.8.0" - jest-util "^24.8.0" + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" -jest-get-type@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc" - integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ== +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== -jest-haste-map@^24.7.1, jest-haste-map@^24.8.0: - version "24.8.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.1.tgz#f39cc1d2b1d907e014165b4bd5a957afcb992982" - integrity sha512-SwaxMGVdAZk3ernAx2Uv2sorA7jm3Kx+lR0grp6rMmnY06Kn/urtKx1LPN2mGTea4fCT38impYT28FfcLUhX0g== +jest-haste-map@^24.7.1, jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" anymatch "^2.0.0" fb-watchman "^2.0.0" graceful-fs "^4.1.15" invariant "^2.2.4" - jest-serializer "^24.4.0" - jest-util "^24.8.0" - jest-worker "^24.6.0" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" micromatch "^3.1.10" sane "^4.0.3" walker "^1.0.7" optionalDependencies: fsevents "^1.2.7" -jest-jasmine2@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz#a9c7e14c83dd77d8b15e820549ce8987cc8cd898" - integrity sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong== +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" co "^4.6.0" - expect "^24.8.0" + expect "^24.9.0" is-generator-fn "^2.0.0" - jest-each "^24.8.0" - jest-matcher-utils "^24.8.0" - jest-message-util "^24.8.0" - jest-runtime "^24.8.0" - jest-snapshot "^24.8.0" - jest-util "^24.8.0" - pretty-format "^24.8.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" throat "^4.0.0" -jest-leak-detector@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz#c0086384e1f650c2d8348095df769f29b48e6980" - integrity sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g== +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== dependencies: - pretty-format "^24.8.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" -jest-matcher-utils@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz#2bce42204c9af12bde46f83dc839efe8be832495" - integrity sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw== +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== dependencies: chalk "^2.0.1" - jest-diff "^24.8.0" - jest-get-type "^24.8.0" - pretty-format "^24.8.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" -jest-message-util@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.8.0.tgz#0d6891e72a4beacc0292b638685df42e28d6218b" - integrity sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g== +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" "@types/stack-utils" "^1.0.1" chalk "^2.0.1" micromatch "^3.1.10" slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.8.0.tgz#2f9d14d37699e863f1febf4e4d5a33b7fdbbde56" - integrity sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A== +jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== -jest-regex-util@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" - integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== -jest-resolve-dependencies@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz#19eec3241f2045d3f990dba331d0d7526acff8e0" - integrity sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw== +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" jest-regex-util "^24.3.0" - jest-snapshot "^24.8.0" + jest-snapshot "^24.9.0" -jest-resolve@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.8.0.tgz#84b8e5408c1f6a11539793e2b5feb1b6e722439f" - integrity sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw== +jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" browser-resolve "^1.11.3" chalk "^2.0.1" jest-pnp-resolver "^1.2.1" realpath-native "^1.1.0" -jest-runner@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.8.0.tgz#4f9ae07b767db27b740d7deffad0cf67ccb4c5bb" - integrity sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow== +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== dependencies: "@jest/console" "^24.7.1" - "@jest/environment" "^24.8.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" chalk "^2.4.2" exit "^0.1.2" graceful-fs "^4.1.15" - jest-config "^24.8.0" + jest-config "^24.9.0" jest-docblock "^24.3.0" - jest-haste-map "^24.8.0" - jest-jasmine2 "^24.8.0" - jest-leak-detector "^24.8.0" - jest-message-util "^24.8.0" - jest-resolve "^24.8.0" - jest-runtime "^24.8.0" - jest-util "^24.8.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" jest-worker "^24.6.0" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.8.0.tgz#05f94d5b05c21f6dc54e427cd2e4980923350620" - integrity sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA== +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== dependencies: "@jest/console" "^24.7.1" - "@jest/environment" "^24.8.0" + "@jest/environment" "^24.9.0" "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.8.0" - "@jest/types" "^24.8.0" - "@types/yargs" "^12.0.2" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.1.15" - jest-config "^24.8.0" - jest-haste-map "^24.8.0" - jest-message-util "^24.8.0" - jest-mock "^24.8.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" jest-regex-util "^24.3.0" - jest-resolve "^24.8.0" - jest-snapshot "^24.8.0" - jest-util "^24.8.0" - jest-validate "^24.8.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" realpath-native "^1.1.0" slash "^2.0.0" strip-bom "^3.0.0" - yargs "^12.0.2" + yargs "^13.3.0" -jest-serializer@^24.4.0: - version "24.4.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" - integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== +jest-serializer@^24.4.0, jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== -jest-snapshot@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.8.0.tgz#3bec6a59da2ff7bc7d097a853fb67f9d415cb7c6" - integrity sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg== +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" chalk "^2.0.1" - expect "^24.8.0" - jest-diff "^24.8.0" - jest-matcher-utils "^24.8.0" - jest-message-util "^24.8.0" - jest-resolve "^24.8.0" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^24.8.0" - semver "^5.5.0" - -jest-util@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.8.0.tgz#41f0e945da11df44cc76d64ffb915d0716f46cd1" - integrity sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA== - dependencies: - "@jest/console" "^24.7.1" - "@jest/fake-timers" "^24.8.0" - "@jest/source-map" "^24.3.0" - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" + pretty-format "^24.9.0" + semver "^6.2.0" + +jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" callsites "^3.0.0" chalk "^2.0.1" graceful-fs "^4.1.15" @@ -6025,51 +6073,51 @@ jest-util@^24.8.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.7.0, jest-validate@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.8.0.tgz#624c41533e6dfe356ffadc6e2423a35c2d3b4849" - integrity sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA== +jest-validate@^24.7.0, jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== dependencies: - "@jest/types" "^24.8.0" - camelcase "^5.0.0" + "@jest/types" "^24.9.0" + camelcase "^5.3.1" chalk "^2.0.1" - jest-get-type "^24.8.0" - leven "^2.1.0" - pretty-format "^24.8.0" - -jest-watcher@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.8.0.tgz#58d49915ceddd2de85e238f6213cef1c93715de4" - integrity sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw== - dependencies: - "@jest/test-result" "^24.8.0" - "@jest/types" "^24.8.0" - "@types/yargs" "^12.0.9" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + +jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" ansi-escapes "^3.0.0" chalk "^2.0.1" - jest-util "^24.8.0" + jest-util "^24.9.0" string-length "^2.0.0" -jest-worker@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" - integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== dependencies: - merge-stream "^1.0.1" + merge-stream "^2.0.0" supports-color "^6.1.0" jest@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.8.0.tgz#d5dff1984d0d1002196e9b7f12f75af1b2809081" - integrity sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg== + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== dependencies: import-local "^2.0.0" - jest-cli "^24.8.0" + jest-cli "^24.9.0" jetifier@^1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.3.tgz#61a95b29aefddfe3b6d81ee956f5e99f8b9cba19" - integrity sha512-i0rb2nHVPZDPzFhgs9+yYxEDMh2z0iSHRD3vBQmvn98wlgWKwhmU2F3MUEEXfK+MLnKwLKqsCTvlcS1+CpDTUg== + version "1.6.4" + resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.4.tgz#6159db8e275d97980d26162897a0648b6d4a3222" + integrity sha512-+f/4OLeqY8RAmXnonI1ffeY1DR8kMNJPhv5WMFehchf7U71cjMQVKkOz1n6asz6kfVoAqKNWJz1A/18i18AcXA== js-sha3@0.5.7: version "0.5.7" @@ -6277,7 +6325,7 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" -kleur@^3.0.2: +kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== @@ -6396,11 +6444,6 @@ levelup@^0.18.2: semver "~2.3.1" xtend "~3.0.0" -leven@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -6499,12 +6542,13 @@ log-symbols@^3.0.0: dependencies: chalk "^2.4.2" -logkitty@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/logkitty/-/logkitty-0.5.0.tgz#5a348c2049551aa02da69543c3b5c44e28c7c24f" - integrity sha512-UA06TmPaSPiHxMBlo5uxL3ZvjJ2Gx/rEECrqowHsIsNoAoSB8aBSP553Fr2FJhOp3it2ulLsd520DZWS1IaYOw== +logkitty@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/logkitty/-/logkitty-0.6.0.tgz#e327d4b144dd5c11d912d002cf57ac9fbae20e15" + integrity sha512-+F1ROENmfG3b4N9WGlRz5QGTBw/xgjZe2JzZLADYeCmzdId5c+QI7WTGRofs/10hwP84aAmjK2WStx+/oQVnwA== dependencies: ansi-fragments "^0.2.1" + dayjs "^1.8.15" yargs "^12.0.5" longest-streak@^2.0.1: @@ -6654,9 +6698,9 @@ mem@^4.0.0: p-is-promise "^2.0.0" memoize-one@^5.0.0: - version "5.0.5" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e" - integrity sha512-ey6EpYv0tEaIbM/nTDOpHciXUvd+ackQrJgEzBwemhZZIWZjcyodqEcrmqDy2BKRTM3a65kKBV4WtLXJDt26SQ== + version "5.1.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" + integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== meow@^5.0.0: version "5.0.0" @@ -6674,11 +6718,11 @@ meow@^5.0.0: yargs-parser "^10.0.0" merge-anything@^2.2.4, merge-anything@^2.2.5: - version "2.4.0" - resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.0.tgz#86959caf02bb8969d1ae5e1b652862bc5fe54e44" - integrity sha512-MhJcPOEcDUIbwU0LnEfx5S9s9dfQ/KPu4g2UA5T5G1LRKS0XmpDvJ9+UUfTkfhge+nA1gStE4tJAvx6lXLs+rg== + version "2.4.1" + resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.1.tgz#e9bccaec1e49ec6cb5f77ca78c5770d1a35315e6" + integrity sha512-dYOIAl9GFCJNctSIHWOj9OJtarCjsD16P8ObCl6oxrujAG+kOvlwJuOD9/O9iYZ9aTi1RGpGTG9q9etIvuUikQ== dependencies: - is-what "^3.2.4" + is-what "^3.3.1" merge-deep@^3.0.2: version "3.0.2" @@ -6696,15 +6740,15 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" -merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== +merge2@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== methods@^1.1.2: version "1.1.2" @@ -6835,48 +6879,6 @@ metro-react-native-babel-preset@0.54.1: metro-babel7-plugin-react-transform "0.54.1" react-transform-hmr "^1.0.4" -metro-react-native-babel-preset@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" - integrity sha512-Hfr32+u5yYl3qhYQJU8NQ26g4kQlc3yFMg7keVR/3H8rwBIbFqXgsKt8oe0dOrv7WvrMqBHhDtVdU9ls3sSq8g== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.54.1" - react-transform-hmr "^1.0.4" - metro-react-native-babel-preset@^0.55.0: version "0.55.0" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.55.0.tgz#d5d4a6cbe9ccbcedd72fcbb71c0c311e3d56876e" @@ -6918,16 +6920,6 @@ metro-react-native-babel-preset@^0.55.0: "@babel/template" "^7.0.0" react-refresh "^0.2.0" -metro-react-native-babel-transformer@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz#57a695e97a19d95de63c9633f9d0dc024ee8e99a" - integrity sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.0" - metro-react-native-babel-preset "0.51.0" - metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" @@ -7071,11 +7063,16 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.40.0, "mime-db@>= 1.40.0 < 2": +mime-db@1.40.0: version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== +"mime-db@>= 1.40.0 < 2": + version "1.41.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.41.0.tgz#9110408e1f6aa1b34aef51f2c9df3caddf46b6a0" + integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw== + mime-db@~1.23.0: version "1.23.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" @@ -7095,7 +7092,7 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime@1.6.0, mime@^1.3.4: +mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -7168,17 +7165,17 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + version "2.5.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" + integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + version "1.2.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.2.tgz#6f0ccc82fa53e1bf2ff145f220d2da9fa6e3a166" + integrity sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ== dependencies: minipass "^2.2.1" @@ -7284,15 +7281,15 @@ mv@~2: ncp "~2.0.0" rimraf "~2.4.0" -nan@^2.10.0, nan@^2.12.1: +nan@^2.12.1, nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.3.tgz#dde999e173bc9d7bd2ee2746b89909ade98e075e" - integrity sha512-NbaoqdhIYmY6FXDRB4eYtDVC9Z9eCbn8TyaiC16LNKtpPv/aqa0tOPD8y6gNE4yUNnaZ7LLhYtXOev/6+cBtfw== + version "2.1.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" + integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== nanomatch@^1.2.9: version "1.2.13" @@ -7396,10 +7393,10 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.2.1: - version "5.4.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" - integrity sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ== +node-notifier@^5.2.1, node-notifier@^5.4.2: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -7423,10 +7420,10 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.25: - version "1.1.26" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937" - integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ== +node-releases@^1.1.29: + version "1.1.30" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" + integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== dependencies: semver "^5.3.0" @@ -7568,7 +7565,17 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-keys@^1.0.11, object-keys@^1.0.12: +object-inspect@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-is@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" + integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -7836,9 +7843,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: p-try "^2.0.0" @@ -7997,9 +8004,9 @@ pascalcase@^0.1.1: integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= patch-package@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.1.2.tgz#9ed0b3defb5c34ecbef3f334ddfb13e01b3d3ff6" - integrity sha512-5GnzR8lEyeleeariG+hGabUnD2b1yL7AIGFjlLo95zMGRWhZCel58IpeKD46wwPb7i+uNhUI8unV56ogk8Bgqg== + version "6.2.0" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.0.tgz#677de858e352b6ca4e6cb48a6efde2cec9fde566" + integrity sha512-HWlQflaBBMjLBfOWomfolF8aqsFDeNbSNro1JDUgYqnVvPM5OILJ9DQdwIRiKmGaOsmHvhkl1FYkvv1I9r2ZJw== dependencies: "@yarnpkg/lockfile" "^1.1.0" chalk "^2.4.2" @@ -8287,14 +8294,14 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz#99a983d365f7b2ad8d0f9b8c3094926eab4b936d" - integrity sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ== + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.7: - version "7.0.17" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" - integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== + version "7.0.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233" + integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -8330,12 +8337,12 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== -pretty-format@^24.7.0, pretty-format@^24.8.0: - version "24.8.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2" - integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw== +pretty-format@^24.7.0, pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== dependencies: - "@jest/types" "^24.8.0" + "@jest/types" "^24.9.0" ansi-regex "^4.0.0" ansi-styles "^3.2.0" react-is "^16.8.4" @@ -8373,12 +8380,12 @@ promise@^7.1.1: asap "~2.0.3" prompts@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.1.0.tgz#bf90bc71f6065d255ea2bdc0fe6520485c1b45db" - integrity sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg== + version "2.2.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35" + integrity sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw== dependencies: - kleur "^3.0.2" - sisteransi "^1.0.0" + kleur "^3.0.3" + sisteransi "^1.0.3" prop-types@15.5.8: version "15.5.8" @@ -8440,9 +8447,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" + integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== public-encrypt@^4.0.0: version "4.0.3" @@ -8495,9 +8502,9 @@ qrcode@^1.2.0: yargs "^13.2.4" qs@^6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + version "6.8.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.8.0.tgz#87b763f0d37ca54200334cd57bb2ef8f68a1d081" + integrity sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w== qs@~6.5.2: version "6.5.2" @@ -8505,9 +8512,9 @@ qs@~6.5.2: integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^6.4.2: - version "6.8.2" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.2.tgz#36cb7e452ae11a4b5e9efee83375e0954407b2f6" - integrity sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw== + version "6.8.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.3.tgz#fd9fb7ffb068b79062b43383685611ee47777d4b" + integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -8528,13 +8535,21 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= -randombytes@^2.0.0, randombytes@^2.0.1: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -8560,11 +8575,6 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-clone-referenced-element@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" - integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== - react-coin-icon@^0.1.9: version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" @@ -8579,7 +8589,7 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.0: +react-devtools-core@^3.6.1: version "3.6.3" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== @@ -8593,11 +8603,11 @@ react-display-name@^0.2.4: integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" - integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== + version "16.9.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" + integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw== -react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== @@ -8608,9 +8618,9 @@ react-native-actionsheet@^2.4.2: integrity sha512-DBoWIvVwuWXuptF4t46pBqkFxaUxS+rsIdHiA05t0n4BdTIDV2R4s9bLEUVOGzb94D7VxIamsXZPA/3mmw+SXg== react-native-camera@^2.11.0: - version "2.11.1" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-2.11.1.tgz#a72062f59bb57c0cb2bd57fe6713fa23b2a90571" - integrity sha512-ZmPZHcY7UXEf7Z8PoJX/WhFtmLFtdRPBGDwemOLlPRVwTVyu/OXVINDUWCug4daBqV8Fs3X1O6V927+K2u2GfA== + version "2.11.2" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-2.11.2.tgz#4936bb0a484e8ba7d0b3ecf28fa7c161833b1ac0" + integrity sha512-9Fw5zpOJqaZOa/n1SUG141sbD5b77/EWSv0VTBvP66SneN4tuuS4tYtM0YndqF+BRlyAggjYGJPDs3L7BMYsmQ== dependencies: prop-types "^15.6.2" @@ -8627,11 +8637,11 @@ react-native-clean-project@^3.1.0: integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== react-native-code-push@^5.6.0: - version "5.6.1" - resolved "https://registry.yarnpkg.com/react-native-code-push/-/react-native-code-push-5.6.1.tgz#d08d5a05ec619c6909822c2f6c4130da5d264d93" - integrity sha512-3iAKPeVCiqOdpBes7KQ4mUXjFTYiY2YdNR5smFfebGZQTgMj1hDWknQfIULaIwr7yE7+UiBe+WsnoAzepoNOIA== + version "5.7.0" + resolved "https://registry.yarnpkg.com/react-native-code-push/-/react-native-code-push-5.7.0.tgz#38667c1ba5a5e1a6dd1b4271468c6ef6284b3ca4" + integrity sha512-Sy54tRfV9kKH9gcu4mVlcmpGLzPinw3fuSlxxmOdndIH03zZdclys2QU9ipk1zYEgmYhT7ls/MjXFz84YdJL2w== dependencies: - code-push "^2.0.7" + code-push "^3.0.1" glob "^5.0.15" hoist-non-react-statics "^2.3.1" inquirer "^1.1.2" @@ -8640,9 +8650,9 @@ react-native-code-push@^5.6.0: xcode "1.0.0" react-native-crypto@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/react-native-crypto/-/react-native-crypto-2.1.2.tgz#cfe68cad51cd1f73a4202b7ac164f96c1144cb2a" - integrity sha1-z+aMrVHNH3OkICt6wWT5bBFEyyo= + version "2.2.0" + resolved "https://registry.yarnpkg.com/react-native-crypto/-/react-native-crypto-2.2.0.tgz#c999ed7c96064f830e1f958687f53d0c44025770" + integrity sha512-eZu9Y8pa8BN9FU2pIex7MLRAi+Cd1Y6bsxfiufKh7sfraAACJvjQTeW7/zcQAT93WMfM+D0OVk+bubvkrbrUkw== dependencies: browserify-cipher "^1.0.0" browserify-sign "^4.0.4" @@ -8653,11 +8663,12 @@ react-native-crypto@^2.1.2: inherits "^2.0.1" pbkdf2 "3.0.8" public-encrypt "^4.0.0" + randomfill "^1.0.3" react-native-device-info@^2.1.3: - version "2.3.1" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" - integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== react-native-dotenv@^0.2.0: version "0.2.0" @@ -8688,13 +8699,14 @@ react-native-firebase@^4.3.8: prop-types "^15.6.1" react-native-gesture-handler@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.3.0.tgz#d0386f565928ccc1849537f03f2e37fd5f6ad43f" - integrity sha512-ASRFIXBuKRvqlmwkWJhV8yP2dTpvcqVrLNpd7FKVBFHYWr6SAxjGyO9Ik8w1lAxDhMlRP2IcJ9p9eq5X2WWeLQ== + version "1.4.1" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" + integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== dependencies: + hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" - invariant "^2.2.2" - prop-types "^15.5.10" + invariant "^2.2.4" + prop-types "^15.7.2" react-native-haptic-feedback@^1.8.2: version "1.8.2" @@ -8747,9 +8759,9 @@ react-native-mail@^3.0.6: integrity sha512-FHe4kKJKAGuCPPWcDwaRSjdUhEE4IWIsVtTZ05dgD/MgOm00isYmM20zuJHla7oiHVQ2HmzGji76g6IuhIrCjw== react-native-os@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.4.tgz#f9ea7423cc9a9e865bc9cad590941ce37b7a3aee" - integrity sha512-ohlP5BxJxvWp8JZ99g8+xdZ2s8Z4bEoP6g99VDeytz04m+VYdVrCP7Xovy6FoEqA4qxyUbv4xeGHR+pzNnkZeg== + version "1.2.5" + resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" + integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== react-native-permissions@^1.1.1: version "1.2.0" @@ -8788,9 +8800,9 @@ react-native-reanimated@1.1.0: integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== react-native-redash@^7.2.1: - version "7.5.0" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.0.tgz#fa72c7a23ad2f3f884a494ed76a0e79041ae70e1" - integrity sha512-y2J19HbBYWOYq4kq+3U86wfbsDusxv1/ak4a6KqvfTmt/E3i85mnnUDIF+nk1Shqz0aYcwNMB2KD7bEWsVK/sw== + version "7.5.1" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.1.tgz#79c52c9a629b8ddeeb17e73336216aba1cc2f689" + integrity sha512-NidcTKlK57BtjCMC9OKhXJnH50TDlfb+vel4oLUfaYHO2kGY56jGj+IS29V3joZgB5iO1X+U5K5FYWuQuDnepA== dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -8798,9 +8810,9 @@ react-native-redash@^7.2.1: use-memo-one "^1.1.1" react-native-safe-area-view@^0.14.1: - version "0.14.6" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" - integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA== + version "0.14.8" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" + integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== dependencies: hoist-non-react-statics "^2.3.1" @@ -8836,9 +8848,9 @@ react-native-store-review@^0.1.5: integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== react-native-svg@^9.5.1: - version "9.5.3" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.5.3.tgz#2389f3ffd700c6441166496a1aeade31ead89c59" - integrity sha512-VUOe4TLz7RFdmm/XT9EH87VSwlRykx49qbwJMA+dh9eFM7KPY1qH3kEyN7uRCqJD2eE8toxt9NpjR6ByvtPNlA== + version "9.9.3" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.9.3.tgz#5dab1a44b20b13a3f35245a286f30882b9611d66" + integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -8885,15 +8897,15 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.60.4: - version "0.60.4" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.4.tgz#4378171e63dd5310497e15e54ec9185cb470752d" - integrity sha512-WE41lbGQjnzM9srIFtMDtMJkQAvk95iZwuFvAxl68s80bkYa7Ou9sGFHpeYIV6cY8yHtheCSo5q6YMxhdfkdOw== +react-native@0.60.5: + version "0.60.5" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.5.tgz#3c1d9c06a0fbab9807220b6acac09488d39186ee" + integrity sha512-cZwI0XzzihACN+7an1Dy46A83FRaAe2Xyd7laCalFFAppZIYeMVphZQWrVljJk5kIZBNtYG35TY1VsghQ0Oc2Q== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^2.0.1" - "@react-native-community/cli-platform-android" "^2.0.1" - "@react-native-community/cli-platform-ios" "^2.0.1" + "@react-native-community/cli" "^2.6.0" + "@react-native-community/cli-platform-android" "^2.6.0" + "@react-native-community/cli-platform-ios" "^2.4.1" abort-controller "^3.0.0" art "^0.10.0" base64-js "^1.1.2" @@ -8919,38 +8931,39 @@ react-native@0.60.4: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-drawer@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.2.1.tgz#7bd5efeee7d2f611d3ebb0933e0c8e8eb7cafe52" - integrity sha512-T2kaBjY2c4/3I6noWFnaf/c18ntNH5DsST38i+pdc2NPxn5Yi5lkK+ZZTeKuHSFD4a7G0jWY9OGf1iRkHWLMAQ== +react-navigation-drawer@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.4.0.tgz#70f3dd83e3da9cd4ea6e2739526502c823d466b9" + integrity sha512-ZyWBozcjB2aZ7vwCALv90cYA2NpDjM+WALaiYRshvPvue8l7cqynePbHK8GhlMGyJDwZqp4MxQmu8u1XAKp3Bw== dependencies: react-native-tab-view "^1.2.0" -react-navigation-stack@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.4.0.tgz#69cdb029ea4ee5877d7e933b3117dc90bc841eb2" - integrity sha512-zEe9wCA0Ot8agarYb//0nSWYW1GM+1R0tY/nydUV0EizeJ27At0EklYVWvYEuYU6C48va6cu8OPL7QD/CcJACw== +react-navigation-stack@~1.5.0: + version "1.5.5" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" + integrity sha512-qMhOhmUmyPNfFGWMbwv5flrNVsFU4JZSBWnONSgVGK4KWGW8DbobXBi4i4sBAC9Kg8EqJK0qyWcxnkMJJtfMWA== + dependencies: + prop-types "^15.7.2" -react-navigation-tabs@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" - integrity sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ== +react-navigation-tabs@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" + integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== dependencies: hoist-non-react-statics "^2.5.0" prop-types "^15.6.1" - react-lifecycles-compat "^3.0.4" react-native-tab-view "^1.4.1" react-navigation@^3.11.1: - version "3.11.1" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.1.tgz#ba696ad6b512088a97a20cc7e6a250c53dbddd26" - integrity sha512-n64HxLG5s5ucVFo1Gs+D9ujChhHDd98lpQ1p27wL7gq8V1PaRJMvsBEIsguhtc2rTIL/TWDynOesXQDG+Eg6FQ== + version "3.12.1" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" + integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== dependencies: - "@react-navigation/core" "~3.4.1" - "@react-navigation/native" "~3.5.0" - react-navigation-drawer "~1.2.1" - react-navigation-stack "~1.4.0" - react-navigation-tabs "~1.1.4" + "@react-navigation/core" "~3.5.0" + "@react-navigation/native" "~3.6.1" + react-navigation-drawer "~1.4.0" + react-navigation-stack "~1.5.0" + react-navigation-tabs "~1.2.0" react-primitives@^0.8.0: version "0.8.0" @@ -9025,15 +9038,15 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@16.8.6: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" - integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== +react@16.8.3: + version "16.8.3" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" + integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.6" + scheduler "^0.13.3" read-pkg-up@^2.0.0: version "2.0.0" @@ -9162,7 +9175,7 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" -recyclerlistview@^2.0.1-alpha.1: +recyclerlistview@2.0.1-alpha.1: version "2.0.1-alpha.1" resolved "https://registry.yarnpkg.com/recyclerlistview/-/recyclerlistview-2.0.1-alpha.1.tgz#881955e6917911fb54a9b272004e39e5c0d64f4a" integrity sha512-UaeJyxG9LL8lcfiAqkp0kPLxvjbYg95Dcq1U/QUvzwXU4+H2khg/LAws/FssxPX6CXNMw7BLcT2YHAhkFElqRQ== @@ -9197,7 +9210,7 @@ redux@^4.0.1: loose-envify "^1.4.0" symbol-observable "^1.2.0" -regenerate-unicode-properties@^8.0.2: +regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== @@ -9239,18 +9252,25 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp.prototype.flags@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c" + integrity sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== + dependencies: + define-properties "^1.1.2" + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== + version "4.6.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" + integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" + regenerate-unicode-properties "^8.1.0" regjsgen "^0.5.0" regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" @@ -9480,13 +9500,20 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: +rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@~2.2.6: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" @@ -9513,9 +9540,9 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: inherits "^2.0.1" rn-nodeify@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.0.1.tgz#b54a3f2a61eda88b40639ee9262f51f34039e353" - integrity sha512-x7vxo7Nzp5wu6DLLW/qHJ3jRJtcxSe0L/Nb7oUTWAViTRJFEan05Ewlvd5aNrh1fjSztPuqciNtohZesM4oLZQ== + version "10.1.0" + resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.1.0.tgz#e36c4aa25d6bf1dbde7d9f733ab30168772d50c6" + integrity sha512-EW9I7OWt1aTShdJEnnS/qoEvfb2myLee6uWcAMxJWcisn3z3DxWTTLfm5bqwn/2eYjcs6j677JLY6nL02uMaaQ== dependencies: "@yarnpkg/lockfile" "^1.0.0" deep-equal "^1.0.0" @@ -9569,9 +9596,9 @@ rxjs@^5.4.3: symbol-observable "1.0.1" rxjs@^6.4.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" - integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== dependencies: tslib "^1.9.0" @@ -9580,7 +9607,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -9618,22 +9645,17 @@ sane@^4.0.3: walker "~1.0.5" sanitize-filename@^1.6.1: - version "1.6.2" - resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.2.tgz#01b4fc8809f14e9d22761fe70380fe7f3f902185" - integrity sha512-cmTzND7RMxUB+f7gI+4+KAVHWEg0lfXvQJdko+FXDP5bNbGIdx4KMP5pX6lv5jfT9jSf6OBbjyxjFtZQwYA/ig== + version "1.6.3" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== dependencies: truncate-utf8-bytes "^1.0.0" -sax@^1.2.4, sax@~1.2.4: +sax@^1.2.1, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -sax@~1.1.1: - version "1.1.6" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" - integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= - schedule@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.4.0.tgz#fa20cfd0bfbf91c47d02272fd7096780d3170bbb" @@ -9649,7 +9671,7 @@ scheduler@0.14.0: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.13.3, scheduler@^0.13.6: +scheduler@^0.13.3: version "0.13.6" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== @@ -9670,16 +9692,16 @@ semver-diff@^2.0.0: semver "^5.0.3" "semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== -semver@^6.0.0, semver@^6.1.1: +semver@^6.0.0, semver@^6.1.1, semver@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -9788,7 +9810,7 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shell-quote@1.6.1, shell-quote@^1.6.1: +shell-quote@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= @@ -9798,6 +9820,11 @@ shell-quote@1.6.1, shell-quote@^1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" +shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + shell-utils@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/shell-utils/-/shell-utils-1.0.10.tgz#7fe7b8084f5d6d21323d941267013bc38aed063e" @@ -9833,10 +9860,10 @@ simple-plist@^1.0.0: bplist-parser "0.1.1" plist "^3.0.1" -sisteransi@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.2.tgz#ec57d64b6f25c4f26c0e2c7dd23f2d7f12f7e418" - integrity sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w== +sisteransi@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" + integrity sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg== sjcl@^1.0.3: version "1.0.8" @@ -9959,9 +9986,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@^0.5.6, source-map-support@^0.5.9: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -10063,11 +10090,11 @@ stack-utils@^1.0.1: integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== stacktrace-parser@^0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.6.tgz#c17d466d15ba51bee2f753d064f17327a886ff37" - integrity sha512-wXhu0Z8YgCGigUtHQq+J7pjXCppk3Um5DwH4qskOKHMlJmKwuuUSm+wDAgU7t4sbVjvuDTNGwOfFKgjMEqSflA== + version "0.1.7" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.7.tgz#9ed005638a5e79dcf256611da1dfb4871e6fd14d" + integrity sha512-Evm+NuZ2ZTwGazsbsZC+EV1EGsvyxgIvtNwbyFfeXaq/8L78M5Kdh0qpmQaTkUpbOAKbbPP7c7qZa7u8XFsrUA== dependencies: - type-fest "^0.3.0" + type-fest "^0.7.1" state-toggle@^1.0.0: version "1.0.2" @@ -10158,17 +10185,33 @@ string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^5.2.0" +string.prototype.trimleft@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + string_decoder@^0.10.31, string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= string_decoder@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - safe-buffer "~5.1.0" + safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" @@ -10252,9 +10295,9 @@ styled-components@4.3.1: supports-color "^5.5.0" styled-components@^5.0.0-beta.8: - version "5.0.0-beta.6-ej4" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.6-ej4.tgz#7570ebbf9c9356a8cca03ea37dd94233f2e40e84" - integrity sha512-WaytinYy4+Zc1TKXdTlPmkAOIj58QWvjn1rdgxCSAMAR4GFLlu2m7rQXwZ6WYWYk6GJd141rnZnE2Ig3XERc5A== + version "5.0.0-beta.8-groupsizefix" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8-groupsizefix.tgz#0497f11c0d60e9e51faa4b802afab7cc22136e42" + integrity sha512-5FDDRE4QhH8g6zsvHGPZ2NrJRi12AH1GxpZMy+y0lRYGrfNL6W5xni5Sz8kOKXS4PGf1VeyfVXaEG10mbrQYsA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -10448,9 +10491,9 @@ symbol-tree@^3.2.2: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^5.2.3: - version "5.4.4" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.4.tgz#6e0f88fdae3692793d1077fd172a4667afe986a6" - integrity sha512-IIfEAUx5QlODLblLrGTTLJA7Tk0iLSGBvgY8essPRVNGHAzThujww1YqHLs6h3HfTg55h++RzLHH5Xw/rfv+mg== + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== dependencies: ajv "^6.10.2" lodash "^4.17.14" @@ -10458,9 +10501,9 @@ table@^5.2.3: string-width "^3.0.0" tail@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.2.tgz#86073f3a9a568807b7fd886897a7350314275b5f" - integrity sha512-raFipiKWdGKEzxbvZwnhUGqjvsv0gpa/1A479rL//NOxnNwYZDN4MPk6xJJdUFs8P2Xrff3nbH5fcyYRLU4UHQ== + version "2.0.3" + resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" + integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== tar@^4: version "4.4.10" @@ -10702,9 +10745,9 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== tsutils@^3.7.0: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.14.1.tgz#f1d2b93d2a0876481f2f1f98c25ba42bbd7ee860" - integrity sha512-kiuZzD1uUA5DxGj/uxbde+ymp6VVdAxdzOIlAFbYKrPyla8/uiJ9JLBm1QsPhOm4Muj0/+cWEDP99yoCUcSl6Q== + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== dependencies: tslib "^1.8.1" @@ -10732,10 +10775,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" - integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== typedarray@^0.0.6: version "0.0.6" @@ -11007,9 +11050,9 @@ uuid@3.0.1: integrity sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE= uuid@^3.0.1, uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== validate-npm-package-license@^3.0.1: version "3.0.4" @@ -11055,6 +11098,11 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" +vlq@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" + integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== + vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -11295,12 +11343,12 @@ xmlbuilder@^9.0.7: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xmldoc@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" - integrity sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg= +xmldoc@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" + integrity sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ== dependencies: - sax "~1.1.1" + sax "^1.2.1" xmldom@0.1.x: version "0.1.27" @@ -11434,7 +11482,7 @@ yargs@13.2.2: y18n "^4.0.0" yargs-parser "^13.0.0" -yargs@^12.0.2, yargs@^12.0.5: +yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== @@ -11452,7 +11500,7 @@ yargs@^12.0.2, yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^13.0.0, yargs@^13.2.4: +yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== From a9b1a81792574226fe065aa048e6c998a6bfa171 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 00:11:26 -0400 Subject: [PATCH 078/636] Cleanup RecyclerAssetList --- .../asset-list/RecyclerAssetList.js | 101 +++++++++++------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 4a42e218d9b..873745fc446 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -15,11 +15,12 @@ import { } from 'recyclerlistview'; import StickyContainer from 'recyclerlistview/dist/reactnative/core/StickyContainer'; import styled from 'styled-components/primitives'; -import { withFabSelection, withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; import { - buildAssetHeaderUniqueIdentifier, - buildAssetUniqueIdentifier, -} from '../../helpers/assets'; + withFabSelection, + withOpenBalances, + withOpenFamilyTabs, + withOpenInvestmentCards, +} from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; import { CoinRow } from '../coin-row'; @@ -69,7 +70,7 @@ const layoutItemAnimator = { animateWillUpdate: NOOP, }; -const reloadHeightOfsetTop = -60; +const reloadHeightOffsetTop = -60; const reloadHeightOffsetBottom = -62; // eslint-disable-next-line react/prop-types @@ -162,6 +163,7 @@ class RecyclerAssetList extends Component { const { openFamilyTabs, openInvestmentCards, sections, } = this.props; + const { headersIndices } = this.state; if (headersIndices.includes(index)) { return ViewTypes.HEADER; @@ -226,7 +228,13 @@ class RecyclerAssetList extends Component { return ViewTypes.COIN_ROW; }, (type, dim) => { - const { hideHeader, paddingBottom } = this.props; + const { + hideHeader, + openSmallBalances, + paddingBottom, + sections, + } = this.props; + const { areSmallCollectibles } = this.state; dim.width = deviceUtils.dimensions.width; @@ -254,11 +262,13 @@ class RecyclerAssetList extends Component { } else if (type.get === ViewTypes.UNIQUE_TOKEN_ROW_CLOSED) { dim.height = TokenFamilyHeaderHeight + firstRowExtraTopPadding; } else if (type === ViewTypes.COIN_ROW_LAST) { - dim.height = this.state.areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height + 1; + dim.height = areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height + 1; } else if (type === ViewTypes.COIN_SMALL_BALANCES) { - const balancesIndex = findIndex(this.props.sections, ({ name }) => name === 'balances'); - const size = this.props.sections[balancesIndex].data[this.props.sections[balancesIndex].data.length - 1].assets.length; - dim.height = this.props.openSmallBalances ? CoinDivider.height + (size * CoinRow.height) + ListFooter.height + 9 : CoinDivider.height + ListFooter.height + 16; + const balancesIndex = findIndex(sections, ({ name }) => name === 'balances'); + const size = sections[balancesIndex].data[sections[balancesIndex].data.length - 1].assets.length; + dim.height = openSmallBalances + ? CoinDivider.height + (size * CoinRow.height) + ListFooter.height + 9 + : CoinDivider.height + ListFooter.height + 16; } else if (type === ViewTypes.COIN_ROW) { dim.height = CoinRow.height; } else if (type === ViewTypes.UNISWAP_ROW_LAST) { @@ -270,7 +280,7 @@ class RecyclerAssetList extends Component { } else if (type === ViewTypes.UNISWAP_ROW_CLOSED) { dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical; } else if (type === ViewTypes.HEADER) { - dim.height = this.props.hideHeader ? 0 : AssetListHeader.height; + dim.height = hideHeader ? 0 : AssetListHeader.height; } else if (type === ViewTypes.FOOTER) { dim.height = 0; } @@ -303,11 +313,20 @@ class RecyclerAssetList extends Component { this.isCancelled = false; }; - componentDidUpdate(prev) { + componentDidUpdate(prevProps) { + const { + openFamilyTabs, + openInvestmentCards, + openSmallBalances, + scrollingVelocity, + sections, + } = this.props; + let balances = {}; let collectibles = {}; let investments = {}; - this.props.sections.forEach(section => { + + sections.forEach((section) => { if (section.balances) { balances = section; } else if (section.collectibles) { @@ -316,22 +335,25 @@ class RecyclerAssetList extends Component { investments = section; } }); - if (this.props.scrollingVelocity === 0) { + + if (scrollingVelocity === 0) { clearInterval(this.interval); } - if (this.props.scrollingVelocity && this.props.scrollingVelocity !== prev.scrollingVelocity) { + + if (scrollingVelocity && scrollingVelocity !== prevProps.scrollingVelocity) { clearInterval(this.interval); this.interval = setInterval(() => { - this.rlv.scrollToOffset(0, this.position + this.props.scrollingVelocity * 10); + this.rlv.scrollToOffset(0, this.position + scrollingVelocity * 10); }, 30); } - if (this.props.openFamilyTabs !== prev.openFamilyTabs && collectibles.data) { + + if (openFamilyTabs !== prevProps.openFamilyTabs && collectibles.data) { let i = 0; while (i < collectibles.data.length) { - if (this.props.openFamilyTabs[i] === true && !prev.openFamilyTabs[i]) { + if (openFamilyTabs[i] === true && !prevProps.openFamilyTabs[i]) { let collectiblesHeight = 0; for (let j = 0; j < i; j++) { - if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + if (openFamilyTabs[j] && collectibles.data[j].tokens) { collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; } else { collectiblesHeight += TokenFamilyHeader.height; @@ -340,7 +362,7 @@ class RecyclerAssetList extends Component { let investmentHeight = 0; if (investments.data) { for (let k = 0; k < investments.data.length; k++) { - if (!this.props.openInvestmentCards[investments.data[k].uniqueId]) { + if (!openInvestmentCards[investments.data[k].uniqueId]) { investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); } else { investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); @@ -352,7 +374,7 @@ class RecyclerAssetList extends Component { balancesHeight += CoinRow.height * (balances.data.length - 1); if (balances.data[balances.data.length - 1].smallBalancesContainer) { balancesHeight += CoinDivider.height + ListFooter.height + 9; - if (this.props.openSmallBalances) { + if (openSmallBalances) { balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; } } else { @@ -361,7 +383,7 @@ class RecyclerAssetList extends Component { } const verticalOffset = 10; const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (this.props.sections.length - 1) + ListFooter.height * (this.props.sections.length - 1) + balancesHeight + investmentHeight; + const sectionBeforeCollectibles = AssetListHeader.height * (sections.length - 1) + ListFooter.height * (sections.length - 1) + balancesHeight + investmentHeight; const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; const renderSize = collectibles.data[i].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop; @@ -384,7 +406,7 @@ class RecyclerAssetList extends Component { let shouldAutoscrollBack = false; if (collectibles.data) { for (let i = 0; i < collectibles.data.length; i++) { - if (this.props.openFamilyTabs[i] === false && prev.openFamilyTabs[i] === true) { + if (openFamilyTabs[i] === false && prevProps.openFamilyTabs[i] === true) { shouldAutoscrollBack = true; break; } @@ -393,7 +415,7 @@ class RecyclerAssetList extends Component { if (investments.data && !shouldAutoscrollBack) { for (let i = 0; i < investments.data.length; i++) { - if (this.props.openInvestmentCards[investments.data[i].uniqueId] === true && prev.openInvestmentCards[investments.data[i].uniqueId] === false) { + if (openInvestmentCards[investments.data[i].uniqueId] === true && prevProps.openInvestmentCards[investments.data[i].uniqueId] === false) { shouldAutoscrollBack = true; break; } @@ -401,13 +423,13 @@ class RecyclerAssetList extends Component { } if (shouldAutoscrollBack - || (this.props.openSmallBalances === false && prev.openSmallBalances === true)) { + || (openSmallBalances === false && prevProps.openSmallBalances === true)) { let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); if (balances.data[balances.data.length - 1].smallBalancesContainer) { balancesHeight += CoinDivider.height + ListFooter.height; - if (this.props.openSmallBalances) { + if (openSmallBalances) { balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; } } else { @@ -418,7 +440,7 @@ class RecyclerAssetList extends Component { let investmentHeight = 0; if (investments.data) { for (let k = 0; k < investments.data.length; k++) { - if (!this.props.openInvestmentCards[investments.data[k].uniqueId]) { + if (!openInvestmentCards[investments.data[k].uniqueId]) { investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); } else { investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); @@ -430,7 +452,7 @@ class RecyclerAssetList extends Component { if (balances.data) { collectiblesHeight = collectibles.data.length > 0 ? AssetListHeader.height : 0; for (let j = 0; j < collectibles.data.length; j++) { - if (this.props.openFamilyTabs[j] && collectibles.data[j].tokens) { + if (openFamilyTabs[j] && collectibles.data[j].tokens) { collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; } else { collectiblesHeight += TokenFamilyHeader.height; @@ -461,8 +483,9 @@ class RecyclerAssetList extends Component { } getStableId = (index) => { - const row = get(this.state, `dataProvider._data[${index}]`); - let stableId; + const { dataProvider } = this.state; + const row = get(dataProvider, `_data[${index}]`); + if (row.isHeader) { return `header_${row.title}`; } @@ -483,11 +506,11 @@ class RecyclerAssetList extends Component { return `balance_${row.item.stableId}`; } - if (index === this.state.dataProvider._data.length - 1) { + if (index === dataProvider._data.length - 1) { return 'footer'; } - return stableId; + return index; }; handleListRef = (ref) => { this.rlv = ref; } @@ -522,7 +545,7 @@ class RecyclerAssetList extends Component { } if ((contentSize.height - layoutMeasurement.height >= offsetY && offsetY >= 0) - || (offsetY < -60 && offsetY > -62)) { + || (offsetY < reloadHeightOffsetTop && offsetY > reloadHeightOffsetBottom)) { if (this.props.scrollViewTracker) { this.props.scrollViewTracker.setValue(offsetY); } @@ -552,13 +575,15 @@ class RecyclerAssetList extends Component { if (type === ViewTypes.COIN_SMALL_BALANCES) { const renderList = []; for (let i = 0; i < item.assets.length; i++) { - const selectedItem = { item: item.assets[i] }; - selectedItem.item.isSmall = true; - renderList.push(renderItem(selectedItem)); + renderList.push(renderItem({ + item: { + ...item.assets[i], + isSmall: true, + }, + })); } - const wrappedRenderList = ; - return wrappedRenderList; + return ; } const isNotUniqueToken = ( From 30d5a6f0de7c3013c26a6a31548142a7b7c0dd79 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 00:13:38 -0400 Subject: [PATCH 079/636] Cleanup CoinDivider components --- .../asset-list/RecyclerAssetList.js | 3 +- src/components/coin-divider/CoinDivider.js | 192 ++++++++---------- .../coin-divider/CoinDividerButtonLabel.js | 42 ++++ .../coin-divider/SmallBalancesWrapper.js | 149 +++++++------- src/components/coin-divider/index.js | 2 + 5 files changed, 208 insertions(+), 180 deletions(-) create mode 100644 src/components/coin-divider/CoinDividerButtonLabel.js create mode 100644 src/components/coin-divider/index.js diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 873745fc446..3370b920deb 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -23,6 +23,7 @@ import { } from '../../hoc'; import { colors } from '../../styles'; import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; +import { CoinDivider, SmallBalancesWrapper } from '../coin-divider'; import { CoinRow } from '../coin-row'; import { TokenFamilyHeader } from '../token-family'; import { FloatingActionButton } from '../fab'; @@ -30,8 +31,6 @@ import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../ import { ListFooter } from '../list'; import { UniqueTokenRow } from '../unique-token'; import AssetListHeader from './AssetListHeader'; -import CoinDivider from '../coin-divider/CoinDivider'; -import SmallBalancesWrapper from '../coin-divider/SmallBalancesWrapper'; import { TokenFamilyWrapPaddingTop } from '../token-family/TokenFamilyWrap'; /* eslint-disable sort-keys */ diff --git a/src/components/coin-divider/CoinDivider.js b/src/components/coin-divider/CoinDivider.js index ea759a8b406..a27b980acb0 100644 --- a/src/components/coin-divider/CoinDivider.js +++ b/src/components/coin-divider/CoinDivider.js @@ -1,18 +1,21 @@ +import { isNil } from 'lodash'; import PropTypes from 'prop-types'; -import React from 'react'; -import styled from 'styled-components/primitives'; -import { View, Text } from 'react-native'; +import React, { PureComponent } from 'react'; +import { View } from 'react-native'; import FastImage from 'react-native-fast-image'; import Animated from 'react-native-reanimated'; -import { colors, fonts } from '../../styles'; -import { ButtonPressAnimation } from '../animations'; +import Caret from '../../assets/show-all-arrow.png'; import { deviceUtils } from '../../utils'; -import { Monospace } from '../text'; +import { + ButtonPressAnimation, + OpacityToggler, + RotationArrow, + RoundButtonSizeToggler, +} from '../animations'; import Highlight from '../Highlight'; -import RotationArrow from '../animations/RotationArrow'; -import Caret from '../../assets/show-all-arrow.png'; -import OpacityToggler from '../animations/OpacityToggler'; -import RoundButtonSizeToggler from '../animations/RoundButtonSizeToggler'; +import { Row } from '../layout'; +import { Monospace } from '../text'; +import CoinDividerButtonLabel from './CoinDividerButtonLabel'; const { block, @@ -21,12 +24,14 @@ const { cond, interpolate, set, - startClock, spring, - Value, SpringUtils, + startClock, + Value, } = Animated; +const CoinDividerHeight = 30; + function runTiming(clock, value, dest, isOpen) { const state = { finished: new Value(1), @@ -35,7 +40,7 @@ function runTiming(clock, value, dest, isOpen) { velocity: new Value(0), }; - const config = Animated.SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + const config = SpringUtils.makeConfigFromOrigamiTensionAndFriction({ ...SpringUtils.makeDefaultConfig(), friction: 20, tension: 200, @@ -58,64 +63,29 @@ function runTiming(clock, value, dest, isOpen) { ]); } -const marginLeft = 19; -const marginRight = 19; -const Wrapper = styled(View)` - margin: 8px 0 0 0; - padding-right: ${marginRight}px; - padding-left: ${marginLeft}px; - width: ${deviceUtils.dimensions.width}; - flex-direction: row; - align-items: center; - justify-content: space-between; - height: 30px; -`; - -const Container = styled(View)` - height: 30px; - border-radius: 15px; - align-items: center; - padding: 0 10px; - flex-direction: row; - justify-content: space-between; - min-width: 41.5px; -`; - -const BackgroundColor = styled(View)` - height: 30px; -`; - -const Header = styled(Text)` - color: ${colors.blueGreyDark}; - font-family: ${fonts.family.SFProText}; - font-size: ${fonts.size.lmedium}; - font-weight: ${fonts.weight.semibold}; - letter-spacing: ${fonts.letterSpacing.tighter}; - top: -10.25px; - opacity: 0.6; - position: absolute; -`; - -const SettingIconWrap = styled(View)` - opacity: 0.6; - padding-bottom: 1px; -`; +export default class CoinDivider extends PureComponent { + static propTypes = { + balancesSum: PropTypes.string, + isCoinDivider: PropTypes.bool, + onPress: PropTypes.func, + openSmallBalances: PropTypes.bool, + } -const SettingIcon = styled(FastImage)` - height: 17px; - width: 9px; -`; + static height = CoinDividerHeight -class CoinDivider extends React.Component { componentWillMount() { this._initialState = this.props.openSmallBalances; } - componentWillUpdate(prev) { - if (prev.openSmallBalances !== undefined - && prev.openSmallBalances !== this.props.openSmallBalances) { + componentWillUpdate(prevProps) { + const { openSmallBalances } = this.props; + + if (!isNil(prevProps.openSmallBalances) && prevProps.openSmallBalances !== openSmallBalances) { const clock = new Clock(); - const base = this.props.openSmallBalances ? runTiming(clock, -1, 1, this.props.openSmallBalances) : runTiming(clock, 1, -1, this.props.openSmallBalances); + const base = openSmallBalances + ? runTiming(clock, -1, 1, openSmallBalances) + : runTiming(clock, 1, -1, openSmallBalances); + this._node = interpolate(base, { inputRange: [-1, 1], outputRange: [1, 0], @@ -125,61 +95,73 @@ class CoinDivider extends React.Component { render() { const { - openSmallBalances, - onChangeOpenBalances, balancesSum, isCoinDivider, + onPress, + openSmallBalances, } = this.props; return ( - + - - - - - + + + - -

- All -
- - -
- Less -
-
+ + - - - + + + - - + + - + {balancesSum} - + ); } } - -CoinDivider.propTypes = { - balancesSum: PropTypes.string, - isCoinDivider: PropTypes.bool, - onChangeOpenBalances: PropTypes.func, - openSmallBalances: PropTypes.bool, -}; - -CoinDivider.height = 30; - - -export default CoinDivider; diff --git a/src/components/coin-divider/CoinDividerButtonLabel.js b/src/components/coin-divider/CoinDividerButtonLabel.js new file mode 100644 index 00000000000..d68ffa3c736 --- /dev/null +++ b/src/components/coin-divider/CoinDividerButtonLabel.js @@ -0,0 +1,42 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { onlyUpdateForKeys } from 'recompact'; +import { OpacityToggler } from '../animations'; +import { Text } from '../text'; + +const CoinDividerButtonLabel = ({ + isVisible, + label, + node, + steps, +}) => ( + + + {label} + + +); + +CoinDividerButtonLabel.propTypes = { + isVisible: PropTypes.bool, + label: PropTypes.string, + node: PropTypes.any, + steps: PropTypes.arrayOf(PropTypes.number), +}; + +export default onlyUpdateForKeys(['isVisible'])(CoinDividerButtonLabel); diff --git a/src/components/coin-divider/SmallBalancesWrapper.js b/src/components/coin-divider/SmallBalancesWrapper.js index f2de07269ed..ce80a4dfa29 100644 --- a/src/components/coin-divider/SmallBalancesWrapper.js +++ b/src/components/coin-divider/SmallBalancesWrapper.js @@ -1,87 +1,90 @@ import { withSafeTimeout } from '@hocs/safe-timers'; +import { get, isNumber } from 'lodash'; import PropTypes from 'prop-types'; -import React from 'react'; -import { View } from 'react-native'; -import { - compose, - lifecycle, - withState, - withHandlers, -} from 'recompact'; -import { withOpenBalances } from '../../hoc'; +import React, { Fragment, PureComponent } from 'react'; +import { compose, withProps } from 'recompact'; +import { withAccountSettings, withOpenBalances } from '../../hoc'; +import { OpacityToggler } from '../animations'; import CoinDivider from './CoinDivider'; -import OpacityToggler from '../animations/OpacityToggler'; -const balancesSum = (balances) => { - let sum = 0; - for (let i = 0; i < balances.length; i++) { - if (balances[i].props.item.native) { - if (!isNaN(balances[i].props.item.native.balance.amount)) { - sum += Number(balances[i].props.item.native.balance.amount); - } +class SmallBalancesWrapper extends PureComponent { + static propTypes = { + areChildrenVisible: PropTypes.bool, + assets: PropTypes.array, + balancesSum: PropTypes.string, + openSmallBalances: PropTypes.bool, + setOpenSmallBalances: PropTypes.func, + setSafeTimeout: PropTypes.func, + } + + state = { areChildrenVisible: true } + + componentDidMount() { + this.toggleChildrenVisibility(true); + } + + componentDidUpdate() { + const { openSmallBalances, setSafeTimeout } = this.props; + + if (!openSmallBalances) { + setSafeTimeout(this.hideChildren, 200); + } else { + this.toggleChildrenVisibility(true); } } - return `$${Number(sum).toFixed(2)}`; -}; -const SmallBalancesWrapper = ({ - areChildrenVisible, - openSmallBalances, - setOpenSmallBalances, - assets, - ...props -}) => ( - - setOpenSmallBalances(!openSmallBalances)} - /> - - {areChildrenVisible && assets} - - -); + handlePress = () => this.props.setOpenSmallBalances(!this.props.openSmallBalances) + + hideChildren = () => { + if (!this.props.openSmallBalances) { + this.toggleChildrenVisibility(false); + } + } -SmallBalancesWrapper.propTypes = { - areChildrenVisible: PropTypes.bool, - assets: PropTypes.array, - balancesSum: PropTypes.string, - openSmallBalances: PropTypes.bool, - setOpenSmallBalances: PropTypes.func, + toggleChildrenVisibility = (nextVisibility) => { + if (this.state.areChildrenVisible !== nextVisibility) { + this.setState({ areChildrenVisible: nextVisibility }); + } + } + + render = () => { + const { assets, balancesSum, openSmallBalances } = this.props; + const { areChildrenVisible } = this.state; + + return ( + + + + {areChildrenVisible ? assets : null} + + + ); + } +} + +const getBalanceFromAsset = asset => Number(get(asset, 'props.item.native.balance.amount', 0)); +const reduceBalances = (accumulator, currentValue) => { + const balance = getBalanceFromAsset(currentValue); + const sum = isNumber(accumulator) ? accumulator : getBalanceFromAsset(accumulator); + return sum + balance; }; export default compose( - withSafeTimeout, + withAccountSettings, withOpenBalances, - withState('areChildrenVisible', 'setAreChildrenVisible', true), - withHandlers({ - onHideChildren: ({ areChildrenVisible, setAreChildrenVisible }) => () => { - if (areChildrenVisible) { - setAreChildrenVisible(false); - } - }, - onShowChildren: ({ areChildrenVisible, setAreChildrenVisible }) => () => { - if (!areChildrenVisible) { - setAreChildrenVisible(true); - } - }, - }), - lifecycle({ - componentDidMount() { - this.props.onShowChildren(); - }, - componentDidUpdate() { - if (!this.props.openSmallBalances) { - setTimeout(() => { - if (!this.props.openSmallBalance) { - this.props.onHideChildren(); - } - }, 200); - } else { - this.props.onShowChildren(); - } - }, + withSafeTimeout, + withProps(({ assets, nativeCurrencySymbol }) => { + const balance = assets.reduce(reduceBalances, 0); + return isNumber(balance) + ? { balancesSum: `${nativeCurrencySymbol}${balance.toFixed(2)}` } + : {}; }), )(SmallBalancesWrapper); diff --git a/src/components/coin-divider/index.js b/src/components/coin-divider/index.js new file mode 100644 index 00000000000..896d2258837 --- /dev/null +++ b/src/components/coin-divider/index.js @@ -0,0 +1,2 @@ +export { default as CoinDivider } from './CoinDivider'; +export { default as SmallBalancesWrapper } from './SmallBalancesWrapper'; From fc731a382bc3f59d28f5f96b6b262eee5343210c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 00:37:19 -0400 Subject: [PATCH 080/636] Cleanup MovableFabWrapper component --- src/components/fab/MovableFabWrapper.js | 28 +++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/components/fab/MovableFabWrapper.js b/src/components/fab/MovableFabWrapper.js index 323f7639fcf..f7bcbc31d7b 100644 --- a/src/components/fab/MovableFabWrapper.js +++ b/src/components/fab/MovableFabWrapper.js @@ -3,18 +3,17 @@ import React, { PureComponent } from 'react'; import { PanGestureHandler, State } from 'react-native-gesture-handler'; import Animated from 'react-native-reanimated'; import { compose, withProps } from 'recompact'; -import { withFabSelection, withOpenFamilyTabs, withOpenInvestmentCards, withOpenBalances } from '../../hoc'; import { - setActionType, - setScrollingVelocity, - updateSelectedID, -} from '../../redux/selectedWithFab'; + withFabSelection, + withOpenBalances, + withOpenFamilyTabs, + withOpenInvestmentCards, +} from '../../hoc'; import { deviceUtils } from '../../utils'; import { CoinRow } from '../coin-row'; import { ListFooter } from '../list'; -import { CardSize, CardMargin } from '../unique-token/UniqueTokenRow'; -import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../investment-cards'; -import CoinDivider from '../coin-divider/CoinDivider'; +import { InvestmentCard, InvestmentCardHeader, UniswapInvestmentCard } from '../investment-cards'; +import { CoinDivider } from '../coin-divider'; import { UniqueTokenRow } from '../unique-token'; import DeleteButton from './DeleteButton'; @@ -305,11 +304,17 @@ class MovableFabWrapper extends PureComponent { } } -const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestmentCards, openSmallBalances }) => { +const traverseSectionsToDimensions = ({ + openFamilyTabs, + openInvestmentCards, + openSmallBalances, + sections, +}) => { let balances = false; let collectibles = false; let investments = false; - sections.forEach(section => { + + sections.forEach((section) => { if (section.balances) { balances = section; } else if (section.collectibles) { @@ -318,6 +323,7 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment investments = section; } }); + if (sections) { const areas = []; const headerHeight = 54; @@ -343,7 +349,7 @@ const traverseSectionsToDimensions = ({ sections, openFamilyTabs, openInvestment }); height += CoinDivider.height; if (openSmallBalances) { - let smallBalances = balances.data[balances.data.length - 1].assets; + const smallBalances = balances.data[balances.data.length - 1].assets; for (let i = 0; i < smallBalances.length; i++) { areas.push({ bottom: height + CoinRow.height, From 48713296ce857f289eb7787a028b87f08e40ffd8 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 00:54:09 -0400 Subject: [PATCH 081/636] Cleanup InvestmentCard related components --- .../expanded-state/InvestmentExpandedState.js | 2 +- .../investment-cards/InvestmentCard.js | 140 +++++++++--------- .../investment-cards/InvestmentCardHeader.js | 138 +++++++---------- .../investment-cards/UniswapInvestmentCard.js | 102 ++++++------- 4 files changed, 176 insertions(+), 206 deletions(-) diff --git a/src/components/expanded-state/InvestmentExpandedState.js b/src/components/expanded-state/InvestmentExpandedState.js index 44a340ae67b..051b9b6376e 100644 --- a/src/components/expanded-state/InvestmentExpandedState.js +++ b/src/components/expanded-state/InvestmentExpandedState.js @@ -9,9 +9,9 @@ const InvestmentExpandedState = ({ asset }) => ( ); diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index bb8e1e8da46..4991504698d 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -2,119 +2,117 @@ import PropTypes from 'prop-types'; import React from 'react'; import LinearGradient from 'react-native-linear-gradient'; import { View } from 'react-native'; +import { compose, withHandlers } from 'recompact'; +import { withOpenInvestmentCards } from '../../hoc'; import { colors, position } from '../../styles'; import InnerBorder from '../InnerBorder'; import { Column } from '../layout'; +import { ButtonPressAnimation, SizeToggler } from '../animations'; import InvestmentCardHeader from './InvestmentCardHeader'; -import { ButtonPressAnimation } from '../animations'; -import { withOpenInvestmentCards } from '../../hoc'; -import SizeToggler from '../animations/SizeToggler'; + +const InvestmentCardBorderRadius = 18; const InvestmentCardMargin = { horizontal: 19, vertical: 15, }; -const InvestmentCard = ({ +const enhance = compose( + withOpenInvestmentCards, + withHandlers({ + onPress: ({ openInvestmentCards, setOpenInvestmentCards, uniqueId }) => () => { + setOpenInvestmentCards({ + index: uniqueId, + state: !openInvestmentCards[uniqueId], + }); + }, + }), +); + +const InvestmentCard = enhance(({ children, collapsed, containerHeight, gradientColors, - isExtendedState, headerProps, - height, + isExpandedState, onLayout, - shadows, - setOpenInvestmentCards, + onPress, openInvestmentCards, uniqueId, - isCollapsible, - ...props -}) => { - const onPress = () => { - setOpenInvestmentCards({ index: uniqueId, state: !openInvestmentCards[uniqueId] }); - }; - - return ( - ( + - - + + + - + - - - - - {children} - - - - - - ); -}; + + {children} + + + + + +)); InvestmentCard.propTypes = { children: PropTypes.node, collapsed: PropTypes.bool, + containerHeight: PropTypes.number, gradientColors: PropTypes.arrayOf(PropTypes.string).isRequired, headerProps: PropTypes.shape(InvestmentCardHeader.propTypes), - isCollapsible: PropTypes.bool, - isExtendedState: PropTypes.bool, + isExpandedState: PropTypes.bool, onLayout: PropTypes.func.isRequired, + onPress: PropTypes.func, openInvestmentCards: PropTypes.bool, - setOpenInvestmentCards: PropTypes.func, - shadows: PropTypes.arrayOf(PropTypes.array), uniqueId: PropTypes.string, }; InvestmentCard.defaultProps = { containerHeight: InvestmentCardHeader.height, gradientColors: ['#F7FAFC', '#E0E6EC'], - height: InvestmentCardHeader.height, - shadows: [ - [0, 1, 3, colors.dark, 0.08], - [0, 4, 6, colors.dark, 0.04], - ], }; InvestmentCard.margin = InvestmentCardMargin; -export default withOpenInvestmentCards(InvestmentCard); +export default InvestmentCard; diff --git a/src/components/investment-cards/InvestmentCardHeader.js b/src/components/investment-cards/InvestmentCardHeader.js index b7978c00775..065a24756b0 100644 --- a/src/components/investment-cards/InvestmentCardHeader.js +++ b/src/components/investment-cards/InvestmentCardHeader.js @@ -1,92 +1,64 @@ import PropTypes from 'prop-types'; import React from 'react'; -import styled from 'styled-components/primitives'; import FastImage from 'react-native-fast-image'; -import { View } from 'react-native'; -import { colors, padding } from '../../styles'; -import { - Column, - Row, - RowWithMargins, -} from '../layout'; -import { Emoji, Monospace, Text } from '../text'; -import RotationArrow from '../animations/RotationArrow'; +import { View } from 'react-primitives'; +import { pure } from 'recompact'; import Caret from '../../assets/family-dropdown-arrow.png'; +import { colors } from '../../styles'; +import { Column, Row, RowWithMargins } from '../layout'; +import { Emoji, Monospace, Text } from '../text'; +import { RotationArrow } from '../animations'; -const HeaderHeight = 48; - -const Container = styled(Row).attrs({ - align: 'center', - justify: 'space-between', -})` - ${padding(0, 15)}; - height: ${HeaderHeight}; -`; - -const SettingIconWrap = styled(View)` - padding-left: 10px; -`; - -const SettingIcon = styled(FastImage)` - height: 13.5px; - width: 6.5px; -`; - -class InvestmentCardHeader extends React.Component { - render() { - const { - collapsed, - color, - emoji, - isCollapsible, - title, - titleColor, - value, - } = this.props; +const height = 48; - return ( - - - - ( + + + + + + + {title} + + + + + {value} + + {isCollapsible && ( + + + - - - {title} - - - - - {value} - - {isCollapsible && ( - - - - - - )} - - - ); - } -} + + + )} + + +)); InvestmentCardHeader.propTypes = { collapsed: PropTypes.bool, @@ -103,6 +75,6 @@ InvestmentCardHeader.defaultProps = { isCollapsible: false, }; -InvestmentCardHeader.height = HeaderHeight; +InvestmentCardHeader.height = height; export default InvestmentCardHeader; diff --git a/src/components/investment-cards/UniswapInvestmentCard.js b/src/components/investment-cards/UniswapInvestmentCard.js index cc1435ac302..6be27227ada 100644 --- a/src/components/investment-cards/UniswapInvestmentCard.js +++ b/src/components/investment-cards/UniswapInvestmentCard.js @@ -38,6 +38,7 @@ const enhance = compose( ); const UniswapInvestmentCard = enhance(({ + isCollapsible, item: { ethBalance, tokenBalance, @@ -45,64 +46,63 @@ const UniswapInvestmentCard = enhance(({ tokenSymbol, totalBalanceAmount, totalNativeDisplay, - uniqueId + uniqueId, }, + nativeCurrency, onPress, onPressContainer, - nativeCurrency, openInvestmentCards, - isCollapsible, ...props }) => ( - + + - - - - - Ethereum - {tokenName} - - - - - - - - - )); + + + Ethereum + {tokenName} + + + + + + + + +)); UniswapInvestmentCard.propTypes = { item: PropTypes.object, From 3a6be48fb4547a444bdd0e486493df1cf4eb0774 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 00:54:20 -0400 Subject: [PATCH 082/636] Cleanup ListHeader component --- src/components/list/ListHeader.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/components/list/ListHeader.js b/src/components/list/ListHeader.js index afe768e1c59..83ac1d49a17 100644 --- a/src/components/list/ListHeader.js +++ b/src/components/list/ListHeader.js @@ -1,23 +1,13 @@ import PropTypes from 'prop-types'; import React, { createElement, Fragment } from 'react'; import { pure } from 'recompact'; -import styled from 'styled-components/primitives'; import { colors, padding } from '../../styles'; import { Row } from '../layout'; import { H1 } from '../text'; import ContextMenu from '../ContextMenu'; import Divider from '../Divider'; -const ListHeaderHeight = 42; - -const Header = styled(Row).attrs({ - align: 'center', - justify: 'space-between', -})` - ${padding(0, 19, 3, 19)} - height: ${ListHeaderHeight}; - width: 100%; -`; +const height = 42; const ListHeader = pure(({ children, @@ -28,13 +18,20 @@ const ListHeader = pure(({ titleRenderer, }) => ( -
+ {createElement(titleRenderer, { children: title })} {contextMenuOptions && ()} {children} -
+ {showDivider && }
)); @@ -52,6 +49,6 @@ ListHeader.defaultProps = { titleRenderer: H1, }; -ListHeader.height = ListHeaderHeight; +ListHeader.height = height; export default ListHeader; From 6b9b0a7ef38a88a5e65945725c8e14f226e5c1e8 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 00:54:28 -0400 Subject: [PATCH 083/636] Cleanup ShadowStack --- src/components/shadow-stack/ShadowStack.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/shadow-stack/ShadowStack.js b/src/components/shadow-stack/ShadowStack.js index dc81789832b..f89c21b40e0 100644 --- a/src/components/shadow-stack/ShadowStack.js +++ b/src/components/shadow-stack/ShadowStack.js @@ -29,11 +29,11 @@ export default class ShadowStack extends PureComponent { static propTypes = { borderRadius: PropTypes.number.isRequired, children: PropTypes.node, + childrenWrapperStyle: stylePropType, height: PropTypes.number.isRequired, shadowProps: PropTypes.object, shadows: PropTypes.arrayOf(PropTypes.array).isRequired, style: stylePropType, - childrenWrapperStyle: stylePropType, width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, } @@ -54,16 +54,19 @@ export default class ShadowStack extends PureComponent { render = () => { const { children, + childrenWrapperStyle, shadows, style, - childrenWrapperStyle, ...props } = this.props; return ( {shadows.map(this.renderItem)} - + {children} From d4f22c0f5bcc9a9202739241939a64394af41902 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 14 Sep 2019 01:40:12 -0400 Subject: [PATCH 084/636] upgrade rngh and reanimated --- ios/Podfile.lock | 4 +- ios/Rainbow.xcodeproj/project.pbxproj | 62 ++++++++--------- package.json | 10 +-- yarn.lock | 98 +++++++-------------------- 4 files changed, 64 insertions(+), 110 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c326e7d4171..de0068a39ec 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -158,7 +158,7 @@ PODS: - React - RNLanguages (3.0.2): - React - - RNReanimated (1.1.0): + - RNReanimated (1.2.0): - React - RNScreens (1.0.0-alpha.23): - React @@ -352,7 +352,7 @@ SPEC CHECKSUMS: RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e - RNReanimated: 7a52c90473b5e81c13408d40d797b98387eaddde + RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index bc5d41fe08b..d43ab347669 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 06B78001D9F2456D9C2D4A86 /* Graphik-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */; }; 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */; }; 0AB30EE90F554EE59F57DFC1 /* SF-Pro-Display-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */; }; - 0D83F39C1A368358BE63E551 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BD400B9F4BAFB66CCE58799E /* libPods-Rainbow.a */; }; 0F4372360E744AF4B37EB905 /* Graphik-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; @@ -54,6 +53,7 @@ 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; 6E37C5716EC449C1B63D0E06 /* libTouchID.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E0A11D8843045ECB80C6AB8 /* libTouchID.a */; }; 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; + 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */; }; 872630C5E4CA448D8DDC783E /* Graphik-Extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */; }; @@ -594,6 +594,7 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Rainbow/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Rainbow/main.m; sourceTree = ""; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; + 15B240C971E54630F3158955 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; 171CDF49E32841EDA7D557DB /* RNGestureHandler.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNGestureHandler.xcodeproj; path = "../node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj"; sourceTree = ""; }; 1736F851327A41C3815212E7 /* SF-Pro-Text-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-BoldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-BoldItalic.otf"; sourceTree = ""; }; 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-RegularItalic.otf"; path = "../src/assets/fonts/Graphik-RegularItalic.otf"; sourceTree = ""; }; @@ -620,7 +621,6 @@ 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ExtralightItalic.otf"; path = "../src/assets/fonts/Graphik-ExtralightItalic.otf"; sourceTree = ""; }; 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNRandomBytes.xcodeproj; path = "../node_modules/react-native-randombytes/RNRandomBytes.xcodeproj"; sourceTree = ""; }; 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Display-Medium.otf"; sourceTree = ""; }; - 2BC795CD9117769AA359DE10 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Light.otf"; path = "../src/assets/fonts/SFMono-Light.otf"; sourceTree = ""; }; 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-MediumItalic.otf"; path = "../src/assets/fonts/Graphik-MediumItalic.otf"; sourceTree = ""; }; @@ -650,12 +650,12 @@ 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Thin.otf"; path = "../src/assets/fonts/SF-Pro-Display-Thin.otf"; sourceTree = ""; }; 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Medium.otf"; path = "../src/assets/fonts/SFMono-Medium.otf"; sourceTree = ""; }; + 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTcpSockets.a; sourceTree = ""; }; + 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-RegularItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-RegularItalic.otf"; sourceTree = ""; }; - 776E95D621071668979C01C5 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Black.otf"; path = "../src/assets/fonts/Graphik-Black.otf"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; - 78E830C92AA20F78D93272D1 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; 7A19C32218BC469EA9228F2E /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNSVG-tvOS.a"; sourceTree = ""; }; 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Light.otf"; path = "../src/assets/fonts/Graphik-Light.otf"; sourceTree = ""; }; 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Super.otf"; path = "../src/assets/fonts/Graphik-Super.otf"; sourceTree = ""; }; @@ -679,6 +679,7 @@ 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Light.otf"; path = "../src/assets/fonts/SF-Pro-Display-Light.otf"; sourceTree = ""; }; 9E0A11D8843045ECB80C6AB8 /* libTouchID.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTouchID.a; sourceTree = ""; }; A014AE1645874354A732EB35 /* libToolTipMenu.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libToolTipMenu.a; sourceTree = ""; }; + A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Regular.otf"; path = "../src/assets/fonts/Graphik-Regular.otf"; sourceTree = ""; }; A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-SemiboldItalic.otf"; path = "../src/assets/fonts/Graphik-SemiboldItalic.otf"; sourceTree = ""; }; A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-BlackItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-BlackItalic.otf"; sourceTree = ""; }; @@ -691,7 +692,6 @@ B98C0A69B3614C65B194BC68 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = ""; }; BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Bold.otf"; path = "../src/assets/fonts/SF-Pro-Display-Bold.otf"; sourceTree = ""; }; BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNMail.xcodeproj; path = "../node_modules/react-native-mail/RNMail.xcodeproj"; sourceTree = ""; }; - BD400B9F4BAFB66CCE58799E /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Black.otf"; path = "../src/assets/fonts/SF-Pro-Display-Black.otf"; sourceTree = ""; }; BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNOS.xcodeproj; path = "../node_modules/react-native-os/ios/RNOS.xcodeproj"; sourceTree = ""; }; C1324455238847F2AD5C08B4 /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = ""; }; @@ -711,11 +711,11 @@ E672AB1C5404435897615660 /* SF-Pro-Text-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Light.otf"; path = "../src/assets/fonts/SF-Pro-Text-Light.otf"; sourceTree = ""; }; E6F010E529544E518E1792C7 /* Graphik-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Bold.otf"; path = "../src/assets/fonts/Graphik-Bold.otf"; sourceTree = ""; }; E8E3CE2A4AD34CB991CD61EE /* SF-Pro-Display-LightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-LightItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-LightItalic.otf"; sourceTree = ""; }; + E93A96605FE51CFC31676801 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; EA95F99E656542F790F685B6 /* libSplashScreen.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSplashScreen.a; sourceTree = ""; }; EB48DC1D46D449759B9C61D4 /* Graphik-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Thin.otf"; path = "../src/assets/fonts/Graphik-Thin.otf"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; - F6164080EB3D274AC63A0D14 /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; F62BBE10D6534F74B2180711 /* SF-Pro-Text-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Bold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Bold.otf"; sourceTree = ""; }; FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-SemiboldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-SemiboldItalic.otf"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -754,7 +754,7 @@ F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */, 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, - 0D83F39C1A368358BE63E551 /* libPods-Rainbow.a in Frameworks */, + 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1092,7 +1092,7 @@ 24979E3620F84003007EB0DA /* Protobuf.framework */, 2D16E6891FA4F8E400B85C8A /* libReact.a */, D1A86E696CA24D4F9D3F7F0F /* libz.tbd */, - BD400B9F4BAFB66CCE58799E /* libPods-Rainbow.a */, + 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */, ); name = Frameworks; sourceTree = ""; @@ -1210,10 +1210,10 @@ C640359C0E6575CE0A7ECD73 /* Pods */ = { isa = PBXGroup; children = ( - F6164080EB3D274AC63A0D14 /* Pods-Rainbow.debug.xcconfig */, - 776E95D621071668979C01C5 /* Pods-Rainbow.release.xcconfig */, - 78E830C92AA20F78D93272D1 /* Pods-Rainbow.localrelease.xcconfig */, - 2BC795CD9117769AA359DE10 /* Pods-Rainbow.staging.xcconfig */, + 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */, + A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */, + 15B240C971E54630F3158955 /* Pods-Rainbow.localrelease.xcconfig */, + E93A96605FE51CFC31676801 /* Pods-Rainbow.staging.xcconfig */, ); path = Pods; sourceTree = ""; @@ -1304,7 +1304,7 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Rainbow" */; buildPhases = ( - 2C90E890400DC5F7A5A37C7E /* [CP] Check Pods Manifest.lock */, + B448B1B66A188D3AC6DA3639 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, @@ -2060,41 +2060,41 @@ shellPath = /bin/sh; shellScript = "export NODE_ARGS=--max-old-space-size=2048\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; }; - 2C90E890400DC5F7A5A37C7E /* [CP] Check Pods Manifest.lock */ = { + 3CF823D3218F310D0024B77B /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( + "$(SRCROOT)/Rainbow/Info.plist", ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Rainbow-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "\"${PODS_ROOT}/Fabric/run\"\n"; }; - 3CF823D3218F310D0024B77B /* ShellScript */ = { + B448B1B66A188D3AC6DA3639 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "$(SRCROOT)/Rainbow/Info.plist", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Rainbow-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Fabric/run\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -2242,7 +2242,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F6164080EB3D274AC63A0D14 /* Pods-Rainbow.debug.xcconfig */; + baseConfigurationReference = 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; @@ -2296,7 +2296,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 776E95D621071668979C01C5 /* Pods-Rainbow.release.xcconfig */; + baseConfigurationReference = A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; @@ -2387,7 +2387,7 @@ }; 2C6A799821127ED9003AFB37 /* Staging */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2BC795CD9117769AA359DE10 /* Pods-Rainbow.staging.xcconfig */; + baseConfigurationReference = E93A96605FE51CFC31676801 /* Pods-Rainbow.staging.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; @@ -2525,7 +2525,7 @@ }; 2C87B79A2197FA1900682EC4 /* LocalRelease */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 78E830C92AA20F78D93272D1 /* Pods-Rainbow.localrelease.xcconfig */; + baseConfigurationReference = 15B240C971E54630F3158955 /* Pods-Rainbow.localrelease.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = ""; diff --git a/package.json b/package.json index e87802e0a63..f13fb2d3457 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "prop-types": "^15.7.2", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "react": "16.8.3", + "react": "16.9.0", "react-coin-icon": "^0.1.9", "react-native": "0.60.5", "react-native-actionsheet": "^2.4.2", @@ -70,7 +70,7 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "^6.0.3", "react-native-firebase": "^4.3.8", - "react-native-gesture-handler": "^1.3.0", + "react-native-gesture-handler": "^1.4.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", "react-native-ios11-devicecheck": "^0.0.3", @@ -86,7 +86,7 @@ "react-native-qrcode-svg": "git+https://github.com/mikedemarais/react-native-qrcode-svg.git", "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", - "react-native-reanimated": "1.1.0", + "react-native-reanimated": "1.2.0", "react-native-redash": "^7.2.1", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", @@ -128,7 +128,7 @@ "devDependencies": { "@babel/core": "^7.5.5", "@babel/runtime": "^7.5.5", - "@react-native-community/cli": "2.0.0-rc.2", + "@react-native-community/cli": "2.9.0", "@react-native-community/eslint-config": "^0.0.5", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^8.2.2", @@ -146,7 +146,7 @@ "eslint-plugin-react-native": "^3.7.0", "eslint-plugin-react-native-animation-linter": "^0.1.2", "jest": "^24.8.0", - "metro-react-native-babel-preset": "^0.55.0", + "metro-react-native-babel-preset": "^0.56.0", "mocha": "^6.1.4", "react-native-clean-project": "^3.1.0", "react-test-renderer": "16.8.3", diff --git a/yarn.lock b/yarn.lock index e528dc6c18c..9eb157aa04a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1074,7 +1074,7 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.0.0-rc.2", "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": +"@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== @@ -1087,7 +1087,7 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^2.0.0-rc.2", "@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": +"@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== @@ -1096,7 +1096,7 @@ chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.8.3": +"@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== @@ -1106,47 +1106,7 @@ mime "^2.4.1" node-fetch "^2.5.0" -"@react-native-community/cli@2.0.0-rc.2": - version "2.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.0.0-rc.2.tgz#8bb3c07a58056b0af5474782bedc457184b42595" - integrity sha512-G0NrMfJ6bcXfJKLijQmxuTV4S22pXfp8c5XI7L1i+b5Vu34IvR6xvKVPT9leYEEI/bg/ZuyguDZuVecycJb63A== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.0.0-rc.2" - "@react-native-community/cli-platform-ios" "^2.0.0-rc.2" - "@react-native-community/cli-tools" "^2.0.0-rc.2" - chalk "^1.1.1" - command-exists "^1.2.8" - commander "^2.19.0" - compression "^1.7.1" - connect "^3.6.5" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - envinfo "^7.1.0" - errorhandler "^1.5.0" - execa "^1.0.0" - fs-extra "^7.0.1" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.54.1" - metro-config "^0.54.1" - metro-core "^0.54.1" - metro-react-native-babel-transformer "^0.54.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-notifier "^5.2.1" - open "^6.2.0" - ora "^3.4.0" - plist "^3.0.0" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" - ws "^1.1.0" - -"@react-native-community/cli@^2.6.0": +"@react-native-community/cli@2.9.0", "@react-native-community/cli@^2.6.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw== @@ -2657,7 +2617,7 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1: +chalk@1.1.3, chalk@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -2933,11 +2893,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -command-exists@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" - integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== - commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" @@ -3653,9 +3608,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.247: - version "1.3.257" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.257.tgz#35da0ad5833b27184c8298804c498a4d2f4ed27d" - integrity sha512-EcKVmUeHCZelPA0wnIaSmpAN8karKhKBwFb+xLUjSVZ8sGRE1l3fst1zQZ7KJUkyJ7H5edPd4RP94pzC9sG00A== + version "1.3.258" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" + integrity sha512-rkPYrgFU7k/8ngjHYvzOZ44OQQ1GeIRIQnhGv00RkSlQXEnJKsGonQppbEEWHuuxZegpMao+WZmYraWQJQJMMg== elliptic@6.3.3: version "6.3.3" @@ -6879,10 +6834,10 @@ metro-react-native-babel-preset@0.54.1: metro-babel7-plugin-react-transform "0.54.1" react-transform-hmr "^1.0.4" -metro-react-native-babel-preset@^0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.55.0.tgz#d5d4a6cbe9ccbcedd72fcbb71c0c311e3d56876e" - integrity sha512-HUI+dEiVym8f1NYIF1grY9PdoY0d3SSS/HED2dDDvTORwndsAEWuXiUgKFOGWX18+RUAQog8obVQuBMgrr8ZBQ== +metro-react-native-babel-preset@^0.56.0: + version "0.56.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.0.tgz#fa47dfd5f7678e89cffd1249020b8add6938fc48" + integrity sha512-MAo1fm0dNn6MVZmylaz6k2HC1MINHLTLfE7O3a9Xz3fAtbGbApisp06rBUfK5uUqIJDmAaKgbiT34lHJSIiE6Q== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" @@ -6918,7 +6873,7 @@ metro-react-native-babel-preset@^0.55.0: "@babel/plugin-transform-typescript" "^7.0.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - react-refresh "^0.2.0" + react-refresh "^0.4.0" metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" @@ -8698,7 +8653,7 @@ react-native-firebase@^4.3.8: postinstall-build "^5.0.1" prop-types "^15.6.1" -react-native-gesture-handler@^1.3.0: +react-native-gesture-handler@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== @@ -8794,10 +8749,10 @@ react-native-randombytes@^3.5.3: buffer "^4.9.1" sjcl "^1.0.3" -react-native-reanimated@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz#ba6864055ec3a206cdd5209a293fe653ce276206" - integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== +react-native-reanimated@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.2.0.tgz#9219227a52a5dfa4d34c324596d6726ccd874293" + integrity sha512-vkWRHrPK5qfHP/ZawlRoo38oeYe9NZaaOH/lmFxRcsKzaSK6x3H5ZPXI8lK6MfTLveqwo1QhJje3zIKXO4nQQw== react-native-redash@^7.2.1: version "7.5.1" @@ -8996,10 +8951,10 @@ react-redux@^5.0.7: react-is "^16.6.0" react-lifecycles-compat "^3.0.0" -react-refresh@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.2.0.tgz#f0cff375e8f75dea7133a847a1b40cf5c073dd0d" - integrity sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg== +react-refresh@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.2.tgz#54a277a6caaac2803d88f1d6f13c1dcfbd81e334" + integrity sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ== react-spring@^5.7.2: version "5.9.2" @@ -9038,15 +8993,14 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@16.8.3: - version "16.8.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" - integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== +react@16.9.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa" + integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.3" read-pkg-up@^2.0.0: version "2.0.0" From 428d4d96df44565886a007fa9f0deff7d1c5abdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 26 Jun 2019 12:37:15 +0200 Subject: [PATCH 085/636] Update react-navigation-stack to 2.0.0-alpha.2 This commit will update `react-navigation-stack` to the newest, cutting edge alpha version. Since at the moment it is not yet used by any version of `react-navigation`, and that alpha wasn't yet published to the npm, I am using yarn resolution directly from Github tag. --- package.json | 1 + yarn.lock | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/package.json b/package.json index f13fb2d3457..5f5dd1eb4e7 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,7 @@ }, "resolutions": { "**/eslint-plugin-import": "2.14.0", + "react-navigation/react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.2", "**/resolve": "1.8.1" }, "jest": { diff --git a/yarn.lock b/yarn.lock index 9eb157aa04a..9bb94d5e348 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8764,10 +8764,17 @@ react-native-redash@^7.2.1: parse-svg-path "^0.1.2" use-memo-one "^1.1.1" +<<<<<<< HEAD react-native-safe-area-view@^0.14.1: version "0.14.8" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== +======= +react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.5.tgz#eeded66bbeb0807f0a7f5f449e7fb2871f7ecf76" + integrity sha512-1NxWK1G0gzwCOuyNV/zf4n18s6FWsiqgwkzU3P9C0Iu8AErjhstK1jUqpRwzLH8+/7hGLsrQedmn+ZbQTOrJPg== +>>>>>>> bc689cd3... Update react-navigation-stack to 2.0.0-alpha.2 dependencies: hoist-non-react-statics "^2.3.1" @@ -8893,12 +8900,20 @@ react-navigation-drawer@~1.4.0: dependencies: react-native-tab-view "^1.2.0" +<<<<<<< HEAD react-navigation-stack@~1.5.0: version "1.5.5" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" integrity sha512-qMhOhmUmyPNfFGWMbwv5flrNVsFU4JZSBWnONSgVGK4KWGW8DbobXBi4i4sBAC9Kg8EqJK0qyWcxnkMJJtfMWA== dependencies: prop-types "^15.7.2" +======= +"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.2", react-navigation-stack@~1.4.0: + version "2.0.0-alpha.2" + resolved "https://github.com/react-navigation/stack#34e12dae8d9fbd9aff455ea82478639dc579df86" + dependencies: + react-native-safe-area-view "^0.14.5" +>>>>>>> bc689cd3... Update react-navigation-stack to 2.0.0-alpha.2 react-navigation-tabs@~1.2.0: version "1.2.0" From 033c1dab639e5feb85dbb848139931b4e2d22fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 3 Jul 2019 17:03:26 +0200 Subject: [PATCH 086/636] Convert parts of the API to the new version --- package.json | 1 - src/screens/Routes.js | 13 +++++++++---- yarn.lock | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5f5dd1eb4e7..f13fb2d3457 100644 --- a/package.json +++ b/package.json @@ -154,7 +154,6 @@ }, "resolutions": { "**/eslint-plugin-import": "2.14.0", - "react-navigation/react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.2", "**/resolve": "1.8.1" }, "jest": { diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 17ad4ac388e..1102bd7d745 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -4,10 +4,10 @@ import React from 'react'; import { createAppContainer, createMaterialTopTabNavigator, - createStackNavigator, } from 'react-navigation'; -import { Navigation } from '../navigation'; -import { buildTransitions, expanded, sheet } from '../navigation/transitions'; +import { createStackNavigator } from 'react-navigation-stack'; +import Navigation from '../navigation'; +// import { buildTransitions, expanded, sheet } from '../navigation/transitions'; import { updateTransitionProps } from '../redux/navigation'; import store from '../redux/store'; import { deviceUtils } from '../utils'; @@ -62,6 +62,7 @@ const MainNavigator = createStackNavigator({ ExampleScreen, ExpandedAssetScreen: { navigationOptions: { + cardTransparent: true, effect: 'expanded', gestureResponseDistance: { vertical: deviceUtils.dimensions.height, @@ -72,6 +73,7 @@ const MainNavigator = createStackNavigator({ ImportSeedPhraseSheet: ImportSeedPhraseSheetWithData, ReceiveModal: { navigationOptions: { + cardTransparent: true, effect: 'expanded', gestureResponseDistance: { vertical: deviceUtils.dimensions.height, @@ -82,6 +84,7 @@ const MainNavigator = createStackNavigator({ SendSheet: SendSheetWithData, SettingsModal: { navigationOptions: { + cardTransparent: true, effect: 'expanded', gesturesEnabled: false, }, @@ -90,6 +93,7 @@ const MainNavigator = createStackNavigator({ SwipeLayout: SwipeStack, WalletConnectConfirmationModal: { navigationOptions: { + cardTransparent: true, effect: 'expanded', gestureResponseDistance: { vertical: deviceUtils.dimensions.height, @@ -98,12 +102,13 @@ const MainNavigator = createStackNavigator({ screen: WalletConnectConfirmationModal, }, }, { + cardStyleInterpolator: () => { }, headerMode: 'none', initialRouteName: 'SwipeLayout', mode: 'modal', onTransitionEnd, onTransitionStart, - transitionConfig: buildTransitions(Navigation, { expanded, sheet }), + // transitionConfig: buildTransitions(Navigation, { expanded, sheet }), transparentCard: true, }); diff --git a/yarn.lock b/yarn.lock index 9bb94d5e348..3907e8ffb6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8900,6 +8900,7 @@ react-navigation-drawer@~1.4.0: dependencies: react-native-tab-view "^1.2.0" +<<<<<<< HEAD <<<<<<< HEAD react-navigation-stack@~1.5.0: version "1.5.5" @@ -8909,16 +8910,31 @@ react-navigation-stack@~1.5.0: prop-types "^15.7.2" ======= "react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.2", react-navigation-stack@~1.4.0: +======= +"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.2": +>>>>>>> 85ffae7a... Convert parts of the API to the new version version "2.0.0-alpha.2" resolved "https://github.com/react-navigation/stack#34e12dae8d9fbd9aff455ea82478639dc579df86" dependencies: react-native-safe-area-view "^0.14.5" >>>>>>> bc689cd3... Update react-navigation-stack to 2.0.0-alpha.2 +<<<<<<< HEAD react-navigation-tabs@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== +======= +react-navigation-stack@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.4.0.tgz#69cdb029ea4ee5877d7e933b3117dc90bc841eb2" + integrity sha512-zEe9wCA0Ot8agarYb//0nSWYW1GM+1R0tY/nydUV0EizeJ27At0EklYVWvYEuYU6C48va6cu8OPL7QD/CcJACw== + +react-navigation-tabs@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" + integrity sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ== +>>>>>>> 85ffae7a... Convert parts of the API to the new version dependencies: hoist-non-react-statics "^2.5.0" prop-types "^15.6.1" From 50863d9caaf476d91146e6eaf4f1eb61aa68cd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 4 Jul 2019 14:19:14 +0200 Subject: [PATCH 087/636] =?UTF-8?q?=F0=9F=9A=A7=20=20Migrate=20to=20the=20?= =?UTF-8?q?new=20version=20of=20react-navigation-stack=20API=20?= =?UTF-8?q?=F0=9F=9A=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/BlurOverlay.js | 3 +- src/hoc/withBlurTransitionProps.js | 20 +++++++---- src/redux/navigation.js | 1 + src/screens/Routes.js | 56 ++++++++++++++++++++++++++---- 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index 7e09ef5184e..a42641356fb 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -1,7 +1,8 @@ import { VibrancyView } from '@react-native-community/blur'; import PropTypes from 'prop-types'; import React from 'react'; -import { Animated, StyleSheet } from 'react-native'; +import { StyleSheet } from 'react-native'; +import Animated from 'react-native-reanimated'; import { pure } from 'recompact'; import { position } from '../styles'; diff --git a/src/hoc/withBlurTransitionProps.js b/src/hoc/withBlurTransitionProps.js index 3071fd1be1f..99d53751cdd 100644 --- a/src/hoc/withBlurTransitionProps.js +++ b/src/hoc/withBlurTransitionProps.js @@ -1,16 +1,24 @@ import { compose, withProps } from 'recompact'; import { createSelector } from 'reselect'; +import Animated from 'react-native-reanimated'; import withTransitionProps from './withTransitionProps'; -const blurOpacityInterpolation = { - inputRange: [0, 0.01, 1], - outputRange: [0, 1, 1], -}; +const { interpolate } = Animated; const transitionPropsSelector = state => state.transitionProps; -const withBlurTransitionProps = ({ effect, isTransitioning, position }) => { - const blurOpacity = position.interpolate(blurOpacityInterpolation); +const withBlurTransitionProps = ({ + effect, + isTransitioning, + isExpanded, + position, +}) => { + const blurOpacity = interpolate(position, { + inputRange: [0, 0.01, 1], + outputRange: [0, 0.8, 1], + }); + + const showBlur = (effect === 'expanded') && (isTransitioning || isExpanded); return { blurOpacity, diff --git a/src/redux/navigation.js b/src/redux/navigation.js index 75643ce0f07..ef710950f6d 100644 --- a/src/redux/navigation.js +++ b/src/redux/navigation.js @@ -11,6 +11,7 @@ export const updateTransitionProps = (payload) => (dispatch) => { const INITIAL_STATE = { transitionProps: { effect: '', + isExpanded: false, isTransitioning: false, nextIndex: 1, position: new Animated.Value(0), diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 1102bd7d745..0ee9b789d5d 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -23,8 +23,46 @@ import SettingsModal from './SettingsModal'; import TransactionConfirmationScreenWithData from './TransactionConfirmationScreenWithData'; import WalletScreen from './WalletScreen'; -const onTransitionEnd = () => store.dispatch(updateTransitionProps({ isTransitioning: false })); -const onTransitionStart = () => store.dispatch(updateTransitionProps({ isTransitioning: true })); +import Animated from 'react-native-reanimated'; +const { call, block, concat, interpolate, color } = Animated; + +const cardStyleInterpolator = props => { + const { progress } = props; + + const { + progress: { current }, + layouts: { screen }, + } = props; + + const translateY = interpolate(current, { + inputRange: [0, 1], + outputRange: [screen.height, 0], + }); + + store.dispatch(updateTransitionProps({ + effect: 'expanded', + position: progress.current, + })); + + return { + cardStyle: { + transform: [{ translateY }], + }, + containerStyle: { + backgroundColor: 'rgba(0,0,0,0.3)', + }, + }; +}; + +const onTransitionEnd = () => { + console.log('onTransitionEnd'); + store.dispatch(updateTransitionProps({ isTransitioning: false })); +}; + +const onTransitionStart = () => { + console.log('onTransitionStart'); + store.dispatch(updateTransitionProps({ isTransitioning: true })); +}; const SwipeStack = createMaterialTopTabNavigator({ ProfileScreen: { @@ -102,14 +140,20 @@ const MainNavigator = createStackNavigator({ screen: WalletConnectConfirmationModal, }, }, { - cardStyleInterpolator: () => { }, + cardStyleInterpolator, headerMode: 'none', initialRouteName: 'SwipeLayout', mode: 'modal', - onTransitionEnd, + wip: { + open: () => { + store.dispatch(updateTransitionProps({ isExpanded: true })); + }, + close: () => { + store.dispatch(updateTransitionProps({ isExpanded: false })); + onTransitionEnd(); + }, + }, onTransitionStart, - // transitionConfig: buildTransitions(Navigation, { expanded, sheet }), - transparentCard: true, }); const AppContainer = createAppContainer(MainNavigator); From df2e168a3dfa82b51682f65b1e2c659c9e633006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 4 Jul 2019 19:35:53 +0200 Subject: [PATCH 088/636] Move on --- package.json | 3 +- src/screens/Routes.js | 128 +++++++++++++++++++++++++++++++++++------- 2 files changed, 111 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index f13fb2d3457..c848cdc1316 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", + "react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.2", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", @@ -236,4 +237,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 0ee9b789d5d..49556222ed7 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -7,7 +7,7 @@ import { } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; import Navigation from '../navigation'; -// import { buildTransitions, expanded, sheet } from '../navigation/transitions'; +import { buildTransitions, expanded, sheet } from '../navigation/transitions'; import { updateTransitionProps } from '../redux/navigation'; import store from '../redux/store'; import { deviceUtils } from '../utils'; @@ -23,35 +23,125 @@ import SettingsModal from './SettingsModal'; import TransactionConfirmationScreenWithData from './TransactionConfirmationScreenWithData'; import WalletScreen from './WalletScreen'; +import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; +const distanceFromTop = 14; +const statusBarHeight = getStatusBarHeight(true); +export const sheetVerticalOffset = distanceFromTop + statusBarHeight; + import Animated from 'react-native-reanimated'; const { call, block, concat, interpolate, color } = Animated; -const cardStyleInterpolator = props => { - const { progress } = props; +let previousEffect = undefined +const cardStyleInterpolator = props => { const { progress: { current }, layouts: { screen }, + effect, } = props; - const translateY = interpolate(current, { - inputRange: [0, 1], - outputRange: [screen.height, 0], - }); + console.log('xd', effect); - store.dispatch(updateTransitionProps({ - effect: 'expanded', - position: progress.current, - })); + store.dispatch(updateTransitionProps({ effect, position: current })); - return { - cardStyle: { - transform: [{ translateY }], - }, - containerStyle: { - backgroundColor: 'rgba(0,0,0,0.3)', - }, - }; + // expanded + const opacityEnd = 0.75; + const translateYStart = deviceUtils.dimensions.height; + + // sheet + const scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? distanceFromTop : 0)) / deviceUtils.dimensions.height); + const heightEnd = statusBarHeight + distanceFromTop; + const borderRadiusEnd = 12; + const borderRadiusScaledEnd = borderRadiusEnd / scaleEnd; + const opacityEndSheet = 0.5; + + if (!effect) { + if (previousEffect === 'expanded') { + const opacity = interpolate(current, { + inputRange: [0, 1], + outputRange: [1, opacityEnd], + }); + + return { + cardStyle: { opacity }, + }; + } + + if (previousEffect === 'sheet') { + const translateY = interpolate(current, { + inputRange: [0, 1], + outputRange: [0, distanceFromTop], + }); + + const opacity = interpolate(current, { + inputRange: [0, 1], + outputRange: [1, opacityEndSheet], + }); + + const scale = interpolate(current, { + inputRange: [0, 1], + outputRange: [1, scaleEnd], + }); + + const borderRadius = interpolate(current, { + inputRange: [0, 1], + outputRange: [isIphoneX() ? 38.5 : 0, borderRadiusScaledEnd], + }); + + return { + containerStyle: { + borderTopLeftRadius: borderRadius, + borderTopRightRadius: borderRadius, + opacity, + // overflow: 'hidden', + transform: [{ + translateY, + }, { + scale, + }], + // zIndex: 1, + }, + }; + } + } else { + // previousEffect = effect; + + if (effect === 'expanded') { + const translateY = interpolate(current, { + inputRange: [0, 1], + outputRange: [translateYStart, 0], + }); + + return { + cardStyle: { + transform: [{ translateY }], + }, + }; + } + + if (effect === 'sheet') { + const { height } = screen; + const translateY = interpolate(current, { + inputRange: [0, 1], + outputRange: [height, heightEnd], + }); + + return { + containerStyle: { + borderTopLeftRadius: borderRadiusEnd, + borderTopRightRadius: borderRadiusEnd, + height: height - heightEnd, + // overflow: 'hidden', + transform: [{ + translateY, + }], + // zIndex: 2, + }, + }; + } + } + + return {}; }; const onTransitionEnd = () => { From 8a48c514b810ec1e5b098b53c34b441d5a8ce0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 10 Jul 2019 08:06:21 +0200 Subject: [PATCH 089/636] Update alpha.2 to alpha.5 --- package.json | 3 ++- src/App.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c848cdc1316..7a27db3e4ff 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", - "react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.2", + "react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.5", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", @@ -155,6 +155,7 @@ }, "resolutions": { "**/eslint-plugin-import": "2.14.0", + "**/react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.5", "**/resolve": "1.8.1" }, "jest": { diff --git a/src/App.js b/src/App.js index 905737cae4c..10e52d66d36 100644 --- a/src/App.js +++ b/src/App.js @@ -33,7 +33,7 @@ if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; } -useScreens(); +useScreens(false); class App extends Component { static propTypes = { From 486ed5106afd4175628ece844a12e50430c6ea73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 10 Jul 2019 08:08:46 +0200 Subject: [PATCH 090/636] Replace navigation animations with new effects --- src/hoc/withBlurTransitionProps.js | 11 +- src/navigation/transitions/effects.js | 195 ++++++++++++ src/screens/Routes.js | 159 ++-------- yarn.lock | 413 +++++++++++++++++++++++++- 4 files changed, 632 insertions(+), 146 deletions(-) create mode 100644 src/navigation/transitions/effects.js diff --git a/src/hoc/withBlurTransitionProps.js b/src/hoc/withBlurTransitionProps.js index 99d53751cdd..e7ac1f143d1 100644 --- a/src/hoc/withBlurTransitionProps.js +++ b/src/hoc/withBlurTransitionProps.js @@ -3,22 +3,17 @@ import { createSelector } from 'reselect'; import Animated from 'react-native-reanimated'; import withTransitionProps from './withTransitionProps'; -const { interpolate } = Animated; - const transitionPropsSelector = state => state.transitionProps; const withBlurTransitionProps = ({ effect, isTransitioning, - isExpanded, + showingModal, position, }) => { - const blurOpacity = interpolate(position, { - inputRange: [0, 0.01, 1], - outputRange: [0, 0.8, 1], - }); + const blurOpacity = position; - const showBlur = (effect === 'expanded') && (isTransitioning || isExpanded); + const showBlur = (effect === 'expanded') && (isTransitioning || showingModal); return { blurOpacity, diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js new file mode 100644 index 00000000000..0026de7fce5 --- /dev/null +++ b/src/navigation/transitions/effects.js @@ -0,0 +1,195 @@ +import Animated from 'react-native-reanimated'; +import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; +import store from '../../redux/store'; +import { updateTransitionProps } from '../../redux/navigation'; +import { deviceUtils } from '../../utils'; +import { colors } from '../../styles'; + +const { + add, + and, + block, + call, + color, + cond, + eq, + interpolate, + multiply, + lessThan, + greaterThan, + set, + sub, + Value, +} = Animated; + +const NO = 0; +const EXPANDED = 1; +const SHEET = 2; + +const CURRENT_EFFECT = new Value(NO); + +const statusBarHeight = getStatusBarHeight(true); + +const getInterpolated = value => interpolate( + value, + { inputRange: [0, 1], outputRange: [0, 1] }, +); + +const expand = {}; +expand.opacityEnd = 0.75; +expand.translateY = deviceUtils.dimensions.height; + +const sheet = {}; +sheet.distanceFromTop = 14; +sheet.borderRadiusEnd = 12; +sheet.scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? sheet.distanceFromTop : 0)) / deviceUtils.dimensions.height); +sheet.heightEnd = statusBarHeight + sheet.distanceFromTop; +sheet.borderRadiusScaledEnd = sheet.borderRadiusEnd / sheet.scaleEnd; +sheet.opacityEnd = 0.5; + +const CLOSING = new Value(-1); + +export const expandStyleInterpolator = ({ + progress: { current }, + closing, +}) => { + const value = getInterpolated(current); + return { + containerStyle: { + transform: [{ + translateY: block([ + call([], () => { + store.dispatch(updateTransitionProps({ + effect: 'expanded', + position: current, + })); + }), + set(CURRENT_EFFECT, EXPANDED), + set(CLOSING, closing), + cond( + eq(closing, 1), + cond(lessThan(value, 0.5), call([], () => { + store.dispatch(updateTransitionProps({ showingModal: false })); + })), + cond(greaterThan(value, 0.5), call([], () => { + store.dispatch(updateTransitionProps({ showingModal: true })); + })), + ), + multiply(expand.translateY, sub(1, value)), + ]), + }], + }, + }; +}; + +export const sheetStyleInterpolator = ({ + progress: { current }, + closing, + layouts: { screen: { height } }, +}) => { + store.dispatch(updateTransitionProps({ + effect: 'sheet', + position: current, + })); + + const value = getInterpolated(current); + + return { + cardStyle: { + borderTopLeftRadius: sheet.borderRadiusEnd, + borderTopRightRadius: sheet.borderRadiusEnd, + transform: [{ + translateY: block([ + call([], () => { + store.dispatch(updateTransitionProps({ + effect: 'sheet', + position: current, + })); + }), + set(CURRENT_EFFECT, SHEET), + set(CLOSING, closing), + add( + sheet.heightEnd, + multiply(sub(height, sheet.heightEnd), sub(1, value)), + ), + ]), + }], + }, + }; +}; + +export const backgroundStyleInterpolator = ({ progress: { next } }) => { + if (!next) return {}; + + const pick = ( + openingSheet, + closingSheet, + openingExpanded, + closingExpanded, + ) => cond( + eq(CURRENT_EFFECT, SHEET), + cond( + eq(CLOSING, 0), + openingSheet, + closingSheet, + ), + cond( + eq(CURRENT_EFFECT, EXPANDED), + cond( + eq(CLOSING, 0), + openingExpanded, + closingExpanded, + ), + ), + ); + + // Expand opening + + const expandOpacity = interpolate(next, { + inputRange: [0, 1], + outputRange: [1, expand.opacityEnd], + }); + + // Sheet opening + + const translateY = interpolate(next, { + inputRange: [0, 1], + outputRange: [0, sheet.distanceFromTop], + }); + + const sheetOpacity = interpolate(next, { + inputRange: [0, 1], + outputRange: [1, sheet.opacityEnd], + }); + + const scale = interpolate(next, { + inputRange: [0, 1], + outputRange: [1, sheet.scaleEnd], + }); + + const sheetOpeningBorderRadius = interpolate(next, { + inputRange: [0, 1], + outputRange: [isIphoneX() ? 38.5 : 0, sheet.borderRadiusScaledEnd], + }); + + const sheetClosingBorderRadius = interpolate(next, { + inputRange: [0, 1], + outputRange: [0, sheet.borderRadiusEnd], + }); + + return { + cardStyle: { + borderTopLeftRadius: pick(sheetOpeningBorderRadius, sheetClosingBorderRadius, 0, 0), + borderTopRightRadius: pick(sheetOpeningBorderRadius, sheetClosingBorderRadius, 0, 0), + opacity: pick(sheetOpacity, sheetOpacity, expandOpacity, expandOpacity), + transform: [{ + scale: pick(scale, scale, 1, 1), + }, { + translateY: pick(translateY, translateY, 0, 0), + }], + }, + containerStyle: { + backgroundColor: color(0, 0, 0), + }, + }; +}; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 49556222ed7..9663c3ffab5 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -7,7 +7,6 @@ import { } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; import Navigation from '../navigation'; -import { buildTransitions, expanded, sheet } from '../navigation/transitions'; import { updateTransitionProps } from '../redux/navigation'; import store from '../redux/store'; import { deviceUtils } from '../utils'; @@ -22,135 +21,17 @@ import SendSheetWithData from './SendSheetWithData'; import SettingsModal from './SettingsModal'; import TransactionConfirmationScreenWithData from './TransactionConfirmationScreenWithData'; import WalletScreen from './WalletScreen'; - -import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; -const distanceFromTop = 14; -const statusBarHeight = getStatusBarHeight(true); -export const sheetVerticalOffset = distanceFromTop + statusBarHeight; - -import Animated from 'react-native-reanimated'; -const { call, block, concat, interpolate, color } = Animated; - -let previousEffect = undefined - -const cardStyleInterpolator = props => { - const { - progress: { current }, - layouts: { screen }, - effect, - } = props; - - console.log('xd', effect); - - store.dispatch(updateTransitionProps({ effect, position: current })); - - // expanded - const opacityEnd = 0.75; - const translateYStart = deviceUtils.dimensions.height; - - // sheet - const scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? distanceFromTop : 0)) / deviceUtils.dimensions.height); - const heightEnd = statusBarHeight + distanceFromTop; - const borderRadiusEnd = 12; - const borderRadiusScaledEnd = borderRadiusEnd / scaleEnd; - const opacityEndSheet = 0.5; - - if (!effect) { - if (previousEffect === 'expanded') { - const opacity = interpolate(current, { - inputRange: [0, 1], - outputRange: [1, opacityEnd], - }); - - return { - cardStyle: { opacity }, - }; - } - - if (previousEffect === 'sheet') { - const translateY = interpolate(current, { - inputRange: [0, 1], - outputRange: [0, distanceFromTop], - }); - - const opacity = interpolate(current, { - inputRange: [0, 1], - outputRange: [1, opacityEndSheet], - }); - - const scale = interpolate(current, { - inputRange: [0, 1], - outputRange: [1, scaleEnd], - }); - - const borderRadius = interpolate(current, { - inputRange: [0, 1], - outputRange: [isIphoneX() ? 38.5 : 0, borderRadiusScaledEnd], - }); - - return { - containerStyle: { - borderTopLeftRadius: borderRadius, - borderTopRightRadius: borderRadius, - opacity, - // overflow: 'hidden', - transform: [{ - translateY, - }, { - scale, - }], - // zIndex: 1, - }, - }; - } - } else { - // previousEffect = effect; - - if (effect === 'expanded') { - const translateY = interpolate(current, { - inputRange: [0, 1], - outputRange: [translateYStart, 0], - }); - - return { - cardStyle: { - transform: [{ translateY }], - }, - }; - } - - if (effect === 'sheet') { - const { height } = screen; - const translateY = interpolate(current, { - inputRange: [0, 1], - outputRange: [height, heightEnd], - }); - - return { - containerStyle: { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - // overflow: 'hidden', - transform: [{ - translateY, - }], - // zIndex: 2, - }, - }; - } - } - - return {}; -}; +import { + expandStyleInterpolator, + sheetStyleInterpolator, + backgroundStyleInterpolator, +} from '../navigation/transitions/effects'; const onTransitionEnd = () => { - console.log('onTransitionEnd'); store.dispatch(updateTransitionProps({ isTransitioning: false })); }; const onTransitionStart = () => { - console.log('onTransitionStart'); store.dispatch(updateTransitionProps({ isTransitioning: true })); }; @@ -190,6 +71,7 @@ const MainNavigator = createStackNavigator({ ExampleScreen, ExpandedAssetScreen: { navigationOptions: { + cardStyleInterpolator: expandStyleInterpolator, cardTransparent: true, effect: 'expanded', gestureResponseDistance: { @@ -209,7 +91,12 @@ const MainNavigator = createStackNavigator({ }, screen: ReceiveModal, }, - SendSheet: SendSheetWithData, + SendSheet: { + navigationOptions: { + cardStyleInterpolator: sheetStyleInterpolator, + }, + screen: SendSheetWithData, + }, SettingsModal: { navigationOptions: { cardTransparent: true, @@ -218,7 +105,12 @@ const MainNavigator = createStackNavigator({ }, screen: SettingsModal, }, - SwipeLayout: SwipeStack, + SwipeLayout: { + navigationOptions: { + cardStyleInterpolator: backgroundStyleInterpolator, + }, + screen: SwipeStack, + }, WalletConnectConfirmationModal: { navigationOptions: { cardTransparent: true, @@ -230,20 +122,13 @@ const MainNavigator = createStackNavigator({ screen: WalletConnectConfirmationModal, }, }, { - cardStyleInterpolator, + defaultNavigationOptions: { + onTransitionEnd, + onTransitionStart, + }, headerMode: 'none', initialRouteName: 'SwipeLayout', mode: 'modal', - wip: { - open: () => { - store.dispatch(updateTransitionProps({ isExpanded: true })); - }, - close: () => { - store.dispatch(updateTransitionProps({ isExpanded: false })); - onTransitionEnd(); - }, - }, - onTransitionStart, }); const AppContainer = createAppContainer(MainNavigator); diff --git a/yarn.lock b/yarn.lock index 3907e8ffb6f..451c1192533 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,6 +16,7 @@ dependencies: "@babel/highlight" "^7.0.0" +<<<<<<< HEAD "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" @@ -28,6 +29,20 @@ "@babel/template" "^7.6.0" "@babel/traverse" "^7.6.0" "@babel/types" "^7.6.0" +======= +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a" + integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.4" + "@babel/helpers" "^7.4.4" + "@babel/parser" "^7.4.5" + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.4.5" + "@babel/types" "^7.4.4" +>>>>>>> 751dba29... Replace navigation animations with new effects convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -36,6 +51,26 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@^7.4.4": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.0.tgz#6ed6a2881ad48a732c5433096d96d1b0ee5eb734" + integrity sha512-6Isr4X98pwXqHvtigw71CKgmhL1etZjPs5A67jL/w0TkLM9eqmFR40YrnJvEc1WnMZFsskjsmid8bHZyxKEAnw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.5.0" + "@babel/helpers" "^7.5.0" + "@babel/parser" "^7.5.0" + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.5.0" + "@babel/types" "^7.5.0" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + "@babel/generator@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" @@ -58,6 +93,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a" + integrity sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA== + dependencies: + "@babel/types" "^7.5.0" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -265,6 +311,15 @@ "@babel/traverse" "^7.6.0" "@babel/types" "^7.6.0" +"@babel/helpers@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.0.tgz#7f0c17666e7ed8355ed6eff643dde12fb681ddb4" + integrity sha512-EgCUEa8cNwuMrwo87l2d7i2oShi8m2Q58H7h3t4TWtqATZalJYFwfL9DulRe02f3KdqM9xmMCw3v/7Ll+EiaWg== + dependencies: + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.5.0" + "@babel/types" "^7.5.0" + "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" @@ -288,6 +343,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== +"@babel/parser@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" + integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== + "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz#7f4cb7dee651cd380d2034847d914288467a6be4" @@ -658,10 +718,24 @@ pirates "^4.0.0" source-map-support "^0.5.9" +<<<<<<< HEAD "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== +======= +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" + integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== +>>>>>>> 751dba29... Replace navigation animations with new effects + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/runtime@^7.4.4": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.0.tgz#49dcbcd637099a55d3a61e590a00d6861393b1b5" + integrity sha512-2xsuyZ0R0RBFwjgae5NpXk8FcfH4qovj5cEM5VEeB7KXnKqzaisIu2HSV/mCEISolJJuR4wkViUGYujA8MH9tw== dependencies: regenerator-runtime "^0.13.2" @@ -715,6 +789,21 @@ globals "^11.1.0" lodash "^4.17.13" +"@babel/traverse@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.0.tgz#4216d6586854ef5c3c4592dab56ec7eb78485485" + integrity sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.5.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.5.0" + "@babel/types" "^7.5.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" @@ -733,6 +822,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" + integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -811,10 +909,17 @@ dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" +<<<<<<< HEAD "@ethersproject/keccak256@>=5.0.0-beta.127": version "5.0.0-beta.128" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.128.tgz#5635a9f386de3692e17b2fa550807a30f9da78b0" integrity sha512-dWp669s9B1+DyUSDSjxtU29+g270qQzBVAfJ0O6GbAnyuWFoyLfU4eeD/4GDGHI6g94iHXNt8yAQNE9wocB+MQ== +======= +"@ethersproject/keccak256@>5.0.0-beta.0": + version "5.0.0-beta.125" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.125.tgz#ac2bd7d20a411ebcddddcfc686ebd426960eb112" + integrity sha512-Vzood4ptHvWk64yqE5DMef7qLivEm3qH3S/60l66kWSAMmf5ISuSxeO+8Ss3o+p86zEGIhyipjpenb2LD6+/xA== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" js-sha3 "0.5.7" @@ -1074,6 +1179,7 @@ dependencies: prop-types "^15.5.10" +<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" @@ -1100,6 +1206,31 @@ version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== +======= +"@react-native-community/cli-platform-android@^2.0.0-alpha.15": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.0.2.tgz#e2e9a93d37d6dab3a8086b14e191210359cb2e45" + integrity sha512-vJ/9ev+1oL5hkgV+o8ssrDtztZc3zugUTj8JVUe8SgHp87FAcSkKYf7XsD/GyZvUzTc+UjKiQ95QQaacs3l+Mw== + dependencies: + "@react-native-community/cli-tools" "^2.0.2" + logkitty "^0.4.0" + slash "^2.0.0" + xmldoc "^0.4.0" + +"@react-native-community/cli-platform-ios@^2.0.0-alpha.15": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.0.2.tgz#ce21fa9771152a71d2b05fba434d849e32e0376a" + integrity sha512-Pwp1EOCfbpNpTXwSLQg7mGmTsCD981nkizu3S7D3QVoIwhQGpuTGXM1xyIFu9IZI2AIHNtUT9W5Nqw97/UDmdw== + dependencies: + "@react-native-community/cli-tools" "^2.0.2" + chalk "^1.1.1" + xcode "^2.0.0" + +"@react-native-community/cli-tools@^2.0.0-alpha.14", "@react-native-community/cli-tools@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.0.2.tgz#1dc4055f27f1b2fe3d0493959a6fc20467e93fe0" + integrity sha512-6OOKrE1Sdq1Lmcdp2K68J5PsG5G80a9USa9I1Kv92wvPHUup6IRt+Dy7E8IZqxmskzC/mlOR62Oh1CB3sFm84g== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1145,10 +1276,57 @@ shell-quote "1.6.1" ws "^1.1.0" +<<<<<<< HEAD "@react-native-community/eslint-config@^0.0.5": version "0.0.5" resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795" integrity sha512-jwO2tnKaTPTLX5XYXMHGEnFdf543SU7jz98/OF5mDH3b7lP+BOaCD+jVfqqHoDRkcqyPlYiR1CgwVGWpi0vMWg== +======= +"@react-native-community/cli@^1.2.1": + version "1.9.11" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.9.11.tgz#b868b17201057b9cd16a3a20c30561176071f21a" + integrity sha512-VVu/tmTTzODfW2xlqIz0pZgeELG2ppPAIgbBEKLgHCO9DMxNZIKSqmei/JqkAi0gEipqQoP6YPAemHPd43lyrA== + dependencies: + chalk "^1.1.1" + commander "^2.19.0" + compression "^1.7.1" + connect "^3.6.5" + denodeify "^1.2.1" + envinfo "^5.7.0" + errorhandler "^1.5.0" + escape-string-regexp "^1.0.5" + execa "^1.0.0" + fs-extra "^7.0.1" + glob "^7.1.1" + graceful-fs "^4.1.3" + inquirer "^3.0.6" + lodash "^4.17.5" + metro "^0.51.0" + metro-config "^0.51.0" + metro-core "^0.51.0" + metro-memory-fs "^0.51.0" + metro-react-native-babel-transformer "^0.51.0" + mime "^1.3.4" + minimist "^1.2.0" + mkdirp "^0.5.1" + morgan "^1.9.0" + node-fetch "^2.2.0" + node-notifier "^5.2.1" + opn "^3.0.2" + plist "^3.0.0" + semver "^5.0.3" + serve-static "^1.13.1" + shell-quote "1.6.1" + slash "^2.0.0" + ws "^1.1.0" + xcode "^2.0.0" + xmldoc "^0.4.0" + +"@react-native-community/eslint-config@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.3.tgz#bf9be8434caa18f85b570cf4e28366f2a7f1ea91" + integrity sha512-YmCiqoiqgSW8YpWYWLwG4WYwVIwvkhfH97COxbin71CuCr5muZPlmhHOFwo2gIQzUvt1ewFb1shtUi1X8TAVhA== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: "@typescript-eslint/eslint-plugin" "^1.5.0" "@typescript-eslint/parser" "^1.5.0" @@ -1264,6 +1442,7 @@ "@svgr/babel-plugin-transform-svg-component" "^4.2.0" "@svgr/cli@^4.3.0": +<<<<<<< HEAD version "4.3.2" resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.2.tgz#fb20fd33429f0d0dfc6c7178e8bfc1e86006e9de" integrity sha512-QdYzVgsowOWpOwkX+3+EK6zxlttADc2v6t0Baj2xETAdhBcpFAf/nZ0xw6b5zxdbGk8fm3nxJyPUddYuBkgzpg== @@ -1271,6 +1450,15 @@ "@svgr/core" "^4.3.2" "@svgr/plugin-jsx" "^4.3.2" "@svgr/plugin-prettier" "^4.3.2" +======= + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.1.tgz#ee4da73b866c81d3fca4ea642df1279924d0cf77" + integrity sha512-et42q/arMztdgzwqVm3IEu1b/sDDOvqYgu3DHZ8wOBkn34XwPbIYfhHfWSYxyqAOBa3zarOPmJJsfv7+gIugAw== + dependencies: + "@svgr/core" "^4.3.1" + "@svgr/plugin-jsx" "^4.3.1" + "@svgr/plugin-prettier" "^4.3.1" +>>>>>>> 751dba29... Replace navigation animations with new effects "@svgr/plugin-svgo" "^4.3.1" camelcase "^5.3.1" chalk "^2.4.2" @@ -1280,6 +1468,7 @@ output-file-sync "^2.0.1" recursive-readdir "^2.2.2" +<<<<<<< HEAD "@svgr/core@^4.3.2": version "4.3.2" resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.2.tgz#939c89be670ad79b762f4c063f213f0e02535f2e" @@ -1310,6 +1499,40 @@ version "4.3.2" resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-4.3.2.tgz#41a95cf0c52a58e2d9841434d227e120d7d533f7" integrity sha512-GErOZQ0n/OinFDjyXg9svfVRNWP+18qqIxsc/9xRoRY7R/cPlnXkadLF7NdgDgSP2BYtt7XGcZ9TU+Skr1B3tw== +======= +"@svgr/core@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.1.tgz#58c44d0ccc3fe41718c50433758b549dabd4d197" + integrity sha512-TXFcvzp6QjxKP5Oy7qoQY08w/nAix9TMOc4jSi3wjIJBBMUqypVwQJFMxtHrViGMQGmFdaN1y2diQrhvA+xNNQ== + dependencies: + "@svgr/plugin-jsx" "^4.3.1" + camelcase "^5.3.1" + cosmiconfig "^5.2.1" + +"@svgr/hast-util-to-babel-ast@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.1.tgz#b3ea5b2228b50ff335a5d3cf3855f4b1f9fbc70e" + integrity sha512-MZbRccEpsro70mE6mhiv5QUXjBwHGDQZ7XrVcrDs44inaNvYUtIcheX0d9eColcnNgJmsfU3tEFfoGRnJ9E5pA== + dependencies: + "@babel/types" "^7.4.4" + +"@svgr/plugin-jsx@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.1.tgz#5b7f849213d1411886e1cec9b6c287faec69143e" + integrity sha512-v9sgsn/VpDM9G1U0ZDCair7ZmYqNrVC5LiSyIQli03DAm34bYLM12xVOOrl3dg8NGNY1k4C3A6YgBL3VKjA6Og== + dependencies: + "@babel/core" "^7.4.5" + "@svgr/babel-preset" "^4.3.1" + "@svgr/hast-util-to-babel-ast" "^4.3.1" + rehype-parse "^6.0.0" + unified "^7.1.0" + vfile "^4.0.1" + +"@svgr/plugin-prettier@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-4.3.1.tgz#b50347ec95a0163091ecbbc305991e727076c7d8" + integrity sha512-RTTZniRGtUQw+BufJk1sLKbeglZlHXCoJeE/op+hhrVLI3UZSbtliaQbyV6Rm5tZOed+08miuSWTLa6x3Tf10w== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: merge-deep "^3.0.2" prettier "^1.17.1" @@ -2098,12 +2321,16 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" +<<<<<<< HEAD babel-plugin-rewire@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ== "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.0: +>>>>>>> 751dba29... Replace navigation animations with new effects version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -2590,10 +2817,31 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= +<<<<<<< HEAD caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +======= +can-promise@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/can-promise/-/can-promise-0.0.1.tgz#7a7597ad801fb14c8b22341dfec314b6bd6ad8d3" + integrity sha512-gzVrHyyrvgt0YpDm7pn04MQt8gjh0ZAhN4ZDyCRtGl6YnuuK6b4aiUTD7G52r9l4YNmxfTtEscb92vxtAlL6XQ== + dependencies: + window-or-global "^1.0.1" + +caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: + version "1.0.30000979" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz#92f16d00186a6cf20d6c5711bb6e042a3d667029" + integrity sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw== + +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= + dependencies: + rsvp "^3.3.3" +>>>>>>> 751dba29... Replace navigation animations with new effects capture-exit@^2.0.0: version "2.0.0" @@ -2963,6 +3211,7 @@ concat-stream@^1.4.4, concat-stream@^1.4.7, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +<<<<<<< HEAD configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" @@ -2979,6 +3228,12 @@ confusing-browser-globals@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz#93ffec1f82a6e2bf2bc36769cc3a92fa20e502f3" integrity sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg== +======= +confusing-browser-globals@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.7.tgz#5ae852bd541a910e7ffb2dbb864a2d21a36ad29b" + integrity sha512-cgHI1azax5ATrZ8rJ+ODDML9Fvu67PimB6aNxBrc/QwSaDaM9eTfIEUHx3bBLJJ82ioSb+/5zfsMCCEJax3ByQ== +>>>>>>> 751dba29... Replace navigation animations with new effects connect@^3.6.5: version "3.7.0" @@ -3044,7 +3299,11 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +<<<<<<< HEAD cosmiconfig@^5.0.5, cosmiconfig@^5.1.0, cosmiconfig@^5.2.0, cosmiconfig@^5.2.1: +======= +cosmiconfig@^5.0.0, cosmiconfig@^5.0.5, cosmiconfig@^5.1.0, cosmiconfig@^5.2.1: +>>>>>>> 751dba29... Replace navigation animations with new effects version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== @@ -3191,6 +3450,7 @@ csso@^3.5.1: dependencies: css-tree "1.0.0-alpha.29" +<<<<<<< HEAD cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" @@ -3200,8 +3460,19 @@ cssstyle@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== +======= +"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" + integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== + +cssstyle@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.3.0.tgz#c36c466f7037fd30f03baa271b65f0f17b50585c" + integrity sha512-wXsoRfsRfsLVNaVzoKdqvEmK/5PFaEXNspVT22Ots6K/cnJdpoDKuQFw+qlMiXnmaif1OgeC466X1zISgAOcGg== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: - cssom "0.3.x" + cssom "~0.3.6" currently-unhandled@^0.4.1: version "0.4.1" @@ -3607,10 +3878,17 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" integrity sha512-rkPYrgFU7k/8ngjHYvzOZ44OQQ1GeIRIQnhGv00RkSlQXEnJKsGonQppbEEWHuuxZegpMao+WZmYraWQJQJMMg== +======= +electron-to-chromium@^1.3.164: + version "1.3.182" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.182.tgz#1711122c0c035f1568aea0d1b6b93c04b5f9fdf2" + integrity sha512-uqKh3J1/s4LkmtbrVi2cPpd5g2u7efYJdnRXApQLVhZlLjzaJZakafp+JFSUZNYrBDJNIqQChcJTCDZXqQOBYg== +>>>>>>> 751dba29... Replace navigation animations with new effects elliptic@6.3.3: version "6.3.3" @@ -3623,9 +3901,15 @@ elliptic@6.3.3: inherits "^2.0.1" elliptic@^6.0.0: +<<<<<<< HEAD version "6.5.1" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b" integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg== +======= + version "6.5.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca" + integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -3845,9 +4129,15 @@ eslint-plugin-import@2.14.0: resolve "^1.6.0" eslint-plugin-import@^2.14.0: +<<<<<<< HEAD version "2.18.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== +======= + version "2.18.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz#7a5ba8d32622fb35eb9c8db195c2090bd18a3678" + integrity sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: array-includes "^3.0.3" contains-path "^0.1.0" @@ -3875,9 +4165,15 @@ eslint-plugin-prettier@2.6.2: jest-docblock "^21.0.0" eslint-plugin-react-hooks@^1.5.1: +<<<<<<< HEAD version "1.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== +======= + version "1.6.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz#3c66a5515ea3e0a221ffc5d4e75c971c217b1a4c" + integrity sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA== +>>>>>>> 751dba29... Replace navigation animations with new effects eslint-plugin-react-native-animation-linter@^0.1.2: version "0.1.2" @@ -3916,10 +4212,17 @@ eslint-plugin-react@7.12.4: prop-types "^15.6.2" resolve "^1.9.0" +<<<<<<< HEAD eslint-plugin-react@^7.13.0: version "7.14.3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== +======= +eslint-plugin-react@^7.12.1: + version "7.14.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz#94c193cc77a899ac0ecbb2766fbef88685b7ecc1" + integrity sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: array-includes "^3.0.3" doctrine "^2.1.0" @@ -4054,10 +4357,17 @@ eth-contract-metadata@^1.9.2: resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== +<<<<<<< HEAD ethers@^4.0.33: version "4.0.37" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== +======= +ethers@^4.0.27: + version "4.0.32" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.32.tgz#46378864cb3bf29b57c2effd17508b560743abf6" + integrity sha512-r0k2tBNF6MYEsvwmINeP3VPppD/7eAZyiOk/ifDDawXGCKqr3iEQkPq6OZSDVD+4Jie38WPteS9thXzpn2+A5Q== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -4833,9 +5143,15 @@ got@^6.7.1: url-parse-lax "^1.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +<<<<<<< HEAD version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== +======= + version "4.2.0" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" + integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== +>>>>>>> 751dba29... Replace navigation animations with new effects growl@1.10.5: version "1.10.5" @@ -5079,9 +5395,15 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: +<<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" integrity sha512-yEGSWX9UTpWQskPsFy03t8uhZh5wyZ7v9p+MCo08Sd2edTaFdg1gFA633dg9OqTxJ/z1rtCiacgOlDSBpgssgw== +======= + version "17.0.6" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.6.tgz#01079cc2bcef408139ea8ce24d18ac0d512fbe85" + integrity sha512-bdNhzhcM6RG5m82RypVguCrAQNie/ycxW0Q5C6K9UDWD5hqApZfdJFbj4Ikz9jxIR+Ja1eg0yCQLhlCT+opwIg== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: "@babel/runtime" "^7.3.1" @@ -7375,10 +7697,17 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" +<<<<<<< HEAD node-releases@^1.1.29: version "1.1.30" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== +======= +node-releases@^1.1.23: + version "1.1.24" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.24.tgz#2fb494562705c01bfb81a7af9f8584c4d56311b4" + integrity sha512-wym2jptfuKowMmkZsfCSTsn8qAVo8zm+UiQA6l5dNqUcpfChZSnS/vbbpOeXczf+VdPhutxh+99lWHhdd6xKzg== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: semver "^5.3.0" @@ -8402,9 +8731,15 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: +<<<<<<< HEAD version "1.4.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== +======= + version "1.2.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" + integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== +>>>>>>> 751dba29... Replace navigation animations with new effects public-encrypt@^4.0.0: version "4.0.3" @@ -8639,7 +8974,11 @@ react-native-emoji@1.5.0: dependencies: node-emoji "1.10.0" +<<<<<<< HEAD react-native-fast-image@^6.0.3: +======= +react-native-fast-image@^6.0.0: +>>>>>>> 751dba29... Replace navigation animations with new effects version "6.1.1" resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-6.1.1.tgz#502165beeafdd117e09dfb68ba322fe602534b8e" integrity sha512-9bYUY8GLKpuTF9WOC28VM/ceH0+GyV60g3bcwYeiq0A+oDBVyVlj/ovMaJqRxHII6GQYX0WbTkiT5kWtPCtWkA== @@ -8714,9 +9053,15 @@ react-native-mail@^3.0.6: integrity sha512-FHe4kKJKAGuCPPWcDwaRSjdUhEE4IWIsVtTZ05dgD/MgOm00isYmM20zuJHla7oiHVQ2HmzGji76g6IuhIrCjw== react-native-os@^1.2.2: +<<<<<<< HEAD version "1.2.5" resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== +======= + version "1.2.4" + resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.4.tgz#f9ea7423cc9a9e865bc9cad590941ce37b7a3aee" + integrity sha512-ohlP5BxJxvWp8JZ99g8+xdZ2s8Z4bEoP6g99VDeytz04m+VYdVrCP7Xovy6FoEqA4qxyUbv4xeGHR+pzNnkZeg== +>>>>>>> 751dba29... Replace navigation animations with new effects react-native-permissions@^1.1.1: version "1.2.0" @@ -8749,6 +9094,7 @@ react-native-randombytes@^3.5.3: buffer "^4.9.1" sjcl "^1.0.3" +<<<<<<< HEAD react-native-reanimated@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.2.0.tgz#9219227a52a5dfa4d34c324596d6726ccd874293" @@ -8771,6 +9117,14 @@ react-native-safe-area-view@^0.14.1: integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== ======= react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.5: +======= +react-native-reanimated@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz#ba6864055ec3a206cdd5209a293fe653ce276206" + integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== + +react-native-safe-area-view@^0.14.1: +>>>>>>> 751dba29... Replace navigation animations with new effects version "0.14.5" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.5.tgz#eeded66bbeb0807f0a7f5f449e7fb2871f7ecf76" integrity sha512-1NxWK1G0gzwCOuyNV/zf4n18s6FWsiqgwkzU3P9C0Iu8AErjhstK1jUqpRwzLH8+/7hGLsrQedmn+ZbQTOrJPg== @@ -8778,6 +9132,13 @@ react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.5: dependencies: hoist-non-react-statics "^2.3.1" +react-native-safe-area-view@^0.14.6: + version "0.14.6" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" + integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA== + dependencies: + hoist-non-react-statics "^2.3.1" + react-native-safe-area-view@mikedemarais/react-native-safe-area-view: version "0.10.0" resolved "https://codeload.github.com/mikedemarais/react-native-safe-area-view/tar.gz/b67379092dd176887569465a7e41362a83698a3e" @@ -8821,7 +9182,11 @@ react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: dependencies: prop-types "^15.6.1" +<<<<<<< HEAD react-native-tcp@^3.3.0: +======= +react-native-tcp@^3.2.1: +>>>>>>> 751dba29... Replace navigation animations with new effects version "3.3.1" resolved "https://registry.yarnpkg.com/react-native-tcp/-/react-native-tcp-3.3.1.tgz#dfb35ac48356fa8b707dafe69a971feb0845d88b" integrity sha512-kySTh7oUixfoNHCNAuxjSMjGPYXkg06sgCQOzj1bVInrTNMOSQpYvlKVSSqIorHvus2yvMmYOguTgLffMe65TA== @@ -8900,6 +9265,7 @@ react-navigation-drawer@~1.4.0: dependencies: react-native-tab-view "^1.2.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD react-navigation-stack@~1.5.0: @@ -8929,6 +9295,13 @@ react-navigation-stack@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.4.0.tgz#69cdb029ea4ee5877d7e933b3117dc90bc841eb2" integrity sha512-zEe9wCA0Ot8agarYb//0nSWYW1GM+1R0tY/nydUV0EizeJ27At0EklYVWvYEuYU6C48va6cu8OPL7QD/CcJACw== +======= +"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.5", react-navigation-stack@~1.4.0: + version "2.0.0-alpha.5" + resolved "https://github.com/react-navigation/stack#67a942dd5e880574f72ce214b02730ddf286109a" + dependencies: + react-native-safe-area-view "^0.14.6" +>>>>>>> 751dba29... Replace navigation animations with new effects react-navigation-tabs@~1.1.4: version "1.1.4" @@ -9288,6 +9661,18 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" +<<<<<<< HEAD +======= +rehype-parse@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.1.tgz#a5401d7f4144d5e17cbb69be11f05a2a7ba87e27" + integrity sha512-FrGSbOzcGxIvWty1qHjKTvHT4WBTt7C6JLs65EkvFPa7ZKraSmsoDDj6al1eBxaXS1t/kiGdPYazUe58Mgflgw== + dependencies: + hast-util-from-parse5 "^5.0.0" + parse5 "^5.0.0" + xtend "^4.0.1" + +>>>>>>> 751dba29... Replace navigation animations with new effects remark-parse@^6.0.0: version "6.0.3" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" @@ -9681,6 +10066,7 @@ semver-diff@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +<<<<<<< HEAD semver@5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -9690,6 +10076,12 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +======= +semver@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" + integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== +>>>>>>> 751dba29... Replace navigation animations with new effects semver@~2.3.1: version "2.3.2" @@ -10434,9 +10826,15 @@ svg-tags@^1.0.0: integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= svgo@^1.2.2: +<<<<<<< HEAD version "1.3.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== +======= + version "1.2.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316" + integrity sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA== +>>>>>>> 751dba29... Replace navigation animations with new effects dependencies: chalk "^2.4.1" coa "^2.0.2" @@ -11083,10 +11481,23 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" +<<<<<<< HEAD vlq@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== +======= +vfile@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.1.tgz#fc3d43a1c71916034216bf65926d5ee3c64ed60c" + integrity sha512-lRHFCuC4SQBFr7Uq91oJDJxlnftoTLQ7eKIpMdubhYcVMho4781a8MWXLy3qZrZ0/STD1kRiKc0cQOHm4OkPeA== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + replace-ext "1.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" +>>>>>>> 751dba29... Replace navigation animations with new effects vm-browserify@0.0.4: version "0.0.4" From 5172e7bb9f649dff7cfe62c1cdc6573526767906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 10 Jul 2019 14:51:20 +0200 Subject: [PATCH 091/636] Fix missing borderRadius --- src/navigation/transitions/effects.js | 35 +++------------------------ 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index 0026de7fce5..d6fbbfd66ba 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -1,5 +1,6 @@ import Animated from 'react-native-reanimated'; import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; +import chroma from 'chroma-js'; import store from '../../redux/store'; import { updateTransitionProps } from '../../redux/navigation'; import { deviceUtils } from '../../utils'; @@ -87,6 +88,8 @@ export const sheetStyleInterpolator = ({ closing, layouts: { screen: { height } }, }) => { + if (!current || !closing || !height) return {}; + store.dispatch(updateTransitionProps({ effect: 'sheet', position: current, @@ -98,6 +101,7 @@ export const sheetStyleInterpolator = ({ cardStyle: { borderTopLeftRadius: sheet.borderRadiusEnd, borderTopRightRadius: sheet.borderRadiusEnd, + overflow: 'hidden', transform: [{ translateY: block([ call([], () => { @@ -143,50 +147,19 @@ export const backgroundStyleInterpolator = ({ progress: { next } }) => { ), ); - // Expand opening - const expandOpacity = interpolate(next, { inputRange: [0, 1], outputRange: [1, expand.opacityEnd], }); - // Sheet opening - - const translateY = interpolate(next, { - inputRange: [0, 1], - outputRange: [0, sheet.distanceFromTop], - }); - const sheetOpacity = interpolate(next, { inputRange: [0, 1], outputRange: [1, sheet.opacityEnd], }); - const scale = interpolate(next, { - inputRange: [0, 1], - outputRange: [1, sheet.scaleEnd], - }); - - const sheetOpeningBorderRadius = interpolate(next, { - inputRange: [0, 1], - outputRange: [isIphoneX() ? 38.5 : 0, sheet.borderRadiusScaledEnd], - }); - - const sheetClosingBorderRadius = interpolate(next, { - inputRange: [0, 1], - outputRange: [0, sheet.borderRadiusEnd], - }); - return { cardStyle: { - borderTopLeftRadius: pick(sheetOpeningBorderRadius, sheetClosingBorderRadius, 0, 0), - borderTopRightRadius: pick(sheetOpeningBorderRadius, sheetClosingBorderRadius, 0, 0), opacity: pick(sheetOpacity, sheetOpacity, expandOpacity, expandOpacity), - transform: [{ - scale: pick(scale, scale, 1, 1), - }, { - translateY: pick(translateY, translateY, 0, 0), - }], }, containerStyle: { backgroundColor: color(0, 0, 0), From 5c0f3751d5f593e1a5945b67c083b3ab83e6b6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Mon, 15 Jul 2019 16:29:28 +0200 Subject: [PATCH 092/636] Fix JS callbacks being called too often --- src/navigation/transitions/effects.js | 47 ++++++++++++++------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index d6fbbfd66ba..940d8e07c81 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -16,8 +16,6 @@ const { eq, interpolate, multiply, - lessThan, - greaterThan, set, sub, Value, @@ -27,7 +25,7 @@ const NO = 0; const EXPANDED = 1; const SHEET = 2; -const CURRENT_EFFECT = new Value(NO); +const CURRENT_EFFECT = new Value(EXPANDED); const statusBarHeight = getStatusBarHeight(true); @@ -54,28 +52,30 @@ export const expandStyleInterpolator = ({ progress: { current }, closing, }) => { + if (!current || !closing) return {}; + const value = getInterpolated(current); + + const onOpen = and(eq(closing, 0), eq(current, 0)); + const onClose = and(eq(closing, 1), eq(current, 1)); + return { containerStyle: { transform: [{ translateY: block([ - call([], () => { + cond(onOpen, call([], () => { store.dispatch(updateTransitionProps({ effect: 'expanded', position: current, })); - }), + store.dispatch(updateTransitionProps({ showingModal: true })); + })), + cond(onClose, call([], () => { + console.log('dupa'); + store.dispatch(updateTransitionProps({ showingModal: false })); + })), set(CURRENT_EFFECT, EXPANDED), set(CLOSING, closing), - cond( - eq(closing, 1), - cond(lessThan(value, 0.5), call([], () => { - store.dispatch(updateTransitionProps({ showingModal: false })); - })), - cond(greaterThan(value, 0.5), call([], () => { - store.dispatch(updateTransitionProps({ showingModal: true })); - })), - ), multiply(expand.translateY, sub(1, value)), ]), }], @@ -90,13 +90,11 @@ export const sheetStyleInterpolator = ({ }) => { if (!current || !closing || !height) return {}; - store.dispatch(updateTransitionProps({ - effect: 'sheet', - position: current, - })); - const value = getInterpolated(current); + const onOpen = and(eq(closing, 0), eq(current, 0)); + const onClose = and(eq(closing, 1), eq(current, 1)); + return { cardStyle: { borderTopLeftRadius: sheet.borderRadiusEnd, @@ -104,12 +102,17 @@ export const sheetStyleInterpolator = ({ overflow: 'hidden', transform: [{ translateY: block([ - call([], () => { + cond(onOpen, call([], () => { store.dispatch(updateTransitionProps({ effect: 'sheet', position: current, })); - }), + store.dispatch(updateTransitionProps({ showingModal: true })); + })), + cond(onClose, call([], () => { + console.log('dupa'); + store.dispatch(updateTransitionProps({ showingModal: false })); + })), set(CURRENT_EFFECT, SHEET), set(CLOSING, closing), add( @@ -122,7 +125,7 @@ export const sheetStyleInterpolator = ({ }; }; -export const backgroundStyleInterpolator = ({ progress: { next } }) => { +export const backgroundStyleInterpolator = ({ progress: { current, next } }) => { if (!next) return {}; const pick = ( From e77e809d0f683e3030c9b78535367e63f1c90f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Mon, 15 Jul 2019 16:44:25 +0200 Subject: [PATCH 093/636] Remove unused files --- src/components/send/SendAssetForm.js | 4 ++-- src/components/send/SendEmptyState.js | 4 ++-- src/navigation/transitions/effects.js | 2 -- src/navigation/transitions/index.js | 34 --------------------------- src/screens/ImportSeedPhraseSheet.js | 4 ++-- 5 files changed, 6 insertions(+), 42 deletions(-) delete mode 100644 src/navigation/transitions/index.js diff --git a/src/components/send/SendAssetForm.js b/src/components/send/SendAssetForm.js index a32c66e7291..718b777e665 100644 --- a/src/components/send/SendAssetForm.js +++ b/src/components/send/SendAssetForm.js @@ -3,7 +3,7 @@ import React, { createElement } from 'react'; import { pure } from 'recompose'; import styled from 'styled-components/primitives'; import CollectiblesSendRow from '../coin-row/CollectiblesSendRow'; -import transitions from '../../navigation/transitions'; +import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { colors, padding, position } from '../../styles'; import { deviceUtils, ethereumUtils, safeAreaInsetValues } from '../../utils'; import { SendCoinRow } from '../coin-row'; @@ -21,7 +21,7 @@ const Container = styled(Column)` `; const nftPaddingBottom = safeAreaInsetValues.bottom + 19; -const tokenPaddingBottom = transitions.sheetVerticalOffset + 19; +const tokenPaddingBottom = sheetVerticalOffset + 19; const TransactionContainer = styled(Column).attrs({ align: 'end', diff --git a/src/components/send/SendEmptyState.js b/src/components/send/SendEmptyState.js index bf40ad9323e..e52be2975a9 100644 --- a/src/components/send/SendEmptyState.js +++ b/src/components/send/SendEmptyState.js @@ -4,14 +4,14 @@ import { PasteAddressButton } from '../buttons'; import { Icon } from '../icons'; import { Centered, Column, Row } from '../layout'; import { withNeverRerender } from '../../hoc'; -import transitionConfig from '../../navigation/transitions'; +import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { colors, padding } from '../../styles'; const SendEmptyState = ({ onPressPaste }) => ( { - console.log('dupa'); store.dispatch(updateTransitionProps({ showingModal: false })); })), set(CURRENT_EFFECT, EXPANDED), @@ -110,7 +109,6 @@ export const sheetStyleInterpolator = ({ store.dispatch(updateTransitionProps({ showingModal: true })); })), cond(onClose, call([], () => { - console.log('dupa'); store.dispatch(updateTransitionProps({ showingModal: false })); })), set(CURRENT_EFFECT, SHEET), diff --git a/src/navigation/transitions/index.js b/src/navigation/transitions/index.js deleted file mode 100644 index 78b9e062cef..00000000000 --- a/src/navigation/transitions/index.js +++ /dev/null @@ -1,34 +0,0 @@ -import { get, each } from 'lodash'; -import expandedTransition from './expanded'; -import sheetTransition, { sheetVerticalOffset } from './sheet'; - -export function buildTransitions(navigation, transitions) { - return (transitionProps, prevTransitionProps) => { - const nextEffect = get(transitionProps, 'scene.descriptor.options.effect'); - const prevEffect = get(prevTransitionProps, 'scene.descriptor.options.effect'); - - let currentTransition = null; - - each(transitions, (transition, key) => { - if (nextEffect === key || prevEffect === key) { - currentTransition = transition; - } - }); - - if (typeof currentTransition === 'function') { - return currentTransition(navigation, transitionProps, prevTransitionProps); - } - - return {}; - }; -} - -export const expanded = expandedTransition; -export const sheet = sheetTransition; - -export default { - buildTransitions, - expanded, - sheet, - sheetVerticalOffset, -}; diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index cb9ef3edc20..2f8d11cf0d2 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -9,7 +9,7 @@ import { MultiLineInput } from '../components/inputs'; import { Centered, Column, Row } from '../components/layout'; import { LoadingOverlay } from '../components/modal'; import { Text } from '../components/text'; -import transitionConfig from '../navigation/transitions'; +import { sheetVerticalOffset } from '../navigation/transitions/effects'; import { borders, colors, padding } from '../styles'; const Container = styled(Column).attrs({ @@ -58,7 +58,7 @@ const ImportSeedPhraseSheet = ({ Import Date: Tue, 16 Jul 2019 10:05:10 +0200 Subject: [PATCH 094/636] Add missing 'expand' declaration --- src/screens/Routes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 9663c3ffab5..e9022a88111 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -113,11 +113,13 @@ const MainNavigator = createStackNavigator({ }, WalletConnectConfirmationModal: { navigationOptions: { + cardStyleInterpolator: expandStyleInterpolator, cardTransparent: true, effect: 'expanded', gestureResponseDistance: { vertical: deviceUtils.dimensions.height, }, + transitionSpec: expandedTransitionSpec, }, screen: WalletConnectConfirmationModal, }, From d6bd0d7a306b4d2676581285e13926c056fe966a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 16 Jul 2019 10:10:53 +0200 Subject: [PATCH 095/636] Remove leftover 'expandedTransitionSpec' --- src/screens/Routes.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index e9022a88111..3fac51d9950 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -119,7 +119,6 @@ const MainNavigator = createStackNavigator({ gestureResponseDistance: { vertical: deviceUtils.dimensions.height, }, - transitionSpec: expandedTransitionSpec, }, screen: WalletConnectConfirmationModal, }, From 0aee6dbb125aa7b86945156fd9d004fdef532e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 16 Jul 2019 10:31:32 +0200 Subject: [PATCH 096/636] Change effects to rely on specified presets --- src/navigation/transitions/effects.js | 65 +++++++++++++++++++++++++-- src/screens/Routes.js | 33 ++++---------- 2 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index df25fa32ba5..af5087fe2d1 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -1,10 +1,11 @@ -import Animated from 'react-native-reanimated'; +import Animated, { Easing } from 'react-native-reanimated'; import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; import chroma from 'chroma-js'; import store from '../../redux/store'; import { updateTransitionProps } from '../../redux/navigation'; import { deviceUtils } from '../../utils'; import { colors } from '../../styles'; +import { TransitionIOSSpec } from 'react-navigation-stack/src/TransitionConfigs/TransitionSpecs'; const { add, @@ -46,9 +47,11 @@ sheet.heightEnd = statusBarHeight + sheet.distanceFromTop; sheet.borderRadiusScaledEnd = sheet.borderRadiusEnd / sheet.scaleEnd; sheet.opacityEnd = 0.5; +export const sheetVerticalOffset = sheet.distanceFromTop + statusBarHeight; + const CLOSING = new Value(-1); -export const expandStyleInterpolator = ({ +const expandStyleInterpolator = ({ progress: { current }, closing, }) => { @@ -123,7 +126,7 @@ export const sheetStyleInterpolator = ({ }; }; -export const backgroundStyleInterpolator = ({ progress: { current, next } }) => { +const backgroundStyleInterpolator = ({ progress: { current, next } }) => { if (!next) return {}; const pick = ( @@ -167,3 +170,59 @@ export const backgroundStyleInterpolator = ({ progress: { current, next } }) => }, }; }; + +const expandTransitionSpec = { + close: { + duration: 50, + easing: Easing.in(Easing.linear), + timing: 'timing', + }, + open: { + config: SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + friction: 11, + tension: 100, + }), + timing: 'spring', + }, +}; + +const sheetTransitionSpec = { + close: { + duration: 50, + easing: Easing.in(Easing.linear), + timing: 'timing', + }, + open: { + config: SpringUtils.makeConfigFromOrigamiTensionAndFriction({ + friction: 9.8, + tension: 58, + }), + timing: 'spring', + }, +}; + +const gestureResponseDistance = { + vertical: deviceUtils.dimensions.height, +}; + +export const expandedPreset = { + cardStyleInterpolator: expandStyleInterpolator, + cardTransparent: true, + effect: 'expanded', + gestureDirection: 'vertical', + gestureResponseDistance, + transitionSpec: { close: TransitionIOSSpec, open: TransitionIOSSpec }, +}; + +export const sheetPreset = { + cardStyleInterpolator: sheetStyleInterpolator, + cardTransparent: true, + effect: 'sheet', + gestureDirection: 'vertical', + gestureResponseDistance, + transitionSpec: { close: TransitionIOSSpec, open: TransitionIOSSpec }, +}; + +export const backgroundPreset = { + cardStyleInterpolator: backgroundStyleInterpolator, +}; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 3fac51d9950..557b7b9c83d 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -22,9 +22,9 @@ import SettingsModal from './SettingsModal'; import TransactionConfirmationScreenWithData from './TransactionConfirmationScreenWithData'; import WalletScreen from './WalletScreen'; import { - expandStyleInterpolator, - sheetStyleInterpolator, - backgroundStyleInterpolator, + expandedPreset, + sheetPreset, + backgroundPreset, } from '../navigation/transitions/effects'; const onTransitionEnd = () => { @@ -71,54 +71,39 @@ const MainNavigator = createStackNavigator({ ExampleScreen, ExpandedAssetScreen: { navigationOptions: { - cardStyleInterpolator: expandStyleInterpolator, - cardTransparent: true, - effect: 'expanded', - gestureResponseDistance: { - vertical: deviceUtils.dimensions.height, - }, + ...expandedPreset, }, screen: ExpandedAssetScreenWithData, }, ImportSeedPhraseSheet: ImportSeedPhraseSheetWithData, ReceiveModal: { navigationOptions: { - cardTransparent: true, - effect: 'expanded', - gestureResponseDistance: { - vertical: deviceUtils.dimensions.height, - }, + ...expandedPreset, }, screen: ReceiveModal, }, SendSheet: { navigationOptions: { - cardStyleInterpolator: sheetStyleInterpolator, + ...sheetPreset, }, screen: SendSheetWithData, }, SettingsModal: { navigationOptions: { - cardTransparent: true, - effect: 'expanded', gesturesEnabled: false, + ...expandedPreset, }, screen: SettingsModal, }, SwipeLayout: { navigationOptions: { - cardStyleInterpolator: backgroundStyleInterpolator, + ...backgroundPreset, }, screen: SwipeStack, }, WalletConnectConfirmationModal: { navigationOptions: { - cardStyleInterpolator: expandStyleInterpolator, - cardTransparent: true, - effect: 'expanded', - gestureResponseDistance: { - vertical: deviceUtils.dimensions.height, - }, + ...expandedPreset, }, screen: WalletConnectConfirmationModal, }, From 7f614d428552e163a35d853d6373c002e28b66a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 16 Jul 2019 10:39:08 +0200 Subject: [PATCH 097/636] Bump version of react-navigation-stack to alpha.6 --- package.json | 4 ++-- yarn.lock | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7a27db3e4ff..c0aa0d6aa20 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", - "react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.5", + "react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.6", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", @@ -155,7 +155,7 @@ }, "resolutions": { "**/eslint-plugin-import": "2.14.0", - "**/react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.5", + "**/react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.6", "**/resolve": "1.8.1" }, "jest": { diff --git a/yarn.lock b/yarn.lock index 451c1192533..02b8525f2ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9268,6 +9268,7 @@ react-navigation-drawer@~1.4.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD react-navigation-stack@~1.5.0: version "1.5.5" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" @@ -9299,6 +9300,11 @@ react-navigation-stack@~1.4.0: "react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.5", react-navigation-stack@~1.4.0: version "2.0.0-alpha.5" resolved "https://github.com/react-navigation/stack#67a942dd5e880574f72ce214b02730ddf286109a" +======= +"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.6", react-navigation-stack@~1.4.0: + version "2.0.0-alpha.6" + resolved "https://github.com/react-navigation/stack#28359b3853ce234586302e98377c91638d75c585" +>>>>>>> 3a2e4076... Bump version of react-navigation-stack to alpha.6 dependencies: react-native-safe-area-view "^0.14.6" >>>>>>> 751dba29... Replace navigation animations with new effects From 37c838de108a34e0497a03b45468d4f6c75a5f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 16 Jul 2019 13:35:58 +0200 Subject: [PATCH 098/636] Update withBlurOpacity --- src/hoc/withBlurTransitionProps.js | 7 ++++++- src/navigation/transitions/effects.js | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/hoc/withBlurTransitionProps.js b/src/hoc/withBlurTransitionProps.js index e7ac1f143d1..b24af18f6a5 100644 --- a/src/hoc/withBlurTransitionProps.js +++ b/src/hoc/withBlurTransitionProps.js @@ -3,6 +3,8 @@ import { createSelector } from 'reselect'; import Animated from 'react-native-reanimated'; import withTransitionProps from './withTransitionProps'; +const { interpolate } = Animated; + const transitionPropsSelector = state => state.transitionProps; const withBlurTransitionProps = ({ @@ -11,7 +13,10 @@ const withBlurTransitionProps = ({ showingModal, position, }) => { - const blurOpacity = position; + const blurOpacity = interpolate(position, { + inputRange: [0, 0.01, 1], + outputRange: [0, 0.8, 1], + }); const showBlur = (effect === 'expanded') && (isTransitioning || showingModal); diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index af5087fe2d1..ac01e0b7505 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -183,6 +183,9 @@ const expandTransitionSpec = { tension: 100, }), timing: 'spring', + // duration: 315, + // easing: Easing.bezier(0.19, 1, 0.22, 1), + // timing: Animated.timing, }, }; @@ -198,6 +201,9 @@ const sheetTransitionSpec = { tension: 58, }), timing: 'spring', + // duration: 375, + // easing: Easing.bezier(0.19, 1, 0.22, 1), + // timing: Animated.timing, }, }; From 15e5a4881db79e23f984223caeb821efe3657dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 16 Jul 2019 15:36:35 +0200 Subject: [PATCH 099/636] Apply animation specs --- src/navigation/transitions/effects.js | 45 ++++++++------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index ac01e0b7505..c272ef6eed0 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -20,6 +20,7 @@ const { set, sub, Value, + SpringUtils, } = Animated; const NO = 0; @@ -171,40 +172,20 @@ const backgroundStyleInterpolator = ({ progress: { current, next } }) => { }; }; -const expandTransitionSpec = { - close: { - duration: 50, - easing: Easing.in(Easing.linear), - timing: 'timing', - }, - open: { - config: SpringUtils.makeConfigFromOrigamiTensionAndFriction({ - friction: 11, - tension: 100, - }), - timing: 'spring', - // duration: 315, - // easing: Easing.bezier(0.19, 1, 0.22, 1), - // timing: Animated.timing, +const expandedSpec = { + config: { + duration: 315, + easing: Easing.bezier(0.19, 1, 0.22, 1), }, + timing: 'timing', }; -const sheetTransitionSpec = { - close: { - duration: 50, - easing: Easing.in(Easing.linear), - timing: 'timing', - }, - open: { - config: SpringUtils.makeConfigFromOrigamiTensionAndFriction({ - friction: 9.8, - tension: 58, - }), - timing: 'spring', - // duration: 375, - // easing: Easing.bezier(0.19, 1, 0.22, 1), - // timing: Animated.timing, +const sheetSpec = { + config: { + duration: 375, + easing: Easing.bezier(0.19, 1, 0.22, 1), }, + timing: 'timing', }; const gestureResponseDistance = { @@ -217,7 +198,7 @@ export const expandedPreset = { effect: 'expanded', gestureDirection: 'vertical', gestureResponseDistance, - transitionSpec: { close: TransitionIOSSpec, open: TransitionIOSSpec }, + transitionSpec: { close: expandedSpec, open: expandedSpec }, }; export const sheetPreset = { @@ -226,7 +207,7 @@ export const sheetPreset = { effect: 'sheet', gestureDirection: 'vertical', gestureResponseDistance, - transitionSpec: { close: TransitionIOSSpec, open: TransitionIOSSpec }, + transitionSpec: { close: sheetSpec, open: sheetSpec }, }; export const backgroundPreset = { From 60f144ab0155892db059c17c5afa9046e6743d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 16 Jul 2019 15:42:30 +0200 Subject: [PATCH 100/636] Apply more corresponding color --- src/navigation/transitions/effects.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index c272ef6eed0..67db0a99a24 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -5,7 +5,6 @@ import store from '../../redux/store'; import { updateTransitionProps } from '../../redux/navigation'; import { deviceUtils } from '../../utils'; import { colors } from '../../styles'; -import { TransitionIOSSpec } from 'react-navigation-stack/src/TransitionConfigs/TransitionSpecs'; const { add, @@ -20,7 +19,6 @@ const { set, sub, Value, - SpringUtils, } = Animated; const NO = 0; @@ -167,7 +165,12 @@ const backgroundStyleInterpolator = ({ progress: { current, next } }) => { opacity: pick(sheetOpacity, sheetOpacity, expandOpacity, expandOpacity), }, containerStyle: { - backgroundColor: color(0, 0, 0), + backgroundColor: pick( + color(0, 0, 0), + color(0, 0, 0), + chroma(colors.blueGreyDarker).num(), + chroma(colors.blueGreyDarker).num(), + ), }, }; }; From b866c6c79ae121376ad94fb8438618d2993646d7 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Wed, 17 Jul 2019 02:58:08 -0700 Subject: [PATCH 101/636] Patch react-navigation-stack, adjust expanded state transitions Patch improves card gesture velocity handling --- ...react-navigation-stack+2.0.0-alpha.6.patch | 9 ++++++ src/navigation/transitions/effects.js | 31 ++++++++++--------- 2 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 patches/react-navigation-stack+2.0.0-alpha.6.patch diff --git a/patches/react-navigation-stack+2.0.0-alpha.6.patch b/patches/react-navigation-stack+2.0.0-alpha.6.patch new file mode 100644 index 00000000000..513de1458ab --- /dev/null +++ b/patches/react-navigation-stack+2.0.0-alpha.6.patch @@ -0,0 +1,9 @@ +diff --git a/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js b/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js +index c0dbd9c..9e97ee8 100644 +--- a/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js ++++ b/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js +@@ -1,2 +1,2 @@ +-import _extends from"@babel/runtime/helpers/extends";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _objectSpread from"@babel/runtime/helpers/objectSpread";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _classCallCheck from"@babel/runtime/helpers/classCallCheck";import _createClass from"@babel/runtime/helpers/createClass";import _possibleConstructorReturn from"@babel/runtime/helpers/possibleConstructorReturn";import _getPrototypeOf from"@babel/runtime/helpers/getPrototypeOf";import _inherits from"@babel/runtime/helpers/inherits";var _jsxFileName="/Users/christian/Library/Caches/Yarn/v3/.tmp/746e207dec8265bba0e2772ba0a15c83.28359b3853ce234586302e98377c91638d75c585.prepare/src/views/Stack/Card.tsx";import*as React from'react';import{View,I18nManager,StyleSheet,Platform}from'react-native';import Animated from'react-native-reanimated';import{PanGestureHandler,State as GestureState}from'react-native-gesture-handler';import memoize from'../../utils/memoize';import StackGestureContext from'../../utils/StackGestureContext';import PointerEventsView from'./PointerEventsView';var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.01;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=Animated.abs,add=Animated.add,block=Animated.block,call=Animated.call,cond=Animated.cond,divide=Animated.divide,eq=Animated.eq,greaterThan=Animated.greaterThan,lessThan=Animated.lessThan,max=Animated.max,min=Animated.min,multiply=Animated.multiply,neq=Animated.neq,onChange=Animated.onChange,set=Animated.set,spring=Animated.spring,sub=Animated.sub,timing=Animated.timing,startClock=Animated.startClock,stopClock=Animated.stopClock,clockRunning=Animated.clockRunning,Clock=Animated.Clock,Value=Animated.Value;var Card=function(_React$Component){_inherits(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;_classCallCheck(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=_possibleConstructorReturn(this,(_getPrototypeOf2=_getPrototypeOf(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=_slicedToArray(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=_slicedToArray(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.velocitySignum=cond(_this.velocity,divide(abs(_this.velocity),_this.velocity),0);_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,_this.velocity,_this.velocitySignum,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=_slicedToArray(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,GestureState.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=_slicedToArray(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,GestureState.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=Animated.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=Animated.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=memoize(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}_createClass(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gestureEnabled=_this$props5.gestureEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=_objectWithoutProperties(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gestureEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(StackGestureContext.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:504}},React.createElement(View,_extends({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:505}}),React.createElement(Animated.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:506}}),overlayEnabled&&overlayStyle?React.createElement(Animated.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:508}}):null,React.createElement(Animated.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:513}},React.createElement(PanGestureHandler,_extends({ref:this.gestureRef,enabled:layout.width!==0&&gestureEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:517}}),React.createElement(Animated.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:524}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(Animated.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:526}}):null,React.createElement(PointerEventsView,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:537}},children))))));}}]);return Card;}(React.Component);Card.defaultProps={overlayEnabled:Platform.OS!=='ios',shadowEnabled:true,gestureEnabled:true};export{Card as default};var styles=StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:_objectSpread({},StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); ++var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");var _interopRequireWildcard=require("@babel/runtime/helpers/interopRequireWildcard");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends"));var _objectWithoutProperties2=_interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));var _objectSpread2=_interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _possibleConstructorReturn2=_interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));var _getPrototypeOf3=_interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));var _inherits2=_interopRequireDefault(require("@babel/runtime/helpers/inherits"));var React=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _reactNativeReanimated=_interopRequireDefault(require("react-native-reanimated"));var _reactNativeGestureHandler=require("react-native-gesture-handler");var _memoize=_interopRequireDefault(require("../../utils/memoize"));var _StackGestureContext=_interopRequireDefault(require("../../utils/StackGestureContext"));var _PointerEventsView=_interopRequireDefault(require("./PointerEventsView"));var _jsxFileName="/Users/christian/Downloads/stack/src/views/Stack/Card.tsx";var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.3;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=_reactNativeReanimated.default.abs,add=_reactNativeReanimated.default.add,block=_reactNativeReanimated.default.block,call=_reactNativeReanimated.default.call,cond=_reactNativeReanimated.default.cond,divide=_reactNativeReanimated.default.divide,eq=_reactNativeReanimated.default.eq,greaterThan=_reactNativeReanimated.default.greaterThan,lessThan=_reactNativeReanimated.default.lessThan,max=_reactNativeReanimated.default.max,min=_reactNativeReanimated.default.min,multiply=_reactNativeReanimated.default.multiply,neq=_reactNativeReanimated.default.neq,onChange=_reactNativeReanimated.default.onChange,set=_reactNativeReanimated.default.set,spring=_reactNativeReanimated.default.spring,sub=_reactNativeReanimated.default.sub,timing=_reactNativeReanimated.default.timing,startClock=_reactNativeReanimated.default.startClock,stopClock=_reactNativeReanimated.default.stopClock,clockRunning=_reactNativeReanimated.default.clockRunning,Clock=_reactNativeReanimated.default.Clock,Value=_reactNativeReanimated.default.Value;var Card=function(_React$Component){(0,_inherits2.default)(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;(0,_classCallCheck2.default)(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=(0,_possibleConstructorReturn2.default)(this,(_getPrototypeOf2=(0,_getPrototypeOf3.default)(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=(0,_slicedToArray2.default)(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{velocity:_this.transitionVelocity}),(0,_objectSpread2.default)({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{frameTime:_this.frameTime}),(0,_objectSpread2.default)({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{velocity:_this.transitionVelocity}),(0,_objectSpread2.default)({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{frameTime:_this.frameTime}),(0,_objectSpread2.default)({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=(0,_slicedToArray2.default)(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.velocitySignum=cond(_this.velocity,divide(abs(_this.velocity),_this.velocity),0);_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,_this.velocitySignum,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=(0,_slicedToArray2.default)(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,_reactNativeGestureHandler.State.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=(0,_slicedToArray2.default)(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,_reactNativeGestureHandler.State.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=_reactNativeReanimated.default.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,_reactNative.I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,_reactNative.I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=_reactNativeReanimated.default.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=(0,_memoize.default)(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}(0,_createClass2.default)(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(_reactNative.I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gesturesEnabled=_this$props5.gesturesEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=(0,_objectWithoutProperties2.default)(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gesturesEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(_StackGestureContext.default.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:499}},React.createElement(_reactNative.View,(0,_extends2.default)({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:500}}),React.createElement(_reactNativeReanimated.default.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:501}}),overlayEnabled&&overlayStyle?React.createElement(_reactNativeReanimated.default.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:503}}):null,React.createElement(_reactNativeReanimated.default.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:508}},React.createElement(_reactNativeGestureHandler.PanGestureHandler,(0,_extends2.default)({ref:this.gestureRef,enabled:layout.width!==0&&gesturesEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:512}}),React.createElement(_reactNativeReanimated.default.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:519}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(_reactNativeReanimated.default.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:521}}):null,React.createElement(_PointerEventsView.default,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:532}},children))))));}}]);return Card;}(React.Component);exports.default=Card;Card.defaultProps={overlayEnabled:_reactNative.Platform.OS!=='ios',shadowEnabled:true,gesturesEnabled:true};var styles=_reactNative.StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:(0,_objectSpread2.default)({},_reactNative.StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); + //# sourceMappingURL=Card.js.map +\ No newline at end of file diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index 67db0a99a24..e0c98cb5a6c 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -17,6 +17,7 @@ const { interpolate, multiply, set, + SpringUtils, sub, Value, } = Animated; @@ -175,20 +176,22 @@ const backgroundStyleInterpolator = ({ progress: { current, next } }) => { }; }; -const expandedSpec = { - config: { - duration: 315, - easing: Easing.bezier(0.19, 1, 0.22, 1), - }, - timing: 'timing', +const expandedCloseSpec = { + config: SpringUtils.makeConfigFromBouncinessAndSpeed({ + ...SpringUtils.makeDefaultConfig(), + bounciness: 0, + speed: 20, + }), + timing: 'spring', }; -const sheetSpec = { - config: { - duration: 375, - easing: Easing.bezier(0.19, 1, 0.22, 1), - }, - timing: 'timing', +const expandedOpenSpec = { + config: SpringUtils.makeConfigFromBouncinessAndSpeed({ + ...SpringUtils.makeDefaultConfig(), + bounciness: 5, + speed: 20, + }), + timing: 'spring', }; const gestureResponseDistance = { @@ -201,7 +204,7 @@ export const expandedPreset = { effect: 'expanded', gestureDirection: 'vertical', gestureResponseDistance, - transitionSpec: { close: expandedSpec, open: expandedSpec }, + transitionSpec: { close: expandedCloseSpec, open: expandedOpenSpec }, }; export const sheetPreset = { @@ -210,7 +213,7 @@ export const sheetPreset = { effect: 'sheet', gestureDirection: 'vertical', gestureResponseDistance, - transitionSpec: { close: sheetSpec, open: sheetSpec }, + transitionSpec: { close: expandedCloseSpec, open: expandedOpenSpec }, }; export const backgroundPreset = { From 08ca98d01c74bdb4490c9233c0440bc1d5aebf56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 17 Jul 2019 15:35:10 +0200 Subject: [PATCH 102/636] Remove redundant opacity animation --- src/hoc/withBlurTransitionProps.js | 4 ++-- src/navigation/transitions/effects.js | 2 +- src/screens/WalletScreen.js | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/hoc/withBlurTransitionProps.js b/src/hoc/withBlurTransitionProps.js index b24af18f6a5..cd325ef1ae5 100644 --- a/src/hoc/withBlurTransitionProps.js +++ b/src/hoc/withBlurTransitionProps.js @@ -14,8 +14,8 @@ const withBlurTransitionProps = ({ position, }) => { const blurOpacity = interpolate(position, { - inputRange: [0, 0.01, 1], - outputRange: [0, 0.8, 1], + inputRange: [0, 0.9, 1], + outputRange: [0, 0.1, 1], }); const showBlur = (effect === 'expanded') && (isTransitioning || showingModal); diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index e0c98cb5a6c..82a3ee4a37a 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -45,7 +45,7 @@ sheet.borderRadiusEnd = 12; sheet.scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? sheet.distanceFromTop : 0)) / deviceUtils.dimensions.height); sheet.heightEnd = statusBarHeight + sheet.distanceFromTop; sheet.borderRadiusScaledEnd = sheet.borderRadiusEnd / sheet.scaleEnd; -sheet.opacityEnd = 0.5; +sheet.opacityEnd = 0.2; export const sheetVerticalOffset = sheet.distanceFromTop + statusBarHeight; diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index bd4cf42db6a..404ed0ecd3a 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -142,11 +142,7 @@ class WalletScreen extends Component { sections={sections} /> - {showBlur && ( - - - - )} + {showBlur && } ); } From bd7a9e37214872664fabd2f7264107bc21c71c81 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Wed, 17 Jul 2019 15:31:34 -0700 Subject: [PATCH 103/636] Update react-navigation-stack patch Removes velocitySignum from gesture computation --- patches/react-navigation-stack+2.0.0-alpha.6.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/react-navigation-stack+2.0.0-alpha.6.patch b/patches/react-navigation-stack+2.0.0-alpha.6.patch index 513de1458ab..a67fb7859ae 100644 --- a/patches/react-navigation-stack+2.0.0-alpha.6.patch +++ b/patches/react-navigation-stack+2.0.0-alpha.6.patch @@ -1,9 +1,9 @@ diff --git a/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js b/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js -index c0dbd9c..9e97ee8 100644 +index c0dbd9c..ebfc1e1 100644 --- a/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js +++ b/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js @@ -1,2 +1,2 @@ -import _extends from"@babel/runtime/helpers/extends";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _objectSpread from"@babel/runtime/helpers/objectSpread";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _classCallCheck from"@babel/runtime/helpers/classCallCheck";import _createClass from"@babel/runtime/helpers/createClass";import _possibleConstructorReturn from"@babel/runtime/helpers/possibleConstructorReturn";import _getPrototypeOf from"@babel/runtime/helpers/getPrototypeOf";import _inherits from"@babel/runtime/helpers/inherits";var _jsxFileName="/Users/christian/Library/Caches/Yarn/v3/.tmp/746e207dec8265bba0e2772ba0a15c83.28359b3853ce234586302e98377c91638d75c585.prepare/src/views/Stack/Card.tsx";import*as React from'react';import{View,I18nManager,StyleSheet,Platform}from'react-native';import Animated from'react-native-reanimated';import{PanGestureHandler,State as GestureState}from'react-native-gesture-handler';import memoize from'../../utils/memoize';import StackGestureContext from'../../utils/StackGestureContext';import PointerEventsView from'./PointerEventsView';var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.01;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=Animated.abs,add=Animated.add,block=Animated.block,call=Animated.call,cond=Animated.cond,divide=Animated.divide,eq=Animated.eq,greaterThan=Animated.greaterThan,lessThan=Animated.lessThan,max=Animated.max,min=Animated.min,multiply=Animated.multiply,neq=Animated.neq,onChange=Animated.onChange,set=Animated.set,spring=Animated.spring,sub=Animated.sub,timing=Animated.timing,startClock=Animated.startClock,stopClock=Animated.stopClock,clockRunning=Animated.clockRunning,Clock=Animated.Clock,Value=Animated.Value;var Card=function(_React$Component){_inherits(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;_classCallCheck(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=_possibleConstructorReturn(this,(_getPrototypeOf2=_getPrototypeOf(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=_slicedToArray(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=_slicedToArray(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.velocitySignum=cond(_this.velocity,divide(abs(_this.velocity),_this.velocity),0);_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,_this.velocity,_this.velocitySignum,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=_slicedToArray(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,GestureState.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=_slicedToArray(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,GestureState.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=Animated.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=Animated.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=memoize(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}_createClass(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gestureEnabled=_this$props5.gestureEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=_objectWithoutProperties(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gestureEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(StackGestureContext.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:504}},React.createElement(View,_extends({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:505}}),React.createElement(Animated.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:506}}),overlayEnabled&&overlayStyle?React.createElement(Animated.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:508}}):null,React.createElement(Animated.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:513}},React.createElement(PanGestureHandler,_extends({ref:this.gestureRef,enabled:layout.width!==0&&gestureEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:517}}),React.createElement(Animated.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:524}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(Animated.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:526}}):null,React.createElement(PointerEventsView,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:537}},children))))));}}]);return Card;}(React.Component);Card.defaultProps={overlayEnabled:Platform.OS!=='ios',shadowEnabled:true,gestureEnabled:true};export{Card as default};var styles=StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:_objectSpread({},StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); -+var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");var _interopRequireWildcard=require("@babel/runtime/helpers/interopRequireWildcard");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends"));var _objectWithoutProperties2=_interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));var _objectSpread2=_interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _possibleConstructorReturn2=_interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));var _getPrototypeOf3=_interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));var _inherits2=_interopRequireDefault(require("@babel/runtime/helpers/inherits"));var React=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _reactNativeReanimated=_interopRequireDefault(require("react-native-reanimated"));var _reactNativeGestureHandler=require("react-native-gesture-handler");var _memoize=_interopRequireDefault(require("../../utils/memoize"));var _StackGestureContext=_interopRequireDefault(require("../../utils/StackGestureContext"));var _PointerEventsView=_interopRequireDefault(require("./PointerEventsView"));var _jsxFileName="/Users/christian/Downloads/stack/src/views/Stack/Card.tsx";var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.3;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=_reactNativeReanimated.default.abs,add=_reactNativeReanimated.default.add,block=_reactNativeReanimated.default.block,call=_reactNativeReanimated.default.call,cond=_reactNativeReanimated.default.cond,divide=_reactNativeReanimated.default.divide,eq=_reactNativeReanimated.default.eq,greaterThan=_reactNativeReanimated.default.greaterThan,lessThan=_reactNativeReanimated.default.lessThan,max=_reactNativeReanimated.default.max,min=_reactNativeReanimated.default.min,multiply=_reactNativeReanimated.default.multiply,neq=_reactNativeReanimated.default.neq,onChange=_reactNativeReanimated.default.onChange,set=_reactNativeReanimated.default.set,spring=_reactNativeReanimated.default.spring,sub=_reactNativeReanimated.default.sub,timing=_reactNativeReanimated.default.timing,startClock=_reactNativeReanimated.default.startClock,stopClock=_reactNativeReanimated.default.stopClock,clockRunning=_reactNativeReanimated.default.clockRunning,Clock=_reactNativeReanimated.default.Clock,Value=_reactNativeReanimated.default.Value;var Card=function(_React$Component){(0,_inherits2.default)(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;(0,_classCallCheck2.default)(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=(0,_possibleConstructorReturn2.default)(this,(_getPrototypeOf2=(0,_getPrototypeOf3.default)(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=(0,_slicedToArray2.default)(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{velocity:_this.transitionVelocity}),(0,_objectSpread2.default)({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{frameTime:_this.frameTime}),(0,_objectSpread2.default)({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{velocity:_this.transitionVelocity}),(0,_objectSpread2.default)({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,(0,_objectSpread2.default)({},_this.transitionState,{frameTime:_this.frameTime}),(0,_objectSpread2.default)({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=(0,_slicedToArray2.default)(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.velocitySignum=cond(_this.velocity,divide(abs(_this.velocity),_this.velocity),0);_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,_this.velocitySignum,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=(0,_slicedToArray2.default)(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,_reactNativeGestureHandler.State.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=(0,_slicedToArray2.default)(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,_reactNativeGestureHandler.State.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=_reactNativeReanimated.default.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,_reactNative.I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,_reactNative.I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=_reactNativeReanimated.default.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=(0,_memoize.default)(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}(0,_createClass2.default)(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(_reactNative.I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gesturesEnabled=_this$props5.gesturesEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=(0,_objectWithoutProperties2.default)(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gesturesEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(_StackGestureContext.default.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:499}},React.createElement(_reactNative.View,(0,_extends2.default)({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:500}}),React.createElement(_reactNativeReanimated.default.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:501}}),overlayEnabled&&overlayStyle?React.createElement(_reactNativeReanimated.default.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:503}}):null,React.createElement(_reactNativeReanimated.default.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:508}},React.createElement(_reactNativeGestureHandler.PanGestureHandler,(0,_extends2.default)({ref:this.gestureRef,enabled:layout.width!==0&&gesturesEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:512}}),React.createElement(_reactNativeReanimated.default.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:519}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(_reactNativeReanimated.default.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:521}}):null,React.createElement(_PointerEventsView.default,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:532}},children))))));}}]);return Card;}(React.Component);exports.default=Card;Card.defaultProps={overlayEnabled:_reactNative.Platform.OS!=='ios',shadowEnabled:true,gesturesEnabled:true};var styles=_reactNative.StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:(0,_objectSpread2.default)({},_reactNative.StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); ++import _extends from"@babel/runtime/helpers/extends";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _objectSpread from"@babel/runtime/helpers/objectSpread";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _classCallCheck from"@babel/runtime/helpers/classCallCheck";import _createClass from"@babel/runtime/helpers/createClass";import _possibleConstructorReturn from"@babel/runtime/helpers/possibleConstructorReturn";import _getPrototypeOf from"@babel/runtime/helpers/getPrototypeOf";import _inherits from"@babel/runtime/helpers/inherits";var _jsxFileName="/Users/christian/Downloads/stack2/src/views/Stack/Card.tsx";import*as React from'react';import{View,I18nManager,StyleSheet,Platform}from'react-native';import Animated from'react-native-reanimated';import{PanGestureHandler,State as GestureState}from'react-native-gesture-handler';import memoize from'../../utils/memoize';import StackGestureContext from'../../utils/StackGestureContext';import PointerEventsView from'./PointerEventsView';var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.3;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=Animated.abs,add=Animated.add,block=Animated.block,call=Animated.call,cond=Animated.cond,divide=Animated.divide,eq=Animated.eq,greaterThan=Animated.greaterThan,lessThan=Animated.lessThan,max=Animated.max,min=Animated.min,multiply=Animated.multiply,neq=Animated.neq,onChange=Animated.onChange,set=Animated.set,spring=Animated.spring,sub=Animated.sub,timing=Animated.timing,startClock=Animated.startClock,stopClock=Animated.stopClock,clockRunning=Animated.clockRunning,Clock=Animated.Clock,Value=Animated.Value;var Card=function(_React$Component){_inherits(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;_classCallCheck(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=_possibleConstructorReturn(this,(_getPrototypeOf2=_getPrototypeOf(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=_slicedToArray(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=_slicedToArray(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=_slicedToArray(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,GestureState.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=_slicedToArray(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,GestureState.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=Animated.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=Animated.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=memoize(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}_createClass(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gesturesEnabled=_this$props5.gesturesEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=_objectWithoutProperties(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gesturesEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(StackGestureContext.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:494}},React.createElement(View,_extends({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:495}}),React.createElement(Animated.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:496}}),overlayEnabled&&overlayStyle?React.createElement(Animated.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:498}}):null,React.createElement(Animated.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:503}},React.createElement(PanGestureHandler,_extends({ref:this.gestureRef,enabled:layout.width!==0&&gesturesEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:507}}),React.createElement(Animated.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:514}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(Animated.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:516}}):null,React.createElement(PointerEventsView,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:527}},children))))));}}]);return Card;}(React.Component);Card.defaultProps={overlayEnabled:Platform.OS!=='ios',shadowEnabled:true,gesturesEnabled:true};export{Card as default};var styles=StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:_objectSpread({},StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); //# sourceMappingURL=Card.js.map \ No newline at end of file From e8f2d63cb41e53f9348f5b1337e40101c41de43d Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 18 Jul 2019 01:45:39 -0700 Subject: [PATCH 104/636] Adjust cardStyleInterpolators --- src/navigation/transitions/effects.js | 144 +++++++------------------- 1 file changed, 35 insertions(+), 109 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index 82a3ee4a37a..c563b3ce91d 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -40,138 +40,67 @@ expand.opacityEnd = 0.75; expand.translateY = deviceUtils.dimensions.height; const sheet = {}; -sheet.distanceFromTop = 14; -sheet.borderRadiusEnd = 12; -sheet.scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? sheet.distanceFromTop : 0)) / deviceUtils.dimensions.height); -sheet.heightEnd = statusBarHeight + sheet.distanceFromTop; -sheet.borderRadiusScaledEnd = sheet.borderRadiusEnd / sheet.scaleEnd; -sheet.opacityEnd = 0.2; +sheet.borderRadiusEnd = 16; -export const sheetVerticalOffset = sheet.distanceFromTop + statusBarHeight; +export const sheetVerticalOffset = statusBarHeight; const CLOSING = new Value(-1); const expandStyleInterpolator = ({ progress: { current }, - closing, + layouts: { screen }, }) => { - if (!current || !closing) return {}; - - const value = getInterpolated(current); + const backgroundOpacity = interpolate(current, { + inputRange: [0, 0.975], + outputRange: [0, 0.7], + extrapolate: 'clamp', + }); - const onOpen = and(eq(closing, 0), eq(current, 0)); - const onClose = and(eq(closing, 1), eq(current, 1)); + const translateY = interpolate(current, { + inputRange: [0, 1], + outputRange: [screen.height, 0], + }); return { + cardStyle: { + transform: [ + // Translation for the animation of the current card + { translateY }, + ], + }, containerStyle: { - transform: [{ - translateY: block([ - cond(onOpen, call([], () => { - store.dispatch(updateTransitionProps({ - effect: 'expanded', - position: current, - })); - store.dispatch(updateTransitionProps({ showingModal: true })); - })), - cond(onClose, call([], () => { - store.dispatch(updateTransitionProps({ showingModal: false })); - })), - set(CURRENT_EFFECT, EXPANDED), - set(CLOSING, closing), - multiply(expand.translateY, sub(1, value)), - ]), - }], + backgroundColor: color(37, 41, 46, backgroundOpacity), }, }; }; export const sheetStyleInterpolator = ({ progress: { current }, - closing, - layouts: { screen: { height } }, + layouts: { screen }, }) => { - if (!current || !closing || !height) return {}; - - const value = getInterpolated(current); - - const onOpen = and(eq(closing, 0), eq(current, 0)); - const onClose = and(eq(closing, 1), eq(current, 1)); - - return { - cardStyle: { - borderTopLeftRadius: sheet.borderRadiusEnd, - borderTopRightRadius: sheet.borderRadiusEnd, - overflow: 'hidden', - transform: [{ - translateY: block([ - cond(onOpen, call([], () => { - store.dispatch(updateTransitionProps({ - effect: 'sheet', - position: current, - })); - store.dispatch(updateTransitionProps({ showingModal: true })); - })), - cond(onClose, call([], () => { - store.dispatch(updateTransitionProps({ showingModal: false })); - })), - set(CURRENT_EFFECT, SHEET), - set(CLOSING, closing), - add( - sheet.heightEnd, - multiply(sub(height, sheet.heightEnd), sub(1, value)), - ), - ]), - }], - }, - }; -}; - -const backgroundStyleInterpolator = ({ progress: { current, next } }) => { - if (!next) return {}; - - const pick = ( - openingSheet, - closingSheet, - openingExpanded, - closingExpanded, - ) => cond( - eq(CURRENT_EFFECT, SHEET), - cond( - eq(CLOSING, 0), - openingSheet, - closingSheet, - ), - cond( - eq(CURRENT_EFFECT, EXPANDED), - cond( - eq(CLOSING, 0), - openingExpanded, - closingExpanded, - ), - ), - ); - - const expandOpacity = interpolate(next, { - inputRange: [0, 1], - outputRange: [1, expand.opacityEnd], + const backgroundOpacity = interpolate(current, { + inputRange: [0, 0.975], + outputRange: [0, 0.7], + extrapolate: 'clamp', }); - const sheetOpacity = interpolate(next, { + const translateY = interpolate(current, { inputRange: [0, 1], - outputRange: [1, sheet.opacityEnd], + outputRange: [screen.height, statusBarHeight], }); return { cardStyle: { - opacity: pick(sheetOpacity, sheetOpacity, expandOpacity, expandOpacity), + borderTopLeftRadius: sheet.borderRadiusEnd, + borderTopRightRadius: sheet.borderRadiusEnd, + overflow: 'hidden', + transform: [ + // Translation for the animation of the current card + { translateY }, + ], }, containerStyle: { - backgroundColor: pick( - color(0, 0, 0), - color(0, 0, 0), - chroma(colors.blueGreyDarker).num(), - chroma(colors.blueGreyDarker).num(), - ), + backgroundColor: color(37, 41, 46, backgroundOpacity), }, }; }; @@ -180,6 +109,7 @@ const expandedCloseSpec = { config: SpringUtils.makeConfigFromBouncinessAndSpeed({ ...SpringUtils.makeDefaultConfig(), bounciness: 0, + overshootClamping: true, speed: 20, }), timing: 'spring', @@ -215,7 +145,3 @@ export const sheetPreset = { gestureResponseDistance, transitionSpec: { close: expandedCloseSpec, open: expandedOpenSpec }, }; - -export const backgroundPreset = { - cardStyleInterpolator: backgroundStyleInterpolator, -}; From ab5eb263e0e421971385bb27f11e549dae8b6f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 19 Jul 2019 10:46:35 +0200 Subject: [PATCH 105/636] Clean up imports --- src/screens/WalletScreen.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 404ed0ecd3a..35e48285172 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -10,7 +10,6 @@ import { withProps, withState, } from 'recompact'; -import { FadeInAnimation } from '../components/animations'; import { AssetList } from '../components/asset-list'; import BlurOverlay from '../components/BlurOverlay'; import { FabWrapper } from '../components/fab'; @@ -20,6 +19,11 @@ import { ProfileHeaderButton, } from '../components/header'; import { Page } from '../components/layout'; +import { + getSmallBalanceToggle, + getOpenInvestmentCards, + getOpenFamilies, +} from '../handlers/commonStorage'; import buildWalletSectionsSelector from '../helpers/buildWalletSections'; import { withAccountData, @@ -32,13 +36,12 @@ import { withStatusBarStyle, withUniswapLiquidity, } from '../hoc'; +import { setOpenSmallBalances } from '../redux/openBalances'; +import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; +import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForPath } from '../utils'; -import { getSmallBalanceToggle, getOpenInvestmentCards, getOpenFamilies } from '../handlers/commonStorage'; -import { setOpenSmallBalances } from '../redux/openBalances'; -import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; -import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; class WalletScreen extends Component { static propTypes = { From 1707dd8716cf5e0d6bcc7c02d10f669d7480dc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 19 Jul 2019 11:38:40 +0200 Subject: [PATCH 106/636] Bump react-navigation stack to current master --- package.json | 4 +-- yarn.lock | 86 ++++++---------------------------------------------- 2 files changed, 12 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index c0aa0d6aa20..a0345726a2e 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", - "react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.6", + "react-navigation-stack": "https://github.com/react-navigation/stack#master", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", @@ -155,7 +155,7 @@ }, "resolutions": { "**/eslint-plugin-import": "2.14.0", - "**/react-navigation-stack": "https://github.com/react-navigation/stack#2.0.0-alpha.6", + "**/react-navigation-stack": "https://github.com/react-navigation/stack#master", "**/resolve": "1.8.1" }, "jest": { diff --git a/yarn.lock b/yarn.lock index 02b8525f2ec..56ae73c98c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,26 +51,6 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.4.4": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.0.tgz#6ed6a2881ad48a732c5433096d96d1b0ee5eb734" - integrity sha512-6Isr4X98pwXqHvtigw71CKgmhL1etZjPs5A67jL/w0TkLM9eqmFR40YrnJvEc1WnMZFsskjsmid8bHZyxKEAnw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/helpers" "^7.5.0" - "@babel/parser" "^7.5.0" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" - convert-source-map "^1.1.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.11" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - "@babel/generator@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" @@ -93,17 +73,6 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a" - integrity sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA== - dependencies: - "@babel/types" "^7.5.0" - jsesc "^2.5.1" - lodash "^4.17.11" - source-map "^0.5.0" - trim-right "^1.0.1" - "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -311,15 +280,6 @@ "@babel/traverse" "^7.6.0" "@babel/types" "^7.6.0" -"@babel/helpers@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.0.tgz#7f0c17666e7ed8355ed6eff643dde12fb681ddb4" - integrity sha512-EgCUEa8cNwuMrwo87l2d7i2oShi8m2Q58H7h3t4TWtqATZalJYFwfL9DulRe02f3KdqM9xmMCw3v/7Ll+EiaWg== - dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" - "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" @@ -343,11 +303,6 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== -"@babel/parser@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" - integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== - "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz#7f4cb7dee651cd380d2034847d914288467a6be4" @@ -732,13 +687,6 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.4.4": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.0.tgz#49dcbcd637099a55d3a61e590a00d6861393b1b5" - integrity sha512-2xsuyZ0R0RBFwjgae5NpXk8FcfH4qovj5cEM5VEeB7KXnKqzaisIu2HSV/mCEISolJJuR4wkViUGYujA8MH9tw== - dependencies: - regenerator-runtime "^0.13.2" - "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" @@ -789,21 +737,6 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/traverse@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.0.tgz#4216d6586854ef5c3c4592dab56ec7eb78485485" - integrity sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.0" - "@babel/types" "^7.5.0" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.11" - "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" @@ -822,15 +755,6 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" - integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== - dependencies: - esutils "^2.0.2" - lodash "^4.17.11" - to-fast-properties "^2.0.0" - "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -9123,6 +9047,7 @@ react-native-reanimated@1.1.0: resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz#ba6864055ec3a206cdd5209a293fe653ce276206" integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== +<<<<<<< HEAD react-native-safe-area-view@^0.14.1: >>>>>>> 751dba29... Replace navigation animations with new effects version "0.14.5" @@ -9133,6 +9058,9 @@ react-native-safe-area-view@^0.14.1: hoist-non-react-statics "^2.3.1" react-native-safe-area-view@^0.14.6: +======= +react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: +>>>>>>> 3984235a... Bump react-navigation stack to current master version "0.14.6" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA== @@ -9269,6 +9197,7 @@ react-navigation-drawer@~1.4.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD react-navigation-stack@~1.5.0: version "1.5.5" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" @@ -9305,6 +9234,11 @@ react-navigation-stack@~1.4.0: version "2.0.0-alpha.6" resolved "https://github.com/react-navigation/stack#28359b3853ce234586302e98377c91638d75c585" >>>>>>> 3a2e4076... Bump version of react-navigation-stack to alpha.6 +======= +"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: + version "2.0.0-alpha.6" + resolved "https://github.com/react-navigation/stack#2ddf3a4a3985047811c3c90f1d8263ea71994966" +>>>>>>> 3984235a... Bump react-navigation stack to current master dependencies: react-native-safe-area-view "^0.14.6" >>>>>>> 751dba29... Replace navigation animations with new effects From 9055beb64a5d04d61b0a50fe85782bde0e33243b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 19 Jul 2019 13:37:44 +0200 Subject: [PATCH 107/636] Change showBlur to rely only on animated values --- src/components/BlurOverlay.js | 1 + src/hoc/withBlurTransitionProps.js | 12 +--- src/navigation/transitions/effects.js | 73 +++++++++----------- src/redux/navigation.js | 9 ++- src/screens/ImportSeedPhraseSheetWithData.js | 1 - src/screens/ProfileScreen.js | 16 ++--- src/screens/Routes.js | 8 +-- src/screens/SendSheetWithData.js | 1 - src/screens/WalletScreen.js | 14 ++-- 9 files changed, 52 insertions(+), 83 deletions(-) diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index a42641356fb..a7f981fd5ce 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -22,6 +22,7 @@ const BlurOverlay = ({ translateY, }) => ( state.transitionProps; const withBlurTransitionProps = ({ - effect, isTransitioning, showingModal, position, @@ -17,13 +16,8 @@ const withBlurTransitionProps = ({ inputRange: [0, 0.9, 1], outputRange: [0, 0.1, 1], }); - - const showBlur = (effect === 'expanded') && (isTransitioning || showingModal); - - return { - blurOpacity, - showBlur: (effect === 'expanded') && (isTransitioning || blurOpacity.__getValue() > 0), - }; + const showBlur = !!(isTransitioning || showingModal); + return showBlur ? { blurOpacity } : { blurOpacity: new Value(0) }; }; const withBlurTransitionPropsSelector = createSelector( diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index c563b3ce91d..f487d7bb82d 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -1,13 +1,10 @@ -import Animated, { Easing } from 'react-native-reanimated'; -import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; -import chroma from 'chroma-js'; +import Animated from 'react-native-reanimated'; +import { getStatusBarHeight } from 'react-native-iphone-x-helper'; import store from '../../redux/store'; import { updateTransitionProps } from '../../redux/navigation'; import { deviceUtils } from '../../utils'; -import { colors } from '../../styles'; const { - add, and, block, call, @@ -15,26 +12,12 @@ const { cond, eq, interpolate, - multiply, - set, + or, SpringUtils, - sub, - Value, } = Animated; -const NO = 0; -const EXPANDED = 1; -const SHEET = 2; - -const CURRENT_EFFECT = new Value(EXPANDED); - const statusBarHeight = getStatusBarHeight(true); -const getInterpolated = value => interpolate( - value, - { inputRange: [0, 1], outputRange: [0, 1] }, -); - const expand = {}; expand.opacityEnd = 0.75; expand.translateY = deviceUtils.dimensions.height; @@ -44,16 +27,15 @@ sheet.borderRadiusEnd = 16; export const sheetVerticalOffset = statusBarHeight; -const CLOSING = new Value(-1); - const expandStyleInterpolator = ({ - progress: { current }, + closing, layouts: { screen }, + progress: { current }, }) => { const backgroundOpacity = interpolate(current, { + extrapolate: 'clamp', inputRange: [0, 0.975], outputRange: [0, 0.7], - extrapolate: 'clamp', }); const translateY = interpolate(current, { @@ -61,12 +43,16 @@ const expandStyleInterpolator = ({ outputRange: [screen.height, 0], }); + const onStart = or(and(eq(closing, 0), eq(current, 0)), and(eq(closing, 1), eq(current, 1))); + const setShowingModal = call([], () => { + store.dispatch(updateTransitionProps({ showingModal: true })); + }); + return { cardStyle: { - transform: [ - // Translation for the animation of the current card - { translateY }, - ], + opacity: block([cond(onStart, setShowingModal), 1]), + // Translation for the animation of the current card + transform: [{ translateY }], }, containerStyle: { backgroundColor: color(37, 41, 46, backgroundOpacity), @@ -74,14 +60,14 @@ const expandStyleInterpolator = ({ }; }; -export const sheetStyleInterpolator = ({ +const sheetStyleInterpolator = ({ progress: { current }, layouts: { screen }, }) => { const backgroundOpacity = interpolate(current, { + extrapolate: 'clamp', inputRange: [0, 0.975], outputRange: [0, 0.7], - extrapolate: 'clamp', }); const translateY = interpolate(current, { @@ -94,10 +80,8 @@ export const sheetStyleInterpolator = ({ borderTopLeftRadius: sheet.borderRadiusEnd, borderTopRightRadius: sheet.borderRadiusEnd, overflow: 'hidden', - transform: [ - // Translation for the animation of the current card - { translateY }, - ], + // Translation for the animation of the current card + transform: [{ translateY }], }, containerStyle: { backgroundColor: color(37, 41, 46, backgroundOpacity), @@ -105,7 +89,14 @@ export const sheetStyleInterpolator = ({ }; }; -const expandedCloseSpec = { +const backgroundInterpolator = ({ progress: { next } }) => { + const dispatch = cond(call([], () => { + store.dispatch(updateTransitionProps({ position: next })); + })); + return { cardStyle: { opacity: block([dispatch, 1]) } }; +}; + +const closeSpec = { config: SpringUtils.makeConfigFromBouncinessAndSpeed({ ...SpringUtils.makeDefaultConfig(), bounciness: 0, @@ -115,7 +106,7 @@ const expandedCloseSpec = { timing: 'spring', }; -const expandedOpenSpec = { +const openSpec = { config: SpringUtils.makeConfigFromBouncinessAndSpeed({ ...SpringUtils.makeDefaultConfig(), bounciness: 5, @@ -131,17 +122,19 @@ const gestureResponseDistance = { export const expandedPreset = { cardStyleInterpolator: expandStyleInterpolator, cardTransparent: true, - effect: 'expanded', gestureDirection: 'vertical', gestureResponseDistance, - transitionSpec: { close: expandedCloseSpec, open: expandedOpenSpec }, + transitionSpec: { close: closeSpec, open: openSpec }, }; export const sheetPreset = { cardStyleInterpolator: sheetStyleInterpolator, cardTransparent: true, - effect: 'sheet', gestureDirection: 'vertical', gestureResponseDistance, - transitionSpec: { close: expandedCloseSpec, open: expandedOpenSpec }, + transitionSpec: { close: closeSpec, open: openSpec }, +}; + +export const backgroundPreset = { + cardStyleInterpolator: backgroundInterpolator, }; diff --git a/src/redux/navigation.js b/src/redux/navigation.js index ef710950f6d..1d7fac78dfa 100644 --- a/src/redux/navigation.js +++ b/src/redux/navigation.js @@ -1,4 +1,6 @@ -import { Animated } from 'react-native'; +import Animated from 'react-native-reanimated'; + +const { Value } = Animated; // -- Constants --------------------------------------- // const UPDATE_TRANSITION_PROPS = 'navigation/UPDATE_TRANSITION_PROPS'; @@ -10,12 +12,9 @@ export const updateTransitionProps = (payload) => (dispatch) => { // -- Reducer ----------------------------------------- // const INITIAL_STATE = { transitionProps: { - effect: '', isExpanded: false, isTransitioning: false, - nextIndex: 1, - position: new Animated.Value(0), - prevIndex: 0, + position: new Value(0), }, }; diff --git a/src/screens/ImportSeedPhraseSheetWithData.js b/src/screens/ImportSeedPhraseSheetWithData.js index 0018dee9a2d..711c43840cf 100644 --- a/src/screens/ImportSeedPhraseSheetWithData.js +++ b/src/screens/ImportSeedPhraseSheetWithData.js @@ -122,7 +122,6 @@ const ImportSeedPhraseSheetWithData = compose( )(ImportSeedPhraseSheet); ImportSeedPhraseSheetWithData.navigationOptions = ({ navigation }) => ({ - effect: 'sheet', gestureResponseDistance: { vertical: deviceUtils.dimensions.height / 2, }, diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index 3dc859c9746..78b420d54ab 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -19,7 +19,6 @@ const ProfileScreen = ({ onPressBackButton, onPressSettings, requests, - showBlur, transactions, transactionsCount, }) => ( @@ -49,15 +48,11 @@ const ProfileScreen = ({ transactionsCount={transactionsCount} /> {isEmpty && } - {showBlur && ( - - - - )} + ); @@ -70,7 +65,6 @@ ProfileScreen.propTypes = { onPressBackButton: PropTypes.func, onPressSettings: PropTypes.func, requests: PropTypes.array, - showBlur: PropTypes.bool, transactions: PropTypes.array, transactionsCount: PropTypes.number, }; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 557b7b9c83d..ad0d153f85d 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -27,13 +27,9 @@ import { backgroundPreset, } from '../navigation/transitions/effects'; -const onTransitionEnd = () => { - store.dispatch(updateTransitionProps({ isTransitioning: false })); -}; +const onTransitionEnd = () => store.dispatch(updateTransitionProps({ isTransitioning: false })); -const onTransitionStart = () => { - store.dispatch(updateTransitionProps({ isTransitioning: true })); -}; +const onTransitionStart = () => store.dispatch(updateTransitionProps({ isTransitioning: true })); const SwipeStack = createMaterialTopTabNavigator({ ProfileScreen: { diff --git a/src/screens/SendSheetWithData.js b/src/screens/SendSheetWithData.js index 8b8864a8252..6ee8fd0d081 100644 --- a/src/screens/SendSheetWithData.js +++ b/src/screens/SendSheetWithData.js @@ -8,7 +8,6 @@ const SendSheetWithData = withSendComponentWithData(SendSheet, { }); SendSheetWithData.navigationOptions = ({ navigation: { state: { params } } }) => ({ - effect: 'sheet', gestureResponseDistance: { vertical: params && params.verticalGestureResponseDistance, }, diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 35e48285172..4e50e377b66 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -58,7 +58,6 @@ class WalletScreen extends Component { scrollViewTracker: PropTypes.object, sections: PropTypes.array, setSafeTimeout: PropTypes.func, - showBlur: PropTypes.bool, uniqueTokens: PropTypes.array, } @@ -90,13 +89,10 @@ class WalletScreen extends Component { const isNewIsWalletEthZero = isNewValueForPath(this.props, nextProps, 'isWalletEthZero'); const isNewLanguage = isNewValueForPath(this.props, nextProps, 'language'); const isNewSections = isNewValueForPath(this.props, nextProps, 'sections'); - const isNewShowBlur = isNewValueForPath(this.props, nextProps, 'showBlur'); const isNewTransitionProps = isNewValueForPath(this.props, nextProps, 'transitionProps'); - if (!nextProps.isFocused && !nextProps.showBlur) { - return isNewBlurOpacity - || isNewShowBlur - || isNewTransitionProps; + if (!nextProps.isFocused) { + return isNewBlurOpacity || isNewTransitionProps; } return isNewFetchingAssets @@ -107,8 +103,7 @@ class WalletScreen extends Component { || isNewCurrency || isNewBlurOpacity || isNewSections - || isNewTransitionProps - || isNewShowBlur; + || isNewTransitionProps; } render = () => { @@ -120,7 +115,6 @@ class WalletScreen extends Component { refreshAccountData, scrollViewTracker, sections, - showBlur, } = this.props; return ( @@ -145,7 +139,7 @@ class WalletScreen extends Component { sections={sections} /> - {showBlur && } + ); } From 4ea32c5b5cadff09102c061bdaf076ade421469e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 24 Jul 2019 10:46:45 +0200 Subject: [PATCH 108/636] Change status bar to light when sheet is open --- src/screens/SendSheet.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 44e9175d9b5..c2013426562 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -12,7 +12,7 @@ import { } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { Keyboard, KeyboardAvoidingView } from 'react-native'; +import { Keyboard, KeyboardAvoidingView, StatusBar } from 'react-native'; import { isIphoneX } from 'react-native-iphone-x-helper'; import { compose, withHandlers } from 'recompact'; import styled from 'styled-components/primitives'; @@ -242,6 +242,7 @@ class SendSheet extends Component { return ( + Date: Wed, 24 Jul 2019 12:33:41 +0200 Subject: [PATCH 109/636] Skip redux in blur --- src/navigation/transitions/effects.js | 6 +++++- src/screens/ProfileScreen.js | 3 ++- src/screens/WalletScreen.js | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index f487d7bb82d..a9a78f7f4d9 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -13,9 +13,13 @@ const { eq, interpolate, or, + Value, SpringUtils, } = Animated; +// eslint-disable-next-line import/no-mutable-exports +export let progressNode = new Value(0); + const statusBarHeight = getStatusBarHeight(true); const expand = {}; @@ -91,7 +95,7 @@ const sheetStyleInterpolator = ({ const backgroundInterpolator = ({ progress: { next } }) => { const dispatch = cond(call([], () => { - store.dispatch(updateTransitionProps({ position: next })); + progressNode = next; })); return { cardStyle: { opacity: block([dispatch, 1]) } }; }; diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index 78b420d54ab..a6182dab457 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -9,6 +9,7 @@ import { FlexItem, Page } from '../components/layout'; import { Icon } from '../components/icons'; import { ProfileMasthead } from '../components/profile'; import { colors, position } from '../styles'; +import { progressNode } from '../navigation/transitions/effects'; const ProfileScreen = ({ accountAddress, @@ -51,7 +52,7 @@ const ProfileScreen = ({ ); diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 4e50e377b66..55571985a05 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -42,6 +42,7 @@ import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForPath } from '../utils'; +import { progressNode } from '../navigation/transitions/effects'; class WalletScreen extends Component { static propTypes = { @@ -139,7 +140,7 @@ class WalletScreen extends Component { sections={sections} /> - + ); } From 68a34d6b76dd02202b0788b34edcdd813f114e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 24 Jul 2019 15:33:11 +0200 Subject: [PATCH 110/636] Disable shadow causing bad looking graphical glitch in settings modal --- src/components/modal/Modal.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js index a26a8130b4d..1706380ba87 100644 --- a/src/components/modal/Modal.js +++ b/src/components/modal/Modal.js @@ -17,10 +17,6 @@ const ModalElement = styled(Column)` border-radius: 12; flex-shrink: 0; height: ${({ height }) => height}; - shadow-color: ${colors.dark}; - shadow-offset: 0px 10px; - shadow-opacity: 0.6; - shadow-radius: 50; width: 100%; `; From 909b1b8e16722bab456df45d33abd30ffa812cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 25 Jul 2019 11:41:08 +0200 Subject: [PATCH 111/636] Fix modal shadows --- src/navigation/transitions/effects.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index a9a78f7f4d9..fa4514f0eb4 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -3,6 +3,7 @@ import { getStatusBarHeight } from 'react-native-iphone-x-helper'; import store from '../../redux/store'; import { updateTransitionProps } from '../../redux/navigation'; import { deviceUtils } from '../../utils'; +import { colors } from '../../styles'; const { and, @@ -55,6 +56,10 @@ const expandStyleInterpolator = ({ return { cardStyle: { opacity: block([cond(onStart, setShowingModal), 1]), + shadowColor: colors.dark, + shadowOffset: { height: 10, width: 0 }, + shadowOpacity: 0.6, + shadowRadius: 50, // Translation for the animation of the current card transform: [{ translateY }], }, @@ -124,6 +129,7 @@ const gestureResponseDistance = { }; export const expandedPreset = { + cardShadowEnabled: true, cardStyleInterpolator: expandStyleInterpolator, cardTransparent: true, gestureDirection: 'vertical', From 33ce7bebf5824ecdbbcb1c83f603d417a812e69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 25 Jul 2019 11:51:47 +0200 Subject: [PATCH 112/636] Revert change with skipping redux during blur --- src/navigation/transitions/effects.js | 5 +---- src/screens/ProfileScreen.js | 4 +--- src/screens/WalletScreen.js | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index fa4514f0eb4..86f92e25f3c 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -18,9 +18,6 @@ const { SpringUtils, } = Animated; -// eslint-disable-next-line import/no-mutable-exports -export let progressNode = new Value(0); - const statusBarHeight = getStatusBarHeight(true); const expand = {}; @@ -100,7 +97,7 @@ const sheetStyleInterpolator = ({ const backgroundInterpolator = ({ progress: { next } }) => { const dispatch = cond(call([], () => { - progressNode = next; + store.dispatch(updateTransitionProps({ position: next })); })); return { cardStyle: { opacity: block([dispatch, 1]) } }; }; diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index a6182dab457..5cec34bfa20 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -2,14 +2,12 @@ import PropTypes from 'prop-types'; import React from 'react'; import { ActivityList } from '../components/activity-list'; import AddFundsInterstitial from '../components/AddFundsInterstitial'; -import { FadeInAnimation } from '../components/animations'; import BlurOverlay from '../components/BlurOverlay'; import { BackButton, Header, HeaderButton } from '../components/header'; import { FlexItem, Page } from '../components/layout'; import { Icon } from '../components/icons'; import { ProfileMasthead } from '../components/profile'; import { colors, position } from '../styles'; -import { progressNode } from '../navigation/transitions/effects'; const ProfileScreen = ({ accountAddress, @@ -52,7 +50,7 @@ const ProfileScreen = ({ ); diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 55571985a05..4e50e377b66 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -42,7 +42,6 @@ import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForPath } from '../utils'; -import { progressNode } from '../navigation/transitions/effects'; class WalletScreen extends Component { static propTypes = { @@ -140,7 +139,7 @@ class WalletScreen extends Component { sections={sections} /> - + ); } From cdb0edd602807e33db3e529718453e9aee80821a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 25 Jul 2019 15:22:20 +0200 Subject: [PATCH 113/636] Add expanded state to transaction confirmation modal --- src/screens/Routes.js | 7 +++++- src/screens/TransactionConfirmationScreen.js | 1 - .../TransactionConfirmationScreenWithData.js | 22 +++++++++---------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index ad0d153f85d..9582922418d 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -63,8 +63,13 @@ const SwipeStack = createMaterialTopTabNavigator({ }); const MainNavigator = createStackNavigator({ - ConfirmRequest: TransactionConfirmationScreenWithData, ExampleScreen, + ConfirmRequest: { + navigationOptions: { + ...expandedPreset, + }, + screen: TransactionConfirmationScreenWithData, + }, ExpandedAssetScreen: { navigationOptions: { ...expandedPreset, diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 8549bb70da3..946e762da7a 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -24,7 +24,6 @@ const CancelButtonContainer = styled.View` const Container = styled(Column)` ${position.size('100%')} - background-color: ${colors.black}; flex: 1; `; diff --git a/src/screens/TransactionConfirmationScreenWithData.js b/src/screens/TransactionConfirmationScreenWithData.js index 50cc89ca646..7abdba366fb 100644 --- a/src/screens/TransactionConfirmationScreenWithData.js +++ b/src/screens/TransactionConfirmationScreenWithData.js @@ -28,8 +28,6 @@ class TransactionConfirmationScreenWithData extends PureComponent { } componentDidMount() { - StatusBar.setBarStyle('light-content', true); - const autoOpened = get(this.props, 'navigation.state.params.autoOpened'); if (autoOpened) { Vibration.vibrate(); @@ -140,7 +138,6 @@ class TransactionConfirmationScreenWithData extends PureComponent { } closeScreen = () => { - StatusBar.setBarStyle('dark-content', true); this.props.navigation.popToTop(); } @@ -157,14 +154,17 @@ class TransactionConfirmationScreenWithData extends PureComponent { } = this.props.navigation.state.params; return ( - + <> + + + ); } } From 09d3566bd07708f37862de484c565f456e123418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 26 Jul 2019 10:54:32 +0200 Subject: [PATCH 114/636] Apply sheet preset to import screen --- src/screens/Routes.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 9582922418d..b98dd83bc84 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -76,7 +76,12 @@ const MainNavigator = createStackNavigator({ }, screen: ExpandedAssetScreenWithData, }, - ImportSeedPhraseSheet: ImportSeedPhraseSheetWithData, + ImportSeedPhraseSheet: { + navigationOptions: { + ...sheetPreset, + }, + screen: ImportSeedPhraseSheetWithData, + }, ReceiveModal: { navigationOptions: { ...expandedPreset, From 172fc534093dd30b908071b767261db6d334e4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 26 Jul 2019 13:32:00 +0200 Subject: [PATCH 115/636] Move setting status bar styles to navigation Instead of setting it declaratively in screens, we are now setting status bar in transition callbacks to make animation more reliable. --- src/components/modal/Modal.js | 1 - src/navigation/transitions/effects.js | 11 +++++++++++ src/screens/ExpandedAssetScreen.js | 1 - src/screens/SendSheet.js | 1 - src/screens/TransactionConfirmationScreenWithData.js | 1 - 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js index 1706380ba87..88ea1cfaccd 100644 --- a/src/components/modal/Modal.js +++ b/src/components/modal/Modal.js @@ -27,7 +27,6 @@ const Modal = ({ ...props }) => ( - { + if (closing) { + StatusBar.setBarStyle('dark-content'); + } else { + StatusBar.setBarStyle('light-content'); + } +}; + export const expandedPreset = { cardShadowEnabled: true, cardStyleInterpolator: expandStyleInterpolator, cardTransparent: true, gestureDirection: 'vertical', gestureResponseDistance, + onTransitionStart, transitionSpec: { close: closeSpec, open: openSpec }, }; @@ -139,6 +149,7 @@ export const sheetPreset = { cardTransparent: true, gestureDirection: 'vertical', gestureResponseDistance, + onTransitionStart, transitionSpec: { close: closeSpec, open: openSpec }, }; diff --git a/src/screens/ExpandedAssetScreen.js b/src/screens/ExpandedAssetScreen.js index a77018d95ea..9ff925355ca 100644 --- a/src/screens/ExpandedAssetScreen.js +++ b/src/screens/ExpandedAssetScreen.js @@ -34,7 +34,6 @@ const ExpandedAssetScreen = withNeverRerender(({ css={padding(safeAreaTop, containerPadding, safeAreaBottom || safeAreaTop)} direction="column" > - {createElement(ScreenTypes[type], props)} diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index c2013426562..64ed10f8dc6 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -242,7 +242,6 @@ class SendSheet extends Component { return ( - - Date: Wed, 31 Jul 2019 17:09:32 +0200 Subject: [PATCH 116/636] Change blur behavior to work on blur intensity instead of opacity --- src/components/BlurOverlay.js | 58 +++++++++--------------------- src/hoc/withBlurTransitionProps.js | 8 ++--- src/screens/ProfileScreen.js | 8 ++--- src/screens/WalletScreen.js | 12 +++---- 4 files changed, 30 insertions(+), 56 deletions(-) diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index a7f981fd5ce..3125be2db3d 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -1,59 +1,33 @@ -import { VibrancyView } from '@react-native-community/blur'; import PropTypes from 'prop-types'; import React from 'react'; -import { StyleSheet } from 'react-native'; -import Animated from 'react-native-reanimated'; +import { StyleSheet, View } from 'react-native'; import { pure } from 'recompact'; -import { position } from '../styles'; +import Animated from 'react-native-reanimated'; +import { BlurView } from '@react-native-community/blur'; + +const { Value, multiply, cond, lessThan } = Animated; -const styles = StyleSheet.create({ - overlay: { - ...position.coverAsObject, - zIndex: 1, - }, -}); +const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); -const BlurOverlay = ({ - backgroundColor, - blurAmount, - blurType, - opacity, - translateX, - translateY, -}) => ( - - ( + + - + ); BlurOverlay.propTypes = { - backgroundColor: PropTypes.string, - blurAmount: PropTypes.number, - blurType: PropTypes.oneOf(['dark', 'light', 'xlight']).isRequired, - opacity: PropTypes.object, - translateX: PropTypes.any, - translateY: PropTypes.any, + blurType: PropTypes.oneOf(['default', 'light', 'dark']).isRequired, + intensity: PropTypes.number, }; BlurOverlay.defaultProps = { - blurAmount: 15, blurType: 'dark', - translateX: 0, - translateY: 0, + intensity: new Value(0), }; export default pure(BlurOverlay); diff --git a/src/hoc/withBlurTransitionProps.js b/src/hoc/withBlurTransitionProps.js index 0ee5c002688..6f054f4fb85 100644 --- a/src/hoc/withBlurTransitionProps.js +++ b/src/hoc/withBlurTransitionProps.js @@ -12,12 +12,12 @@ const withBlurTransitionProps = ({ showingModal, position, }) => { - const blurOpacity = interpolate(position, { - inputRange: [0, 0.9, 1], - outputRange: [0, 0.1, 1], + const blurIntensity = interpolate(position, { + inputRange: [0, 1], + outputRange: [0, 1], }); const showBlur = !!(isTransitioning || showingModal); - return showBlur ? { blurOpacity } : { blurOpacity: new Value(0) }; + return showBlur ? { blurIntensity } : { blurIntensity: new Value(0) }; }; const withBlurTransitionPropsSelector = createSelector( diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index 5cec34bfa20..8f2331018ac 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -11,7 +11,7 @@ import { colors, position } from '../styles'; const ProfileScreen = ({ accountAddress, - blurOpacity, + blurIntensity, isEmpty, nativeCurrency, navigation, @@ -48,16 +48,16 @@ const ProfileScreen = ({ /> {isEmpty && } ); ProfileScreen.propTypes = { accountAddress: PropTypes.string, - blurOpacity: PropTypes.object, + blurIntensity: PropTypes.object, isEmpty: PropTypes.bool, nativeCurrency: PropTypes.string, navigation: PropTypes.object, diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 4e50e377b66..d135246691f 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -48,7 +48,7 @@ class WalletScreen extends Component { allAssetsCount: PropTypes.number, assets: PropTypes.array, assetsTotal: PropTypes.object, - blurOpacity: PropTypes.object, + blurIntensity: PropTypes.object, initializeWallet: PropTypes.func, isEmpty: PropTypes.bool.isRequired, isFocused: PropTypes.bool, @@ -81,7 +81,7 @@ class WalletScreen extends Component { } shouldComponentUpdate = (nextProps) => { - const isNewBlurOpacity = isNewValueForPath(this.props, nextProps, 'blurOpacity'); + const isNewBlurIntensity = isNewValueForPath(this.props, nextProps, 'blurIntensity'); const isNewCurrency = isNewValueForPath(this.props, nextProps, 'nativeCurrency'); const isNewFetchingAssets = isNewValueForPath(this.props, nextProps, 'fetchingAssets'); const isNewFetchingUniqueTokens = isNewValueForPath(this.props, nextProps, 'fetchingUniqueTokens'); @@ -92,7 +92,7 @@ class WalletScreen extends Component { const isNewTransitionProps = isNewValueForPath(this.props, nextProps, 'transitionProps'); if (!nextProps.isFocused) { - return isNewBlurOpacity || isNewTransitionProps; + return isNewBlurIntensity || isNewTransitionProps; } return isNewFetchingAssets @@ -101,14 +101,14 @@ class WalletScreen extends Component { || isNewIsWalletEthZero || isNewLanguage || isNewCurrency - || isNewBlurOpacity + || isNewBlurIntensity || isNewSections || isNewTransitionProps; } render = () => { const { - blurOpacity, + blurIntensity, isEmpty, isWalletEthZero, navigation, @@ -139,7 +139,7 @@ class WalletScreen extends Component { sections={sections} /> - + ); } From 204b6dec960fb40c96d50c6d671fe07c80fea19f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Sun, 28 Jul 2019 13:28:58 -0700 Subject: [PATCH 117/636] Remove react-navigation-stack patch now that fixes are merged to master --- patches/react-navigation-stack+2.0.0-alpha.6.patch | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 patches/react-navigation-stack+2.0.0-alpha.6.patch diff --git a/patches/react-navigation-stack+2.0.0-alpha.6.patch b/patches/react-navigation-stack+2.0.0-alpha.6.patch deleted file mode 100644 index a67fb7859ae..00000000000 --- a/patches/react-navigation-stack+2.0.0-alpha.6.patch +++ /dev/null @@ -1,9 +0,0 @@ -diff --git a/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js b/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js -index c0dbd9c..ebfc1e1 100644 ---- a/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js -+++ b/node_modules/react-navigation-stack/lib/module/views/Stack/Card.js -@@ -1,2 +1,2 @@ --import _extends from"@babel/runtime/helpers/extends";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _objectSpread from"@babel/runtime/helpers/objectSpread";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _classCallCheck from"@babel/runtime/helpers/classCallCheck";import _createClass from"@babel/runtime/helpers/createClass";import _possibleConstructorReturn from"@babel/runtime/helpers/possibleConstructorReturn";import _getPrototypeOf from"@babel/runtime/helpers/getPrototypeOf";import _inherits from"@babel/runtime/helpers/inherits";var _jsxFileName="/Users/christian/Library/Caches/Yarn/v3/.tmp/746e207dec8265bba0e2772ba0a15c83.28359b3853ce234586302e98377c91638d75c585.prepare/src/views/Stack/Card.tsx";import*as React from'react';import{View,I18nManager,StyleSheet,Platform}from'react-native';import Animated from'react-native-reanimated';import{PanGestureHandler,State as GestureState}from'react-native-gesture-handler';import memoize from'../../utils/memoize';import StackGestureContext from'../../utils/StackGestureContext';import PointerEventsView from'./PointerEventsView';var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.01;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=Animated.abs,add=Animated.add,block=Animated.block,call=Animated.call,cond=Animated.cond,divide=Animated.divide,eq=Animated.eq,greaterThan=Animated.greaterThan,lessThan=Animated.lessThan,max=Animated.max,min=Animated.min,multiply=Animated.multiply,neq=Animated.neq,onChange=Animated.onChange,set=Animated.set,spring=Animated.spring,sub=Animated.sub,timing=Animated.timing,startClock=Animated.startClock,stopClock=Animated.stopClock,clockRunning=Animated.clockRunning,Clock=Animated.Clock,Value=Animated.Value;var Card=function(_React$Component){_inherits(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;_classCallCheck(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=_possibleConstructorReturn(this,(_getPrototypeOf2=_getPrototypeOf(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=_slicedToArray(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=_slicedToArray(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.velocitySignum=cond(_this.velocity,divide(abs(_this.velocity),_this.velocity),0);_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,_this.velocity,_this.velocitySignum,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=_slicedToArray(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,GestureState.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=_slicedToArray(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,GestureState.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=Animated.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=Animated.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=memoize(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}_createClass(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gestureEnabled=_this$props5.gestureEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=_objectWithoutProperties(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gestureEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(StackGestureContext.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:504}},React.createElement(View,_extends({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:505}}),React.createElement(Animated.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:506}}),overlayEnabled&&overlayStyle?React.createElement(Animated.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:508}}):null,React.createElement(Animated.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:513}},React.createElement(PanGestureHandler,_extends({ref:this.gestureRef,enabled:layout.width!==0&&gestureEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:517}}),React.createElement(Animated.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:524}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(Animated.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:526}}):null,React.createElement(PointerEventsView,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:537}},children))))));}}]);return Card;}(React.Component);Card.defaultProps={overlayEnabled:Platform.OS!=='ios',shadowEnabled:true,gestureEnabled:true};export{Card as default};var styles=StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:_objectSpread({},StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); -+import _extends from"@babel/runtime/helpers/extends";import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _objectSpread from"@babel/runtime/helpers/objectSpread";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _classCallCheck from"@babel/runtime/helpers/classCallCheck";import _createClass from"@babel/runtime/helpers/createClass";import _possibleConstructorReturn from"@babel/runtime/helpers/possibleConstructorReturn";import _getPrototypeOf from"@babel/runtime/helpers/getPrototypeOf";import _inherits from"@babel/runtime/helpers/inherits";var _jsxFileName="/Users/christian/Downloads/stack2/src/views/Stack/Card.tsx";import*as React from'react';import{View,I18nManager,StyleSheet,Platform}from'react-native';import Animated from'react-native-reanimated';import{PanGestureHandler,State as GestureState}from'react-native-gesture-handler';import memoize from'../../utils/memoize';import StackGestureContext from'../../utils/StackGestureContext';import PointerEventsView from'./PointerEventsView';var TRUE=1;var FALSE=0;var NOOP=0;var UNSET=-1;var DIRECTION_VERTICAL=-1;var DIRECTION_HORIZONTAL=1;var SWIPE_VELOCITY_IMPACT=0.3;var GESTURE_RESPONSE_DISTANCE_HORIZONTAL=50;var GESTURE_RESPONSE_DISTANCE_VERTICAL=135;var abs=Animated.abs,add=Animated.add,block=Animated.block,call=Animated.call,cond=Animated.cond,divide=Animated.divide,eq=Animated.eq,greaterThan=Animated.greaterThan,lessThan=Animated.lessThan,max=Animated.max,min=Animated.min,multiply=Animated.multiply,neq=Animated.neq,onChange=Animated.onChange,set=Animated.set,spring=Animated.spring,sub=Animated.sub,timing=Animated.timing,startClock=Animated.startClock,stopClock=Animated.stopClock,clockRunning=Animated.clockRunning,Clock=Animated.Clock,Value=Animated.Value;var Card=function(_React$Component){_inherits(Card,_React$Component);function Card(){var _getPrototypeOf2;var _this;_classCallCheck(this,Card);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this=_possibleConstructorReturn(this,(_getPrototypeOf2=_getPrototypeOf(Card)).call.apply(_getPrototypeOf2,[this].concat(args)));_this.isVisible=new Value(TRUE);_this.nextIsVisible=new Value(UNSET);_this.isClosing=new Value(FALSE);_this.isRunningAnimation=false;_this.clock=new Clock();_this.direction=new Value(_this.props.gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);_this.layout={width:new Value(_this.props.layout.width),height:new Value(_this.props.layout.height)};_this.distance=cond(eq(_this.direction,DIRECTION_VERTICAL),_this.layout.height,_this.layout.width);_this.gesture=new Value(0);_this.offset=new Value(0);_this.velocity=new Value(0);_this.gestureState=new Value(0);_this.isSwiping=new Value(FALSE);_this.isSwipeCancelled=new Value(FALSE);_this.isSwipeGesture=new Value(FALSE);_this.toValue=new Value(0);_this.frameTime=new Value(0);_this.transitionVelocity=new Value(0);_this.transitionState={position:_this.props.current,time:new Value(0),finished:new Value(FALSE)};_this.runTransition=function(isVisible){var _this$props$transitio=_this.props.transitionSpec,openingSpec=_this$props$transitio.open,closingSpec=_this$props$transitio.close;return cond(eq(_this.props.current,isVisible),NOOP,[cond(clockRunning(_this.clock),NOOP,[set(_this.toValue,isVisible),set(_this.transitionVelocity,multiply(cond(_this.distance,divide(_this.velocity,_this.distance),0),-1)),set(_this.frameTime,0),set(_this.transitionState.time,0),set(_this.transitionState.finished,FALSE),set(_this.isVisible,isVisible),startClock(_this.clock),call([_this.isVisible],function(_ref){var _ref2=_slicedToArray(_ref,1),value=_ref2[0];var onTransitionStart=_this.props.onTransitionStart;_this.isRunningAnimation=true;onTransitionStart&&onTransitionStart({closing:!value});})]),cond(eq(isVisible,1),openingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},openingSpec.config,{toValue:_this.toValue})),closingSpec.timing==='spring'?spring(_this.clock,_objectSpread({},_this.transitionState,{velocity:_this.transitionVelocity}),_objectSpread({},closingSpec.config,{toValue:_this.toValue})):timing(_this.clock,_objectSpread({},_this.transitionState,{frameTime:_this.frameTime}),_objectSpread({},closingSpec.config,{toValue:_this.toValue}))),cond(_this.transitionState.finished,[set(_this.isSwipeGesture,FALSE),set(_this.gesture,0),set(_this.velocity,0),stopClock(_this.clock),call([_this.isVisible],function(_ref3){var _ref4=_slicedToArray(_ref3,1),value=_ref4[0];var isOpen=Boolean(value);var _this$props=_this.props,onOpen=_this$props.onOpen,onClose=_this$props.onClose;_this.isRunningAnimation=false;if(isOpen){onOpen(true);}else{onClose(true);}})])]);};_this.extrapolatedPosition=add(_this.gesture,multiply(_this.velocity,SWIPE_VELOCITY_IMPACT));_this.exec=block([onChange(_this.isClosing,cond(_this.isClosing,set(_this.nextIsVisible,FALSE))),onChange(_this.nextIsVisible,cond(neq(_this.nextIsVisible,UNSET),[cond(clockRunning(_this.clock),[call([],function(){return _this.isRunningAnimation=false;}),stopClock(_this.clock)]),set(_this.gesture,0),set(_this.isVisible,_this.nextIsVisible),set(_this.nextIsVisible,UNSET)])),onChange(_this.isSwiping,call([_this.isSwiping,_this.isSwipeCancelled],function(_ref5){var _ref6=_slicedToArray(_ref5,2),isSwiping=_ref6[0],isSwipeCancelled=_ref6[1];var _this$props2=_this.props,onGestureBegin=_this$props2.onGestureBegin,onGestureEnd=_this$props2.onGestureEnd,onGestureCanceled=_this$props2.onGestureCanceled;if(isSwiping===TRUE){onGestureBegin&&onGestureBegin();}else{if(isSwipeCancelled===TRUE){onGestureCanceled&&onGestureCanceled();}else{onGestureEnd&&onGestureEnd();}}})),cond(eq(_this.gestureState,GestureState.ACTIVE),[cond(_this.isSwiping,NOOP,[set(_this.isSwipeCancelled,FALSE),set(_this.isSwiping,TRUE),set(_this.isSwipeGesture,TRUE),set(_this.offset,_this.props.current)]),set(_this.props.current,min(max(sub(_this.offset,cond(_this.distance,divide(_this.gesture,_this.distance),1)),0),1)),cond(clockRunning(_this.clock),call([_this.toValue],function(_ref7){var _ref8=_slicedToArray(_ref7,1),target=_ref8[0];_this.isRunningAnimation=false;if(target){_this.props.onOpen(false);}else{_this.props.onClose(false);}})),stopClock(_this.clock)],[set(_this.isSwipeCancelled,eq(_this.gestureState,GestureState.CANCELLED)),set(_this.isSwiping,FALSE),_this.runTransition(cond(greaterThan(abs(_this.extrapolatedPosition),divide(_this.distance,2)),cond(lessThan(cond(eq(_this.velocity,0),_this.gesture,_this.velocity),0),TRUE,FALSE),_this.isVisible))])]);_this.handleGestureEventHorizontal=Animated.event([{nativeEvent:{translationX:function translationX(x){return set(_this.gesture,multiply(x,I18nManager.isRTL?-1:1));},velocityX:function velocityX(x){return set(_this.velocity,multiply(x,I18nManager.isRTL?-1:1));},state:_this.gestureState}}]);_this.handleGestureEventVertical=Animated.event([{nativeEvent:{translationY:_this.gesture,velocityY:_this.velocity,state:_this.gestureState}}]);_this.getInterpolatedStyle=memoize(function(styleInterpolator,index,current,next,layout){return styleInterpolator({index:index,progress:{current:current,next:next},closing:_this.isClosing,layouts:{screen:layout}});});_this.gestureRef=React.createRef();return _this;}_createClass(Card,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this$props3=this.props,layout=_this$props3.layout,gestureDirection=_this$props3.gestureDirection,closing=_this$props3.closing;var width=layout.width,height=layout.height;if(width!==prevProps.layout.width){this.layout.width.setValue(width);}if(height!==prevProps.layout.height){this.layout.height.setValue(height);}if(gestureDirection!==prevProps.gestureDirection){this.direction.setValue(gestureDirection==='vertical'?DIRECTION_VERTICAL:DIRECTION_HORIZONTAL);}if(closing!==prevProps.closing){this.isClosing.setValue(closing?TRUE:FALSE);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){if(this.isRunningAnimation){this.props.onClose(false);}}},{key:"gestureActivationCriteria",value:function gestureActivationCriteria(){var _this$props4=this.props,layout=_this$props4.layout,gestureDirection=_this$props4.gestureDirection,gestureResponseDistance=_this$props4.gestureResponseDistance;var distance=gestureDirection==='vertical'?gestureResponseDistance&&gestureResponseDistance.vertical||GESTURE_RESPONSE_DISTANCE_VERTICAL:gestureResponseDistance&&gestureResponseDistance.horizontal||GESTURE_RESPONSE_DISTANCE_HORIZONTAL;if(gestureDirection==='vertical'){return{maxDeltaX:15,minOffsetY:5,hitSlop:{bottom:-layout.height+distance}};}else{var hitSlop=-layout.width+distance;if(I18nManager.isRTL){return{minOffsetX:-5,maxDeltaY:20,hitSlop:{left:hitSlop}};}else{return{minOffsetX:5,maxDeltaY:20,hitSlop:{right:hitSlop}};}}}},{key:"render",value:function render(){var _this$props5=this.props,index=_this$props5.index,active=_this$props5.active,transparent=_this$props5.transparent,layout=_this$props5.layout,current=_this$props5.current,next=_this$props5.next,overlayEnabled=_this$props5.overlayEnabled,shadowEnabled=_this$props5.shadowEnabled,gesturesEnabled=_this$props5.gesturesEnabled,gestureDirection=_this$props5.gestureDirection,children=_this$props5.children,styleInterpolator=_this$props5.styleInterpolator,customContainerStyle=_this$props5.containerStyle,contentStyle=_this$props5.contentStyle,rest=_objectWithoutProperties(_this$props5,["index","active","transparent","layout","current","next","overlayEnabled","shadowEnabled","gesturesEnabled","gestureDirection","children","styleInterpolator","containerStyle","contentStyle"]);var _this$getInterpolated=this.getInterpolatedStyle(styleInterpolator,index,current,next,layout),containerStyle=_this$getInterpolated.containerStyle,cardStyle=_this$getInterpolated.cardStyle,overlayStyle=_this$getInterpolated.overlayStyle,shadowStyle=_this$getInterpolated.shadowStyle;var handleGestureEvent=gestureDirection==='vertical'?this.handleGestureEventVertical:this.handleGestureEventHorizontal;return React.createElement(StackGestureContext.Provider,{value:this.gestureRef,__source:{fileName:_jsxFileName,lineNumber:494}},React.createElement(View,_extends({pointerEvents:"box-none"},rest,{__source:{fileName:_jsxFileName,lineNumber:495}}),React.createElement(Animated.Code,{exec:this.exec,__source:{fileName:_jsxFileName,lineNumber:496}}),overlayEnabled&&overlayStyle?React.createElement(Animated.View,{pointerEvents:"none",style:[styles.overlay,overlayStyle],__source:{fileName:_jsxFileName,lineNumber:498}}):null,React.createElement(Animated.View,{style:[styles.container,containerStyle,customContainerStyle],pointerEvents:"box-none",__source:{fileName:_jsxFileName,lineNumber:503}},React.createElement(PanGestureHandler,_extends({ref:this.gestureRef,enabled:layout.width!==0&&gesturesEnabled,onGestureEvent:handleGestureEvent,onHandlerStateChange:handleGestureEvent},this.gestureActivationCriteria(),{__source:{fileName:_jsxFileName,lineNumber:507}}),React.createElement(Animated.View,{style:[styles.container,cardStyle],__source:{fileName:_jsxFileName,lineNumber:514}},shadowEnabled&&shadowStyle&&!transparent?React.createElement(Animated.View,{style:[styles.shadow,gestureDirection==='horizontal'?styles.shadowHorizontal:styles.shadowVertical,shadowStyle],pointerEvents:"none",__source:{fileName:_jsxFileName,lineNumber:516}}):null,React.createElement(PointerEventsView,{active:active,progress:this.props.current,style:[styles.content,transparent?styles.transparent:styles.opaque,contentStyle],__source:{fileName:_jsxFileName,lineNumber:527}},children))))));}}]);return Card;}(React.Component);Card.defaultProps={overlayEnabled:Platform.OS!=='ios',shadowEnabled:true,gesturesEnabled:true};export{Card as default};var styles=StyleSheet.create({container:{flex:1},content:{flex:1,overflow:'hidden'},overlay:_objectSpread({},StyleSheet.absoluteFillObject,{backgroundColor:'#000'}),shadow:{position:'absolute',backgroundColor:'#fff',shadowRadius:5,shadowColor:'#000',shadowOpacity:0.3},shadowHorizontal:{top:0,left:0,bottom:0,width:3,shadowOffset:{width:-1,height:1}},shadowVertical:{top:0,left:0,right:0,height:3,shadowOffset:{width:1,height:-1}},transparent:{backgroundColor:'transparent'},opaque:{backgroundColor:'#eee'}}); - //# sourceMappingURL=Card.js.map -\ No newline at end of file From 794fc86174dc6d3f67130314721a980cda779bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 10:45:58 +0200 Subject: [PATCH 118/636] Update react-navigation-stack to alpha.7 --- package.json | 2 +- yarn.lock | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a0345726a2e..9167f025671 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", - "react-navigation-stack": "https://github.com/react-navigation/stack#master", + "react-navigation-stack": "^2.0.0-alpha.7", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", diff --git a/yarn.lock b/yarn.lock index 56ae73c98c5..c11c3d1e97e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9198,6 +9198,7 @@ react-navigation-drawer@~1.4.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD react-navigation-stack@~1.5.0: version "1.5.5" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" @@ -9235,6 +9236,15 @@ react-navigation-stack@~1.4.0: resolved "https://github.com/react-navigation/stack#28359b3853ce234586302e98377c91638d75c585" >>>>>>> 3a2e4076... Bump version of react-navigation-stack to alpha.6 ======= +======= +react-navigation-stack@^2.0.0-alpha.7: + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.7.tgz#1534e31e0f9cfc9c3340f0d752e5c992a1961a89" + integrity sha512-9ltkEY+ayNRBnOMRRC7UCTAS6wqdH15Tg8hE004sYLvsZw3HwwTj2il0C5BWzDq+IwItj+LI+S9tDdHUxF1a1Q== + dependencies: + react-native-safe-area-view "^0.14.6" + +>>>>>>> 996fc4e7... Update react-navigation-stack to alpha.7 "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: version "2.0.0-alpha.6" resolved "https://github.com/react-navigation/stack#2ddf3a4a3985047811c3c90f1d8263ea71994966" From b7668f56163c24a64f556ef1bacc31c65de2ccfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 10:46:31 +0200 Subject: [PATCH 119/636] Add patch chaning keyboard handling behavior --- ...react-navigation-stack+2.0.0-alpha.7.patch | 29 +++++++++++++++++++ src/components/BlurOverlay.js | 7 ++++- src/screens/Routes.js | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 patches/react-navigation-stack+2.0.0-alpha.7.patch diff --git a/patches/react-navigation-stack+2.0.0-alpha.7.patch b/patches/react-navigation-stack+2.0.0-alpha.7.patch new file mode 100644 index 00000000000..d00984676b6 --- /dev/null +++ b/patches/react-navigation-stack+2.0.0-alpha.7.patch @@ -0,0 +1,29 @@ +diff --git a/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx b/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx +index 01721bb..571fc5d 100644 +--- a/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx ++++ b/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx +@@ -15,10 +15,13 @@ export default class KeyboardManager extends React.Component { + private previouslyFocusedTextInput: number | null = null; + + private handlePageChangeStart = () => { +- const input = TextInput.State.currentlyFocusedField(); ++ const input = TextInput.State.currentlyFocusedField() ++ || this.previouslyFocusedTextInput; + + // When a page change begins, blur the currently focused input +- TextInput.State.blurTextInput(input); ++ if (input !== null) { ++ TextInput.State.blurTextInput(input); ++ } + + // Store the id of this input so we can refocus it if change was cancelled + this.previouslyFocusedTextInput = input; +@@ -38,8 +41,6 @@ export default class KeyboardManager extends React.Component { + if (input) { + TextInput.State.focusTextInput(input); + } +- +- this.previouslyFocusedTextInput = null; + }; + + render() { \ No newline at end of file diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index 3125be2db3d..adb1a16f440 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -5,7 +5,12 @@ import { pure } from 'recompact'; import Animated from 'react-native-reanimated'; import { BlurView } from '@react-native-community/blur'; -const { Value, multiply, cond, lessThan } = Animated; +const { + Value, + multiply, + cond, + lessThan, +} = Animated; const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index b98dd83bc84..8494eebceb3 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -118,6 +118,7 @@ const MainNavigator = createStackNavigator({ onTransitionEnd, onTransitionStart, }, + disableKeyboardHandling: true, headerMode: 'none', initialRouteName: 'SwipeLayout', mode: 'modal', From bb0859ead9e49c9b1c427ac2b633e8e560b331b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 11:14:50 +0200 Subject: [PATCH 120/636] Code cleanup --- src/components/modal/Modal.js | 1 - src/navigation/transitions/effects.js | 1 - src/redux/navigation.js | 1 - src/screens/ExpandedAssetScreen.js | 1 - src/screens/SendSheet.js | 2 +- 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js index 88ea1cfaccd..22c1a563b0e 100644 --- a/src/components/modal/Modal.js +++ b/src/components/modal/Modal.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { StatusBar } from 'react-native'; import styled from 'styled-components'; import { colors, padding } from '../../styles'; import { deviceUtils } from '../../utils'; diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index b79c30e788f..7de726c7cb6 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -15,7 +15,6 @@ const { eq, interpolate, or, - Value, SpringUtils, } = Animated; diff --git a/src/redux/navigation.js b/src/redux/navigation.js index 1d7fac78dfa..099645d316e 100644 --- a/src/redux/navigation.js +++ b/src/redux/navigation.js @@ -12,7 +12,6 @@ export const updateTransitionProps = (payload) => (dispatch) => { // -- Reducer ----------------------------------------- // const INITIAL_STATE = { transitionProps: { - isExpanded: false, isTransitioning: false, position: new Value(0), }, diff --git a/src/screens/ExpandedAssetScreen.js b/src/screens/ExpandedAssetScreen.js index 9ff925355ca..b65d767a187 100644 --- a/src/screens/ExpandedAssetScreen.js +++ b/src/screens/ExpandedAssetScreen.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import React, { createElement } from 'react'; -import { StatusBar } from 'react-native'; import { InvestmentExpandedState, TokenExpandedState, diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 64ed10f8dc6..44e9175d9b5 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -12,7 +12,7 @@ import { } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { Keyboard, KeyboardAvoidingView, StatusBar } from 'react-native'; +import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { isIphoneX } from 'react-native-iphone-x-helper'; import { compose, withHandlers } from 'recompact'; import styled from 'styled-components/primitives'; From ffd85a68d462c955720cceef1cbf197d9a4047a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 11:18:00 +0200 Subject: [PATCH 121/636] Update onTransitionStart to reflect alpha.7 API changes --- src/navigation/transitions/effects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index 7de726c7cb6..bb384811d4b 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -125,8 +125,8 @@ const gestureResponseDistance = { vertical: deviceUtils.dimensions.height, }; -const onTransitionStart = closing => { - if (closing) { +const onTransitionStart = props => { + if (props.closing) { StatusBar.setBarStyle('dark-content'); } else { StatusBar.setBarStyle('light-content'); From 6945faa915d265affbbb90a0a213e63459d9ab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 11:56:56 +0200 Subject: [PATCH 122/636] Fix merge mistakes --- src/hoc/withDataInit.js | 2 +- src/screens/Routes.js | 2 +- yarn.lock | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 5bdc681b1d5..353db8c723d 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -10,7 +10,7 @@ import { dataLoadState, dataInit, } from '../redux/data'; -import { clearIsWalletEmpty, loadIsWalletEmpty } from '../redux/isWalletEmpty'; +import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 8494eebceb3..289d9fa43f3 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -63,13 +63,13 @@ const SwipeStack = createMaterialTopTabNavigator({ }); const MainNavigator = createStackNavigator({ - ExampleScreen, ConfirmRequest: { navigationOptions: { ...expandedPreset, }, screen: TransactionConfirmationScreenWithData, }, + ExampleScreen, ExpandedAssetScreen: { navigationOptions: { ...expandedPreset, diff --git a/yarn.lock b/yarn.lock index c11c3d1e97e..d5e19e7dd17 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9034,6 +9034,7 @@ react-native-redash@^7.2.1: parse-svg-path "^0.1.2" use-memo-one "^1.1.1" +<<<<<<< HEAD <<<<<<< HEAD react-native-safe-area-view@^0.14.1: version "0.14.8" @@ -9061,6 +9062,9 @@ react-native-safe-area-view@^0.14.6: ======= react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: >>>>>>> 3984235a... Bump react-navigation stack to current master +======= +react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: +>>>>>>> e162a3d6... Fix merge mistakes version "0.14.6" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA== From 279d696ae1de4d8192d598f48b1c523d6c6cf5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 13:37:42 +0200 Subject: [PATCH 123/636] Fix bug with settings and back icons on ProfileScreen displaying over blur --- src/components/BlurOverlay.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index adb1a16f440..7906c0b80ef 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -15,7 +15,13 @@ const { const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); const BlurOverlay = ({ blurType, intensity }) => ( - + Date: Thu, 1 Aug 2019 13:38:36 +0200 Subject: [PATCH 124/636] Remove unnecessary stack option --- src/screens/Routes.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 289d9fa43f3..45b9dabb99b 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -118,7 +118,6 @@ const MainNavigator = createStackNavigator({ onTransitionEnd, onTransitionStart, }, - disableKeyboardHandling: true, headerMode: 'none', initialRouteName: 'SwipeLayout', mode: 'modal', From 95c17a0dc0256b87f3668f09d8c92e95be28561a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 1 Aug 2019 16:10:37 +0200 Subject: [PATCH 125/636] Avoid bad looking blur when reaching lower range of intensity values --- src/components/BlurOverlay.js | 42 ++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index 7906c0b80ef..e5852f0c0ca 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -8,28 +8,34 @@ import { BlurView } from '@react-native-community/blur'; const { Value, multiply, - cond, - lessThan, + interpolate, + min, + add, } = Animated; const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); -const BlurOverlay = ({ blurType, intensity }) => ( - - - -); +const BlurOverlay = ({ blurType, intensity }) => { + const opacity = interpolate(intensity, { inputRange: [0, 0.3, 1], outputRange: [0, 1, 1] }); + const blurAmount = min(add(multiply(intensity, 15), 5), 100); + + return ( + + + + ); +}; BlurOverlay.propTypes = { blurType: PropTypes.oneOf(['default', 'light', 'dark']).isRequired, From 73177a7fd60eb27d36f8033241bedcf1de768df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 13 Aug 2019 14:11:30 +0200 Subject: [PATCH 126/636] Change react-native-blur version to fork --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9167f025671..100a21f29c3 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.5.0", - "@react-native-community/blur": "^3.3.1", + "@react-native-community/blur": "willcosgrove/react-native-blur#animate", "@react-native-community/masked-view": "^0.1.1", "@react-native-community/netinfo": "^3.2.1", "@segment/analytics-react-native": "^1.0.1", From 474712dd35160bfe50c08ea62f059fab05738731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Wed, 21 Aug 2019 16:21:55 +0200 Subject: [PATCH 127/636] Remove blur radius animation --- package.json | 2 +- src/components/BlurOverlay.js | 11 ++++++++--- yarn.lock | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 100a21f29c3..98b1b74389e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.5.0", - "@react-native-community/blur": "willcosgrove/react-native-blur#animate", + "@react-native-community/blur": "@react-native-community/blur", "@react-native-community/masked-view": "^0.1.1", "@react-native-community/netinfo": "^3.2.1", "@segment/analytics-react-native": "^1.0.1", diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index e5852f0c0ca..7ad2defa94f 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -16,8 +16,13 @@ const { const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); const BlurOverlay = ({ blurType, intensity }) => { - const opacity = interpolate(intensity, { inputRange: [0, 0.3, 1], outputRange: [0, 1, 1] }); - const blurAmount = min(add(multiply(intensity, 15), 5), 100); + const opacity = interpolate( + intensity, + { + inputRange: [0, 0.1, 1], + outputRange: [0, 0, 1], + }, + ); return ( { > diff --git a/yarn.lock b/yarn.lock index d5e19e7dd17..226c13982a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1096,7 +1096,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.5.0.tgz#647ffcd832272068b0be57332e08d73036ed391f" integrity sha512-2yE4RzQ5IL+UTPhuMY0ykNRKHf1m90jOnmp8fcDPUun5U97cXlorjI4p66ovDgF0FuOv8ZpiUKvunGy3qqBxwg== -"@react-native-community/blur@^3.3.1": +"@react-native-community/blur@@react-native-community/blur": version "3.3.1" resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.3.1.tgz#bc9ecd6d85d89739d8180138716535ac7cfa4680" integrity sha512-UfH2ut/l4GpZHeq/TGx3BrmyXSCSBBwBCVx1DhPodP3k959zJ2ajgXa3PiU/qjutftTUw6KH9Frsh2U0ax9dMQ== From e90e77c5a414772be50bbfddec0127b369297b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 22 Aug 2019 12:29:48 +0200 Subject: [PATCH 128/636] Add better keyboard control via onTransition callbacks --- src/navigation/transitions/effects.js | 2 +- src/screens/Routes.js | 6 ++++++ src/screens/restoreKeyboard.js | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/screens/restoreKeyboard.js diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index bb384811d4b..e1d2054f8f3 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -125,7 +125,7 @@ const gestureResponseDistance = { vertical: deviceUtils.dimensions.height, }; -const onTransitionStart = props => { +export const onTransitionStart = props => { if (props.closing) { StatusBar.setBarStyle('dark-content'); } else { diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 45b9dabb99b..9dd81a6148b 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -25,7 +25,9 @@ import { expandedPreset, sheetPreset, backgroundPreset, + onTransitionStart as onTransitionStartEffect, } from '../navigation/transitions/effects'; +import restoreKeyboard from './restoreKeyboard'; const onTransitionEnd = () => store.dispatch(updateTransitionProps({ isTransitioning: false })); @@ -91,6 +93,10 @@ const MainNavigator = createStackNavigator({ SendSheet: { navigationOptions: { ...sheetPreset, + onTransitionStart: props => { + onTransitionStartEffect(props); + restoreKeyboard(); + }, }, screen: SendSheetWithData, }, diff --git a/src/screens/restoreKeyboard.js b/src/screens/restoreKeyboard.js new file mode 100644 index 00000000000..6d8f16e33e7 --- /dev/null +++ b/src/screens/restoreKeyboard.js @@ -0,0 +1,16 @@ +import { TextInput } from 'react-native'; + +let input = null; + +const restoreKeyboard = () => { + const currentInput = TextInput.State.currentlyFocusedField(); + if (!currentInput && input) { + TextInput.State.focusTextInput(input); + } + + if (currentInput) { + input = currentInput; + } +}; + +export default restoreKeyboard; From 105ca46a5d5711a260cd6feb87a5791b025a4517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Thu, 22 Aug 2019 13:42:45 +0200 Subject: [PATCH 129/636] Remove useless patch-package --- ...react-navigation-stack+2.0.0-alpha.7.patch | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 patches/react-navigation-stack+2.0.0-alpha.7.patch diff --git a/patches/react-navigation-stack+2.0.0-alpha.7.patch b/patches/react-navigation-stack+2.0.0-alpha.7.patch deleted file mode 100644 index d00984676b6..00000000000 --- a/patches/react-navigation-stack+2.0.0-alpha.7.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx b/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx -index 01721bb..571fc5d 100644 ---- a/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx -+++ b/node_modules/react-navigation-stack/src/views/KeyboardManager.tsx -@@ -15,10 +15,13 @@ export default class KeyboardManager extends React.Component { - private previouslyFocusedTextInput: number | null = null; - - private handlePageChangeStart = () => { -- const input = TextInput.State.currentlyFocusedField(); -+ const input = TextInput.State.currentlyFocusedField() -+ || this.previouslyFocusedTextInput; - - // When a page change begins, blur the currently focused input -- TextInput.State.blurTextInput(input); -+ if (input !== null) { -+ TextInput.State.blurTextInput(input); -+ } - - // Store the id of this input so we can refocus it if change was cancelled - this.previouslyFocusedTextInput = input; -@@ -38,8 +41,6 @@ export default class KeyboardManager extends React.Component { - if (input) { - TextInput.State.focusTextInput(input); - } -- -- this.previouslyFocusedTextInput = null; - }; - - render() { \ No newline at end of file From 6977baa1cd1b17598aa0113ee0f4fd3a001e0e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 23 Aug 2019 13:22:32 +0200 Subject: [PATCH 130/636] Bump react-navigation-stack version to alpha.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 98b1b74389e..326d7b737c3 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", - "react-navigation-stack": "^2.0.0-alpha.7", + "react-navigation-stack": "^2.0.0-alpha.9", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", From 62c8f849570ed3c104b747434e90fcfe78f32483 Mon Sep 17 00:00:00 2001 From: osdnk Date: Mon, 22 Apr 2019 17:06:50 +0200 Subject: [PATCH 131/636] WIP: initial skeleton --- src/components/GestureBlocker.js | 32 +++ src/components/coin-row/BalanceCoinRow.js | 4 +- src/components/fab/ExchangeFab.js | 44 ++++ src/components/fab/FabWrapper.js | 4 +- src/components/modal/Modal.js | 8 +- src/components/modal/ModalHeader.js | 18 +- src/hoc/withBlockedHorizontalSwipe.js | 15 ++ src/hoc/withBlockedVerticalSwipe.js | 15 ++ src/navigation/transitions/expanded.js | 2 + src/navigation/transitions/horizontalSwipe.js | 241 ++++++++++++++++++ src/screens/CurrencySelectModal.js | 122 +++++++++ src/screens/ExchangeModal.js | 197 ++++++++++++++ src/screens/Routes.js | 41 +++ src/screens/SendSheet.js | 3 +- 14 files changed, 734 insertions(+), 12 deletions(-) create mode 100644 src/components/GestureBlocker.js create mode 100644 src/components/fab/ExchangeFab.js create mode 100644 src/hoc/withBlockedHorizontalSwipe.js create mode 100644 src/hoc/withBlockedVerticalSwipe.js create mode 100644 src/navigation/transitions/horizontalSwipe.js create mode 100644 src/screens/CurrencySelectModal.js create mode 100644 src/screens/ExchangeModal.js diff --git a/src/components/GestureBlocker.js b/src/components/GestureBlocker.js new file mode 100644 index 00000000000..ad5dfaf8611 --- /dev/null +++ b/src/components/GestureBlocker.js @@ -0,0 +1,32 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { PanGestureHandler } from 'react-native-gesture-handler'; +import { StyleSheet, View } from 'react-native'; +import { deviceUtils } from '../utils'; + +const { height } = deviceUtils.dimensions; + +const GestureBlocker = ({ type }) => ( + + + + + +); + +GestureBlocker.propTypes = { + type: PropTypes.string, +} + +export default GestureBlocker; diff --git a/src/components/coin-row/BalanceCoinRow.js b/src/components/coin-row/BalanceCoinRow.js index 888d331b77b..37405145ba3 100644 --- a/src/components/coin-row/BalanceCoinRow.js +++ b/src/components/coin-row/BalanceCoinRow.js @@ -69,8 +69,8 @@ const BalanceCoinRow = ({ onPressSend, openSmallBalances, ...props -}) => ( - +}) => console.log(item, props) || ( + ( + + + +); + +ExchangeFab.propTypes = { + disabled: PropTypes.bool, + onPress: PropTypes.func, +}; + +export default compose( + pure, + withNavigation, + withHandlers({ + onPress: ({ navigation }) => () => { + navigation.navigate('ExchangeModal'); + }, + }), + onlyUpdateForKeys(['disabled']), +)(ExchangeFab); diff --git a/src/components/fab/FabWrapper.js b/src/components/fab/FabWrapper.js index 72a9798cf73..9c7f19777ba 100644 --- a/src/components/fab/FabWrapper.js +++ b/src/components/fab/FabWrapper.js @@ -4,6 +4,7 @@ import { onlyUpdateForKeys } from 'recompact'; import { safeAreaInsetValues } from '../../utils'; import { FlexItem, RowWithMargins } from '../layout'; import SendFab from './SendFab'; +import ExchangeFab from './ExchangeFab'; const bottomPosition = 21 + safeAreaInsetValues.bottom; @@ -26,7 +27,6 @@ const FabWrapper = enhance(({ `} direction="row-reverse" margin={12} - marginKey="left" > {fabs.map(fab => createElement(fab, props))} @@ -43,7 +43,7 @@ FabWrapper.propTypes = { }; FabWrapper.defaultProps = { - fabs: [SendFab], + fabs: [ExchangeFab, SendFab], }; FabWrapper.bottomPosition = bottomPosition; diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js index 22c1a563b0e..f958830cbd1 100644 --- a/src/components/modal/Modal.js +++ b/src/components/modal/Modal.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { StatusBar, View } from 'react-native'; import styled from 'styled-components'; import { colors, padding } from '../../styles'; import { deviceUtils } from '../../utils'; @@ -7,7 +8,6 @@ import { Centered, Column } from '../layout'; import TouchableBackdrop from '../TouchableBackdrop'; const Container = styled(Centered)` - ${padding(15)}; height: 100%; `; @@ -23,9 +23,11 @@ const Modal = ({ height, onCloseModal, statusBarStyle, + containerPadding, ...props }) => ( - + + ( @@ -51,11 +52,13 @@ const ModalHeader = ({ {title} - + {showDoneButton && ( + + )} ); @@ -63,9 +66,14 @@ ModalHeader.propTypes = { onPressBack: PropTypes.func, onPressClose: PropTypes.func, showBackButton: PropTypes.bool, + showDoneButton: PropTypes.bool, title: PropTypes.string, }; +ModalHeader.defaultProps = { + showDoneButton: true, +}; + ModalHeader.height = ModalHeaderHeight; export default ModalHeader; diff --git a/src/hoc/withBlockedHorizontalSwipe.js b/src/hoc/withBlockedHorizontalSwipe.js new file mode 100644 index 00000000000..0098a72c17a --- /dev/null +++ b/src/hoc/withBlockedHorizontalSwipe.js @@ -0,0 +1,15 @@ +/* eslint-disable react/display-name */ +import { PanGestureHandler } from 'react-native-gesture-handler'; +import React from 'react'; +import { Animated } from 'react-native'; + +export default (InnerComponent) => (props) => ( + + + + + +); diff --git a/src/hoc/withBlockedVerticalSwipe.js b/src/hoc/withBlockedVerticalSwipe.js new file mode 100644 index 00000000000..1fc98dadf72 --- /dev/null +++ b/src/hoc/withBlockedVerticalSwipe.js @@ -0,0 +1,15 @@ +/* eslint-disable react/display-name */ +import { PanGestureHandler } from 'react-native-gesture-handler'; +import React from 'react'; +import { Animated } from 'react-native'; + +export default (InnerComponent) => (props) => ( + + + + + +); diff --git a/src/navigation/transitions/expanded.js b/src/navigation/transitions/expanded.js index 26e7c16d40f..573c4958c77 100644 --- a/src/navigation/transitions/expanded.js +++ b/src/navigation/transitions/expanded.js @@ -50,6 +50,7 @@ export default function expanded(navigation, transitionProps, prevTransitionProp }); return { + backgroundColor: 'transparent', opacity, }; } @@ -61,6 +62,7 @@ export default function expanded(navigation, transitionProps, prevTransitionProp }); return { + backgroundColor: 'transparent', transform: [{ translateY, }], diff --git a/src/navigation/transitions/horizontalSwipe.js b/src/navigation/transitions/horizontalSwipe.js new file mode 100644 index 00000000000..dce82c1a239 --- /dev/null +++ b/src/navigation/transitions/horizontalSwipe.js @@ -0,0 +1,241 @@ +import { get } from 'lodash'; +import { Animated } from 'react-native'; +import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; +import { updateTransitionProps } from '../../redux/navigation'; +import store from '../../redux/store'; +import { colors } from '../../styles'; +import { deviceUtils, statusBar } from '../../utils'; + +const distanceFromTop = 14; +const statusBarHeight = getStatusBarHeight(true); + +export const sheetVerticalOffset = distanceFromTop + statusBarHeight; +export const transitionName = 'sheet'; + +export default function sheet(navigation, transitionProps, prevTransitionProps) { + const nextEffect = get(transitionProps, 'scene.descriptor.options.effect'); + const prevEffect = get(prevTransitionProps, 'scene.descriptor.options.effect'); + const nextIndex = get(transitionProps, 'index'); + const prevIndex = get(prevTransitionProps, 'index', nextIndex - 1); + + if (nextEffect === transitionName) { + statusBar.setBarStyle('light-content', true); + } + + if (prevEffect === transitionName) { + statusBar.setBarStyle('dark-content', true); + } + + return { + containerStyle: { + backgroundColor: colors.black, + opacity: 1, + }, + screenInterpolator: (sceneProps = {}) => { + const { + layout, + position, + scene, + } = sceneProps; + + store.dispatch(updateTransitionProps({ + effect: transitionName, + nextIndex, + position, + prevIndex, + })); + + const scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? distanceFromTop : 0)) / deviceUtils.dimensions.height); + const heightEnd = statusBarHeight + distanceFromTop; + const borderRadiusEnd = 12; + const borderRadiusScaledEnd = borderRadiusEnd / scaleEnd; + const opacityEnd = 0.5; + + if (nextEffect === transitionName && scene.index === prevIndex && nextIndex > prevIndex) { + const translateY = position.interpolate({ + inputRange: [prevIndex, nextIndex], + outputRange: [0, distanceFromTop], + }); + + const opacity = position.interpolate({ + inputRange: [prevIndex, nextIndex], + outputRange: [1, opacityEnd], + }); + + const scale = position.interpolate({ + inputRange: [prevIndex, nextIndex], + outputRange: [1, scaleEnd], + }); + + const borderRadius = position.interpolate({ + inputRange: [prevIndex, nextIndex], + outputRange: [isIphoneX() ? 38.5 : 0, borderRadiusScaledEnd], + }); + + return { + borderTopLeftRadius: borderRadius, + borderTopRightRadius: borderRadius, + opacity, + overflow: 'hidden', + transform: [{ + translateY, + }, { + scale, + }], + zIndex: 1, + }; + } + + if (nextEffect === transitionName && scene.index === nextIndex && nextIndex > prevIndex) { + const height = layout.initHeight; + const translateY = position.interpolate({ + inputRange: [prevIndex, nextIndex], + outputRange: [height, heightEnd], + }); + + return { + borderTopLeftRadius: borderRadiusEnd, + borderTopRightRadius: borderRadiusEnd, + height: height - heightEnd, + overflow: 'hidden', + transform: [{ + translateY, + }], + zIndex: 2, + }; + } + + if (prevEffect === transitionName && scene.index === nextIndex && nextIndex < prevIndex) { + const opacity = position.interpolate({ + inputRange: [nextIndex, prevIndex], + outputRange: [1, opacityEnd], + }); + + const scale = position.interpolate({ + inputRange: [nextIndex, prevIndex], + outputRange: [1, scaleEnd], + }); + + const borderRadius = position.interpolate({ + inputRange: [nextIndex, prevIndex], + outputRange: [0, borderRadiusEnd], + }); + + return { + borderTopLeftRadius: borderRadius, + borderTopRightRadius: borderRadius, + opacity, + overflow: 'hidden', + transform: [{ + scale, + }], + zIndex: 1, + }; + } + + if (prevEffect === transitionName && scene.index === prevIndex && nextIndex < prevIndex) { + const height = layout.initHeight; + const translateY = position.interpolate({ + inputRange: [nextIndex, prevIndex], + outputRange: [height, heightEnd], + }); + + return { + borderTopLeftRadius: borderRadiusEnd, + borderTopRightRadius: borderRadiusEnd, + height: height - heightEnd, + overflow: 'hidden', + transform: [{ + translateY, + }], + zIndex: 2, + }; + } + + if ((prevEffect === transitionName && scene.index === prevIndex) || (nextEffect === transitionName && scene.index === nextIndex)) { + const height = layout.initHeight; + const width = layout.initWidth; + const translateX = position.interpolate({ + inputRange: [scene.index - 1, scene.index], + outputRange: [width, 0], + }); + + return { + borderTopLeftRadius: borderRadiusEnd, + borderTopRightRadius: borderRadiusEnd, + height: height - heightEnd, + overflow: 'hidden', + transform: [{ + translateX, + }, { + translateY: heightEnd, + }], + zIndex: 2, + }; + } + + if (nextEffect === transitionName && prevIndex > nextIndex && scene.index === nextIndex - 1) { + const width = layout.initWidth; + const translateX = position.interpolate({ + inputRange: [nextIndex - 1, nextIndex], + outputRange: [width, 0], + }); + + return { + borderTopLeftRadius: borderRadiusEnd, + borderTopRightRadius: borderRadiusEnd, + opacity: opacityEnd, + overflow: 'hidden', + transform: [{ + translateX, + }, { + translateY: distanceFromTop, + }, { + scale: scaleEnd, + }], + }; + } + + if (prevEffect === transitionName && prevIndex < nextIndex && scene.index === prevIndex - 1) { + const width = layout.initWidth; + const translateX = position.interpolate({ + inputRange: [prevIndex - 1, prevIndex], + outputRange: [width, 0], + }); + + return { + borderTopLeftRadius: borderRadiusEnd, + borderTopRightRadius: borderRadiusEnd, + opacity: opacityEnd, + overflow: 'hidden', + transform: [{ + translateX, + }, { + translateY: distanceFromTop, + }, { + scale: scaleEnd, + }], + }; + } + + const width = layout.initWidth; + const translateX = position.interpolate({ + inputRange: [scene.index - 1, scene.index], + outputRange: [width, 0], + }); + + return { + overflow: 'hidden', + transform: [{ + translateX, + }], + }; + }, + transitionSpec: { + friction: 9.8, + tension: 58, + timing: ((nextEffect === transitionName) && (nextIndex > prevIndex)) ? Animated.spring : Animated.timing, + useNativeDriver: true, + }, + }; +} diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js new file mode 100644 index 00000000000..8cf37eaaf2a --- /dev/null +++ b/src/screens/CurrencySelectModal.js @@ -0,0 +1,122 @@ +import { get } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { createElement } from 'react'; +import { InteractionManager, View, StyleSheet, Animated } from 'react-native'; +import { + compose, + onlyUpdateForKeys, + withHandlers, + withProps, +} from 'recompact'; +import { Column } from '../components/layout'; +import { Modal, ModalHeader } from '../components/modal'; +import { AnimatedPager } from '../components/pager'; +import { + BackupSection, + CurrencySection, + LanguageSection, + NetworkSection, + SettingsSection, +} from '../components/settings-menu'; +import { PanGestureHandler } from 'react-native-gesture-handler' +import { deviceUtils } from '../utils'; +import withBlockedVerticalSwipe from '../hoc/withBlockedVerticalSwipe'; + +const SettingsPages = { + backup: { + component: BackupSection, + title: 'Backup', + }, + currency: { + component: CurrencySection, + title: 'Currency', + }, + default: { + component: null, + title: 'Settings', + }, + language: { + component: LanguageSection, + title: 'Language', + }, + network: { + component: NetworkSection, + title: 'Network', + }, +}; + +const { height } = deviceUtils.dimensions; + +const GestureBlocker = ({ type }) => ( + + + + + +) + +const SettingsModal = ({ + currentSettingsPage, + navigation, + onCloseModal, + onPressBack, + onPressImportSeedPhrase, + onPressSection, +}) => { + const { title } = currentSettingsPage; + const isDefaultPage = title === SettingsPages.default.title; + + return ( + + + + navigation.navigate('CurrencySelectScreen')} + showBackButton={!isDefaultPage} + title={title} + /> + + + + ); +}; + +SettingsModal.propTypes = { + currentSettingsPage: PropTypes.oneOf(Object.values(SettingsPages)), + navigation: PropTypes.object, + onCloseModal: PropTypes.func, + onPressBack: PropTypes.func, + onPressImportSeedPhrase: PropTypes.func, + onPressSection: PropTypes.func, +}; + +export default compose( + withProps(({ navigation }) => ({ + currentSettingsPage: get(navigation, 'state.params.section', SettingsPages.default), + })), + withHandlers({ + onCloseModal: ({ navigation }) => () => navigation.goBack(), + onPressBack: ({ navigation }) => () => navigation.setParams({ section: SettingsPages.default }), + onPressImportSeedPhrase: ({ navigation, setSafeTimeout }) => () => { + navigation.goBack(); + InteractionManager.runAfterInteractions(() => { + navigation.navigate('ImportSeedPhraseSheet'); + }); + }, + onPressSection: ({ navigation }) => (section) => () => navigation.setParams({ section }), + }), + onlyUpdateForKeys(['currentSettingsPage']), + withBlockedVerticalSwipe, +)(SettingsModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js new file mode 100644 index 00000000000..5c711f93771 --- /dev/null +++ b/src/screens/ExchangeModal.js @@ -0,0 +1,197 @@ +import { get } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { createElement } from 'react'; +import { + InteractionManager, View, StyleSheet, Animated, TextInput, KeyboardAvoidingView, Keyboard, +} from 'react-native'; +import { + compose, + onlyUpdateForKeys, + withHandlers, + withProps, + withState, +} from 'recompact'; +import { PanGestureHandler } from 'react-native-gesture-handler'; +import { NavigationEvents } from 'react-navigation'; +import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; +import { withAccountAssets } from '@rainbow-me/rainbow-common'; +import { + Centered, Column, FlexItem, Row, +} from '../components/layout'; +import { Modal, ModalHeader } from '../components/modal'; +import { AnimatedPager } from '../components/pager'; +import { + BackupSection, + CurrencySection, + LanguageSection, + NetworkSection, + SettingsSection, +} from '../components/settings-menu'; +import { deviceUtils, statusBar } from '../utils'; +import withBlockedHorizontalSwipe from '../hoc/withBlockedHorizontalSwipe'; +import { colors, padding, shadow } from '../styles'; +import { Icon } from '../components/icons'; +import FloatingPanels from '../components/expanded-state/FloatingPanels'; +import { AssetPanel, AssetPanelAction, AssetPanelHeader } from '../components/expanded-state/asset-panel'; +import FloatingPanel from '../components/expanded-state/FloatingPanel'; +import CoinRow from '../components/coin-row/CoinRow'; +import CoinName from '../components/coin-row/CoinName'; +import BalanceText from '../components/coin-row/BalanceText'; +import Button from '../components/buttons/Button'; +import { Text } from '../components/text'; +import GestureBlocker from '../components/GestureBlocker'; + +const Container = styled(Centered).attrs({ direction: 'column' })` + background-color: transparent; + height: 100%; +`; + +const ConfirmExchngeButton = styled(Button)` + ${shadow.build(0, 6, 10, colors.purple, 0.14)} + background-color: ${colors.appleBlue}; + width: 100%; + padding-horizontal: 5; + align-self: center +`; + +const TopRow = ({ navigateToCurrencySelection, amount, changeAmount }) => console.log(amount) || ( + + + + + + + {/* + {nativeDisplay || `${nativeCurrencySymbol}0.00`} + */} + + +); + +TopRow.propTypes = { + amountToExchange: PropTypes.number, + navigateToCurrencySelection: PropTypes.func, +}; + + +const SettingsModal = ({ + amountToExchange, + onPressConfirmExchange, + onPressSelectCurrency, + onPressSelectTargetCurrency, + selectedCurrency, + selectedTargetCurrency, + setAmountToExchange, + ...rest +}) => console.log(rest) || ( + + + + + + + + + + null} + topRowRender={TopRow} + symbol='ETH' + /> + null} + topRowRender={TopRow} + symbol='ETH' + /> + + + + + Hold to swap + + + + + + +); + + +SettingsModal.propTypes = { + amountToExchange: PropTypes.number, + onPressConfirmExchange: PropTypes.func, + onPressSelectCurrency: PropTypes.func, + onPressSelectTargetCurrency: PropTypes.func, + selectedCurrency: PropTypes.number, + selectedTargetCurrency: PropTypes.number, + setAmountToExchange: PropTypes.func, + setSelectedCurrency: PropTypes.func, + setSelectedTargetCurrency: PropTypes.func, +}; + +const withMockedPrices = withProps({ + currencyToDollar: 3, + targetCurrencyToDollar: 2, +}); + +export default compose( + withAccountAssets, + withState('amountToExchange', 'setAmountToExchange', '0'), + withState('selectedCurrency', 'setSelectedCurrency', 'ETH'), + withState('selectedTargetCurrency', 'setSelectedTargetCurrency', 'ETH'), + withHandlers({ + onPressSelectCurrency: ({ navigation, setSelectedCurrency }) => () => { + Keyboard.dismiss(); + navigation.navigate('CurrencySelectScreen', { setSelectedCurrency }); + }, + onPressSelectTargetCurrency: + ({ navigation, setSelectedTargetCurrency }) => () => { + Keyboard.dismiss(); + navigation.navigate('CurrencySelectScreen', { setSelectedCurrency: setSelectedTargetCurrency }) + }, + onPressConfirmExchange: + ({ navigation }) => () => { + Keyboard.dismiss(); + navigation.navigate('WalletScreen'); + }, + }), + withBlockedHorizontalSwipe, + withMockedPrices, +)(SettingsModal); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 9dd81a6148b..b77f09c2ebe 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -28,6 +28,8 @@ import { onTransitionStart as onTransitionStartEffect, } from '../navigation/transitions/effects'; import restoreKeyboard from './restoreKeyboard'; +import ExchangeModal from './ExchangeModal'; +import CurrencySelectModal from './CurrencySelectModal'; const onTransitionEnd = () => store.dispatch(updateTransitionProps({ isTransitioning: false })); @@ -64,6 +66,21 @@ const SwipeStack = createMaterialTopTabNavigator({ tabBarComponent: null, }); +const ExchangeModalNavigator = createMaterialTopTabNavigator({ + MainExchangeScreen: { + screen: ExchangeModal, + }, + // eslint-disable-next-line sort-keys + CurrencySelectScreen: { + screen: CurrencySelectModal, + }, +}, { + headerMode: 'none', + tabBarComponent: null, + mode: 'modal', + transparentCard: true, +}) + const MainNavigator = createStackNavigator({ ConfirmRequest: { navigationOptions: { @@ -106,6 +123,30 @@ const MainNavigator = createStackNavigator({ ...expandedPreset, }, screen: SettingsModal, + transparentCard: true, + + }, + ExchangeModal2: { + navigationOptions: { + effect: 'sheet', + gestureResponseDistance: { + vertical: deviceUtils.dimensions.height, + }, + mode: 'card', + gesturesEnabled: true, + }, + mode: 'card', + screen: ExchangeModal, + }, + ExchangeModal: { + navigationOptions: { + effect: 'expanded', + gestureResponseDistance: { + vertical: deviceUtils.dimensions.height, + }, + gesturesEnabled: true, + }, + screen: ExchangeModalNavigator, }, SwipeLayout: { navigationOptions: { diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 44e9175d9b5..114cdf8055c 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -12,11 +12,12 @@ import { } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { Keyboard, KeyboardAvoidingView } from 'react-native'; +import { Keyboard, KeyboardAvoidingView, View, Animated } from 'react-native'; import { isIphoneX } from 'react-native-iphone-x-helper'; import { compose, withHandlers } from 'recompact'; import styled from 'styled-components/primitives'; import { Column } from '../components/layout'; +import { PanGestureHandler } from 'react-native-gesture-handler' import { SendAssetForm, SendAssetList, From d4ca96b7ac1b00545577a178b31a14a86dfec145 Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 23 Apr 2019 20:22:16 +0200 Subject: [PATCH 132/636] Improved blocking gestures --- .../asset-list/RecyclerAssetList.js | 4 +- src/components/coin-row/SendCoinRow.js | 4 +- src/hoc/withBlockedHorizontalSwipe.js | 6 +- src/hoc/withBlockedVerticalSwipe.js | 15 -- src/screens/CurrencySelectModal.js | 138 ++++++++---------- src/screens/ExchangeModal.js | 103 +++++++------ src/screens/Routes.js | 23 ++- src/screens/WalletScreen.js | 1 + 8 files changed, 143 insertions(+), 151 deletions(-) delete mode 100644 src/hoc/withBlockedVerticalSwipe.js diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 3370b920deb..1a6d6297a19 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -109,6 +109,7 @@ const hasRowChanged = (r1, r2) => { class RecyclerAssetList extends Component { static propTypes = { + externalScrollView: PropTypes.any, fetchData: PropTypes.func, hideHeader: PropTypes.bool, openFamilyTabs: PropTypes.object, @@ -622,6 +623,7 @@ class RecyclerAssetList extends Component { dataProvider={dataProvider} extendedState={{ headersIndices }} itemAnimator={layoutItemAnimator} + externalScrollView={this.props.externalScrollView} layoutProvider={this.layoutProvider} onScroll={this.handleScroll} ref={this.handleListRef} @@ -632,7 +634,7 @@ class RecyclerAssetList extends Component { top: hideHeader ? 0 : AssetListHeader.height, }} scrollViewProps={{ - refreshControl: this.renderRefreshControl(), + refreshControl: this.props.fetchData && this.renderRefreshControl(), }} style={{ backgroundColor: colors.white, diff --git a/src/components/coin-row/SendCoinRow.js b/src/components/coin-row/SendCoinRow.js index 63629052b03..b1870d6b420 100644 --- a/src/components/coin-row/SendCoinRow.js +++ b/src/components/coin-row/SendCoinRow.js @@ -63,9 +63,11 @@ const SendCoinRow = enhance(({ item, onPress, selected, + disabled, + ...props }) => ( - + (props) => ( +export default (InnerComponent) => setDisplayName('HorizontalGestureBlocker')((props) => ( (props) => ( -); +)); diff --git a/src/hoc/withBlockedVerticalSwipe.js b/src/hoc/withBlockedVerticalSwipe.js deleted file mode 100644 index 1fc98dadf72..00000000000 --- a/src/hoc/withBlockedVerticalSwipe.js +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable react/display-name */ -import { PanGestureHandler } from 'react-native-gesture-handler'; -import React from 'react'; -import { Animated } from 'react-native'; - -export default (InnerComponent) => (props) => ( - - - - - -); diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 8cf37eaaf2a..61b4fc337f8 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,13 +1,17 @@ import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { createElement } from 'react'; -import { InteractionManager, View, StyleSheet, Animated } from 'react-native'; +import { + InteractionManager, View, StyleSheet, Animated, +} from 'react-native'; import { compose, onlyUpdateForKeys, withHandlers, withProps, } from 'recompact'; +import { ScrollView } from 'react-native-gesture-handler'; +import lang from 'i18n-js'; import { Column } from '../components/layout'; import { Modal, ModalHeader } from '../components/modal'; import { AnimatedPager } from '../components/pager'; @@ -18,105 +22,83 @@ import { NetworkSection, SettingsSection, } from '../components/settings-menu'; -import { PanGestureHandler } from 'react-native-gesture-handler' import { deviceUtils } from '../utils'; -import withBlockedVerticalSwipe from '../hoc/withBlockedVerticalSwipe'; +import { FlyInAnimation } from '../components/animations'; +import AssetList from '../components/asset-list/RecyclerAssetList'; +import { SendCoinRow } from '../components/coin-row'; +import GestureBlocker from '../components/GestureBlocker'; +import { withAccountAssets } from '@rainbow-me/rainbow-common'; +import { NavigationEvents } from "react-navigation"; +import store from '../redux/store'; +import { disableGestureForModal, updateTransitionProps } from '../redux/navigation'; + + -const SettingsPages = { - backup: { - component: BackupSection, - title: 'Backup', - }, - currency: { - component: CurrencySection, - title: 'Currency', - }, - default: { - component: null, - title: 'Settings', - }, - language: { - component: LanguageSection, - title: 'Language', - }, - network: { - component: NetworkSection, - title: 'Network', - }, -}; -const { height } = deviceUtils.dimensions; +const BalancesRenderItem = ({ + index, + item: { symbol, ...item }, + section: { onSelectAsset }, +}) => ( + +); -const GestureBlocker = ({ type }) => ( - - - - - -) -const SettingsModal = ({ +const SelectCurrencyModal = ({ + allAssets, currentSettingsPage, navigation, onCloseModal, onPressBack, onPressImportSeedPhrase, onPressSection, + simultaniousRef, + verticalRef, + ...rest }) => { - const { title } = currentSettingsPage; - const isDefaultPage = title === SettingsPages.default.title; + const sections = [ + { + balances: true, + data: allAssets, + onSelectAsset: () => null, + renderItem: BalancesRenderItem, + }, + ]; + return ( - - - - navigation.navigate('CurrencySelectScreen')} - showBackButton={!isDefaultPage} - title={title} - /> - - - + + + navigation.dangerouslyGetParent().setParams({ isGestureBlocked: true })} + onWillBlur={() => navigation.dangerouslyGetParent().setParams({ isGestureBlocked: false })} + /> + + + + + ); }; -SettingsModal.propTypes = { - currentSettingsPage: PropTypes.oneOf(Object.values(SettingsPages)), +SelectCurrencyModal.propTypes = { navigation: PropTypes.object, onCloseModal: PropTypes.func, onPressBack: PropTypes.func, onPressImportSeedPhrase: PropTypes.func, onPressSection: PropTypes.func, + verticalRef: PropTypes.any, }; export default compose( - withProps(({ navigation }) => ({ - currentSettingsPage: get(navigation, 'state.params.section', SettingsPages.default), - })), - withHandlers({ - onCloseModal: ({ navigation }) => () => navigation.goBack(), - onPressBack: ({ navigation }) => () => navigation.setParams({ section: SettingsPages.default }), - onPressImportSeedPhrase: ({ navigation, setSafeTimeout }) => () => { - navigation.goBack(); - InteractionManager.runAfterInteractions(() => { - navigation.navigate('ImportSeedPhraseSheet'); - }); - }, - onPressSection: ({ navigation }) => (section) => () => navigation.setParams({ section }), - }), - onlyUpdateForKeys(['currentSettingsPage']), - withBlockedVerticalSwipe, -)(SettingsModal); + withAccountAssets, +)(SelectCurrencyModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 5c711f93771..b7defc306e7 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -105,53 +105,52 @@ const SettingsModal = ({ selectedTargetCurrency, setAmountToExchange, ...rest -}) => console.log(rest) || ( - - - - - - - - - - null} - topRowRender={TopRow} - symbol='ETH' - /> - null} - topRowRender={TopRow} - symbol='ETH' - /> - - - - - Hold to swap - - - - - - -); +}) => { + return ( + + + + + + + + + null} + topRowRender={TopRow} + symbol='ETH' + /> + null} + topRowRender={TopRow} + symbol='ETH' + /> + + + + + Hold to swap + + + + + ); +}; SettingsModal.propTypes = { @@ -177,6 +176,11 @@ export default compose( withState('selectedCurrency', 'setSelectedCurrency', 'ETH'), withState('selectedTargetCurrency', 'setSelectedTargetCurrency', 'ETH'), withHandlers({ + onPressConfirmExchange: + ({ navigation }) => () => { + Keyboard.dismiss(); + navigation.navigate('WalletScreen'); + }, onPressSelectCurrency: ({ navigation, setSelectedCurrency }) => () => { Keyboard.dismiss(); navigation.navigate('CurrencySelectScreen', { setSelectedCurrency }); @@ -186,11 +190,6 @@ export default compose( Keyboard.dismiss(); navigation.navigate('CurrencySelectScreen', { setSelectedCurrency: setSelectedTargetCurrency }) }, - onPressConfirmExchange: - ({ navigation }) => () => { - Keyboard.dismiss(); - navigation.navigate('WalletScreen'); - }, }), withBlockedHorizontalSwipe, withMockedPrices, diff --git a/src/screens/Routes.js b/src/screens/Routes.js index b77f09c2ebe..871480c75b7 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -79,7 +79,15 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ tabBarComponent: null, mode: 'modal', transparentCard: true, -}) +}); + + +const EnhancedExchangeModalNavigator = props => ; +EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; +EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ + gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), +}); + const MainNavigator = createStackNavigator({ ConfirmRequest: { @@ -89,6 +97,19 @@ const MainNavigator = createStackNavigator({ screen: TransactionConfirmationScreenWithData, }, ExampleScreen, + ExchangeModal: { + navigationOptions: { + effect: 'expanded', + gestureResponseDistance: { + vertical: deviceUtils.dimensions.height, + }, + }, + params: { + isGestureBlocked: false, + isSwipeBlocked: true, + }, + screen: EnhancedExchangeModalNavigator, + }, ExpandedAssetScreen: { navigationOptions: { ...expandedPreset, diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index d135246691f..07de31ab511 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -117,6 +117,7 @@ class WalletScreen extends Component { sections, } = this.props; + console.log(this.props) return ( {/* Line below appears to be needed for having scrollViewTracker persistent while From 4a52d562b4136ac084b72db92a0465a55682de3b Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 23 Apr 2019 22:49:29 +0200 Subject: [PATCH 133/636] Add more logic --- src/components/coin-row/SendCoinRow.js | 6 +- src/hoc/withBlockedHorizontalSwipe.js | 3 +- src/screens/CurrencySelectModal.js | 119 ++++++++++++++++--------- src/screens/ExchangeModal.js | 14 +-- src/screens/Routes.js | 8 +- src/screens/SendSheet.js | 3 +- 6 files changed, 98 insertions(+), 55 deletions(-) diff --git a/src/components/coin-row/SendCoinRow.js b/src/components/coin-row/SendCoinRow.js index b1870d6b420..c7201f57c89 100644 --- a/src/components/coin-row/SendCoinRow.js +++ b/src/components/coin-row/SendCoinRow.js @@ -63,18 +63,16 @@ const SendCoinRow = enhance(({ item, onPress, selected, - disabled, - ...props }) => ( - + )); diff --git a/src/hoc/withBlockedHorizontalSwipe.js b/src/hoc/withBlockedHorizontalSwipe.js index 1bd6351656c..d5c4b148a7c 100644 --- a/src/hoc/withBlockedHorizontalSwipe.js +++ b/src/hoc/withBlockedHorizontalSwipe.js @@ -2,7 +2,8 @@ import { PanGestureHandler } from 'react-native-gesture-handler'; import React from 'react'; import { Animated } from 'react-native'; import { setDisplayName } from 'recompact'; - +// Adding extra PanGestureHandler allows for capturing gesture +// before it got delivered to navigator export default (InnerComponent) => setDisplayName('HorizontalGestureBlocker')((props) => ( { + return ( + + {symbol} + + ); +}; + +BottomRow.propTypes = { + balance: PropTypes.shape({ display: PropTypes.string }), + native: PropTypes.object, + nativeCurrencySymbol: PropTypes.string, +}; + -const BalancesRenderItem = ({ +const CurrencyRenderItem = ({ index, item: { symbol, ...item }, section: { onSelectAsset }, @@ -45,60 +64,80 @@ const BalancesRenderItem = ({ {...item} onPress={onSelectAsset(symbol)} symbol={symbol} + bottomRowRender={BottomRow} /> ); -const SelectCurrencyModal = ({ - allAssets, - currentSettingsPage, - navigation, - onCloseModal, - onPressBack, - onPressImportSeedPhrase, - onPressSection, - simultaniousRef, - verticalRef, - ...rest -}) => { - const sections = [ - { - balances: true, - data: allAssets, - onSelectAsset: () => null, - renderItem: BalancesRenderItem, - }, - ]; +CurrencyRenderItem.propTypes = { + index: PropTypes.number, + item: PropTypes.shape({ symbol: PropTypes.string }), + section: PropTypes.shape({ onSelectAsset: PropTypes.func }), +}; +class SelectCurrencyModal extends React.Component { + render() { + const { + allAssets, + currentSettingsPage, + navigation, + onCloseModal, + } = this.props + const sections = [ + { + balances: true, + data: allAssets, + onSelectAsset: (symbol) => () => { + // It's a bit weird and I'm not sure why on invoking + // navigation.getParam('setSelectedCurrency')(symbol) + // but this small hack seems to be a legit workaround + this.callback(symbol); + navigation.navigate('MainExchangeScreen'); + }, + renderItem: CurrencyRenderItem, + }, + ]; - return ( - - - navigation.dangerouslyGetParent().setParams({ isGestureBlocked: true })} - onWillBlur={() => navigation.dangerouslyGetParent().setParams({ isGestureBlocked: false })} - /> - - + + navigation.dangerouslyGetParent() + .setParams({ isGestureBlocked: true })} + onWillBlur={() => navigation.dangerouslyGetParent() + .setParams({ isGestureBlocked: false })} /> - - - - ); -}; + + + + + + ); + } +} + SelectCurrencyModal.propTypes = { + callback: PropTypes.func, navigation: PropTypes.object, onCloseModal: PropTypes.func, onPressBack: PropTypes.func, onPressImportSeedPhrase: PropTypes.func, onPressSection: PropTypes.func, + setCallback: PropTypes.func, verticalRef: PropTypes.any, }; export default compose( withAccountAssets, + withState('callback', 'setCallback', null), )(SelectCurrencyModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index b7defc306e7..a3260a438d5 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -54,7 +54,7 @@ const ConfirmExchngeButton = styled(Button)` align-self: center `; -const TopRow = ({ navigateToCurrencySelection, amount, changeAmount }) => console.log(amount) || ( +const TopRow = ({ navigateToCurrencySelection, amount, changeAmount, symbol }) => console.log(amount) || ( consol weight="semibold" style={{ fontSize: 12 }} > - ETH + {symbol} null} topRowRender={TopRow} - symbol='ETH' + symbol={selectedCurrency} /> null} topRowRender={TopRow} - symbol='ETH' + symbol={selectedTargetCurrency} /> @@ -173,8 +173,12 @@ const withMockedPrices = withProps({ export default compose( withAccountAssets, withState('amountToExchange', 'setAmountToExchange', '0'), - withState('selectedCurrency', 'setSelectedCurrency', 'ETH'), + withState('selectedCurrency', 'setSelectedCurrency', null), withState('selectedTargetCurrency', 'setSelectedTargetCurrency', 'ETH'), + withProps(({ + selectedCurrency, + allAssets: [{ symbol }], + }) => ({ selectedCurrency: selectedCurrency || symbol })), withHandlers({ onPressConfirmExchange: ({ navigation }) => () => { diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 871480c75b7..063904855e6 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -76,15 +76,18 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ }, }, { headerMode: 'none', - tabBarComponent: null, mode: 'modal', + tabBarComponent: null, transparentCard: true, }); +// I need it for changing navigationOptions dynamically +// for preventing swipe down to close on CurrencySelectScreen const EnhancedExchangeModalNavigator = props => ; EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; -EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ +EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => console.log(EnhancedExchangeModalNavigator.navigationOptions) || ({ + ...navigation.state.params, gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), }); @@ -106,7 +109,6 @@ const MainNavigator = createStackNavigator({ }, params: { isGestureBlocked: false, - isSwipeBlocked: true, }, screen: EnhancedExchangeModalNavigator, }, diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 114cdf8055c..44e9175d9b5 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -12,12 +12,11 @@ import { } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { Keyboard, KeyboardAvoidingView, View, Animated } from 'react-native'; +import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { isIphoneX } from 'react-native-iphone-x-helper'; import { compose, withHandlers } from 'recompact'; import styled from 'styled-components/primitives'; import { Column } from '../components/layout'; -import { PanGestureHandler } from 'react-native-gesture-handler' import { SendAssetForm, SendAssetList, From 279023edf6f390e9e06f0df1a7f92c9ec17608d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Osadnik?= Date: Tue, 23 Apr 2019 22:53:14 +0200 Subject: [PATCH 134/636] Delete horizontalSwipe.js --- src/navigation/transitions/horizontalSwipe.js | 241 ------------------ 1 file changed, 241 deletions(-) delete mode 100644 src/navigation/transitions/horizontalSwipe.js diff --git a/src/navigation/transitions/horizontalSwipe.js b/src/navigation/transitions/horizontalSwipe.js deleted file mode 100644 index dce82c1a239..00000000000 --- a/src/navigation/transitions/horizontalSwipe.js +++ /dev/null @@ -1,241 +0,0 @@ -import { get } from 'lodash'; -import { Animated } from 'react-native'; -import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; -import { updateTransitionProps } from '../../redux/navigation'; -import store from '../../redux/store'; -import { colors } from '../../styles'; -import { deviceUtils, statusBar } from '../../utils'; - -const distanceFromTop = 14; -const statusBarHeight = getStatusBarHeight(true); - -export const sheetVerticalOffset = distanceFromTop + statusBarHeight; -export const transitionName = 'sheet'; - -export default function sheet(navigation, transitionProps, prevTransitionProps) { - const nextEffect = get(transitionProps, 'scene.descriptor.options.effect'); - const prevEffect = get(prevTransitionProps, 'scene.descriptor.options.effect'); - const nextIndex = get(transitionProps, 'index'); - const prevIndex = get(prevTransitionProps, 'index', nextIndex - 1); - - if (nextEffect === transitionName) { - statusBar.setBarStyle('light-content', true); - } - - if (prevEffect === transitionName) { - statusBar.setBarStyle('dark-content', true); - } - - return { - containerStyle: { - backgroundColor: colors.black, - opacity: 1, - }, - screenInterpolator: (sceneProps = {}) => { - const { - layout, - position, - scene, - } = sceneProps; - - store.dispatch(updateTransitionProps({ - effect: transitionName, - nextIndex, - position, - prevIndex, - })); - - const scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? distanceFromTop : 0)) / deviceUtils.dimensions.height); - const heightEnd = statusBarHeight + distanceFromTop; - const borderRadiusEnd = 12; - const borderRadiusScaledEnd = borderRadiusEnd / scaleEnd; - const opacityEnd = 0.5; - - if (nextEffect === transitionName && scene.index === prevIndex && nextIndex > prevIndex) { - const translateY = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [0, distanceFromTop], - }); - - const opacity = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [1, opacityEnd], - }); - - const scale = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [1, scaleEnd], - }); - - const borderRadius = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [isIphoneX() ? 38.5 : 0, borderRadiusScaledEnd], - }); - - return { - borderTopLeftRadius: borderRadius, - borderTopRightRadius: borderRadius, - opacity, - overflow: 'hidden', - transform: [{ - translateY, - }, { - scale, - }], - zIndex: 1, - }; - } - - if (nextEffect === transitionName && scene.index === nextIndex && nextIndex > prevIndex) { - const height = layout.initHeight; - const translateY = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [height, heightEnd], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - overflow: 'hidden', - transform: [{ - translateY, - }], - zIndex: 2, - }; - } - - if (prevEffect === transitionName && scene.index === nextIndex && nextIndex < prevIndex) { - const opacity = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [1, opacityEnd], - }); - - const scale = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [1, scaleEnd], - }); - - const borderRadius = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [0, borderRadiusEnd], - }); - - return { - borderTopLeftRadius: borderRadius, - borderTopRightRadius: borderRadius, - opacity, - overflow: 'hidden', - transform: [{ - scale, - }], - zIndex: 1, - }; - } - - if (prevEffect === transitionName && scene.index === prevIndex && nextIndex < prevIndex) { - const height = layout.initHeight; - const translateY = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [height, heightEnd], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - overflow: 'hidden', - transform: [{ - translateY, - }], - zIndex: 2, - }; - } - - if ((prevEffect === transitionName && scene.index === prevIndex) || (nextEffect === transitionName && scene.index === nextIndex)) { - const height = layout.initHeight; - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [scene.index - 1, scene.index], - outputRange: [width, 0], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - overflow: 'hidden', - transform: [{ - translateX, - }, { - translateY: heightEnd, - }], - zIndex: 2, - }; - } - - if (nextEffect === transitionName && prevIndex > nextIndex && scene.index === nextIndex - 1) { - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [nextIndex - 1, nextIndex], - outputRange: [width, 0], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - opacity: opacityEnd, - overflow: 'hidden', - transform: [{ - translateX, - }, { - translateY: distanceFromTop, - }, { - scale: scaleEnd, - }], - }; - } - - if (prevEffect === transitionName && prevIndex < nextIndex && scene.index === prevIndex - 1) { - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [prevIndex - 1, prevIndex], - outputRange: [width, 0], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - opacity: opacityEnd, - overflow: 'hidden', - transform: [{ - translateX, - }, { - translateY: distanceFromTop, - }, { - scale: scaleEnd, - }], - }; - } - - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [scene.index - 1, scene.index], - outputRange: [width, 0], - }); - - return { - overflow: 'hidden', - transform: [{ - translateX, - }], - }; - }, - transitionSpec: { - friction: 9.8, - tension: 58, - timing: ((nextEffect === transitionName) && (nextIndex > prevIndex)) ? Animated.spring : Animated.timing, - useNativeDriver: true, - }, - }; -} From f21803c040428f03f05c6468a54399adc3cf1264 Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 23 Apr 2019 22:56:37 +0200 Subject: [PATCH 135/636] Remove dummy things --- src/screens/ExchangeModal.js | 32 ++++++++------------------------ src/screens/WalletScreen.js | 1 - 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a3260a438d5..65ce6449d63 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,42 +1,27 @@ -import { get } from 'lodash'; +import React from 'react'; import PropTypes from 'prop-types'; -import React, { createElement } from 'react'; import { - InteractionManager, View, StyleSheet, Animated, TextInput, KeyboardAvoidingView, Keyboard, + TextInput, KeyboardAvoidingView, Keyboard, } from 'react-native'; import { compose, - onlyUpdateForKeys, withHandlers, withProps, withState, } from 'recompact'; -import { PanGestureHandler } from 'react-native-gesture-handler'; -import { NavigationEvents } from 'react-navigation'; import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; import { withAccountAssets } from '@rainbow-me/rainbow-common'; import { Centered, Column, FlexItem, Row, } from '../components/layout'; -import { Modal, ModalHeader } from '../components/modal'; -import { AnimatedPager } from '../components/pager'; -import { - BackupSection, - CurrencySection, - LanguageSection, - NetworkSection, - SettingsSection, -} from '../components/settings-menu'; -import { deviceUtils, statusBar } from '../utils'; +import { ModalHeader } from '../components/modal'; import withBlockedHorizontalSwipe from '../hoc/withBlockedHorizontalSwipe'; -import { colors, padding, shadow } from '../styles'; +import { colors, shadow } from '../styles'; import { Icon } from '../components/icons'; import FloatingPanels from '../components/expanded-state/FloatingPanels'; -import { AssetPanel, AssetPanelAction, AssetPanelHeader } from '../components/expanded-state/asset-panel'; import FloatingPanel from '../components/expanded-state/FloatingPanel'; import CoinRow from '../components/coin-row/CoinRow'; import CoinName from '../components/coin-row/CoinName'; -import BalanceText from '../components/coin-row/BalanceText'; import Button from '../components/buttons/Button'; import { Text } from '../components/text'; import GestureBlocker from '../components/GestureBlocker'; @@ -54,7 +39,7 @@ const ConfirmExchngeButton = styled(Button)` align-self: center `; -const TopRow = ({ navigateToCurrencySelection, amount, changeAmount, symbol }) => console.log(amount) || ( +const TopRow = ({ navigateToCurrencySelection, amount, changeAmount, symbol }) => ( - {/* - {nativeDisplay || `${nativeCurrencySymbol}0.00`} - */} ); TopRow.propTypes = { - amountToExchange: PropTypes.number, + amount: PropTypes.number, + changeAmount: PropTypes.func, navigateToCurrencySelection: PropTypes.func, + symbol: PropTypes.func, }; diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 07de31ab511..d135246691f 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -117,7 +117,6 @@ class WalletScreen extends Component { sections, } = this.props; - console.log(this.props) return ( {/* Line below appears to be needed for having scrollViewTracker persistent while From c32ba37c6a54673ec440eabd8eed285cd5d1cc92 Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 23 Apr 2019 23:41:09 +0200 Subject: [PATCH 136/636] Add no coin --- src/components/coin-icon/CoinIcon.js | 1 + src/screens/ExchangeModal.js | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/coin-icon/CoinIcon.js b/src/components/coin-icon/CoinIcon.js index 16ca1571ed3..572ed125aeb 100644 --- a/src/components/coin-icon/CoinIcon.js +++ b/src/components/coin-icon/CoinIcon.js @@ -17,6 +17,7 @@ const CoinIconFallback = fallbackProps => ( ); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 65ce6449d63..b7deba4c5dc 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -39,29 +39,34 @@ const ConfirmExchngeButton = styled(Button)` align-self: center `; -const TopRow = ({ navigateToCurrencySelection, amount, changeAmount, symbol }) => ( +const TopRow = ({ + navigateToCurrencySelection, amount, changeAmount, symbol, +}) => ( + > + {symbol ? null : '–'} + +); + +ConfirmExchangeButton.propTypes = { + disabled: PropTypes.bool, + onPress: PropTypes.func, +}; + +export default ConfirmExchangeButton; diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js new file mode 100644 index 00000000000..72ab10b4d14 --- /dev/null +++ b/src/components/exchange/ExchangeInputField.js @@ -0,0 +1,130 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { TouchableWithoutFeedback } from 'react-native'; +import { colors, position } from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { CoolButton } from '../buttons'; +import { CoinIcon } from '../coin-icon'; +import { Input } from '../inputs'; +import { + Centered, + ColumnWithMargins, + Row, + RowWithMargins, +} from '../layout'; +import { Monospace, Text } from '../text'; + +import TextInputMask from 'react-native-text-input-mask'; + +export default class ExchangeInputField extends PureComponent { + static propTypes = { + amount: PropTypes.string, + onPressMaxBalance: PropTypes.func, + onPressSelectInputCurrency: PropTypes.string, + selectedInputCurrency: PropTypes.string, + setAmountToExchange: PropTypes.func, + } + + inputRef = React.createRef() + + maskRef = null + + padding = 15 + + handleFocusInput = () => { + + if (this.maskRef) { + this.maskRef.focus(); + } + } + + + handleMaskRef = (ref) => { + this.maskRef = ref; + } + + render = () => { + const { + amount, + onPressMaxBalance, + onPressSelectInputCurrency, + selectedInputCurrency, + setAmountToExchange, + } = this.props; + // mask="[0...][-][9...]" + + return ( + + + + + + + + + + + + + {selectedInputCurrency || 'Choose a Coin'} + + + + + + $0.00 + + + + + + 💰Max + + + + + + ); + } +} diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js new file mode 100644 index 00000000000..e566e3c86fb --- /dev/null +++ b/src/components/exchange/ExchangeOutputField.js @@ -0,0 +1,133 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { TouchableWithoutFeedback } from 'react-native'; +import { colors, padding, position, shadow } from '../../styles'; +import { CoolButton } from '../buttons'; +import { CoinIcon } from '../coin-icon'; +import { Input } from '../inputs'; +import { + Centered, + ColumnWithMargins, + Row, + RowWithMargins, +} from '../layout'; +import { Monospace, Text } from '../text'; +import { EmDash } from '../html-entities'; + +import { + withNeverRerender, +} from '../../hoc'; +import { Icon } from '../icons'; +import { ShadowStack } from '../shadow-stack'; + +const paddingValue = 15; + +const FakeNotchThing = withNeverRerender(() => ( + +)); + +// + // null} + // topRowRender={() => null} + // symbol={selectedOutputCurrency} + // /> + +class ExchangeOutputField extends React.Component { + static propTypes = { + amount: PropTypes.number, + onPressSelectOutputCurrency: PropTypes.string, + selectedOutputCurrency: PropTypes.string, + setAmountToExchange: PropTypes.func, + } + + inputRef = React.createRef() + + handleFocusInput = () => this.inputRef.current.focus() + + render = () => { + const { + amount, + onPressSelectOutputCurrency, + selectedOutputCurrency, + setAmountToExchange, + } = this.props; + + const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); + const placeholderColor = colors.alpha(colors.blueGreyDark, 0.5); + + console.log('selectedOutputCurrency', selectedOutputCurrency); + + return ( + + + + + + + + {selectedOutputCurrency || 'Choose a Coin'} + + + ); + } +} + +export default ExchangeOutputField; diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js new file mode 100644 index 00000000000..8f1bc4daa54 --- /dev/null +++ b/src/components/exchange/index.js @@ -0,0 +1,4 @@ +export { default as ConfirmExchangeButton } from './ConfirmExchangeButton'; +export { default as ExchangeInputField } from './ExchangeInputField'; +export { default as ExchangeOutputField } from './ExchangeOutputField'; + diff --git a/yarn.lock b/yarn.lock index 226c13982a7..ed6d0e93601 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,11 +16,19 @@ dependencies: "@babel/highlight" "^7.0.0" +<<<<<<< HEAD <<<<<<< HEAD "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== +======= +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": +<<<<<<< HEAD + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" + integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/code-frame" "^7.5.5" "@babel/generator" "^7.6.0" @@ -40,9 +48,27 @@ "@babel/helpers" "^7.4.4" "@babel/parser" "^7.4.5" "@babel/template" "^7.4.4" +<<<<<<< HEAD "@babel/traverse" "^7.4.5" "@babel/types" "^7.4.4" >>>>>>> 751dba29... Replace navigation animations with new effects +======= + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" +======= + version "7.5.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd" + integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.5.0" + "@babel/helpers" "^7.5.4" + "@babel/parser" "^7.5.0" + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.5.0" + "@babel/types" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -62,12 +88,30 @@ source-map "^0.5.0" trim-right "^1.0.1" +<<<<<<< HEAD "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA== dependencies: "@babel/types" "^7.6.0" +======= +<<<<<<< HEAD +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" + integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== + dependencies: + "@babel/types" "^7.5.5" +======= +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a" + integrity sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA== + dependencies: + "@babel/types" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -105,10 +149,24 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" +<<<<<<< HEAD "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== +======= +<<<<<<< HEAD +"@babel/helper-create-class-features-plugin@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" + integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== +======= +"@babel/helper-create-class-features-plugin@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz#02edb97f512d44ba23b3227f1bf2ed43454edac5" + integrity sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.5.5" @@ -271,6 +329,7 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" +<<<<<<< HEAD "@babel/helpers@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e" @@ -279,6 +338,27 @@ "@babel/template" "^7.6.0" "@babel/traverse" "^7.6.0" "@babel/types" "^7.6.0" +======= +<<<<<<< HEAD +"@babel/helpers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" + integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== + dependencies: + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.5.5" + "@babel/types" "^7.5.5" +======= +"@babel/helpers@^7.5.4": + version "7.5.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.4.tgz#2f00608aa10d460bde0ccf665d6dcf8477357cf0" + integrity sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow== + dependencies: + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.5.0" + "@babel/types" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" @@ -298,10 +378,24 @@ esutils "^2.0.2" js-tokens "^4.0.0" +<<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== +======= +<<<<<<< HEAD +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" + integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== +======= +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" + integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -311,11 +405,19 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": +<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" +======= + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007" + integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": @@ -335,9 +437,15 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": +<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== +======= + version "7.5.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331" + integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -605,9 +713,21 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": +<<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" integrity sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg== +======= +<<<<<<< HEAD + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" + integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== +======= + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.0.tgz#45242c2c9281158c5f06d25beebac63e498a284e" + integrity sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -645,11 +765,27 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": +<<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz#48d78405f1aa856ebeea7288a48a19ed8da377a6" integrity sha512-yzw7EopOOr6saONZ3KA3lpizKnWRTe+rfBqg4AmQbSow7ik7fqmzrfIqt053osLwLE2AaTqGinLM2tl6+M/uog== dependencies: "@babel/helper-create-class-features-plugin" "^7.6.0" +======= +<<<<<<< HEAD + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" + integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.5.5" +======= + version "7.5.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz#ea7da440d29b8ccdb1bd02e18f6cfdc7ce6c16f5" + integrity sha512-r4zJOMbKY5puETm8+cIpaa0RQZG/sSASW1u0pj8qYklcERgVIbxVbP2wyJA7zI1//h7lEagQmXi9IL9iI5rfsA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -673,6 +809,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" +<<<<<<< HEAD <<<<<<< HEAD "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.6.0" @@ -684,6 +821,18 @@ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== >>>>>>> 751dba29... Replace navigation animations with new effects +======= +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": +<<<<<<< HEAD + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" + integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== +======= + version "7.5.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b" + integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: regenerator-runtime "^0.13.2" @@ -722,17 +871,43 @@ invariant "^2.2.0" lodash "^4.2.0" +<<<<<<< HEAD "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== +======= +<<<<<<< HEAD +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" + integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/code-frame" "^7.5.5" "@babel/generator" "^7.6.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" +<<<<<<< HEAD "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" +======= + "@babel/parser" "^7.5.5" + "@babel/types" "^7.5.5" +======= +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.0.tgz#4216d6586854ef5c3c4592dab56ec7eb78485485" + integrity sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.5.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.5.0" + "@babel/types" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" @@ -746,10 +921,24 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +<<<<<<< HEAD "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": version "7.6.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== +======= +<<<<<<< HEAD +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" + integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== +======= +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" + integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1103,16 +1292,25 @@ dependencies: prop-types "^15.5.10" +<<<<<<< HEAD <<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== +======= +"@react-native-community/cli-platform-android@^2.0.0-rc.2": +<<<<<<< HEAD + version "2.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" + integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" execa "^1.0.0" jetifier "^1.6.2" +<<<<<<< HEAD logkitty "^0.6.0" slash "^3.0.0" xmldoc "^1.1.2" @@ -1145,16 +1343,56 @@ version "2.0.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.0.2.tgz#ce21fa9771152a71d2b05fba434d849e32e0376a" integrity sha512-Pwp1EOCfbpNpTXwSLQg7mGmTsCD981nkizu3S7D3QVoIwhQGpuTGXM1xyIFu9IZI2AIHNtUT9W5Nqw97/UDmdw== +======= +======= + version "2.4.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.4.1.tgz#27d4c5c7be2a6a28b07cd37f10e661a5eef70b0f" + integrity sha512-M482L65Kst1LYQWDkXNTFgBDcBmUAmiF8f6SLkhsps8zmimluMUrJ/yTcBnHSK8QGuxfpW/B+QT2sT1louShmw== + dependencies: + "@react-native-community/cli-tools" "^2.4.1" + chalk "^2.4.2" +>>>>>>> 8d2e8d2f... BREAK UP + logkitty "^0.5.0" + slash "^2.0.0" + xmldoc "^0.4.0" + +"@react-native-community/cli-platform-ios@^2.0.0-rc.2": +<<<<<<< HEAD + version "2.8.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" + integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@react-native-community/cli-tools" "^2.0.2" chalk "^1.1.1" xcode "^2.0.0" +<<<<<<< HEAD "@react-native-community/cli-tools@^2.0.0-alpha.14", "@react-native-community/cli-tools@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.0.2.tgz#1dc4055f27f1b2fe3d0493959a6fc20467e93fe0" integrity sha512-6OOKrE1Sdq1Lmcdp2K68J5PsG5G80a9USa9I1Kv92wvPHUup6IRt+Dy7E8IZqxmskzC/mlOR62Oh1CB3sFm84g== >>>>>>> 751dba29... Replace navigation animations with new effects +======= +"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" + integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== +======= + version "2.4.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" + integrity sha512-EKfnN+ubIcCHbCCo2a1SlYcd4jLZDT12HfoLHhFg8WXG3/zFWc/vMNpBi+omrvT7Hoktr8cTtROXPg9cIS7FCQ== + dependencies: + "@react-native-community/cli-tools" "^2.4.1" + chalk "^2.4.2" + xcode "^2.0.0" + +"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.4.1.tgz#5a23b92d0b486753add00a27d77d0ea9e8c331e1" + integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1561,9 +1799,16 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": +<<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== +======= +<<<<<<< HEAD + version "12.6.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" + integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== +>>>>>>> f7a61a13... Create Exchange related Input components "@types/node@^10.3.2": version "10.14.18" @@ -1571,9 +1816,30 @@ integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== "@types/node@^8.0.7": +<<<<<<< HEAD version "8.10.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== +======= + version "8.10.51" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627" + integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== +======= + version "12.6.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" + integrity sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ== + +"@types/node@^10.3.2": + version "10.14.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f" + integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg== + +"@types/node@^8.0.7": + version "8.10.50" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.50.tgz#f3d68482b1f54b5f4fba8daaac385db12bb6a706" + integrity sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components "@types/q@^1.5.1": version "1.5.2" @@ -1773,9 +2039,21 @@ acorn@^5.5.3: integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.1, acorn@^6.0.7: +<<<<<<< HEAD version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== +======= +<<<<<<< HEAD + version "6.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" + integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== +======= + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" + integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components aes-js@3.0.0: version "3.0.0" @@ -1787,13 +2065,18 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= +<<<<<<< HEAD agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: +======= +agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@^4.3.0: +>>>>>>> 8d2e8d2f... BREAK UP version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" +<<<<<<< HEAD agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -1805,6 +2088,12 @@ ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== +======= +ajv@^6.5.5, ajv@^6.9.1: + version "6.10.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" + integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -2251,10 +2540,19 @@ babel-plugin-rewire@^1.2.0: resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ== +<<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ======= +<<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.0: >>>>>>> 751dba29... Replace navigation animations with new effects +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.2: +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> d743296d... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -2593,6 +2891,7 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.6.3: +<<<<<<< HEAD version "4.7.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA== @@ -2600,6 +2899,24 @@ browserslist@^4.6.3: caniuse-lite "^1.0.30000989" electron-to-chromium "^1.3.247" node-releases "^1.1.29" +======= +<<<<<<< HEAD + version "4.6.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" + integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== + dependencies: + caniuse-lite "^1.0.30000984" + electron-to-chromium "^1.3.191" +======= + version "4.6.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" + integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== + dependencies: + caniuse-lite "^1.0.30000981" + electron-to-chromium "^1.3.188" +>>>>>>> 8d2e8d2f... BREAK UP + node-releases "^1.1.25" +>>>>>>> f7a61a13... Create Exchange related Input components bser@^2.0.0: version "2.1.0" @@ -2741,6 +3058,7 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= +<<<<<<< HEAD <<<<<<< HEAD caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: version "1.0.30000989" @@ -2758,6 +3076,24 @@ caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: version "1.0.30000979" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz#92f16d00186a6cf20d6c5711bb6e042a3d667029" integrity sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw== +======= +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: +<<<<<<< HEAD + version "1.0.30000987" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" + integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== +======= + version "1.0.30000985" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f" + integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w== +======= +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: + version "1.0.30000983" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" + integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> f7a61a13... Create Exchange related Input components capture-exit@^1.2.0: version "1.2.0" @@ -3376,6 +3712,9 @@ csso@^3.5.1: <<<<<<< HEAD cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": +======= +"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: +>>>>>>> 8d2e8d2f... BREAK UP version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== @@ -3802,6 +4141,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +<<<<<<< HEAD <<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" @@ -3813,6 +4153,30 @@ electron-to-chromium@^1.3.164: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.182.tgz#1711122c0c035f1568aea0d1b6b93c04b5f9fdf2" integrity sha512-uqKh3J1/s4LkmtbrVi2cPpd5g2u7efYJdnRXApQLVhZlLjzaJZakafp+JFSUZNYrBDJNIqQChcJTCDZXqQOBYg== >>>>>>> 751dba29... Replace navigation animations with new effects +======= +electron-to-chromium@^1.3.191: +<<<<<<< HEAD + version "1.3.205" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" + integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== +======= +<<<<<<< HEAD + version "1.3.200" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" + integrity sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg== +======= + version "1.3.199" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.199.tgz#f9a62a74cda77854310a2abffde8b75591ea09a1" + integrity sha512-gachlDdHSK47s0N2e58GH9HMC6Z4ip0SfmYUa5iEbE50AKaOUXysaJnXMfKj0xB245jWbYcyFSH+th3rqsF8hA== +======= +electron-to-chromium@^1.3.188: + version "1.3.188" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.188.tgz#e28e1afe4bb229989e280bfd3b395c7ec03c8b7a" + integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> d743296d... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> f7a61a13... Create Exchange related Input components elliptic@6.3.3: version "6.3.3" @@ -4735,10 +5099,20 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +<<<<<<< HEAD form-data@^2.3.3: +<<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== +======= +======= +form-data@^2.3.1: +>>>>>>> 8d2e8d2f... BREAK UP + version "2.5.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" + integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" @@ -6724,10 +7098,21 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= +<<<<<<< HEAD lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: +======= +<<<<<<< HEAD +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: +>>>>>>> d743296d... BREAK UP version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +======= +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: + version "4.17.14" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" + integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== +>>>>>>> 8d2e8d2f... BREAK UP log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" @@ -8706,9 +9091,15 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: +<<<<<<< HEAD version "1.4.1" resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w== +======= + version "1.4.0" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.0.tgz#b4b41b4bbfd5eeac8d5163efacef34ee5b8ad455" + integrity sha512-18u+bdSosXO0+wx6F1UUFzJz01VRfMBcb/wbBw/tKYRD0A2Vho5WQ4xz30pHwhh4IE/qhObqIs5yNO0mGdHKkA== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: dijkstrajs "^1.0.1" isarray "^2.0.1" @@ -8846,9 +9237,15 @@ react-native-circular-progress@^1.1.0: prop-types "^15.7.2" react-native-clean-project@^3.1.0: +<<<<<<< HEAD version "3.2.4" resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.4.tgz#55a71006eb4336dff91d0ca5ab3564d8f0db45cc" integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== +======= + version "3.2.3" + resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.3.tgz#40313a3a4131353d5d082d7691b41b4de6f40eb2" + integrity sha512-c8NgNTXAwugyuP+bS5b5mwpML4JrSP+u9D5b6X5OudU6hPlzPsiFLnBzQUvJVSPRHRwCFj30/qHGCjLc/jPzUw== +>>>>>>> 8d2e8d2f... BREAK UP react-native-code-push@^5.6.0: version "5.7.0" @@ -8926,10 +9323,20 @@ react-native-gesture-handler@^1.4.1: invariant "^2.2.4" prop-types "^15.7.2" +<<<<<<< HEAD react-native-haptic-feedback@^1.8.2: +======= +react-native-haptic-feedback@^1.8.0: +<<<<<<< HEAD +>>>>>>> d743296d... BREAK UP version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== +======= + version "1.8.1" + resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.1.tgz#7e255fa7421dccd5d1da35f2a6bb922c253324a2" + integrity sha512-Y/lXN9S70TJIqg1F4984OlJ/2k0Nt6/5dAyilhVr4CFVvIulFf2dHAXkB1I+OlBiY9iuiCKtw5RixXad5jFEbw== +>>>>>>> 8d2e8d2f... BREAK UP react-native-indicators@^0.13.0: version "0.13.0" @@ -9077,7 +9484,15 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" +<<<<<<< HEAD +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: +======= +<<<<<<< HEAD +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.22: +======= "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> d743296d... BREAK UP version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -9130,6 +9545,11 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" +react-native-text-input-mask@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.1.tgz#93b4374c3c73bc78eac907094662d5d98166f359" + integrity sha512-gN0N+3tpw1kgHsuaqzugN7hc5XsjlyXET4/Q3C36F6LxwpIdnf3k9yCL4vfAlw6QxwuBTtyFaRxGJgwZkzk4Ng== + react-native-tooltip@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/react-native-tooltip/-/react-native-tooltip-5.2.0.tgz#4358ea1e9bdcb49dad28bf5881440b0182927422" @@ -10625,10 +11045,23 @@ styled-components@4.3.1: stylis-rule-sheet "^0.0.10" supports-color "^5.5.0" +<<<<<<< HEAD styled-components@^5.0.0-beta.8: +<<<<<<< HEAD version "5.0.0-beta.8-groupsizefix" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8-groupsizefix.tgz#0497f11c0d60e9e51faa4b802afab7cc22136e42" integrity sha512-5FDDRE4QhH8g6zsvHGPZ2NrJRi12AH1GxpZMy+y0lRYGrfNL6W5xni5Sz8kOKXS4PGf1VeyfVXaEG10mbrQYsA== +======= + version "5.0.0-beta.6-ej4" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.6-ej4.tgz#7570ebbf9c9356a8cca03ea37dd94233f2e40e84" + integrity sha512-WaytinYy4+Zc1TKXdTlPmkAOIj58QWvjn1rdgxCSAMAR4GFLlu2m7rQXwZ6WYWYk6GJd141rnZnE2Ig3XERc5A== +======= +styled-components@5.0.0-beta.8: + version "5.0.0-beta.8" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8.tgz#ad1e672589a891987f5492cbe3ca6f480fcd99dc" + integrity sha512-g4MrDmfaoR2jJnA56+JSTFf1ZsDpJYdvTyQSw3HWOHoV/KlCgaSFmU8TrHfTy7DwWQskxyX//IQInNZdn4mGcA== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -11547,6 +11980,7 @@ wide-align@1.1.3, wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +<<<<<<< HEAD widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" @@ -11554,6 +11988,8 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +======= +>>>>>>> 8d2e8d2f... BREAK UP wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -11850,10 +12286,20 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" +<<<<<<< HEAD yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: +======= +yargs@^13.0.0, yargs@^13.2.4: +<<<<<<< HEAD +>>>>>>> f7a61a13... Create Exchange related Input components version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== +======= + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: cliui "^5.0.0" find-up "^3.0.0" From 827aac666808b1711f65f73dc507579e6e5ea838 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 03:39:15 -0700 Subject: [PATCH 160/636] Create CoolButton component lol please lets rename this tho idk --- src/components/buttons/CoolButton.js | 81 ++++++++++++++++++++++++++++ src/components/buttons/index.js | 1 + 2 files changed, 82 insertions(+) create mode 100644 src/components/buttons/CoolButton.js diff --git a/src/components/buttons/CoolButton.js b/src/components/buttons/CoolButton.js new file mode 100644 index 00000000000..9d9b6f66660 --- /dev/null +++ b/src/components/buttons/CoolButton.js @@ -0,0 +1,81 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { compose, onlyUpdateForPropTypes, withProps } from 'recompact'; +import { withNeverRerender } from '../../hoc'; +import { + colors, + margin, + padding, + position, +} from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { Icon } from '../icons'; +import InnerBorder from '../InnerBorder'; +import { Row, RowWithMargins } from '../layout'; +import { ShadowStack } from '../shadow-stack'; +import { Text } from '../text'; + +const CoolCaretIcon = compose( + withNeverRerender, + withProps({ + color: 'white', + flex: 0, + name: 'caret', + size: 7.5, + }), +)(Icon); + +const CoolLabel = withProps({ + color: 'white', + flex: 1, + size: 'lmedium', + weight: 'semibold', +})(Text); + +const CoolButton = ({ + borderRadius, + children, + color, + onPress, + shadows, +}) => ( + + + + + {children} + + + + + +); + +CoolButton.propTypes = { + borderRadius: PropTypes.number, + children: PropTypes.node, + color: PropTypes.string, + onPress: PropTypes.func, + shadows: PropTypes.arrayOf(PropTypes.array), +}; + +CoolButton.defaultProps = { + borderRadius: 20, + shadows: [ + [0, 0, 1, colors.dark, 0.01], + [0, 4, 12, colors.dark, 0.04], + [0, 8, 23, colors.dark, 0.05], + ], +}; + +export default onlyUpdateForPropTypes(CoolButton); diff --git a/src/components/buttons/index.js b/src/components/buttons/index.js index 72f64968559..9ef6c2012f0 100644 --- a/src/components/buttons/index.js +++ b/src/components/buttons/index.js @@ -3,3 +3,4 @@ export { default as Button } from './Button'; export { default as PasteAddressButton } from './PasteAddressButton'; export { default as HoldToAuthorizeButton } from './HoldToAuthorizeButton'; // export { default as LongPressButton } from './LongPressButton'; +export { default as CoolButton } from './CoolButton'; From 4bdbc3a6ec6fcf26180906803dde6f25b6c7d3a7 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 03:40:08 -0700 Subject: [PATCH 161/636] ExchangeModal / CurrencySelectModal related UI cleanup --- src/components/coin-icon/CoinIcon.js | 19 +- src/screens/CurrencySelectModal.js | 121 +++++----- src/screens/ExchangeModal.js | 343 ++++++++++----------------- src/screens/Routes.js | 15 +- 4 files changed, 214 insertions(+), 284 deletions(-) diff --git a/src/components/coin-icon/CoinIcon.js b/src/components/coin-icon/CoinIcon.js index 572ed125aeb..ff42f5ed83d 100644 --- a/src/components/coin-icon/CoinIcon.js +++ b/src/components/coin-icon/CoinIcon.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { css } from 'styled-components/primitives'; import ReactCoinIcon, { FallbackIcon } from 'react-coin-icon'; -import { hoistStatics, onlyUpdateForKeys } from 'recompact'; +import { onlyUpdateForKeys } from 'recompact'; import { borders, colors, fonts } from '../../styles'; import { ShadowStack } from '../shadow-stack'; @@ -21,16 +21,21 @@ const CoinIconFallback = fallbackProps => ( /> ); -const CoinIcon = ({ +const enhance = onlyUpdateForKeys(['bgColor', 'symbol']); + +const CoinIcon = enhance(({ + bgColor, showShadow, size, symbol, ...props }) => ( +console.log('bgColor', bgColor), showShadow ? ( ) : ( ) -); +)); CoinIcon.propTypes = { + bgColor: PropTypes.string, showShadow: PropTypes.bool, size: PropTypes.number, symbol: PropTypes.string, @@ -68,5 +74,4 @@ CoinIcon.defaultProps = { CoinIcon.size = CoinIconSize; -const enhance = onlyUpdateForKeys(['symbol']); -export default hoistStatics(enhance)(CoinIcon); +export default CoinIcon; diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 01d89399bed..cbd94042750 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,21 +1,21 @@ import PropTypes from 'prop-types'; -import React from 'react'; -import { compose } from 'recompact'; +import React, { Component } from 'react'; +import { compose, withHandlers } from 'recompact'; import { View } from 'react-native' import { NavigationEvents } from 'react-navigation'; -import styled from 'styled-components'; +import styled from 'styled-components/primitives'; import { Column, FlexItem, Row } from '../components/layout'; import { Modal, ModalHeader } from '../components/modal'; import AssetList from '../components/asset-list/RecyclerAssetList'; import { SendCoinRow } from '../components/coin-row'; import GestureBlocker from '../components/GestureBlocker'; import { Monospace, TruncatedText } from '../components/text'; +import { withAccountData } from '../hoc'; import { borders, colors } from '../styles'; import StarIcon from '../components/icons/svg/StarIcon'; import { ModalHeaderHeight } from '../components/modal/ModalHeader'; import { BackButton } from '../components/header'; import Flex from '../components/layout/Flex'; -import { withAccountData } from '../hoc'; import { exchangeModalBorderRadius } from './ExchangeModal'; const HeaderContainer = styled(Row).attrs({ @@ -29,7 +29,6 @@ const HeaderContainer = styled(Row).attrs({ width: 100%; `; - const BackButtonWrapper = styled(Flex).attrs({ align: 'center', justify: 'center', @@ -53,12 +52,9 @@ BottomRow.propTypes = { symbol: PropTypes.string, }; - const StarRender = ({ favorite }) => ( - + ); @@ -66,62 +62,87 @@ StarRender.propTypes = { favorite: PropTypes.bool, }; -const CurrencyRenderItem = ({ - index, - item: { symbol, ...item }, - section: { onSelectAsset }, -}) => ( +const CurrencyRenderItem = ({ item, onPress }) => ( ); - CurrencyRenderItem.propTypes = { index: PropTypes.number, item: PropTypes.shape({ symbol: PropTypes.string }), - section: PropTypes.shape({ onSelectAsset: PropTypes.func }), + onPress: PropTypes.func, }; -class SelectCurrencyModal extends React.Component { +const EnhancedCurrencyRenderItem = withHandlers({ + onPress: ({ item: { symbol }, onPress }) => () => onPress(symbol), +})(CurrencyRenderItem); + +class SelectCurrencyModal extends Component { + static propTypes = { + allAssets: PropTypes.array, + navigation: PropTypes.object, + } + + callback = null + + componentDidMount() { + this.callback = this.props.navigation.getParam('onSelectCurrency'); + } + + componentDidUpdate() { + this.callback = this.props.navigation.getParam('onSelectCurrency'); + } + + dangerouslySetIsGestureBlocked = (isGestureBlocked) => { + // dangerouslyGetParent is a bad pattern in general, but in this case is exactly what we expect + this.props.navigation.dangerouslyGetParent().setParams({ isGestureBlocked }); + } + + handleWillBlur = () => this.dangerouslySetIsGestureBlocked(false) + + handleWillFocus = () => this.dangerouslySetIsGestureBlocked(true) + + handlePressBack = () => this.props.navigation.navigate('MainExchangeScreen') + + handleSelectAsset = (symbol) => { + // It's a bit weird and I'm not sure why on invoking + // navigation.getParam('onSelectCurrency')(symbol) + // but this small hack seems to be a legit workaround + this.callback(symbol); + this.props.navigation.navigate('MainExchangeScreen'); + } + + renderCurrencyItem = (itemProps) => ( + + ) + render() { - const { - allAssets, - navigation, - } = this.props; - const sections = [ + const fakeDataThatNeedsToBeHookedUp = [ { balances: true, - data: allAssets, - onSelectAsset: (symbol) => () => { - // It's a bit weird and I'm not sure why on invoking - // navigation.getParam('setSelectedCurrency')(symbol) - // but this small hack seems to be a legit workaround - this.callback(symbol); - navigation.navigate('MainExchangeScreen'); - }, - renderItem: CurrencyRenderItem, + data: this.props.allAssets, + renderItem: this.renderCurrencyItem, }, ]; - const currentCallback = navigation.getParam('setSelectedCurrency'); - if (currentCallback) { - this.callback = currentCallback; - } - return ( - + navigation.dangerouslyGetParent() - .setParams({ isGestureBlocked: true })} - onWillBlur={() => navigation.dangerouslyGetParent() - .setParams({ isGestureBlocked: false })} + onWillBlur={this.handleWillBlur} + onWillFocus={this.handleWillFocus} /> @@ -129,7 +150,7 @@ class SelectCurrencyModal extends React.Component { navigation.navigate('MainExchangeScreen')} + onPress={this.handlePressBack} size='8' /> @@ -144,7 +165,7 @@ class SelectCurrencyModal extends React.Component { @@ -153,12 +174,6 @@ class SelectCurrencyModal extends React.Component { } } - -SelectCurrencyModal.propTypes = { - allAssets: PropTypes.array, - navigation: PropTypes.object, -}; - export default compose( withAccountData, )(SelectCurrencyModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 0efe94dd822..485e0684c28 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,256 +1,160 @@ import PropTypes from 'prop-types'; -import React from 'react'; -import { - TextInput, - KeyboardAvoidingView, - Keyboard, - View, -} from 'react-native'; +import React, { Fragment } from 'react'; +import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { compose, withHandlers, withProps, withState, } from 'recompact'; -import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; -import { ButtonPressAnimation } from '../components/animations'; -import Button from '../components/buttons/Button'; -import BottomRowText from '../components/coin-row/BottomRowText'; -import CoinName from '../components/coin-row/CoinName'; -import CoinRow, { CoinRowPaddingVertical } from '../components/coin-row/CoinRow'; -import FloatingPanel from '../components/expanded-state/FloatingPanel'; -import FloatingPanels from '../components/expanded-state/FloatingPanels'; -import GestureBlocker from '../components/GestureBlocker'; -import { Icon } from '../components/icons'; +import { NavigationEvents } from 'react-navigation'; +import styled from 'styled-components/primitives'; import { Centered, Column, - FlexItem, - Row, - RowWithMargins, + ColumnWithMargins, } from '../components/layout'; -import { ModalHeader } from '../components/modal'; -import { Text } from '../components/text'; -import { withAccountData } from '../hoc'; -import withBlockedHorizontalSwipe from '../hoc/withBlockedHorizontalSwipe'; +import { withAccountData, withBlockedHorizontalSwipe } from '../hoc'; import { colors, padding, shadow } from '../styles'; +import FloatingPanels from '../components/expanded-state/FloatingPanels'; +import FloatingPanel from '../components/expanded-state/FloatingPanel'; +import { Emoji, Text } from '../components/text'; +import { + ConfirmExchangeButton, + ExchangeInputField, + ExchangeOutputField, +} from '../components/exchange'; +import GestureBlocker from '../components/GestureBlocker'; +import { SheetHandle } from '../components/sheet'; const Container = styled(Centered).attrs({ direction: 'column' })` background-color: transparent; height: 100%; `; -const DollarRow = styled(Row)` - ${padding(CoinRowPaddingVertical, 19, CoinRowPaddingVertical, 15)} - background-color: ${colors.white}; - align-content: center; - width: 100%; - justify-content: space-between; -`; - -const MonoTextInput = styled(TextInput)` - font-family: SFMono-Regular; -`; - -const ConfirmExchangeButton = styled(Button)` - ${shadow.build(0, 6, 10, colors.purple, 0.14)} - width: 100%; - height: 64; - padding-horizontal: 5; - align-self: center -`; - - -const FeeHolder = styled(View)` +const FeeHolder = styled.View` + ${padding(4, 10)} ${shadow.build(0, 6, 10, colors.dark, 0.14)} align-self: center; + border-color: ${colors.alpha(colors.white, 0.45)}; border-radius: 16; + border-width: 1; height: 32; - ${padding(4, 10)} margin-top: 32; - border-width: 1; - border-color: ${colors.alpha(colors.white, 0.45)}; `; export const exchangeModalBorderRadius = 30; - -const ExchangeRow = styled(View)` +const ExchangeRow = styled.View` width: 100%; padding-horizontal: 15; `; +const ExchangeModal = (props) => { + const { + inputAmount, + navigation, + onNavigationToCurrencySelection, + onPressConfirmExchange, + onPressSelectInputCurrency, + onPressSelectOutputCurrency, + outputAmount, + selectedInputCurrency, + selectedOutputCurrency, + setAmountToExchange, + setInputAmount, + setOutputAmount, + showConfirmButton, + } = props; + + console.log('navigation', navigation); -const MaxAction = ({ onPress }) => ( - - - 💰Max - - -); - -MaxAction.propTypes = { - onPress: PropTypes.func, -} - -const TopRow = ({ - navigateToCurrencySelection, amount, changeAmount, symbol, -}) => ( - - - - {symbol ? null : '–'} - - - - - - -); - -TopRow.propTypes = { - amount: PropTypes.number, - changeAmount: PropTypes.func, - navigateToCurrencySelection: PropTypes.func, - symbol: PropTypes.func, -}; - - -const ExchangeModal = ({ - amountToExchange, - onPressConfirmExchange, - onPressSelectCurrency, - onPressSelectTargetCurrency, - selectedCurrency, - selectedTargetCurrency, - setAmountToExchange, -}) => { return ( - + + + + + + Swap + + - - - null} - topRowRender={TopRow} - symbol={selectedCurrency} - /> - - $0.00 - - - null} - topRowRender={TopRow} - symbol={selectedTargetCurrency} + + {/* null} + topRowRender={() => null} + symbol={selectedOutputCurrency} + /> + */} - {selectedTargetCurrency - && - - - {Number(amountToExchange) ? - + {showConfirmButton && ( + + + + + {!!Number(inputAmount) && ( + - Hold to swap + Fee: $0.06 - : 'Enter an amount' } - - - {!!Number(amountToExchange) && - - 👾 Fee: $0.06 - - } - - } + + )} + + )} ); }; - ExchangeModal.propTypes = { - amountToExchange: PropTypes.number, + inputAmount: PropTypes.number, onPressConfirmExchange: PropTypes.func, - onPressSelectCurrency: PropTypes.func, - onPressSelectTargetCurrency: PropTypes.func, - selectedCurrency: PropTypes.number, - selectedTargetCurrency: PropTypes.number, + onPressSelectInputCurrency: PropTypes.func, + onPressSelectOutputCurrency: PropTypes.func, + outputAmount: PropTypes.number, + selectedInputCurrency: PropTypes.number, + selectedOutputCurrency: PropTypes.number, setAmountToExchange: PropTypes.func, - setSelectedCurrency: PropTypes.func, - setSelectedTargetCurrency: PropTypes.func, + setSelectedInputCurrency: PropTypes.func, + setSelectedOutputCurrency: PropTypes.func, + showConfirmButton: PropTypes.bool, }; const withMockedPrices = withProps({ @@ -260,28 +164,33 @@ const withMockedPrices = withProps({ export default compose( withAccountData, - withState('amountToExchange', 'setAmountToExchange', '0'), - withState('selectedCurrency', 'setSelectedCurrency', null), - withState('selectedTargetCurrency', 'setSelectedTargetCurrency', null), - withProps(({ - selectedCurrency, - allAssets: [{ symbol }], - }) => ({ selectedCurrency: selectedCurrency || symbol })), + withState('inputAmount', 'setInputAmount', null), + withState('outputAmount', 'setOutputAmount', null), + withState('showConfirmButton', 'setShowConfirmButton', false), + withState('selectedInputCurrency', 'setSelectedInputCurrency', 'ETH'), + withState('selectedOutputCurrency', 'setSelectedOutputCurrency', null), withHandlers({ - onPressConfirmExchange: - ({ navigation }) => () => { - Keyboard.dismiss(); - navigation.navigate('WalletScreen'); - }, - onPressSelectCurrency: ({ navigation, setSelectedCurrency }) => () => { + onSelectInputCurrency: ({ setSelectedInputCurrency }) => value => setSelectedInputCurrency(value), + onSelectOutputCurrency: ({ setSelectedOutputCurrency }) => value => setSelectedOutputCurrency(value), + }), + withHandlers({ + onNavigationToCurrencySelection: ({ selectedOutputCurrency, setShowConfirmButton }) => (lol) => { + console.log('LOLOL', lol); + + if (selectedOutputCurrency) { + setShowConfirmButton(true); + } + }, + onPressConfirmExchange: ({ navigation }) => () => { Keyboard.dismiss(); - navigation.navigate('CurrencySelectScreen', { setSelectedCurrency }); + navigation.navigate('WalletScreen'); + }, + onPressSelectInputCurrency: ({ navigation, onSelectInputCurrency }) => () => { + navigation.navigate('CurrencySelectScreen', { onSelectCurrency: onSelectInputCurrency }); + }, + onPressSelectOutputCurrency: ({ navigation, onSelectOutputCurrency, setShowConfirmButton }) => () => { + navigation.navigate('CurrencySelectScreen', { onSelectCurrency: onSelectOutputCurrency }); }, - onPressSelectTargetCurrency: - ({ navigation, setSelectedTargetCurrency }) => () => { - Keyboard.dismiss(); - navigation.navigate('CurrencySelectScreen', { setSelectedCurrency: setSelectedTargetCurrency }); - }, }), withBlockedHorizontalSwipe, withMockedPrices, diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 2a2aae86f13..e6d5df6a95e 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -86,7 +86,7 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = props => ; +const EnhancedExchangeModalNavigator = React.memo(props => ); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ ...navigation.state.params, @@ -190,6 +190,7 @@ const MainNavigator = createStackNavigator({ onTransitionEnd, onTransitionStart, }, + disableKeyboardHandling: true, // XXX not sure about this from rebase headerMode: 'none', initialRouteName: 'SwipeLayout', mode: 'modal', @@ -210,15 +211,15 @@ const AppContainerWithAnalytics = ({ ref, screenProps }) => ( return analytics.screen(`${routeName}${subRoute ? `>${subRoute}` : ''}`); } - if (prevRouteName === 'MainExchangeScreen' && routeName === 'WalletScreen') { - store.dispatch(updateTransitionProps({ blurColor: null })); - } else if (routeName === 'MainExchangeScreen') { - store.dispatch(updateTransitionProps({ blurColor: colors.alpha(colors.black, 0.9) })); - } - if (routeName !== prevRouteName) { let paramsToTrack = null; + if (prevRouteName === 'MainExchangeScreen' && routeName === 'WalletScreen') { + store.dispatch(updateTransitionProps({ blurColor: null })); + } else if (prevRouteName === 'WalletScreen' && routeName === 'MainExchangeScreen') { + store.dispatch(updateTransitionProps({ blurColor: colors.alpha(colors.black, 0.9) })); + } + if (routeName === 'ExpandedAssetScreen') { const { asset, type } = params; paramsToTrack = { From baf9ac222ef924f060e28b5d4d1c309d9f173aae Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 03:43:11 -0700 Subject: [PATCH 162/636] Add SearchIcon --- src/components/icons/Icon.js | 2 ++ src/components/icons/svg/CaretIcon.js | 2 ++ src/components/icons/svg/SearchIcon.js | 27 ++++++++++++++++++++++++++ src/styles/colors.js | 2 +- 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/components/icons/svg/SearchIcon.js diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index 5ec537f91dd..8a5de2f752e 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -24,6 +24,7 @@ import HandleIcon from './svg/HandleIcon'; import InboxIcon from './svg/InboxIcon'; import OfflineIcon from './svg/OfflineIcon'; import ProgressIcon from './svg/ProgressIcon'; +import SearchIcon from './svg/SearchIcon'; import SendIcon from './svg/SendIcon'; import SendSmallIcon from './svg/SendSmallIcon'; import ShareIcon from './svg/ShareIcon'; @@ -59,6 +60,7 @@ Icon.IconTypes = { inbox: InboxIcon, offline: OfflineIcon, progress: ProgressIcon, + search: SearchIcon, send: SendIcon, sendSmall: SendSmallIcon, share: ShareIcon, diff --git a/src/components/icons/svg/CaretIcon.js b/src/components/icons/svg/CaretIcon.js index 1996a97e7eb..c55593d8297 100644 --- a/src/components/icons/svg/CaretIcon.js +++ b/src/components/icons/svg/CaretIcon.js @@ -3,6 +3,7 @@ import React from 'react'; import { Path } from 'svgs'; import { withRotationForDirection } from '../../../hoc'; import { colors } from '../../../styles'; +import { directionPropType } from '../../../utils'; import Svg from '../Svg'; /* eslint-disable max-len */ @@ -29,6 +30,7 @@ const CaretIcon = ({ CaretIcon.propTypes = { color: PropTypes.string, + direction: directionPropType, size: PropTypes.number, }; diff --git a/src/components/icons/svg/SearchIcon.js b/src/components/icons/svg/SearchIcon.js new file mode 100644 index 00000000000..a1a6b91d25d --- /dev/null +++ b/src/components/icons/svg/SearchIcon.js @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Path } from 'svgs'; +import { colors } from '../../../styles'; +import Svg from '../Svg'; + +/* eslint-disable max-len */ +const SearchIcon = ({ color, ...props }) => ( + + + +); +/* eslint-disable max-len */ + +SearchIcon.propTypes = { + color: PropTypes.string, +}; + +SearchIcon.defaultProps = { + color: colors.black, +}; + +export default SearchIcon; diff --git a/src/styles/colors.js b/src/styles/colors.js index 1128d036851..5bd6043e61a 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -8,7 +8,7 @@ const base = { blueGreyDarker: '#0F0F11', // '15, 15, 17' blueGreyLight: '#A1A5AC', blueGreyLighter: '#666A73', // '102, 106, 115' - blueGreyLightest: '#8A8E97', // '138, 142, 151' + blueGreyLightest: '#888D96', // '136, 141, 150' blueGreyMedium: '#636875', // '99, 104, 117' blueGreyMediumLight: '#7b7f8a', // '123, 127, 138' dark: '#25292E', // '37, 41, 46' From 6a34d6ac1f482beb15562588225e6a60bb7c4c4d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 04:24:38 -0700 Subject: [PATCH 163/636] WIP swap ui polish --- .../buttons/HoldToAuthorizeButton.js | 83 ++--- .../exchange/ConfirmExchangeButton.js | 59 +-- .../exchange/ExchangeGasFeeButton.js | 54 +++ src/components/exchange/ExchangeInput.js | 77 ++++ src/components/exchange/ExchangeInputField.js | 113 +++--- .../exchange/ExchangeOutputField.js | 74 ++-- src/components/exchange/ExchangeSearch.js | 77 ++++ src/components/exchange/index.js | 4 +- src/components/modal/Modal.js | 13 +- src/screens/CurrencySelectModal.js | 198 ++++++---- src/screens/ExchangeModal.js | 345 +++++++++--------- src/screens/Routes.js | 12 +- yarn.lock | 37 ++ 13 files changed, 709 insertions(+), 437 deletions(-) create mode 100644 src/components/exchange/ExchangeGasFeeButton.js create mode 100644 src/components/exchange/ExchangeInput.js create mode 100644 src/components/exchange/ExchangeSearch.js diff --git a/src/components/buttons/HoldToAuthorizeButton.js b/src/components/buttons/HoldToAuthorizeButton.js index a38caf180b0..b5adc823a6f 100644 --- a/src/components/buttons/HoldToAuthorizeButton.js +++ b/src/components/buttons/HoldToAuthorizeButton.js @@ -1,17 +1,12 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { - LongPressGestureHandler, - State, - TapGestureHandler, -} from 'react-native-gesture-handler'; +import { LongPressGestureHandler, State, TapGestureHandler } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { withProps } from 'recompact'; import styled from 'styled-components/primitives'; import { colors, padding, position } from '../../styles'; -import { deviceUtils } from '../../utils'; -import { ScaleInAnimation } from '../animations'; +import { FadeInAnimation, ScaleInAnimation } from '../animations'; import { BiometryIcon, Icon } from '../icons'; import InnerBorder from '../InnerBorder'; import { Centered } from '../layout'; @@ -31,6 +26,12 @@ const { const ButtonBorderRadius = 30; const ButtonHeight = 59; + +const ButtonDisabledBgColor = { + dark: colors.darkGrey,// blueGreyLighter, + light: colors.lighterGrey, +}; + const ButtonShadows = { default: [ [0, 3, 5, colors.dark, 0.2], @@ -46,7 +47,7 @@ const ButtonShadows = { const progressDurationMs = 500; // @christian approves const Content = styled(Centered)` - ${padding(15)} + ${padding(15)}; border-radius: ${ButtonBorderRadius}; flex-grow: 0; height: ${ButtonHeight}; @@ -54,8 +55,9 @@ const Content = styled(Centered)` width: 100%; `; +const BiometryIconSize = 31; const IconContainer = styled(Centered)` - ${position.size(34)} + ${position.size(BiometryIconSize)}; left: 19; margin-bottom: 2; position: absolute; @@ -68,17 +70,6 @@ const Title = withProps({ weight: 'semibold', })(Text); -const GradientColors = { - default: { - from: colors.primaryBlue, - to: '#006FFF', - }, - disabled: { - from: colors.grey, - to: colors.grey, - }, -}; - const buildAnimation = (value, options) => { const { duration = 150, @@ -104,15 +95,17 @@ const HoldToAuthorizeButtonIcon = ({ animatedValue, isAuthorizing }) => { return ( - - - - - - + + + + + + + + ); }; @@ -124,15 +117,20 @@ HoldToAuthorizeButtonIcon.propTypes = { export default class HoldToAuthorizeButton extends PureComponent { static propTypes = { + backgroundColor: PropTypes.string, children: PropTypes.any, disabled: PropTypes.bool, isAuthorizing: PropTypes.bool, onLongPress: PropTypes.func.isRequired, + shadows: PropTypes.arrayOf(PropTypes.array), style: PropTypes.object, + theme: PropTypes.oneOf(['light', 'dark']), } static defaultProps = { + backgroundColor: colors.appleBlue, disabled: false, + theme: 'light', } state = { @@ -200,13 +198,17 @@ export default class HoldToAuthorizeButton extends PureComponent { render() { const { + backgroundColor, children, disabled, + shadows, style, + theme, ...props } = this.props; + const { isAuthorizing } = this.state; - const theme = disabled ? 'disabled' : 'default'; + const bgColor = disabled ? ButtonDisabledBgColor[theme] : backgroundColor; return ( @@ -216,22 +218,21 @@ export default class HoldToAuthorizeButton extends PureComponent { > - - + + {!disabled && ( + + )} - {this.state.isAuthorizing - ? 'Authorizing' - : children - } + {isAuthorizing ? 'Authorizing' : children} diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 913fb192893..5d978820cea 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -1,56 +1,29 @@ -import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { - // compose, - // withHandlers, - // withProps, - // withState, -} from 'recompact'; -import styled from 'styled-components/primitives'; -import { colors, padding, position, shadow } from '../../styles'; +import React from 'react'; +import { onlyUpdateForPropTypes } from 'recompact'; +import { colors } from '../../styles'; -import { Button } from '../buttons'; -import { Icon } from '../icons'; -import { Text } from '../text'; - - // ${shadow.build(0, 6, 10, colors.purple, 0.14)}; - // width: 100%; -// const ConfirmExchangeButton = styled(Button)` -// padding-horizontal: 5; -// `; - // height: 64; +import { HoldToAuthorizeButton } from '../buttons'; const ConfirmExchangeButton = ({ disabled, onPress, }) => ( - + : 'Hold to swap' + } + ); ConfirmExchangeButton.propTypes = { @@ -58,4 +31,4 @@ ConfirmExchangeButton.propTypes = { onPress: PropTypes.func, }; -export default ConfirmExchangeButton; +export default onlyUpdateForPropTypes(ConfirmExchangeButton); diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js new file mode 100644 index 00000000000..403a1f3efe4 --- /dev/null +++ b/src/components/exchange/ExchangeGasFeeButton.js @@ -0,0 +1,54 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { compose, pure, withHandlers } from 'recompact'; +import styled from 'styled-components/primitives'; +import { colors, padding, shadow } from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { RowWithMargins } from '../layout'; +import { Emoji, Text } from '../text'; + +const Container = styled(RowWithMargins)` + ${padding(5.5, 10)}; + ${shadow.build(0, 0, 1, colors.dark, 1)}; + border-color: ${colors.alpha(colors.white, 0.15)}; + border-radius: 16; + border-width: 1.75; +`; + +const enhance = compose( + pure, + withHandlers({ + onPress: ({ onPress }) => (event) => { + if (onPress) { + onPress(event); + } + }, + }), +); + +const ExchangeGasFeeButton = enhance(({ gasPrice, onPress }) => ( + + + + + {`Fee: ${gasPrice}`} + + + +)); + +ExchangeGasFeeButton.propTypes = { + gasPrice: PropTypes.string, + onPress: PropTypes.func, +}; + +export default ExchangeGasFeeButton; diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js new file mode 100644 index 00000000000..7b6023dbd93 --- /dev/null +++ b/src/components/exchange/ExchangeInput.js @@ -0,0 +1,77 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import TextInputMask from 'react-native-text-input-mask'; +import stylePropType from 'react-style-proptype'; +import { colors, fonts } from '../../styles'; + +export default class ExchangeInput extends PureComponent { + static propTypes = { + fontSize: PropTypes.string, + mask: PropTypes.string, + onChangeText: PropTypes.func, + placeholder: PropTypes.string, + placeholderTextColor: PropTypes.string, + style: stylePropType, + value: PropTypes.string, + } + + static defaultProps = { + fontSize: fonts.size.h2, + mask: '[099999999999].[9999999999999]', + placeholder: '0', + placeholderTextColor: colors.alpha(colors.blueGreyDark, 0.5), + } + + onChangeText = (formatted, extracted) => { + // console.log('formatted', typeof extracted, !!formatted, formatted); + // console.log('extracted', typeof extracted, !!extracted, extracted); + + const condition = !!extracted; + + // console.log('CONDITION', condition); + + const thing = condition ? formatted : ''; + // console.log('thing', thing); + + + + + // XXX TODO: some funky stuff is going on here related to the '$' symbol in the input mask + + this.props.onChangeText(thing); + } + + render = () => { + const { + fontSize, + mask, + onChangeText, + placeholder, + refInput, + placeholderTextColor, + style, + value, + } = this.props; + + return ( + + ); + } +} diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 72ab10b4d14..bad72001e5f 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -1,38 +1,39 @@ -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; -import { colors, position } from '../../styles'; +import { colors, fonts } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; -import { Input } from '../inputs'; import { - Centered, ColumnWithMargins, Row, RowWithMargins, } from '../layout'; -import { Monospace, Text } from '../text'; +import { Emoji, Text } from '../text'; +import ExchangeInput from './ExchangeInput'; -import TextInputMask from 'react-native-text-input-mask'; - -export default class ExchangeInputField extends PureComponent { +export default class ExchangeInputField extends Component { static propTypes = { - amount: PropTypes.string, + autoFocus: PropTypes.bool, + inputAmount: PropTypes.string, + inputCurrency: PropTypes.string, + nativeAmount: PropTypes.string, onPressMaxBalance: PropTypes.func, onPressSelectInputCurrency: PropTypes.string, - selectedInputCurrency: PropTypes.string, - setAmountToExchange: PropTypes.func, + setInputAmount: PropTypes.func, + setNativeAmount: PropTypes.func, } inputRef = React.createRef() maskRef = null + dollarRef = null + padding = 15 handleFocusInput = () => { - if (this.maskRef) { this.maskRef.focus(); } @@ -43,15 +44,24 @@ export default class ExchangeInputField extends PureComponent { this.maskRef = ref; } + handleDollarRef = (ref) => { + this.dollarRef = ref; + } + render = () => { const { - amount, + autoFocus, + inputAmount, + inputCurrency, + nativeAmount, onPressMaxBalance, onPressSelectInputCurrency, - selectedInputCurrency, - setAmountToExchange, + setInputAmount, + setNativeAmount, } = this.props; - // mask="[0...][-][9...]" + + + // mask="[0...][-][9...]" return ( @@ -65,63 +75,44 @@ export default class ExchangeInputField extends PureComponent { > - - - + - {selectedInputCurrency || 'Choose a Coin'} + {inputCurrency || 'Choose a Coin'} - - - $0.00 - - + - - - 💰Max - - + + + Max + diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index e566e3c86fb..5f7ba6a5e0f 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -1,24 +1,13 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; -import { TouchableWithoutFeedback } from 'react-native'; +import { withNeverRerender } from '../../hoc'; import { colors, padding, position, shadow } from '../../styles'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; -import { Input } from '../inputs'; -import { - Centered, - ColumnWithMargins, - Row, - RowWithMargins, -} from '../layout'; -import { Monospace, Text } from '../text'; import { EmDash } from '../html-entities'; - -import { - withNeverRerender, -} from '../../hoc'; -import { Icon } from '../icons'; +import { Row, RowWithMargins } from '../layout'; import { ShadowStack } from '../shadow-stack'; +import ExchangeInput from './ExchangeInput'; const paddingValue = 15; @@ -42,22 +31,12 @@ const FakeNotchThing = withNeverRerender(() => ( /> )); -// - // null} - // topRowRender={() => null} - // symbol={selectedOutputCurrency} - // /> - -class ExchangeOutputField extends React.Component { +class ExchangeOutputField extends PureComponent { static propTypes = { - amount: PropTypes.number, onPressSelectOutputCurrency: PropTypes.string, - selectedOutputCurrency: PropTypes.string, - setAmountToExchange: PropTypes.func, + outputAmount: PropTypes.number, + outputCurrency: PropTypes.string, + setOutputAmount: PropTypes.func, } inputRef = React.createRef() @@ -66,17 +45,15 @@ class ExchangeOutputField extends React.Component { render = () => { const { - amount, onPressSelectOutputCurrency, - selectedOutputCurrency, - setAmountToExchange, + outputAmount, + outputCurrency, + setOutputAmount, } = this.props; const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); const placeholderColor = colors.alpha(colors.blueGreyDark, 0.5); - console.log('selectedOutputCurrency', selectedOutputCurrency); - return ( - - {selectedOutputCurrency || 'Choose a Coin'} + {outputCurrency || 'Choose a Coin'} ); diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js new file mode 100644 index 00000000000..f9a9f368308 --- /dev/null +++ b/src/components/exchange/ExchangeSearch.js @@ -0,0 +1,77 @@ +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { compose, withHandlers } from 'recompact'; +import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; +import styled from 'styled-components/primitives'; +import { colors, margin, padding, position } from '../../styles'; +import { Icon } from '../icons'; +import { Input } from '../inputs'; +import InnerBorder from '../InnerBorder'; +import { RowWithMargins } from '../layout'; + +const Container = styled(RowWithMargins).attrs({ + margin: 6.5, +})` + ${margin(0, 15, 10)}; + ${padding(9, 13, 10)}; + background-color: ${colors.skeleton}; + border-radius: 20; +`; + +class ExchangeSearch extends PureComponent { + static propTypes = { + onChangeText: PropTypes.func, + } + + state = { + searchQuery: null, + } + + inputRef = React.createRef() + + focus = (event) => { + if (this.inputRef && this.inputRef.current) { + this.inputRef.current.focus(event); + } + } + + render = () => { + return ( + + + + + + + + ); + } +} + +export default ExchangeSearch; diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js index 8f1bc4daa54..6fc59587fa3 100644 --- a/src/components/exchange/index.js +++ b/src/components/exchange/index.js @@ -1,4 +1,6 @@ export { default as ConfirmExchangeButton } from './ConfirmExchangeButton'; +export { default as ExchangeGasFeeButton } from './ExchangeGasFeeButton'; +export { default as ExchangeInput } from './ExchangeInput'; export { default as ExchangeInputField } from './ExchangeInputField'; export { default as ExchangeOutputField } from './ExchangeOutputField'; - +export { default as ExchangeSearch } from './ExchangeSearch'; diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js index bf70e313216..6cd9bbb832c 100644 --- a/src/components/modal/Modal.js +++ b/src/components/modal/Modal.js @@ -7,10 +7,6 @@ import { deviceUtils } from '../../utils'; import { Centered, Column } from '../layout'; import TouchableBackdrop from '../TouchableBackdrop'; -const Container = styled(Centered)` - height: 100%; -`; - const ModalElement = styled(Column)` background-color: ${colors.white}; border-radius: ${({ radius }) => radius || 12}; @@ -26,14 +22,19 @@ const Modal = ({ containerPadding, ...props }) => ( - + - + ); Modal.propTypes = { diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index cbd94042750..f649af7fb99 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,41 +1,38 @@ import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React, { Component, PureComponent } from 'react'; import { compose, withHandlers } from 'recompact'; -import { View } from 'react-native' -import { NavigationEvents } from 'react-navigation'; +import { KeyboardAvoidingView, View } from 'react-native' +import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import styled from 'styled-components/primitives'; -import { Column, FlexItem, Row } from '../components/layout'; +import { Centered, Column, FlexItem, Row } from '../components/layout'; +import { deviceUtils, safeAreaInsetValues } from '../utils'; import { Modal, ModalHeader } from '../components/modal'; import AssetList from '../components/asset-list/RecyclerAssetList'; import { SendCoinRow } from '../components/coin-row'; import GestureBlocker from '../components/GestureBlocker'; import { Monospace, TruncatedText } from '../components/text'; import { withAccountData } from '../hoc'; -import { borders, colors } from '../styles'; +import { borders, colors, position } from '../styles'; import StarIcon from '../components/icons/svg/StarIcon'; import { ModalHeaderHeight } from '../components/modal/ModalHeader'; import { BackButton } from '../components/header'; import Flex from '../components/layout/Flex'; +import { ExchangeSearch } from '../components/exchange'; import { exchangeModalBorderRadius } from './ExchangeModal'; -const HeaderContainer = styled(Row).attrs({ - align: 'center', +const HeaderContainer = styled(Centered).attrs({ flex: 0, - justify: 'center', })` ${borders.buildRadius('top', 12)}; background-color: ${colors.white}; - height: ${ModalHeaderHeight}; + height: 60; width: 100%; `; -const BackButtonWrapper = styled(Flex).attrs({ - align: 'center', - justify: 'center', -})` +const BackButtonWrapper = styled(Centered)` left: 0; - position: absolute; margin-left: 15; + position: absolute; `; const BottomRow = ({ balance, symbol }) => ( @@ -52,26 +49,20 @@ BottomRow.propTypes = { symbol: PropTypes.string, }; -const StarRender = ({ favorite }) => ( - - - -); - -StarRender.propTypes = { - favorite: PropTypes.bool, -}; - -const CurrencyRenderItem = ({ item, onPress }) => ( +const CurrencyRenderItem = ({ favorite, item, onPress }) => ( + > + + + + ); CurrencyRenderItem.propTypes = { + favorite: PropTypes.bool, index: PropTypes.number, item: PropTypes.shape({ symbol: PropTypes.string }), onPress: PropTypes.func, @@ -81,7 +72,7 @@ const EnhancedCurrencyRenderItem = withHandlers({ onPress: ({ item: { symbol }, onPress }) => () => onPress(symbol), })(CurrencyRenderItem); -class SelectCurrencyModal extends Component { +class SelectCurrencyModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, navigation: PropTypes.object, @@ -89,12 +80,30 @@ class SelectCurrencyModal extends Component { callback = null + keyboardHeight = 0 + + viewportHeight = deviceUtils.dimensions.height + + searchInputRef = React.createRef() + componentDidMount() { - this.callback = this.props.navigation.getParam('onSelectCurrency'); + this.getDataFromParams(); } componentDidUpdate() { - this.callback = this.props.navigation.getParam('onSelectCurrency'); + this.getDataFromParams(); + } + + getDataFromParams = () => { + const { navigation } = this.props; + + this.callback = navigation.getParam('onSelectCurrency'); + this.keyboardHeight = navigation.getParam('keyboardHeight'); + + // console.log('getDataFromParams this.keyboardHeight', this.keyboardHeight); + + this.viewportHeight = deviceUtils.dimensions.height - this.keyboardHeight; + // console.log('getDataFromParams this.viewportHeight', this.viewportHeight); } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { @@ -123,7 +132,24 @@ class SelectCurrencyModal extends Component { /> ) + handleDidFocus = () => { + // setTimeout(() => this.searchInputRef.current.focus(), 500); + } + render() { + const magicNumber = this.viewportHeight + ? (this.viewportHeight - 10) // - 5 + : 0; + + if (!!this.viewportHeight) { + // console.log(' ') + // console.log('SelectCurrencyModal -- isFocused', this.props.isFocused); + // console.log('magicNumber', magicNumber); + // console.log('SelectCurrencyModal -- this.props', this.props); + // console.log('this.viewportHeight', this.viewportHeight); + // console.log(' ') + } + const fakeDataThatNeedsToBeHookedUp = [ { balances: true, @@ -133,47 +159,89 @@ class SelectCurrencyModal extends Component { ]; return ( - - - - - - - - - + + + - Receive - - - - - - + + + + + + + + + Receive + + + + + + + + + + ); } } export default compose( withAccountData, + withNavigationFocus, )(SelectCurrencyModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 485e0684c28..300157ab011 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,161 +1,199 @@ import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; -import { Keyboard, KeyboardAvoidingView } from 'react-native'; -import { - compose, - withHandlers, - withProps, - withState, -} from 'recompact'; -import { NavigationEvents } from 'react-navigation'; -import styled from 'styled-components/primitives'; +import React, { Fragment, PureComponent } from 'react'; +import { KeyboardAvoidingView, View } from 'react-native'; +import { compose, withProps } from 'recompact'; +import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { Centered, Column, ColumnWithMargins, } from '../components/layout'; -import { withAccountData, withBlockedHorizontalSwipe } from '../hoc'; -import { colors, padding, shadow } from '../styles'; +import { + withAccountData, + withBlockedHorizontalSwipe, + withNeverRerender, +} from '../hoc'; +import { colors, padding, position } from '../styles'; +import { deviceUtils, safeAreaInsetValues } from '../utils'; import FloatingPanels from '../components/expanded-state/FloatingPanels'; import FloatingPanel from '../components/expanded-state/FloatingPanel'; -import { Emoji, Text } from '../components/text'; +import { Text } from '../components/text'; import { ConfirmExchangeButton, + ExchangeGasFeeButton, ExchangeInputField, ExchangeOutputField, } from '../components/exchange'; import GestureBlocker from '../components/GestureBlocker'; import { SheetHandle } from '../components/sheet'; -const Container = styled(Centered).attrs({ direction: 'column' })` - background-color: transparent; - height: 100%; -`; - -const FeeHolder = styled.View` - ${padding(4, 10)} - ${shadow.build(0, 6, 10, colors.dark, 0.14)} - align-self: center; - border-color: ${colors.alpha(colors.white, 0.45)}; - border-radius: 16; - border-width: 1; - height: 32; - margin-top: 32; -`; - export const exchangeModalBorderRadius = 30; -const ExchangeRow = styled.View` - width: 100%; - padding-horizontal: 15; -`; - -const ExchangeModal = (props) => { - const { - inputAmount, - navigation, - onNavigationToCurrencySelection, - onPressConfirmExchange, - onPressSelectInputCurrency, - onPressSelectOutputCurrency, - outputAmount, - selectedInputCurrency, - selectedOutputCurrency, - setAmountToExchange, - setInputAmount, - setOutputAmount, - showConfirmButton, - } = props; - - console.log('navigation', navigation); - - return ( - - - - - - - - - - Swap - - - - - - {/* null} - topRowRender={() => null} - symbol={selectedOutputCurrency} - /> - */} - - - - {showConfirmButton && ( - - - - - {!!Number(inputAmount) && ( - - - Fee: $0.06 - - +const ExchangeModalHeader = withNeverRerender(() => ( + + + + Swap + + +)); + +class ExchangeModal extends PureComponent { + static propTypes = { + inputAmount: PropTypes.number, + navigation: PropTypes.object, + outputAmount: PropTypes.number, + showConfirmButton: PropTypes.bool, + } + + state = { + inputAmount: null, + inputCurrency: 'ETH', + // keyboardHeight: 0, + nativeAmount: null, + outputAmount: null, + outputCurrency: null, + showConfirmButton: false, + } + + keyboardHeight = null + + inputFieldRef = null + + setInputAmount = inputAmount => this.setState({ inputAmount }) + + setNativeAmount = nativeAmount => this.setState({ nativeAmount }) + + setOutputAmount = outputAmount => this.setState({ outputAmount }) + + setInputCurrency = inputCurrency => this.setState({ inputCurrency }) + + setOutputCurrency = outputCurrency => this.setState({ outputCurrency }) + + handleSelectInputCurrency = () => { + this.props.navigation.navigate('CurrencySelectScreen', { + keyboardHeight: this.keyboardHeight, + onSelectCurrency: this.setInputCurrency, + }); + } + + handleSelectOutputCurrency = () => { + this.props.navigation.navigate('CurrencySelectScreen', { + keyboardHeight: this.keyboardHeight, + onSelectCurrency: this.setOutputCurrency, + }); + } + + handleSubmit = () => { + this.props.navigation.navigate('WalletScreen'); + } + + handleWillFocus = () => { + if (this.state.outputCurrency) { + this.setState({ showConfirmButton: true }); + } + } + + handleInputFieldRef = (ref) => { + this.inputFieldRef = ref; + } + + handleDidFocus = () => { + if (this.inputFieldRef) { + // setTimeout(() => this.inputFieldRef.focus(), 500); + } + } + + lolThing = ({ nativeEvent: { layout } }) => { + if (!this.keyboardHeight) { + this.keyboardHeight = deviceUtils.dimensions.height - layout.height;// - safeAreaInsetValues.bottom; + } + } + + render = () => { + const { onPressConfirmExchange } = this.props; + + const { + inputAmount, + inputCurrency, + nativeAmount, + outputAmount, + outputCurrency, + showConfirmButton, + } = this.state; + + return ( + + + + + + + + + + + + + + + + {showConfirmButton && ( + + + + + {!!Number(inputAmount) && ( + + )} + )} - - )} - - - - ); -}; - -ExchangeModal.propTypes = { - inputAmount: PropTypes.number, - onPressConfirmExchange: PropTypes.func, - onPressSelectInputCurrency: PropTypes.func, - onPressSelectOutputCurrency: PropTypes.func, - outputAmount: PropTypes.number, - selectedInputCurrency: PropTypes.number, - selectedOutputCurrency: PropTypes.number, - setAmountToExchange: PropTypes.func, - setSelectedInputCurrency: PropTypes.func, - setSelectedOutputCurrency: PropTypes.func, - showConfirmButton: PropTypes.bool, -}; + + + + + ); + } +} const withMockedPrices = withProps({ currencyToDollar: 3, @@ -164,34 +202,7 @@ const withMockedPrices = withProps({ export default compose( withAccountData, - withState('inputAmount', 'setInputAmount', null), - withState('outputAmount', 'setOutputAmount', null), - withState('showConfirmButton', 'setShowConfirmButton', false), - withState('selectedInputCurrency', 'setSelectedInputCurrency', 'ETH'), - withState('selectedOutputCurrency', 'setSelectedOutputCurrency', null), - withHandlers({ - onSelectInputCurrency: ({ setSelectedInputCurrency }) => value => setSelectedInputCurrency(value), - onSelectOutputCurrency: ({ setSelectedOutputCurrency }) => value => setSelectedOutputCurrency(value), - }), - withHandlers({ - onNavigationToCurrencySelection: ({ selectedOutputCurrency, setShowConfirmButton }) => (lol) => { - console.log('LOLOL', lol); - - if (selectedOutputCurrency) { - setShowConfirmButton(true); - } - }, - onPressConfirmExchange: ({ navigation }) => () => { - Keyboard.dismiss(); - navigation.navigate('WalletScreen'); - }, - onPressSelectInputCurrency: ({ navigation, onSelectInputCurrency }) => () => { - navigation.navigate('CurrencySelectScreen', { onSelectCurrency: onSelectInputCurrency }); - }, - onPressSelectOutputCurrency: ({ navigation, onSelectOutputCurrency, setShowConfirmButton }) => () => { - navigation.navigate('CurrencySelectScreen', { onSelectCurrency: onSelectOutputCurrency }); - }, - }), withBlockedHorizontalSwipe, + withNavigationFocus, withMockedPrices, )(ExchangeModal); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index e6d5df6a95e..ac7c976e2ad 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -52,6 +52,7 @@ const SwipeStack = createMaterialTopTabNavigator({ }, }, { headerMode: 'none', + initialLayout: deviceUtils.dimensions, initialRouteName: 'WalletScreen', mode: 'modal', springConfig: { @@ -78,12 +79,20 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ }, { headerMode: 'none', initialLayout: deviceUtils.dimensions, + keyboardDismissMode: 'none', mode: 'modal', + springConfig: { + damping: 16, + mass: 0.3, + overshootClamping: false, + restDisplacementThreshold: 1, + restSpeedThreshold: 1, + stiffness: 140, + }, tabBarComponent: null, transparentCard: true, }); - // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen const EnhancedExchangeModalNavigator = React.memo(props => ); @@ -193,6 +202,7 @@ const MainNavigator = createStackNavigator({ disableKeyboardHandling: true, // XXX not sure about this from rebase headerMode: 'none', initialRouteName: 'SwipeLayout', + keyboardDismissMode: true, mode: 'modal', }); diff --git a/yarn.lock b/yarn.lock index ed6d0e93601..87ec66ac70d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4170,13 +4170,28 @@ electron-to-chromium@^1.3.191: integrity sha512-gachlDdHSK47s0N2e58GH9HMC6Z4ip0SfmYUa5iEbE50AKaOUXysaJnXMfKj0xB245jWbYcyFSH+th3rqsF8hA== ======= electron-to-chromium@^1.3.188: +<<<<<<< HEAD version "1.3.188" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.188.tgz#e28e1afe4bb229989e280bfd3b395c7ec03c8b7a" integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> d743296d... BREAK UP +<<<<<<< HEAD >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components +======= +======= +======= +======= + version "1.3.190" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz#5bf599519983bfffd9d4387817039a3ed7ca085f" + integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== +>>>>>>> 9a56f78d... WIP swap ui polish +>>>>>>> 2db58de2... WIP swap ui polish +>>>>>>> 30cb3e0d... WIP swap ui polish +>>>>>>> 397368cb... WIP swap ui polish elliptic@6.3.3: version "6.3.3" @@ -7098,9 +7113,12 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= +<<<<<<< HEAD <<<<<<< HEAD lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: ======= +======= +>>>>>>> 2db58de2... WIP swap ui polish <<<<<<< HEAD lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: >>>>>>> d743296d... BREAK UP @@ -7109,6 +7127,9 @@ lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13 integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== ======= lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: +======= +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: +>>>>>>> 9a56f78d... WIP swap ui polish version "4.17.14" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== @@ -9180,7 +9201,23 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +<<<<<<< HEAD +======= +react-clone-referenced-element@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" + integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== + +<<<<<<< HEAD +react-coin-icon@^0.1.9: +======= +<<<<<<< HEAD +react-coin-icon@^0.1.8: +======= +>>>>>>> 397368cb... WIP swap ui polish react-coin-icon@^0.1.9: +>>>>>>> 9a56f78d... WIP swap ui polish +>>>>>>> 2db58de2... WIP swap ui polish version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== From c56945a80d3adca85574cee9c6a9179de41a655b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 04:27:25 -0700 Subject: [PATCH 164/636] idk --- src/components/exchange/ExchangeSearch.js | 2 ++ src/screens/CurrencySelectModal.js | 4 +--- src/screens/Routes.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index f9a9f368308..5eb61fb4eee 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -16,10 +16,12 @@ const Container = styled(RowWithMargins).attrs({ ${padding(9, 13, 10)}; background-color: ${colors.skeleton}; border-radius: 20; + height: 40; `; class ExchangeSearch extends PureComponent { static propTypes = { + autoFocus: PropTypes.bool, onChangeText: PropTypes.func, } diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index f649af7fb99..bb56c16dc12 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React, { Component, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import { compose, withHandlers } from 'recompact'; import { KeyboardAvoidingView, View } from 'react-native' import { NavigationEvents, withNavigationFocus } from 'react-navigation'; @@ -14,9 +14,7 @@ import { Monospace, TruncatedText } from '../components/text'; import { withAccountData } from '../hoc'; import { borders, colors, position } from '../styles'; import StarIcon from '../components/icons/svg/StarIcon'; -import { ModalHeaderHeight } from '../components/modal/ModalHeader'; import { BackButton } from '../components/header'; -import Flex from '../components/layout/Flex'; import { ExchangeSearch } from '../components/exchange'; import { exchangeModalBorderRadius } from './ExchangeModal'; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index ac7c976e2ad..da508ac58f3 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -95,7 +95,7 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = React.memo(props => ); +const EnhancedExchangeModalNavigator = props => ; // React.memo(); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ ...navigation.state.params, From 8855004f431c7e7b722367c9044730934b6cf5c7 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 04:30:26 -0700 Subject: [PATCH 165/636] fix conflicts after rebasing over latest wallet-zero branch --- ios/Podfile.lock | 74 +++++++++++ src/screens/WalletScreen.js | 15 +-- yarn.lock | 238 ++++++++++++++++++++++++------------ 3 files changed, 240 insertions(+), 87 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index de0068a39ec..bf164d97317 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -45,11 +45,24 @@ PODS: - GoogleToolboxForMac/Defines (= 2.2.1) - "GoogleToolboxForMac/NSData+zlib (2.2.1)": - GoogleToolboxForMac/Defines (= 2.2.1) +<<<<<<< HEAD - libwebp (1.0.3): - libwebp/demux (= 1.0.3) - libwebp/mux (= 1.0.3) - libwebp/webp (= 1.0.3) - libwebp/demux (1.0.3): +======= + - libwebp (1.0.2): + - libwebp/core (= 1.0.2) + - libwebp/dec (= 1.0.2) + - libwebp/demux (= 1.0.2) + - libwebp/dsp (= 1.0.2) + - libwebp/enc (= 1.0.2) + - libwebp/mux (= 1.0.2) + - libwebp/utils (= 1.0.2) + - libwebp/webp (= 1.0.2) + - libwebp/core (1.0.2): +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch - libwebp/webp - libwebp/mux (1.0.3): - libwebp/demux @@ -60,6 +73,7 @@ PODS: - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - Protobuf (3.9.0) +<<<<<<< HEAD - React (0.60.5): - React-Core (= 0.60.5) - React-DevSupport (= 0.60.5) @@ -105,6 +119,10 @@ PODS: - React-cxxreact (= 0.60.5) - React-jsi (= 0.60.5) - React-jsinspector (0.60.5) +======= + - React (0.59.9): + - React/Core (= 0.59.9) +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -150,9 +168,21 @@ PODS: - React - RNCAsyncStorage (1.5.0): - React +<<<<<<< HEAD - RNCMaskedView (0.1.1): - React +<<<<<<< HEAD - RNDeviceInfo (2.3.2): +======= +<<<<<<< HEAD + - RNDeviceInfo (2.3.1): +======= + - RNDeviceInfo (2.3.0): +======= + - RNDeviceInfo (2.3.1): +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch - React - RNIOS11DeviceCheck (0.0.3): - React @@ -162,12 +192,25 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React +<<<<<<< HEAD - RNStoreReview (0.1.5): - React +<<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) - SDWebImage/Core (5.1.1) - yoga (0.60.5.React) +======= + - SDWebImage (5.0.2): + - SDWebImage/Core (= 5.0.2) + - SDWebImage/Core (5.0.2) +======= + - SDWebImage (5.0.6): + - SDWebImage/Core (= 5.0.6) + - SDWebImage/Core (5.0.6) +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch + - yoga (0.59.9.React) +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -318,6 +361,7 @@ SPEC CHECKSUMS: FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 +<<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 @@ -331,6 +375,15 @@ SPEC CHECKSUMS: React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 +======= + Folly: de497beb10f102453a1afa9edbf8cf8a251890de + glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d + GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 + libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a + React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 @@ -348,15 +401,36 @@ SPEC CHECKSUMS: React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 +<<<<<<< HEAD RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 +<<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +======= +<<<<<<< HEAD + RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 +======= + RNDeviceInfo: 65106cc87ad6f6f71ef2ecc667f4c59b840888e2 +======= + RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 +<<<<<<< HEAD RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 +<<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 +======= + SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 +======= + SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch + yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index d135246691f..f3c14dca244 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -13,11 +13,7 @@ import { import { AssetList } from '../components/asset-list'; import BlurOverlay from '../components/BlurOverlay'; import { FabWrapper } from '../components/fab'; -import { - CameraHeaderButton, - Header, - ProfileHeaderButton, -} from '../components/header'; +import { CameraHeaderButton, Header, ProfileHeaderButton } from '../components/header'; import { Page } from '../components/layout'; import { getSmallBalanceToggle, @@ -32,8 +28,8 @@ import { withDataInit, withIsWalletEmpty, withIsWalletEthZero, - withUniqueTokens, withStatusBarStyle, + withUniqueTokens, withUniswapLiquidity, } from '../hoc'; import { setOpenSmallBalances } from '../redux/openBalances'; @@ -41,7 +37,7 @@ import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; -import { isNewValueForPath } from '../utils'; +import { deviceUtils, isNewValueForPath } from '../utils'; class WalletScreen extends Component { static propTypes = { @@ -117,6 +113,11 @@ class WalletScreen extends Component { sections, } = this.props; + const blurTranslateY = blurOpacity.interpolate({ + inputRange: [0, 0.001, 1], + outputRange: [deviceUtils.dimensions.height, 0, 0], + }); + return ( {/* Line below appears to be needed for having scrollViewTracker persistent while diff --git a/yarn.lock b/yarn.lock index 87ec66ac70d..092fe6b9c9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,6 @@ integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== ======= "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": -<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -55,6 +54,7 @@ ======= "@babel/traverse" "^7.5.5" "@babel/types" "^7.5.5" +<<<<<<< HEAD ======= version "7.5.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd" @@ -69,6 +69,8 @@ "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -88,6 +90,7 @@ source-map "^0.5.0" trim-right "^1.0.1" +<<<<<<< HEAD <<<<<<< HEAD "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": version "7.6.0" @@ -97,12 +100,15 @@ "@babel/types" "^7.6.0" ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== dependencies: "@babel/types" "^7.5.5" +<<<<<<< HEAD ======= "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.0": version "7.5.0" @@ -112,6 +118,8 @@ "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -149,6 +157,7 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" +<<<<<<< HEAD <<<<<<< HEAD "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": version "7.6.0" @@ -156,10 +165,13 @@ integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/helper-create-class-features-plugin@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== +<<<<<<< HEAD ======= "@babel/helper-create-class-features-plugin@^7.5.0": version "7.5.0" @@ -167,6 +179,8 @@ integrity sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.5.5" @@ -329,6 +343,7 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" +<<<<<<< HEAD <<<<<<< HEAD "@babel/helpers@^7.6.0": version "7.6.0" @@ -340,6 +355,8 @@ "@babel/types" "^7.6.0" ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/helpers@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" @@ -348,6 +365,7 @@ "@babel/template" "^7.4.4" "@babel/traverse" "^7.5.5" "@babel/types" "^7.5.5" +<<<<<<< HEAD ======= "@babel/helpers@^7.5.4": version "7.5.4" @@ -359,6 +377,8 @@ "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" @@ -378,6 +398,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" +<<<<<<< HEAD <<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" @@ -385,10 +406,13 @@ integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== +<<<<<<< HEAD ======= "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.0": version "7.5.0" @@ -396,6 +420,8 @@ integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -405,19 +431,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": -<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" -======= - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007" - integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": @@ -437,15 +455,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": -<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== -======= - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331" - integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -713,6 +725,7 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": +<<<<<<< HEAD <<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" @@ -728,6 +741,11 @@ integrity sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" + integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -765,6 +783,7 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": +<<<<<<< HEAD <<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz#48d78405f1aa856ebeea7288a48a19ed8da377a6" @@ -773,11 +792,14 @@ "@babel/helper-create-class-features-plugin" "^7.6.0" ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" +<<<<<<< HEAD ======= version "7.5.2" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz#ea7da440d29b8ccdb1bd02e18f6cfdc7ce6c16f5" @@ -786,6 +808,8 @@ "@babel/helper-create-class-features-plugin" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -823,16 +847,18 @@ >>>>>>> 751dba29... Replace navigation animations with new effects ======= "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": -<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== +<<<<<<< HEAD ======= version "7.5.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b" integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch dependencies: regenerator-runtime "^0.13.2" @@ -871,6 +897,7 @@ invariant "^2.2.0" lodash "^4.2.0" +<<<<<<< HEAD <<<<<<< HEAD "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": version "7.6.0" @@ -878,6 +905,8 @@ integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" @@ -894,6 +923,7 @@ ======= "@babel/parser" "^7.5.5" "@babel/types" "^7.5.5" +<<<<<<< HEAD ======= "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.0": version "7.5.0" @@ -908,6 +938,8 @@ "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" @@ -921,6 +953,7 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +<<<<<<< HEAD <<<<<<< HEAD "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": version "7.6.1" @@ -928,10 +961,13 @@ integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== +<<<<<<< HEAD ======= "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0": version "7.5.0" @@ -939,6 +975,8 @@ integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1300,7 +1338,6 @@ integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== ======= "@react-native-community/cli-platform-android@^2.0.0-rc.2": -<<<<<<< HEAD version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== @@ -1310,6 +1347,7 @@ chalk "^2.4.2" execa "^1.0.0" jetifier "^1.6.2" +<<<<<<< HEAD <<<<<<< HEAD logkitty "^0.6.0" slash "^3.0.0" @@ -1352,12 +1390,13 @@ "@react-native-community/cli-tools" "^2.4.1" chalk "^2.4.2" >>>>>>> 8d2e8d2f... BREAK UP +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch logkitty "^0.5.0" slash "^2.0.0" xmldoc "^0.4.0" "@react-native-community/cli-platform-ios@^2.0.0-rc.2": -<<<<<<< HEAD version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== @@ -1378,6 +1417,7 @@ version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== +<<<<<<< HEAD ======= version "2.4.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" @@ -1393,6 +1433,8 @@ integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1799,12 +1841,15 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch version "12.6.8" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== @@ -1824,6 +1869,7 @@ version "8.10.51" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627" integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== +<<<<<<< HEAD ======= version "12.6.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" @@ -1840,6 +1886,8 @@ integrity sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch "@types/q@^1.5.1": version "1.5.2" @@ -2039,6 +2087,7 @@ acorn@^5.5.3: integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.1, acorn@^6.0.7: +<<<<<<< HEAD <<<<<<< HEAD version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" @@ -2054,6 +2103,11 @@ acorn@^6.0.1, acorn@^6.0.7: integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= + version "6.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" + integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch aes-js@3.0.0: version "3.0.0" @@ -2065,18 +2119,13 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -<<<<<<< HEAD agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: -======= -agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@^4.3.0: ->>>>>>> 8d2e8d2f... BREAK UP version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" -<<<<<<< HEAD agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -2088,12 +2137,6 @@ ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== -======= -ajv@^6.5.5, ajv@^6.9.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" - integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -2534,12 +2577,12 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" -<<<<<<< HEAD babel-plugin-rewire@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ== +<<<<<<< HEAD <<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ======= @@ -2552,7 +2595,13 @@ babel-plugin-rewire@^1.2.0: "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> d743296d... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components +======= +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -2891,6 +2940,7 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.6.3: +<<<<<<< HEAD <<<<<<< HEAD version "4.7.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" @@ -2901,20 +2951,14 @@ browserslist@^4.6.3: node-releases "^1.1.29" ======= <<<<<<< HEAD +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch version "4.6.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== dependencies: caniuse-lite "^1.0.30000984" electron-to-chromium "^1.3.191" -======= - version "4.6.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" - integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== - dependencies: - caniuse-lite "^1.0.30000981" - electron-to-chromium "^1.3.188" ->>>>>>> 8d2e8d2f... BREAK UP node-releases "^1.1.25" >>>>>>> f7a61a13... Create Exchange related Input components @@ -3058,6 +3102,7 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: @@ -3077,7 +3122,10 @@ caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz#92f16d00186a6cf20d6c5711bb6e042a3d667029" integrity sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw== ======= +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: +<<<<<<< HEAD <<<<<<< HEAD version "1.0.30000987" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" @@ -3093,7 +3141,15 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components +======= +======= + version "1.0.30000987" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" + integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch capture-exit@^1.2.0: version "1.2.0" @@ -3710,11 +3766,7 @@ csso@^3.5.1: dependencies: css-tree "1.0.0-alpha.29" -<<<<<<< HEAD cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": -======= -"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: ->>>>>>> 8d2e8d2f... BREAK UP version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== @@ -4141,6 +4193,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD electron-to-chromium@^1.3.247: @@ -4154,12 +4207,17 @@ electron-to-chromium@^1.3.164: integrity sha512-uqKh3J1/s4LkmtbrVi2cPpd5g2u7efYJdnRXApQLVhZlLjzaJZakafp+JFSUZNYrBDJNIqQChcJTCDZXqQOBYg== >>>>>>> 751dba29... Replace navigation animations with new effects ======= +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch electron-to-chromium@^1.3.191: +<<<<<<< HEAD <<<<<<< HEAD version "1.3.205" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== ======= +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch <<<<<<< HEAD version "1.3.200" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" @@ -4190,8 +4248,19 @@ electron-to-chromium@^1.3.188: integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== >>>>>>> 9a56f78d... WIP swap ui polish >>>>>>> 2db58de2... WIP swap ui polish +<<<<<<< HEAD >>>>>>> 30cb3e0d... WIP swap ui polish +<<<<<<< HEAD >>>>>>> 397368cb... WIP swap ui polish +======= +======= +======= + version "1.3.205" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" + integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch elliptic@6.3.3: version "6.3.3" @@ -5114,8 +5183,8 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -<<<<<<< HEAD form-data@^2.3.3: +<<<<<<< HEAD <<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -5124,6 +5193,8 @@ form-data@^2.3.3: ======= form-data@^2.3.1: >>>>>>> 8d2e8d2f... BREAK UP +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch version "2.5.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== @@ -7113,6 +7184,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: @@ -7120,20 +7192,13 @@ lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13 ======= >>>>>>> 2db58de2... WIP swap ui polish <<<<<<< HEAD +======= +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: >>>>>>> d743296d... BREAK UP version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -======= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: -======= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: ->>>>>>> 9a56f78d... WIP swap ui polish - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== ->>>>>>> 8d2e8d2f... BREAK UP log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" @@ -9112,15 +9177,9 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: -<<<<<<< HEAD version "1.4.1" resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w== -======= - version "1.4.0" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.0.tgz#b4b41b4bbfd5eeac8d5163efacef34ee5b8ad455" - integrity sha512-18u+bdSosXO0+wx6F1UUFzJz01VRfMBcb/wbBw/tKYRD0A2Vho5WQ4xz30pHwhh4IE/qhObqIs5yNO0mGdHKkA== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: dijkstrajs "^1.0.1" isarray "^2.0.1" @@ -9208,6 +9267,7 @@ react-clone-referenced-element@^1.0.1: resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== +<<<<<<< HEAD <<<<<<< HEAD react-coin-icon@^0.1.9: ======= @@ -9218,6 +9278,9 @@ react-coin-icon@^0.1.8: react-coin-icon@^0.1.9: >>>>>>> 9a56f78d... WIP swap ui polish >>>>>>> 2db58de2... WIP swap ui polish +======= +react-coin-icon@^0.1.9: +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== @@ -9274,15 +9337,9 @@ react-native-circular-progress@^1.1.0: prop-types "^15.7.2" react-native-clean-project@^3.1.0: -<<<<<<< HEAD version "3.2.4" resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.4.tgz#55a71006eb4336dff91d0ca5ab3564d8f0db45cc" integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== -======= - version "3.2.3" - resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.3.tgz#40313a3a4131353d5d082d7691b41b4de6f40eb2" - integrity sha512-c8NgNTXAwugyuP+bS5b5mwpML4JrSP+u9D5b6X5OudU6hPlzPsiFLnBzQUvJVSPRHRwCFj30/qHGCjLc/jPzUw== ->>>>>>> 8d2e8d2f... BREAK UP react-native-code-push@^5.6.0: version "5.7.0" @@ -9314,9 +9371,27 @@ react-native-crypto@^2.1.2: randomfill "^1.0.3" react-native-device-info@^2.1.3: +<<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +======= +<<<<<<< HEAD + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" + integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== +======= +<<<<<<< HEAD + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.0.tgz#7b2a8baf8453324bd8d120ce46e5e2bb0181ccd4" + integrity sha512-ISEChH2zg4bRX8PL1cYoNWffJ7wmgYosKyJbkWyTxs8g+rpeGkmMf9Wo4COriAt1AJ2jC78IGhJYFzbIc+Przw== +======= + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" + integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch react-native-dotenv@^0.2.0: version "0.2.0" @@ -9365,15 +9440,13 @@ react-native-haptic-feedback@^1.8.2: ======= react-native-haptic-feedback@^1.8.0: <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> d743296d... BREAK UP +======= +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -======= - version "1.8.1" - resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.1.tgz#7e255fa7421dccd5d1da35f2a6bb922c253324a2" - integrity sha512-Y/lXN9S70TJIqg1F4984OlJ/2k0Nt6/5dAyilhVr4CFVvIulFf2dHAXkB1I+OlBiY9iuiCKtw5RixXad5jFEbw== ->>>>>>> 8d2e8d2f... BREAK UP react-native-indicators@^0.13.0: version "0.13.0" @@ -9521,6 +9594,7 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" +<<<<<<< HEAD <<<<<<< HEAD "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: ======= @@ -9530,6 +9604,9 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> d743296d... BREAK UP +======= +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -9583,9 +9660,9 @@ react-native-tcp@^3.2.1: util "^0.10.3" react-native-text-input-mask@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.1.tgz#93b4374c3c73bc78eac907094662d5d98166f359" - integrity sha512-gN0N+3tpw1kgHsuaqzugN7hc5XsjlyXET4/Q3C36F6LxwpIdnf3k9yCL4vfAlw6QxwuBTtyFaRxGJgwZkzk4Ng== + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" + integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== react-native-tooltip@^5.2.0: version "5.2.0" @@ -11082,6 +11159,7 @@ styled-components@4.3.1: stylis-rule-sheet "^0.0.10" supports-color "^5.5.0" +<<<<<<< HEAD <<<<<<< HEAD styled-components@^5.0.0-beta.8: <<<<<<< HEAD @@ -11093,12 +11171,17 @@ styled-components@^5.0.0-beta.8: resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.6-ej4.tgz#7570ebbf9c9356a8cca03ea37dd94233f2e40e84" integrity sha512-WaytinYy4+Zc1TKXdTlPmkAOIj58QWvjn1rdgxCSAMAR4GFLlu2m7rQXwZ6WYWYk6GJd141rnZnE2Ig3XERc5A== ======= +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch styled-components@5.0.0-beta.8: version "5.0.0-beta.8" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8.tgz#ad1e672589a891987f5492cbe3ca6f480fcd99dc" integrity sha512-g4MrDmfaoR2jJnA56+JSTFf1ZsDpJYdvTyQSw3HWOHoV/KlCgaSFmU8TrHfTy7DwWQskxyX//IQInNZdn4mGcA== +<<<<<<< HEAD >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -12017,7 +12100,6 @@ wide-align@1.1.3, wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -<<<<<<< HEAD widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" @@ -12025,8 +12107,6 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" -======= ->>>>>>> 8d2e8d2f... BREAK UP wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -12328,15 +12408,13 @@ yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: ======= yargs@^13.0.0, yargs@^13.2.4: <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components +======= +>>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== -======= - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: cliui "^5.0.0" find-up "^3.0.0" From 2b4a8a0cda9478465bc7e3194607015f4903221f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 02:25:54 -0700 Subject: [PATCH 166/636] begin mike --- ios/Podfile.lock | 30 ++- package.json | 20 +- src/components/fab/ExchangeFab.js | 19 +- src/components/fab/FloatingActionButton.js | 4 +- src/components/fab/SendFab.js | 2 + src/components/icons/Icon.js | 2 + src/components/icons/svg/SwapIcon.js | 26 ++ src/styles/colors.js | 1 + yarn.lock | 285 ++++++++++++--------- 9 files changed, 245 insertions(+), 144 deletions(-) create mode 100644 src/components/icons/svg/SwapIcon.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bf164d97317..1199a55db11 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -168,12 +168,14 @@ PODS: - React - RNCAsyncStorage (1.5.0): - React -<<<<<<< HEAD - RNCMaskedView (0.1.1): - React +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= +======= +>>>>>>> 96db5a28... begin mike <<<<<<< HEAD - RNDeviceInfo (2.3.1): ======= @@ -182,7 +184,13 @@ PODS: - RNDeviceInfo (2.3.1): >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + - RNDeviceInfo (2.3.1): +>>>>>>> dc42f3f4... begin mike +>>>>>>> 96db5a28... begin mike - React - RNIOS11DeviceCheck (0.0.3): - React @@ -192,9 +200,9 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React -<<<<<<< HEAD - RNStoreReview (0.1.5): - React +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -205,10 +213,11 @@ PODS: - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) ======= +======= +>>>>>>> 96db5a28... begin mike - SDWebImage (5.0.6): - SDWebImage/Core (= 5.0.6) - SDWebImage/Core (5.0.6) ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch - yoga (0.59.9.React) >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch @@ -401,11 +410,13 @@ SPEC CHECKSUMS: React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 -<<<<<<< HEAD RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= +======= +>>>>>>> 96db5a28... begin mike <<<<<<< HEAD RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 ======= @@ -414,21 +425,28 @@ SPEC CHECKSUMS: RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 +>>>>>>> dc42f3f4... begin mike +>>>>>>> 96db5a28... begin mike RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 -<<<<<<< HEAD RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 ======= SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 ======= +======= +>>>>>>> 96db5a28... begin mike SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch diff --git a/package.json b/package.json index cc670a04bc1..ee9fdd9d782 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "react-native-keychain": "^3.1.3", "react-native-languages": "^3.0.0", "react-native-level-fs": "^3.0.1", - "react-native-linear-gradient": "^2.5.4", + "react-native-linear-gradient": "^2.5.6", "react-native-mail": "^3.0.6", "react-native-os": "^1.2.2", "react-native-permissions": "^1.1.1", @@ -87,15 +87,15 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "1.2.0", - "react-native-redash": "^7.2.1", + "react-native-redash": "^7.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "^9.5.1", + "react-native-svg": "^9.5.3", "react-native-tcp": "^3.3.0", - "react-native-text-input-mask": "^1.0.1", + "react-native-text-input-mask": "^1.0.4", "react-native-tooltip": "^5.2.0", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", @@ -133,7 +133,7 @@ "@react-native-community/cli": "2.9.0", "@react-native-community/eslint-config": "^0.0.5", "babel-core": "7.0.0-bridge.0", - "babel-eslint": "^8.2.2", + "babel-eslint": "^10.0.2", "babel-jest": "^24.8.0", "babel-plugin-date-fns": "^0.2.1", "babel-plugin-lodash": "^3.3.4", @@ -141,10 +141,10 @@ "babel-plugin-rewire": "^1.2.0", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", - "eslint": "^5.16.0", - "eslint-config-airbnb-base": "^13.1.0", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-react": "^7.13.0", + "eslint": "^6.1.0", + "eslint-config-airbnb-base": "^13.2.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-react": "^7.14.3", "eslint-plugin-react-native": "^3.7.0", "eslint-plugin-react-native-animation-linter": "^0.1.2", "jest": "^24.8.0", @@ -152,7 +152,7 @@ "mocha": "^6.1.4", "react-native-clean-project": "^3.1.0", "react-test-renderer": "16.8.3", - "schedule": "0.4.0" + "schedule": "0.5.0" }, "resolutions": { "**/eslint-plugin-import": "2.14.0", diff --git a/src/components/fab/ExchangeFab.js b/src/components/fab/ExchangeFab.js index 0f9195800b3..d0cff646c7c 100644 --- a/src/components/fab/ExchangeFab.js +++ b/src/components/fab/ExchangeFab.js @@ -7,24 +7,23 @@ import { pure, withHandlers, } from 'recompact'; -import Icon from '../icons/Icon'; -import FloatingActionButton from './FloatingActionButton'; +import { withFabSelection } from '../../hoc'; import { colors } from '../../styles'; +import { Icon } from '../icons'; +import FloatingActionButton from './FloatingActionButton'; const ExchangeFab = ({ disabled, onPress, ...props }) => ( ); @@ -35,7 +34,7 @@ ExchangeFab.propTypes = { }; export default compose( - pure, + withFabSelection, withNavigation, withHandlers({ onPress: ({ navigation }) => () => { diff --git a/src/components/fab/FloatingActionButton.js b/src/components/fab/FloatingActionButton.js index 61f138fd679..222dc0d07b4 100644 --- a/src/components/fab/FloatingActionButton.js +++ b/src/components/fab/FloatingActionButton.js @@ -17,6 +17,7 @@ const FabShadow = [ export default class FloatingActionButton extends Component { static propTypes = { + backgroundColor: PropTypes.string, children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), disabled: PropTypes.bool, isFabSelectionValid: PropTypes.bool, @@ -58,6 +59,7 @@ export default class FloatingActionButton extends Component { render = () => { const { + backgroundColor, children, disabled, isFabSelectionValid, @@ -84,7 +86,7 @@ export default class FloatingActionButton extends Component { diff --git a/src/components/fab/SendFab.js b/src/components/fab/SendFab.js index 9942b4a760f..6ce81487bef 100644 --- a/src/components/fab/SendFab.js +++ b/src/components/fab/SendFab.js @@ -9,6 +9,7 @@ import { withProps, } from 'recompact'; import { withFabSelection } from '../../hoc'; +import { colors } from '../../styles'; import { Icon } from '../icons'; import { Centered } from '../layout'; // import DeleteButton from './DeleteButton'; @@ -40,6 +41,7 @@ const SendFab = ({ > */} ( + + + +); +/* eslint-disable max-len */ + +SwapIcon.propTypes = { + color: PropTypes.string, +}; + +SwapIcon.defaultProps = { + color: colors.white, +}; + +export default SwapIcon; diff --git a/src/styles/colors.js b/src/styles/colors.js index 5bd6043e61a..3a467bdeac1 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -13,6 +13,7 @@ const base = { blueGreyMediumLight: '#7b7f8a', // '123, 127, 138' dark: '#25292E', // '37, 41, 46' darkGrey: '#71778a', // '113, 119, 138' + dodgerBlue: '#575CFF', // '87, 92, 255' green: '#00994d', // '0, 153, 77' grey: '#a9adb9', // '169, 173, 185' headerTitle: '#aaafbd', // '170, 175, 189' diff --git a/yarn.lock b/yarn.lock index 092fe6b9c9c..8145d8f290c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" - integrity sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g== - dependencies: - "@babel/highlight" "7.0.0-beta.44" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" @@ -16,6 +9,7 @@ dependencies: "@babel/highlight" "^7.0.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": @@ -24,6 +18,9 @@ integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== ======= "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": +======= +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": +>>>>>>> 96db5a28... begin mike version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -79,6 +76,7 @@ semver "^5.4.1" source-map "^0.5.0" +<<<<<<< HEAD "@babel/generator@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" @@ -102,6 +100,8 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 96db5a28... begin mike "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" @@ -206,15 +206,6 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-function-name@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" - integrity sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg== - dependencies: - "@babel/helper-get-function-arity" "7.0.0-beta.44" - "@babel/template" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - "@babel/helper-function-name@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" @@ -224,13 +215,6 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-get-function-arity@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" - integrity sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw== - dependencies: - "@babel/types" "7.0.0-beta.44" - "@babel/helper-get-function-arity@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" @@ -319,13 +303,6 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-split-export-declaration@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" - integrity sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA== - dependencies: - "@babel/types" "7.0.0-beta.44" - "@babel/helper-split-export-declaration@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" @@ -380,15 +357,6 @@ ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -"@babel/highlight@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" - integrity sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^3.0.0" - "@babel/highlight@^7.0.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" @@ -833,6 +801,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": @@ -847,6 +816,9 @@ >>>>>>> 751dba29... Replace navigation animations with new effects ======= "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": +======= +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": +>>>>>>> 96db5a28... begin mike version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== @@ -862,6 +834,7 @@ dependencies: regenerator-runtime "^0.13.2" +<<<<<<< HEAD "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" @@ -876,11 +849,18 @@ version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== +======= +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" + integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== +>>>>>>> 96db5a28... begin mike dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" +<<<<<<< HEAD "@babel/traverse@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" @@ -907,6 +887,8 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 96db5a28... begin mike "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" @@ -944,6 +926,7 @@ globals "^11.1.0" lodash "^4.17.13" +<<<<<<< HEAD "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" @@ -963,6 +946,8 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 96db5a28... begin mike "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" @@ -1330,6 +1315,7 @@ dependencies: prop-types "^15.5.10" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": @@ -1338,6 +1324,9 @@ integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== ======= "@react-native-community/cli-platform-android@^2.0.0-rc.2": +======= +"@react-native-community/cli-platform-android@^2.7.0": +>>>>>>> 96db5a28... begin mike version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== @@ -1396,7 +1385,7 @@ slash "^2.0.0" xmldoc "^0.4.0" -"@react-native-community/cli-platform-ios@^2.0.0-rc.2": +"@react-native-community/cli-platform-ios@^2.8.0": version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== @@ -1406,6 +1395,7 @@ chalk "^1.1.1" xcode "^2.0.0" +<<<<<<< HEAD <<<<<<< HEAD "@react-native-community/cli-tools@^2.0.0-alpha.14", "@react-native-community/cli-tools@^2.0.2": version "2.0.2" @@ -1414,6 +1404,9 @@ >>>>>>> 751dba29... Replace navigation animations with new effects ======= "@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": +======= +"@react-native-community/cli-tools@^2.7.0": +>>>>>>> 96db5a28... begin mike version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== @@ -1441,6 +1434,7 @@ mime "^2.4.1" node-fetch "^2.5.0" +<<<<<<< HEAD "@react-native-community/cli@2.9.0", "@react-native-community/cli@^2.6.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" @@ -1450,6 +1444,17 @@ "@react-native-community/cli-platform-android" "^2.9.0" "@react-native-community/cli-platform-ios" "^2.9.0" "@react-native-community/cli-tools" "^2.8.3" +======= +"@react-native-community/cli@2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.0.tgz#346ff73ace6b2265d99ec217a8624b8735d19930" + integrity sha512-sN43IyvBtFtC1iOjx3pfKeo7DK4wkJxWiggR3QkkNQdyjuGT3RGXiYZVPu+zda6BPKdeGYpS+7UJrkGT+1tuFg== + dependencies: + "@hapi/joi" "^15.0.3" + "@react-native-community/cli-platform-android" "^2.7.0" + "@react-native-community/cli-platform-ios" "^2.8.0" + "@react-native-community/cli-tools" "^2.7.0" +>>>>>>> 96db5a28... begin mike chalk "^2.4.2" commander "^2.19.0" compression "^1.7.1" @@ -2133,7 +2138,7 @@ agent-base@~4.2.1: dependencies: es6-promisify "^5.0.0" -ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== @@ -2503,15 +2508,15 @@ babel-eslint@10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-eslint@^8.2.2: - version "8.2.6" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" - integrity sha512-aCdHjhzcILdP8c9lej7hvXKvQieyRt20SF102SIGyY4cUIiw6UaAtK4j2o3dXX74jEmy0TJ0CEhv4fTIM3SzcA== +babel-eslint@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.2.tgz#182d5ac204579ff0881684b040560fdcc1558456" + integrity sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q== dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/traverse" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" @@ -2582,6 +2587,7 @@ babel-plugin-rewire@^1.2.0: resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ== +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: @@ -2602,6 +2608,9 @@ babel-plugin-rewire@^1.2.0: "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +>>>>>>> 96db5a28... begin mike version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -2684,11 +2693,6 @@ babel-runtime@^6.22.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babylon@7.0.0-beta.44: - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" - integrity sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g== - backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -3457,7 +3461,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +<<<<<<< HEAD commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: +======= +commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: +>>>>>>> 96db5a28... begin mike version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -4211,6 +4219,7 @@ electron-to-chromium@^1.3.164: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch electron-to-chromium@^1.3.191: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.3.205" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" @@ -4260,7 +4269,15 @@ electron-to-chromium@^1.3.188: integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "1.3.205" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" + integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== +>>>>>>> dc42f3f4... begin mike +>>>>>>> 96db5a28... begin mike elliptic@6.3.3: version "6.3.3" @@ -4444,7 +4461,7 @@ escodegen@1.x.x, escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" -eslint-config-airbnb-base@^13.1.0: +eslint-config-airbnb-base@^13.2.0: version "13.2.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.2.0.tgz#f6ea81459ff4dec2dda200c35f1d8f7419d57943" integrity sha512-1mg/7eoB4AUeB0X1c/ho4vb2gYkNH8Trr/EgCT/aGmKhhG+F6vF5s8+iRBlWAzFIAphxIdp3YfEKgEl0f9Xg+w== @@ -4500,8 +4517,12 @@ eslint-plugin-import@2.14.0: read-pkg-up "^2.0.0" resolve "^1.6.0" +<<<<<<< HEAD eslint-plugin-import@^2.14.0: <<<<<<< HEAD +======= +eslint-plugin-import@^2.18.2: +>>>>>>> 96db5a28... begin mike version "2.18.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== @@ -4584,8 +4605,12 @@ eslint-plugin-react@7.12.4: prop-types "^15.6.2" resolve "^1.9.0" +<<<<<<< HEAD <<<<<<< HEAD eslint-plugin-react@^7.13.0: +======= +eslint-plugin-react@^7.14.3: +>>>>>>> 96db5a28... begin mike version "7.14.3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== @@ -4614,7 +4639,7 @@ eslint-scope@3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^4.0.0, eslint-scope@^4.0.3: +eslint-scope@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== @@ -4622,6 +4647,14 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-utils@^1.3.1: version "1.4.2" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" @@ -4634,52 +4667,53 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^5.16.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== +eslint@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" + integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.9.1" + ajv "^6.10.0" chalk "^2.1.0" cross-spawn "^6.0.5" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^4.0.3" + eslint-scope "^5.0.0" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^5.0.1" + espree "^6.0.0" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" - glob "^7.1.2" + glob-parent "^5.0.0" globals "^11.7.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.2.2" - js-yaml "^3.13.0" + inquirer "^6.4.1" + is-glob "^4.0.0" + js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.11" + lodash "^4.17.14" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.2" progress "^2.0.0" regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" table "^5.2.3" text-table "^0.2.0" + v8-compile-cache "^2.0.3" -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== +espree@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6" + integrity sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q== dependencies: acorn "^6.0.7" acorn-jsx "^5.0.0" @@ -5396,6 +5430,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" + integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + dependencies: + is-glob "^4.0.1" + glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" @@ -5971,10 +6012,17 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" +<<<<<<< HEAD inquirer@^6.2.2: version "6.5.2" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== +======= +inquirer@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" + integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== +>>>>>>> 96db5a28... begin mike dependencies: ansi-escapes "^3.2.0" chalk "^2.4.2" @@ -6181,7 +6229,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0: +is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -6785,17 +6833,12 @@ js-sha3@0.5.7: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= -js-tokens@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.13.1, js-yaml@^3.13.0, js-yaml@^3.13.1: +js-yaml@3.13.1, js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -7184,18 +7227,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: -======= -======= ->>>>>>> 2db58de2... WIP swap ui polish -<<<<<<< HEAD -======= ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: ->>>>>>> d743296d... BREAK UP +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -8721,7 +8753,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1, path-is-inside@^1.0.2: +path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -9267,6 +9299,7 @@ react-clone-referenced-element@^1.0.1: resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD react-coin-icon@^0.1.9: @@ -9279,8 +9312,9 @@ react-coin-icon@^0.1.9: >>>>>>> 9a56f78d... WIP swap ui polish >>>>>>> 2db58de2... WIP swap ui polish ======= +======= +>>>>>>> 96db5a28... begin mike react-coin-icon@^0.1.9: ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== @@ -9371,11 +9405,14 @@ react-native-crypto@^2.1.2: randomfill "^1.0.3" react-native-device-info@^2.1.3: +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== ======= +======= +>>>>>>> 96db5a28... begin mike <<<<<<< HEAD version "2.3.1" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" @@ -9391,7 +9428,15 @@ react-native-device-info@^2.1.3: integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" + integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== +>>>>>>> dc42f3f4... begin mike +>>>>>>> 96db5a28... begin mike react-native-dotenv@^0.2.0: version "0.2.0" @@ -9435,15 +9480,7 @@ react-native-gesture-handler@^1.4.1: invariant "^2.2.4" prop-types "^15.7.2" -<<<<<<< HEAD react-native-haptic-feedback@^1.8.2: -======= -react-native-haptic-feedback@^1.8.0: -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> d743296d... BREAK UP -======= ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== @@ -9594,19 +9631,7 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" -<<<<<<< HEAD -<<<<<<< HEAD "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: -======= -<<<<<<< HEAD -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.22: -======= -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> d743296d... BREAK UP -======= -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -10514,10 +10539,22 @@ sax@^1.2.1, sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +<<<<<<< HEAD schedule@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.4.0.tgz#fa20cfd0bfbf91c47d02272fd7096780d3170bbb" integrity sha512-hYjmoaEMojiMkWCxKr6ue+LYcZ29u29+AamWYmzwT2VOO9ws5UJp/wNhsVUPiUeNh+EdRfZm7nDeB40ffTfMhA== +======= +sax@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" + integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= + +schedule@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" + integrity sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw== +>>>>>>> 96db5a28... begin mike dependencies: object-assign "^4.1.1" @@ -10560,7 +10597,11 @@ semver@5.5.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== +<<<<<<< HEAD semver@^6.0.0, semver@^6.1.1, semver@^6.2.0: +======= +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2: +>>>>>>> 96db5a28... begin mike version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -11131,11 +11172,16 @@ strip-indent@^2.0.0: resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= -strip-json-comments@2.0.1, strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: +strip-json-comments@2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + style-search@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" @@ -11944,6 +11990,11 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== +v8-compile-cache@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" From 86d031bf93194496a6f5e8b23d591882230138ca Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 6 Aug 2019 03:21:58 -0700 Subject: [PATCH 167/636] Cleanup ButtonPressAnimation --- ios/Podfile.lock | 28 ++ package.json | 5 +- .../animations/ButtonPressAnimation.js | 336 +++++++++----- src/components/coin-icon/CoinIcon.js | 1 - src/components/coin-row/CoinRow.js | 3 - src/components/coin-row/ExchangeCoinRow.js | 107 +++++ src/components/coin-row/index.js | 1 + src/components/fab/ExchangeFab.js | 13 +- src/components/icons/Icon.js | 2 + src/screens/CurrencySelectModal.js | 42 +- src/screens/ExampleScreen.js | 42 +- yarn.lock | 435 +++++++++++++++++- 12 files changed, 820 insertions(+), 195 deletions(-) create mode 100644 src/components/coin-row/ExchangeCoinRow.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1199a55db11..41e7afe9f84 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -171,11 +171,14 @@ PODS: - RNCMaskedView (0.1.1): - React <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> e1a27438... Cleanup ButtonPressAnimation <<<<<<< HEAD - RNDeviceInfo (2.3.1): ======= @@ -190,7 +193,13 @@ PODS: ======= - RNDeviceInfo (2.3.1): >>>>>>> dc42f3f4... begin mike +<<<<<<< HEAD >>>>>>> 96db5a28... begin mike +======= +======= + - RNDeviceInfo (2.3.2): +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> e1a27438... Cleanup ButtonPressAnimation - React - RNIOS11DeviceCheck (0.0.3): - React @@ -203,6 +212,7 @@ PODS: - RNStoreReview (0.1.5): - React <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -218,6 +228,11 @@ PODS: - SDWebImage (5.0.6): - SDWebImage/Core (= 5.0.6) - SDWebImage/Core (5.0.6) +======= + - SDWebImage (5.1.0): + - SDWebImage/Core (= 5.1.0) + - SDWebImage/Core (5.1.0) +>>>>>>> e1a27438... Cleanup ButtonPressAnimation - yoga (0.59.9.React) >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch @@ -412,11 +427,14 @@ SPEC CHECKSUMS: RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> e1a27438... Cleanup ButtonPressAnimation <<<<<<< HEAD RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 ======= @@ -431,13 +449,20 @@ SPEC CHECKSUMS: ======= RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 >>>>>>> dc42f3f4... begin mike +<<<<<<< HEAD >>>>>>> 96db5a28... begin mike +======= +======= + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> e1a27438... Cleanup ButtonPressAnimation RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -447,6 +472,9 @@ SPEC CHECKSUMS: ======= >>>>>>> 96db5a28... begin mike SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 +======= + SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f +>>>>>>> e1a27438... Cleanup ButtonPressAnimation yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch diff --git a/package.json b/package.json index ee9fdd9d782..50fa9b1d24a 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "react-native-store-review": "^0.1.5", "react-native-svg": "^9.5.3", "react-native-tcp": "^3.3.0", - "react-native-text-input-mask": "^1.0.4", + "react-native-text-input-mask": "^1.0.6", "react-native-tooltip": "^5.2.0", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", @@ -137,8 +137,8 @@ "babel-jest": "^24.8.0", "babel-plugin-date-fns": "^0.2.1", "babel-plugin-lodash": "^3.3.4", - "babel-plugin-styled-components": "^1.10.6", "babel-plugin-rewire": "^1.2.0", + "babel-plugin-styled-components": "^1.10.6", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", "eslint": "^6.1.0", @@ -150,6 +150,7 @@ "jest": "^24.8.0", "metro-react-native-babel-preset": "^0.56.0", "mocha": "^6.1.4", + "react-native-bundle-visualizer": "^2.0.1", "react-native-clean-project": "^3.1.0", "react-test-renderer": "16.8.3", "schedule": "0.5.0" diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index cb145ac14fa..c0e9d272ec1 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -1,181 +1,273 @@ -import { compact } from 'lodash'; +import { omit, pick, toUpper } from 'lodash'; import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import { Animated } from 'react-native'; -import { State, TapGestureHandler } from 'react-native-gesture-handler'; +import React, { Fragment, PureComponent } from 'react'; +import { InteractionManager } from 'react-native'; +import { createNativeWrapper, PureNativeButton, State } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import { animations } from '../../styles'; +import Animated, { Easing } from 'react-native-reanimated'; +import { + contains, + runDelay, + runTiming, + transformOrigin as transformOriginUtil, +} from 'react-native-redash'; +import stylePropType from 'react-style-proptype'; +import { animations, colors } from '../../styles'; import { directionPropType } from '../../utils'; -const ButtonKeyframes = animations.keyframes.button; +const { + block, + call, + Clock, + cond, + createAnimatedComponent, + divide, + eq, + event, + floor, + greaterThan, + interpolate, + multiply, + onChange, + or, + set, + Value, +} = Animated; -const DefaultAnimatedValues = { - opacity: 1, - scale: ButtonKeyframes.from.scale, - transX: 0, +const { + ACTIVE, + BEGAN, + CANCELLED, + END, + FAILED, + UNDETERMINED, +} = State; + +const TransformOriginMap = { + BOTTOM: 3, + LEFT: 4, + RIGHT: 2, + TOP: 1, }; -let buttonExcludingMutex = null; +const { + BOTTOM, + LEFT, + RIGHT, + TOP, +} = TransformOriginMap; + +const AnimatedRawButton = createNativeWrapper( + createAnimatedComponent(PureNativeButton), + { + shouldActivateOnStart: true, + shouldCancelWhenOutside: false, + }, +); + +const NOOP = () => undefined; export default class ButtonPressAnimation extends PureComponent { static propTypes = { activeOpacity: PropTypes.number, children: PropTypes.any, + defaultScale: PropTypes.number, disabled: PropTypes.bool, + duration: PropTypes.number, + easing: PropTypes.object, enableHapticFeedback: PropTypes.bool, + exclusive: PropTypes.bool, + isInteraction: PropTypes.bool, onPress: PropTypes.func, scaleTo: PropTypes.number, - style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), + style: stylePropType, tapRef: PropTypes.object, transformOrigin: directionPropType, - waitFor: PropTypes.any, } static defaultProps = { + activeOpacity: 1, + defaultScale: animations.keyframes.button.from.scale, + duration: 200, + easing: Easing.bezier(0.25, 0.46, 0.45, 0.94), enableHapticFeedback: true, - scaleTo: ButtonKeyframes.to.scale, + exclusive: true, + scaleTo: animations.keyframes.button.to.scale, } - state = { scaleOffsetX: null } + constructor(props) { + super(props); - opacity = new Animated.Value(DefaultAnimatedValues.opacity) + this.clock = new Clock(); + this.gestureState = new Value(UNDETERMINED); + this.handle = undefined; + this.scale = new Value(1); + this.shouldSpring = new Value(-1); - scale = new Animated.Value(DefaultAnimatedValues.scale) + this.state = { + height: 0, + width: 0, + }; - transX = new Animated.Value(DefaultAnimatedValues.transX) + this.transformOrigin = props.transformOrigin + ? TransformOriginMap[toUpper(props.transformOrigin)] + : undefined; - componentWillUnmount = () => { - this.opacity.stopAnimation(); - this.scale.stopAnimation(); - this.transX.stopAnimation(); - } + const isDirectionNegative = or( + eq(this.transformOrigin, LEFT), + eq(this.transformOrigin, TOP), + ); - handleLayout = ({ nativeEvent: { layout } }) => { - const { scaleTo, transformOrigin } = this.props; + this.directionMultiple = cond(isDirectionNegative, -1, 1); - if (transformOrigin) { - const width = Math.floor(layout.width); - const scaleOffsetX = (width - (width * scaleTo)) / 2; - this.setState({ scaleOffsetX }); - } + this.onGestureEvent = event([{ + nativeEvent: { + state: this.gestureState, + }, + }]); } - handleStateChange = ({ nativeEvent: { state, absoluteX, absoluteY } }) => { - const { - activeOpacity, - enableHapticFeedback, - onPress, - scaleTo, - transformOrigin, - } = this.props; - const { scaleOffsetX } = this.state; - - const isActive = state === State.BEGAN; - - if (buttonExcludingMutex !== this) { - if (buttonExcludingMutex === null && isActive) { - buttonExcludingMutex = this; - } else { - return; - } - } - if (state === State.END || state === State.FAILED || state === State.CANCELLED) { - buttonExcludingMutex = null; - } + componentWillUnmount = () => this.clearInteraction() - const animationsArray = [ - // Default spring animation - animations.buildSpring({ - config: { - isInteraction: false, - }, - from: ButtonKeyframes.from.scale, - isActive, - to: scaleTo, - value: this.scale, - }), - ]; - - if (activeOpacity) { - // Opacity animation - animationsArray.push(animations.buildSpring({ - config: { - isInteraction: false, - }, - from: DefaultAnimatedValues.opacity, - isActive, - to: activeOpacity, - value: this.opacity, - })); + clearInteraction = () => { + if (this.props.isInteraction && this.handle) { + InteractionManager.clearInteractionHandle(this.handle); } + } - if (scaleOffsetX) { - // Fake 'transform-origin' support by abusing translateX - const directionMultiple = (transformOrigin === 'left') ? -1 : 1; - animationsArray.push(animations.buildSpring({ - config: { - isInteraction: false, - }, - from: DefaultAnimatedValues.transX, - isActive, - to: scaleOffsetX * (directionMultiple), - value: this.transX, - })); + createInteraction = () => { + if (this.props.isInteraction) { + this.handle = InteractionManager.createInteractionHandle(); } + } - // Start animations - Animated.parallel(animationsArray).start(); - - if (enableHapticFeedback && state === State.ACTIVE) { + handleHaptic = () => { + if (this.props.enableHapticFeedback) { ReactNativeHapticFeedback.trigger('selection'); } + } - if (isActive) { - this.initPos = { absoluteX, absoluteY }; + handleLayout = ({ nativeEvent: { layout } }) => { + // only setState if height+width dont already exist + if (!Object.values(this.state).reduce((a, b) => a + b)) { + this.setState(pick(layout, Object.keys(this.state))); } + } - if (state === State.END && onPress) { - // condition below covers issue when tap is simultaneous with pan - if (Math.abs(this.initPos.absoluteX - absoluteX) < 5 && Math.abs(this.initPos.absoluteY - absoluteY) < 5) { - onPress(); - } + handlePress = () => { + if (this.props.onPress) { + this.props.onPress(); } } - buildAnimationStyles = () => { - const { activeOpacity, transformOrigin } = this.props; - return ({ - ...(activeOpacity ? { opacity: this.opacity } : {}), - transform: compact([ - transformOrigin ? { translateX: this.transX } : null, - { scale: this.scale }, - ]), - }); - } + handleRunInteraction = () => ( + this.props.isInteraction + ? InteractionManager.runAfterInteractions(this.handlePress) + : this.handlePress() + ) render = () => { const { + activeOpacity, children, + defaultScale, disabled, + duration, + easing, + exclusive, + scaleTo, style, tapRef, - waitFor, + ...props } = this.props; + const offsetX = cond( + or(eq(this.transformOrigin, LEFT), eq(this.transformOrigin, RIGHT)), + divide(multiply(floor(this.state.width), this.directionMultiple), 2), + 0, + ); + + const offsetY = cond( + or(eq(this.transformOrigin, BOTTOM), eq(this.transformOrigin, TOP)), + divide(multiply(floor(this.state.height), this.directionMultiple), 2), + 0, + ); + + const opacity = cond( + greaterThan(scaleTo, defaultScale), + activeOpacity, + interpolate(divide(this.scale, defaultScale), { + inputRange: [scaleTo, defaultScale], + outputRange: [activeOpacity, 1], + }), + ); + + const transform = transformOriginUtil(offsetX, offsetY, { scale: this.scale }); + return ( - - + - {children} - - + + {children} + + + + ); } } diff --git a/src/components/coin-icon/CoinIcon.js b/src/components/coin-icon/CoinIcon.js index ff42f5ed83d..6c3bcd35f97 100644 --- a/src/components/coin-icon/CoinIcon.js +++ b/src/components/coin-icon/CoinIcon.js @@ -30,7 +30,6 @@ const CoinIcon = enhance(({ symbol, ...props }) => ( -console.log('bgColor', bgColor), showShadow ? ( )); @@ -76,7 +74,6 @@ CoinRow.propTypes = { contentStyles: PropTypes.string, highlight: PropTypes.bool, onPress: PropTypes.func, - starRender: PropTypes.func, symbol: PropTypes.string, topRowRender: PropTypes.func, }; diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js new file mode 100644 index 00000000000..43ae4da6c4f --- /dev/null +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -0,0 +1,107 @@ +import { get } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +// import { NavigationEvents, withNavigationFocus } from 'react-navigation'; +// import styled from 'styled-components/primitives'; +import { withProps } from 'recompact'; +import Animated from 'react-native-reanimated'; +import { borders, colors, position } from '../../styles'; +import { isNewValueForPath } from '../../utils';isNewValueForPath +import { ButtonPressAnimation } from '../animations'; +import { Icon } from '../icons'; +import { Centered, Column, FlexItem, Row } from '../layout'; +import { Monospace } from '../text'; +import SendCoinRow from './SendCoinRow'; +import CoinName from './CoinName'; +import CoinRow from './CoinRow'; + +const BottomRow = ({ balance, symbol }) => ( + + {symbol} + +); + +BottomRow.propTypes = { + balance: PropTypes.shape({ display: PropTypes.string }), + symbol: PropTypes.string, +}; + +const TopRow = ({ name }) => {name}; + +TopRow.propTypes = { + name: PropTypes.string, +}; + +export default class ExchangeCoinRow extends PureComponent { + static propTypes = { + favorite: PropTypes.bool, + index: PropTypes.number, + item: PropTypes.shape({ symbol: PropTypes.string }), + onPress: PropTypes.func, + } + + starRef = React.createRef() + + shouldComponentUpdate = (nextProps) => { + const should = ( + isNewValueForPath(this.props, nextProps, 'item.uniqueId') + || isNewValueForPath(this.props, nextProps, 'favorite') + ); + + // console.log('ExchangeCoinRow shouldComponentUpdate', should); + + return true; + } + + handleToggleFavorite = () => { + console.log('favorite'); + } + + handlePress = () => { + const { item: { symbol }, onPress } = this.props; + + if (onPress) { + onPress(symbol); + } + } + + render = () => { + const { favorite, item } = this.props; + + console.log('item', item); + + return ( + + + + + + + + + + ); + } +} diff --git a/src/components/coin-row/index.js b/src/components/coin-row/index.js index b9da0c14f76..1f6231de05f 100644 --- a/src/components/coin-row/index.js +++ b/src/components/coin-row/index.js @@ -3,6 +3,7 @@ export { default as BottomRowText } from './BottomRowText'; export { default as CoinRow } from './CoinRow'; export { default as CollectiblesSendRow } from './CollectiblesSendRow'; export { default as ContractInteractionCoinRow } from './ContractInteractionCoinRow'; +export { default as ExchangeCoinRow } from './ExchangeCoinRow'; export { default as RequestCoinRow } from './RequestCoinRow'; export { default as SendCoinRow } from './SendCoinRow'; export { default as TransactionCoinRow } from './TransactionCoinRow'; diff --git a/src/components/fab/ExchangeFab.js b/src/components/fab/ExchangeFab.js index d0cff646c7c..33e15c866af 100644 --- a/src/components/fab/ExchangeFab.js +++ b/src/components/fab/ExchangeFab.js @@ -1,12 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { withNavigation } from 'react-navigation'; -import { - compose, - onlyUpdateForKeys, - pure, - withHandlers, -} from 'recompact'; +import { compose, onlyUpdateForKeys, withHandlers } from 'recompact'; import { withFabSelection } from '../../hoc'; import { colors } from '../../styles'; import { Icon } from '../icons'; @@ -36,10 +31,6 @@ ExchangeFab.propTypes = { export default compose( withFabSelection, withNavigation, - withHandlers({ - onPress: ({ navigation }) => () => { - navigation.navigate('ExchangeModal'); - }, - }), + withHandlers({ onPress: ({ navigation }) => () => navigation.navigate('ExchangeModal') }), onlyUpdateForKeys(['disabled']), )(ExchangeFab); diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index 8186d0b20c3..a2bcbc213e4 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -30,6 +30,7 @@ import SendSmallIcon from './svg/SendSmallIcon'; import ShareIcon from './svg/ShareIcon'; import SignatureIcon from './svg/SignatureIcon'; import SpinnerIcon from './svg/SpinnerIcon'; +import StarIcon from './svg/StarIcon'; import SwapIcon from './svg/SwapIcon'; import ThreeDotsIcon from './svg/ThreeDotsIcon'; import TouchIdIcon from './svg/TouchIdIcon'; @@ -67,6 +68,7 @@ Icon.IconTypes = { share: ShareIcon, signature: SignatureIcon, spinner: SpinnerIcon, + star: StarIcon, swap: SwapIcon, threeDots: ThreeDotsIcon, touchid: TouchIdIcon, diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index bb56c16dc12..6be6f281998 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -8,12 +8,11 @@ import { Centered, Column, FlexItem, Row } from '../components/layout'; import { deviceUtils, safeAreaInsetValues } from '../utils'; import { Modal, ModalHeader } from '../components/modal'; import AssetList from '../components/asset-list/RecyclerAssetList'; -import { SendCoinRow } from '../components/coin-row'; +import { ExchangeCoinRow, SendCoinRow } from '../components/coin-row'; import GestureBlocker from '../components/GestureBlocker'; import { Monospace, TruncatedText } from '../components/text'; import { withAccountData } from '../hoc'; import { borders, colors, position } from '../styles'; -import StarIcon from '../components/icons/svg/StarIcon'; import { BackButton } from '../components/header'; import { ExchangeSearch } from '../components/exchange'; import { exchangeModalBorderRadius } from './ExchangeModal'; @@ -33,43 +32,6 @@ const BackButtonWrapper = styled(Centered)` position: absolute; `; -const BottomRow = ({ balance, symbol }) => ( - - {symbol} - -); - -BottomRow.propTypes = { - balance: PropTypes.shape({ display: PropTypes.string }), - symbol: PropTypes.string, -}; - -const CurrencyRenderItem = ({ favorite, item, onPress }) => ( - - - - - -); - -CurrencyRenderItem.propTypes = { - favorite: PropTypes.bool, - index: PropTypes.number, - item: PropTypes.shape({ symbol: PropTypes.string }), - onPress: PropTypes.func, -}; - -const EnhancedCurrencyRenderItem = withHandlers({ - onPress: ({ item: { symbol }, onPress }) => () => onPress(symbol), -})(CurrencyRenderItem); - class SelectCurrencyModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, @@ -124,7 +86,7 @@ class SelectCurrencyModal extends PureComponent { } renderCurrencyItem = (itemProps) => ( - diff --git a/src/screens/ExampleScreen.js b/src/screens/ExampleScreen.js index e8e04c3c275..3d61a82348f 100644 --- a/src/screens/ExampleScreen.js +++ b/src/screens/ExampleScreen.js @@ -1,9 +1,39 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { Page } from '../components/layout'; +import { View } from 'react-native'; +import { ExchangeCoinRow } from '../components/coin-row'; +import { Centered, Row, Page } from '../components/layout'; import { withHideSplashScreen } from '../hoc'; import { position } from '../styles'; +const item = { + address: "eth", + balance: { + amount: "0.07429230016603229", + display: "0.0743 ETH", + }, + decimals: 18, + name: "Ethereum", + native: { + balance: { + amount: "17.1696934913717225419", + display: "$17.17", + }, + change: "5.28%", + price: { + amount: 231.11, + display: "$231.11", + }, + }, + price: { + changed_at: 1564999503, + relative_change_24h: 5.279701166180759, + value: 231.11, + }, + symbol: "ETH", + uniqueId: "eth", +}; + class ExampleScreen extends PureComponent { static propTypes = { onHideSplashScreen: PropTypes.func, @@ -22,8 +52,18 @@ class ExampleScreen extends PureComponent { // ... i dont want to set up storybook right now */} + + + + + ) } + // + // + // + // + // export default withHideSplashScreen(ExampleScreen); diff --git a/yarn.lock b/yarn.lock index 8145d8f290c..8e2d25cb167 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1010,6 +1010,7 @@ integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": +<<<<<<< HEAD version "5.0.0-beta.129" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.129.tgz#bc93d04d3f0e8b7d33dbe7b47a81081f02af5a0e" integrity sha512-ob+olQe+i7Gvq10nZyDa3XFGCdVc7ojG1VsfwwFdxt8/li2cv74fFueR4rjTpgKBhJuPM2bwTeHq6sGLsVxetw== @@ -1056,10 +1057,52 @@ resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.125.tgz#ac2bd7d20a411ebcddddcfc686ebd426960eb112" integrity sha512-Vzood4ptHvWk64yqE5DMef7qLivEm3qH3S/60l66kWSAMmf5ISuSxeO+8Ss3o+p86zEGIhyipjpenb2LD6+/xA== >>>>>>> 751dba29... Replace navigation animations with new effects +======= + version "5.0.0-beta.127" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.127.tgz#2110938680d703f341bde765d6f9088f1d2e1b1b" + integrity sha512-xHENyIzB56DO98Bs8EM4x09ssSS5Iy/7ZCDDwPuXnYefMrLOCrlZYFw1+hKNz27gUVJSQMxIDK/g8J6Gs3pE6g== + dependencies: + "@ethersproject/bignumber" ">5.0.0-beta.0" + "@ethersproject/bytes" ">5.0.0-beta.0" + "@ethersproject/keccak256" ">5.0.0-beta.0" + "@ethersproject/logger" ">5.0.0-beta.0" + "@ethersproject/rlp" ">5.0.0-beta.0" + bn.js "^4.4.0" + +"@ethersproject/bignumber@>5.0.0-beta.0": + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.129.tgz#86260a2221b178e60cb082e68cb23b5a824e6515" + integrity sha512-uT8tnOWB9OwHq+17YrI/jppVOnqSNfj3WfTBXljb38Vq/oLKMlma7z8KFB4Ua3w0gtK2hawgpI+5M3uE+qxs5w== + dependencies: + "@ethersproject/bytes" ">5.0.0-beta.0" + "@ethersproject/logger" ">5.0.0-beta.0" + "@ethersproject/properties" ">5.0.0-beta.0" + bn.js "^4.4.0" + +"@ethersproject/bytes@>5.0.0-beta.0", "@ethersproject/bytes@^5.0.0-beta.126": + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.128.tgz#86300abd80d512be7dfa286eca5953206796d594" + integrity sha512-LvH0nZ7gR7pJAiAGWa3PxmSZcBtqhU70e9mTWFJirfOpXb8QqomGDdmU3I3cz9PsPnwkv3TD/NYwFRXzlpiiNw== + dependencies: + "@ethersproject/logger" ">5.0.0-beta.0" + +"@ethersproject/constants@>5.0.0-beta.0": + version "5.0.0-beta.127" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.127.tgz#2b9c0acdbf6bf2f3284632d16a6dd3ce591caca4" + integrity sha512-JNsDHD4w50Rg3kB08FStN1f7vCZ2e428MsDckF7YOQK96l2poC14wrek/GEbaUV96MxubSXmLeV7uDffp8NFew== + dependencies: + "@ethersproject/bignumber" ">5.0.0-beta.0" + +"@ethersproject/keccak256@>5.0.0-beta.0": + version "5.0.0-beta.126" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.126.tgz#19695119e16f95e6ff205dd90b35e7ac46194686" + integrity sha512-po/Yh+VakW1etttj7Ll8it9fZdoQBN2GD/6ZyHIIv5Oxh2bdNMruxKGfgsafxbuIvWZmBsQ+6FNJKO1ICdARzQ== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" js-sha3 "0.5.7" +<<<<<<< HEAD "@ethersproject/logger@>=5.0.0-beta.129": version "5.0.0-beta.130" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.130.tgz#65fb67819ef59d16fe3a45ca04d50a4f7bc3953e" @@ -1076,10 +1119,29 @@ version "5.0.0-beta.127" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.127.tgz#b9b9ab962f7392ced7c5c220d3d617f5e9df5953" integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== +======= +"@ethersproject/logger@>5.0.0-beta.0": + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" + integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== + +"@ethersproject/properties@>5.0.0-beta.0": + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" + integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== + dependencies: + "@ethersproject/logger" ">5.0.0-beta.0" + +"@ethersproject/rlp@>5.0.0-beta.0": + version "5.0.0-beta.125" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.125.tgz#e203233cf1bdd7d4f1cc7aba37808be5faa831e2" + integrity sha512-Tn1HZ9+D2sV/6ekyhpYzfGXufulRuWXHrIJnOsm0TkP1cmEH73MvDWyspByN/onrXkkUM9jtBIHY8FmrwnQoOw== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": +<<<<<<< HEAD version "5.0.0-beta.131" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" integrity sha512-TEUr1U1XWTPGEehAitqkG7SMgVspsAtB1+ESXdniznaYaMoP/D3W3lsDuFdvIIPWlAb97ra1w2pnCKxVcMmc4A== @@ -1087,6 +1149,15 @@ "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/constants" ">=5.0.0-beta.128" "@ethersproject/logger" ">=5.0.0-beta.129" +======= + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" + integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== + dependencies: + "@ethersproject/bytes" ">5.0.0-beta.0" + "@ethersproject/constants" ">5.0.0-beta.0" + "@ethersproject/logger" ">5.0.0-beta.0" +>>>>>>> e1a27438... Cleanup ButtonPressAnimation "@hapi/address@2.x.x": version "2.1.1" @@ -1326,11 +1397,17 @@ "@react-native-community/cli-platform-android@^2.0.0-rc.2": ======= "@react-native-community/cli-platform-android@^2.7.0": +<<<<<<< HEAD >>>>>>> 96db5a28... begin mike version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== >>>>>>> f7a61a13... Create Exchange related Input components +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" + integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1382,10 +1459,11 @@ ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch logkitty "^0.5.0" - slash "^2.0.0" - xmldoc "^0.4.0" + slash "^3.0.0" + xmldoc "^1.1.2" "@react-native-community/cli-platform-ios@^2.8.0": +<<<<<<< HEAD version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== @@ -1428,6 +1506,20 @@ >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" + integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== + dependencies: + "@react-native-community/cli-tools" "^2.8.3" + chalk "^2.4.2" + xcode "^2.0.0" + +"@react-native-community/cli-tools@^2.7.0", "@react-native-community/cli-tools@^2.8.3": + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" + integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1847,6 +1939,7 @@ "@types/node@*": <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -1864,6 +1957,16 @@ version "10.14.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== +======= + version "12.6.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" + integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== + +"@types/node@^10.3.2": + version "10.14.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" + integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation "@types/node@^8.0.7": <<<<<<< HEAD @@ -1976,6 +2079,7 @@ lodash.unescape "4.0.1" semver "5.5.0" +<<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.35": version "1.0.0-beta.35" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" @@ -2002,11 +2106,43 @@ version "1.0.0-beta.35" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== +======= +"@walletconnect/core@^1.0.0-beta.32": + version "1.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" + integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== + dependencies: + "@walletconnect/types" "^1.0.0-beta.32" + "@walletconnect/utils" "^1.0.0-beta.32" + +"@walletconnect/react-native@^1.0.0-beta.29": + version "1.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.32.tgz#4d6bd623a4687d658ae26ebe27f417b8ea83f897" + integrity sha512-6+Pamxq2c+K+Kz+q1oKJRZU58J5dg5U+SFJ5T5qkMpSsN0BCvpMvD3/6TPCzBYaFXCyjO5OJhvHsKmYa/IvA0g== + dependencies: + "@walletconnect/core" "^1.0.0-beta.32" + "@walletconnect/types" "^1.0.0-beta.32" + "@walletconnect/utils" "^1.0.0-beta.32" + +"@walletconnect/types@^1.0.0-beta.32": + version "1.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.32.tgz#aeb3b41145a6028412b22c05d0fd63e23a7381db" + integrity sha512-vXBUHc51mOyFLaScrSzYyobS/ctPiNHFBWB6M0oydd43X29Ihl7C4c4B7ExDbfPlrBspebcZEkuKzHOZSZVKSg== + +"@walletconnect/utils@^1.0.0-beta.32": + version "1.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.32.tgz#f87841eaf60d62441b26e78603aafbd9b7bc7f2e" + integrity sha512-ShnWCVPFv2fZcIKInNDhROCu/gEUD2+vjbBUCPTRB1M+ERTK8fyrMgl2vId8NOSTR/Sd3Ie4+hCbUluLZYvrGQ== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" +<<<<<<< HEAD "@walletconnect/types" "^1.0.0-beta.35" +======= + "@walletconnect/types" "^1.0.0-beta.32" +>>>>>>> e1a27438... Cleanup ButtonPressAnimation bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -2069,9 +2205,15 @@ accepts@~1.3.5, accepts@~1.3.7: negotiator "0.6.2" acorn-globals@^4.1.0: +<<<<<<< HEAD version "4.3.4" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +======= + version "4.3.3" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.3.tgz#a86f75b69680b8780d30edd21eee4e0ea170c05e" + integrity sha512-vkR40VwS2SYO98AIeFvzWWh+xyc2qi9s7OoXSFEGIP/rOJKzjnhykaZJNnHdoq4BL2gGxI5EZOU16z896EYnOQ== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" @@ -2973,6 +3115,11 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +btoa@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" + integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== + buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -3130,6 +3277,7 @@ caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.0.30000987" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" @@ -3153,7 +3301,15 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> e1a27438... Cleanup ButtonPressAnimation capture-exit@^1.2.0: version "1.2.0" @@ -3591,7 +3747,7 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -convert-source-map@^1.1.0, convert-source-map@^1.4.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== @@ -4204,6 +4360,7 @@ ee-first@1.1.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" @@ -4217,9 +4374,17 @@ electron-to-chromium@^1.3.164: ======= ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +ejs@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" + integrity sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q== + +>>>>>>> e1a27438... Cleanup ButtonPressAnimation electron-to-chromium@^1.3.191: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.3.205" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" @@ -4277,7 +4442,15 @@ electron-to-chromium@^1.3.188: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== >>>>>>> dc42f3f4... begin mike +<<<<<<< HEAD >>>>>>> 96db5a28... begin mike +======= +======= + version "1.3.215" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.215.tgz#c833cb31110c2e0a7dade1110648c2174f75233b" + integrity sha512-ZV3OnwF0FlIygwxAG2H92yt7WGjWBpawyFAFu8e9k7xJatY+BPowID0D0Bs3PMACYAJATEejw/I9cawO27ZvTg== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> e1a27438... Cleanup ButtonPressAnimation elliptic@6.3.3: version "6.3.3" @@ -4374,6 +4547,14 @@ entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== +<<<<<<< HEAD +======= + +envinfo@^5.7.0: + version "5.12.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" + integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation envinfo@^7.1.0: version "7.3.1" @@ -4439,7 +4620,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -escape-html@~1.0.3: +escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= @@ -4847,6 +5028,21 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.3.tgz#4b84301b33042cfb622771e886ed0b10e5634642" + integrity sha512-iM124nlyGSrXmuyZF1EMe83ESY2chIYVyDRZKgmcDynid2Q2v/+GuE7gNMl6Sy9Niwf4MC0DDxagOxeMPjuLsw== + dependencies: + cross-spawn "^6.0.5" + get-stream "^5.0.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^3.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + execall@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45" @@ -5398,6 +5594,13 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-uri@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.3.tgz#fa13352269781d75162c6fc813c9e905323fbab5" @@ -5568,6 +5771,7 @@ got@^6.7.1: url-parse-lax "^1.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +<<<<<<< HEAD <<<<<<< HEAD version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" @@ -5577,6 +5781,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== >>>>>>> 751dba29... Replace navigation animations with new effects +======= + version "4.2.1" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d" + integrity sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation growl@1.10.5: version "1.10.5" @@ -5745,9 +5954,17 @@ hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.1.0, hoist-non-react- react-is "^16.7.0" hosted-git-info@^2.1.4: +<<<<<<< HEAD version "2.8.4" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== +======= + version "2.8.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.2.tgz#a35c3f355ac1249f1093c0c2a542ace8818c171a" + integrity sha512-CyjlXII6LMsPMyUzxpTt8fzh5QwzGqPmQXgY/Jyf4Zfp27t/FvfhwoE/8laaMUcMy816CkWF20I7NeQhwwY88w== + dependencies: + lru-cache "^5.1.1" +>>>>>>> e1a27438... Cleanup ButtonPressAnimation html-encoding-sniffer@^1.0.2: version "1.0.2" @@ -5820,6 +6037,7 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -5829,6 +6047,11 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.6.tgz#01079cc2bcef408139ea8ce24d18ac0d512fbe85" integrity sha512-bdNhzhcM6RG5m82RypVguCrAQNie/ycxW0Q5C6K9UDWD5hqApZfdJFbj4Ikz9jxIR+Ja1eg0yCQLhlCT+opwIg== >>>>>>> 751dba29... Replace navigation animations with new effects +======= + version "17.0.9" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.9.tgz#5f835e91a34fa5e7da1e5ae4c4586c81d7c4b17f" + integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@babel/runtime" "^7.3.1" @@ -5867,9 +6090,15 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^3.1.3: +<<<<<<< HEAD version "3.3.0" resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== +======= + version "3.2.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-3.2.0.tgz#53686471e9dd2b070e0fb5500c6fdecd3a99375f" + integrity sha512-+a2R8z9eELHst6aht++nzVzJ8LJ+Hsg49qttfg9Kc/vmoxEdPXw5/rV6+4DYWGgnq+B36KbLr4OTaGtS9mDjtg== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation import-fresh@^2.0.0: version "2.0.0" @@ -6327,6 +6556,11 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -6339,7 +6573,11 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +<<<<<<< HEAD is-what@^3.3.1: +======= +is-what@^3.2.4: +>>>>>>> e1a27438... Cleanup ButtonPressAnimation version "3.3.1" resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.3.1.tgz#79502181f40226e2d8c09226999db90ef7c1bcbe" integrity sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA== @@ -7288,6 +7526,13 @@ lru-cache@^4.0.1, lru-cache@^4.1.2: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + ltgt@^2.1.3: version "2.2.1" resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" @@ -7448,6 +7693,14 @@ merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +<<<<<<< HEAD +======= + +merge2@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.4.tgz#c9269589e6885a60cf80605d9522d4b67ca646e3" + integrity sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation merge2@^1.2.3: version "1.3.0" @@ -7811,7 +8064,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-fn@^2.0.0: +mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -8097,10 +8350,17 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= +<<<<<<< HEAD node-notifier@^5.2.1, node-notifier@^5.4.2: version "5.4.3" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== +======= +node-notifier@^5.2.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.1.tgz#7c0192cc63aedb25cd99619174daa27902b10903" + integrity sha512-p52B+onAEHKW1OF9MGO/S7k/ahGEHfhP5/tvwYzog/5XLYOd8ZuD6vdNZdUuWMONRnKPneXV43v3s6Snx1wsCQ== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -8210,6 +8470,25 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +<<<<<<< HEAD +======= +npm-run-path@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" + integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== + dependencies: + path-key "^3.0.0" + +npmlog@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" + integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= + dependencies: + ansi "~0.3.1" + are-we-there-yet "~1.1.2" + gauge "~1.2.5" + +>>>>>>> e1a27438... Cleanup ButtonPressAnimation npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -8405,7 +8684,14 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -open@^6.2.0: +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +open@^6.2.0, open@^6.3.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== @@ -8541,6 +8827,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-is-promise@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" @@ -8763,6 +9054,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" + integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== + path-parse@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -9005,9 +9301,15 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.0: +<<<<<<< HEAD version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== +======= + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz#e3f6172cc91302912c89da55a42454025485250f" + integrity sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.7: version "7.0.18" @@ -9158,6 +9460,7 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: +<<<<<<< HEAD <<<<<<< HEAD version "1.4.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" @@ -9167,6 +9470,11 @@ psl@^1.1.24, psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== >>>>>>> 751dba29... Replace navigation animations with new effects +======= + version "1.3.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" + integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation public-encrypt@^4.0.0: version "4.0.3" @@ -9356,6 +9664,15 @@ react-native-actionsheet@^2.4.2: resolved "https://registry.yarnpkg.com/react-native-actionsheet/-/react-native-actionsheet-2.4.2.tgz#6a00dd51a75ef2c8974312130e405af73191500f" integrity sha512-DBoWIvVwuWXuptF4t46pBqkFxaUxS+rsIdHiA05t0n4BdTIDV2R4s9bLEUVOGzb94D7VxIamsXZPA/3mmw+SXg== +react-native-bundle-visualizer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/react-native-bundle-visualizer/-/react-native-bundle-visualizer-2.0.1.tgz#8847d3c89356bc6db3d634481b6ae57e8eaec575" + integrity sha512-MPjpbD12lwat1snp1EKGipT1rHulihznGb8h1QGR9J1hUBkjcQYnvaqG8Cd/t6zJEZd17b8f5zak/a7AB5h9TA== + dependencies: + execa "^2.0.3" + minimist "^1.2.0" + source-map-explorer "^2.0.1" + react-native-camera@^2.11.0: version "2.11.2" resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-2.11.2.tgz#4936bb0a484e8ba7d0b3ecf28fa7c161833b1ac0" @@ -9406,6 +9723,7 @@ react-native-crypto@^2.1.2: react-native-device-info@^2.1.3: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" @@ -9413,6 +9731,8 @@ react-native-device-info@^2.1.3: ======= ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> e1a27438... Cleanup ButtonPressAnimation <<<<<<< HEAD version "2.3.1" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" @@ -9436,7 +9756,15 @@ react-native-device-info@^2.1.3: resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== >>>>>>> dc42f3f4... begin mike +<<<<<<< HEAD >>>>>>> 96db5a28... begin mike +======= +======= + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> e1a27438... Cleanup ButtonPressAnimation react-native-dotenv@^0.2.0: version "0.2.0" @@ -9470,10 +9798,16 @@ react-native-firebase@^4.3.8: postinstall-build "^5.0.1" prop-types "^15.6.1" +<<<<<<< HEAD react-native-gesture-handler@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== +======= +react-native-gesture-handler@mikedemarais/react-native-gesture-handler#mike-hooks: + version "1.3.1" + resolved "https://codeload.github.com/mikedemarais/react-native-gesture-handler/tar.gz/beb63c2d8af5ae26cf264cb598376fb76d41c08c" +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -9520,7 +9854,7 @@ react-native-level-fs@^3.0.1: level-filesystem "^1.0.1" levelup "^0.18.2" -react-native-linear-gradient@^2.5.4: +react-native-linear-gradient@^2.5.6: version "2.5.6" resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz#96215cbc5ec7a01247a20890888aa75b834d44a0" integrity sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg== @@ -9578,10 +9912,17 @@ react-native-reanimated@1.2.0: resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.2.0.tgz#9219227a52a5dfa4d34c324596d6726ccd874293" integrity sha512-vkWRHrPK5qfHP/ZawlRoo38oeYe9NZaaOH/lmFxRcsKzaSK6x3H5ZPXI8lK6MfTLveqwo1QhJje3zIKXO4nQQw== +<<<<<<< HEAD react-native-redash@^7.2.1: version "7.5.1" resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.1.tgz#79c52c9a629b8ddeeb17e73336216aba1cc2f689" integrity sha512-NidcTKlK57BtjCMC9OKhXJnH50TDlfb+vel4oLUfaYHO2kGY56jGj+IS29V3joZgB5iO1X+U5K5FYWuQuDnepA== +======= +react-native-redash@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.0.tgz#fa72c7a23ad2f3f884a494ed76a0e79041ae70e1" + integrity sha512-y2J19HbBYWOYq4kq+3U86wfbsDusxv1/ak4a6KqvfTmt/E3i85mnnUDIF+nk1Shqz0aYcwNMB2KD7bEWsVK/sw== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -9656,10 +9997,17 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== +<<<<<<< HEAD react-native-svg@^9.5.1: version "9.9.3" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.9.3.tgz#5dab1a44b20b13a3f35245a286f30882b9611d66" integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== +======= +react-native-svg@^9.5.3: + version "9.6.2" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" + integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -9684,10 +10032,10 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" -react-native-text-input-mask@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" - integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== +react-native-text-input-mask@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" + integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== react-native-tooltip@^5.2.0: version "5.2.0" @@ -10383,7 +10731,11 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +<<<<<<< HEAD rimraf@2.6.3: +======= +rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@~2.6.2: +>>>>>>> e1a27438... Cleanup ButtonPressAnimation version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -10880,6 +11232,23 @@ socks@~2.3.2: ip "^1.1.5" smart-buffer "4.0.2" +source-map-explorer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.0.1.tgz#988721e8320d7b6925bc40289e5de658fe4cad4d" + integrity sha512-mv2sv2b6oN2L9n18O/eLrYiP5zfWEHESLq4utWBqNw8GnkbuRuXs8twVCOhMT5hxRzfQgS7Yxh7HlQaW8oeiAQ== + dependencies: + btoa "^1.2.1" + chalk "^2.4.2" + convert-source-map "^1.6.0" + ejs "^2.6.2" + escape-html "^1.0.3" + glob "^7.1.4" + lodash "^4.17.11" + open "^6.3.0" + source-map "^0.7.3" + temp "^0.9.0" + yargs "^13.2.4" + source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" @@ -10914,6 +11283,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + spawn-sync@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" @@ -11167,6 +11541,11 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" @@ -11427,9 +11806,15 @@ symbol-tree@^3.2.2: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^5.2.3: +<<<<<<< HEAD version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +======= + version "5.4.5" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.5.tgz#c8f4ea2d8fee08c0027fac27b0ec0a4fe01dfa42" + integrity sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: ajv "^6.10.2" lodash "^4.17.14" @@ -11474,6 +11859,13 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" +temp@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.0.tgz#61391795a11bd9738d4c4d7f55f012cb8f55edaa" + integrity sha512-YfUhPQCJoNQE5N+FJQcdPz63O3x3sdT4Xju69Gj4iZe0lBKOtnAMi0SLj9xKhGkcGhsxThvTJ/usxtFPo438zQ== + dependencies: + rimraf "~2.6.2" + tempfile@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" @@ -11681,9 +12073,15 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== tsutils@^3.7.0: +<<<<<<< HEAD version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== +======= + version "3.17.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.0.tgz#c3ccab927a475aa2beef6a3695c2ff76da13cdf8" + integrity sha512-fyveWOtAXfumAxIqkcMHuPaaVyLBKjB8Y00ANZkqh+HITBAQscCbQIHwwBTJdvQq7RykLEbOPcUUnJ16X4NA0g== +>>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: tslib "^1.8.1" @@ -11991,9 +12389,9 @@ uuid@^3.0.1, uuid@^3.3.2: integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== v8-compile-cache@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== validate-npm-package-license@^3.0.1: version "3.0.4" @@ -12304,6 +12702,13 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" +xmldoc@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" + integrity sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ== + dependencies: + sax "^1.2.1" + xmldom@0.1.x: version "0.1.27" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" @@ -12367,7 +12772,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.3: +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== From 43cb8f27451e5217cabad2da998df9d13001c60c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 6 Aug 2019 07:17:05 -0700 Subject: [PATCH 168/636] Cleanup ExchangeCoinRow --- src/components/coin-row/ExchangeCoinRow.js | 90 ++++++++++--------- .../floating-emojis/FloatingEmoji.js | 9 +- .../floating-emojis/FloatingEmojis.js | 20 +++-- src/screens/ExampleScreen.js | 13 +-- 4 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 43ae4da6c4f..6d981a197a7 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -1,17 +1,13 @@ -import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -// import { NavigationEvents, withNavigationFocus } from 'react-navigation'; -// import styled from 'styled-components/primitives'; -import { withProps } from 'recompact'; -import Animated from 'react-native-reanimated'; -import { borders, colors, position } from '../../styles'; -import { isNewValueForPath } from '../../utils';isNewValueForPath +import { View } from 'react-native'; +import { colors, padding } from '../../styles'; +import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; +import { FloatingEmojis } from '../floating-emojis'; import { Icon } from '../icons'; -import { Centered, Column, FlexItem, Row } from '../layout'; +import { Centered } from '../layout'; import { Monospace } from '../text'; -import SendCoinRow from './SendCoinRow'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; @@ -45,20 +41,16 @@ export default class ExchangeCoinRow extends PureComponent { starRef = React.createRef() - shouldComponentUpdate = (nextProps) => { - const should = ( - isNewValueForPath(this.props, nextProps, 'item.uniqueId') - || isNewValueForPath(this.props, nextProps, 'favorite') - ); - - // console.log('ExchangeCoinRow shouldComponentUpdate', should); - - return true; + state = { + emojiCount: 0, + favorite: false, } - handleToggleFavorite = () => { - console.log('favorite'); - } + shouldComponentUpdate = (nextProps, nextState) => ( + isNewValueForPath(this.props, nextProps, 'item.uniqueId') + || isNewValueForPath(this.state, nextState, 'favorite') + || isNewValueForPath(this.state, nextState, 'emojiCount') + ) handlePress = () => { const { item: { symbol }, onPress } = this.props; @@ -68,38 +60,56 @@ export default class ExchangeCoinRow extends PureComponent { } } - render = () => { - const { favorite, item } = this.props; + handleToggleFavorite = () => { + this.setState(prevState => { + const favorite = !prevState.favorite; + return { + emojiCount: favorite ? prevState.emojiCount + 1 : prevState.emojiCount, + favorite, + }; + }); + } - console.log('item', item); + render = () => { + const { item, ...props } = this.props; + const { emojiCount, favorite } = this.state; return ( - - + - - - + + + + + + ); diff --git a/src/components/floating-emojis/FloatingEmoji.js b/src/components/floating-emojis/FloatingEmoji.js index 9e7e4717b42..deb285bd375 100644 --- a/src/components/floating-emojis/FloatingEmoji.js +++ b/src/components/floating-emojis/FloatingEmoji.js @@ -10,7 +10,6 @@ const { interpolate, timing, Value, - View, } = Animated; export default class FloatingEmoji extends PureComponent { @@ -23,6 +22,7 @@ export default class FloatingEmoji extends PureComponent { right: PropTypes.string.isRequired, size: PropTypes.string.isRequired, style: stylePropType, + top: PropTypes.number, } static defaultProps = { @@ -52,6 +52,7 @@ export default class FloatingEmoji extends PureComponent { right, size, style, + top, } = this.props; const distance = Math.ceil(this.props.distance); @@ -85,14 +86,14 @@ export default class FloatingEmoji extends PureComponent { }); return ( - - + ); } } diff --git a/src/components/floating-emojis/FloatingEmojis.js b/src/components/floating-emojis/FloatingEmojis.js index f6c7ca69609..e0f366b900f 100644 --- a/src/components/floating-emojis/FloatingEmojis.js +++ b/src/components/floating-emojis/FloatingEmojis.js @@ -7,8 +7,8 @@ import FloatingEmoji from './FloatingEmoji'; const getRandomNumber = (min, max) => Math.random() * (max - min) + min; -const createEmojiItem = () => { - const right = `${getRandomNumber(0, 80)}%`; +const createEmojiItem = (range) => { + const right = `${getRandomNumber(...range)}%`; return ({ id: right, @@ -21,13 +21,17 @@ export default class FloatingEmojis extends PureComponent { color: PropTypes.string, count: PropTypes.number, distance: PropTypes.number, + duration: PropTypes.number, emoji: PropTypes.string.isRequired, + range: PropTypes.arrayOf(PropTypes.number), size: PropTypes.string.isRequired, style: stylePropType, + top: PropTypes.number, } static defaultProps = { count: -1, + range: [0, 80], size: 'h2', } @@ -35,19 +39,21 @@ export default class FloatingEmojis extends PureComponent { emojis: [], } - componentWillUpdate(nextProps) { - const oldCount = this.props.count; - const newCount = nextProps.count; + componentDidUpdate(prevProps) { + const oldCount = prevProps.count; + const newCount = this.props.count; const numEmojis = newCount - oldCount; if (numEmojis <= 0) return; const items = Array(numEmojis).fill(); - const newEmojis = items.map((_, i) => oldCount + i).map(createEmojiItem); + const newEmojis = items.map((_, i) => oldCount + i).map(this.createItem); this.setState({ emojis: this.state.emojis.concat(newEmojis) }); } + createItem = () => createEmojiItem(this.props.range) + removeEmoji = (id) => { const newEmojis = this.state.emojis.filter(emoji => emoji.id !== id); this.setState({ emojis: newEmojis }); @@ -63,11 +69,13 @@ export default class FloatingEmojis extends PureComponent { ))} diff --git a/src/screens/ExampleScreen.js b/src/screens/ExampleScreen.js index 3d61a82348f..b996b72bf7d 100644 --- a/src/screens/ExampleScreen.js +++ b/src/screens/ExampleScreen.js @@ -52,18 +52,11 @@ class ExampleScreen extends PureComponent { // ... i dont want to set up storybook right now */} - - - - - + + + ) } - // - // - // - // - // export default withHideSplashScreen(ExampleScreen); From 1c03ba4076d24c8287ebaab3e6a28a8f7f61cc2a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 7 Aug 2019 15:45:03 -0700 Subject: [PATCH 169/636] Begin keyboard focus management for ExchangeModal --- src/components/exchange/ExchangeInput.js | 18 +------ src/components/exchange/ExchangeInputField.js | 50 +++++++++---------- .../exchange/ExchangeOutputField.js | 23 ++++++--- src/components/exchange/ExchangeSearch.js | 1 + 4 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 7b6023dbd93..3c407fec3b8 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -23,22 +23,8 @@ export default class ExchangeInput extends PureComponent { } onChangeText = (formatted, extracted) => { - // console.log('formatted', typeof extracted, !!formatted, formatted); - // console.log('extracted', typeof extracted, !!extracted, extracted); - - const condition = !!extracted; - - // console.log('CONDITION', condition); - - const thing = condition ? formatted : ''; - // console.log('thing', thing); - - - - // XXX TODO: some funky stuff is going on here related to the '$' symbol in the input mask - - this.props.onChangeText(thing); + this.props.onChangeText(!!extracted ? formatted : ''); } render = () => { @@ -58,13 +44,13 @@ export default class ExchangeInput extends PureComponent { {...this.props} allowFontScaling={false} flex={1} - refInput={refInput} keyboardAppearance="dark" keyboardType="decimal-pad" mask={mask} onChangeText={this.onChangeText} placeholder={placeholder} placeholderTextColor={placeholderTextColor} + refInput={refInput} selectionColor={colors.appleBlue} style={[{ fontFamily: fonts.family.SFMono, diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index bad72001e5f..fad847040cb 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; import { colors, fonts } from '../../styles'; @@ -13,39 +13,39 @@ import { import { Emoji, Text } from '../text'; import ExchangeInput from './ExchangeInput'; -export default class ExchangeInputField extends Component { +export default class ExchangeInputField extends PureComponent { static propTypes = { autoFocus: PropTypes.bool, inputAmount: PropTypes.string, inputCurrency: PropTypes.string, + inputFieldRef: PropTypes.func, nativeAmount: PropTypes.string, + nativeFieldRef: PropTypes.func, onPressMaxBalance: PropTypes.func, onPressSelectInputCurrency: PropTypes.string, setInputAmount: PropTypes.func, setNativeAmount: PropTypes.func, } - inputRef = React.createRef() - - maskRef = null - - dollarRef = null + inputFieldRef = undefined + nativeFieldRef = undefined padding = 15 - handleFocusInput = () => { - if (this.maskRef) { - this.maskRef.focus(); + handleFocusInputField = () => { + if (this.inputFieldRef) { + this.inputFieldRef.focus(); } } - - handleMaskRef = (ref) => { - this.maskRef = ref; + handleInputFieldRef = (ref) => { + this.inputFieldRef = ref; + this.props.inputFieldRef(ref); } - handleDollarRef = (ref) => { - this.dollarRef = ref; + handleNativeFieldRef = (ref) => { + this.nativeFieldRef = ref; + this.props.nativeFieldRef(ref); } render = () => { @@ -53,35 +53,34 @@ export default class ExchangeInputField extends Component { autoFocus, inputAmount, inputCurrency, + inputFieldRef, + onFocus, nativeAmount, + nativeFieldRef, onPressMaxBalance, onPressSelectInputCurrency, setInputAmount, setNativeAmount, } = this.props; - // mask="[0...][-][9...]" - + // return ( - + - + @@ -97,10 +96,11 @@ export default class ExchangeInputField extends Component { diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index 5f7ba6a5e0f..07e6ea78165 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -31,20 +31,31 @@ const FakeNotchThing = withNeverRerender(() => ( /> )); -class ExchangeOutputField extends PureComponent { +export default class ExchangeOutputField extends PureComponent { static propTypes = { onPressSelectOutputCurrency: PropTypes.string, outputAmount: PropTypes.number, outputCurrency: PropTypes.string, + outputFieldRef: PropTypes.func.isRequired, setOutputAmount: PropTypes.func, } - inputRef = React.createRef() + outputFieldRef = null - handleFocusInput = () => this.inputRef.current.focus() + handleFocusInput = () => { + if (this.outputFieldRef) { + this.outputFieldRef.focus(); + } + } + + handleOutputFieldRef = (ref) => { + this.outputFieldRef = ref; + this.props.outputFieldRef(ref); + } render = () => { const { + onFocus, onPressSelectOutputCurrency, outputAmount, outputCurrency, @@ -80,12 +91,12 @@ class ExchangeOutputField extends PureComponent { symbol={outputCurrency} /> @@ -99,5 +110,3 @@ class ExchangeOutputField extends PureComponent { ); } } - -export default ExchangeOutputField; diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 5eb61fb4eee..54789d78372 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -58,6 +58,7 @@ class ExchangeSearch extends PureComponent { keyboardType="default" lineHeight="loose" onChangeText={this.props.onChangeText} + onFocus={this.props.onFocus} placeholder="Search" placeholderTextColor={colors.grey} ref={this.inputRef} From 0f691591e11f15323c932849d45178610d9d1a6d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 7 Aug 2019 15:47:55 -0700 Subject: [PATCH 170/636] create KeyboardFixedOpenLayout component --- .../layout/KeyboardFixedOpenLayout.js | 87 +++++++++++++++++++ src/components/layout/index.js | 1 + src/handlers/commonStorage.js | 9 ++ 3 files changed, 97 insertions(+) create mode 100644 src/components/layout/KeyboardFixedOpenLayout.js diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js new file mode 100644 index 00000000000..5d362a459c2 --- /dev/null +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -0,0 +1,87 @@ +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { Keyboard, KeyboardAvoidingView } from 'react-native'; +import styled from 'styled-components/primitives'; +import { + getUndecoratedKeyboardHeight, + setUndecoratedKeyboardHeight, +} from '../../handlers/commonStorage' +import { colors, position } from '../../styles'; +import { deviceUtils, safeAreaInsetValues } from '../../utils'; +import { Centered } from '../layout'; + +const FallbackKeyboardHeight = Math.floor(deviceUtils.dimensions.height * 0.333); + +const Container = styled.View` + left: 0; + position: absolute; + right: 0; + top: 0; +`; + +const InnerWrapper = styled(Centered)` + ${position.size('100%')}; + background-color: ${colors.transparent}; + padding-bottom: 10; +`; + +export default class KeyboardFixedOpenLayout extends PureComponent { + static propTypes = { + children: PropTypes.node, + } + + constructor(props) { + super(props); + + this.willShowListener = undefined; + + this.state = { + keyboardHeight: 0, + } + } + + componentDidMount = async () => { + const keyboardHeight = await getUndecoratedKeyboardHeight(); + + if (keyboardHeight && keyboardHeight !== this.state.keyboardHeight) { + this.setState({ keyboardHeight }); + } + + if (!keyboardHeight) { + this.willShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); + } + } + + componentWillUnmount = () => this.clearKeyboardListeners() + + clearKeyboardListeners = () => { + if (this.willShowListener) { + this.willShowListener.remove(); + } + } + + keyboardWillShow = async ({ endCoordinates: { height } }) => { + const keyboardHeight = Math.floor(height); + this.setState({ keyboardHeight }); + return setUndecoratedKeyboardHeight(keyboardHeight).then(this.clearKeyboardListeners); + } + + render = () => { + const { keyboardHeight } = this.state; + + const resolvedKeyboardHeight = keyboardHeight || FallbackKeyboardHeight; + const containerHeight = deviceUtils.dimensions.height - resolvedKeyboardHeight; + + return ( + + + + + + ); + } +} + diff --git a/src/components/layout/index.js b/src/components/layout/index.js index 8e6ffb4819a..01407a14db7 100644 --- a/src/components/layout/index.js +++ b/src/components/layout/index.js @@ -4,6 +4,7 @@ export { default as ColumnWithDividers } from './ColumnWithDividers'; export { default as ColumnWithMargins } from './ColumnWithMargins'; export { default as Flex } from './Flex'; export { default as FlexItem } from './FlexItem'; +export { default as KeyboardFixedOpenLayout } from './KeyboardFixedOpenLayout'; export { default as LayoutWithDividers } from './LayoutWithDividers'; export { default as LayoutWithMargins } from './LayoutWithMargins'; export { default as Page } from './Page'; diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index b5002ec3bfe..002e065add6 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -514,3 +514,12 @@ export const getAppStoreReviewRequestCount = async () => { export const setAppStoreReviewRequestCount = async (newCount) => { await saveLocal('appStoreReviewRequestCount', { data: newCount }); }; + +export const getUndecoratedKeyboardHeight = async () => { + const height = await getLocal('undecoratedKeyboardHeight'); + return height ? height.data : 0; +}; + +export const setUndecoratedKeyboardHeight = async (newHeight) => { + await saveLocal('undecoratedKeyboardHeight', { data: newHeight }); +}; From ffd1b41e1215cc911821f2cc04b79bd90be71e8d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 7 Aug 2019 15:49:02 -0700 Subject: [PATCH 171/636] create keyboardFocusHistory reducer + withKeyboardFocusHistory hoc --- src/hoc/index.js | 1 + src/hoc/withKeyboardFocusHistory.js | 12 ++++++++++++ src/redux/keyboardFocusHistory.js | 30 +++++++++++++++++++++++++++++ src/redux/reducers.js | 2 ++ 4 files changed, 45 insertions(+) create mode 100644 src/hoc/withKeyboardFocusHistory.js create mode 100644 src/redux/keyboardFocusHistory.js diff --git a/src/hoc/index.js b/src/hoc/index.js index ac9d8b8e4e4..47520aa4ecb 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -14,6 +14,7 @@ export { default as withImageDimensionsCache } from './withImageDimensionsCache' export { default as withIsWalletEmpty } from './withIsWalletEmpty'; export { default as withIsWalletEthZero } from './withIsWalletEthZero'; export { default as withIsWalletImporting } from './withIsWalletImporting'; +export { default as withKeyboardFocusHistory } from './withKeyboardFocusHistory'; export { default as withMessageSigningScreen } from './withMessageSigningScreen'; export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; diff --git a/src/hoc/withKeyboardFocusHistory.js b/src/hoc/withKeyboardFocusHistory.js new file mode 100644 index 00000000000..133fbe0d05f --- /dev/null +++ b/src/hoc/withKeyboardFocusHistory.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux'; +import { + clearKeyboardFocusHistory, + pushKeyboardFocusHistory, +} from '../redux/keyboardFocusHistory'; + +const mapStateToProps = ({ keyboardFocusHistory }) => keyboardFocusHistory; + +export default connect(mapStateToProps, { + clearKeyboardFocusHistory, + pushKeyboardFocusHistory, +}); diff --git a/src/redux/keyboardFocusHistory.js b/src/redux/keyboardFocusHistory.js new file mode 100644 index 00000000000..51306d24100 --- /dev/null +++ b/src/redux/keyboardFocusHistory.js @@ -0,0 +1,30 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const CLEAR_KEYBOARD_FOCUS_HISTORY = 'keyboardFocusHistory/CLEAR_KEYBOARD_FOCUS_HISTORY'; +const PUSH_KEYBOARD_FOCUS_HISTORY = 'keyboardFocusHistory/PUSH_KEYBOARD_FOCUS_HISTORY'; + +export const clearKeyboardFocusHistory = () => dispatch => dispatch({ + type: CLEAR_KEYBOARD_FOCUS_HISTORY, +}); + +export const pushKeyboardFocusHistory = payload => dispatch => dispatch({ + payload, + type: PUSH_KEYBOARD_FOCUS_HISTORY, +}); + + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + keyboardFocusHistory: [], +}; + +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + if (action.type === PUSH_KEYBOARD_FOCUS_HISTORY) { + draft.keyboardFocusHistory.push(action.payload) + } else if (action.type === CLEAR_KEYBOARD_FOCUS_HISTORY) { + return INITIAL_STATE; + } + }) +); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index c0ebec7e366..199cbf5b0a2 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -6,6 +6,7 @@ import imageDimensionsCache from './imageDimensionsCache'; import isWalletEmpty from './isWalletEmpty'; import isWalletEthZero from './isWalletEthZero'; import isWalletImporting from './isWalletImporting'; +import keyboardFocusHistory from './keyboardFocusHistory'; import navigation from './navigation'; import nonce from './nonce'; import openBalances from './openBalances'; @@ -26,6 +27,7 @@ export default combineReducers({ isWalletEmpty, isWalletEthZero, isWalletImporting, + keyboardFocusHistory, navigation, nonce, openBalances, From c306935fb903dc1bedf2e0d807e31ac4cf55ab34 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 7 Aug 2019 15:50:11 -0700 Subject: [PATCH 172/636] Begin orchestrating keyboard focus between swap modal views --- package.json | 1 + src/components/exchange/ExchangeInput.js | 2 +- .../expanded-state/FloatingPanels.js | 6 +- .../layout/KeyboardFixedOpenLayout.js | 41 ++- src/handlers/commonStorage.js | 9 - src/hoc/index.js | 1 + src/hoc/withKeyboardHeight.js | 6 + src/redux/keyboardHeight.js | 20 ++ src/redux/reducers.js | 2 + src/screens/CurrencySelectModal.js | 204 +++++++-------- src/screens/ExchangeModal.js | 234 +++++++++++------- src/screens/Routes.js | 41 ++- yarn.lock | 35 +++ 13 files changed, 355 insertions(+), 247 deletions(-) create mode 100644 src/hoc/withKeyboardHeight.js create mode 100644 src/redux/keyboardHeight.js diff --git a/package.json b/package.json index 50fa9b1d24a..de8b8af9f44 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", "react-navigation-stack": "^2.0.0-alpha.9", + "react-navigation-tabs": "^2.3.0", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 3c407fec3b8..ce25e5d2fff 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -33,8 +33,8 @@ export default class ExchangeInput extends PureComponent { mask, onChangeText, placeholder, - refInput, placeholderTextColor, + refInput, style, value, } = this.props; diff --git a/src/components/expanded-state/FloatingPanels.js b/src/components/expanded-state/FloatingPanels.js index 1557e7a84d1..bccf16707c1 100644 --- a/src/components/expanded-state/FloatingPanels.js +++ b/src/components/expanded-state/FloatingPanels.js @@ -6,12 +6,12 @@ const FloatingPanelsMargin = 20; const FloatingPanels = compose( setDisplayName('FloatingPanels'), - withProps({ + withProps(({ style }) => ({ justify: 'center', margin: FloatingPanelsMargin, pointerEvents: 'box-none', - style: position.sizeAsObject('100%'), - }), + style: [position.sizeAsObject('100%'), style], + })), )(ColumnWithMargins); FloatingPanels.margin = FloatingPanelsMargin; diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index 5d362a459c2..18c7219f2f6 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -1,11 +1,9 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { Keyboard, KeyboardAvoidingView } from 'react-native'; +import { compose, onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components/primitives'; -import { - getUndecoratedKeyboardHeight, - setUndecoratedKeyboardHeight, -} from '../../handlers/commonStorage' +import { withKeyboardHeight } from '../../hoc'; import { colors, position } from '../../styles'; import { deviceUtils, safeAreaInsetValues } from '../../utils'; import { Centered } from '../layout'; @@ -25,29 +23,17 @@ const InnerWrapper = styled(Centered)` padding-bottom: 10; `; -export default class KeyboardFixedOpenLayout extends PureComponent { +class KeyboardFixedOpenLayout extends PureComponent { static propTypes = { children: PropTypes.node, + keyboardHeight: PropTypes.number, + setKeyboardHeight: PropTypes.func, } - constructor(props) { - super(props); + willShowListener = undefined - this.willShowListener = undefined; - - this.state = { - keyboardHeight: 0, - } - } - - componentDidMount = async () => { - const keyboardHeight = await getUndecoratedKeyboardHeight(); - - if (keyboardHeight && keyboardHeight !== this.state.keyboardHeight) { - this.setState({ keyboardHeight }); - } - - if (!keyboardHeight) { + componentDidMount = () => { + if (!this.props.keyboardHeight) { this.willShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); } } @@ -61,13 +47,12 @@ export default class KeyboardFixedOpenLayout extends PureComponent { } keyboardWillShow = async ({ endCoordinates: { height } }) => { - const keyboardHeight = Math.floor(height); - this.setState({ keyboardHeight }); - return setUndecoratedKeyboardHeight(keyboardHeight).then(this.clearKeyboardListeners); + this.props.setKeyboardHeight(Math.floor(height)); + this.clearKeyboardListeners(); } render = () => { - const { keyboardHeight } = this.state; + const { keyboardHeight } = this.props; const resolvedKeyboardHeight = keyboardHeight || FallbackKeyboardHeight; const containerHeight = deviceUtils.dimensions.height - resolvedKeyboardHeight; @@ -85,3 +70,7 @@ export default class KeyboardFixedOpenLayout extends PureComponent { } } +export default compose( + withKeyboardHeight, + onlyUpdateForKeys(['height']), +)(KeyboardFixedOpenLayout); diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 002e065add6..b5002ec3bfe 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -514,12 +514,3 @@ export const getAppStoreReviewRequestCount = async () => { export const setAppStoreReviewRequestCount = async (newCount) => { await saveLocal('appStoreReviewRequestCount', { data: newCount }); }; - -export const getUndecoratedKeyboardHeight = async () => { - const height = await getLocal('undecoratedKeyboardHeight'); - return height ? height.data : 0; -}; - -export const setUndecoratedKeyboardHeight = async (newHeight) => { - await saveLocal('undecoratedKeyboardHeight', { data: newHeight }); -}; diff --git a/src/hoc/index.js b/src/hoc/index.js index 47520aa4ecb..8ed99e3004c 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -15,6 +15,7 @@ export { default as withIsWalletEmpty } from './withIsWalletEmpty'; export { default as withIsWalletEthZero } from './withIsWalletEthZero'; export { default as withIsWalletImporting } from './withIsWalletImporting'; export { default as withKeyboardFocusHistory } from './withKeyboardFocusHistory'; +export { default as withKeyboardHeight } from './withKeyboardHeight'; export { default as withMessageSigningScreen } from './withMessageSigningScreen'; export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; diff --git a/src/hoc/withKeyboardHeight.js b/src/hoc/withKeyboardHeight.js new file mode 100644 index 00000000000..c6751fc5bd2 --- /dev/null +++ b/src/hoc/withKeyboardHeight.js @@ -0,0 +1,6 @@ +import { connect } from 'react-redux'; +import { setKeyboardHeight } from '../redux/keyboardHeight'; + +const mapStateToProps = ({ keyboardHeight }) => keyboardHeight; + +export default connect(mapStateToProps, { setKeyboardHeight }); diff --git a/src/redux/keyboardHeight.js b/src/redux/keyboardHeight.js new file mode 100644 index 00000000000..6e28fe29988 --- /dev/null +++ b/src/redux/keyboardHeight.js @@ -0,0 +1,20 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_KEYBOARD_HEIGHT = 'keyboardHeight/SET_KEYBOARD_HEIGHT'; + +export const setKeyboardHeight = payload => dispatch => dispatch({ + payload, + type: SET_KEYBOARD_HEIGHT, +}); + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { keyboardHeight: 0 }; + +export default (state = INITIAL_STATE, action) => ( + produce(state, draft => { + if (action.type === SET_KEYBOARD_HEIGHT) { + draft.keyboardHeight = action.payload; + } + }) +); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 199cbf5b0a2..61365ccb9b8 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -7,6 +7,7 @@ import isWalletEmpty from './isWalletEmpty'; import isWalletEthZero from './isWalletEthZero'; import isWalletImporting from './isWalletImporting'; import keyboardFocusHistory from './keyboardFocusHistory'; +import keyboardHeight from './keyboardHeight'; import navigation from './navigation'; import nonce from './nonce'; import openBalances from './openBalances'; @@ -28,6 +29,7 @@ export default combineReducers({ isWalletEthZero, isWalletImporting, keyboardFocusHistory, + keyboardHeight, navigation, nonce, openBalances, diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 6be6f281998..1cf3431c55f 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,17 +1,23 @@ +import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { compose, withHandlers } from 'recompact'; -import { KeyboardAvoidingView, View } from 'react-native' +import { InteractionManager, KeyboardAvoidingView, View } from 'react-native' import { NavigationEvents, withNavigationFocus } from 'react-navigation'; +import Animated from 'react-native-reanimated'; import styled from 'styled-components/primitives'; -import { Centered, Column, FlexItem, Row } from '../components/layout'; +import { Centered, Column, FlexItem, KeyboardFixedOpenLayout, Row } from '../components/layout'; import { deviceUtils, safeAreaInsetValues } from '../utils'; import { Modal, ModalHeader } from '../components/modal'; -import AssetList from '../components/asset-list/RecyclerAssetList'; +import { RecyclerAssetList } from '../components/asset-list'; import { ExchangeCoinRow, SendCoinRow } from '../components/coin-row'; import GestureBlocker from '../components/GestureBlocker'; import { Monospace, TruncatedText } from '../components/text'; -import { withAccountData } from '../hoc'; +import { + withAccountData, + withKeyboardFocusHistory, + withTransitionProps, +} from '../hoc'; import { borders, colors, position } from '../styles'; import { BackButton } from '../components/header'; import { ExchangeSearch } from '../components/exchange'; @@ -32,7 +38,7 @@ const BackButtonWrapper = styled(Centered)` position: absolute; `; -class SelectCurrencyModal extends PureComponent { +class CurrencySelectModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, navigation: PropTypes.object, @@ -40,30 +46,30 @@ class SelectCurrencyModal extends PureComponent { callback = null - keyboardHeight = 0 - - viewportHeight = deviceUtils.dimensions.height - searchInputRef = React.createRef() componentDidMount() { this.getDataFromParams(); } - componentDidUpdate() { - this.getDataFromParams(); - } + componentDidUpdate(prevProps) { + const { + isFocused, + keyboardFocusHistory, + transitionProps: { isTransitioning }, + } = this.props; - getDataFromParams = () => { - const { navigation } = this.props; + const prevTransitioning = get(prevProps, 'transitionProps.isTransitioning'); - this.callback = navigation.getParam('onSelectCurrency'); - this.keyboardHeight = navigation.getParam('keyboardHeight'); + if (isFocused && (!isTransitioning && prevTransitioning)) { + this.searchInputRef.current.focus(); + } - // console.log('getDataFromParams this.keyboardHeight', this.keyboardHeight); + this.getDataFromParams(); + } - this.viewportHeight = deviceUtils.dimensions.height - this.keyboardHeight; - // console.log('getDataFromParams this.viewportHeight', this.viewportHeight); + getDataFromParams = () => { + this.callback = this.props.navigation.getParam('onSelectCurrency'); } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { @@ -92,111 +98,87 @@ class SelectCurrencyModal extends PureComponent { /> ) - handleDidFocus = () => { - // setTimeout(() => this.searchInputRef.current.focus(), 500); + handleFocusField = ({ currentTarget }) => { + this.props.pushKeyboardFocusHistory(currentTarget); } render() { - const magicNumber = this.viewportHeight - ? (this.viewportHeight - 10) // - 5 - : 0; - - if (!!this.viewportHeight) { - // console.log(' ') - // console.log('SelectCurrencyModal -- isFocused', this.props.isFocused); - // console.log('magicNumber', magicNumber); - // console.log('SelectCurrencyModal -- this.props', this.props); - // console.log('this.viewportHeight', this.viewportHeight); - // console.log(' ') - } + const { + allAssets, + navigation, + transitionProps: { isTransitioning }, + } = this.props; const fakeDataThatNeedsToBeHookedUp = [ { balances: true, - data: this.props.allAssets, + data: [...allAssets, ...allAssets.map(({ uniqueId, ...asset }) => ({ + ...asset, + uniqueId: `${uniqueId}_currency`, + }))], renderItem: this.renderCurrencyItem, }, ]; return ( - - + - - - - - + + + + + + + + + Receive + + + + - - - - - - - Receive - - - - - - - - - - + + + + + ); } } @@ -204,4 +186,6 @@ class SelectCurrencyModal extends PureComponent { export default compose( withAccountData, withNavigationFocus, -)(SelectCurrencyModal); + withTransitionProps, + withKeyboardFocusHistory, +)(CurrencySelectModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 300157ab011..a9451f8ba12 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,34 +1,47 @@ +import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; -import { KeyboardAvoidingView, View } from 'react-native'; -import { compose, withProps } from 'recompact'; -import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { - Centered, - Column, - ColumnWithMargins, -} from '../components/layout'; + Dimensions, + InteractionManager, + Keyboard, + KeyboardAvoidingView, + TextInput, + View, +} from 'react-native'; +import { compose, toClass, withProps } from 'recompact'; +import Animated from 'react-native-reanimated'; +import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { withAccountData, withBlockedHorizontalSwipe, + withKeyboardFocusHistory, withNeverRerender, + withTransitionProps, } from '../hoc'; import { colors, padding, position } from '../styles'; import { deviceUtils, safeAreaInsetValues } from '../utils'; -import FloatingPanels from '../components/expanded-state/FloatingPanels'; -import FloatingPanel from '../components/expanded-state/FloatingPanel'; -import { Text } from '../components/text'; import { ConfirmExchangeButton, ExchangeGasFeeButton, ExchangeInputField, ExchangeOutputField, } from '../components/exchange'; +import { FloatingPanel, FloatingPanels } from '../components/expanded-state'; import GestureBlocker from '../components/GestureBlocker'; +import { + Centered, + Column, + ColumnWithMargins, + KeyboardFixedOpenLayout, +} from '../components/layout'; import { SheetHandle } from '../components/sheet'; +import { Text } from '../components/text'; export const exchangeModalBorderRadius = 30; +const AnimatedFloatingPanels = Animated.createAnimatedComponent(toClass(FloatingPanels)); + const ExchangeModalHeader = withNeverRerender(() => ( ( class ExchangeModal extends PureComponent { static propTypes = { + clearKeyboardFocusHistory: PropTypes.func, inputAmount: PropTypes.number, + keyboardFocusHistory: PropTypes.array, navigation: PropTypes.object, outputAmount: PropTypes.number, + pushKeyboardFocusHistory: PropTypes.func, showConfirmButton: PropTypes.bool, } state = { inputAmount: null, inputCurrency: 'ETH', - // keyboardHeight: 0, nativeAmount: null, outputAmount: null, outputCurrency: null, showConfirmButton: false, } - keyboardHeight = null + componentDidMount = () => { + // console.log('componentDidMount dangerouslyGetParent', this.props.navigation.dangerouslyGetParent()) + // console.log('this.props.navigation', this.props.navigation); + } + + componentDidUpdate = (prevProps) => { + const { + isFocused, + keyboardFocusHistory, + transitionProps: { isTransitioning }, + } = this.props; + + const prevTransitioning = get(prevProps, 'transitionProps.isTransitioning'); + + if (isFocused && (!isTransitioning && prevTransitioning)) { + const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; + + if (lastFocusedInput) { + TextInput.State.focusTextInput(lastFocusedInput); + } else { + // console.log('ELSE') + // this.inputFieldRef.focus(); + } + } + + if (this.state.outputCurrency) { + this.setState({ showConfirmButton: true }); + } + } + + componentWillUnmount = () => { + this.props.clearKeyboardFocusHistory(); + } inputFieldRef = null + nativeFieldRef = null + + outputFieldRef = null + setInputAmount = inputAmount => this.setState({ inputAmount }) setNativeAmount = nativeAmount => this.setState({ nativeAmount }) @@ -81,14 +132,12 @@ class ExchangeModal extends PureComponent { handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { - keyboardHeight: this.keyboardHeight, onSelectCurrency: this.setInputCurrency, }); } handleSelectOutputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { - keyboardHeight: this.keyboardHeight, onSelectCurrency: this.setOutputCurrency, }); } @@ -97,30 +146,38 @@ class ExchangeModal extends PureComponent { this.props.navigation.navigate('WalletScreen'); } - handleWillFocus = () => { - if (this.state.outputCurrency) { - this.setState({ showConfirmButton: true }); + handleWillFocus = ({ lastState }) => { + + if (!lastState && this.inputFieldRef) { + return this.inputFieldRef.focus(); } } - handleInputFieldRef = (ref) => { - this.inputFieldRef = ref; - } + handleInputFieldRef = (ref) => { this.inputFieldRef = ref; } + + handleNativeFieldRef = (ref) => { this.nativeFieldRef = ref; } + + handleOutputFieldRef = (ref) => { this.outputFieldRef = ref; } handleDidFocus = () => { - if (this.inputFieldRef) { - // setTimeout(() => this.inputFieldRef.focus(), 500); - } + // console.log('DID FOCUS', this.props.navigation) + + // if (this.inputFieldRef) { + // setTimeout(() => this.inputFieldRef.focus(), 250); + // } } - lolThing = ({ nativeEvent: { layout } }) => { - if (!this.keyboardHeight) { - this.keyboardHeight = deviceUtils.dimensions.height - layout.height;// - safeAreaInsetValues.bottom; - } + handleFocusField = ({ currentTarget }) => { + this.props.pushKeyboardFocusHistory(currentTarget); } render = () => { - const { onPressConfirmExchange } = this.props; + const { + keyboardFocusHistory, + onPressConfirmExchange, + navigation, + transitionProps, + } = this.props; const { inputAmount, @@ -132,65 +189,70 @@ class ExchangeModal extends PureComponent { } = this.state; return ( - - - - - - - - - - - + + + + + + + + + + + + + {showConfirmButton && ( + + + - + {!!Number(inputAmount) && ( + - - - - {showConfirmButton && ( - - - - - {!!Number(inputAmount) && ( - - )} - - )} - - - - + )} + + )} + + + ); } } @@ -205,4 +267,6 @@ export default compose( withBlockedHorizontalSwipe, withNavigationFocus, withMockedPrices, + withKeyboardFocusHistory, + withTransitionProps, )(ExchangeModal); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index da508ac58f3..f02f9b4fb33 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -1,6 +1,7 @@ import analytics from '@segment/analytics-react-native'; import { get } from 'lodash'; import React from 'react'; +import Animated from 'react-native-reanimated'; import { createAppContainer, createMaterialTopTabNavigator, @@ -68,41 +69,55 @@ const SwipeStack = createMaterialTopTabNavigator({ tabBarComponent: null, }); -const ExchangeModalNavigator = createMaterialTopTabNavigator({ - MainExchangeScreen: { - screen: ExchangeModal, - }, - // eslint-disable-next-line sort-keys +const ExchangeModalTabPosition = new Animated.Value(0); + +const ExchangeModalNavigator = newTopTabNavigator({ CurrencySelectScreen: { + params: { + position: ExchangeModalTabPosition, + }, screen: CurrencySelectModal, }, + MainExchangeScreen: { + params: { + position: ExchangeModalTabPosition, + }, + screen: ExchangeModal, + }, }, { + disableKeyboardHandling: true, headerMode: 'none', initialLayout: deviceUtils.dimensions, - keyboardDismissMode: 'none', + keyboardDismissMode: 'on-drag', + keyboardShouldPersistTaps: 'always', mode: 'modal', + onTransitionEnd, + onTransitionStart, + position: ExchangeModalTabPosition, springConfig: { - damping: 16, - mass: 0.3, + damping: 40, + mass: 1, overshootClamping: false, - restDisplacementThreshold: 1, - restSpeedThreshold: 1, - stiffness: 140, + restDisplacementThreshold: 0.01, + restSpeedThreshold: 0.01, + stiffness: 300, }, + swipeDistanceMinimum: 0, + swipeVelocityImpact: 1, + swipeVelocityScale: 1, tabBarComponent: null, transparentCard: true, }); // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = props => ; // React.memo(); +const EnhancedExchangeModalNavigator = React.memo(props => ); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ ...navigation.state.params, gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), }); - const MainNavigator = createStackNavigator({ ConfirmRequest: { navigationOptions: { diff --git a/yarn.lock b/yarn.lock index 8e2d25cb167..0f7fb7517c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1940,6 +1940,7 @@ "@types/node@*": <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -1961,6 +1962,11 @@ version "12.6.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== +======= + version "12.7.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.0.tgz#545dde2a1a5c27d281cfb8308d6736e0708f5d6c" + integrity sha512-vqcj1MVm2Sla4PpMfYKh1MyDN4D2f/mPIZD7RdAGqEsbE+JxfeqQHHVbRDQ0Nqn8i73gJa1HQ1Pu3+nH4Q0Yiw== +>>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views "@types/node@^10.3.2": version "10.14.14" @@ -4385,6 +4391,7 @@ electron-to-chromium@^1.3.191: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.3.205" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" @@ -4450,7 +4457,15 @@ electron-to-chromium@^1.3.188: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.215.tgz#c833cb31110c2e0a7dade1110648c2174f75233b" integrity sha512-ZV3OnwF0FlIygwxAG2H92yt7WGjWBpawyFAFu8e9k7xJatY+BPowID0D0Bs3PMACYAJATEejw/I9cawO27ZvTg== >>>>>>> b1697d93... Cleanup ButtonPressAnimation +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +======= + version "1.3.218" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.218.tgz#8a873456e6640da1bed18a8718da1b1a3c4f604c" + integrity sha512-+ABuwQH2bEUbJTMPUMfP9mjBFtbLgDjlrkg3QGQZwr/RJB7aJZBm8g3SK/lR/J76P6l/4a6RgW2yQjZQDdjtFw== +>>>>>>> 55f47d2b... Begin orchestrating keyboard focus between swap modal views +>>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views elliptic@6.3.3: version "6.3.3" @@ -9907,6 +9922,9 @@ react-native-randombytes@^3.5.3: sjcl "^1.0.3" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views react-native-reanimated@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.2.0.tgz#9219227a52a5dfa4d34c324596d6726ccd874293" @@ -10017,6 +10035,14 @@ react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: prop-types "^15.6.1" <<<<<<< HEAD +<<<<<<< HEAD +======= +react-native-tab-view@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.0.tgz#5e249e5650502010013449ffd4e5edc18a95364b" + integrity sha512-qgexVz5eO4yaFjdkmn/sURXgVvaBo6pZD/q1eoca96SbPVbaH3WzVhF3bRUfeTHwZkXwznFTpS3JURqIFU8vQA== + +>>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views react-native-tcp@^3.3.0: ======= react-native-tcp@^3.2.1: @@ -10164,6 +10190,15 @@ react-navigation-stack@^2.0.0-alpha.7: react-native-safe-area-view "^0.14.6" >>>>>>> 751dba29... Replace navigation animations with new effects +react-navigation-tabs@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.3.0.tgz#0288830e6ac5157f203ee3947bc29b0d6eda66b1" + integrity sha512-0LiTwXEVt7XdzVT02fvg14NMz90zfPUyw1g2mIrWA70+M56br5k6tXKrZg8NjH1MgWVz5TWBx90SI0MhD2OssA== + dependencies: + hoist-non-react-statics "^3.3.0" + react-lifecycles-compat "^3.0.4" + react-native-tab-view "^2.9.0" + react-navigation-tabs@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" From 7446cc469681abf9b6b19b94a57f018f0856ba03 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 7 Aug 2019 17:19:39 -0700 Subject: [PATCH 173/636] use latest react-native-tabs for ExchangeModalNavigator --- src/screens/Routes.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index f02f9b4fb33..831e2308ff2 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -7,7 +7,8 @@ import { createMaterialTopTabNavigator, } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; -import Navigation from '../navigation'; +import { createMaterialTopTabNavigator as newTopTabNavigator } from 'react-navigation-tabs'; +import { Navigation } from '../navigation'; import { updateTransitionProps } from '../redux/navigation'; import store from '../redux/store'; import { colors } from '../styles'; @@ -88,8 +89,10 @@ const ExchangeModalNavigator = newTopTabNavigator({ disableKeyboardHandling: true, headerMode: 'none', initialLayout: deviceUtils.dimensions, - keyboardDismissMode: 'on-drag', + keyboardDismissMode: 'none', keyboardShouldPersistTaps: 'always', + onSwipeStart: onTransitionStart, + onSwipeEnd: onTransitionEnd, mode: 'modal', onTransitionEnd, onTransitionStart, @@ -187,16 +190,6 @@ const MainNavigator = createStackNavigator({ mode: 'card', screen: ExchangeModal, }, - ExchangeModal: { - navigationOptions: { - effect: 'expanded', - gestureResponseDistance: { - vertical: deviceUtils.dimensions.height, - }, - gesturesEnabled: true, - }, - screen: ExchangeModalNavigator, - }, SwipeLayout: { navigationOptions: { ...backgroundPreset, @@ -217,7 +210,7 @@ const MainNavigator = createStackNavigator({ disableKeyboardHandling: true, // XXX not sure about this from rebase headerMode: 'none', initialRouteName: 'SwipeLayout', - keyboardDismissMode: true, + keyboardDismissMode: 'none', // true? mode: 'modal', }); From 78b5798e6394557c2f3551a2d4453659e7a5d687 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 7 Aug 2019 22:16:34 -0700 Subject: [PATCH 174/636] Minor cleanup Header component --- ios/Podfile.lock | 8 ++++ package.json | 2 +- src/components/header/Header.js | 25 ++++++------ yarn.lock | 70 +++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 15 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 41e7afe9f84..e3ee2f68905 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -172,6 +172,7 @@ PODS: - React <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= @@ -200,6 +201,9 @@ PODS: - RNDeviceInfo (2.3.2): >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + - RNDeviceInfo (2.3.2): +>>>>>>> 1d794746... Minor cleanup Header component - React - RNIOS11DeviceCheck (0.0.3): - React @@ -428,6 +432,7 @@ SPEC CHECKSUMS: RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= @@ -456,6 +461,9 @@ SPEC CHECKSUMS: RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +>>>>>>> 1d794746... Minor cleanup Header component RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 diff --git a/package.json b/package.json index de8b8af9f44..f0c64b81ba0 100644 --- a/package.json +++ b/package.json @@ -241,4 +241,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file diff --git a/src/components/header/Header.js b/src/components/header/Header.js index 3fbde49e01e..3e84be65338 100644 --- a/src/components/header/Header.js +++ b/src/components/header/Header.js @@ -1,6 +1,5 @@ import React from 'react'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; -import styled from 'styled-components/primitives'; import { padding } from '../../styles'; import { Row } from '../layout'; @@ -8,19 +7,17 @@ const StatusBarHeight = getStatusBarHeight(true); const HeaderHeight = 52; const HeaderHeightWithStatusBar = HeaderHeight + StatusBarHeight; -const Container = styled(Row).attrs({ align: 'end' })` - ${padding(StatusBarHeight, 9, 0)}; - flex-shrink: 0; - height: ${({ excludeStatusBarHeight }) => ( - (excludeStatusBarHeight === true) - ? HeaderHeight - : HeaderHeightWithStatusBar - )}; - width: 100%; - z-index: 1; -`; - -const Header = props => ; +const Header = React.memo((props) => ( + +)); Header.height = HeaderHeight; diff --git a/yarn.lock b/yarn.lock index 0f7fb7517c2..14693281c70 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1170,9 +1170,15 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x": +<<<<<<< HEAD version "8.2.4" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020" integrity sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow== +======= + version "8.2.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.0.tgz#079a133be240ff866ad8532eaa46a691bdd91117" + integrity sha512-pR2ZgiP562aiaQvQ98WgfqfTrm+xG+7hwHRPEiYZ+7U1OHAAb4OVZJIalCP03bMqYSioQzflzVTVrybSwDBn1Q== +>>>>>>> 1d794746... Minor cleanup Header component "@hapi/joi@^15.0.3": version "15.1.1" @@ -1941,6 +1947,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -1973,6 +1980,16 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "12.7.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" + integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== + +"@types/node@^10.3.2": + version "10.14.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" + integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g== +>>>>>>> 1d794746... Minor cleanup Header component "@types/node@^8.0.7": <<<<<<< HEAD @@ -3284,6 +3301,7 @@ caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.0.30000987" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" @@ -3316,6 +3334,11 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +>>>>>>> 1d794746... Minor cleanup Header component capture-exit@^1.2.0: version "1.2.0" @@ -3714,12 +3737,15 @@ confusing-browser-globals@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz#93ffec1f82a6e2bf2bc36769cc3a92fa20e502f3" integrity sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg== +<<<<<<< HEAD ======= confusing-browser-globals@^1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.7.tgz#5ae852bd541a910e7ffb2dbb864a2d21a36ad29b" integrity sha512-cgHI1azax5ATrZ8rJ+ODDML9Fvu67PimB6aNxBrc/QwSaDaM9eTfIEUHx3bBLJJ82ioSb+/5zfsMCCEJax3ByQ== >>>>>>> 751dba29... Replace navigation animations with new effects +======= +>>>>>>> 1d794746... Minor cleanup Header component connect@^3.6.5: version "3.7.0" @@ -3780,6 +3806,14 @@ core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== +<<<<<<< HEAD +======= +core-js@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.0.tgz#0a835fdf6aa677fff83a823a7b5276c9e7cebb76" + integrity sha512-gybgLzmr7SQRSF6UzGYXducx4eE10ONQlyEnQoqiGPbmbn7zLkb73tPfc4YbZN0lvcTQwoLNPjq4RuCaCumGyQ== + +>>>>>>> 1d794746... Minor cleanup Header component core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -4392,6 +4426,7 @@ electron-to-chromium@^1.3.191: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.3.205" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" @@ -4466,6 +4501,11 @@ electron-to-chromium@^1.3.188: integrity sha512-+ABuwQH2bEUbJTMPUMfP9mjBFtbLgDjlrkg3QGQZwr/RJB7aJZBm8g3SK/lR/J76P6l/4a6RgW2yQjZQDdjtFw== >>>>>>> 55f47d2b... Begin orchestrating keyboard focus between swap modal views >>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views +======= + version "1.3.221" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.221.tgz#421a58ac8d1931c8df400d55c7f6fd621710da10" + integrity sha512-YbNA7KgCvLq9ZaEa7wpYP7IP4LrJ4+b36oeF1lYBSJ0zVGVN7uo3Ct9qDUm/M3VDOWj03RVgsMFF8PdL8UjhzA== +>>>>>>> 1d794746... Minor cleanup Header component elliptic@6.3.3: version "6.3.3" @@ -4754,6 +4794,7 @@ eslint-plugin-prettier@2.6.2: jest-docblock "^21.0.0" eslint-plugin-react-hooks@^1.5.1: +<<<<<<< HEAD <<<<<<< HEAD version "1.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" @@ -4763,6 +4804,11 @@ eslint-plugin-react-hooks@^1.5.1: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz#3c66a5515ea3e0a221ffc5d4e75c971c217b1a4c" integrity sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA== >>>>>>> 751dba29... Replace navigation animations with new effects +======= + version "1.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" + integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== +>>>>>>> 1d794746... Minor cleanup Header component eslint-plugin-react-native-animation-linter@^0.1.2: version "0.1.2" @@ -6053,6 +6099,7 @@ i18n-js@^3.0.11: i18next@^17.0.3: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -6067,6 +6114,11 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.9.tgz#5f835e91a34fa5e7da1e5ae4c4586c81d7c4b17f" integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "17.0.10" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" + integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== +>>>>>>> 1d794746... Minor cleanup Header component dependencies: "@babel/runtime" "^7.3.1" @@ -9316,6 +9368,7 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.0: +<<<<<<< HEAD <<<<<<< HEAD version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" @@ -9325,6 +9378,11 @@ postcss-value-parser@^4.0.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz#e3f6172cc91302912c89da55a42454025485250f" integrity sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== +>>>>>>> 1d794746... Minor cleanup Header component postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.7: version "7.0.18" @@ -9739,6 +9797,7 @@ react-native-crypto@^2.1.2: react-native-device-info@^2.1.3: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" @@ -9780,6 +9839,11 @@ react-native-device-info@^2.1.3: integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +>>>>>>> 1d794746... Minor cleanup Header component react-native-dotenv@^0.2.0: version "0.2.0" @@ -12108,6 +12172,7 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== tsutils@^3.7.0: +<<<<<<< HEAD <<<<<<< HEAD version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -12117,6 +12182,11 @@ tsutils@^3.7.0: resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.0.tgz#c3ccab927a475aa2beef6a3695c2ff76da13cdf8" integrity sha512-fyveWOtAXfumAxIqkcMHuPaaVyLBKjB8Y00ANZkqh+HITBAQscCbQIHwwBTJdvQq7RykLEbOPcUUnJ16X4NA0g== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== +>>>>>>> 1d794746... Minor cleanup Header component dependencies: tslib "^1.8.1" From 59011d84da77da71d39a930730e596315b5adedf Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 03:38:45 -0700 Subject: [PATCH 175/636] Create Exchange related Input components --- package.json | 2 +- .../exchange/ConfirmExchangeButton.js | 6 +- src/components/exchange/ExchangeInputField.js | 11 +- .../exchange/ExchangeOutputField.js | 4 +- yarn.lock | 369 ++++++++++++++++++ 5 files changed, 379 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index f0c64b81ba0..de8b8af9f44 100644 --- a/package.json +++ b/package.json @@ -241,4 +241,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 5d978820cea..938c0879c63 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -2,13 +2,9 @@ import PropTypes from 'prop-types'; import React from 'react'; import { onlyUpdateForPropTypes } from 'recompact'; import { colors } from '../../styles'; - import { HoldToAuthorizeButton } from '../buttons'; -const ConfirmExchangeButton = ({ - disabled, - onPress, -}) => ( +const ConfirmExchangeButton = ({ disabled, onPress }) => ( @@ -96,10 +97,10 @@ export default class ExchangeInputField extends PureComponent { ( export default class ExchangeOutputField extends PureComponent { static propTypes = { - onPressSelectOutputCurrency: PropTypes.string, - outputAmount: PropTypes.number, + onPressSelectOutputCurrency: PropTypes.func, + outputAmount: PropTypes.string, outputCurrency: PropTypes.string, outputFieldRef: PropTypes.func.isRequired, setOutputAmount: PropTypes.func, diff --git a/yarn.lock b/yarn.lock index 14693281c70..28ac941d67b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" @@ -21,6 +22,13 @@ ======= "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": >>>>>>> 96db5a28... begin mike +======= +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": +======= +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": +<<<<<<< HEAD +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -52,6 +60,9 @@ "@babel/traverse" "^7.5.5" "@babel/types" "^7.5.5" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= version "7.5.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd" @@ -65,9 +76,12 @@ "@babel/traverse" "^7.5.0" "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -77,6 +91,10 @@ source-map "^0.5.0" <<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/generator@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" @@ -88,6 +106,7 @@ source-map "^0.5.0" trim-right "^1.0.1" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": @@ -102,6 +121,9 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" @@ -109,6 +131,9 @@ dependencies: "@babel/types" "^7.5.5" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.0": version "7.5.0" @@ -117,9 +142,12 @@ dependencies: "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -157,6 +185,7 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": @@ -167,20 +196,28 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/helper-create-class-features-plugin@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= "@babel/helper-create-class-features-plugin@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz#02edb97f512d44ba23b3227f1bf2ed43454edac5" integrity sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.5.5" @@ -320,6 +357,7 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/helpers@^7.6.0": @@ -334,6 +372,8 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/helpers@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" @@ -343,6 +383,9 @@ "@babel/traverse" "^7.5.5" "@babel/types" "^7.5.5" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= "@babel/helpers@^7.5.4": version "7.5.4" @@ -353,9 +396,12 @@ "@babel/traverse" "^7.5.0" "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/highlight@^7.0.0": version "7.5.0" @@ -366,6 +412,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": @@ -376,20 +423,28 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -399,11 +454,19 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": +<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" +======= + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007" + integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.5.0" +>>>>>>> 8d2e8d2f... BREAK UP "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": @@ -423,9 +486,15 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": +<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== +======= + version "7.5.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331" + integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -694,12 +763,15 @@ "@babel/plugin-transform-runtime@^7.0.0": <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" integrity sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg== ======= <<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== @@ -708,12 +780,15 @@ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.0.tgz#45242c2c9281158c5f06d25beebac63e498a284e" integrity sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -752,6 +827,7 @@ "@babel/plugin-transform-typescript@^7.0.0": <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz#48d78405f1aa856ebeea7288a48a19ed8da377a6" @@ -762,12 +838,17 @@ <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= version "7.5.2" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz#ea7da440d29b8ccdb1bd02e18f6cfdc7ce6c16f5" @@ -775,9 +856,12 @@ dependencies: "@babel/helper-create-class-features-plugin" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -804,6 +888,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" @@ -823,14 +908,27 @@ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== <<<<<<< HEAD +======= +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": +======= +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": +<<<<<<< HEAD +>>>>>>> 034f7aa3... Create Exchange related Input components + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" + integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== +>>>>>>> 2216260a... Create Exchange related Input components ======= version "7.5.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b" integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components dependencies: regenerator-runtime "^0.13.2" @@ -857,10 +955,18 @@ >>>>>>> 96db5a28... begin mike dependencies: "@babel/code-frame" "^7.0.0" +<<<<<<< HEAD "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" <<<<<<< HEAD +======= + "@babel/parser" "^7.4.4" + "@babel/types" "^7.4.4" + +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/traverse@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" @@ -877,6 +983,7 @@ invariant "^2.2.0" lodash "^4.2.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": @@ -889,6 +996,9 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" @@ -906,6 +1016,9 @@ "@babel/parser" "^7.5.5" "@babel/types" "^7.5.5" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.0": version "7.5.0" @@ -919,14 +1032,21 @@ "@babel/parser" "^7.5.0" "@babel/types" "^7.5.0" >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" <<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> 2216260a... Create Exchange related Input components "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" @@ -936,6 +1056,7 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": @@ -948,20 +1069,29 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1395,6 +1525,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" @@ -1402,6 +1533,8 @@ ======= "@react-native-community/cli-platform-android@^2.0.0-rc.2": ======= +======= +>>>>>>> 2216260a... Create Exchange related Input components "@react-native-community/cli-platform-android@^2.7.0": <<<<<<< HEAD >>>>>>> 96db5a28... begin mike @@ -1413,13 +1546,24 @@ version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +======= +"@react-native-community/cli-platform-android@^2.0.0-rc.2": +<<<<<<< HEAD + version "2.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" + integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" execa "^1.0.0" jetifier "^1.6.2" <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD logkitty "^0.6.0" slash "^3.0.0" @@ -1454,6 +1598,8 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.0.2.tgz#ce21fa9771152a71d2b05fba434d849e32e0376a" integrity sha512-Pwp1EOCfbpNpTXwSLQg7mGmTsCD981nkizu3S7D3QVoIwhQGpuTGXM1xyIFu9IZI2AIHNtUT9W5Nqw97/UDmdw== ======= +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= version "2.4.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.4.1.tgz#27d4c5c7be2a6a28b07cd37f10e661a5eef70b0f" @@ -1462,12 +1608,16 @@ "@react-native-community/cli-tools" "^2.4.1" chalk "^2.4.2" >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components logkitty "^0.5.0" slash "^3.0.0" xmldoc "^1.1.2" +<<<<<<< HEAD "@react-native-community/cli-platform-ios@^2.8.0": <<<<<<< HEAD version "2.8.0" @@ -1516,16 +1666,47 @@ version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== +======= +"@react-native-community/cli-platform-ios@^2.0.0-rc.2": +<<<<<<< HEAD + version "2.8.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" + integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== +>>>>>>> 034f7aa3... Create Exchange related Input components dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" xcode "^2.0.0" +<<<<<<< HEAD "@react-native-community/cli-tools@^2.7.0", "@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +======= +"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" + integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== +======= + version "2.4.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" + integrity sha512-EKfnN+ubIcCHbCCo2a1SlYcd4jLZDT12HfoLHhFg8WXG3/zFWc/vMNpBi+omrvT7Hoktr8cTtROXPg9cIS7FCQ== + dependencies: + "@react-native-community/cli-tools" "^2.4.1" + chalk "^2.4.2" + xcode "^2.0.0" + +"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.4.1.tgz#5a23b92d0b486753add00a27d77d0ea9e8c331e1" + integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1948,6 +2129,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -1981,9 +2163,17 @@ integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= +======= +>>>>>>> 2216260a... Create Exchange related Input components version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== +======= +<<<<<<< HEAD + version "12.6.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" + integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== +>>>>>>> 034f7aa3... Create Exchange related Input components "@types/node@^10.3.2": version "10.14.15" @@ -2001,6 +2191,9 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627" integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components ======= version "12.6.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" @@ -2016,9 +2209,12 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.50.tgz#f3d68482b1f54b5f4fba8daaac385db12bb6a706" integrity sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components "@types/q@^1.5.1": version "1.5.2" @@ -2258,12 +2454,15 @@ acorn@^5.5.3: acorn@^6.0.1, acorn@^6.0.7: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== ======= <<<<<<< HEAD +======= +>>>>>>> 2216260a... Create Exchange related Input components version "6.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== @@ -2272,12 +2471,15 @@ acorn@^6.0.1, acorn@^6.0.7: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== >>>>>>> 8d2e8d2f... BREAK UP +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= version "6.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components aes-js@3.0.0: version "3.0.0" @@ -2289,13 +2491,18 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= +<<<<<<< HEAD agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: +======= +agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@^4.3.0: +>>>>>>> 8d2e8d2f... BREAK UP version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" +<<<<<<< HEAD agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -2307,6 +2514,12 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== +======= +ajv@^6.5.5, ajv@^6.9.1: + version "6.10.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" + integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -2747,6 +2960,7 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" +<<<<<<< HEAD babel-plugin-rewire@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" @@ -2755,6 +2969,7 @@ babel-plugin-rewire@^1.2.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ======= <<<<<<< HEAD @@ -2776,6 +2991,15 @@ babel-plugin-rewire@^1.2.0: ======= "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: >>>>>>> 96db5a28... begin mike +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.2: +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> d743296d... BREAK UP +>>>>>>> 2216260a... Create Exchange related Input components version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -3110,6 +3334,7 @@ browserify-zlib@^0.1.4: browserslist@^4.6.3: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "4.7.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" @@ -3122,12 +3347,22 @@ browserslist@^4.6.3: <<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components version "4.6.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== dependencies: caniuse-lite "^1.0.30000984" electron-to-chromium "^1.3.191" +======= + version "4.6.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" + integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== + dependencies: + caniuse-lite "^1.0.30000981" + electron-to-chromium "^1.3.188" +>>>>>>> 8d2e8d2f... BREAK UP node-releases "^1.1.25" >>>>>>> f7a61a13... Create Exchange related Input components @@ -3279,6 +3514,7 @@ camelize@^1.0.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" @@ -3339,6 +3575,24 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== >>>>>>> 1d794746... Minor cleanup Header component +======= +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: +<<<<<<< HEAD + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +======= + version "1.0.30000985" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f" + integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w== +======= +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: + version "1.0.30000983" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" + integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components capture-exit@^1.2.0: version "1.2.0" @@ -3970,7 +4224,11 @@ csso@^3.5.1: dependencies: css-tree "1.0.0-alpha.29" +<<<<<<< HEAD cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": +======= +"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: +>>>>>>> 8d2e8d2f... BREAK UP version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== @@ -4401,6 +4659,7 @@ ee-first@1.1.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" @@ -4415,6 +4674,8 @@ electron-to-chromium@^1.3.164: ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= +======= +>>>>>>> 2216260a... Create Exchange related Input components ejs@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" @@ -4505,7 +4766,29 @@ electron-to-chromium@^1.3.188: version "1.3.221" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.221.tgz#421a58ac8d1931c8df400d55c7f6fd621710da10" integrity sha512-YbNA7KgCvLq9ZaEa7wpYP7IP4LrJ4+b36oeF1lYBSJ0zVGVN7uo3Ct9qDUm/M3VDOWj03RVgsMFF8PdL8UjhzA== +<<<<<<< HEAD >>>>>>> 1d794746... Minor cleanup Header component +======= +======= +<<<<<<< HEAD +electron-to-chromium@^1.3.191: +<<<<<<< HEAD + version "1.3.200" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" + integrity sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg== +======= + version "1.3.199" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.199.tgz#f9a62a74cda77854310a2abffde8b75591ea09a1" + integrity sha512-gachlDdHSK47s0N2e58GH9HMC6Z4ip0SfmYUa5iEbE50AKaOUXysaJnXMfKj0xB245jWbYcyFSH+th3rqsF8hA== +======= +electron-to-chromium@^1.3.188: + version "1.3.188" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.188.tgz#e28e1afe4bb229989e280bfd3b395c7ec03c8b7a" + integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ== +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> d743296d... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components elliptic@6.3.3: version "6.3.3" @@ -5474,8 +5757,10 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +<<<<<<< HEAD form-data@^2.3.3: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -5486,6 +5771,11 @@ form-data@^2.3.1: >>>>>>> 8d2e8d2f... BREAK UP ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= +form-data@^2.3.1: +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> 2216260a... Create Exchange related Input components version "2.5.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== @@ -7532,10 +7822,25 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= +<<<<<<< HEAD lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: +======= +<<<<<<< HEAD +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: +======= +<<<<<<< HEAD +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: +>>>>>>> d743296d... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +======= +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: + version "4.17.14" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" + integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== +>>>>>>> 8d2e8d2f... BREAK UP log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" @@ -9590,9 +9895,15 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: +<<<<<<< HEAD version "1.4.1" resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w== +======= + version "1.4.0" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.0.tgz#b4b41b4bbfd5eeac8d5163efacef34ee5b8ad455" + integrity sha512-18u+bdSosXO0+wx6F1UUFzJz01VRfMBcb/wbBw/tKYRD0A2Vho5WQ4xz30pHwhh4IE/qhObqIs5yNO0mGdHKkA== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: dijkstrajs "^1.0.1" isarray "^2.0.1" @@ -9761,9 +10072,15 @@ react-native-circular-progress@^1.1.0: prop-types "^15.7.2" react-native-clean-project@^3.1.0: +<<<<<<< HEAD version "3.2.4" resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.4.tgz#55a71006eb4336dff91d0ca5ab3564d8f0db45cc" integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== +======= + version "3.2.3" + resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.3.tgz#40313a3a4131353d5d082d7691b41b4de6f40eb2" + integrity sha512-c8NgNTXAwugyuP+bS5b5mwpML4JrSP+u9D5b6X5OudU6hPlzPsiFLnBzQUvJVSPRHRwCFj30/qHGCjLc/jPzUw== +>>>>>>> 8d2e8d2f... BREAK UP react-native-code-push@^5.6.0: version "5.7.0" @@ -9893,10 +10210,20 @@ react-native-gesture-handler@mikedemarais/react-native-gesture-handler#mike-hook invariant "^2.2.4" prop-types "^15.7.2" +<<<<<<< HEAD react-native-haptic-feedback@^1.8.2: +======= +react-native-haptic-feedback@^1.8.0: +<<<<<<< HEAD +>>>>>>> d743296d... BREAK UP version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== +======= + version "1.8.1" + resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.1.tgz#7e255fa7421dccd5d1da35f2a6bb922c253324a2" + integrity sha512-Y/lXN9S70TJIqg1F4984OlJ/2k0Nt6/5dAyilhVr4CFVvIulFf2dHAXkB1I+OlBiY9iuiCKtw5RixXad5jFEbw== +>>>>>>> 8d2e8d2f... BREAK UP react-native-indicators@^0.13.0: version "0.13.0" @@ -10054,7 +10381,15 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" +<<<<<<< HEAD +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: +======= +<<<<<<< HEAD +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.22: +======= "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> d743296d... BREAK UP version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -10122,10 +10457,17 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" +<<<<<<< HEAD react-native-text-input-mask@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== +======= +react-native-text-input-mask@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.1.tgz#93b4374c3c73bc78eac907094662d5d98166f359" + integrity sha512-gN0N+3tpw1kgHsuaqzugN7hc5XsjlyXET4/Q3C36F6LxwpIdnf3k9yCL4vfAlw6QxwuBTtyFaRxGJgwZkzk4Ng== +>>>>>>> 034f7aa3... Create Exchange related Input components react-native-tooltip@^5.2.0: version "5.2.0" @@ -11683,6 +12025,7 @@ styled-components@4.3.1: stylis-rule-sheet "^0.0.10" supports-color "^5.5.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD styled-components@^5.0.0-beta.8: @@ -11691,21 +12034,36 @@ styled-components@^5.0.0-beta.8: resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8-groupsizefix.tgz#0497f11c0d60e9e51faa4b802afab7cc22136e42" integrity sha512-5FDDRE4QhH8g6zsvHGPZ2NrJRi12AH1GxpZMy+y0lRYGrfNL6W5xni5Sz8kOKXS4PGf1VeyfVXaEG10mbrQYsA== ======= +======= +======= +<<<<<<< HEAD +styled-components@^5.0.0-beta.8: +>>>>>>> 2216260a... Create Exchange related Input components version "5.0.0-beta.6-ej4" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.6-ej4.tgz#7570ebbf9c9356a8cca03ea37dd94233f2e40e84" integrity sha512-WaytinYy4+Zc1TKXdTlPmkAOIj58QWvjn1rdgxCSAMAR4GFLlu2m7rQXwZ6WYWYk6GJd141rnZnE2Ig3XERc5A== ======= +<<<<<<< HEAD ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components styled-components@5.0.0-beta.8: version "5.0.0-beta.8" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8.tgz#ad1e672589a891987f5492cbe3ca6f480fcd99dc" integrity sha512-g4MrDmfaoR2jJnA56+JSTFf1ZsDpJYdvTyQSw3HWOHoV/KlCgaSFmU8TrHfTy7DwWQskxyX//IQInNZdn4mGcA== <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +>>>>>>> 2216260a... Create Exchange related Input components dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -12654,6 +13012,7 @@ wide-align@1.1.3, wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +<<<<<<< HEAD widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" @@ -12661,6 +13020,8 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +======= +>>>>>>> 8d2e8d2f... BREAK UP wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -12970,12 +13331,20 @@ yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: yargs@^13.0.0, yargs@^13.2.4: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 2216260a... Create Exchange related Input components version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== +======= + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== +>>>>>>> 8d2e8d2f... BREAK UP dependencies: cliui "^5.0.0" find-up "^3.0.0" From 1af4776c8ccb4efead680d4573ade6b93512621f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 30 Jul 2019 04:30:26 -0700 Subject: [PATCH 176/636] fix conflicts after rebasing over latest wallet-zero branch --- ios/Podfile.lock | 50 ++++++++ package.json | 2 +- yarn.lock | 305 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 290 insertions(+), 67 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e3ee2f68905..5a3763d4e13 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -168,11 +168,13 @@ PODS: - React - RNCAsyncStorage (1.5.0): - React +<<<<<<< HEAD - RNCMaskedView (0.1.1): - React <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= @@ -204,6 +206,15 @@ PODS: ======= - RNDeviceInfo (2.3.2): >>>>>>> 1d794746... Minor cleanup Header component +======= + - RNDeviceInfo (2.3.2): +======= + - RNDeviceInfo (2.3.0): +======= + - RNDeviceInfo (2.3.1): +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - React - RNIOS11DeviceCheck (0.0.3): - React @@ -213,10 +224,12 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React +<<<<<<< HEAD - RNStoreReview (0.1.5): - React <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -237,6 +250,21 @@ PODS: - SDWebImage/Core (= 5.1.0) - SDWebImage/Core (5.1.0) >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + - SDWebImage (5.1.0): + - SDWebImage/Core (= 5.1.0) + - SDWebImage/Core (5.1.0) +======= + - SDWebImage (5.0.2): + - SDWebImage/Core (= 5.0.2) + - SDWebImage/Core (5.0.2) +======= + - SDWebImage (5.0.6): + - SDWebImage/Core (= 5.0.6) + - SDWebImage/Core (5.0.6) +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - yoga (0.59.9.React) >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch @@ -429,10 +457,12 @@ SPEC CHECKSUMS: React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 +<<<<<<< HEAD RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= @@ -464,13 +494,24 @@ SPEC CHECKSUMS: ======= RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 >>>>>>> 1d794746... Minor cleanup Header component +======= + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +======= + RNDeviceInfo: 65106cc87ad6f6f71ef2ecc667f4c59b840888e2 +======= + RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 +<<<<<<< HEAD RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -483,6 +524,15 @@ SPEC CHECKSUMS: ======= SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f +======= + SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 +======= + SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch diff --git a/package.json b/package.json index de8b8af9f44..f0c64b81ba0 100644 --- a/package.json +++ b/package.json @@ -241,4 +241,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 28ac941d67b..6f0eec309f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27,8 +27,14 @@ ======= "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -61,6 +67,7 @@ "@babel/types" "^7.5.5" <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -82,6 +89,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -109,6 +118,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" @@ -124,6 +134,11 @@ ======= >>>>>>> 034f7aa3... Create Exchange related Input components >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" @@ -132,6 +147,7 @@ "@babel/types" "^7.5.5" <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -148,6 +164,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -188,6 +206,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" @@ -198,12 +217,15 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/helper-create-class-features-plugin@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -218,6 +240,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.5.5" @@ -360,6 +384,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/helpers@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e" @@ -374,6 +399,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/helpers@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" @@ -384,6 +411,7 @@ "@babel/types" "^7.5.5" <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -402,6 +430,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/highlight@^7.0.0": version "7.5.0" @@ -415,6 +445,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" @@ -425,12 +456,15 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -445,6 +479,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -454,19 +490,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": -<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" -======= - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz#5bc6a0537d286fcb4fd4e89975adbca334987007" - integrity sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": @@ -486,15 +514,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": -<<<<<<< HEAD version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== -======= - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331" - integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -764,6 +786,7 @@ "@babel/plugin-transform-runtime@^7.0.0": <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" @@ -789,6 +812,11 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" + integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -828,6 +856,7 @@ "@babel/plugin-transform-typescript@^7.0.0": <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz#48d78405f1aa856ebeea7288a48a19ed8da377a6" @@ -840,6 +869,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== @@ -847,6 +878,7 @@ "@babel/helper-create-class-features-plugin" "^7.5.5" <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -862,6 +894,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -913,10 +947,14 @@ ======= "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 034f7aa3... Create Exchange related Input components +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components ======= version "7.5.4" @@ -929,6 +967,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: regenerator-runtime "^0.13.2" @@ -986,6 +1026,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" @@ -999,6 +1040,11 @@ ======= >>>>>>> 034f7aa3... Create Exchange related Input components >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" @@ -1017,6 +1063,7 @@ "@babel/types" "^7.5.5" <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -1038,6 +1085,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" @@ -1059,6 +1108,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": version "7.6.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" @@ -1072,12 +1122,18 @@ ======= >>>>>>> 034f7aa3... Create Exchange related Input components >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 034f7aa3... Create Exchange related Input components +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -1092,6 +1148,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1256,9 +1314,15 @@ integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== "@ethersproject/properties@>5.0.0-beta.0": +<<<<<<< HEAD version "5.0.0-beta.130" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== +======= + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.128.tgz#26e8a4cb95f0d048531f0a8da39773b16b4633b4" + integrity sha512-4ABgX2WmpQLlmbyR6EwxoT5YTRYxV6fGRtK+1nt48dvG2Y8FSkg33JvCfei3w432RjEEHEN5IOmTf+nTr9n6VA== +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@ethersproject/logger" ">5.0.0-beta.0" @@ -1271,6 +1335,7 @@ "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": +<<<<<<< HEAD <<<<<<< HEAD version "5.0.0-beta.131" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" @@ -1280,9 +1345,16 @@ "@ethersproject/constants" ">=5.0.0-beta.128" "@ethersproject/logger" ">=5.0.0-beta.129" ======= +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "5.0.0-beta.129" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== +======= + version "5.0.0-beta.127" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.127.tgz#e07848b92cb1b615a11d7289449312c069a234e9" + integrity sha512-FKQDBKgcX7Bc0J45TIwwT4PTnE1TvtDRka3dAkH1VX4odnj6DzpZ99QdkhX4mBL2J+6/XK+trA7m/HTDx+5YqA== +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@ethersproject/bytes" ">5.0.0-beta.0" "@ethersproject/constants" ">5.0.0-beta.0" @@ -1551,7 +1623,6 @@ ======= ======= "@react-native-community/cli-platform-android@^2.0.0-rc.2": -<<<<<<< HEAD version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== @@ -1564,6 +1635,7 @@ jetifier "^1.6.2" <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD logkitty "^0.6.0" slash "^3.0.0" @@ -1613,6 +1685,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch logkitty "^0.5.0" slash "^3.0.0" xmldoc "^1.1.2" @@ -1668,7 +1742,6 @@ integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== ======= "@react-native-community/cli-platform-ios@^2.0.0-rc.2": -<<<<<<< HEAD version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== @@ -1691,6 +1764,7 @@ version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== +<<<<<<< HEAD ======= version "2.4.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" @@ -1706,7 +1780,12 @@ integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -2130,6 +2209,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -2165,11 +2245,15 @@ ======= ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== ======= <<<<<<< HEAD +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch version "12.6.8" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== @@ -2192,6 +2276,7 @@ integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components ======= @@ -2215,6 +2300,8 @@ >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@types/q@^1.5.1": version "1.5.2" @@ -2455,6 +2542,7 @@ acorn@^5.5.3: acorn@^6.0.1, acorn@^6.0.7: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" @@ -2480,6 +2568,11 @@ acorn@^6.0.1, acorn@^6.0.7: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= + version "6.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" + integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch aes-js@3.0.0: version "3.0.0" @@ -2491,18 +2584,13 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -<<<<<<< HEAD agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: -======= -agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@^4.3.0: ->>>>>>> 8d2e8d2f... BREAK UP version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" -<<<<<<< HEAD agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -2514,12 +2602,6 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== -======= -ajv@^6.5.5, ajv@^6.9.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" - integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -2960,7 +3042,6 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" -<<<<<<< HEAD babel-plugin-rewire@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" @@ -2970,6 +3051,7 @@ babel-plugin-rewire@^1.2.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ======= <<<<<<< HEAD @@ -2992,6 +3074,8 @@ babel-plugin-rewire@^1.2.0: "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: >>>>>>> 96db5a28... begin mike ======= +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ======= "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.2: @@ -2999,7 +3083,13 @@ babel-plugin-rewire@^1.2.0: "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> d743296d... BREAK UP +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -3335,6 +3425,7 @@ browserify-zlib@^0.1.4: browserslist@^4.6.3: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "4.7.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" @@ -3349,20 +3440,14 @@ browserslist@^4.6.3: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "4.6.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== dependencies: caniuse-lite "^1.0.30000984" electron-to-chromium "^1.3.191" -======= - version "4.6.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" - integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== - dependencies: - caniuse-lite "^1.0.30000981" - electron-to-chromium "^1.3.188" ->>>>>>> 8d2e8d2f... BREAK UP node-releases "^1.1.25" >>>>>>> f7a61a13... Create Exchange related Input components @@ -3515,6 +3600,7 @@ camelize@^1.0.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" @@ -3576,7 +3662,10 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== >>>>>>> 1d794746... Minor cleanup Header component ======= +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: +<<<<<<< HEAD <<<<<<< HEAD version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" @@ -3592,7 +3681,15 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= + version "1.0.30000987" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" + integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch capture-exit@^1.2.0: version "1.2.0" @@ -4224,11 +4321,7 @@ csso@^3.5.1: dependencies: css-tree "1.0.0-alpha.29" -<<<<<<< HEAD cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": -======= -"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: ->>>>>>> 8d2e8d2f... BREAK UP version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== @@ -4660,6 +4753,7 @@ ee-first@1.1.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" @@ -4676,6 +4770,8 @@ electron-to-chromium@^1.3.164: ======= ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch ejs@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" @@ -4771,7 +4867,10 @@ electron-to-chromium@^1.3.188: ======= ======= <<<<<<< HEAD +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch electron-to-chromium@^1.3.191: +<<<<<<< HEAD <<<<<<< HEAD version "1.3.200" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" @@ -4787,8 +4886,26 @@ electron-to-chromium@^1.3.188: integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ== >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> d743296d... BREAK UP +<<<<<<< HEAD >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +======= +======= + version "1.3.190" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz#5bf599519983bfffd9d4387817039a3ed7ca085f" + integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== +>>>>>>> 9a56f78d... WIP swap ui polish +>>>>>>> 2db58de2... WIP swap ui polish +======= + version "1.3.205" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" + integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch elliptic@6.3.3: version "6.3.3" @@ -5757,10 +5874,10 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -<<<<<<< HEAD form-data@^2.3.3: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -5776,6 +5893,8 @@ form-data@^2.3.1: form-data@^2.3.1: >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "2.5.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== @@ -6390,6 +6509,7 @@ i18n-js@^3.0.11: i18next@^17.0.3: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -6409,6 +6529,16 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== >>>>>>> 1d794746... Minor cleanup Header component +======= + version "17.0.10" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" + integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== +======= + version "17.0.7" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.7.tgz#aae8591634b109c0ecec755b46c6414b0d743e07" + integrity sha512-fQn+gcyDaHb3qXIeahjCnGMsCeHaKveSORclang55stBjOL13oK7ZYxXVz1AaFV6p3SzOSu/KW+tgZcUuDdf6Q== +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/runtime" "^7.3.1" @@ -7826,21 +7956,27 @@ lodash.unescape@4.0.1: lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: ======= <<<<<<< HEAD +<<<<<<< HEAD lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: ======= <<<<<<< HEAD +======= +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: >>>>>>> d743296d... BREAK UP >>>>>>> 034f7aa3... Create Exchange related Input components version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +<<<<<<< HEAD ======= lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: version "4.17.14" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== >>>>>>> 8d2e8d2f... BREAK UP +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" @@ -9895,15 +10031,9 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: -<<<<<<< HEAD version "1.4.1" resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w== -======= - version "1.4.0" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.0.tgz#b4b41b4bbfd5eeac8d5163efacef34ee5b8ad455" - integrity sha512-18u+bdSosXO0+wx6F1UUFzJz01VRfMBcb/wbBw/tKYRD0A2Vho5WQ4xz30pHwhh4IE/qhObqIs5yNO0mGdHKkA== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: dijkstrajs "^1.0.1" isarray "^2.0.1" @@ -9993,20 +10123,33 @@ react-clone-referenced-element@^1.0.1: <<<<<<< HEAD <<<<<<< HEAD +======= +react-coin-icon@^0.1.9: +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD <<<<<<< HEAD react-coin-icon@^0.1.9: ======= <<<<<<< HEAD react-coin-icon@^0.1.8: ======= +<<<<<<< HEAD >>>>>>> 397368cb... WIP swap ui polish +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch react-coin-icon@^0.1.9: >>>>>>> 9a56f78d... WIP swap ui polish >>>>>>> 2db58de2... WIP swap ui polish ======= +<<<<<<< HEAD ======= >>>>>>> 96db5a28... begin mike +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch react-coin-icon@^0.1.9: +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== @@ -10072,15 +10215,9 @@ react-native-circular-progress@^1.1.0: prop-types "^15.7.2" react-native-clean-project@^3.1.0: -<<<<<<< HEAD version "3.2.4" resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.4.tgz#55a71006eb4336dff91d0ca5ab3564d8f0db45cc" integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== -======= - version "3.2.3" - resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.3.tgz#40313a3a4131353d5d082d7691b41b4de6f40eb2" - integrity sha512-c8NgNTXAwugyuP+bS5b5mwpML4JrSP+u9D5b6X5OudU6hPlzPsiFLnBzQUvJVSPRHRwCFj30/qHGCjLc/jPzUw== ->>>>>>> 8d2e8d2f... BREAK UP react-native-code-push@^5.6.0: version "5.7.0" @@ -10115,6 +10252,7 @@ react-native-device-info@^2.1.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" @@ -10161,6 +10299,22 @@ react-native-device-info@^2.1.3: resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== >>>>>>> 1d794746... Minor cleanup Header component +======= + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +======= +<<<<<<< HEAD + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.0.tgz#7b2a8baf8453324bd8d120ce46e5e2bb0181ccd4" + integrity sha512-ISEChH2zg4bRX8PL1cYoNWffJ7wmgYosKyJbkWyTxs8g+rpeGkmMf9Wo4COriAt1AJ2jC78IGhJYFzbIc+Przw== +======= + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" + integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch react-native-dotenv@^0.2.0: version "0.2.0" @@ -10215,15 +10369,13 @@ react-native-haptic-feedback@^1.8.2: ======= react-native-haptic-feedback@^1.8.0: <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> d743296d... BREAK UP +======= +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -======= - version "1.8.1" - resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.1.tgz#7e255fa7421dccd5d1da35f2a6bb922c253324a2" - integrity sha512-Y/lXN9S70TJIqg1F4984OlJ/2k0Nt6/5dAyilhVr4CFVvIulFf2dHAXkB1I+OlBiY9iuiCKtw5RixXad5jFEbw== ->>>>>>> 8d2e8d2f... BREAK UP react-native-indicators@^0.13.0: version "0.13.0" @@ -10381,6 +10533,7 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" +<<<<<<< HEAD <<<<<<< HEAD "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: ======= @@ -10390,6 +10543,9 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> d743296d... BREAK UP +======= +"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: +>>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -10464,10 +10620,16 @@ react-native-text-input-mask@^1.0.6: integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== ======= react-native-text-input-mask@^1.0.1: +<<<<<<< HEAD version "1.0.1" resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.1.tgz#93b4374c3c73bc78eac907094662d5d98166f359" integrity sha512-gN0N+3tpw1kgHsuaqzugN7hc5XsjlyXET4/Q3C36F6LxwpIdnf3k9yCL4vfAlw6QxwuBTtyFaRxGJgwZkzk4Ng== >>>>>>> 034f7aa3... Create Exchange related Input components +======= + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" + integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch react-native-tooltip@^5.2.0: version "5.2.0" @@ -12028,6 +12190,7 @@ styled-components@4.3.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD styled-components@^5.0.0-beta.8: <<<<<<< HEAD version "5.0.0-beta.8-groupsizefix" @@ -12036,6 +12199,8 @@ styled-components@^5.0.0-beta.8: ======= ======= ======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= <<<<<<< HEAD styled-components@^5.0.0-beta.8: >>>>>>> 2216260a... Create Exchange related Input components @@ -12048,13 +12213,19 @@ styled-components@^5.0.0-beta.8: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch styled-components@5.0.0-beta.8: version "5.0.0-beta.8" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8.tgz#ad1e672589a891987f5492cbe3ca6f480fcd99dc" integrity sha512-g4MrDmfaoR2jJnA56+JSTFf1ZsDpJYdvTyQSw3HWOHoV/KlCgaSFmU8TrHfTy7DwWQskxyX//IQInNZdn4mGcA== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components ======= @@ -12064,6 +12235,13 @@ styled-components@5.0.0-beta.8: >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> 034f7aa3... Create Exchange related Input components >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +>>>>>>> 8d2e8d2f... BREAK UP +>>>>>>> 034f7aa3... Create Exchange related Input components +======= +>>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -13012,7 +13190,6 @@ wide-align@1.1.3, wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -<<<<<<< HEAD widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" @@ -13020,8 +13197,6 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" -======= ->>>>>>> 8d2e8d2f... BREAK UP wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -13332,19 +13507,17 @@ yargs@^13.0.0, yargs@^13.2.4: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> f7a61a13... Create Exchange related Input components ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 2216260a... Create Exchange related Input components +======= +>>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== -======= - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== ->>>>>>> 8d2e8d2f... BREAK UP dependencies: cliui "^5.0.0" find-up "^3.0.0" From 0b344fc9cb43f0cd876f558f3b3771ace2e7e175 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 30 Jul 2019 18:48:41 -0400 Subject: [PATCH 177/636] temp updates --- src/hoc/withAccountSettings.js | 2 + src/screens/ExchangeModal.js | 80 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/hoc/withAccountSettings.js b/src/hoc/withAccountSettings.js index f32bee86906..3c0815a56a9 100644 --- a/src/hoc/withAccountSettings.js +++ b/src/hoc/withAccountSettings.js @@ -10,10 +10,12 @@ import { const mapStateToProps = ({ settings: { + chainId, language, nativeCurrency, }, }) => ({ + chainId, language, nativeCurrency, }); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a9451f8ba12..f04b0d471ed 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -14,6 +14,7 @@ import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { withAccountData, + withAccountSettings, withBlockedHorizontalSwipe, withKeyboardFocusHistory, withNeverRerender, @@ -264,6 +265,85 @@ const withMockedPrices = withProps({ export default compose( withAccountData, + withAccountSettings, + withState('useInputAsExactAmount', 'setUseInputAsExactAmount', null), + withState('amountToExchange', 'setAmountToExchange', '0'), + withState('targetAmountToExchange', 'setTargetAmountToExchange', '0'), + withState('selectedCurrency', 'setSelectedCurrency', null), + withState('selectedTargetCurrency', 'setSelectedTargetCurrency', null), + withProps(({ + selectedCurrency, + allAssets: [{ symbol }], + }) => ({ selectedCurrency: selectedCurrency || symbol })), + withHandlers({ + getMarketDetails: ({ + chainId, + selectedCurrency, + selectedTargetCurrency, + setAmountToExchange, + setTargetAmountToExchange, + useInputAsExactAmount, + }) => async () => { + try { + // TODO format amounts + let tradeDetails = null; + // normal amount to raw amount (no pricing) + // convertAmountToRawAmount(amountToExchange, selectedCurrency's decimals); + + if (selectedCurrency === null || selectedTargetCurrency === null || useInputAsExactAmount === null) return; + if (selectedCurrency === 'eth' && selectedTargetCurrency !== 'eth') { + tradeDetails = useInputAsExactAmount + ? await tradeExactEthForTokens(selectedTargetCurrency, amountToExchange, chainId) + : await tradeEthForExactTokens(selectedTargetCurrency, targetAmountToExchange, chainId); + } else if (selectedCurrency !== 'eth' && selectedTargetCurrency === 'eth') { + tradeDetails = useInputAsExactAmount + ? await tradeExactTokensForEth(selectedCurrency, amountToExchange, chainId) + : await tradeTokensForExactEth(selectedCurrency, targetAmountToExchange, chainId); + } else if (selectedCurrency !== 'eth' && selectedTargetCurrency !== 'eth') { + tradeDetails = useInputAsExactAmount + ? await tradeExactTokensForTokens(selectedCurrency, selectedTargetCurrency, amountToExchange, chainId) + : await tradeTokensForExactTokens(selectedCurrency, selectedTargetCurrency, targetAmountToExchange, chainId); + } + if (useInputAsExactAmount) { + // TODO format amounts + const updatedValue = get(tradeDetails, 'outputAmount.amount'); + setTargetAmountToExchange(updatedValue); + } else { + // TODO format amounts + const updatedValue = get(tradeDetails, 'inputAmount.amount'); + setAmountToExchange(updatedValue); + } + } catch (error) { + // TODO + } + }, + }), + withHandlers({ + onPressConfirmExchange: + ({ navigation }) => () => { + Keyboard.dismiss(); + navigation.navigate('WalletScreen'); + }, + onChangeInputAmount: ({ getMarketDetails, setAmountToExchange, setUseInputAsExactAmount }) => async (amount) => { + setAmountToExchange(amount); + setUseInputAsExactAmount(true); + await getMarketDetails(); + }, + onChangeTargetAmount: ({ getMarketDetails, setTargetAmountToExchange, setUseInputAsExactAmount }) => async (amount) => { + setTargetAmountToExchange(amount); + setUseInputAsExactAmount(false); + await getMarketDetails(); + }, + onPressSelectCurrency: ({ navigation, setSelectedCurrency }) => () => { + Keyboard.dismiss(); + navigation.navigate('CurrencySelectScreen', { setSelectedCurrency }); + }, + onPressSelectTargetCurrency: + ({ navigation, setSelectedTargetCurrency }) => () => { + Keyboard.dismiss(); + navigation.navigate('CurrencySelectScreen', { setSelectedCurrency: setSelectedTargetCurrency }); + }, + }), withBlockedHorizontalSwipe, withNavigationFocus, withMockedPrices, From d01d73e4aeff9259ea8d0089c518c0c8aed92175 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 1 Aug 2019 19:21:26 -0700 Subject: [PATCH 178/636] further sdk hookup --- package.json | 1 + src/screens/ExchangeModal.js | 172 ++++++++++++++++------------------- yarn.lock | 36 ++++++++ 3 files changed, 114 insertions(+), 95 deletions(-) diff --git a/package.json b/package.json index f0c64b81ba0..b4c9fe5702c 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@segment/analytics-react-native": "^1.0.1", "@staltz/react-native-tcp": "^3.3.1", "@tradle/react-native-http": "^2.0.1", + "@uniswap/sdk": "^1.0.0-beta.3", "@walletconnect/react-native": "^1.0.0-beta.29", "assert": "^1.4.1", "asyncstorage-down": "^4.2.0", diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index f04b0d471ed..0110c5ff451 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,17 +1,19 @@ +import { + tradeEthForExactTokens, + tradeExactEthForTokens, + tradeExactTokensForEth, + tradeExactTokensForTokens, + tradeTokensForExactEth, + tradeTokensForExactTokens, +} from '@uniswap/sdk'; import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; -import { - Dimensions, - InteractionManager, - Keyboard, - KeyboardAvoidingView, - TextInput, - View, -} from 'react-native'; -import { compose, toClass, withProps } from 'recompact'; +import { TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; +import { compose, toClass, withProps } from 'recompact'; +import { convertAmountToRawAmount } from '../helpers/utilities'; import { withAccountData, withAccountSettings, @@ -63,17 +65,16 @@ const ExchangeModalHeader = withNeverRerender(() => ( class ExchangeModal extends PureComponent { static propTypes = { + chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, - inputAmount: PropTypes.number, keyboardFocusHistory: PropTypes.array, navigation: PropTypes.object, - outputAmount: PropTypes.number, pushKeyboardFocusHistory: PropTypes.func, - showConfirmButton: PropTypes.bool, } state = { inputAmount: null, + inputAsExactAmount: false, inputCurrency: 'ETH', nativeAmount: null, outputAmount: null, @@ -121,11 +122,71 @@ class ExchangeModal extends PureComponent { outputFieldRef = null - setInputAmount = inputAmount => this.setState({ inputAmount }) + getMarketDetails = async () => { + try { + let tradeDetails = null; + const { chainId } = this.props; + const { + inputAmount, + inputAsExactAmount, + inputCurrency, + outputAmount, + outputCurrency, + } = this.state; + if (inputCurrency === null || outputCurrency === null) return; + const { + address: inputCurrencyAddress, + decimals: inputDecimals, + } = inputCurrency; + const { + address: outputCurrencyAddress, + decimals: outputDecimals, + } = outputCurrency; + const rawInputAmount = convertAmountToRawAmount(inputAmount, inputDecimals); + const rawOutputAmount = convertAmountToRawAmount(outputAmount, outputDecimals); + + if (inputCurrencyAddress === 'eth' && outputCurrencyAddress !== 'eth') { + tradeDetails = inputAsExactAmount + ? await tradeExactEthForTokens(outputCurrencyAddress, rawInputAmount, chainId) + : await tradeEthForExactTokens(outputCurrencyAddress, rawOutputAmount, chainId); + } else if (inputCurrencyAddress !== 'eth' && outputCurrencyAddress === 'eth') { + tradeDetails = inputAsExactAmount + ? await tradeExactTokensForEth(inputCurrencyAddress, rawInputAmount, chainId) + : await tradeTokensForExactEth(inputCurrencyAddress, rawOutputAmount, chainId); + } else if (inputCurrencyAddress !== 'eth' && outputCurrencyAddress !== 'eth') { + tradeDetails = inputAsExactAmount + ? await tradeExactTokensForTokens(inputCurrencyAddress, outputCurrencyAddress, rawInputAmount, chainId) + : await tradeTokensForExactTokens(inputCurrencyAddress, outputCurrencyAddress, rawOutputAmount, chainId); + } if (inputAsExactAmount) { + const updatedValue = get(tradeDetails, 'outputAmount.amount'); + const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, outputDecimals); + this.setState({ outputAmount: rawUpdatedValue }); + } else { + const updatedValue = get(tradeDetails, 'inputAmount.amount'); + const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, inputDecimals); + this.setState({ inputAmount: rawUpdatedValue }); + } + } catch (error) { + console.log('error getting market details', error); + // TODO + } + } + + setInputAsExactAmount = (inputAsExactAmount) => this.setState({ inputAsExactAmount }) setNativeAmount = nativeAmount => this.setState({ nativeAmount }) - setOutputAmount = outputAmount => this.setState({ outputAmount }) + setInputAmount = async inputAmount => { + this.setState({ inputAmount }); + setInputAsExactAmount(true); + await getMarketDetails(); + } + + setOutputAmount = async outputAmount => { + this.setState({ outputAmount }); + setInputAsExactAmount(false); + await getMarketDetails(); + } setInputCurrency = inputCurrency => this.setState({ inputCurrency }) @@ -148,7 +209,6 @@ class ExchangeModal extends PureComponent { } handleWillFocus = ({ lastState }) => { - if (!lastState && this.inputFieldRef) { return this.inputFieldRef.focus(); } @@ -238,12 +298,12 @@ class ExchangeModal extends PureComponent { {showConfirmButton && ( - + - + {!!Number(inputAmount) && ( ({ selectedCurrency: selectedCurrency || symbol })), - withHandlers({ - getMarketDetails: ({ - chainId, - selectedCurrency, - selectedTargetCurrency, - setAmountToExchange, - setTargetAmountToExchange, - useInputAsExactAmount, - }) => async () => { - try { - // TODO format amounts - let tradeDetails = null; - // normal amount to raw amount (no pricing) - // convertAmountToRawAmount(amountToExchange, selectedCurrency's decimals); - - if (selectedCurrency === null || selectedTargetCurrency === null || useInputAsExactAmount === null) return; - if (selectedCurrency === 'eth' && selectedTargetCurrency !== 'eth') { - tradeDetails = useInputAsExactAmount - ? await tradeExactEthForTokens(selectedTargetCurrency, amountToExchange, chainId) - : await tradeEthForExactTokens(selectedTargetCurrency, targetAmountToExchange, chainId); - } else if (selectedCurrency !== 'eth' && selectedTargetCurrency === 'eth') { - tradeDetails = useInputAsExactAmount - ? await tradeExactTokensForEth(selectedCurrency, amountToExchange, chainId) - : await tradeTokensForExactEth(selectedCurrency, targetAmountToExchange, chainId); - } else if (selectedCurrency !== 'eth' && selectedTargetCurrency !== 'eth') { - tradeDetails = useInputAsExactAmount - ? await tradeExactTokensForTokens(selectedCurrency, selectedTargetCurrency, amountToExchange, chainId) - : await tradeTokensForExactTokens(selectedCurrency, selectedTargetCurrency, targetAmountToExchange, chainId); - } - if (useInputAsExactAmount) { - // TODO format amounts - const updatedValue = get(tradeDetails, 'outputAmount.amount'); - setTargetAmountToExchange(updatedValue); - } else { - // TODO format amounts - const updatedValue = get(tradeDetails, 'inputAmount.amount'); - setAmountToExchange(updatedValue); - } - } catch (error) { - // TODO - } - }, - }), - withHandlers({ - onPressConfirmExchange: - ({ navigation }) => () => { - Keyboard.dismiss(); - navigation.navigate('WalletScreen'); - }, - onChangeInputAmount: ({ getMarketDetails, setAmountToExchange, setUseInputAsExactAmount }) => async (amount) => { - setAmountToExchange(amount); - setUseInputAsExactAmount(true); - await getMarketDetails(); - }, - onChangeTargetAmount: ({ getMarketDetails, setTargetAmountToExchange, setUseInputAsExactAmount }) => async (amount) => { - setTargetAmountToExchange(amount); - setUseInputAsExactAmount(false); - await getMarketDetails(); - }, - onPressSelectCurrency: ({ navigation, setSelectedCurrency }) => () => { - Keyboard.dismiss(); - navigation.navigate('CurrencySelectScreen', { setSelectedCurrency }); - }, - onPressSelectTargetCurrency: - ({ navigation, setSelectedTargetCurrency }) => () => { - Keyboard.dismiss(); - navigation.navigate('CurrencySelectScreen', { setSelectedCurrency: setSelectedTargetCurrency }); - }, - }), withBlockedHorizontalSwipe, withNavigationFocus, withMockedPrices, diff --git a/yarn.lock b/yarn.lock index 6f0eec309f1..c5a4c580dc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2385,6 +2385,7 @@ lodash.unescape "4.0.1" semver "5.5.0" +<<<<<<< HEAD <<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.35": version "1.0.0-beta.35" @@ -2413,10 +2414,33 @@ resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== ======= +======= +======= +<<<<<<< HEAD +"@walletconnect/core@^1.0.0-beta.31": + version "1.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.31.tgz#ce9257c13a0da7a52a61829b66c45a9686cedca9" + integrity sha512-EggZFGdQ0EMjWZrtqAn6PJslLDlc5suyPBWfp4PP0247tYorcXXz/7OSiek0XWBVQ7dakCqeJAOteuc/FaQ+hw== +======= +"@uniswap/sdk@^1.0.0-beta.3": + version "1.0.0-beta.3" + resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-1.0.0-beta.3.tgz#a8229136cb5b1bb4900b6540e0ab1fc6c17c0a82" + integrity sha512-JfA/xGwTQt3c3p8Aznc7LFHYZkzYCXuPsv2dwPSV8U4PiN103CQ2euK9xh4x8aN2F2MXb7MeoYXTfXU0fbtkCg== + dependencies: + bignumber.js "^9.0.0" + ethers "^4.0.28" + lodash.clonedeepwith "^4.5.0" + +>>>>>>> a1921ad8... further sdk hookup +>>>>>>> 9a1e3741... further sdk hookup "@walletconnect/core@^1.0.0-beta.32": version "1.0.0-beta.32" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== +<<<<<<< HEAD +======= +>>>>>>> c851add0... further sdk hookup +>>>>>>> a1921ad8... further sdk hookup dependencies: "@walletconnect/types" "^1.0.0-beta.32" "@walletconnect/utils" "^1.0.0-beta.32" @@ -5405,6 +5429,7 @@ eth-contract-metadata@^1.9.2: resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== +<<<<<<< HEAD <<<<<<< HEAD ethers@^4.0.33: version "4.0.37" @@ -5416,6 +5441,12 @@ ethers@^4.0.27: resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.32.tgz#46378864cb3bf29b57c2effd17508b560743abf6" integrity sha512-r0k2tBNF6MYEsvwmINeP3VPppD/7eAZyiOk/ifDDawXGCKqr3iEQkPq6OZSDVD+4Jie38WPteS9thXzpn2+A5Q== >>>>>>> 751dba29... Replace navigation animations with new effects +======= +ethers@^4.0.28, ethers@^4.0.33: + version "4.0.33" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" + integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== +>>>>>>> 9a1e3741... further sdk hookup dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -7922,6 +7953,11 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash.clonedeepwith@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" + integrity sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ= + lodash.debounce@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" From 400d0aff8237f93c7d20470f0a0c54b65bf381cf Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 4 Aug 2019 15:07:29 -0700 Subject: [PATCH 179/636] further hookup of uniswap sdk --- src/helpers/utilities.js | 1 - src/redux/send.js | 1 - src/screens/CurrencySelectModal.js | 35 +++++++++++-------- src/screens/ExchangeModal.js | 54 ++++++++++++++++++++++++++---- 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 8f1e6846368..aa635c97331 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -156,7 +156,6 @@ export const divide = (numberOne, numberTwo) => BigNumber(`${numberOne}`) */ export const convertAmountFromNativeValue = ( value, - asset, priceUnit, ) => BigNumber(value) .dividedBy(BigNumber(priceUnit)) diff --git a/src/redux/send.js b/src/redux/send.js index b6a5e74755b..788e7ffa315 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -270,7 +270,6 @@ export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { const priceUnit = get(selected, 'price.value', 0); const assetAmount = convertAmountFromNativeValue( _nativeAmount, - selected, priceUnit, ); _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 1cf3431c55f..ac1067f8322 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,4 +1,4 @@ -import { get } from 'lodash'; +import { get, intersectionWith } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { compose, withHandlers } from 'recompact'; @@ -46,6 +46,8 @@ class CurrencySelectModal extends PureComponent { callback = null + isInputAssets = true + searchInputRef = React.createRef() componentDidMount() { @@ -65,6 +67,9 @@ class CurrencySelectModal extends PureComponent { this.searchInputRef.current.focus(); } + this.callback = navigation.getParam('onSelectCurrency'); + this.isInputAssets = navigation.getParam('isInputAssets'); + this.getDataFromParams(); } @@ -102,6 +107,19 @@ class CurrencySelectModal extends PureComponent { this.props.pushKeyboardFocusHistory(currentTarget); } + const getAssets = () => { + const data = this.isInputAssets + ? intersectionWith(this.props.allAssets, this.props.uniswapAssets, (uniswapAsset, asset) => uniswapAsset.address.toLowerCase() === asset.address.toLowerCase()) + : this.props.uniswapAssets; + return [ + { + balances: true, + data, + renderItem: this.renderCurrencyItem, + }, + ]; + }; + render() { const { allAssets, @@ -109,17 +127,6 @@ class CurrencySelectModal extends PureComponent { transitionProps: { isTransitioning }, } = this.props; - const fakeDataThatNeedsToBeHookedUp = [ - { - balances: true, - data: [...allAssets, ...allAssets.map(({ uniqueId, ...asset }) => ({ - ...asset, - uniqueId: `${uniqueId}_currency`, - }))], - renderItem: this.renderCurrencyItem, - }, - ]; - return ( - + ); } diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 0110c5ff451..5d66ec03e5d 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -13,7 +13,11 @@ import { TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, toClass, withProps } from 'recompact'; -import { convertAmountToRawAmount } from '../helpers/utilities'; +import { + convertAmountFromNativeValue, + convertAmountToNativeAmount, + convertAmountToRawAmount, +} from '../helpers/utilities'; import { withAccountData, withAccountSettings, @@ -65,6 +69,7 @@ const ExchangeModalHeader = withNeverRerender(() => ( class ExchangeModal extends PureComponent { static propTypes = { + allAssets: PropTypes.array, chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, keyboardFocusHistory: PropTypes.array, @@ -80,6 +85,7 @@ class ExchangeModal extends PureComponent { outputAmount: null, outputCurrency: null, showConfirmButton: false, + slippage: null, } componentDidMount = () => { @@ -158,13 +164,16 @@ class ExchangeModal extends PureComponent { ? await tradeExactTokensForTokens(inputCurrencyAddress, outputCurrencyAddress, rawInputAmount, chainId) : await tradeTokensForExactTokens(inputCurrencyAddress, outputCurrencyAddress, rawOutputAmount, chainId); } if (inputAsExactAmount) { + // TODO reuse const updatedValue = get(tradeDetails, 'outputAmount.amount'); + const slippage = get(tradeDetails, 'marketRateSlippage'); const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, outputDecimals); - this.setState({ outputAmount: rawUpdatedValue }); + this.setState({ outputAmount: rawUpdatedValue, slippage }); } else { const updatedValue = get(tradeDetails, 'inputAmount.amount'); + const slippage = get(tradeDetails, 'marketRateSlippage'); const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, inputDecimals); - this.setState({ inputAmount: rawUpdatedValue }); + this.setState({ inputAmount: rawUpdatedValue, slippage }); } } catch (error) { console.log('error getting market details', error); @@ -174,10 +183,18 @@ class ExchangeModal extends PureComponent { setInputAsExactAmount = (inputAsExactAmount) => this.setState({ inputAsExactAmount }) - setNativeAmount = nativeAmount => this.setState({ nativeAmount }) + setNativeAmount = nativeAmount => { + this.setState({ nativeAmount }); + const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.inputCurrency, 'native.price.amount', 0)); + this.setState({ inputAmount }); + setInputAsExactAmount(true); + await getMarketDetails(); + } setInputAmount = async inputAmount => { this.setState({ inputAmount }); + const nativeAmount = convertAmountToNativeAmount(inputAmount, get(this.inputCurrency, 'native.price.amount', 0)); + this.setState({ nativeAmount }); setInputAsExactAmount(true); await getMarketDetails(); } @@ -188,18 +205,43 @@ class ExchangeModal extends PureComponent { await getMarketDetails(); } - setInputCurrency = inputCurrency => this.setState({ inputCurrency }) + setInputCurrency = inputCurrency => { + const previousInputCurrency = this.inputCurrency; + this.setState({ inputCurrency }); + if (inputCurrency.address === this.outputCurrency.address) { + if (this.outputCurrency !== null + && previousInputCurrency !== null) { + this.setOutputCurrency(previousInputCurrency); + } else { + this.setOutputCurrency(null); + } + } + } - setOutputCurrency = outputCurrency => this.setState({ outputCurrency }) + setOutputCurrency = outputCurrency => { + // TODO check that it is valid input currency + const previousOutputCurrency = this.outputCurrency; + this.setState({ outputCurrency }) + if (outputCurrency.address === this.inputCurrency.address) { + if (this.inputCurrency !== null + && previousOutputCurrency !== null) { + this.setInputCurrency(previousOutputCurrency); + } else { + this.setInputCurrency(null); + } + } + } handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { + isInputAssets: true, onSelectCurrency: this.setInputCurrency, }); } handleSelectOutputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { + isInputAssets: false, onSelectCurrency: this.setOutputCurrency, }); } From c3fd0c3da3a3d2c14f1b80c15ea8ce023d556fb4 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 4 Aug 2019 15:58:56 -0700 Subject: [PATCH 180/636] rebase cleanup --- ios/Podfile.lock | 141 +++++++++++++++++++++++++++++++++++-- yarn.lock | 180 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 314 insertions(+), 7 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5a3763d4e13..e50da0fddc3 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Analytics (3.7.0) + - Analytics (3.6.10) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React @@ -40,6 +40,7 @@ PODS: - DoubleConversion - glog - glog (0.3.5) +<<<<<<< HEAD - GoogleToolboxForMac/Defines (2.2.1) - GoogleToolboxForMac/Logger (2.2.1): - GoogleToolboxForMac/Defines (= 2.2.1) @@ -52,6 +53,13 @@ PODS: - libwebp/webp (= 1.0.3) - libwebp/demux (1.0.3): ======= +======= + - GoogleToolboxForMac/Defines (2.2.0) + - GoogleToolboxForMac/Logger (2.2.0): + - GoogleToolboxForMac/Defines (= 2.2.0) + - "GoogleToolboxForMac/NSData+zlib (2.2.0)": + - GoogleToolboxForMac/Defines (= 2.2.0) +>>>>>>> 64f1594b... rebase cleanup - libwebp (1.0.2): - libwebp/core (= 1.0.2) - libwebp/dec (= 1.0.2) @@ -72,6 +80,7 @@ PODS: - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) +<<<<<<< HEAD - Protobuf (3.9.0) <<<<<<< HEAD - React (0.60.5): @@ -122,7 +131,59 @@ PODS: ======= - React (0.59.9): - React/Core (= 0.59.9) +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + - Protobuf (3.7.0) + - React (0.60.4): + - React-Core (= 0.60.4) + - React-DevSupport (= 0.60.4) + - React-RCTActionSheet (= 0.60.4) + - React-RCTAnimation (= 0.60.4) + - React-RCTBlob (= 0.60.4) + - React-RCTImage (= 0.60.4) + - React-RCTLinking (= 0.60.4) + - React-RCTNetwork (= 0.60.4) + - React-RCTSettings (= 0.60.4) + - React-RCTText (= 0.60.4) + - React-RCTVibration (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-Core (0.60.4): + - Folly (= 2018.10.22.00) + - React-cxxreact (= 0.60.4) + - React-jsiexecutor (= 0.60.4) + - yoga (= 0.60.4.React) + - React-cxxreact (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsinspector (= 0.60.4) + - React-DevSupport (0.60.4): + - React-Core (= 0.60.4) + - React-RCTWebSocket (= 0.60.4) + - React-fishhook (0.60.4) + - React-jsi (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsi/Default (= 0.60.4) + - React-jsi/Default (0.60.4): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsiexecutor (0.60.4): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.60.4) + - React-jsi (= 0.60.4) + - React-jsinspector (0.60.4) +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -175,6 +236,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= @@ -207,6 +269,8 @@ PODS: - RNDeviceInfo (2.3.2): >>>>>>> 1d794746... Minor cleanup Header component ======= +======= +>>>>>>> 64f1594b... rebase cleanup - RNDeviceInfo (2.3.2): ======= - RNDeviceInfo (2.3.0): @@ -214,7 +278,13 @@ PODS: - RNDeviceInfo (2.3.1): >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + - RNDeviceInfo (2.3.2): +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup - React - RNIOS11DeviceCheck (0.0.3): - React @@ -230,6 +300,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -251,6 +322,8 @@ PODS: - SDWebImage/Core (5.1.0) >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= +======= +>>>>>>> 64f1594b... rebase cleanup - SDWebImage (5.1.0): - SDWebImage/Core (= 5.1.0) - SDWebImage/Core (5.1.0) @@ -259,6 +332,8 @@ PODS: - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) ======= +======= +>>>>>>> a3543960... rebase cleanup - SDWebImage (5.0.6): - SDWebImage/Core (= 5.0.6) - SDWebImage/Core (5.0.6) @@ -266,7 +341,16 @@ PODS: >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - yoga (0.59.9.React) +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + - SDWebImage (5.0.2): + - SDWebImage/Core (= 5.0.2) + - SDWebImage/Core (5.0.2) + - yoga (0.60.4.React) +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -405,18 +489,19 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 + Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa - FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 - FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 - FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 - FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb + Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 + FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d + FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 + FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 + FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 +<<<<<<< HEAD <<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 @@ -432,6 +517,8 @@ SPEC CHECKSUMS: React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 ======= +======= +>>>>>>> 64f1594b... rebase cleanup Folly: de497beb10f102453a1afa9edbf8cf8a251890de glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 @@ -439,7 +526,26 @@ SPEC CHECKSUMS: nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 + glog: 1f3da668190260b06b429bb211bfbee5cd790c28 + GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d + libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a + React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 + React-Core: 8e0ea421cae5609d2562850f98421b15030476fa + React-cxxreact: 326880209990151a7182a813311054e9772ba510 + React-DevSupport: e9f10e6721e78e87622fc985db695c0c0168db8a + React-fishhook: 1f0e5b08449403fa75c3fb3881a0beefbada14af + React-jsi: 21d3153b1153fbf6510a92b6b11e33e725cb7432 + React-jsiexecutor: 7549641e48bafae7bfee3f3ea19bf4901639c5de + React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 @@ -463,6 +569,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= @@ -495,6 +602,8 @@ SPEC CHECKSUMS: RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 >>>>>>> 1d794746... Minor cleanup Header component ======= +======= +>>>>>>> 64f1594b... rebase cleanup RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= RNDeviceInfo: 65106cc87ad6f6f71ef2ecc667f4c59b840888e2 @@ -502,7 +611,13 @@ SPEC CHECKSUMS: RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 @@ -512,6 +627,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -525,16 +641,27 @@ SPEC CHECKSUMS: SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= +======= +>>>>>>> 64f1594b... rebase cleanup SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ======= SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 ======= +======= +>>>>>>> a3543960... rebase cleanup SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee +<<<<<<< HEAD >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 + yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/yarn.lock b/yarn.lock index c5a4c580dc7..67ff7ee8432 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1309,6 +1309,7 @@ integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== ======= "@ethersproject/logger@>5.0.0-beta.0": +<<<<<<< HEAD version "5.0.0-beta.128" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== @@ -1323,6 +1324,16 @@ resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.128.tgz#26e8a4cb95f0d048531f0a8da39773b16b4633b4" integrity sha512-4ABgX2WmpQLlmbyR6EwxoT5YTRYxV6fGRtK+1nt48dvG2Y8FSkg33JvCfei3w432RjEEHEN5IOmTf+nTr9n6VA== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +======= + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" + integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== + +"@ethersproject/properties@>5.0.0-beta.0": + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" + integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== +>>>>>>> a3543960... rebase cleanup dependencies: "@ethersproject/logger" ">5.0.0-beta.0" @@ -1336,6 +1347,7 @@ "@ethersproject/strings@^5.0.0-beta.125": <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "5.0.0-beta.131" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" @@ -1347,6 +1359,8 @@ ======= ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 64f1594b... rebase cleanup version "5.0.0-beta.129" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== @@ -1355,6 +1369,11 @@ resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.127.tgz#e07848b92cb1b615a11d7289449312c069a234e9" integrity sha512-FKQDBKgcX7Bc0J45TIwwT4PTnE1TvtDRka3dAkH1VX4odnj6DzpZ99QdkhX4mBL2J+6/XK+trA7m/HTDx+5YqA== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +======= + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" + integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== +>>>>>>> a3543960... rebase cleanup dependencies: "@ethersproject/bytes" ">5.0.0-beta.0" "@ethersproject/constants" ">5.0.0-beta.0" @@ -1626,8 +1645,20 @@ version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== +<<<<<<< HEAD >>>>>>> 034f7aa3... Create Exchange related Input components +<<<<<<< HEAD >>>>>>> 2216260a... Create Exchange related Input components +======= +======= +======= +"@react-native-community/cli-platform-android@^2.0.1", "@react-native-community/cli-platform-android@^2.7.0", "@react-native-community/cli-platform-android@^2.8.3": + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" + integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1745,21 +1776,36 @@ version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== +<<<<<<< HEAD >>>>>>> 034f7aa3... Create Exchange related Input components +======= +======= +"@react-native-community/cli-platform-ios@^2.0.1", "@react-native-community/cli-platform-ios@^2.8.0", "@react-native-community/cli-platform-ios@^2.8.3": + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" + integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> a3543960... rebase cleanup dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" xcode "^2.0.0" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a3543960... rebase cleanup "@react-native-community/cli-tools@^2.7.0", "@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= ======= +>>>>>>> 64f1594b... rebase cleanup +======= "@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" @@ -1785,7 +1831,12 @@ ======= ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -1843,18 +1894,33 @@ shell-quote "1.6.1" ws "^1.1.0" +<<<<<<< HEAD <<<<<<< HEAD "@react-native-community/eslint-config@^0.0.5": version "0.0.5" resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795" integrity sha512-jwO2tnKaTPTLX5XYXMHGEnFdf543SU7jz98/OF5mDH3b7lP+BOaCD+jVfqqHoDRkcqyPlYiR1CgwVGWpi0vMWg== ======= +======= +>>>>>>> 64f1594b... rebase cleanup "@react-native-community/cli@^1.2.1": version "1.9.11" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.9.11.tgz#b868b17201057b9cd16a3a20c30561176071f21a" integrity sha512-VVu/tmTTzODfW2xlqIz0pZgeELG2ppPAIgbBEKLgHCO9DMxNZIKSqmei/JqkAi0gEipqQoP6YPAemHPd43lyrA== dependencies: chalk "^1.1.1" +======= +"@react-native-community/cli@^2.0.1": + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.3.tgz#b59c4e44946a1ce6c464ae246328cf3a2ab47bd2" + integrity sha512-khlS6slD6fsIv8R6L0bbQvK2PQ/UJytmh8/XEZ835bDwgbn6U90Yqrf299r6JxKk2/tyckRu6QimQNAkEQxEHg== + dependencies: + "@hapi/joi" "^15.0.3" + "@react-native-community/cli-platform-android" "^2.8.3" + "@react-native-community/cli-platform-ios" "^2.8.3" + "@react-native-community/cli-tools" "^2.8.3" + chalk "^2.4.2" +>>>>>>> 3291cb84... rebase cleanup commander "^2.19.0" compression "^1.7.1" connect "^3.6.5" @@ -2210,6 +2276,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -2247,6 +2314,8 @@ >>>>>>> 2216260a... Create Exchange related Input components ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> 64f1594b... rebase cleanup version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== @@ -2263,7 +2332,20 @@ version "10.14.15" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g== +<<<<<<< HEAD >>>>>>> 1d794746... Minor cleanup Header component +======= +======= + version "12.6.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" + integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== + +"@types/node@^10.3.2": + version "10.14.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" + integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup "@types/node@^8.0.7": <<<<<<< HEAD @@ -2385,6 +2467,7 @@ lodash.unescape "4.0.1" semver "5.5.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.35": @@ -2416,12 +2499,16 @@ ======= ======= ======= +>>>>>>> 64f1594b... rebase cleanup +======= <<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.31": version "1.0.0-beta.31" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.31.tgz#ce9257c13a0da7a52a61829b66c45a9686cedca9" integrity sha512-EggZFGdQ0EMjWZrtqAn6PJslLDlc5suyPBWfp4PP0247tYorcXXz/7OSiek0XWBVQ7dakCqeJAOteuc/FaQ+hw== ======= +======= +>>>>>>> a3543960... rebase cleanup "@uniswap/sdk@^1.0.0-beta.3": version "1.0.0-beta.3" resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-1.0.0-beta.3.tgz#a8229136cb5b1bb4900b6540e0ab1fc6c17c0a82" @@ -2438,9 +2525,12 @@ resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> c851add0... further sdk hookup >>>>>>> a1921ad8... further sdk hookup +======= +>>>>>>> a3543960... rebase cleanup dependencies: "@walletconnect/types" "^1.0.0-beta.32" "@walletconnect/utils" "^1.0.0-beta.32" @@ -3690,6 +3780,7 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" @@ -3713,7 +3804,15 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "1.0.30000988" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000988.tgz#742f35ec1b8b75b9628d705d7652eea1fef983db" + integrity sha512-lPj3T8poYrRc/bniW5SQPND3GRtSrQdUM/R4mCYTbZxyi3jQiggLvZH4+BYUuX0t4TXjU+vMM7KFDQg+rSzZUQ== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup capture-exit@^1.2.0: version "1.2.0" @@ -4021,11 +4120,18 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +<<<<<<< HEAD <<<<<<< HEAD commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: ======= commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: >>>>>>> 96db5a28... begin mike +======= +commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: +======= +commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -4895,6 +5001,7 @@ electron-to-chromium@^1.3.188: >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch electron-to-chromium@^1.3.191: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.3.200" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" @@ -4929,7 +5036,15 @@ electron-to-chromium@^1.3.188: integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "1.3.214" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.214.tgz#8b5b9a0415fd41b69c61f694007597cb8c8eb7e8" + integrity sha512-SU9yyql6uA0Fc8bWR7sCYNGBtxkC+tQb6UaC7ReaadN42Kx7Ka+dzx3lAIm9Ock+ULEawJuTFcVB2x34uOCg0Q== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup elliptic@6.3.3: version "6.3.3" @@ -5022,6 +5137,7 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +<<<<<<< HEAD entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" @@ -5029,11 +5145,23 @@ entities@^2.0.0: <<<<<<< HEAD ======= +======= +<<<<<<< HEAD +>>>>>>> a3543960... rebase cleanup envinfo@^5.7.0: version "5.12.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +======= +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== +>>>>>>> 3291cb84... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup envinfo@^7.1.0: version "7.3.1" @@ -6541,6 +6669,7 @@ i18next@^17.0.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -6561,6 +6690,8 @@ i18next@^17.0.3: integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== >>>>>>> 1d794746... Minor cleanup Header component ======= +======= +>>>>>>> 64f1594b... rebase cleanup version "17.0.10" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== @@ -6569,7 +6700,15 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.7.tgz#aae8591634b109c0ecec755b46c6414b0d743e07" integrity sha512-fQn+gcyDaHb3qXIeahjCnGMsCeHaKveSORclang55stBjOL13oK7ZYxXVz1AaFV6p3SzOSu/KW+tgZcUuDdf6Q== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "17.0.8" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.8.tgz#0c7113a88ad156eb37b9025d83a7684e1bbc2e18" + integrity sha512-oojOrqEPQzKo1HDMDDOl19zTM/EaDwBRPobUSD4kEjNoTi2oERvUbngK2lkIm9nOGddh55jbMGbm6fusMBeoKQ== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup dependencies: "@babel/runtime" "^7.3.1" @@ -10289,6 +10428,7 @@ react-native-device-info@^2.1.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" @@ -10336,6 +10476,8 @@ react-native-device-info@^2.1.3: integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== >>>>>>> 1d794746... Minor cleanup Header component ======= +======= +>>>>>>> 64f1594b... rebase cleanup version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== @@ -10350,7 +10492,15 @@ react-native-device-info@^2.1.3: integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +<<<<<<< HEAD >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup react-native-dotenv@^0.2.0: version "0.2.0" @@ -10613,10 +10763,19 @@ react-native-svg@^9.5.1: integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== ======= react-native-svg@^9.5.3: +<<<<<<< HEAD version "9.6.2" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +======= + version "9.5.3" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.5.3.tgz#2389f3ffd700c6441166496a1aeade31ead89c59" + integrity sha512-VUOe4TLz7RFdmm/XT9EH87VSwlRykx49qbwJMA+dh9eFM7KPY1qH3kEyN7uRCqJD2eE8toxt9NpjR6ByvtPNlA== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -10649,6 +10808,7 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" +<<<<<<< HEAD <<<<<<< HEAD react-native-text-input-mask@^1.0.6: version "1.0.6" @@ -10666,6 +10826,12 @@ react-native-text-input-mask@^1.0.1: resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +======= +react-native-text-input-mask@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" + integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== +>>>>>>> a3543960... rebase cleanup react-native-tooltip@^5.2.0: version "5.2.0" @@ -11530,6 +11696,7 @@ sax@^1.2.1, sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +<<<<<<< HEAD <<<<<<< HEAD schedule@0.4.0: version "0.4.0" @@ -11541,6 +11708,8 @@ sax@~1.1.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= +======= +>>>>>>> 64f1594b... rebase cleanup schedule@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" @@ -12745,6 +12914,7 @@ tslib@^1.8.1, tslib@^1.9.0: tsutils@^3.7.0: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -12759,6 +12929,16 @@ tsutils@^3.7.0: resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== >>>>>>> 1d794746... Minor cleanup Header component +======= + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== +======= + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.15.0.tgz#3efabbf2c18a5d7c7496a878be0609eb90897ed6" + integrity sha512-or184xKZ6fLE1SrDcvsOs3Wkfb1JgizdKs5Fiag3cp/m9k7C7GWd4E7gs3K5LHAePaIP7K62C20ZZI3JQx8iBQ== +>>>>>>> a3543960... rebase cleanup +>>>>>>> 64f1594b... rebase cleanup dependencies: tslib "^1.8.1" From 91850627bad63a9b0ea9cff52ac3e1489f270476 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 4 Aug 2019 17:03:49 -0700 Subject: [PATCH 181/636] podfile lock for text input mask --- ios/Podfile.lock | 33 +++++++++++++++++++ package.json | 2 +- yarn.lock | 83 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 103 insertions(+), 15 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e50da0fddc3..37adbc72606 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -80,6 +80,7 @@ PODS: - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) +<<<<<<< HEAD <<<<<<< HEAD - Protobuf (3.9.0) <<<<<<< HEAD @@ -184,6 +185,11 @@ PODS: - React-jsinspector (0.60.4) >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup +======= + - Protobuf (3.7.0) + - React (0.59.9): + - React/Core (= 0.59.9) +>>>>>>> a7347f4b... podfile lock for text input mask - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -301,6 +307,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -324,6 +331,8 @@ PODS: ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> a7347f4b... podfile lock for text input mask - SDWebImage (5.1.0): - SDWebImage/Core (= 5.1.0) - SDWebImage/Core (5.1.0) @@ -345,12 +354,18 @@ PODS: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= ======= +======= +>>>>>>> bdd78363... podfile lock for text input mask - SDWebImage (5.0.2): - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) +<<<<<<< HEAD - yoga (0.60.4.React) >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup +======= + - yoga (0.59.9.React) +>>>>>>> a7347f4b... podfile lock for text input mask DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -502,6 +517,7 @@ SPEC CHECKSUMS: FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 @@ -532,10 +548,15 @@ SPEC CHECKSUMS: ======= Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 +======= + Folly: de497beb10f102453a1afa9edbf8cf8a251890de + glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d +>>>>>>> a7347f4b... podfile lock for text input mask GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a +<<<<<<< HEAD React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 React-Core: 8e0ea421cae5609d2562850f98421b15030476fa React-cxxreact: 326880209990151a7182a813311054e9772ba510 @@ -546,6 +567,9 @@ SPEC CHECKSUMS: React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup +======= + React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f +>>>>>>> a7347f4b... podfile lock for text input mask react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 @@ -628,6 +652,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -643,6 +668,8 @@ SPEC CHECKSUMS: ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> a7347f4b... podfile lock for text input mask SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ======= SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 @@ -658,10 +685,16 @@ SPEC CHECKSUMS: >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= ======= +======= +>>>>>>> bdd78363... podfile lock for text input mask SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 +<<<<<<< HEAD yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup +======= + yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee +>>>>>>> a7347f4b... podfile lock for text input mask PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/package.json b/package.json index b4c9fe5702c..2614a4f1ff9 100644 --- a/package.json +++ b/package.json @@ -242,4 +242,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 67ff7ee8432..3cd2b17b5c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1617,6 +1617,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" @@ -1634,6 +1635,10 @@ integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== >>>>>>> f7a61a13... Create Exchange related Input components ======= +======= +"@react-native-community/cli-platform-android@^2.7.0": +<<<<<<< HEAD +>>>>>>> a7347f4b... podfile lock for text input mask version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== @@ -1658,7 +1663,15 @@ integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== >>>>>>> 3291cb84... rebase cleanup >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" + integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== +>>>>>>> bdd78363... podfile lock for text input mask +>>>>>>> a7347f4b... podfile lock for text input mask dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1722,8 +1735,8 @@ slash "^3.0.0" xmldoc "^1.1.2" -<<<<<<< HEAD "@react-native-community/cli-platform-ios@^2.8.0": +<<<<<<< HEAD <<<<<<< HEAD version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" @@ -1768,6 +1781,8 @@ ======= >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch ======= +======= +>>>>>>> a7347f4b... podfile lock for text input mask version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== @@ -1786,6 +1801,11 @@ integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== >>>>>>> 3291cb84... rebase cleanup >>>>>>> a3543960... rebase cleanup +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" + integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== +>>>>>>> bdd78363... podfile lock for text input mask dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1894,6 +1914,7 @@ shell-quote "1.6.1" ws "^1.1.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@react-native-community/eslint-config@^0.0.5": @@ -1903,24 +1924,14 @@ ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> a7347f4b... podfile lock for text input mask "@react-native-community/cli@^1.2.1": version "1.9.11" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.9.11.tgz#b868b17201057b9cd16a3a20c30561176071f21a" integrity sha512-VVu/tmTTzODfW2xlqIz0pZgeELG2ppPAIgbBEKLgHCO9DMxNZIKSqmei/JqkAi0gEipqQoP6YPAemHPd43lyrA== dependencies: chalk "^1.1.1" -======= -"@react-native-community/cli@^2.0.1": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.3.tgz#b59c4e44946a1ce6c464ae246328cf3a2ab47bd2" - integrity sha512-khlS6slD6fsIv8R6L0bbQvK2PQ/UJytmh8/XEZ835bDwgbn6U90Yqrf299r6JxKk2/tyckRu6QimQNAkEQxEHg== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.8.3" - "@react-native-community/cli-platform-ios" "^2.8.3" - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" ->>>>>>> 3291cb84... rebase cleanup commander "^2.19.0" compression "^1.7.1" connect "^3.6.5" @@ -3844,7 +3855,7 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== -chalk@1.1.3, chalk@^1.0.0: +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -4120,6 +4131,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: @@ -4132,6 +4144,9 @@ commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup +======= +commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: +>>>>>>> a7347f4b... podfile lock for text input mask version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -5137,6 +5152,7 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +<<<<<<< HEAD <<<<<<< HEAD entities@^2.0.0: version "2.0.0" @@ -5156,12 +5172,22 @@ envinfo@^5.7.0: >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= ======= +======= +>>>>>>> bdd78363... podfile lock for text input mask entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== +<<<<<<< HEAD >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup +======= + +envinfo@^5.7.0: + version "5.12.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" + integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== +>>>>>>> a7347f4b... podfile lock for text input mask envinfo@^7.1.0: version "7.3.1" @@ -10763,6 +10789,7 @@ react-native-svg@^9.5.1: integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== ======= react-native-svg@^9.5.3: +<<<<<<< HEAD <<<<<<< HEAD version "9.6.2" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" @@ -10775,7 +10802,15 @@ react-native-svg@^9.5.3: resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.5.3.tgz#2389f3ffd700c6441166496a1aeade31ead89c59" integrity sha512-VUOe4TLz7RFdmm/XT9EH87VSwlRykx49qbwJMA+dh9eFM7KPY1qH3kEyN7uRCqJD2eE8toxt9NpjR6ByvtPNlA== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "9.6.1" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.1.tgz#4d2ba1e7ecd78d06603e8bf2fbc5072fc5852506" + integrity sha512-X8WvZ5uNHyE+17Q4SSbdQZ1NsRyRxdvAFqipqDldL6D0oUB0pBI2tekx03N4taVtVN+p8Pg3T3SSmIxwXZmMYA== +>>>>>>> bdd78363... podfile lock for text input mask +>>>>>>> a7347f4b... podfile lock for text input mask react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -10808,6 +10843,7 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD react-native-text-input-mask@^1.0.6: @@ -10832,6 +10868,12 @@ react-native-text-input-mask@^1.0.4: resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== >>>>>>> a3543960... rebase cleanup +======= +react-native-text-input-mask@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" + integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== +>>>>>>> bdd78363... podfile lock for text input mask react-native-tooltip@^5.2.0: version "5.2.0" @@ -11696,6 +11738,7 @@ sax@^1.2.1, sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD schedule@0.4.0: @@ -11703,13 +11746,18 @@ schedule@0.4.0: resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.4.0.tgz#fa20cfd0bfbf91c47d02272fd7096780d3170bbb" integrity sha512-hYjmoaEMojiMkWCxKr6ue+LYcZ29u29+AamWYmzwT2VOO9ws5UJp/wNhsVUPiUeNh+EdRfZm7nDeB40ffTfMhA== ======= +======= +>>>>>>> a7347f4b... podfile lock for text input mask sax@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= +<<<<<<< HEAD ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> a7347f4b... podfile lock for text input mask schedule@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" @@ -13552,6 +13600,13 @@ xmlbuilder@^9.0.7: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= +xmldoc@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" + integrity sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg= + dependencies: + sax "~1.1.1" + xmldoc@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" From 92e687ab9d2d9a53efa782fac3599118d34d2d0a Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 4 Aug 2019 18:12:39 -0700 Subject: [PATCH 182/636] typo fixes --- src/screens/CurrencySelectModal.js | 2 +- src/screens/ExchangeModal.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index ac1067f8322..352c11636ad 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -107,7 +107,7 @@ class CurrencySelectModal extends PureComponent { this.props.pushKeyboardFocusHistory(currentTarget); } - const getAssets = () => { + getAssets = () => { const data = this.isInputAssets ? intersectionWith(this.props.allAssets, this.props.uniswapAssets, (uniswapAsset, asset) => uniswapAsset.address.toLowerCase() === asset.address.toLowerCase()) : this.props.uniswapAssets; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 5d66ec03e5d..49af672b27e 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -183,7 +183,7 @@ class ExchangeModal extends PureComponent { setInputAsExactAmount = (inputAsExactAmount) => this.setState({ inputAsExactAmount }) - setNativeAmount = nativeAmount => { + setNativeAmount = async nativeAmount => { this.setState({ nativeAmount }); const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.inputCurrency, 'native.price.amount', 0)); this.setState({ inputAmount }); From 17167efe8cd1a3ec86c630861cb479ee288b1c7b Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 5 Aug 2019 18:28:32 -0700 Subject: [PATCH 183/636] add slippage in UI --- src/screens/ExchangeModal.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 49af672b27e..2f9abb66c0f 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -337,6 +337,11 @@ class ExchangeModal extends PureComponent { /> + + + Slippage {this.state.slippage} + + {showConfirmButton && ( From 810e2f64dc3a7424952e07fdceaf3f81cdfd84be Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 5 Aug 2019 18:28:55 -0700 Subject: [PATCH 184/636] add uniswap pairs reference --- src/references/uniswap-pairs.json | 364 ++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 src/references/uniswap-pairs.json diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json new file mode 100644 index 00000000000..6bd9cdaa81a --- /dev/null +++ b/src/references/uniswap-pairs.json @@ -0,0 +1,364 @@ +{ + "ETH": { + "name": "Ethereum", + "symbol": "ETH", + "decimals": 18, + "exchange_address": null + }, + "0x960b236A07cf122663c4303350609A66A7B288C0": { + "name": "Aragon Network Token", + "symbol": "ANT", + "decimals": 18, + "exchange_address": "0x077d52B047735976dfdA76feF74d4d988AC25196" + }, + "0x0D8775F648430679A709E98d2b0Cb6250d2887EF": { + "name": "Basic Attention Token", + "symbol": "BAT", + "decimals": 18, + "exchange_address": "0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914" + }, + "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { + "name": "Bloom Token", + "symbol": "BLT", + "decimals": 18, + "exchange_address": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" + }, + "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { + "name": "Bancor Network Token", + "symbol": "BNT", + "decimals": 18, + "exchange_address": "0x87d80DBD37E551F58680B4217b23aF6a752DA83F" + }, + "0x26E75307Fc0C021472fEb8F727839531F112f317": { + "name": "Crypto20", + "symbol": "C20", + "decimals": 18, + "exchange_address": "0xF7B5A4b934658025390ff69dB302BC7F2AC4a542" + }, + "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { + "name": "Compound Dai", + "symbol": "cDAI", + "decimals": 8, + "exchange_address": "0x45A2FDfED7F7a2c791fb1bdF6075b83faD821ddE" + }, + "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { + "name": "Civic", + "symbol": "CVC", + "decimals": 8, + "exchange_address": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" + }, + "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { + "name": "Dai Stablecoin v1.0", + "symbol": "DAI", + "decimals": 18, + "exchange_address": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" + }, + "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A": { + "name": "DigixDAO", + "symbol": "DGD", + "decimals": 9, + "exchange_address": "0xD55C1cA9F5992A2e5E379DCe49Abf24294ABe055" + }, + "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { + "name": "Digix Gold Token", + "symbol": "DGX", + "decimals": 9, + "exchange_address": "0xb92dE8B30584392Af27726D5ce04Ef3c4e5c9924" + }, + + "0xc719d010B63E5bbF2C0551872CD5316ED26AcD83": { + "name": "Decentralized Insurance Protocol", + "symbol": "DIP", + "decimals": 18, + "exchange_address": "0x61792F290e5100FBBcBb2309F03A1Bab869fb850" + }, + + "0x4946Fcea7C692606e8908002e55A582af44AC121": { + "name": "FOAM Token", + "symbol": "FOAM", + "decimals": 18, + "exchange_address": "0xf79cb3BEA83BD502737586A6E8B133c378FD1fF2" + }, + "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b": { + "name": "FunFair", + "symbol": "FUN", + "decimals": 8, + "exchange_address": "0x60a87cC7Fca7E53867facB79DA73181B1bB4238B" + }, + "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { + "name": "DAOstack", + "symbol": "GEN", + "decimals": 18, + "exchange_address": "0x26Cc0EAb6Cb650B0Db4D0d0dA8cB5BF69F4ad692" + }, + "0x6810e776880C02933D47DB1b9fc05908e5386b96": { + "name": "Gnosis Token", + "symbol": "GNO", + "decimals": 18, + "exchange_address": "0xe8e45431b93215566BA923a7E611B7342Ea954DF" + }, + "0x12B19D3e2ccc14Da04FAe33e63652ce469b3F2FD": { + "name": "GRID Token", + "symbol": "GRID", + "decimals": 12, + "exchange_address": "0x4B17685b330307C751B47f33890c8398dF4Fe407" + }, + "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { + "name": "Kin", + "symbol": "KIN", + "decimals": 18, + "exchange_address": "0xb7520a5F8c832c573d6BD0Df955fC5c9b72400F7" + }, + "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { + "name": "Kyber Network Crystal", + "symbol": "KNC", + "decimals": 18, + "exchange_address": "0x49c4f9bc14884f6210F28342ceD592A633801a8b" + }, + "0x514910771AF9Ca656af840dff83E8264EcF986CA": { + "name": "ChainLink Token", + "symbol": "LINK", + "decimals": 18, + "exchange_address": "0xF173214C720f58E03e194085B1DB28B50aCDeeaD" + }, + "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { + "name": "LoopringCoin V2", + "symbol": "LRC", + "decimals": 18, + "exchange_address": "0xA539BAaa3aCA455c986bB1E25301CEF936CE1B65" + }, + "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { + "name": "HoloToken", + "symbol": "HOT", + "decimals": 18, + "exchange_address": "0xd4777E164c6C683E10593E08760B803D58529a8E" + }, + "0xD29F0b5b3F50b07Fe9a9511F7d86F4f4bAc3f8c4": { + "name": "Liquidity.Network Token", + "symbol": "LQD", + "decimals": 18, + "exchange_address": "0xe3406e7D0155E0a83236eC25D34Cd3D903036669" + }, + "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { + "name": "LoomToken", + "symbol": "LOOM", + "decimals": 18, + "exchange_address": "0x417CB32bc991fBbDCaE230C7c4771CC0D69daA6b" + }, + "0x58b6A8A3302369DAEc383334672404Ee733aB239": { + "name": "Livepeer Token", + "symbol": "LPT", + "decimals": 18, + "exchange_address": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" + }, + "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { + "name": "Decentraland MANA", + "symbol": "MANA", + "decimals": 18, + "exchange_address": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" + }, + "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { + "name": "Matic Token", + "symbol": "MATIC", + "decimals": 18, + "exchange_address": "0x9a7A75E66B325a3BD46973B2b57c9b8d9D26a621" + }, + "0x80f222a749a2e18Eb7f676D371F19ad7EFEEe3b7": { + "name": "Magnolia Token", + "symbol": "MGN", + "decimals": 18, + "exchange_address": "0xdd80Ca8062c7Ef90FcA2547E6a2A126C596e611F" + }, + "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { + "name": "Maker", + "symbol": "MKR", + "decimals": 18, + "exchange_address": "0x2C4Bd064b998838076fa341A83d007FC2FA50957" + }, + "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { + "name": "Melon Token", + "symbol": "MLN", + "decimals": 18, + "exchange_address": "0xA931F4eB165AC307fD7431b5EC6eADde53E14b0C" + }, + "0x957c30aB0426e0C93CD8241E2c60392d08c6aC8e": { + "name": "Modum Token", + "symbol": "MOD", + "decimals": 0, + "exchange_address": "0xCCB98654CD486216fFF273dd025246588E77cFC1" + }, + "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206": { + "name": "Nexo", + "symbol": "NEXO", + "decimals": 18, + "exchange_address": "0x069C97DBA948175D10af4b2414969e0B88d44669" + }, + "0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671": { + "name": "Numeraire", + "symbol": "NMR", + "decimals": 18, + "exchange_address": "0x2Bf5A5bA29E60682fC56B2Fcf9cE07Bef4F6196f" + }, + "0x8E870D67F660D95d5be530380D0eC0bd388289E1": { + "name": "PAX", + "symbol": "PAX", + "decimals": 18, + "exchange_address": "0xC040d51b07Aea5d94a89Bc21E8078B77366Fc6C7" + }, + "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { + "name": "Pinakion", + "symbol": "PNK", + "decimals": 18, + "exchange_address": "0xF506828B166de88cA2EDb2A98D960aBba0D2402A" + }, + "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { + "name": "POA ERC20 on Foundation", + "symbol": "POA20", + "decimals": 18, + "exchange_address": "0xA2E6B3EF205FeAEe475937c4883b24E6eB717eeF" + }, + "0x687BfC3E73f6af55F0CccA8450114D107E781a0e": { + "name": "QChi", + "symbol": "QCH", + "decimals": 18, + "exchange_address": "0x755899F0540c3548b99E68C59AdB0f15d2695188" + }, + "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6": { + "name": "Raiden Token", + "symbol": "RDN", + "decimals": 18, + "exchange_address": "0x7D03CeCb36820b4666F45E1b4cA2538724Db271C" + }, + "0x408e41876cCCDC0F92210600ef50372656052a38": { + "name": "Republic Token", + "symbol": "REN", + "decimals": 18, + "exchange_address": "0x43892992B0b102459E895B88601Bb2C76736942c" + }, + "0x1985365e9f78359a9B6AD760e32412f4a445E862": { + "name": "Reputation", + "symbol": "REP", + "decimals": 18, + "exchange_address": "0x48B04d2A05B6B604d8d5223Fd1984f191DED51af" + }, + "0x168296bb09e24A88805CB9c33356536B980D3fC5": { + "name": "RHOC", + "symbol": "RHOC", + "decimals": 8, + "exchange_address": "0x394e524b47A3AB3D3327f7fF6629dC378c1494a3" + }, + "0x607F4C5BB672230e8672085532f7e901544a7375": { + "name": "iEx.ec Network Token", + "symbol": "RLC", + "decimals": 9, + "exchange_address": "0xA825CAE02B310E9901b4776806CE25db520c8642" + }, + "0xB4EFd85c19999D84251304bDA99E90B92300Bd93": { + "name": "Rocket Pool", + "symbol": "RPL", + "decimals": 18, + "exchange_address": "0x3Fb2F18065926DdB33E7571475c509541d15dA0e" + }, + "0x4156D3342D5c385a87D264F90653733592000581": { + "name": "Salt", + "symbol": "SALT", + "decimals": 8, + "exchange_address": "0xC0C59cDe851bfcbdddD3377EC10ea54A18Efb937" + }, + "0x42456D7084eacF4083f1140d3229471bbA2949A8": { + "name": "Synth sETH", + "symbol": "sETH", + "decimals": 18, + "exchange_address": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" + }, + "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E": { + "name": "Status Network Token", + "symbol": "SNT", + "decimals": 18, + "exchange_address": "0x1aEC8F11A7E78dC22477e91Ed924Fab46e3A88Fd" + }, + "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { + "name": "Synthetix Network Token", + "symbol": "SNX", + "decimals": 18, + "exchange_address": "0x9fAA0Cb10912DE7Ad1D86705C65de291a9088A61" + }, + "0x42d6622deCe394b54999Fbd73D108123806f6a18": { + "name": "SPANK", + "symbol": "SPANK", + "decimals": 18, + "exchange_address": "0x4e395304655F0796bc3bc63709DB72173b9DdF98" + }, + "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { + "name": "StorjToken", + "symbol": "STORJ", + "decimals": 8, + "exchange_address": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" + }, + "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { + "name": "Synth sUSD", + "symbol": "sUSD", + "decimals": 18, + "exchange_address": "0xA1ECDcca26150cF69090280eE2EE32347C238c7b" + }, + "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { + "name": "Monolith TKN", + "symbol": "TKN", + "decimals": 8, + "exchange_address": "0xb6cFBf322db47D39331E306005DC7E5e6549942B" + }, + "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E": { + "name": "TrueUSD", + "symbol": "TUSD", + "decimals": 18, + "exchange_address": "0x4F30E682D0541eAC91748bd38A648d759261b8f3" + }, + "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { + "name": "Uniswap V1", + "symbol": "UNI-V1:DAI", + "decimals": 18, + "exchange_address": "0x601c32E0580D3aef9437dB52D09f5a5D7E60eC22" + }, + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": { + "name": "USD//C", + "symbol": "USDC", + "decimals": 6, + "exchange_address": "0x97deC872013f6B5fB443861090ad931542878126" + }, + "0x8f3470A7388c05eE4e7AF3d01D8C722b0FF52374": { + "name": "Veritaseum", + "symbol": "VERI", + "decimals": 18, + "exchange_address": "0x17e5BF07D696eaf0d14caA4B44ff8A1E17B34de3" + }, + "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": { + "name": "Wrapped BTC", + "symbol": "WBTC", + "decimals": 8, + "exchange_address": "0x4d2f5cFbA55AE412221182D8475bC85799A5644b" + }, + "0x09fE5f0236F0Ea5D930197DCE254d77B04128075": { + "name": "Wrapped CryptoKitties", + "symbol": "WCK", + "decimals": 18, + "exchange_address": "0x4FF7Fa493559c40aBd6D157a0bfC35Df68d8D0aC" + }, + "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": { + "name": "Wrapped Ether", + "symbol": "WETH", + "decimals": 18, + "exchange_address": "0xA2881A90Bf33F03E7a3f803765Cd2ED5c8928dFb" + }, + "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { + "name": "CryptoFranc", + "symbol": "XCHF", + "decimals": 18, + "exchange_address": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" + }, + "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { + "name": "0x Protocol Token", + "symbol": "ZRX", + "decimals": 18, + "exchange_address": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" + } +} From 9a9a37dccffb83f1fbfb7b1377aec11a38f4db96 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 5 Aug 2019 18:29:49 -0700 Subject: [PATCH 185/636] hook up currency select modal --- src/hoc/index.js | 1 + src/hoc/withUniswapAssets.js | 13 +++++++++++++ src/screens/CurrencySelectModal.js | 21 ++++++++++++++++++--- 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 src/hoc/withUniswapAssets.js diff --git a/src/hoc/index.js b/src/hoc/index.js index 8ed99e3004c..91c706e595d 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -30,6 +30,7 @@ export { default as withStatusBarStyle } from './withStatusBarStyle'; export { default as withTransactionConfirmationScreen } from './withTransactionConfirmationScreen'; export { default as withTransitionProps } from './withTransitionProps'; export { default as withUniqueTokens } from './withUniqueTokens'; +export { default as withUniswapAssets } from './withUniswapAssets'; export { default as withUniswapLiquidity, readableUniswapSelector } from './withUniswapLiquidity'; export { default as withWalletConnectConfirmationModal } from './withWalletConnectConfirmationModal'; export { default as withWalletConnectConnections } from './withWalletConnectConnections'; diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js new file mode 100644 index 00000000000..19b9c073f6e --- /dev/null +++ b/src/hoc/withUniswapAssets.js @@ -0,0 +1,13 @@ +import { mapValues, sortBy, values } from 'lodash'; +import { compose, withProps } from 'recompact'; +import uniswapAssets from '../references/uniswap-pairs.json'; + +const sortUniswapAssetsByName = () => { + const assetList = values(mapValues(uniswapAssets, (asset, address) => ({ ...asset, address }))); + return sortBy(assetList, asset => asset.name); +} + +export default Component => compose( + withProps({ sortedUniswapAssets: sortUniswapAssetsByName() }), +)(Component); + diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 352c11636ad..516152c2013 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,4 +1,10 @@ -import { get, intersectionWith } from 'lodash'; +import { + filter, + findIndex, + get, + keys, + map, +} from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { compose, withHandlers } from 'recompact'; @@ -17,10 +23,12 @@ import { withAccountData, withKeyboardFocusHistory, withTransitionProps, + withUniswapAssets, } from '../hoc'; import { borders, colors, position } from '../styles'; import { BackButton } from '../components/header'; import { ExchangeSearch } from '../components/exchange'; +import uniswapAssets from '../references/uniswap-pairs.json'; import { exchangeModalBorderRadius } from './ExchangeModal'; const HeaderContainer = styled(Centered).attrs({ @@ -41,6 +49,7 @@ const BackButtonWrapper = styled(Centered)` class CurrencySelectModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, + sortedUniswapAssets: PropTypes.array, navigation: PropTypes.object, } @@ -107,10 +116,15 @@ class CurrencySelectModal extends PureComponent { this.props.pushKeyboardFocusHistory(currentTarget); } + getAssetsAvailableOnUniswap = () => { + const uniswapAssetAddresses = map(keys(uniswapAssets), address => address.toLowerCase()); + return filter(this.props.allAssets, asset => findIndex(uniswapAssetAddresses, uniswapAddress => uniswapAddress === asset.address) > -1); + }; + getAssets = () => { const data = this.isInputAssets - ? intersectionWith(this.props.allAssets, this.props.uniswapAssets, (uniswapAsset, asset) => uniswapAsset.address.toLowerCase() === asset.address.toLowerCase()) - : this.props.uniswapAssets; + ? this.getAssetsAvailableOnUniswap() + : this.props.sortedUniswapAssets; return [ { balances: true, @@ -192,6 +206,7 @@ class CurrencySelectModal extends PureComponent { export default compose( withAccountData, + withUniswapAssets, withNavigationFocus, withTransitionProps, withKeyboardFocusHistory, From b7a44961999f881ff615ac0e9db408c7710c8900 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 5 Aug 2019 19:34:38 -0700 Subject: [PATCH 186/636] hooking up exchange input and output fields --- .nvmrc | 2 +- src/screens/ExchangeModal.js | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.nvmrc b/.nvmrc index a933a5dd767..afa7ccbea64 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v11.1.0 +v11.10.1 diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 2f9abb66c0f..bf0183d11dd 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -6,7 +6,7 @@ import { tradeTokensForExactEth, tradeTokensForExactTokens, } from '@uniswap/sdk'; -import { get } from 'lodash'; +import { get, isNil } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { TextInput } from 'react-native'; @@ -27,7 +27,7 @@ import { withTransitionProps, } from '../hoc'; import { colors, padding, position } from '../styles'; -import { deviceUtils, safeAreaInsetValues } from '../utils'; +import { deviceUtils, ethereumUtils, safeAreaInsetValues } from '../utils'; import { ConfirmExchangeButton, ExchangeGasFeeButton, @@ -80,7 +80,7 @@ class ExchangeModal extends PureComponent { state = { inputAmount: null, inputAsExactAmount: false, - inputCurrency: 'ETH', + inputCurrency: { address: 'eth', decimals: 18, name: 'Ethereum', symbol: 'ETH' }, nativeAmount: null, outputAmount: null, outputCurrency: null, @@ -208,7 +208,7 @@ class ExchangeModal extends PureComponent { setInputCurrency = inputCurrency => { const previousInputCurrency = this.inputCurrency; this.setState({ inputCurrency }); - if (inputCurrency.address === this.outputCurrency.address) { + if (inputCurrency && this.outputCurrency && inputCurrency.address === this.outputCurrency.address) { if (this.outputCurrency !== null && previousInputCurrency !== null) { this.setOutputCurrency(previousInputCurrency); @@ -219,12 +219,11 @@ class ExchangeModal extends PureComponent { } setOutputCurrency = outputCurrency => { - // TODO check that it is valid input currency const previousOutputCurrency = this.outputCurrency; - this.setState({ outputCurrency }) - if (outputCurrency.address === this.inputCurrency.address) { - if (this.inputCurrency !== null - && previousOutputCurrency !== null) { + this.setState({ outputCurrency }); + if (outputCurrency && this.inputCurrency && outputCurrency.address === this.inputCurrency.address) { + const asset = ethereumUtils.getAsset(this.props.allAssets, address); + if (this.inputCurrency !== null && previousOutputCurrency !== null && !isNil(asset)) { this.setInputCurrency(previousOutputCurrency); } else { this.setInputCurrency(null); @@ -318,7 +317,7 @@ class ExchangeModal extends PureComponent { From 2c23d2c4fd0fb0dd0c243d8a0fa843f5777cd0c2 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 5 Aug 2019 20:36:29 -0700 Subject: [PATCH 187/636] native currencies placeholders and masks --- src/components/exchange/ExchangeInputField.js | 4 +- src/references/native-currencies.json | 70 +++++++++++-------- src/screens/ExchangeModal.js | 23 +++--- 3 files changed, 57 insertions(+), 40 deletions(-) diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 84a2d459493..5314758d3ea 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -1,6 +1,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; +import supportedNativeCurrencies from '../../references/native-currencies.json'; import { colors, fonts } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { CoolButton } from '../buttons'; @@ -55,9 +56,10 @@ export default class ExchangeInputField extends PureComponent { inputAmount, inputCurrency, inputFieldRef, - onFocus, nativeAmount, + nativeCurrency, nativeFieldRef, + onFocus, onPressMaxBalance, onPressSelectInputCurrency, setInputAmount, diff --git a/src/references/native-currencies.json b/src/references/native-currencies.json index e736541b57d..74f824c7a4e 100644 --- a/src/references/native-currencies.json +++ b/src/references/native-currencies.json @@ -1,55 +1,67 @@ { "USD": { - "symbol": "$", - "currency": "USD", - "label": "United States Dollar", - "decimals": 2, "alignment": "left", "assetLimit": 1, - "emojiName": "us" + "currency": "USD", + "decimals": 2, + "emojiName": "us", + "label": "United States Dollar", + "mask": "{$}[099999999999]{.}[00]", + "placeholder": "$0.00", + "symbol": "$" }, "CNY": { - "symbol": "¥", - "currency": "CNY", - "label": "Chinese Yuan", - "decimals": 2, "alignment": "left", "assetLimit": 1, - "emojiName": "cn" + "currency": "CNY", + "decimals": 2, + "emojiName": "cn", + "label": "Chinese Yuan", + "mask": "{¥}[099999999999]{.}[00]", + "placeholder": "¥0.00", + "symbol": "¥" }, "KRW": { - "symbol": "₩", - "currency": "KRW", - "label": "South Korean Won", - "decimals": 0, "alignment": "left", "assetLimit": 1, - "emojiName": "kr" + "currency": "KRW", + "decimals": 0, + "emojiName": "kr", + "label": "South Korean Won", + "mask": "{₩}[099999999999]{.}[00]", + "placeholder": "₩0.00", + "symbol": "₩" }, "RUB": { - "symbol": "₽", - "currency": "RUB", - "label": "Russian Ruble", - "decimals": 2, "alignment": "right", "assetLimit": 1, - "emojiName": "ru" + "currency": "RUB", + "decimals": 2, + "emojiName": "ru", + "label": "Russian Ruble", + "mask": "{₽}[099999999999]{.}[00]", + "placeholder": "₽0.00", + "symbol": "₽" }, "EUR": { - "symbol": "€", - "currency": "EUR", - "label": "Euro", - "decimals": 2, "alignment": "left", "assetLimit": 1, - "emojiName": "flag-eu" + "currency": "EUR", + "decimals": 2, + "emojiName": "flag-eu", + "label": "Euro", + "mask": "{€}[099999999999]{.}[00]", + "placeholder": "€0.00", + "symbol": "€" }, "ETH": { - "symbol": "Ξ", + "alignment": "right", + "assetLimit": 0.001, "currency": "ETH", - "label": "Ethereum", "decimals": 8, - "alignment": "right", - "assetLimit": 0.001 + "label": "Ethereum", + "mask": "[99999999999]{.}[999999999999999999]{ ETH}", + "placeholder": "0 ETH", + "symbol": "Ξ" } } diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index bf0183d11dd..e95195cd787 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -73,6 +73,7 @@ class ExchangeModal extends PureComponent { chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, keyboardFocusHistory: PropTypes.array, + nativeCurrency: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, } @@ -185,7 +186,7 @@ class ExchangeModal extends PureComponent { setNativeAmount = async nativeAmount => { this.setState({ nativeAmount }); - const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.inputCurrency, 'native.price.amount', 0)); + const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); this.setState({ inputAmount }); setInputAsExactAmount(true); await getMarketDetails(); @@ -193,7 +194,7 @@ class ExchangeModal extends PureComponent { setInputAmount = async inputAmount => { this.setState({ inputAmount }); - const nativeAmount = convertAmountToNativeAmount(inputAmount, get(this.inputCurrency, 'native.price.amount', 0)); + const nativeAmount = convertAmountToNativeAmount(inputAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); this.setState({ nativeAmount }); setInputAsExactAmount(true); await getMarketDetails(); @@ -206,10 +207,10 @@ class ExchangeModal extends PureComponent { } setInputCurrency = inputCurrency => { - const previousInputCurrency = this.inputCurrency; + const previousInputCurrency = this.state.inputCurrency; this.setState({ inputCurrency }); - if (inputCurrency && this.outputCurrency && inputCurrency.address === this.outputCurrency.address) { - if (this.outputCurrency !== null + if (inputCurrency && this.state.outputCurrency && inputCurrency.address === this.state.outputCurrency.address) { + if (this.state.outputCurrency !== null && previousInputCurrency !== null) { this.setOutputCurrency(previousInputCurrency); } else { @@ -219,11 +220,11 @@ class ExchangeModal extends PureComponent { } setOutputCurrency = outputCurrency => { - const previousOutputCurrency = this.outputCurrency; + const previousOutputCurrency = this.state.outputCurrency; this.setState({ outputCurrency }); - if (outputCurrency && this.inputCurrency && outputCurrency.address === this.inputCurrency.address) { + if (outputCurrency && this.state.inputCurrency && outputCurrency.address === this.state.inputCurrency.address) { const asset = ethereumUtils.getAsset(this.props.allAssets, address); - if (this.inputCurrency !== null && previousOutputCurrency !== null && !isNil(asset)) { + if (this.state.inputCurrency !== null && previousOutputCurrency !== null && !isNil(asset)) { this.setInputCurrency(previousOutputCurrency); } else { this.setInputCurrency(null); @@ -276,8 +277,9 @@ class ExchangeModal extends PureComponent { render = () => { const { keyboardFocusHistory, - onPressConfirmExchange, + nativeCurrency, navigation, + onPressConfirmExchange, transitionProps, } = this.props; @@ -318,8 +320,9 @@ class ExchangeModal extends PureComponent { Date: Mon, 5 Aug 2019 22:30:51 -0700 Subject: [PATCH 188/636] input currency on exchange --- src/helpers/utilities.js | 16 +++++++++++- src/screens/ExchangeModal.js | 48 +++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index aa635c97331..f7480facab5 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -1,4 +1,4 @@ -import { get } from 'lodash'; +import { get, split } from 'lodash'; import BigNumber from 'bignumber.js'; import supportedNativeCurrencies from '../references/native-currencies.json'; @@ -341,6 +341,20 @@ export const convertAmountToNativeDisplay = (value, nativeCurrency, buffer) => { return `${display} ${nativeSelected.currency}`; }; +/** + * @desc convert to amount value from display formatted string + * @param {String} formatted native value + * @param {String} nativeCurrency + * @return {String} + */ +export const convertAmountFromNativeDisplay = (nativeDisplayValue, nativeCurrency) => { + const nativeSelected = supportedNativeCurrencies[nativeCurrency]; + if (nativeSelected.alignment === 'left') { + return nativeDisplayValue.trim().slice(1); + } + return split(nativeDisplayValue, ' ')[0]; +}; + /** * @desc convert from raw amount to decimal format * @param {String|Number} value diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index e95195cd787..9d4110ae120 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -14,9 +14,11 @@ import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, toClass, withProps } from 'recompact'; import { + convertAmountFromNativeDisplay, convertAmountFromNativeValue, convertAmountToNativeAmount, convertAmountToRawAmount, + convertRawAmountToDecimalFormat, } from '../helpers/utilities'; import { withAccountData, @@ -81,7 +83,7 @@ class ExchangeModal extends PureComponent { state = { inputAmount: null, inputAsExactAmount: false, - inputCurrency: { address: 'eth', decimals: 18, name: 'Ethereum', symbol: 'ETH' }, + inputCurrency: ethereumUtils.getAsset(this.props.allAssets), nativeAmount: null, outputAmount: null, outputCurrency: null, @@ -129,6 +131,13 @@ class ExchangeModal extends PureComponent { outputFieldRef = null + parseTradeDetails = (path, tradeDetails, decimals) => { + const updatedValue = get(tradeDetails, path); + const slippage = get(tradeDetails, 'marketRateSlippage'); + const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, decimals); + return { rawUpdatedValue, slippage: slippage.toFixed() }; + }; + getMarketDetails = async () => { try { let tradeDetails = null; @@ -141,6 +150,7 @@ class ExchangeModal extends PureComponent { outputCurrency, } = this.state; if (inputCurrency === null || outputCurrency === null) return; + if (isNil(inputAmount) && isNil(outputAmount)) return; const { address: inputCurrencyAddress, decimals: inputDecimals, @@ -149,8 +159,8 @@ class ExchangeModal extends PureComponent { address: outputCurrencyAddress, decimals: outputDecimals, } = outputCurrency; - const rawInputAmount = convertAmountToRawAmount(inputAmount, inputDecimals); - const rawOutputAmount = convertAmountToRawAmount(outputAmount, outputDecimals); + const rawInputAmount = convertAmountToRawAmount(inputAmount || 0, inputDecimals); + const rawOutputAmount = convertAmountToRawAmount(outputAmount || 0, outputDecimals); if (inputCurrencyAddress === 'eth' && outputCurrencyAddress !== 'eth') { tradeDetails = inputAsExactAmount @@ -164,18 +174,11 @@ class ExchangeModal extends PureComponent { tradeDetails = inputAsExactAmount ? await tradeExactTokensForTokens(inputCurrencyAddress, outputCurrencyAddress, rawInputAmount, chainId) : await tradeTokensForExactTokens(inputCurrencyAddress, outputCurrencyAddress, rawOutputAmount, chainId); - } if (inputAsExactAmount) { - // TODO reuse - const updatedValue = get(tradeDetails, 'outputAmount.amount'); - const slippage = get(tradeDetails, 'marketRateSlippage'); - const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, outputDecimals); - this.setState({ outputAmount: rawUpdatedValue, slippage }); - } else { - const updatedValue = get(tradeDetails, 'inputAmount.amount'); - const slippage = get(tradeDetails, 'marketRateSlippage'); - const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, inputDecimals); - this.setState({ inputAmount: rawUpdatedValue, slippage }); } + const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; + const path = inputAsExactAmount ? 'outputAmount.amount' : 'inputAmount.amount'; + const { rawUpdatedValue, slippage } = this.parseTradeDetails(path, tradeDetails, decimals); + this.setState({ outputAmount: rawUpdatedValue, slippage }); } catch (error) { console.log('error getting market details', error); // TODO @@ -184,26 +187,27 @@ class ExchangeModal extends PureComponent { setInputAsExactAmount = (inputAsExactAmount) => this.setState({ inputAsExactAmount }) - setNativeAmount = async nativeAmount => { - this.setState({ nativeAmount }); + setNativeAmount = async nativeAmountDisplay => { + this.setState({ nativeAmount: nativeAmountDisplay }); + const nativeAmount = convertAmountFromNativeDisplay(nativeAmountDisplay, this.props.nativeCurrency); const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); this.setState({ inputAmount }); - setInputAsExactAmount(true); - await getMarketDetails(); + this.setInputAsExactAmount(true); + await this.getMarketDetails(); } setInputAmount = async inputAmount => { this.setState({ inputAmount }); const nativeAmount = convertAmountToNativeAmount(inputAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); this.setState({ nativeAmount }); - setInputAsExactAmount(true); - await getMarketDetails(); + this.setInputAsExactAmount(true); + await this.getMarketDetails(); } setOutputAmount = async outputAmount => { this.setState({ outputAmount }); - setInputAsExactAmount(false); - await getMarketDetails(); + this.setInputAsExactAmount(false); + await this.getMarketDetails(); } setInputCurrency = inputCurrency => { From d6ac1b4074dbf2e0a7719fdff4774aee5074b224 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 5 Aug 2019 23:04:14 -0700 Subject: [PATCH 189/636] set input field --- src/screens/ExchangeModal.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 9d4110ae120..e333fc31337 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -178,7 +178,11 @@ class ExchangeModal extends PureComponent { const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; const path = inputAsExactAmount ? 'outputAmount.amount' : 'inputAmount.amount'; const { rawUpdatedValue, slippage } = this.parseTradeDetails(path, tradeDetails, decimals); - this.setState({ outputAmount: rawUpdatedValue, slippage }); + if (inputAsExactAmount) { + this.setState({ outputAmount: rawUpdatedValue, slippage }); + } else { + this.setState({ inputAmount: rawUpdatedValue, slippage }); + } } catch (error) { console.log('error getting market details', error); // TODO From ca398769d990f7fbace9e8326b507f32f645f33c Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 6 Aug 2019 15:39:16 -0700 Subject: [PATCH 190/636] minimum support for swap actions --- src/handlers/uniswap.js | 86 +++++++++++++++++++++++++++++++++++- src/redux/uniswap.js | 2 +- src/screens/ExchangeModal.js | 12 ++++- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index f45eab3bb76..b4c79860202 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -7,11 +7,93 @@ import { fromWei, multiply, } from '../helpers/utilities'; +import { loadWallet } from '../model/wallet'; import exchangeABI from '../references/uniswap-exchange-abi.json'; import erc20ABI from '../references/erc20-abi.json'; import { web3Provider } from './web3'; -export default async function getUniswapLiquidityInfo(accountAddress, exchangeContracts) { +const convertArgsForEthers = (methodArguments) => methodArguments.map(arg => (typeof arg === 'object') ? ethers.utils.bigNumberify(arg.toFixed()) : arg); + +const convertValueForEthers = (value) => { + const valueBigNumber = ethers.utils.bigNumberify(value.toString()); + return ethers.utils.hexlify(valueBigNumber); +}; + +export const executeSwap = async (executionDetails) => { + const wallet = await loadWallet(); + if (!wallet) return null; + const { + exchangeAddress, + methodArguments, + methodName, + value: rawValue, + } = executionDetails; + const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); + try { + switch (methodName) { + case 'ethToTokenSwapInput': { + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + const gasLimit = await exchange.estimate.ethToTokenSwapInput(...updatedMethodArgs, { value }); + const txn = await exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); + // TODO add to new txn + console.log('eth to token input', txn); + return; + } + case 'ethToTokenSwapOutput': { + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + const gasLimit = await exchange.estimate.ethToTokenSwapOutput(...updatedMethodArgs, { value }); + const txn = await exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); + // TODO add to new txn + console.log('eth to token output', txn); + return; + } + case 'tokenToEthSwapInput': { + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + const gasLimit = await exchange.estimate.tokenToEthSwapInput(...updatedMethodArgs, { value }); + const txn = await exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); + // TODO add to new txn + console.log('token to eth input', txn); + return; + } + case 'tokenToEthSwapOutput': { + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + const gasLimit = await exchange.estimate.tokenToEthSwapOutput(...updatedMethodArgs, { value }); + const txn = await exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); + // TODO add to new txn + console.log('token to eth output', txn); + return; + } + case 'tokenToTokenSwapInput': { + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + const gasLimit = await exchange.estimate.tokenToTokenSwapInput(...updatedMethodArgs, { value }); + const txn = await exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); + // TODO add to new txn + console.log('token to token input', txn); + return; + } + case 'tokenToTokenSwapOutput': { + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + const gasLimit = await exchange.estimate.tokenToTokenSwapOutput(...updatedMethodArgs, { value }); + const txn = await exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); + // TODO add to new txn + console.log('token to token output', txn); + return; + } + default: + return null; + } + } catch (error) { + console.log('error exchanging', error); + } +}; + +export const getUniswapLiquidityInfo = async (accountAddress, exchangeContracts) => { const promises = map(exchangeContracts, async (exchangeAddress) => { try { const ethReserveCall = web3Provider.getBalance(exchangeAddress); @@ -81,4 +163,4 @@ export default async function getUniswapLiquidityInfo(accountAddress, exchangeCo const results = await Promise.all(promises); return zipObject(exchangeContracts, results); -} +}; diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index c4839c226dc..ebda6299a0f 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -13,7 +13,7 @@ import { saveUniswap, saveUniswapLiquidityTokens, } from '../handlers/commonStorage'; -import getUniswapLiquidityInfo from '../handlers/uniswap'; +import { getUniswapLiquidityInfo } from '../handlers/uniswap'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index e333fc31337..a911054ba01 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,4 +1,5 @@ import { + getExecutionDetails, tradeEthForExactTokens, tradeExactEthForTokens, tradeExactTokensForEth, @@ -13,6 +14,7 @@ import { TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, toClass, withProps } from 'recompact'; +import { executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeDisplay, convertAmountFromNativeValue, @@ -78,6 +80,7 @@ class ExchangeModal extends PureComponent { nativeCurrency: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, + tradeDetails: PropTypes.object, } state = { @@ -89,6 +92,7 @@ class ExchangeModal extends PureComponent { outputCurrency: null, showConfirmButton: false, slippage: null, + tradeDetails: null, } componentDidMount = () => { @@ -177,6 +181,7 @@ class ExchangeModal extends PureComponent { } const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; const path = inputAsExactAmount ? 'outputAmount.amount' : 'inputAmount.amount'; + this.setState({ tradeDetails }); const { rawUpdatedValue, slippage } = this.parseTradeDetails(path, tradeDetails, decimals); if (inputAsExactAmount) { this.setState({ outputAmount: rawUpdatedValue, slippage }); @@ -254,8 +259,11 @@ class ExchangeModal extends PureComponent { }); } - handleSubmit = () => { - this.props.navigation.navigate('WalletScreen'); + handleSubmit = async () => { + const { tradeDetails } = this.state; + const executionDetails = getExecutionDetails(tradeDetails); + await executeSwap(executionDetails); + this.props.navigation.navigate('ProfileScreen'); } handleWillFocus = ({ lastState }) => { From 7bc7f2d441fdfccad339948e598cf1eb0ec4cb5f Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 6 Aug 2019 16:44:15 -0700 Subject: [PATCH 191/636] cleanup --- src/handlers/uniswap.js | 63 ++++++++++++++---------------------- src/screens/ExchangeModal.js | 4 +-- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index b4c79860202..7d54a4a69f5 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -1,3 +1,4 @@ +import { getExecutionDetails } from '@uniswap/sdk'; import contractMap from 'eth-contract-metadata'; import { ethers } from 'ethers'; import { get, map, zipObject } from 'lodash'; @@ -19,7 +20,8 @@ const convertValueForEthers = (value) => { return ethers.utils.hexlify(valueBigNumber); }; -export const executeSwap = async (executionDetails) => { +export const executeSwap = async (tradeDetails) => { + const executionDetails = getExecutionDetails(tradeDetails); const wallet = await loadWallet(); if (!wallet) return null; const { @@ -29,68 +31,51 @@ export const executeSwap = async (executionDetails) => { value: rawValue, } = executionDetails; const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); + const updatedMethodArgs = convertArgsForEthers(methodArguments); + const value = convertValueForEthers(rawValue); + let txn = null; try { switch (methodName) { case 'ethToTokenSwapInput': { - const updatedMethodArgs = convertArgsForEthers(methodArguments); - const value = convertValueForEthers(rawValue); const gasLimit = await exchange.estimate.ethToTokenSwapInput(...updatedMethodArgs, { value }); - const txn = await exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); - // TODO add to new txn - console.log('eth to token input', txn); - return; + txn = await exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); + break; } case 'ethToTokenSwapOutput': { - const updatedMethodArgs = convertArgsForEthers(methodArguments); - const value = convertValueForEthers(rawValue); const gasLimit = await exchange.estimate.ethToTokenSwapOutput(...updatedMethodArgs, { value }); - const txn = await exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); - // TODO add to new txn - console.log('eth to token output', txn); - return; + txn = await exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); + break; } case 'tokenToEthSwapInput': { - const updatedMethodArgs = convertArgsForEthers(methodArguments); - const value = convertValueForEthers(rawValue); + // TODO approval check const gasLimit = await exchange.estimate.tokenToEthSwapInput(...updatedMethodArgs, { value }); - const txn = await exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); - // TODO add to new txn - console.log('token to eth input', txn); - return; + txn = await exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); + break; } case 'tokenToEthSwapOutput': { - const updatedMethodArgs = convertArgsForEthers(methodArguments); - const value = convertValueForEthers(rawValue); + // TODO approval check const gasLimit = await exchange.estimate.tokenToEthSwapOutput(...updatedMethodArgs, { value }); - const txn = await exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); - // TODO add to new txn - console.log('token to eth output', txn); - return; + txn = await exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); + break; } case 'tokenToTokenSwapInput': { - const updatedMethodArgs = convertArgsForEthers(methodArguments); - const value = convertValueForEthers(rawValue); + // TODO approval check const gasLimit = await exchange.estimate.tokenToTokenSwapInput(...updatedMethodArgs, { value }); - const txn = await exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); - // TODO add to new txn - console.log('token to token input', txn); - return; + txn = await exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); + break; } case 'tokenToTokenSwapOutput': { - const updatedMethodArgs = convertArgsForEthers(methodArguments); - const value = convertValueForEthers(rawValue); + // TODO approval check const gasLimit = await exchange.estimate.tokenToTokenSwapOutput(...updatedMethodArgs, { value }); - const txn = await exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); - // TODO add to new txn - console.log('token to token output', txn); - return; + txn = await exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); + break; } default: - return null; - } + break; } catch (error) { console.log('error exchanging', error); } + // TODO add to new txn }; export const getUniswapLiquidityInfo = async (accountAddress, exchangeContracts) => { diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a911054ba01..6d676e3a906 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,5 +1,4 @@ import { - getExecutionDetails, tradeEthForExactTokens, tradeExactEthForTokens, tradeExactTokensForEth, @@ -261,8 +260,7 @@ class ExchangeModal extends PureComponent { handleSubmit = async () => { const { tradeDetails } = this.state; - const executionDetails = getExecutionDetails(tradeDetails); - await executeSwap(executionDetails); + await executeSwap(tradeDetails); this.props.navigation.navigate('ProfileScreen'); } From ba9ccbabc094db72eba143a19766f47c069ff735 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 7 Aug 2019 00:27:36 -0700 Subject: [PATCH 192/636] expose approve function --- src/handlers/uniswap.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 7d54a4a69f5..636b998221d 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -20,6 +20,16 @@ const convertValueForEthers = (value) => { return ethers.utils.hexlify(valueBigNumber); }; +export const approve = async (exchangeAddress) => { + const wallet = await loadWallet(); + if (!wallet) return null; + const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); + const gasLimit = await exchange.estimate.approve(exchangeAddress, ethers.constants.MaxUint256); + const txn = await exchange.approve(exchangeAddress, ethers.constants.MaxUint256, { gasLimit }); + // TODO MIKE save txn hash somewhere + return txn; +}; + export const executeSwap = async (tradeDetails) => { const executionDetails = getExecutionDetails(tradeDetails); const wallet = await loadWallet(); From c0d3b92e34b46e5ce0a3f9b78ac9cb3f1f1b9604 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 7 Aug 2019 13:07:27 -0700 Subject: [PATCH 193/636] add new swap txn to pending --- src/handlers/uniswap.js | 29 +++++++++++------------------ src/screens/ExchangeModal.js | 27 +++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 636b998221d..a41d2310772 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -20,14 +20,13 @@ const convertValueForEthers = (value) => { return ethers.utils.hexlify(valueBigNumber); }; +// TODO save txn hash somewhere export const approve = async (exchangeAddress) => { const wallet = await loadWallet(); if (!wallet) return null; const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); const gasLimit = await exchange.estimate.approve(exchangeAddress, ethers.constants.MaxUint256); - const txn = await exchange.approve(exchangeAddress, ethers.constants.MaxUint256, { gasLimit }); - // TODO MIKE save txn hash somewhere - return txn; + return exchange.approve(exchangeAddress, ethers.constants.MaxUint256, { gasLimit }); }; export const executeSwap = async (tradeDetails) => { @@ -43,49 +42,43 @@ export const executeSwap = async (tradeDetails) => { const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); const updatedMethodArgs = convertArgsForEthers(methodArguments); const value = convertValueForEthers(rawValue); - let txn = null; try { switch (methodName) { case 'ethToTokenSwapInput': { const gasLimit = await exchange.estimate.ethToTokenSwapInput(...updatedMethodArgs, { value }); - txn = await exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); - break; + return exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); } case 'ethToTokenSwapOutput': { const gasLimit = await exchange.estimate.ethToTokenSwapOutput(...updatedMethodArgs, { value }); - txn = await exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); - break; + return exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); } case 'tokenToEthSwapInput': { // TODO approval check const gasLimit = await exchange.estimate.tokenToEthSwapInput(...updatedMethodArgs, { value }); - txn = await exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); - break; + return exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); } case 'tokenToEthSwapOutput': { // TODO approval check const gasLimit = await exchange.estimate.tokenToEthSwapOutput(...updatedMethodArgs, { value }); - txn = await exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); - break; + return exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); } case 'tokenToTokenSwapInput': { // TODO approval check const gasLimit = await exchange.estimate.tokenToTokenSwapInput(...updatedMethodArgs, { value }); - txn = await exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); - break; + return exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); } case 'tokenToTokenSwapOutput': { // TODO approval check const gasLimit = await exchange.estimate.tokenToTokenSwapOutput(...updatedMethodArgs, { value }); - txn = await exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); - break; + return exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); } default: - break; + return null; + } } catch (error) { console.log('error exchanging', error); + return null; } - // TODO add to new txn }; export const getUniswapLiquidityInfo = async (accountAddress, exchangeContracts) => { diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 6d676e3a906..9701f8dc184 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -22,11 +22,13 @@ import { convertRawAmountToDecimalFormat, } from '../helpers/utilities'; import { + withAccountAddress, withAccountData, withAccountSettings, withBlockedHorizontalSwipe, withKeyboardFocusHistory, withNeverRerender, + withTransactionConfirmationScreen, withTransitionProps, } from '../hoc'; import { colors, padding, position } from '../styles'; @@ -75,6 +77,7 @@ class ExchangeModal extends PureComponent { allAssets: PropTypes.array, chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, + dataAddNewTransaction: PropTypes.func, keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, navigation: PropTypes.object, @@ -260,8 +263,26 @@ class ExchangeModal extends PureComponent { handleSubmit = async () => { const { tradeDetails } = this.state; - await executeSwap(tradeDetails); - this.props.navigation.navigate('ProfileScreen'); + try { + const txn = await executeSwap(tradeDetails); + if (txn) { + const txnDetails = { + amount: this.state.inputAmount, + asset: this.state.inputCurrency, + from: this.props.accountAddress, + hash: txn.hash, + nonce: get(txn, 'nonce'), + to: get(txn, 'to'), + }; + this.props.dataAddNewTransaction(txnDetails); + this.props.navigation.navigate('ProfileScreen'); + } else { + this.props.navigation.navigate('ProfileScreen'); + } + } catch (error) { + console.log('error submitting swap', error); + this.props.navigation.navigate('WalletScreen'); + } } handleWillFocus = ({ lastState }) => { @@ -387,9 +408,11 @@ const withMockedPrices = withProps({ }); export default compose( + withAccountAddress, withAccountData, withAccountSettings, withBlockedHorizontalSwipe, + withTransactionConfirmationScreen, withNavigationFocus, withMockedPrices, withKeyboardFocusHistory, From 0d9e0126ff3d0975f18ba782eb071e99f6a1770f Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 7 Aug 2019 19:16:57 -0700 Subject: [PATCH 194/636] first implementation of search --- src/screens/CurrencySelectModal.js | 53 ++++++++++++++++-------------- src/screens/ExchangeModal.js | 20 ++++++++++- src/utils/__tests__/search.test.js | 19 +++++++++++ src/utils/search.js | 19 +++++++++++ 4 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 src/utils/__tests__/search.test.js create mode 100644 src/utils/search.js diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 516152c2013..fa9a76df715 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -2,6 +2,7 @@ import { filter, findIndex, get, + isEmpty, keys, map, } from 'lodash'; @@ -28,7 +29,7 @@ import { import { borders, colors, position } from '../styles'; import { BackButton } from '../components/header'; import { ExchangeSearch } from '../components/exchange'; -import uniswapAssets from '../references/uniswap-pairs.json'; +import { filterList } from '../utils/search'; import { exchangeModalBorderRadius } from './ExchangeModal'; const HeaderContainer = styled(Centered).attrs({ @@ -48,15 +49,24 @@ const BackButtonWrapper = styled(Centered)` class CurrencySelectModal extends PureComponent { static propTypes = { - allAssets: PropTypes.array, - sortedUniswapAssets: PropTypes.array, navigation: PropTypes.object, } + state = { + searchResults: [], + } + + assets = [] + callback = null isInputAssets = true + onChangeSearchText = (searchPhrase) => { + const searchResults = filterList(this.assets, searchPhrase, 'index'); + this.setState({ searchResults }); + } + searchInputRef = React.createRef() componentDidMount() { @@ -83,7 +93,11 @@ class CurrencySelectModal extends PureComponent { } getDataFromParams = () => { - this.callback = this.props.navigation.getParam('onSelectCurrency'); + const { navigation } = this.props; + this.callback = navigation.getParam('onSelectCurrency'); + const assets = navigation.getParam('assets') || []; + const indexedAssets = map(assets, asset => ({ ...asset, index: `${asset.name} ${asset.symbol}` })); + this.assets = indexedAssets; } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { @@ -116,23 +130,15 @@ class CurrencySelectModal extends PureComponent { this.props.pushKeyboardFocusHistory(currentTarget); } - getAssetsAvailableOnUniswap = () => { - const uniswapAssetAddresses = map(keys(uniswapAssets), address => address.toLowerCase()); - return filter(this.props.allAssets, asset => findIndex(uniswapAssetAddresses, uniswapAddress => uniswapAddress === asset.address) > -1); - }; - - getAssets = () => { - const data = this.isInputAssets - ? this.getAssetsAvailableOnUniswap() - : this.props.sortedUniswapAssets; - return [ - { - balances: true, - data, - renderItem: this.renderCurrencyItem, - }, - ]; - }; + getSections = () => { + const data = (this.state.searchResults) ? this.assets : this.state.searchResults; + return [{ + balances: true, + data, + renderItem: this.renderCurrencyItem, + }]; + } + render() { const { @@ -186,6 +192,7 @@ class CurrencySelectModal extends PureComponent { @@ -193,7 +200,7 @@ class CurrencySelectModal extends PureComponent { flex={0} hideHeader paddingBottom={100} - sections={this.getAssets()} + sections={this.getSections()} /> @@ -205,8 +212,6 @@ class CurrencySelectModal extends PureComponent { } export default compose( - withAccountData, - withUniswapAssets, withNavigationFocus, withTransitionProps, withKeyboardFocusHistory, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 9701f8dc184..891450fdea7 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -6,7 +6,14 @@ import { tradeTokensForExactEth, tradeTokensForExactTokens, } from '@uniswap/sdk'; -import { get, isNil } from 'lodash'; +import { + filter, + findIndex, + get, + isNil, + keys, + map, +} from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { TextInput } from 'react-native'; @@ -30,7 +37,9 @@ import { withNeverRerender, withTransactionConfirmationScreen, withTransitionProps, + withUniswapAssets, } from '../hoc'; +import uniswapAssets from '../references/uniswap-pairs.json'; import { colors, padding, position } from '../styles'; import { deviceUtils, ethereumUtils, safeAreaInsetValues } from '../utils'; import { @@ -82,6 +91,7 @@ class ExchangeModal extends PureComponent { nativeCurrency: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, + sortedUniswapAssets: PropTypes.array, tradeDetails: PropTypes.object, } @@ -247,8 +257,14 @@ class ExchangeModal extends PureComponent { } } + getAssetsAvailableOnUniswap = () => { + const uniswapAssetAddresses = map(keys(uniswapAssets), address => address.toLowerCase()); + return filter(this.props.allAssets, asset => findIndex(uniswapAssetAddresses, uniswapAddress => uniswapAddress === asset.address) > -1); + }; + handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { + assets: this.getAssetsAvailableOnUniswap(), isInputAssets: true, onSelectCurrency: this.setInputCurrency, }); @@ -256,6 +272,7 @@ class ExchangeModal extends PureComponent { handleSelectOutputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { + assets: this.props.sortedUniswapAssets, isInputAssets: false, onSelectCurrency: this.setOutputCurrency, }); @@ -413,6 +430,7 @@ export default compose( withAccountSettings, withBlockedHorizontalSwipe, withTransactionConfirmationScreen, + withUniswapAssets, withNavigationFocus, withMockedPrices, withKeyboardFocusHistory, diff --git a/src/utils/__tests__/search.test.js b/src/utils/__tests__/search.test.js new file mode 100644 index 00000000000..493b047b925 --- /dev/null +++ b/src/utils/__tests__/search.test.js @@ -0,0 +1,19 @@ +import { filterList } from '../search'; + +test('filterListSimpleArray', () => { + const list = ['a dog', 'black cat']; + const searchPhrase = 'cat'; + const result = filterList(list, searchPhrase); + expect(result.length).toBe(1); +}); + +test('filterListWithParameter', () => { + const list = [ + { name: 'Ethereum', symbol: 'ETH' }, + { name: '0x Protocol Token', symbol: 'ZRX'}, + ]; + const searchPhrase = 'eth'; + const result = filterList(list, searchPhrase, searchParameter = 'name'); + expect(result.length).toBe(1); +}); + diff --git a/src/utils/search.js b/src/utils/search.js new file mode 100644 index 00000000000..f1bbee9ae42 --- /dev/null +++ b/src/utils/search.js @@ -0,0 +1,19 @@ +export const filterList = (list, searchPhrase, searchParameter = false, separator = ' ') => { + const filteredList = []; + if (list && searchPhrase.length > 0) { + for (let i = 0; i < list.length; i++) { + let searchedItem = searchParameter ? list[i][searchParameter] : list[i]; + const splitedWordList = searchedItem.split(separator); + splitedWordList.push(searchedItem); + for (let j = 0; j < splitedWordList.length; j++) { + if (splitedWordList[j].toLowerCase().startsWith(searchPhrase.toLowerCase())) { + filteredList.push(list[i]); + break; + } + } + } + } else { + return list; + } + return filteredList; +} From f874f5431f1df103228ce9b7948a9f7ec2ff4287 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 7 Aug 2019 19:38:22 -0700 Subject: [PATCH 195/636] cleanup --- src/screens/CurrencySelectModal.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index fa9a76df715..fc7f1f3d805 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -95,8 +95,7 @@ class CurrencySelectModal extends PureComponent { getDataFromParams = () => { const { navigation } = this.props; this.callback = navigation.getParam('onSelectCurrency'); - const assets = navigation.getParam('assets') || []; - const indexedAssets = map(assets, asset => ({ ...asset, index: `${asset.name} ${asset.symbol}` })); + const indexedAssets = map(navigation.getParam('assets', []), asset => ({ ...asset, index: `${asset.name} ${asset.symbol}` })); this.assets = indexedAssets; } From 5c623a9dee38b34887dfd741c6bcf8861ebd03ef Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 8 Aug 2019 13:17:24 -0700 Subject: [PATCH 196/636] send max balance on exchange --- src/redux/send.js | 28 ++--------------- src/screens/ExchangeModal.js | 9 ++++++ src/utils/__tests__/ethereumUtils.test.js | 37 +++++++++++++++++++++++ src/utils/ethereumUtils.js | 16 ++++++++++ 4 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 src/utils/__tests__/ethereumUtils.test.js diff --git a/src/redux/send.js b/src/redux/send.js index 788e7ffa315..0b42a00f471 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -6,11 +6,8 @@ import { ethereumUtils } from '../utils'; import { convertAmountAndPriceToNativeDisplay, convertAmountFromNativeValue, - convertNumberToString, formatInputDecimals, fromWei, - greaterThan, - subtract, } from '../helpers/utilities'; import { parseGasPrices, @@ -46,22 +43,6 @@ const SEND_UPDATE_NFT_SELECTED = 'send/SEND_UPDATE_NFT_SELECTED'; const SEND_CLEAR_FIELDS = 'send/SEND_CLEAR_FIELDS'; -function getBalanceAmount(assets, gasPrice, selected) { - let amount = ''; - - if (selected.address === 'eth') { - const balanceAmount = get(selected, 'balance.amount', 0); - const txFeeRaw = get(gasPrice, 'txFee.value.amount'); - const txFeeAmount = fromWei(txFeeRaw); - const remaining = subtract(balanceAmount, txFeeAmount); - amount = convertNumberToString(greaterThan(remaining, 0) ? remaining : 0); - } else { - amount = get(selected, 'balance.amount', 0); - } - - return amount; -} - // -- Actions --------------------------------------------------------------- // const getEthPriceUnit = (assets) => { const ethAsset = ethereumUtils.getAsset(assets); @@ -236,7 +217,6 @@ export const sendUpdateRecipient = recipient => dispatch => { }; export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { - const { assets } = getState().data; const { nativeCurrency } = getState().settings; const { gasPrice, selected } = getState().send; const _assetAmount = assetAmount.replace(/[^0-9.]/g, ''); @@ -250,7 +230,7 @@ export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { ); _nativeAmount = formatInputDecimals(nativeAmount, _assetAmount); } - const balanceAmount = getBalanceAmount(assets, gasPrice, selected); + const balanceAmount = ethereumUtils.getBalanceAmount(gasPrice, selected); dispatch({ payload: { assetAmount: _assetAmount, @@ -262,7 +242,6 @@ export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { }; export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { - const { assets } = getState().data; const { gasPrice, selected } = getState().send; const _nativeAmount = nativeAmount.replace(/[^0-9.]/g, ''); let _assetAmount = ''; @@ -275,7 +254,7 @@ export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); } - const balanceAmount = getBalanceAmount(assets, gasPrice, selected); + const balanceAmount = ethereumUtils.getBalanceAmount(gasPrice, selected); dispatch({ payload: { @@ -313,8 +292,7 @@ export const sendUpdateSelected = (asset) => (dispatch, getState) => { export const sendMaxBalance = () => (dispatch, getState) => { const { gasPrice, selected } = getState().send; - const { assets } = getState().data; - const balanceAmount = getBalanceAmount(assets, gasPrice, selected); + const balanceAmount = ethereumUtils.getBalanceAmount(gasPrice, selected); dispatch(sendUpdateAssetAmount(balanceAmount)); dispatch(sendUpdateGasPrice()); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 891450fdea7..1f1f854a6a4 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -27,6 +27,7 @@ import { convertAmountToNativeAmount, convertAmountToRawAmount, convertRawAmountToDecimalFormat, + subtract, } from '../helpers/utilities'; import { withAccountAddress, @@ -262,6 +263,13 @@ class ExchangeModal extends PureComponent { return filter(this.props.allAssets, asset => findIndex(uniswapAssetAddresses, uniswapAddress => uniswapAddress === asset.address) > -1); }; + onPressMaxBalance = () => { + const { inputCurrency } = this.state; + const balance = get(inputCurrency, 'balance.amount', 0); + const inputAmount = (inputCurrency.address === 'eth') ? subtract(balance, 0.01) : balance; + this.setState({ inputAmount }); + } + handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { assets: this.getAssetsAvailableOnUniswap(), @@ -377,6 +385,7 @@ class ExchangeModal extends PureComponent { nativeCurrency={nativeCurrency} nativeFieldRef={this.handleNativeFieldRef} onFocus={this.handleFocusField} + onPressMaxBalance={this.onPressMaxBalance} onPressSelectInputCurrency={this.handleSelectInputCurrency} setInputAmount={this.setInputAmount} setNativeAmount={this.setNativeAmount} diff --git a/src/utils/__tests__/ethereumUtils.test.js b/src/utils/__tests__/ethereumUtils.test.js new file mode 100644 index 00000000000..45987472c2c --- /dev/null +++ b/src/utils/__tests__/ethereumUtils.test.js @@ -0,0 +1,37 @@ +import { getBalanceAmount } from '../ethereumUtils'; + +const gasPrice = { + txFee: { + value: { + amount: 21000, + } + } +}; + +test('getBalanceAmountEth', () => { + const selected = { + address: 'eth', + balance: { amount: '1' }, + }; + const updatedBalance = getBalanceAmount(gasPrice, selected); + expect(updatedBalance).toBe('0.999999999999979'); +}); + +test('getBalanceAmountInsufficientEth', () => { + const selected = { + address: 'eth', + balance: { amount: '0.00000000000000001' }, + }; + const updatedBalance = getBalanceAmount(gasPrice, selected); + expect(updatedBalance).toBe('0'); +}); + +test('getBalanceAmountToken', () => { + const selected = { + address: '0x12345', + balance: { amount: '1' }, + }; + const updatedBalance = getBalanceAmount(gasPrice, selected); + expect(updatedBalance).toBe('1'); +}); + diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index 4d397b84a50..5b893abf932 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -4,8 +4,24 @@ import { add, convertNumberToString, fromWei, + greaterThan, + subtract, } from '../helpers/utilities'; +export const getBalanceAmount = (gasPrice, selected) => { + let amount = ''; + if (selected.address === 'eth') { + const balanceAmount = get(selected, 'balance.amount', 0); + const txFeeRaw = get(gasPrice, 'txFee.value.amount'); + const txFeeAmount = fromWei(txFeeRaw); + const remaining = subtract(balanceAmount, txFeeAmount); + amount = convertNumberToString(greaterThan(remaining, 0) ? remaining : 0); + } else { + amount = get(selected, 'balance.amount', 0); + } + return amount; +}; + export const getAsset = (assets, address = 'eth') => find(assets, asset => asset.address === address); /** From ad6fcf00cedbf287834c6c148e70b44771759c6b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 6 Aug 2019 03:21:58 -0700 Subject: [PATCH 197/636] Cleanup ButtonPressAnimation --- ios/Podfile.lock | 38 +++++ src/components/coin-row/ExchangeCoinRow.js | 5 + src/screens/ExampleScreen.js | 5 + yarn.lock | 166 +++++++++++++++++++++ 4 files changed, 214 insertions(+) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 37adbc72606..2ff1004c0ad 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -243,6 +243,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= @@ -277,6 +278,8 @@ PODS: ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation - RNDeviceInfo (2.3.2): ======= - RNDeviceInfo (2.3.0): @@ -290,7 +293,13 @@ PODS: ======= - RNDeviceInfo (2.3.2): >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + - RNDeviceInfo (2.3.2): +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation - React - RNIOS11DeviceCheck (0.0.3): - React @@ -308,6 +317,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -333,6 +343,8 @@ PODS: >>>>>>> 64f1594b... rebase cleanup ======= >>>>>>> a7347f4b... podfile lock for text input mask +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation - SDWebImage (5.1.0): - SDWebImage/Core (= 5.1.0) - SDWebImage/Core (5.1.0) @@ -359,11 +371,19 @@ PODS: - SDWebImage (5.0.2): - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) +<<<<<<< HEAD <<<<<<< HEAD - yoga (0.60.4.React) >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup ======= +======= +======= + - SDWebImage (5.1.0): + - SDWebImage/Core (= 5.1.0) + - SDWebImage/Core (5.1.0) +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation - yoga (0.59.9.React) >>>>>>> a7347f4b... podfile lock for text input mask @@ -594,6 +614,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= @@ -628,6 +649,8 @@ SPEC CHECKSUMS: ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= RNDeviceInfo: 65106cc87ad6f6f71ef2ecc667f4c59b840888e2 @@ -641,7 +664,13 @@ SPEC CHECKSUMS: ======= RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 @@ -653,6 +682,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -670,6 +700,8 @@ SPEC CHECKSUMS: >>>>>>> 64f1594b... rebase cleanup ======= >>>>>>> a7347f4b... podfile lock for text input mask +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ======= SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 @@ -688,11 +720,17 @@ SPEC CHECKSUMS: ======= >>>>>>> bdd78363... podfile lock for text input mask SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 +<<<<<<< HEAD <<<<<<< HEAD yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup ======= +======= +======= + SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> a7347f4b... podfile lock for text input mask diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 6d981a197a7..c0c3d3f656a 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -86,6 +86,11 @@ export default class ExchangeCoinRow extends PureComponent { bottomRowRender={BottomRow} topRowRender={TopRow} > + {/* + TODO + XXX + + Is this View necessary?????*/} + // + // + // + // export default withHideSplashScreen(ExampleScreen); diff --git a/yarn.lock b/yarn.lock index 3cd2b17b5c1..dcb9bd1aab5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1309,6 +1309,7 @@ integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== ======= "@ethersproject/logger@>5.0.0-beta.0": +<<<<<<< HEAD <<<<<<< HEAD version "5.0.0-beta.128" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" @@ -1326,6 +1327,9 @@ >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ======= version "5.0.0-beta.128" +======= + version "5.0.0-beta.128" +>>>>>>> b1697d93... Cleanup ButtonPressAnimation resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== @@ -1333,7 +1337,10 @@ version "5.0.0-beta.130" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== +<<<<<<< HEAD >>>>>>> a3543960... rebase cleanup +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@ethersproject/logger" ">5.0.0-beta.0" @@ -1348,6 +1355,7 @@ "@ethersproject/strings@^5.0.0-beta.125": <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "5.0.0-beta.131" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" @@ -1361,6 +1369,8 @@ >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "5.0.0-beta.129" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== @@ -1374,6 +1384,11 @@ resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== >>>>>>> a3543960... rebase cleanup +======= + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" + integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@ethersproject/bytes" ">5.0.0-beta.0" "@ethersproject/constants" ">5.0.0-beta.0" @@ -1638,7 +1653,11 @@ ======= "@react-native-community/cli-platform-android@^2.7.0": <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> a7347f4b... podfile lock for text input mask +======= +<<<<<<< HEAD +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== @@ -1671,7 +1690,15 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== >>>>>>> bdd78363... podfile lock for text input mask +<<<<<<< HEAD >>>>>>> a7347f4b... podfile lock for text input mask +======= +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" + integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1737,6 +1764,7 @@ "@react-native-community/cli-platform-ios@^2.8.0": <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" @@ -1783,6 +1811,8 @@ ======= ======= >>>>>>> a7347f4b... podfile lock for text input mask +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== @@ -1806,26 +1836,37 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== >>>>>>> bdd78363... podfile lock for text input mask +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" + integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" xcode "^2.0.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD ======= >>>>>>> a3543960... rebase cleanup +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation "@react-native-community/cli-tools@^2.7.0", "@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= ======= >>>>>>> 64f1594b... rebase cleanup ======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= "@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" @@ -1856,7 +1897,12 @@ ======= ======= >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -2288,6 +2334,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -2327,6 +2374,8 @@ >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== @@ -2356,7 +2405,20 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "12.6.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" + integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== + +"@types/node@^10.3.2": + version "10.14.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" + integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation "@types/node@^8.0.7": <<<<<<< HEAD @@ -2481,6 +2543,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.35": version "1.0.0-beta.35" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" @@ -2512,6 +2575,8 @@ ======= >>>>>>> 64f1594b... rebase cleanup ======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= <<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.31": version "1.0.0-beta.31" @@ -2530,18 +2595,26 @@ lodash.clonedeepwith "^4.5.0" >>>>>>> a1921ad8... further sdk hookup +<<<<<<< HEAD >>>>>>> 9a1e3741... further sdk hookup +======= +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation "@walletconnect/core@^1.0.0-beta.32": version "1.0.0-beta.32" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD ======= >>>>>>> c851add0... further sdk hookup >>>>>>> a1921ad8... further sdk hookup ======= >>>>>>> a3543960... rebase cleanup +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@walletconnect/types" "^1.0.0-beta.32" "@walletconnect/utils" "^1.0.0-beta.32" @@ -3792,6 +3865,7 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" @@ -3823,7 +3897,15 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000988.tgz#742f35ec1b8b75b9628d705d7652eea1fef983db" integrity sha512-lPj3T8poYrRc/bniW5SQPND3GRtSrQdUM/R4mCYTbZxyi3jQiggLvZH4+BYUuX0t4TXjU+vMM7KFDQg+rSzZUQ== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "1.0.30000989" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" + integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation capture-exit@^1.2.0: version "1.2.0" @@ -4899,6 +4981,7 @@ ee-first@1.1.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" @@ -4917,11 +5000,16 @@ electron-to-chromium@^1.3.164: >>>>>>> 2216260a... Create Exchange related Input components ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation ejs@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" integrity sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q== +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation electron-to-chromium@^1.3.191: <<<<<<< HEAD @@ -5004,6 +5092,10 @@ electron-to-chromium@^1.3.188: >>>>>>> 55f47d2b... Begin orchestrating keyboard focus between swap modal views >>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views ======= +======= +<<<<<<< HEAD +electron-to-chromium@^1.3.191: +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "1.3.221" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.221.tgz#421a58ac8d1931c8df400d55c7f6fd621710da10" integrity sha512-YbNA7KgCvLq9ZaEa7wpYP7IP4LrJ4+b36oeF1lYBSJ0zVGVN7uo3Ct9qDUm/M3VDOWj03RVgsMFF8PdL8UjhzA== @@ -5059,7 +5151,16 @@ electron-to-chromium@^1.3.188: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.214.tgz#8b5b9a0415fd41b69c61f694007597cb8c8eb7e8" integrity sha512-SU9yyql6uA0Fc8bWR7sCYNGBtxkC+tQb6UaC7ReaadN42Kx7Ka+dzx3lAIm9Ock+ULEawJuTFcVB2x34uOCg0Q== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= +electron-to-chromium@^1.3.191: + version "1.3.215" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.215.tgz#c833cb31110c2e0a7dade1110648c2174f75233b" + integrity sha512-ZV3OnwF0FlIygwxAG2H92yt7WGjWBpawyFAFu8e9k7xJatY+BPowID0D0Bs3PMACYAJATEejw/I9cawO27ZvTg== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation elliptic@6.3.3: version "6.3.3" @@ -5152,6 +5253,7 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD entities@^2.0.0: @@ -5174,6 +5276,8 @@ envinfo@^5.7.0: ======= ======= >>>>>>> bdd78363... podfile lock for text input mask +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" @@ -6696,6 +6800,7 @@ i18next@^17.0.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -6718,6 +6823,8 @@ i18next@^17.0.3: ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "17.0.10" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== @@ -6734,7 +6841,15 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.8.tgz#0c7113a88ad156eb37b9025d83a7684e1bbc2e18" integrity sha512-oojOrqEPQzKo1HDMDDOl19zTM/EaDwBRPobUSD4kEjNoTi2oERvUbngK2lkIm9nOGddh55jbMGbm6fusMBeoKQ== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "17.0.9" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.9.tgz#5f835e91a34fa5e7da1e5ae4c4586c81d7c4b17f" + integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation dependencies: "@babel/runtime" "^7.3.1" @@ -10011,6 +10126,7 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: postcss-value-parser@^4.0.0: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" @@ -10025,6 +10141,16 @@ postcss-value-parser@^4.0.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== >>>>>>> 1d794746... Minor cleanup Header component +======= + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== +======= + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz#e3f6172cc91302912c89da55a42454025485250f" + integrity sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.7: version "7.0.18" @@ -10455,6 +10581,7 @@ react-native-device-info@^2.1.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" @@ -10504,6 +10631,8 @@ react-native-device-info@^2.1.3: ======= ======= >>>>>>> 64f1594b... rebase cleanup +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== @@ -10526,7 +10655,15 @@ react-native-device-info@^2.1.3: resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation react-native-dotenv@^0.2.0: version "0.2.0" @@ -10790,6 +10927,7 @@ react-native-svg@^9.5.1: ======= react-native-svg@^9.5.3: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "9.6.2" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" @@ -10810,7 +10948,15 @@ react-native-svg@^9.5.3: resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.1.tgz#4d2ba1e7ecd78d06603e8bf2fbc5072fc5852506" integrity sha512-X8WvZ5uNHyE+17Q4SSbdQZ1NsRyRxdvAFqipqDldL6D0oUB0pBI2tekx03N4taVtVN+p8Pg3T3SSmIxwXZmMYA== >>>>>>> bdd78363... podfile lock for text input mask +<<<<<<< HEAD >>>>>>> a7347f4b... podfile lock for text input mask +======= +======= + version "9.6.2" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" + integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -10846,10 +10992,14 @@ react-native-tcp@^3.2.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation react-native-text-input-mask@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== +<<<<<<< HEAD ======= react-native-text-input-mask@^1.0.1: <<<<<<< HEAD @@ -10874,6 +11024,8 @@ react-native-text-input-mask@1.0.4: resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== >>>>>>> bdd78363... podfile lock for text input mask +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation react-native-tooltip@^5.2.0: version "5.2.0" @@ -12963,6 +13115,7 @@ tslib@^1.8.1, tslib@^1.9.0: tsutils@^3.7.0: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -12978,6 +13131,8 @@ tsutils@^3.7.0: integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== >>>>>>> 1d794746... Minor cleanup Header component ======= +======= +>>>>>>> 908925bc... Cleanup ButtonPressAnimation version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== @@ -12986,7 +13141,15 @@ tsutils@^3.7.0: resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.15.0.tgz#3efabbf2c18a5d7c7496a878be0609eb90897ed6" integrity sha512-or184xKZ6fLE1SrDcvsOs3Wkfb1JgizdKs5Fiag3cp/m9k7C7GWd4E7gs3K5LHAePaIP7K62C20ZZI3JQx8iBQ== >>>>>>> a3543960... rebase cleanup +<<<<<<< HEAD >>>>>>> 64f1594b... rebase cleanup +======= +======= + version "3.17.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.0.tgz#c3ccab927a475aa2beef6a3695c2ff76da13cdf8" + integrity sha512-fyveWOtAXfumAxIqkcMHuPaaVyLBKjB8Y00ANZkqh+HITBAQscCbQIHwwBTJdvQq7RykLEbOPcUUnJ16X4NA0g== +>>>>>>> b1697d93... Cleanup ButtonPressAnimation +>>>>>>> 908925bc... Cleanup ButtonPressAnimation dependencies: tslib "^1.8.1" @@ -13614,6 +13777,7 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" +<<<<<<< HEAD xmldoc@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" @@ -13621,6 +13785,8 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" +======= +>>>>>>> b1697d93... Cleanup ButtonPressAnimation xmldom@0.1.x: version "0.1.27" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" From a2295d76969bd99ab24ee7c8529f7306fa8c795a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 13 Aug 2019 01:59:14 -0700 Subject: [PATCH 198/636] very work in progress --- ios/Podfile.lock | 56 ++- package.json | 2 +- src/components/asset-list/AssetList.js | 1 + src/components/asset-list/EmptyAssetList.js | 17 +- .../asset-list/RecyclerAssetList.js | 23 +- src/components/asset-list/index.js | 1 + src/components/coin-row/ExchangeCoinRow.js | 22 +- src/components/exchange/ExchangeAssetList.js | 92 +++++ src/components/exchange/ExchangeSearch.js | 5 + src/components/exchange/index.js | 1 + .../layout/KeyboardFixedOpenLayout.js | 2 +- src/components/send/SendAssetList.js | 10 +- src/helpers/buildWalletSections.js | 2 + src/hoc/withUniswapAssets.js | 21 +- src/screens/CurrencySelectModal.js | 126 +++--- src/screens/ExampleScreen.js | 5 - src/screens/ExchangeModal.js | 16 +- src/screens/Routes.js | 14 +- yarn.lock | 391 ++++++++++-------- 19 files changed, 507 insertions(+), 300 deletions(-) create mode 100644 src/components/exchange/ExchangeAssetList.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2ff1004c0ad..39911195799 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Analytics (3.6.10) + - Analytics (3.7.0) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React @@ -41,17 +41,24 @@ PODS: - glog - glog (0.3.5) <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> dca19a02... very work in progress - GoogleToolboxForMac/Defines (2.2.1) - GoogleToolboxForMac/Logger (2.2.1): - GoogleToolboxForMac/Defines (= 2.2.1) - "GoogleToolboxForMac/NSData+zlib (2.2.1)": - GoogleToolboxForMac/Defines (= 2.2.1) <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> dca19a02... very work in progress - libwebp (1.0.3): - libwebp/demux (= 1.0.3) - libwebp/mux (= 1.0.3) - libwebp/webp (= 1.0.3) - libwebp/demux (1.0.3): +<<<<<<< HEAD ======= ======= - GoogleToolboxForMac/Defines (2.2.0) @@ -71,6 +78,8 @@ PODS: - libwebp/webp (= 1.0.2) - libwebp/core (1.0.2): >>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> dca19a02... very work in progress - libwebp/webp - libwebp/mux (1.0.3): - libwebp/demux @@ -81,6 +90,7 @@ PODS: - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - Protobuf (3.9.0) <<<<<<< HEAD @@ -187,6 +197,9 @@ PODS: >>>>>>> 64f1594b... rebase cleanup ======= - Protobuf (3.7.0) +======= + - Protobuf (3.9.0) +>>>>>>> dca19a02... very work in progress - React (0.59.9): - React/Core (= 0.59.9) >>>>>>> a7347f4b... podfile lock for text input mask @@ -235,7 +248,6 @@ PODS: - React - RNCAsyncStorage (1.5.0): - React -<<<<<<< HEAD - RNCMaskedView (0.1.1): - React <<<<<<< HEAD @@ -244,6 +256,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - RNDeviceInfo (2.3.2): ======= @@ -300,6 +313,9 @@ PODS: - RNDeviceInfo (2.3.2): >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + - RNDeviceInfo (2.3.2): +>>>>>>> dca19a02... very work in progress - React - RNIOS11DeviceCheck (0.0.3): - React @@ -309,7 +325,6 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React -<<<<<<< HEAD - RNStoreReview (0.1.5): - React <<<<<<< HEAD @@ -318,6 +333,7 @@ PODS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -384,6 +400,11 @@ PODS: - SDWebImage/Core (5.1.0) >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + - SDWebImage (5.1.0): + - SDWebImage/Core (= 5.1.0) + - SDWebImage/Core (5.1.0) +>>>>>>> dca19a02... very work in progress - yoga (0.59.9.React) >>>>>>> a7347f4b... podfile lock for text input mask @@ -524,17 +545,17 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 + Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 - FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d - FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 - FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 - FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 + Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa + FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 + FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 + FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 + FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 <<<<<<< HEAD <<<<<<< HEAD @@ -571,6 +592,7 @@ SPEC CHECKSUMS: ======= Folly: de497beb10f102453a1afa9edbf8cf8a251890de glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d +<<<<<<< HEAD >>>>>>> a7347f4b... podfile lock for text input mask GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 @@ -588,6 +610,12 @@ SPEC CHECKSUMS: >>>>>>> 3291cb84... rebase cleanup >>>>>>> 64f1594b... rebase cleanup ======= +======= + GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 + libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a +>>>>>>> dca19a02... very work in progress React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f >>>>>>> a7347f4b... podfile lock for text input mask react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c @@ -607,7 +635,6 @@ SPEC CHECKSUMS: React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 -<<<<<<< HEAD RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 <<<<<<< HEAD <<<<<<< HEAD @@ -615,6 +642,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ======= @@ -671,11 +699,13 @@ SPEC CHECKSUMS: RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 +>>>>>>> dca19a02... very work in progress RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 -<<<<<<< HEAD RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 <<<<<<< HEAD <<<<<<< HEAD @@ -683,6 +713,7 @@ SPEC CHECKSUMS: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -731,6 +762,9 @@ SPEC CHECKSUMS: SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f +>>>>>>> dca19a02... very work in progress yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> a7347f4b... podfile lock for text input mask diff --git a/package.json b/package.json index 2614a4f1ff9..b4c9fe5702c 100644 --- a/package.json +++ b/package.json @@ -242,4 +242,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file diff --git a/src/components/asset-list/AssetList.js b/src/components/asset-list/AssetList.js index a2f1f3a22aa..2fa4bc73bf7 100644 --- a/src/components/asset-list/AssetList.js +++ b/src/components/asset-list/AssetList.js @@ -25,6 +25,7 @@ const AssetList = ({ ? ( ) : ( diff --git a/src/components/asset-list/EmptyAssetList.js b/src/components/asset-list/EmptyAssetList.js index 0c10cf0138e..70802b6d412 100644 --- a/src/components/asset-list/EmptyAssetList.js +++ b/src/components/asset-list/EmptyAssetList.js @@ -21,12 +21,17 @@ const renderSkeleton = (index, isWalletEthZero) => ( /> ); -const EmptyAssetList = ({ isWalletEthZero, ...props }) => ( +const EmptyAssetList = ({ + hideHeader, + isWalletEthZero, + skeletonCount, + ...props +}) => ( - + {hideHeader && } - {times(5, index => renderSkeleton(index, isWalletEthZero))} + {times(skeletonCount, index => renderSkeleton(index, isWalletEthZero))} {isWalletEthZero && ()} @@ -34,7 +39,13 @@ const EmptyAssetList = ({ isWalletEthZero, ...props }) => ( ); EmptyAssetList.propTypes = { + hideHeader: PropTypes.bool, isWalletEthZero: PropTypes.bool, + skeletonCount: PropTypes.number, +}; + +EmptyAssetList.defaultProps = { + skeletonCount: 5, }; export default withNeverRerender(EmptyAssetList); diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 1a6d6297a19..ac58d70a442 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -156,6 +156,7 @@ class RecyclerAssetList extends Component { dataProvider: new DataProvider(hasRowChanged, this.getStableId), headersIndices: [], isRefreshing: false, + itemsCount: 0, }; this.layoutProvider = new LayoutProvider( @@ -169,7 +170,7 @@ class RecyclerAssetList extends Component { return ViewTypes.HEADER; } - if (index === this.state.length - 1) { + if (index === this.state.itemsCount - 1) { return ViewTypes.FOOTER; } @@ -212,7 +213,7 @@ class RecyclerAssetList extends Component { return { get: ViewTypes.UNIQUE_TOKEN_ROW, isFirst: index === headersIndices[collectiblesIndex] + 1, - isLast: index === this.state.length - 2, + isLast: index === this.state.itemsCount - 2, rowCount: get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`, []).length, }; } @@ -220,7 +221,7 @@ class RecyclerAssetList extends Component { return { get: ViewTypes.UNIQUE_TOKEN_ROW_CLOSED, isFirst: index === headersIndices[collectiblesIndex] + 1, - isLast: index === this.state.length - 2, + isLast: index === this.state.itemsCount - 2, }; } } @@ -305,7 +306,7 @@ class RecyclerAssetList extends Component { areSmallCollectibles, dataProvider: state.dataProvider.cloneWithRows(items), headersIndices, - length: items.length, + itemsCount: items.length, }; } @@ -612,7 +613,13 @@ class RecyclerAssetList extends Component { }; render() { - const { hideHeader, renderAheadOffset, ...props } = this.props; + const { + externalScrollView, + fetchData, + hideHeader, + renderAheadOffset, + ...props + } = this.props; const { dataProvider, headersIndices } = this.state; return ( @@ -621,9 +628,9 @@ class RecyclerAssetList extends Component { ( - isNewValueForPath(this.props, nextProps, 'item.uniqueId') + isNewValueForPath(this.props, nextProps, 'uniqueId') || isNewValueForPath(this.state, nextState, 'favorite') || isNewValueForPath(this.state, nextState, 'emojiCount') ) @@ -74,9 +75,12 @@ export default class ExchangeCoinRow extends PureComponent { const { item, ...props } = this.props; const { emojiCount, favorite } = this.state; + // console.log('this.props', this.props); + return ( @@ -86,11 +90,13 @@ export default class ExchangeCoinRow extends PureComponent { bottomRowRender={BottomRow} topRowRender={TopRow} > - {/* - TODO - XXX - - Is this View necessary?????*/} + { + /* + TODO + XXX + Is this View necessary????? + */ + } isNewValueForPath(r1, r2, 'uniqueId') + +export default class ExchangeAssetList extends PureComponent { + static propTypes = { + items: PropTypes.arrayOf(PropTypes.object), + itemsCount: PropTypes.number, + renderItem: PropTypes.func, + } + + constructor(props) { + super(props); + + this.state = { + dataProvider: new DataProvider(hasRowChanged, this.getStableId), + } + + this.layoutProvider = new LayoutProvider((index) => { + return ViewTypes.COIN_ROW; + }, (type, dim) => { + if (type === ViewTypes.COIN_ROW) { + dim.width = deviceUtils.dimensions.width; + dim.height = CoinRow.height; + } else { + dim.width = 0; + dim.height = 0; + } + }) + } + + componentDidMount = () => { + this.updateList(); + } + + componentDidUpdate = (prevProps, prevState) => { + if (this.props.items !== prevProps.items) { + this.updateList(); + } + } + + updateList = () => { + this.setState((prevState) => ({ + dataProvider: prevState.dataProvider.cloneWithRows(this.props.items), + })) + } + + getStableId = (index) => get(this.state, `dataProvider._data[${index}].uniqueId`) + + renderRow = (type, data) => this.props.renderItem(data) + + render = () => { + const { isEmpty, items, ...props } = this.props; + const { dataProvider } = this.state; + + console.log('dataProvider', dataProvider); + + return ( + + ); + }; +} diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 54789d78372..7c91e712173 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -37,6 +37,8 @@ class ExchangeSearch extends PureComponent { } } + // + // autoCapitalize="words" render = () => { return ( ; - balancesRenderLastItem = item => { - return <> + balancesRenderLastItem = item => ( + - ; - }; + + ); collectiblesRenderItem = item => { return diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index 3ee586262fb..18dcf5cad11 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -84,6 +84,8 @@ const buildWalletSections = ( const isEmpty = !filteredSections.length; setIsWalletEmpty(isEmpty); + // console.log('filteredSections', filteredSections) + return { isEmpty, sections: filteredSections, diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 19b9c073f6e..edaf0ee29ab 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -1,13 +1,16 @@ -import { mapValues, sortBy, values } from 'lodash'; +import { + mapValues, + sortBy, + property, + values, +} from 'lodash'; import { compose, withProps } from 'recompact'; -import uniswapAssets from '../references/uniswap-pairs.json'; +import uniswapAssetsRaw from '../references/uniswap-pairs.json'; -const sortUniswapAssetsByName = () => { - const assetList = values(mapValues(uniswapAssets, (asset, address) => ({ ...asset, address }))); - return sortBy(assetList, asset => asset.name); -} +const mapUniswapAssetItem = (asset, address) => ({ ...asset, address }); -export default Component => compose( - withProps({ sortedUniswapAssets: sortUniswapAssetsByName() }), -)(Component); +const uniswapAssets = values(mapValues(uniswapAssetsRaw, mapUniswapAssetItem)); +const sortedUniswapAssets = sortBy(uniswapAssets, property('name')); + +export default withProps({ sortedUniswapAssets }); diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index fc7f1f3d805..aea54d8a581 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,34 +1,33 @@ import { - filter, - findIndex, get, - isEmpty, - keys, - map, } from 'lodash'; import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import { compose, withHandlers } from 'recompact'; -import { InteractionManager, KeyboardAvoidingView, View } from 'react-native' +import React, { Component, PureComponent } from 'react'; +import { compose } from 'recompact'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; +import { ReText } from 'react-native-redash'; import Animated from 'react-native-reanimated'; import styled from 'styled-components/primitives'; -import { Centered, Column, FlexItem, KeyboardFixedOpenLayout, Row } from '../components/layout'; -import { deviceUtils, safeAreaInsetValues } from '../utils'; -import { Modal, ModalHeader } from '../components/modal'; -import { RecyclerAssetList } from '../components/asset-list'; -import { ExchangeCoinRow, SendCoinRow } from '../components/coin-row'; +import { + Centered, + Column, + FlexItem, + KeyboardFixedOpenLayout, + Row, +} from '../components/layout'; +import { safeAreaInsetValues } from '../utils'; +import { Modal } from '../components/modal'; +import { ExchangeCoinRow } from '../components/coin-row'; import GestureBlocker from '../components/GestureBlocker'; -import { Monospace, TruncatedText } from '../components/text'; +import { TruncatedText } from '../components/text'; import { - withAccountData, withKeyboardFocusHistory, withTransitionProps, - withUniswapAssets, } from '../hoc'; import { borders, colors, position } from '../styles'; +import { EmptyAssetList } from '../components/asset-list'; import { BackButton } from '../components/header'; -import { ExchangeSearch } from '../components/exchange'; +import { ExchangeAssetList, ExchangeSearch } from '../components/exchange'; import { filterList } from '../utils/search'; import { exchangeModalBorderRadius } from './ExchangeModal'; @@ -47,23 +46,27 @@ const BackButtonWrapper = styled(Centered)` position: absolute; `; -class CurrencySelectModal extends PureComponent { +const appendAssetWithSearchableKey = (asset) => ({ + ...asset, + uniqueId: `${asset.name} ${asset.symbol}`, +}); + +class CurrencySelectModal extends PureComponent { //Component { static propTypes = { navigation: PropTypes.object, } state = { + assets: [], searchResults: [], } - assets = [] + headerTitle = 'Receive' - callback = null - - isInputAssets = true + position = undefined onChangeSearchText = (searchPhrase) => { - const searchResults = filterList(this.assets, searchPhrase, 'index'); + const searchResults = filterList(this.state.assets, searchPhrase, 'uniqueId'); this.setState({ searchResults }); } @@ -77,6 +80,7 @@ class CurrencySelectModal extends PureComponent { const { isFocused, keyboardFocusHistory, + navigation, transitionProps: { isTransitioning }, } = this.props; @@ -86,17 +90,29 @@ class CurrencySelectModal extends PureComponent { this.searchInputRef.current.focus(); } - this.callback = navigation.getParam('onSelectCurrency'); - this.isInputAssets = navigation.getParam('isInputAssets'); - this.getDataFromParams(); } getDataFromParams = () => { const { navigation } = this.props; - this.callback = navigation.getParam('onSelectCurrency'); - const indexedAssets = map(navigation.getParam('assets', []), asset => ({ ...asset, index: `${asset.name} ${asset.symbol}` })); - this.assets = indexedAssets; + // this.callback = ; + + this.headerTitle = navigation.getParam('headerTitle'); + // console.log('nav get params', navigation.getScreenProps()); + // console.log('nav get params', navigation); + + // console.log('getDataFromParams -- assets --', assets); + + if (!this.state.assets.length) { + const thing = navigation.getParam('assets', []).map(appendAssetWithSearchableKey); + // console.log('assets',assets ); + // console.log('THIGN', thing); + // console.log('this.state.assets', this.state.assets); + if (!!thing.length) { + // console.log('THE THING,,,,,, its happening') + this.setState({ assets: thing }); + } + } } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { @@ -111,17 +127,21 @@ class CurrencySelectModal extends PureComponent { handlePressBack = () => this.props.navigation.navigate('MainExchangeScreen') handleSelectAsset = (symbol) => { + const { navigation } = this.props; // It's a bit weird and I'm not sure why on invoking // navigation.getParam('onSelectCurrency')(symbol) // but this small hack seems to be a legit workaround - this.callback(symbol); - this.props.navigation.navigate('MainExchangeScreen'); + const onSelectCurrency = navigation.getParam('onSelectCurrency'); + onSelectCurrency(symbol); + navigation.navigate('MainExchangeScreen'); } - renderCurrencyItem = (itemProps) => ( + // {...itemProps} + renderCurrencyItem = (item) => ( ) @@ -129,23 +149,16 @@ class CurrencySelectModal extends PureComponent { this.props.pushKeyboardFocusHistory(currentTarget); } - getSections = () => { - const data = (this.state.searchResults) ? this.assets : this.state.searchResults; - return [{ - balances: true, - data, - renderItem: this.renderCurrencyItem, - }]; - } - - - render() { + render = () => { const { allAssets, navigation, transitionProps: { isTransitioning }, } = this.props; + const { assets, searchResults } = this.state; + const items = searchResults.length ? searchResults : assets; + return ( - Receive + {this.headerTitle} - + {(items.length === 0) ? ( + + ) : ( + + )} + @@ -210,6 +226,14 @@ class CurrencySelectModal extends PureComponent { } } + + + // + // + // flex={0} + // style={{ backgroundColor: 'blue', height: 400 }} + // paddingBottom={100} + // height={400} export default compose( withNavigationFocus, withTransitionProps, diff --git a/src/screens/ExampleScreen.js b/src/screens/ExampleScreen.js index 237df477443..b996b72bf7d 100644 --- a/src/screens/ExampleScreen.js +++ b/src/screens/ExampleScreen.js @@ -59,9 +59,4 @@ class ExampleScreen extends PureComponent { ) } - // - // - // - // - // export default withHideSplashScreen(ExampleScreen); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 1f1f854a6a4..b2f7139fb8f 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -18,7 +18,7 @@ import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; -import { NavigationEvents, withNavigationFocus } from 'react-navigation'; +import { NavigationActions, NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, toClass, withProps } from 'recompact'; import { executeSwap } from '../handlers/uniswap'; import { @@ -261,7 +261,7 @@ class ExchangeModal extends PureComponent { getAssetsAvailableOnUniswap = () => { const uniswapAssetAddresses = map(keys(uniswapAssets), address => address.toLowerCase()); return filter(this.props.allAssets, asset => findIndex(uniswapAssetAddresses, uniswapAddress => uniswapAddress === asset.address) > -1); - }; + } onPressMaxBalance = () => { const { inputCurrency } = this.state; @@ -273,7 +273,7 @@ class ExchangeModal extends PureComponent { handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { assets: this.getAssetsAvailableOnUniswap(), - isInputAssets: true, + headerTitle: 'Swap', onSelectCurrency: this.setInputCurrency, }); } @@ -281,7 +281,7 @@ class ExchangeModal extends PureComponent { handleSelectOutputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { assets: this.props.sortedUniswapAssets, - isInputAssets: false, + headerTitle: 'Receive', onSelectCurrency: this.setOutputCurrency, }); } @@ -438,10 +438,10 @@ export default compose( withAccountData, withAccountSettings, withBlockedHorizontalSwipe, - withTransactionConfirmationScreen, - withUniswapAssets, - withNavigationFocus, - withMockedPrices, withKeyboardFocusHistory, + withMockedPrices, + withNavigationFocus, + withTransactionConfirmationScreen, withTransitionProps, + withUniswapAssets, )(ExchangeModal); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 831e2308ff2..cb8f05bcb42 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -73,17 +73,17 @@ const SwipeStack = createMaterialTopTabNavigator({ const ExchangeModalTabPosition = new Animated.Value(0); const ExchangeModalNavigator = newTopTabNavigator({ - CurrencySelectScreen: { + MainExchangeScreen: { params: { position: ExchangeModalTabPosition, }, - screen: CurrencySelectModal, + screen: ExchangeModal, }, - MainExchangeScreen: { + CurrencySelectScreen: { params: { position: ExchangeModalTabPosition, }, - screen: ExchangeModal, + screen: CurrencySelectModal, }, }, { disableKeyboardHandling: true, @@ -91,9 +91,9 @@ const ExchangeModalNavigator = newTopTabNavigator({ initialLayout: deviceUtils.dimensions, keyboardDismissMode: 'none', keyboardShouldPersistTaps: 'always', - onSwipeStart: onTransitionStart, - onSwipeEnd: onTransitionEnd, mode: 'modal', + // onSwipeEnd: onTransitionEnd, + // onSwipeStart: onTransitionStart, onTransitionEnd, onTransitionStart, position: ExchangeModalTabPosition, @@ -114,7 +114,7 @@ const ExchangeModalNavigator = newTopTabNavigator({ // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = React.memo(props => ); +const EnhancedExchangeModalNavigator = props => ;//React.memo(); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ ...navigation.state.params, diff --git a/yarn.lock b/yarn.lock index dcb9bd1aab5..30642a98ed9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13,6 +13,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" @@ -35,6 +36,9 @@ ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": +>>>>>>> dca19a02... very work in progress version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== @@ -99,6 +103,7 @@ semver "^5.4.1" source-map "^0.5.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD ======= @@ -139,6 +144,8 @@ ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> dca19a02... very work in progress "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" @@ -923,6 +930,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" @@ -943,14 +951,9 @@ integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== <<<<<<< HEAD ======= -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": ======= -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 034f7aa3... Create Exchange related Input components -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +>>>>>>> dca19a02... very work in progress +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== @@ -1004,6 +1007,7 @@ "@babel/parser" "^7.4.4" "@babel/types" "^7.4.4" +<<<<<<< HEAD <<<<<<< HEAD ======= >>>>>>> 2216260a... Create Exchange related Input components @@ -1045,6 +1049,8 @@ ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> dca19a02... very work in progress "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" @@ -1091,6 +1097,7 @@ globals "^11.1.0" lodash "^4.17.13" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD ======= @@ -1127,6 +1134,8 @@ ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> dca19a02... very work in progress "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" @@ -1309,38 +1318,14 @@ integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== ======= "@ethersproject/logger@>5.0.0-beta.0": -<<<<<<< HEAD -<<<<<<< HEAD version "5.0.0-beta.128" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== "@ethersproject/properties@>5.0.0-beta.0": -<<<<<<< HEAD version "5.0.0-beta.130" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== -======= - version "5.0.0-beta.128" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.128.tgz#26e8a4cb95f0d048531f0a8da39773b16b4633b4" - integrity sha512-4ABgX2WmpQLlmbyR6EwxoT5YTRYxV6fGRtK+1nt48dvG2Y8FSkg33JvCfei3w432RjEEHEN5IOmTf+nTr9n6VA== ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -======= - version "5.0.0-beta.128" -======= - version "5.0.0-beta.128" ->>>>>>> b1697d93... Cleanup ButtonPressAnimation - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" - integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== - -"@ethersproject/properties@>5.0.0-beta.0": - version "5.0.0-beta.130" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" - integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== -<<<<<<< HEAD ->>>>>>> a3543960... rebase cleanup -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@ethersproject/logger" ">5.0.0-beta.0" @@ -1356,6 +1341,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "5.0.0-beta.131" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" @@ -1380,15 +1366,11 @@ integrity sha512-FKQDBKgcX7Bc0J45TIwwT4PTnE1TvtDRka3dAkH1VX4odnj6DzpZ99QdkhX4mBL2J+6/XK+trA7m/HTDx+5YqA== >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ======= - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" - integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== ->>>>>>> a3543960... rebase cleanup ======= +>>>>>>> dca19a02... very work in progress version "5.0.0-beta.129" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@ethersproject/bytes" ">5.0.0-beta.0" "@ethersproject/constants" ">5.0.0-beta.0" @@ -1406,6 +1388,7 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x": +<<<<<<< HEAD <<<<<<< HEAD version "8.2.4" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020" @@ -1415,6 +1398,11 @@ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.0.tgz#079a133be240ff866ad8532eaa46a691bdd91117" integrity sha512-pR2ZgiP562aiaQvQ98WgfqfTrm+xG+7hwHRPEiYZ+7U1OHAAb4OVZJIalCP03bMqYSioQzflzVTVrybSwDBn1Q== >>>>>>> 1d794746... Minor cleanup Header component +======= + version "8.2.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.1.tgz#924af04cbb22e17359c620d2a9c946e63f58eb77" + integrity sha512-JPiBy+oSmsq3St7XlipfN5pNA6bDJ1kpa73PrK/zR29CVClDVqy04AanM/M/qx5bSF+I61DdCfAvRrujau+zRg== +>>>>>>> dca19a02... very work in progress "@hapi/joi@^15.0.3": version "15.1.1" @@ -1644,6 +1632,7 @@ >>>>>>> 2216260a... Create Exchange related Input components "@react-native-community/cli-platform-android@^2.7.0": <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 96db5a28... begin mike version "2.7.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" @@ -1699,6 +1688,11 @@ integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" + integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== +>>>>>>> dca19a02... very work in progress dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1765,6 +1759,7 @@ "@react-native-community/cli-platform-ios@^2.8.0": <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.8.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" @@ -1832,27 +1827,16 @@ >>>>>>> 3291cb84... rebase cleanup >>>>>>> a3543960... rebase cleanup ======= - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" - integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== ->>>>>>> bdd78363... podfile lock for text input mask ======= +>>>>>>> dca19a02... very work in progress version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" xcode "^2.0.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> a3543960... rebase cleanup -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation "@react-native-community/cli-tools@^2.7.0", "@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" @@ -1860,6 +1844,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= ======= @@ -1903,6 +1888,8 @@ ======= >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress dependencies: chalk "^2.4.2" lodash "^4.17.5" @@ -2335,6 +2322,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -2376,23 +2364,18 @@ >>>>>>> 64f1594b... rebase cleanup ======= >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== -======= -<<<<<<< HEAD -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch - version "12.6.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" - integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== ->>>>>>> 034f7aa3... Create Exchange related Input components "@types/node@^10.3.2": version "10.14.15" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g== <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 1d794746... Minor cleanup Header component ======= ======= @@ -2419,6 +2402,8 @@ integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress "@types/node@^8.0.7": <<<<<<< HEAD @@ -2544,6 +2529,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.35": version "1.0.0-beta.35" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" @@ -2585,15 +2571,18 @@ ======= ======= >>>>>>> a3543960... rebase cleanup +======= +>>>>>>> dca19a02... very work in progress "@uniswap/sdk@^1.0.0-beta.3": - version "1.0.0-beta.3" - resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-1.0.0-beta.3.tgz#a8229136cb5b1bb4900b6540e0ab1fc6c17c0a82" - integrity sha512-JfA/xGwTQt3c3p8Aznc7LFHYZkzYCXuPsv2dwPSV8U4PiN103CQ2euK9xh4x8aN2F2MXb7MeoYXTfXU0fbtkCg== + version "1.0.0-beta.4" + resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-1.0.0-beta.4.tgz#d14a0ddc15e8de9173f3d97075e7ebbaa2570f1a" + integrity sha512-a2GnlZrmg0Qxr4HFIBPCKygLFxu5f/hhIOKYVm12hG8vzsCVh72DEqZkpaOSFH3o6LDez4p2KnPvmwZkWVUnRg== dependencies: bignumber.js "^9.0.0" ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" +<<<<<<< HEAD >>>>>>> a1921ad8... further sdk hookup <<<<<<< HEAD >>>>>>> 9a1e3741... further sdk hookup @@ -2601,20 +2590,12 @@ ======= >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress "@walletconnect/core@^1.0.0-beta.32": version "1.0.0-beta.32" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> c851add0... further sdk hookup ->>>>>>> a1921ad8... further sdk hookup -======= ->>>>>>> a3543960... rebase cleanup -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation dependencies: "@walletconnect/types" "^1.0.0-beta.32" "@walletconnect/utils" "^1.0.0-beta.32" @@ -2741,6 +2722,7 @@ acorn@^6.0.1, acorn@^6.0.7: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" @@ -2771,6 +2753,11 @@ acorn@^6.0.1, acorn@^6.0.7: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= + version "6.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" + integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== +>>>>>>> dca19a02... very work in progress aes-js@3.0.0: version "3.0.0" @@ -2845,11 +2832,18 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-escapes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" + integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== + dependencies: + type-fest "^0.5.2" + ansi-fragments@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansi-fragments/-/ansi-fragments-0.2.1.tgz#24409c56c4cc37817c3d7caa99d8969e2de5a05e" @@ -3250,6 +3244,7 @@ babel-plugin-rewire@^1.2.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ======= <<<<<<< HEAD @@ -3288,6 +3283,9 @@ babel-plugin-rewire@^1.2.0: "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: +>>>>>>> dca19a02... very work in progress version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -3686,9 +3684,15 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: +<<<<<<< HEAD version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== +======= + version "5.3.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.3.0.tgz#5f9fa5fefe3939888d0fdbf7d964e2a8531fd69c" + integrity sha512-XykNc84nIOC32vZ9euOKbmGAP69JUkXDtBQfLq88c8/6J/gZi/t14A+l/p/9EM2TcT5xNC1MKPCrvO3LVUpVPw== +>>>>>>> dca19a02... very work in progress dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -3863,13 +3867,10 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +<<<<<<< HEAD ======= version "1.0.30000985" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f" @@ -3906,6 +3907,8 @@ caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress capture-exit@^1.2.0: version "1.2.0" @@ -4058,6 +4061,13 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + cli-spinners@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" @@ -4387,9 +4397,9 @@ core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1: <<<<<<< HEAD ======= core-js@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.0.tgz#0a835fdf6aa677fff83a823a7b5276c9e7cebb76" - integrity sha512-gybgLzmr7SQRSF6UzGYXducx4eE10ONQlyEnQoqiGPbmbn7zLkb73tPfc4YbZN0lvcTQwoLNPjq4RuCaCumGyQ== + version "3.2.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09" + integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw== >>>>>>> 1d794746... Minor cleanup Header component core-util-is@1.0.2, core-util-is@~1.0.0: @@ -4982,6 +4992,7 @@ ee-first@1.1.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.258" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" @@ -5004,11 +5015,14 @@ electron-to-chromium@^1.3.164: ======= >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress ejs@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" integrity sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q== +<<<<<<< HEAD <<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation electron-to-chromium@^1.3.191: @@ -5161,6 +5175,12 @@ electron-to-chromium@^1.3.191: integrity sha512-ZV3OnwF0FlIygwxAG2H92yt7WGjWBpawyFAFu8e9k7xJatY+BPowID0D0Bs3PMACYAJATEejw/I9cawO27ZvTg== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +electron-to-chromium@^1.3.191: + version "1.3.225" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.225.tgz#c6786475b5eb5f491ade01a78b82ba2c5bfdf72b" + integrity sha512-7W/L3jw7HYE+tUPbcVOGBmnSrlUmyZ/Uyg24QS7Vx0a9KodtNrN0r0Q/LyGHrcYMtw2rv7E49F/vTXwlV/fuaA== +>>>>>>> dca19a02... very work in progress elliptic@6.3.3: version "6.3.3" @@ -5256,6 +5276,7 @@ entities@^1.1.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" @@ -5278,6 +5299,8 @@ envinfo@^5.7.0: >>>>>>> bdd78363... podfile lock for text input mask ======= >>>>>>> b1697d93... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" @@ -6030,6 +6053,13 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +figures@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" + integrity sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" @@ -6713,6 +6743,7 @@ hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.1.0, hoist-non-react- react-is "^16.7.0" hosted-git-info@^2.1.4: +<<<<<<< HEAD <<<<<<< HEAD version "2.8.4" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" @@ -6724,6 +6755,11 @@ hosted-git-info@^2.1.4: dependencies: lru-cache "^5.1.1" >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "2.8.4" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" + integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== +>>>>>>> dca19a02... very work in progress html-encoding-sniffer@^1.0.2: version "1.0.2" @@ -6801,6 +6837,7 @@ i18next@^17.0.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -6850,6 +6887,11 @@ i18next@^17.0.3: integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + version "17.0.11" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.11.tgz#36424dc01f6de391fae87878d24f5ff713565c27" + integrity sha512-O+yzoNi0usYcd4oi85EFY4WuwZ8NNsYJLauZ629YSjwgIi2D7eYDSQxy6aAR67V++b//GNuZEk7hx/i3L9Rxag== +>>>>>>> dca19a02... very work in progress dependencies: "@babel/runtime" "^7.3.1" @@ -7046,22 +7088,28 @@ inquirer@^6.2.2: integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== ======= inquirer@^6.4.1: +<<<<<<< HEAD version "6.5.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== >>>>>>> 96db5a28... begin mike +======= + version "6.5.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.1.tgz#8bfb7a5ac02dac6ff641ac4c5ff17da112fcdb42" + integrity sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw== +>>>>>>> dca19a02... very work in progress dependencies: - ansi-escapes "^3.2.0" + ansi-escapes "^4.2.1" chalk "^2.4.2" - cli-cursor "^2.1.0" + cli-cursor "^3.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" run-async "^2.2.0" rxjs "^6.4.0" - string-width "^2.1.0" + string-width "^4.1.0" strip-ansi "^5.1.0" through "^2.3.6" @@ -8268,31 +8316,10 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -<<<<<<< HEAD -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: -======= -<<<<<<< HEAD -<<<<<<< HEAD -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: -======= -<<<<<<< HEAD -======= ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: ->>>>>>> d743296d... BREAK UP ->>>>>>> 034f7aa3... Create Exchange related Input components +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -<<<<<<< HEAD -======= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== ->>>>>>> 8d2e8d2f... BREAK UP -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" @@ -8350,13 +8377,6 @@ lru-cache@^4.0.1, lru-cache@^4.1.2: pseudomap "^1.0.2" yallist "^2.1.2" -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - ltgt@^2.1.3: version "2.2.1" resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" @@ -9053,6 +9073,11 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + mv@~2: version "2.1.1" resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" @@ -9208,6 +9233,7 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" +<<<<<<< HEAD <<<<<<< HEAD node-releases@^1.1.29: version "1.1.30" @@ -9219,6 +9245,12 @@ node-releases@^1.1.23: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.24.tgz#2fb494562705c01bfb81a7af9f8584c4d56311b4" integrity sha512-wym2jptfuKowMmkZsfCSTsn8qAVo8zm+UiQA6l5dNqUcpfChZSnS/vbbpOeXczf+VdPhutxh+99lWHhdd6xKzg== >>>>>>> 751dba29... Replace navigation animations with new effects +======= +node-releases@^1.1.25: + version "1.1.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.27.tgz#b19ec8add2afe9a826a99dceccc516104c1edaf4" + integrity sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA== +>>>>>>> dca19a02... very work in progress dependencies: semver "^5.3.0" @@ -9515,7 +9547,7 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -open@^6.2.0, open@^6.3.0: +open@^6.2.0, open@^6.3.0, open@^6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== @@ -10127,6 +10159,7 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: postcss-value-parser@^4.0.0: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" @@ -10151,6 +10184,11 @@ postcss-value-parser@^4.0.0: integrity sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== +>>>>>>> dca19a02... very work in progress postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.7: version "7.0.18" @@ -10448,6 +10486,7 @@ react-clone-referenced-element@^1.0.1: resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD ======= @@ -10477,6 +10516,9 @@ react-coin-icon@^0.1.9: react-coin-icon@^0.1.9: >>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch +======= +react-coin-icon@^0.1.9: +>>>>>>> dca19a02... very work in progress version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== @@ -10519,12 +10561,15 @@ react-native-actionsheet@^2.4.2: integrity sha512-DBoWIvVwuWXuptF4t46pBqkFxaUxS+rsIdHiA05t0n4BdTIDV2R4s9bLEUVOGzb94D7VxIamsXZPA/3mmw+SXg== react-native-bundle-visualizer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/react-native-bundle-visualizer/-/react-native-bundle-visualizer-2.0.1.tgz#8847d3c89356bc6db3d634481b6ae57e8eaec575" - integrity sha512-MPjpbD12lwat1snp1EKGipT1rHulihznGb8h1QGR9J1hUBkjcQYnvaqG8Cd/t6zJEZd17b8f5zak/a7AB5h9TA== + version "2.0.3" + resolved "https://registry.yarnpkg.com/react-native-bundle-visualizer/-/react-native-bundle-visualizer-2.0.3.tgz#9002feaa6058d524869c4d0d7fbada43b73fd234" + integrity sha512-iP0wHXnjQk0Yrt+dvNKcTKOAUhV+Cd12QendhITTwALnFu7kI2zZbcaVWMQcjFAnfR0GOQcsF9qAI6t61Mw13w== dependencies: + chalk "^2.4.2" execa "^2.0.3" minimist "^1.2.0" + open "^6.4.0" + rimraf "^2.6.3" source-map-explorer "^2.0.1" react-native-camera@^2.11.0: @@ -10582,6 +10627,7 @@ react-native-device-info@^2.1.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" @@ -10664,6 +10710,11 @@ react-native-device-info@^2.1.3: integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +>>>>>>> dca19a02... very work in progress react-native-dotenv@^0.2.0: version "0.2.0" @@ -10713,15 +10764,7 @@ react-native-gesture-handler@mikedemarais/react-native-gesture-handler#mike-hook invariant "^2.2.4" prop-types "^15.7.2" -<<<<<<< HEAD react-native-haptic-feedback@^1.8.2: -======= -react-native-haptic-feedback@^1.8.0: -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> d743296d... BREAK UP -======= ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.8.2" resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== @@ -10855,6 +10898,7 @@ react-native-reanimated@1.1.0: <<<<<<< HEAD react-native-safe-area-view@^0.14.1: +<<<<<<< HEAD >>>>>>> 751dba29... Replace navigation animations with new effects version "0.14.5" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.5.tgz#eeded66bbeb0807f0a7f5f449e7fb2871f7ecf76" @@ -10873,6 +10917,11 @@ react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: version "0.14.6" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA== +======= + version "0.14.7" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" + integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== +>>>>>>> dca19a02... very work in progress dependencies: hoist-non-react-statics "^2.3.1" @@ -10882,19 +10931,7 @@ react-native-safe-area-view@mikedemarais/react-native-safe-area-view: dependencies: hoist-non-react-statics "^2.3.1" -<<<<<<< HEAD -<<<<<<< HEAD "react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: -======= -<<<<<<< HEAD -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.22: -======= -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> d743296d... BREAK UP -======= -"react-native-screens@^1.0.0 || ^1.0.0-alpha", react-native-screens@^1.0.0-alpha.23: ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch version "1.0.0-alpha.23" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz#25d7ea4d11bda4fcde2d1da7ae50271c6aa636e0" integrity sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw== @@ -10926,13 +10963,11 @@ react-native-svg@^9.5.1: integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== ======= react-native-svg@^9.5.3: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "9.6.2" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> e1a27438... Cleanup ButtonPressAnimation ======= ======= @@ -10957,6 +10992,8 @@ react-native-svg@^9.5.3: integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= +>>>>>>> dca19a02... very work in progress react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -10989,43 +11026,10 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation react-native-text-input-mask@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== -<<<<<<< HEAD -======= -react-native-text-input-mask@^1.0.1: -<<<<<<< HEAD - version "1.0.1" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.1.tgz#93b4374c3c73bc78eac907094662d5d98166f359" - integrity sha512-gN0N+3tpw1kgHsuaqzugN7hc5XsjlyXET4/Q3C36F6LxwpIdnf3k9yCL4vfAlw6QxwuBTtyFaRxGJgwZkzk4Ng== ->>>>>>> 034f7aa3... Create Exchange related Input components -======= - version "1.0.4" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" - integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -======= -react-native-text-input-mask@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" - integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== ->>>>>>> a3543960... rebase cleanup -======= -react-native-text-input-mask@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.4.tgz#0fd644eaca9c9f29553841e15a3fc3a90a602552" - integrity sha512-RBXj84y/fgOt5rRl0XBLr3eGcNSEZhT/vug0I6Ysa7M1uByNRxDGZE6VRNXtzFkh4ZD9Ysov6MfChU3m8y0JIA== ->>>>>>> bdd78363... podfile lock for text input mask -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation react-native-tooltip@^5.2.0: version "5.2.0" @@ -11483,9 +11487,15 @@ regexpp@^2.0.1: integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^4.5.4: +<<<<<<< HEAD version "4.6.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== +======= + version "4.5.5" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.5.tgz#aaffe61c2af58269b3e516b61a73790376326411" + integrity sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ== +>>>>>>> dca19a02... very work in progress dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^8.1.0" @@ -11720,6 +11730,14 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -12596,6 +12614,7 @@ styled-components@4.3.1: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD styled-components@^5.0.0-beta.8: <<<<<<< HEAD version "5.0.0-beta.8-groupsizefix" @@ -12624,6 +12643,8 @@ styled-components@^5.0.0-beta.8: ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> dca19a02... very work in progress styled-components@5.0.0-beta.8: version "5.0.0-beta.8" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8.tgz#ad1e672589a891987f5492cbe3ca6f480fcd99dc" @@ -12631,6 +12652,7 @@ styled-components@5.0.0-beta.8: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 8d2e8d2f... BREAK UP >>>>>>> f7a61a13... Create Exchange related Input components ======= @@ -12647,6 +12669,8 @@ styled-components@5.0.0-beta.8: ======= >>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +>>>>>>> dca19a02... very work in progress dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -13116,6 +13140,7 @@ tsutils@^3.7.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -13150,6 +13175,11 @@ tsutils@^3.7.0: integrity sha512-fyveWOtAXfumAxIqkcMHuPaaVyLBKjB8Y00ANZkqh+HITBAQscCbQIHwwBTJdvQq7RykLEbOPcUUnJ16X4NA0g== >>>>>>> b1697d93... Cleanup ButtonPressAnimation >>>>>>> 908925bc... Cleanup ButtonPressAnimation +======= + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== +>>>>>>> dca19a02... very work in progress dependencies: tslib "^1.8.1" @@ -13182,6 +13212,11 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +type-fest@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -13777,16 +13812,6 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" -<<<<<<< HEAD -xmldoc@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" - integrity sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ== - dependencies: - sax "^1.2.1" - -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation xmldom@0.1.x: version "0.1.27" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" @@ -13850,7 +13875,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: +yallist@^3.0.0, yallist@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== From babb6b24a1c2d49e949793652081e2c175030b6e Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 13 Aug 2019 14:51:04 -0700 Subject: [PATCH 199/636] fix selection of currency item instead of just symbol --- src/components/coin-row/ExchangeCoinRow.js | 4 ++-- src/screens/CurrencySelectModal.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 52c27422ca1..0d6e771fe1a 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -54,10 +54,10 @@ export default class ExchangeCoinRow extends Component { ) handlePress = () => { - const { item: { symbol }, onPress } = this.props; + const { item, onPress } = this.props; if (onPress) { - onPress(symbol); + onPress(item); } } diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index aea54d8a581..bee910bb644 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -126,13 +126,13 @@ class CurrencySelectModal extends PureComponent { //Component { handlePressBack = () => this.props.navigation.navigate('MainExchangeScreen') - handleSelectAsset = (symbol) => { + handleSelectAsset = (item) => { const { navigation } = this.props; // It's a bit weird and I'm not sure why on invoking - // navigation.getParam('onSelectCurrency')(symbol) + // navigation.getParam('onSelectCurrency')(item) // but this small hack seems to be a legit workaround const onSelectCurrency = navigation.getParam('onSelectCurrency'); - onSelectCurrency(symbol); + onSelectCurrency(item); navigation.navigate('MainExchangeScreen'); } From 4059ef68473188239798a4cb72de3ab07531c30c Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 13 Aug 2019 17:41:47 -0700 Subject: [PATCH 200/636] add allowance check function with tests; fix approve function --- src/handlers/uniswap.js | 9 --------- src/utils/__tests__/contract.test.js | 29 ++++++++++++++++++++++++++++ src/utils/contract.js | 19 ++++++++++++++++++ src/utils/index.js | 1 + 4 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 src/utils/__tests__/contract.test.js create mode 100644 src/utils/contract.js diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index a41d2310772..dd88a61b08c 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -20,15 +20,6 @@ const convertValueForEthers = (value) => { return ethers.utils.hexlify(valueBigNumber); }; -// TODO save txn hash somewhere -export const approve = async (exchangeAddress) => { - const wallet = await loadWallet(); - if (!wallet) return null; - const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); - const gasLimit = await exchange.estimate.approve(exchangeAddress, ethers.constants.MaxUint256); - return exchange.approve(exchangeAddress, ethers.constants.MaxUint256, { gasLimit }); -}; - export const executeSwap = async (tradeDetails) => { const executionDetails = getExecutionDetails(tradeDetails); const wallet = await loadWallet(); diff --git a/src/utils/__tests__/contract.test.js b/src/utils/__tests__/contract.test.js new file mode 100644 index 00000000000..d321f091518 --- /dev/null +++ b/src/utils/__tests__/contract.test.js @@ -0,0 +1,29 @@ +import { greaterThan } from '../../helpers/utilities'; +import { getAllowance } from '../contract'; + +const accountAddress = '0x1492004547FF0eFd778CC2c14E794B26B4701105'; + +test('getAllowanceZrx', async () => { + const exchangeAddress = '0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF'; + const tokenAddress = '0xe41d2489571d322189246dafa5ebde1f4699f498'; + const allowance = await getAllowance(accountAddress, tokenAddress, exchangeAddress); + const result = greaterThan(allowance, 0); + expect(result).toBeTruthy(); +}); + +test('getAllowanceMkr', async () => { + const exchangeAddress = '0x2C4Bd064b998838076fa341A83d007FC2FA50957'; + const tokenAddress = '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2'; + const allowance = await getAllowance(accountAddress, tokenAddress, exchangeAddress); + const result = greaterThan(allowance, 0); + expect(result).toBeTruthy(); +}); + +test('getAllowanceBatNotApproved', async () => { + const exchangeAddress = '0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914'; + const tokenAddress = '0x0d8775f648430679a709e98d2b0cb6250d2887ef'; + const allowance = await getAllowance(accountAddress, tokenAddress, exchangeAddress); + const result = greaterThan(allowance, 0); + expect(result).toBeFalsy(); +}); + diff --git a/src/utils/contract.js b/src/utils/contract.js new file mode 100644 index 00000000000..4cbfeab3cc2 --- /dev/null +++ b/src/utils/contract.js @@ -0,0 +1,19 @@ +import { ethers } from 'ethers'; +import { web3Provider } from '../handlers/web3'; +import { loadWallet } from '../model/wallet'; +import erc20ABI from '../references/erc20-abi.json'; + +export const getAllowance = async (owner, tokenAddress, spender) => { + const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); + const allowance = await tokenContract.allowance(owner, spender); + return ethers.utils.bigNumberify(allowance.toString()); +}; + +export const approve = async (tokenAddress, spender) => { + const wallet = await loadWallet(); + if (!wallet) return null; + const exchange = new ethers.Contract(tokenAddress, erc20ABI, wallet); + const gasLimit = await exchange.estimate.approve(spender, ethers.constants.MaxUint256); + return exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); +}; + diff --git a/src/utils/index.js b/src/utils/index.js index 0840a93573d..5f6d3558274 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,5 +1,6 @@ export { default as abbreviations } from './abbreviations'; export { default as addressUtils } from './address'; +export { default as contractUtils } from './contract'; export { default as deviceUtils } from './deviceUtils'; export { default as dimensionsPropType } from './dimensionsPropType'; export { default as directionPropType } from './directionPropType'; From d7943a26fe3e020883c713e312527336a05b9e7c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 15 Aug 2019 03:19:21 -0700 Subject: [PATCH 201/636] create selectors for data in withUniswapAssets --- src/hoc/withUniswapAssets.js | 50 +++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index edaf0ee29ab..c810c34e41d 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -1,16 +1,54 @@ import { + filter, + keys, + map, mapValues, - sortBy, property, + sortBy, + toLower, values, } from 'lodash'; -import { compose, withProps } from 'recompact'; +import { compose, omitProps, withProps } from 'recompact'; +import { createSelector } from 'reselect'; import uniswapAssetsRaw from '../references/uniswap-pairs.json'; +import withAccountData from './withAccountData'; + +const allAssetsSelector = state => state.allAssets; +const unsortedUniswapAssetsSelector = state => state.unsortedUniswapAssets; + +const uniswapAssetAddresses = map(keys(uniswapAssetsRaw), toLower); +const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); +const withAssetsAvailableOnUniswap = (allAssets) => ({ + assetsAvailableOnUniswap: filter(allAssets, filterUniswapAssetsByAvailability), +}); + +const mapUniswapAssetItem = ({ exchange_address, ...asset }, address) => ({ + ...asset, + address, + exchange_address, + uniqueId: exchange_address, +}); + +const unsortedUniswapAssets = values(mapValues(uniswapAssetsRaw, mapUniswapAssetItem)); +const withSortedUniswapAssets = (unsortedUniswapAssets) => ({ + sortedUniswapAssets: sortBy(unsortedUniswapAssets, property('name')), +}); -const mapUniswapAssetItem = (asset, address) => ({ ...asset, address }); +const withAssetsAvailableOnUniswapSelector = createSelector( + [allAssetsSelector], + withAssetsAvailableOnUniswap, +); -const uniswapAssets = values(mapValues(uniswapAssetsRaw, mapUniswapAssetItem)); -const sortedUniswapAssets = sortBy(uniswapAssets, property('name')); +const withSortedUniswapAssetsSelector = createSelector( + [unsortedUniswapAssetsSelector], + withSortedUniswapAssets, +); -export default withProps({ sortedUniswapAssets }); +export default compose( + withAccountData, + withProps({ unsortedUniswapAssets }), + withProps(withSortedUniswapAssetsSelector), + withProps(withAssetsAvailableOnUniswapSelector), + omitProps('unsortedUniswapAssets'), +); From 96106f77c6c092ae7b55c53fc09f67750cce0756 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 15 Aug 2019 03:21:08 -0700 Subject: [PATCH 202/636] Update recyclerlistview to latest release + update patch --- package.json | 2 +- patches/recyclerlistview+2.0.10.patch | 11088 ++++++++++++++++++++++++ 2 files changed, 11089 insertions(+), 1 deletion(-) create mode 100644 patches/recyclerlistview+2.0.10.patch diff --git a/package.json b/package.json index b4c9fe5702c..2614a4f1ff9 100644 --- a/package.json +++ b/package.json @@ -242,4 +242,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/patches/recyclerlistview+2.0.10.patch b/patches/recyclerlistview+2.0.10.patch new file mode 100644 index 00000000000..682cb641f77 --- /dev/null +++ b/patches/recyclerlistview+2.0.10.patch @@ -0,0 +1,11088 @@ +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.d.ts +new file mode 100644 +index 0000000..dd0e11c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.d.ts +@@ -0,0 +1,15 @@ ++export default interface ItemAnimator { ++ animateWillMount: (atX: number, atY: number, itemIndex: number) => object | undefined; ++ animateDidMount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; ++ animateWillUpdate: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => void; ++ animateShift: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => boolean; ++ animateWillUnmount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; ++} ++export declare class BaseItemAnimator implements ItemAnimator { ++ static USE_NATIVE_DRIVER: boolean; ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js +new file mode 100644 +index 0000000..0ae5165 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js +@@ -0,0 +1,25 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var BaseItemAnimator = /** @class */ (function () { ++ function BaseItemAnimator() { ++ } ++ BaseItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ BaseItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ BaseItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ //no need ++ }; ++ BaseItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ return false; ++ }; ++ BaseItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ BaseItemAnimator.USE_NATIVE_DRIVER = true; ++ return BaseItemAnimator; ++}()); ++exports.BaseItemAnimator = BaseItemAnimator; ++//# sourceMappingURL=ItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js.map +new file mode 100644 +index 0000000..732604a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ItemAnimator.js","sourceRoot":"","sources":["../../../src/core/ItemAnimator.ts"],"names":[],"mappings":";;AAwBA;IAAA;IAoBA,CAAC;IAlBU,2CAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,0CAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,4CAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,SAAS;IACb,CAAC;IAEM,uCAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC1G,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,6CAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IAlBa,kCAAiB,GAAG,IAAI,CAAC;IAmB3C,uBAAC;CAAA,AApBD,IAoBC;AApBY,4CAAgB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.d.ts +new file mode 100644 +index 0000000..c30743a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.d.ts +@@ -0,0 +1,27 @@ ++import RecyclerListView, { RecyclerListViewProps, RecyclerListViewState } from "./RecyclerListView"; ++export interface ProgressiveListViewProps extends RecyclerListViewProps { ++ maxRenderAhead?: number; ++ renderAheadStep?: number; ++} ++/** ++ * This will incremently update renderAhread distance and render the page progressively. ++ */ ++export default class ProgressiveListView extends RecyclerListView { ++ static defaultProps: { ++ maxRenderAhead: number; ++ renderAheadStep: number; ++ renderAheadOffset: number; ++ canChangeSize: boolean; ++ disableRecycling: boolean; ++ initialOffset: number; ++ initialRenderIndex: number; ++ isHorizontal: boolean; ++ onEndReachedThreshold: number; ++ distanceFromWindow: number; ++ }; ++ private renderAheadUdpateCallbackId?; ++ componentDidMount(): void; ++ private updateRenderAheadProgessively; ++ private incrementRenderAhead; ++ private cancelRenderAheadUpdate; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js +new file mode 100644 +index 0000000..9176a38 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js +@@ -0,0 +1,77 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecyclerListView_1 = require("./RecyclerListView"); ++/** ++ * This will incremently update renderAhread distance and render the page progressively. ++ */ ++var ProgressiveListView = /** @class */ (function (_super) { ++ __extends(ProgressiveListView, _super); ++ function ProgressiveListView() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ ProgressiveListView.prototype.componentDidMount = function () { ++ if (_super.prototype.componentDidMount) { ++ _super.prototype.componentDidMount.call(this); ++ } ++ this.updateRenderAheadProgessively(this.getCurrentRenderAheadOffset()); ++ }; ++ ProgressiveListView.prototype.updateRenderAheadProgessively = function (newVal) { ++ var _this = this; ++ this.cancelRenderAheadUpdate(); // Cancel any pending callback. ++ this.renderAheadUdpateCallbackId = requestAnimationFrame(function () { ++ if (!_this.updateRenderAheadOffset(newVal)) { ++ _this.updateRenderAheadProgessively(newVal); ++ } ++ else { ++ _this.incrementRenderAhead(); ++ } ++ }); ++ }; ++ ProgressiveListView.prototype.incrementRenderAhead = function () { ++ if (this.props.maxRenderAhead && this.props.renderAheadStep) { ++ var layoutManager = this.getVirtualRenderer().getLayoutManager(); ++ var currentRenderAheadOffset = this.getCurrentRenderAheadOffset(); ++ if (layoutManager) { ++ var contentDimension = layoutManager.getContentDimension(); ++ var maxContentSize = this.props.isHorizontal ? contentDimension.width : contentDimension.height; ++ if (currentRenderAheadOffset < maxContentSize && currentRenderAheadOffset < this.props.maxRenderAhead) { ++ var newRenderAheadOffset = currentRenderAheadOffset + this.props.renderAheadStep; ++ this.updateRenderAheadProgessively(newRenderAheadOffset); ++ } ++ } ++ } ++ }; ++ ProgressiveListView.prototype.cancelRenderAheadUpdate = function () { ++ if (this.renderAheadUdpateCallbackId) { ++ cancelAnimationFrame(this.renderAheadUdpateCallbackId); ++ } ++ }; ++ ProgressiveListView.defaultProps = __assign({}, RecyclerListView_1.default.defaultProps, { maxRenderAhead: Number.MAX_VALUE, renderAheadStep: 300, renderAheadOffset: 0 }); ++ return ProgressiveListView; ++}(RecyclerListView_1.default)); ++exports.default = ProgressiveListView; ++//# sourceMappingURL=ProgressiveListView.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js.map b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js.map +new file mode 100644 +index 0000000..c9c3fd6 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ProgressiveListView.js","sourceRoot":"","sources":["../../../src/core/ProgressiveListView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uDAAoG;AAKpG;;GAEG;AACH;IAAiD,uCAAiE;IAAlH;;IA+CA,CAAC;IAtCU,+CAAiB,GAAxB;QACI,IAAI,iBAAM,iBAAiB,EAAE;YACzB,iBAAM,iBAAiB,WAAE,CAAC;SAC7B;QACD,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,CAAC;IAC3E,CAAC;IAEO,2DAA6B,GAArC,UAAsC,MAAc;QAApD,iBASC;QARG,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,+BAA+B;QAC/D,IAAI,CAAC,2BAA2B,GAAG,qBAAqB,CAAC;YACrD,IAAI,CAAC,KAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE;gBACvC,KAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;aAC9C;iBAAM;gBACH,KAAI,CAAC,oBAAoB,EAAE,CAAC;aAC/B;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kDAAoB,GAA5B;QACI,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;YACzD,IAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACnE,IAAM,wBAAwB,GAAG,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACpE,IAAI,aAAa,EAAE;gBACf,IAAM,gBAAgB,GAAG,aAAa,CAAC,mBAAmB,EAAE,CAAC;gBAC7D,IAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAClG,IAAI,wBAAwB,GAAG,cAAc,IAAI,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;oBACnG,IAAM,oBAAoB,GAAG,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;oBACnF,IAAI,CAAC,6BAA6B,CAAC,oBAAoB,CAAC,CAAC;iBAC5D;aACJ;SACJ;IACL,CAAC;IAEO,qDAAuB,GAA/B;QACI,IAAI,IAAI,CAAC,2BAA2B,EAAE;YAClC,oBAAoB,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;SAC1D;IACL,CAAC;IA7Ca,gCAAY,gBACnB,0BAAgB,CAAC,YAAY,IAChC,cAAc,EAAE,MAAM,CAAC,SAAS,EAChC,eAAe,EAAE,GAAG,EACpB,iBAAiB,EAAE,CAAC,IACtB;IAyCN,0BAAC;CAAA,AA/CD,CAAiD,0BAAgB,GA+ChE;kBA/CoB,mBAAmB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.d.ts +new file mode 100644 +index 0000000..1a55b49 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.d.ts +@@ -0,0 +1,129 @@ ++import * as React from "react"; ++import ContextProvider from "./dependencies/ContextProvider"; ++import { BaseDataProvider } from "./dependencies/DataProvider"; ++import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; ++import { Layout } from "./layoutmanager/LayoutManager"; ++import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./scrollcomponent/BaseScrollView"; ++import { TOnItemStatusChanged } from "./ViewabilityTracker"; ++import VirtualRenderer, { RenderStack } from "./VirtualRenderer"; ++import ItemAnimator from "./ItemAnimator"; ++import { DebugHandlers } from ".."; ++/*** ++ * To use on web, start importing from recyclerlistview/web. To make it even easier specify an alias in you builder of choice. ++ */ ++/*** ++ * This is the main component, please refer to samples to understand how to use. ++ * For advanced usage check out prop descriptions below. ++ * You also get common methods such as: scrollToIndex, scrollToItem, scrollToTop, scrollToEnd, scrollToOffset, getCurrentScrollOffset, ++ * findApproxFirstVisibleIndex. ++ * You'll need a ref to Recycler in order to call these ++ * Needs to have bounded size in all cases other than window scrolling (web). ++ * ++ * NOTE: React Native implementation uses ScrollView internally which means you get all ScrollView features as well such as Pull To Refresh, paging enabled ++ * You can easily create a recycling image flip view using one paging enabled flag. Read about ScrollView features in official ++ * react native documentation. ++ * NOTE: If you see blank space look at the renderAheadOffset prop and make sure your data provider has a good enough rowHasChanged method. ++ * Blanks are totally avoidable with this listview. ++ * NOTE: Also works on web (experimental) ++ * NOTE: For reflowability set canChangeSize to true (experimental) ++ */ ++export interface OnRecreateParams { ++ lastOffset?: number; ++} ++export interface RecyclerListViewProps { ++ layoutProvider: BaseLayoutProvider; ++ dataProvider: BaseDataProvider; ++ rowRenderer: (type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++ contextProvider?: ContextProvider; ++ renderAheadOffset?: number; ++ isHorizontal?: boolean; ++ onScroll?: (rawEvent: ScrollEvent, offsetX: number, offsetY: number) => void; ++ onRecreate?: (params: OnRecreateParams) => void; ++ onEndReached?: () => void; ++ onEndReachedThreshold?: number; ++ onVisibleIndexesChanged?: TOnItemStatusChanged; ++ onVisibleIndicesChanged?: TOnItemStatusChanged; ++ renderFooter?: () => JSX.Element | JSX.Element[] | null; ++ externalScrollView?: { ++ new (props: ScrollViewDefaultProps): BaseScrollView; ++ }; ++ initialOffset?: number; ++ initialRenderIndex?: number; ++ scrollThrottle?: number; ++ canChangeSize?: boolean; ++ distanceFromWindow?: number; ++ useWindowScroll?: boolean; ++ disableRecycling?: boolean; ++ forceNonDeterministicRendering?: boolean; ++ extendedState?: object; ++ itemAnimator?: ItemAnimator; ++ optimizeForInsertDeleteAnimations?: boolean; ++ style?: object | number; ++ debugHandlers?: DebugHandlers; ++ scrollViewProps?: object; ++} ++export interface RecyclerListViewState { ++ renderStack: RenderStack; ++ internalSnapshot: Record; ++} ++export default class RecyclerListView

extends React.Component { ++ static defaultProps: { ++ canChangeSize: boolean; ++ disableRecycling: boolean; ++ initialOffset: number; ++ initialRenderIndex: number; ++ isHorizontal: boolean; ++ onEndReachedThreshold: number; ++ distanceFromWindow: number; ++ renderAheadOffset: number; ++ }; ++ static propTypes: {}; ++ private refreshRequestDebouncer; ++ private _virtualRenderer; ++ private _onEndReachedCalled; ++ private _initComplete; ++ private _relayoutReqIndex; ++ private _params; ++ private _layout; ++ private _pendingScrollToOffset; ++ private _tempDim; ++ private _initialOffset; ++ private _cachedLayouts?; ++ private _scrollComponent; ++ private _defaultItemAnimator; ++ constructor(props: P, context?: any); ++ componentWillReceiveProps(newProps: RecyclerListViewProps): void; ++ componentDidUpdate(): void; ++ componentWillUnmount(): void; ++ componentWillMount(): void; ++ scrollToIndex(index: number, animate?: boolean): void; ++ scrollToItem(data: any, animate?: boolean): void; ++ getLayout(index: number): Layout | undefined; ++ scrollToTop(animate?: boolean): void; ++ scrollToEnd(animate?: boolean): void; ++ scrollToOffset: (x: number, y: number, animate?: boolean) => void; ++ updateRenderAheadOffset(renderAheadOffset: number): boolean; ++ getCurrentRenderAheadOffset(): number; ++ getCurrentScrollOffset(): number; ++ findApproxFirstVisibleIndex(): number; ++ getRenderedSize(): Dimension; ++ getContentDimension(): Dimension; ++ forceRerender(): void; ++ render(): JSX.Element; ++ protected getVirtualRenderer(): VirtualRenderer; ++ private _checkAndChangeLayouts; ++ private _refreshViewability; ++ private _queueStateRefresh; ++ private _onSizeChanged; ++ private _renderStackWhenReady; ++ private _initTrackers; ++ private _assertDependencyPresence; ++ private _assertType; ++ private _dataHasChanged; ++ private _renderRowUsingMeta; ++ private _onViewContainerSizeChange; ++ private _checkExpectedDimensionDiscrepancy; ++ private _generateRenderStack; ++ private _onScroll; ++ private _processOnEndReached; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js +new file mode 100644 +index 0000000..a8c46fe +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js +@@ -0,0 +1,577 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++/*** ++ * DONE: Reduce layout processing on data insert ++ * DONE: Add notify data set changed and notify data insert option in data source ++ * DONE: Add on end reached callback ++ * DONE: Make another class for render stack generator ++ * DONE: Simplify rendering a loading footer ++ * DONE: Anchor first visible index on any insert/delete data wise ++ * DONE: Build Scroll to index ++ * DONE: Give viewability callbacks ++ * DONE: Add full render logic in cases like change of dimensions ++ * DONE: Fix all proptypes ++ * DONE: Add Initial render Index support ++ * DONE: Add animated scroll to web scrollviewer ++ * DONE: Animate list view transition, including add/remove ++ * DONE: Implement sticky headers and footers ++ * TODO: Destroy less frequently used items in recycle pool, this will help in case of too many types. ++ * TODO: Make viewability callbacks configurable ++ * TODO: Observe size changes on web to optimize for reflowability ++ * TODO: Solve //TSI ++ */ ++var debounce = require("lodash.debounce"); ++var PropTypes = require("prop-types"); ++var React = require("react"); ++var ts_object_utils_1 = require("ts-object-utils"); ++var ContextProvider_1 = require("./dependencies/ContextProvider"); ++var DataProvider_1 = require("./dependencies/DataProvider"); ++var LayoutProvider_1 = require("./dependencies/LayoutProvider"); ++var CustomError_1 = require("./exceptions/CustomError"); ++var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); ++var Constants_1 = require("./constants/Constants"); ++var Messages_1 = require("./constants/Messages"); ++var VirtualRenderer_1 = require("./VirtualRenderer"); ++var ItemAnimator_1 = require("./ItemAnimator"); ++//#if [REACT-NATIVE] ++var ScrollComponent_1 = require("../platform/reactnative/scrollcomponent/ScrollComponent"); ++var ViewRenderer_1 = require("../platform/reactnative/viewrenderer/ViewRenderer"); ++var DefaultJSItemAnimator_1 = require("../platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator"); ++var react_native_1 = require("react-native"); ++var IS_WEB = !react_native_1.Platform || react_native_1.Platform.OS === "web"; ++var RecyclerListView = /** @class */ (function (_super) { ++ __extends(RecyclerListView, _super); ++ function RecyclerListView(props, context) { ++ var _this = _super.call(this, props, context) || this; ++ _this.refreshRequestDebouncer = debounce(function (executable) { ++ executable(); ++ }); ++ _this._onEndReachedCalled = false; ++ _this._initComplete = false; ++ _this._relayoutReqIndex = -1; ++ _this._params = { ++ initialOffset: 0, ++ initialRenderIndex: 0, ++ isHorizontal: false, ++ itemCount: 0, ++ renderAheadOffset: 250, ++ }; ++ _this._layout = { height: 0, width: 0 }; ++ _this._pendingScrollToOffset = null; ++ _this._tempDim = { height: 0, width: 0 }; ++ _this._initialOffset = 0; ++ _this._scrollComponent = null; ++ _this._defaultItemAnimator = new DefaultJSItemAnimator_1.DefaultJSItemAnimator(); ++ _this.scrollToOffset = function (x, y, animate) { ++ if (animate === void 0) { animate = false; } ++ if (_this._scrollComponent) { ++ if (_this.props.isHorizontal) { ++ y = 0; ++ } ++ else { ++ x = 0; ++ } ++ _this._scrollComponent.scrollTo(x, y, animate); ++ } ++ }; ++ _this._onSizeChanged = function (layout) { ++ var hasHeightChanged = _this._layout.height !== layout.height; ++ var hasWidthChanged = _this._layout.width !== layout.width; ++ _this._layout.height = layout.height; ++ _this._layout.width = layout.width; ++ if (layout.height === 0 || layout.width === 0) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.layoutException); ++ } ++ if (!_this._initComplete) { ++ _this._initComplete = true; ++ _this._initTrackers(); ++ _this._processOnEndReached(); ++ } ++ else { ++ if ((hasHeightChanged && hasWidthChanged) || ++ (hasHeightChanged && _this.props.isHorizontal) || ++ (hasWidthChanged && !_this.props.isHorizontal)) { ++ _this._checkAndChangeLayouts(_this.props, true); ++ } ++ else { ++ _this._refreshViewability(); ++ } ++ } ++ }; ++ _this._renderStackWhenReady = function (stack) { ++ _this.setState(function () { ++ return { renderStack: stack }; ++ }); ++ }; ++ _this._dataHasChanged = function (row1, row2) { ++ return _this.props.dataProvider.rowHasChanged(row1, row2); ++ }; ++ _this._onViewContainerSizeChange = function (dim, index) { ++ //Cannot be null here ++ var layoutManager = _this._virtualRenderer.getLayoutManager(); ++ if (_this.props.debugHandlers && _this.props.debugHandlers.resizeDebugHandler) { ++ var itemRect = layoutManager.getLayouts()[index]; ++ _this.props.debugHandlers.resizeDebugHandler.resizeDebug({ ++ width: itemRect.width, ++ height: itemRect.height, ++ }, dim, index); ++ } ++ if (layoutManager.overrideLayout(index, dim)) { ++ if (_this._relayoutReqIndex === -1) { ++ _this._relayoutReqIndex = index; ++ } ++ else { ++ _this._relayoutReqIndex = Math.min(_this._relayoutReqIndex, index); ++ } ++ _this._queueStateRefresh(); ++ } ++ }; ++ _this._onScroll = function (offsetX, offsetY, rawEvent) { ++ //Adjusting offsets using distanceFromWindow ++ _this._virtualRenderer.updateOffset(offsetX, offsetY, -_this.props.distanceFromWindow, true); ++ if (_this.props.onScroll) { ++ _this.props.onScroll(rawEvent, offsetX, offsetY); ++ } ++ _this._processOnEndReached(); ++ }; ++ _this._virtualRenderer = new VirtualRenderer_1.default(_this._renderStackWhenReady, function (offset) { ++ _this._pendingScrollToOffset = offset; ++ }, function (index) { ++ return _this.props.dataProvider.getStableId(index); ++ }, !props.disableRecycling); ++ _this.state = { ++ internalSnapshot: {}, ++ renderStack: {}, ++ }; ++ return _this; ++ } ++ RecyclerListView.prototype.componentWillReceiveProps = function (newProps) { ++ this._assertDependencyPresence(newProps); ++ this._checkAndChangeLayouts(newProps); ++ if (!this.props.onVisibleIndicesChanged) { ++ this._virtualRenderer.removeVisibleItemsListener(); ++ } ++ if (this.props.onVisibleIndexesChanged) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); ++ } ++ if (this.props.onVisibleIndicesChanged) { ++ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); ++ } ++ }; ++ RecyclerListView.prototype.componentDidUpdate = function () { ++ var _this = this; ++ if (this._pendingScrollToOffset) { ++ var offset_1 = this._pendingScrollToOffset; ++ this._pendingScrollToOffset = null; ++ if (this.props.isHorizontal) { ++ offset_1.y = 0; ++ } ++ else { ++ offset_1.x = 0; ++ } ++ setTimeout(function () { ++ _this.scrollToOffset(offset_1.x, offset_1.y, false); ++ }, 0); ++ } ++ this._processOnEndReached(); ++ this._checkAndChangeLayouts(this.props); ++ if (this.props.dataProvider.getSize() === 0) { ++ console.warn(Messages_1.Messages.WARN_NO_DATA); //tslint:disable-line ++ } ++ }; ++ RecyclerListView.prototype.componentWillUnmount = function () { ++ if (this.props.contextProvider) { ++ var uniqueKey = this.props.contextProvider.getUniqueKey(); ++ if (uniqueKey) { ++ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX, this.getCurrentScrollOffset()); ++ if (this.props.forceNonDeterministicRendering) { ++ if (this._virtualRenderer) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ var layoutsToCache = layoutManager.getLayouts(); ++ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX, JSON.stringify({ layoutArray: layoutsToCache })); ++ } ++ } ++ } ++ } ++ } ++ }; ++ RecyclerListView.prototype.componentWillMount = function () { ++ if (this.props.contextProvider) { ++ var uniqueKey = this.props.contextProvider.getUniqueKey(); ++ if (uniqueKey) { ++ var offset = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); ++ if (typeof offset === "number" && offset > 0) { ++ this._initialOffset = offset; ++ if (this.props.onRecreate) { ++ this.props.onRecreate({ lastOffset: this._initialOffset }); ++ } ++ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); ++ } ++ if (this.props.forceNonDeterministicRendering) { ++ var cachedLayouts = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); ++ if (cachedLayouts && typeof cachedLayouts === "string") { ++ this._cachedLayouts = JSON.parse(cachedLayouts).layoutArray; ++ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); ++ } ++ } ++ } ++ } ++ }; ++ RecyclerListView.prototype.scrollToIndex = function (index, animate) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ var offsets = layoutManager.getOffsetForIndex(index); ++ this.scrollToOffset(offsets.x, offsets.y, animate); ++ } ++ else { ++ console.warn(Messages_1.Messages.WARN_SCROLL_TO_INDEX); //tslint:disable-line ++ } ++ }; ++ RecyclerListView.prototype.scrollToItem = function (data, animate) { ++ var count = this.props.dataProvider.getSize(); ++ for (var i = 0; i < count; i++) { ++ if (this.props.dataProvider.getDataForIndex(i) === data) { ++ this.scrollToIndex(i, animate); ++ break; ++ } ++ } ++ }; ++ RecyclerListView.prototype.getLayout = function (index) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ return layoutManager ? layoutManager.getLayouts()[index] : undefined; ++ }; ++ RecyclerListView.prototype.scrollToTop = function (animate) { ++ this.scrollToOffset(0, 0, animate); ++ }; ++ RecyclerListView.prototype.scrollToEnd = function (animate) { ++ var lastIndex = this.props.dataProvider.getSize() - 1; ++ this.scrollToIndex(lastIndex, animate); ++ }; ++ // You can use requestAnimationFrame callback to change renderAhead in multiple frames to enable advanced progressive ++ // rendering when view types are very complex. This method returns a boolean saying if the update was committed. Retry in ++ // the next frame if you get a failure (if mount wasn't complete). Value should be greater than or equal to 0; ++ // Very useful when you have a page where you need a large renderAheadOffset. Setting it at once will slow down the load and ++ // this will help mitigate that. ++ RecyclerListView.prototype.updateRenderAheadOffset = function (renderAheadOffset) { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ if (viewabilityTracker) { ++ viewabilityTracker.updateRenderAheadOffset(renderAheadOffset); ++ return true; ++ } ++ return false; ++ }; ++ RecyclerListView.prototype.getCurrentRenderAheadOffset = function () { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ if (viewabilityTracker) { ++ return viewabilityTracker.getCurrentRenderAheadOffset(); ++ } ++ return this.props.renderAheadOffset; ++ }; ++ RecyclerListView.prototype.getCurrentScrollOffset = function () { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ return viewabilityTracker ? viewabilityTracker.getLastActualOffset() : 0; ++ }; ++ RecyclerListView.prototype.findApproxFirstVisibleIndex = function () { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ return viewabilityTracker ? viewabilityTracker.findFirstLogicallyVisibleIndex() : 0; ++ }; ++ RecyclerListView.prototype.getRenderedSize = function () { ++ return this._layout; ++ }; ++ RecyclerListView.prototype.getContentDimension = function () { ++ return this._virtualRenderer.getLayoutDimension(); ++ }; ++ // Force Rerender forcefully to update view renderer. Use this in rare circumstances ++ RecyclerListView.prototype.forceRerender = function () { ++ this.setState({ ++ internalSnapshot: {}, ++ }); ++ }; ++ RecyclerListView.prototype.render = function () { ++ //TODO:Talha ++ // const { ++ // layoutProvider, ++ // dataProvider, ++ // contextProvider, ++ // renderAheadOffset, ++ // onEndReached, ++ // onEndReachedThreshold, ++ // onVisibleIndicesChanged, ++ // initialOffset, ++ // initialRenderIndex, ++ // disableRecycling, ++ // forceNonDeterministicRendering, ++ // extendedState, ++ // itemAnimator, ++ // rowRenderer, ++ // ...props, ++ // } = this.props; ++ var _this = this; ++ return (React.createElement(ScrollComponent_1.default, __assign({ ref: function (scrollComponent) { return _this._scrollComponent = scrollComponent; } }, this.props, this.props.scrollViewProps, { onScroll: this._onScroll, onSizeChanged: this._onSizeChanged, contentHeight: this._initComplete ? this._virtualRenderer.getLayoutDimension().height : 0, contentWidth: this._initComplete ? this._virtualRenderer.getLayoutDimension().width : 0 }), this._generateRenderStack())); ++ }; ++ RecyclerListView.prototype.getVirtualRenderer = function () { ++ return this._virtualRenderer; ++ }; ++ RecyclerListView.prototype._checkAndChangeLayouts = function (newProps, forceFullRender) { ++ this._params.isHorizontal = newProps.isHorizontal; ++ this._params.itemCount = newProps.dataProvider.getSize(); ++ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); ++ this._virtualRenderer.setLayoutProvider(newProps.layoutProvider); ++ if (newProps.dataProvider.hasStableIds() && this.props.dataProvider !== newProps.dataProvider && newProps.dataProvider.requiresDataChangeHandling()) { ++ this._virtualRenderer.handleDataSetChange(newProps.dataProvider, this.props.optimizeForInsertDeleteAnimations); ++ } ++ if (forceFullRender || this.props.layoutProvider !== newProps.layoutProvider || this.props.isHorizontal !== newProps.isHorizontal) { ++ //TODO:Talha use old layout manager ++ this._virtualRenderer.setLayoutManager(newProps.layoutProvider.newLayoutManager(this._layout, newProps.isHorizontal)); ++ if (newProps.layoutProvider.shouldRefreshWithAnchoring) { ++ this._virtualRenderer.refreshWithAnchor(); ++ } ++ else { ++ this._virtualRenderer.refresh(); ++ } ++ this._refreshViewability(); ++ } ++ else if (this.props.dataProvider !== newProps.dataProvider) { ++ this._onEndReachedCalled = false; ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ layoutManager.relayoutFromIndex(newProps.dataProvider.getFirstIndexToProcessInternal(), newProps.dataProvider.getSize()); ++ this._virtualRenderer.refresh(); ++ } ++ } ++ else if (this._relayoutReqIndex >= 0) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ var dataProviderSize = newProps.dataProvider.getSize(); ++ layoutManager.relayoutFromIndex(Math.min(Math.max(dataProviderSize - 1, 0), this._relayoutReqIndex), dataProviderSize); ++ this._relayoutReqIndex = -1; ++ this._refreshViewability(); ++ } ++ } ++ }; ++ RecyclerListView.prototype._refreshViewability = function () { ++ this._virtualRenderer.refresh(); ++ this._queueStateRefresh(); ++ }; ++ RecyclerListView.prototype._queueStateRefresh = function () { ++ var _this = this; ++ this.refreshRequestDebouncer(function () { ++ _this.setState(function (prevState) { ++ return prevState; ++ }); ++ }); ++ }; ++ RecyclerListView.prototype._initTrackers = function () { ++ this._assertDependencyPresence(this.props); ++ if (this.props.onVisibleIndexesChanged) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); ++ } ++ if (this.props.onVisibleIndicesChanged) { ++ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); ++ } ++ this._params = { ++ initialOffset: this._initialOffset ? this._initialOffset : this.props.initialOffset, ++ initialRenderIndex: this.props.initialRenderIndex, ++ isHorizontal: this.props.isHorizontal, ++ itemCount: this.props.dataProvider.getSize(), ++ renderAheadOffset: this.props.renderAheadOffset, ++ }; ++ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); ++ var layoutManager = this.props.layoutProvider.newLayoutManager(this._layout, this.props.isHorizontal, this._cachedLayouts); ++ this._virtualRenderer.setLayoutManager(layoutManager); ++ this._virtualRenderer.setLayoutProvider(this.props.layoutProvider); ++ this._virtualRenderer.init(); ++ var offset = this._virtualRenderer.getInitialOffset(); ++ var contentDimension = layoutManager.getContentDimension(); ++ if ((offset.y > 0 && contentDimension.height > this._layout.height) || ++ (offset.x > 0 && contentDimension.width > this._layout.width)) { ++ this._pendingScrollToOffset = offset; ++ this.setState({}); ++ } ++ else { ++ this._virtualRenderer.startViewabilityTracker(); ++ } ++ }; ++ RecyclerListView.prototype._assertDependencyPresence = function (props) { ++ if (!props.dataProvider || !props.layoutProvider) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.unresolvedDependenciesException); ++ } ++ }; ++ RecyclerListView.prototype._assertType = function (type) { ++ if (!type && type !== 0) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.itemTypeNullException); ++ } ++ }; ++ RecyclerListView.prototype._renderRowUsingMeta = function (itemMeta) { ++ var dataSize = this.props.dataProvider.getSize(); ++ var dataIndex = itemMeta.dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(dataIndex) && dataIndex < dataSize) { ++ var itemRect = this._virtualRenderer.getLayoutManager().getLayouts()[dataIndex]; ++ var data = this.props.dataProvider.getDataForIndex(dataIndex); ++ var type = this.props.layoutProvider.getLayoutTypeForIndex(dataIndex); ++ var key = this._virtualRenderer.syncAndGetKey(dataIndex); ++ var styleOverrides = this._virtualRenderer.getLayoutManager().getStyleOverridesForIndex(dataIndex); ++ this._assertType(type); ++ if (!this.props.forceNonDeterministicRendering) { ++ this._checkExpectedDimensionDiscrepancy(itemRect, type, dataIndex); ++ } ++ return (React.createElement(ViewRenderer_1.default, { key: key, data: data, dataHasChanged: this._dataHasChanged, x: itemRect.x, y: itemRect.y, layoutType: type, index: dataIndex, styleOverrides: styleOverrides, layoutProvider: this.props.layoutProvider, forceNonDeterministicRendering: this.props.forceNonDeterministicRendering, isHorizontal: this.props.isHorizontal, onSizeChanged: this._onViewContainerSizeChange, childRenderer: this.props.rowRenderer, height: itemRect.height, width: itemRect.width, itemAnimator: ts_object_utils_1.Default.value(this.props.itemAnimator, this._defaultItemAnimator), extendedState: this.props.extendedState, internalSnapshot: this.state.internalSnapshot })); ++ } ++ return null; ++ }; ++ RecyclerListView.prototype._checkExpectedDimensionDiscrepancy = function (itemRect, type, index) { ++ if (this.props.layoutProvider.checkDimensionDiscrepancy(itemRect, type, index)) { ++ if (this._relayoutReqIndex === -1) { ++ this._relayoutReqIndex = index; ++ } ++ else { ++ this._relayoutReqIndex = Math.min(this._relayoutReqIndex, index); ++ } ++ } ++ }; ++ RecyclerListView.prototype._generateRenderStack = function () { ++ var renderedItems = []; ++ for (var key in this.state.renderStack) { ++ if (this.state.renderStack.hasOwnProperty(key)) { ++ renderedItems.push(this._renderRowUsingMeta(this.state.renderStack[key])); ++ } ++ } ++ return renderedItems; ++ }; ++ RecyclerListView.prototype._processOnEndReached = function () { ++ if (this.props.onEndReached && this._virtualRenderer) { ++ var layout = this._virtualRenderer.getLayoutDimension(); ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ if (viewabilityTracker) { ++ var windowBound = this.props.isHorizontal ? layout.width - this._layout.width : layout.height - this._layout.height; ++ var lastOffset = viewabilityTracker ? viewabilityTracker.getLastOffset() : 0; ++ if (windowBound - lastOffset <= ts_object_utils_1.Default.value(this.props.onEndReachedThreshold, 0)) { ++ if (this.props.onEndReached && !this._onEndReachedCalled) { ++ this._onEndReachedCalled = true; ++ this.props.onEndReached(); ++ } ++ } ++ else { ++ this._onEndReachedCalled = false; ++ } ++ } ++ } ++ }; ++ RecyclerListView.defaultProps = { ++ canChangeSize: false, ++ disableRecycling: false, ++ initialOffset: 0, ++ initialRenderIndex: 0, ++ isHorizontal: false, ++ onEndReachedThreshold: 0, ++ distanceFromWindow: 0, ++ renderAheadOffset: IS_WEB ? 1000 : 250, ++ }; ++ RecyclerListView.propTypes = {}; ++ return RecyclerListView; ++}(React.Component)); ++exports.default = RecyclerListView; ++RecyclerListView.propTypes = { ++ //Refer the sample ++ layoutProvider: PropTypes.instanceOf(LayoutProvider_1.BaseLayoutProvider).isRequired, ++ //Refer the sample ++ dataProvider: PropTypes.instanceOf(DataProvider_1.BaseDataProvider).isRequired, ++ //Used to maintain scroll position in case view gets destroyed e.g, cases of back navigation ++ contextProvider: PropTypes.instanceOf(ContextProvider_1.default), ++ //Methods which returns react component to be rendered. You get type of view and data in the callback. ++ rowRenderer: PropTypes.func.isRequired, ++ //Initial offset you want to start rendering from, very useful if you want to maintain scroll context across pages. ++ initialOffset: PropTypes.number, ++ //Specify how many pixels in advance do you want views to be rendered. Increasing this value can help reduce blanks (if any). However keeping this as low ++ //as possible should be the intent. Higher values also increase re-render compute ++ renderAheadOffset: PropTypes.number, ++ //Whether the listview is horizontally scrollable. Both use staggeredGrid implementation ++ isHorizontal: PropTypes.bool, ++ //On scroll callback onScroll(rawEvent, offsetX, offsetY), note you get offsets no need to read scrollTop/scrollLeft ++ onScroll: PropTypes.func, ++ //callback onRecreate(params), when recreating recycler view from context provider. Gives you the initial params in the first ++ //frame itself to allow you to render content accordingly ++ onRecreate: PropTypes.func, ++ //Provide your own ScrollView Component. The contract for the scroll event should match the native scroll event contract, i.e. ++ // scrollEvent = { nativeEvent: { contentOffset: { x: offset, y: offset } } } ++ //Note: Please extend BaseScrollView to achieve expected behaviour ++ externalScrollView: PropTypes.func, ++ //Callback given when user scrolls to the end of the list or footer just becomes visible, useful in incremental loading scenarios ++ onEndReached: PropTypes.func, ++ //Specify how many pixels in advance you onEndReached callback ++ onEndReachedThreshold: PropTypes.number, ++ //Deprecated. Please use onVisibleIndicesChanged instead. ++ onVisibleIndexesChanged: PropTypes.func, ++ //Provides visible index, helpful in sending impression events etc, onVisibleIndicesChanged(all, now, notNow) ++ onVisibleIndicesChanged: PropTypes.func, ++ //Provide this method if you want to render a footer. Helpful in showing a loader while doing incremental loads. ++ renderFooter: PropTypes.func, ++ //Specify the initial item index you want rendering to start from. Preferred over initialOffset if both are specified. ++ initialRenderIndex: PropTypes.number, ++ //iOS only. Scroll throttle duration. ++ scrollThrottle: PropTypes.number, ++ //Specify if size can change, listview will automatically relayout items. For web, works only with useWindowScroll = true ++ canChangeSize: PropTypes.bool, ++ //Specify how far away the first list item is from start of the RecyclerListView. e.g, if you have content padding on top or left. ++ //This is an adjustment for optimization and to make sure onVisibileIndexesChanged callback is correct. ++ //Ideally try to avoid setting large padding values on RLV content. If you have to please correct offsets reported, handle ++ //them in a custom ScrollView and pass it as an externalScrollView. If you want this to be accounted in scrollToOffset please ++ //override the method and handle manually. ++ distanceFromWindow: PropTypes.number, ++ //Web only. Layout elements in window instead of a scrollable div. ++ useWindowScroll: PropTypes.bool, ++ //Turns off recycling. You still get progressive rendering and all other features. Good for lazy rendering. This should not be used in most cases. ++ disableRecycling: PropTypes.bool, ++ //Default is false, if enabled dimensions provided in layout provider will not be strictly enforced. ++ //Rendered dimensions will be used to relayout items. Slower if enabled. ++ forceNonDeterministicRendering: PropTypes.bool, ++ //In some cases the data passed at row level may not contain all the info that the item depends upon, you can keep all other info ++ //outside and pass it down via this prop. Changing this object will cause everything to re-render. Make sure you don't change ++ //it often to ensure performance. Re-renders are heavy. ++ extendedState: PropTypes.object, ++ //Enables animating RecyclerListView item cells e.g, shift, add, remove etc. This prop can be used to pass an external item animation implementation. ++ //Look into BaseItemAnimator/DefaultJSItemAnimator/DefaultNativeItemAnimator/DefaultWebItemAnimator for more info. ++ //By default there are few animations, to disable completely simply pass blank new BaseItemAnimator() object. Remember, create ++ //one object and keep it do not create multiple object of type BaseItemAnimator. ++ //Note: You might want to look into DefaultNativeItemAnimator to check an implementation based on LayoutAnimation. By default, ++ //animations are JS driven to avoid workflow interference. Also, please note LayoutAnimation is buggy on Android. ++ itemAnimator: PropTypes.instanceOf(ItemAnimator_1.BaseItemAnimator), ++ //Enables you to utilize layout animations better by unmounting removed items. Please note, this might increase unmounts ++ //on large data changes. ++ optimizeForInsertDeleteAnimations: PropTypes.bool, ++ //To pass down style to inner ScrollView ++ style: PropTypes.oneOfType([ ++ PropTypes.object, ++ PropTypes.number, ++ ]), ++ //For TS use case, not necessary with JS use. ++ //For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread ++ //and passed down. ++ scrollViewProps: PropTypes.object, ++}; ++//# sourceMappingURL=RecyclerListView.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js.map b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js.map +new file mode 100644 +index 0000000..4c15713 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"RecyclerListView.js","sourceRoot":"","sources":["../../../src/core/RecyclerListView.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.d.ts +new file mode 100644 +index 0000000..e712796 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.d.ts +@@ -0,0 +1,49 @@ ++/** ++ * Created by ananya.chandra on 14/09/18. ++ */ ++import * as React from "react"; ++import { StyleProp, ViewStyle } from "react-native"; ++import { RecyclerListViewProps } from "./RecyclerListView"; ++export interface StickyContainerProps { ++ children: RecyclerChild; ++ stickyHeaderIndices?: number[]; ++ stickyFooterIndices?: number[]; ++ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++ style?: StyleProp; ++} ++export interface RecyclerChild extends React.ReactElement { ++ ref: (recyclerRef: any) => {}; ++ props: RecyclerListViewProps; ++} ++export default class StickyContainer

extends React.Component

{ ++ static propTypes: {}; ++ private _recyclerRef; ++ private _dataProvider; ++ private _layoutProvider; ++ private _extendedState; ++ private _rowRenderer; ++ private _distanceFromWindow; ++ private _stickyHeaderRef; ++ private _stickyFooterRef; ++ private _visibleIndicesAll; ++ constructor(props: P, context?: any); ++ componentWillReceiveProps(newProps: P): void; ++ render(): JSX.Element; ++ private _getRecyclerRef; ++ private _getStickyHeaderRef; ++ private _getStickyFooterRef; ++ private _onVisibleIndicesChanged; ++ private _callStickyObjectsOnVisibleIndicesChanged; ++ private _onScroll; ++ private _assertChildType; ++ private _isChildRecyclerInstance; ++ private _getLayoutForIndex; ++ private _getDataForIndex; ++ private _getLayoutTypeForIndex; ++ private _getExtendedState; ++ private _getRowRenderer; ++ private _getRLVRenderedSize; ++ private _getContentDimension; ++ private _getDistanceFromWindow; ++ private _initParams; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js +new file mode 100644 +index 0000000..8de1ec4 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js +@@ -0,0 +1,187 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 14/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var PropTypes = require("prop-types"); ++var react_native_1 = require("react-native"); ++var StickyHeader_1 = require("./sticky/StickyHeader"); ++var StickyFooter_1 = require("./sticky/StickyFooter"); ++var CustomError_1 = require("./exceptions/CustomError"); ++var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); ++var StickyContainer = /** @class */ (function (_super) { ++ __extends(StickyContainer, _super); ++ function StickyContainer(props, context) { ++ var _this = _super.call(this, props, context) || this; ++ _this._recyclerRef = undefined; ++ _this._stickyHeaderRef = null; ++ _this._stickyFooterRef = null; ++ _this._visibleIndicesAll = []; ++ _this._getRecyclerRef = function (recycler) { ++ _this._recyclerRef = recycler; ++ if (_this.props.children.ref) { ++ if (typeof _this.props.children.ref === "function") { ++ (_this.props.children).ref(recycler); ++ } ++ else { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.refNotAsFunctionException); ++ } ++ } ++ }; ++ _this._getStickyHeaderRef = function (stickyHeaderRef) { ++ if (_this._stickyHeaderRef !== stickyHeaderRef) { ++ _this._stickyHeaderRef = stickyHeaderRef; ++ // TODO: Resetting state once ref is initialized. Can look for better solution. ++ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); ++ } ++ }; ++ _this._getStickyFooterRef = function (stickyFooterRef) { ++ if (_this._stickyFooterRef !== stickyFooterRef) { ++ _this._stickyFooterRef = stickyFooterRef; ++ // TODO: Resetting state once ref is initialized. Can look for better solution. ++ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); ++ } ++ }; ++ _this._onVisibleIndicesChanged = function (all, now, notNow) { ++ _this._visibleIndicesAll = all; ++ _this._callStickyObjectsOnVisibleIndicesChanged(all); ++ if (_this.props.children && _this.props.children.props && _this.props.children.props.onVisibleIndicesChanged) { ++ _this.props.children.props.onVisibleIndicesChanged(all, now, notNow); ++ } ++ }; ++ _this._callStickyObjectsOnVisibleIndicesChanged = function (all) { ++ if (_this._stickyHeaderRef) { ++ _this._stickyHeaderRef.onVisibleIndicesChanged(all); ++ } ++ if (_this._stickyFooterRef) { ++ _this._stickyFooterRef.onVisibleIndicesChanged(all); ++ } ++ }; ++ _this._onScroll = function (rawEvent, offsetX, offsetY) { ++ if (_this._stickyHeaderRef) { ++ _this._stickyHeaderRef.onScroll(offsetY); ++ } ++ if (_this._stickyFooterRef) { ++ _this._stickyFooterRef.onScroll(offsetY); ++ } ++ if (_this.props.children && _this.props.children.props.onScroll) { ++ _this.props.children.props.onScroll(rawEvent, offsetX, offsetY); ++ } ++ }; ++ _this._assertChildType = function () { ++ if (React.Children.count(_this.props.children) !== 1 || !_this._isChildRecyclerInstance()) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.wrongStickyChildTypeException); ++ } ++ }; ++ _this._isChildRecyclerInstance = function () { ++ return (_this.props.children.props.dataProvider ++ && _this.props.children.props.rowRenderer ++ && _this.props.children.props.layoutProvider); ++ }; ++ _this._getLayoutForIndex = function (index) { ++ if (_this._recyclerRef) { ++ return _this._recyclerRef.getLayout(index); ++ } ++ return undefined; ++ }; ++ _this._getDataForIndex = function (index) { ++ return _this._dataProvider.getDataForIndex(index); ++ }; ++ _this._getLayoutTypeForIndex = function (index) { ++ return _this._layoutProvider.getLayoutTypeForIndex(index); ++ }; ++ _this._getExtendedState = function () { ++ return _this._extendedState; ++ }; ++ _this._getRowRenderer = function () { ++ return _this._rowRenderer; ++ }; ++ _this._getRLVRenderedSize = function () { ++ if (_this._recyclerRef) { ++ return _this._recyclerRef.getRenderedSize(); ++ } ++ return undefined; ++ }; ++ _this._getContentDimension = function () { ++ if (_this._recyclerRef) { ++ return _this._recyclerRef.getContentDimension(); ++ } ++ return undefined; ++ }; ++ _this._getDistanceFromWindow = function () { ++ return _this._distanceFromWindow; ++ }; ++ _this._initParams = function (props) { ++ var childProps = props.children.props; ++ _this._dataProvider = childProps.dataProvider; ++ _this._layoutProvider = childProps.layoutProvider; ++ _this._extendedState = childProps.extendedState; ++ _this._rowRenderer = childProps.rowRenderer; ++ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; ++ }; ++ _this._assertChildType(); ++ var childProps = props.children.props; ++ _this._dataProvider = childProps.dataProvider; ++ _this._layoutProvider = childProps.layoutProvider; ++ _this._extendedState = childProps.extendedState; ++ _this._rowRenderer = childProps.rowRenderer; ++ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; ++ return _this; ++ } ++ StickyContainer.prototype.componentWillReceiveProps = function (newProps) { ++ this._initParams(newProps); ++ }; ++ StickyContainer.prototype.render = function () { ++ var _this = this; ++ this._assertChildType(); ++ var recycler = React.cloneElement(this.props.children, __assign({}, this.props.children.props, { ref: this._getRecyclerRef, onVisibleIndicesChanged: this._onVisibleIndicesChanged, onScroll: this._onScroll })); ++ return (React.createElement(react_native_1.View, { style: this.props.style ? this.props.style : { flex: 1 } }, ++ recycler, ++ this.props.stickyHeaderIndices ? (React.createElement(StickyHeader_1.default, { ref: function (stickyHeaderRef) { return _this._getStickyHeaderRef(stickyHeaderRef); }, stickyIndices: this.props.stickyHeaderIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null, ++ this.props.stickyFooterIndices ? (React.createElement(StickyFooter_1.default, { ref: function (stickyFooterRef) { return _this._getStickyFooterRef(stickyFooterRef); }, stickyIndices: this.props.stickyFooterIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null)); ++ }; ++ StickyContainer.propTypes = {}; ++ return StickyContainer; ++}(React.Component)); ++exports.default = StickyContainer; ++StickyContainer.propTypes = { ++ // Mandatory to pass a single child of RecyclerListView or any of its children classes. Exception will be thrown otherwise. ++ children: PropTypes.element.isRequired, ++ // Provide an array of indices whose corresponding items need to be stuck to the top of the recyclerView once the items scroll off the top. ++ // Every subsequent sticky index view will push the previous sticky view off the top to take its place. ++ // Note - Needs to be sorted ascending ++ stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), ++ // Works same as sticky headers, but for views to be stuck at the bottom of the recyclerView. ++ // Note - Needs to be sorted ascending ++ stickyFooterIndices: PropTypes.arrayOf(PropTypes.number), ++ // Will be called instead of rowRenderer for all sticky items. Any changes to the item for when they are stuck can be done here. ++ overrideRowRenderer: PropTypes.func, ++ // For all practical purposes, pass the style that is applied to the RecyclerListView component here. ++ style: PropTypes.object, ++}; ++//# sourceMappingURL=StickyContainer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js.map b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js.map +new file mode 100644 +index 0000000..4dc4cf2 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyContainer.js","sourceRoot":"","sources":["../../../src/core/StickyContainer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.d.ts +new file mode 100644 +index 0000000..820022a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.d.ts +@@ -0,0 +1,61 @@ ++import { Dimension } from "./dependencies/LayoutProvider"; ++import { Layout } from "./layoutmanager/LayoutManager"; ++/*** ++ * Given an offset this utility can compute visible items. Also tracks previously visible items to compute items which get hidden or visible ++ * Virtual renderer uses callbacks from this utility to main recycle pool and the render stack. ++ * The utility optimizes finding visible indexes by using the last visible items. However, that can be slow if scrollToOffset is explicitly called. ++ * We use binary search to optimize in most cases like while finding first visible item or initial offset. In future we'll also be using BS to speed up ++ * scroll to offset. ++ */ ++export interface Range { ++ start: number; ++ end: number; ++} ++export declare type TOnItemStatusChanged = ((all: number[], now: number[], notNow: number[]) => void); ++export default class ViewabilityTracker { ++ onVisibleRowsChanged: TOnItemStatusChanged | null; ++ onEngagedRowsChanged: TOnItemStatusChanged | null; ++ private _currentOffset; ++ private _maxOffset; ++ private _renderAheadOffset; ++ private _visibleWindow; ++ private _engagedWindow; ++ private _relevantDim; ++ private _isHorizontal; ++ private _windowBound; ++ private _visibleIndexes; ++ private _engagedIndexes; ++ private _layouts; ++ private _actualOffset; ++ constructor(renderAheadOffset: number, initialOffset: number); ++ init(): void; ++ setLayouts(layouts: Layout[], maxOffset: number): void; ++ setDimensions(dimension: Dimension, isHorizontal: boolean): void; ++ forceRefresh(): boolean; ++ forceRefreshWithOffset(offset: number): void; ++ updateOffset(offset: number, correction: number, isActual: boolean): void; ++ getLastOffset(): number; ++ getLastActualOffset(): number; ++ getEngagedIndexes(): number[]; ++ findFirstLogicallyVisibleIndex(): number; ++ updateRenderAheadOffset(renderAheadOffset: number): void; ++ getCurrentRenderAheadOffset(): number; ++ private _findFirstVisibleIndexOptimally; ++ private _fitAndUpdate; ++ private _doInitialFit; ++ private _findFirstVisibleIndexLinearly; ++ private _findFirstVisibleIndexUsingBS; ++ private _valueExtractorForBinarySearch; ++ private _fitIndexes; ++ private _checkIntersectionAndReport; ++ private _setRelevantBounds; ++ private _isItemInBounds; ++ private _isItemBoundsBeyondWindow; ++ private _itemIntersectsWindow; ++ private _itemIntersectsEngagedWindow; ++ private _itemIntersectsVisibleWindow; ++ private _updateTrackingWindows; ++ private _diffUpdateOriginalIndexesAndRaiseEvents; ++ private _diffArraysAndCallFunc; ++ private _calculateArrayDiff; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js +new file mode 100644 +index 0000000..dc8271a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js +@@ -0,0 +1,266 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var BinarySearch_1 = require("../utils/BinarySearch"); ++var ViewabilityTracker = /** @class */ (function () { ++ function ViewabilityTracker(renderAheadOffset, initialOffset) { ++ var _this = this; ++ this._layouts = []; ++ this._valueExtractorForBinarySearch = function (index) { ++ var itemRect = _this._layouts[index]; ++ _this._setRelevantBounds(itemRect, _this._relevantDim); ++ return _this._relevantDim.end; ++ }; ++ this._currentOffset = Math.max(0, initialOffset); ++ this._maxOffset = 0; ++ this._actualOffset = 0; ++ this._renderAheadOffset = renderAheadOffset; ++ this._visibleWindow = { start: 0, end: 0 }; ++ this._engagedWindow = { start: 0, end: 0 }; ++ this._isHorizontal = false; ++ this._windowBound = 0; ++ this._visibleIndexes = []; //needs to be sorted ++ this._engagedIndexes = []; //needs to be sorted ++ this.onVisibleRowsChanged = null; ++ this.onEngagedRowsChanged = null; ++ this._relevantDim = { start: 0, end: 0 }; ++ } ++ ViewabilityTracker.prototype.init = function () { ++ this._doInitialFit(this._currentOffset); ++ }; ++ ViewabilityTracker.prototype.setLayouts = function (layouts, maxOffset) { ++ this._layouts = layouts; ++ this._maxOffset = maxOffset; ++ }; ++ ViewabilityTracker.prototype.setDimensions = function (dimension, isHorizontal) { ++ this._isHorizontal = isHorizontal; ++ this._windowBound = isHorizontal ? dimension.width : dimension.height; ++ }; ++ ViewabilityTracker.prototype.forceRefresh = function () { ++ this.forceRefreshWithOffset(this._currentOffset); ++ return false; ++ }; ++ ViewabilityTracker.prototype.forceRefreshWithOffset = function (offset) { ++ this._currentOffset = -1; ++ this.updateOffset(offset, 0, false); ++ }; ++ ViewabilityTracker.prototype.updateOffset = function (offset, correction, isActual) { ++ if (isActual) { ++ this._actualOffset = offset; ++ } ++ offset = Math.min(this._maxOffset, Math.max(0, offset + correction)); ++ if (this._currentOffset !== offset) { ++ this._currentOffset = offset; ++ this._updateTrackingWindows(offset); ++ var startIndex = 0; ++ if (this._visibleIndexes.length > 0) { ++ startIndex = this._visibleIndexes[0]; ++ } ++ this._fitAndUpdate(startIndex); ++ } ++ }; ++ ViewabilityTracker.prototype.getLastOffset = function () { ++ return this._currentOffset; ++ }; ++ ViewabilityTracker.prototype.getLastActualOffset = function () { ++ return this._actualOffset; ++ }; ++ ViewabilityTracker.prototype.getEngagedIndexes = function () { ++ return this._engagedIndexes; ++ }; ++ ViewabilityTracker.prototype.findFirstLogicallyVisibleIndex = function () { ++ var relevantIndex = this._findFirstVisibleIndexUsingBS(0.001); ++ var result = relevantIndex; ++ for (var i = relevantIndex - 1; i >= 0; i--) { ++ if (this._isHorizontal) { ++ if (this._layouts[relevantIndex].x !== this._layouts[i].x) { ++ break; ++ } ++ else { ++ result = i; ++ } ++ } ++ else { ++ if (this._layouts[relevantIndex].y !== this._layouts[i].y) { ++ break; ++ } ++ else { ++ result = i; ++ } ++ } ++ } ++ return result; ++ }; ++ ViewabilityTracker.prototype.updateRenderAheadOffset = function (renderAheadOffset) { ++ this._renderAheadOffset = Math.max(0, renderAheadOffset); ++ this.forceRefreshWithOffset(this._currentOffset); ++ }; ++ ViewabilityTracker.prototype.getCurrentRenderAheadOffset = function () { ++ return this._renderAheadOffset; ++ }; ++ ViewabilityTracker.prototype._findFirstVisibleIndexOptimally = function () { ++ var firstVisibleIndex = 0; ++ //TODO: Talha calculate this value smartly ++ if (this._currentOffset > 5000) { ++ firstVisibleIndex = this._findFirstVisibleIndexUsingBS(); ++ } ++ else if (this._currentOffset > 0) { ++ firstVisibleIndex = this._findFirstVisibleIndexLinearly(); ++ } ++ return firstVisibleIndex; ++ }; ++ ViewabilityTracker.prototype._fitAndUpdate = function (startIndex) { ++ var newVisibleItems = []; ++ var newEngagedItems = []; ++ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex, true); ++ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex + 1, false); ++ this._diffUpdateOriginalIndexesAndRaiseEvents(newVisibleItems, newEngagedItems); ++ }; ++ ViewabilityTracker.prototype._doInitialFit = function (offset) { ++ offset = Math.min(this._maxOffset, Math.max(0, offset)); ++ this._updateTrackingWindows(offset); ++ var firstVisibleIndex = this._findFirstVisibleIndexOptimally(); ++ this._fitAndUpdate(firstVisibleIndex); ++ }; ++ //TODO:Talha switch to binary search and remove atleast once logic in _fitIndexes ++ ViewabilityTracker.prototype._findFirstVisibleIndexLinearly = function () { ++ var count = this._layouts.length; ++ var itemRect = null; ++ var relevantDim = { start: 0, end: 0 }; ++ for (var i = 0; i < count; i++) { ++ itemRect = this._layouts[i]; ++ this._setRelevantBounds(itemRect, relevantDim); ++ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { ++ return i; ++ } ++ } ++ return 0; ++ }; ++ ViewabilityTracker.prototype._findFirstVisibleIndexUsingBS = function (bias) { ++ if (bias === void 0) { bias = 0; } ++ var count = this._layouts.length; ++ return BinarySearch_1.default.findClosestHigherValueIndex(count, this._visibleWindow.start + bias, this._valueExtractorForBinarySearch); ++ }; ++ //TODO:Talha Optimize further in later revisions, alteast once logic can be replace with a BS lookup ++ ViewabilityTracker.prototype._fitIndexes = function (newVisibleIndexes, newEngagedIndexes, startIndex, isReverse) { ++ var count = this._layouts.length; ++ var relevantDim = { start: 0, end: 0 }; ++ var i = 0; ++ var atLeastOneLocated = false; ++ if (startIndex < count) { ++ if (!isReverse) { ++ for (i = startIndex; i < count; i++) { ++ if (this._checkIntersectionAndReport(i, false, relevantDim, newVisibleIndexes, newEngagedIndexes)) { ++ atLeastOneLocated = true; ++ } ++ else { ++ if (atLeastOneLocated) { ++ break; ++ } ++ } ++ } ++ } ++ else { ++ for (i = startIndex; i >= 0; i--) { ++ if (this._checkIntersectionAndReport(i, true, relevantDim, newVisibleIndexes, newEngagedIndexes)) { ++ atLeastOneLocated = true; ++ } ++ else { ++ if (atLeastOneLocated) { ++ break; ++ } ++ } ++ } ++ } ++ } ++ }; ++ ViewabilityTracker.prototype._checkIntersectionAndReport = function (index, insertOnTop, relevantDim, newVisibleIndexes, newEngagedIndexes) { ++ var itemRect = this._layouts[index]; ++ var isFound = false; ++ this._setRelevantBounds(itemRect, relevantDim); ++ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { ++ if (insertOnTop) { ++ newVisibleIndexes.splice(0, 0, index); ++ newEngagedIndexes.splice(0, 0, index); ++ } ++ else { ++ newVisibleIndexes.push(index); ++ newEngagedIndexes.push(index); ++ } ++ isFound = true; ++ } ++ else if (this._itemIntersectsEngagedWindow(relevantDim.start, relevantDim.end)) { ++ //TODO: This needs to be optimized ++ if (insertOnTop) { ++ newEngagedIndexes.splice(0, 0, index); ++ } ++ else { ++ newEngagedIndexes.push(index); ++ } ++ isFound = true; ++ } ++ return isFound; ++ }; ++ ViewabilityTracker.prototype._setRelevantBounds = function (itemRect, relevantDim) { ++ if (this._isHorizontal) { ++ relevantDim.end = itemRect.x + itemRect.width; ++ relevantDim.start = itemRect.x; ++ } ++ else { ++ relevantDim.end = itemRect.y + itemRect.height; ++ relevantDim.start = itemRect.y; ++ } ++ }; ++ ViewabilityTracker.prototype._isItemInBounds = function (window, itemBound) { ++ return (window.start < itemBound && window.end > itemBound); ++ }; ++ ViewabilityTracker.prototype._isItemBoundsBeyondWindow = function (window, startBound, endBound) { ++ return (window.start >= startBound && window.end <= endBound); ++ }; ++ ViewabilityTracker.prototype._itemIntersectsWindow = function (window, startBound, endBound) { ++ return this._isItemInBounds(window, startBound) || ++ this._isItemInBounds(window, endBound) || ++ this._isItemBoundsBeyondWindow(window, startBound, endBound); ++ }; ++ ViewabilityTracker.prototype._itemIntersectsEngagedWindow = function (startBound, endBound) { ++ return this._itemIntersectsWindow(this._engagedWindow, startBound, endBound); ++ }; ++ ViewabilityTracker.prototype._itemIntersectsVisibleWindow = function (startBound, endBound) { ++ return this._itemIntersectsWindow(this._visibleWindow, startBound, endBound); ++ }; ++ ViewabilityTracker.prototype._updateTrackingWindows = function (newOffset) { ++ this._engagedWindow.start = Math.max(0, newOffset - this._renderAheadOffset); ++ this._engagedWindow.end = newOffset + this._windowBound + this._renderAheadOffset; ++ this._visibleWindow.start = newOffset; ++ this._visibleWindow.end = newOffset + this._windowBound; ++ }; ++ //TODO:Talha optimize this ++ ViewabilityTracker.prototype._diffUpdateOriginalIndexesAndRaiseEvents = function (newVisibleItems, newEngagedItems) { ++ this._diffArraysAndCallFunc(newVisibleItems, this._visibleIndexes, this.onVisibleRowsChanged); ++ this._diffArraysAndCallFunc(newEngagedItems, this._engagedIndexes, this.onEngagedRowsChanged); ++ this._visibleIndexes = newVisibleItems; ++ this._engagedIndexes = newEngagedItems; ++ }; ++ ViewabilityTracker.prototype._diffArraysAndCallFunc = function (newItems, oldItems, func) { ++ if (func) { ++ var now = this._calculateArrayDiff(newItems, oldItems); ++ var notNow = this._calculateArrayDiff(oldItems, newItems); ++ if (now.length > 0 || notNow.length > 0) { ++ func(newItems.slice(), now, notNow); ++ } ++ } ++ }; ++ //TODO:Talha since arrays are sorted this can be much faster ++ ViewabilityTracker.prototype._calculateArrayDiff = function (arr1, arr2) { ++ var len = arr1.length; ++ var diffArr = []; ++ for (var i = 0; i < len; i++) { ++ if (BinarySearch_1.default.findIndexOf(arr2, arr1[i]) === -1) { ++ diffArr.push(arr1[i]); ++ } ++ } ++ return diffArr; ++ }; ++ return ViewabilityTracker; ++}()); ++exports.default = ViewabilityTracker; ++//# sourceMappingURL=ViewabilityTracker.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js.map b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js.map +new file mode 100644 +index 0000000..ba78826 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewabilityTracker.js","sourceRoot":"","sources":["../../../src/core/ViewabilityTracker.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.d.ts +new file mode 100644 +index 0000000..190e53a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.d.ts +@@ -0,0 +1,66 @@ ++import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; ++import { Point, LayoutManager } from "./layoutmanager/LayoutManager"; ++import ViewabilityTracker, { TOnItemStatusChanged } from "./ViewabilityTracker"; ++import { BaseDataProvider } from "./dependencies/DataProvider"; ++/*** ++ * Renderer which keeps track of recyclable items and the currently rendered items. Notifies list view to re render if something changes, like scroll offset ++ */ ++export interface RenderStackItem { ++ dataIndex?: number; ++} ++export interface StableIdMapItem { ++ key: string; ++ type: string | number; ++} ++export interface RenderStack { ++ [key: string]: RenderStackItem; ++} ++export interface RenderStackParams { ++ isHorizontal?: boolean; ++ itemCount: number; ++ initialOffset?: number; ++ initialRenderIndex?: number; ++ renderAheadOffset?: number; ++} ++export declare type StableIdProvider = (index: number) => string; ++export default class VirtualRenderer { ++ private onVisibleItemsChanged; ++ private _scrollOnNextUpdate; ++ private _stableIdToRenderKeyMap; ++ private _engagedIndexes; ++ private _renderStack; ++ private _renderStackChanged; ++ private _fetchStableId; ++ private _isRecyclingEnabled; ++ private _isViewTrackerRunning; ++ private _markDirty; ++ private _startKey; ++ private _layoutProvider; ++ private _recyclePool; ++ private _params; ++ private _layoutManager; ++ private _viewabilityTracker; ++ private _dimensions; ++ constructor(renderStackChanged: (renderStack: RenderStack) => void, scrollOnNextUpdate: (point: Point) => void, fetchStableId: StableIdProvider, isRecyclingEnabled: boolean); ++ getLayoutDimension(): Dimension; ++ updateOffset(offsetX: number, offsetY: number, correction: number, isActual: boolean): void; ++ attachVisibleItemsListener(callback: TOnItemStatusChanged): void; ++ removeVisibleItemsListener(): void; ++ getLayoutManager(): LayoutManager | null; ++ setParamsAndDimensions(params: RenderStackParams, dim: Dimension): void; ++ setLayoutManager(layoutManager: LayoutManager): void; ++ setLayoutProvider(layoutProvider: BaseLayoutProvider): void; ++ getViewabilityTracker(): ViewabilityTracker | null; ++ refreshWithAnchor(): void; ++ refresh(): void; ++ getInitialOffset(): Point; ++ init(): void; ++ startViewabilityTracker(): void; ++ syncAndGetKey(index: number, overrideStableIdProvider?: StableIdProvider, newRenderStack?: RenderStack): string; ++ handleDataSetChange(newDataProvider: BaseDataProvider, shouldOptimizeForAnimations?: boolean): void; ++ private _getCollisionAvoidingKey; ++ private _prepareViewabilityTracker; ++ private _onVisibleItemsChanged; ++ private _onEngagedItemsChanged; ++ private _updateRenderStack; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js +new file mode 100644 +index 0000000..921ccbc +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js +@@ -0,0 +1,321 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecycleItemPool_1 = require("../utils/RecycleItemPool"); ++var CustomError_1 = require("./exceptions/CustomError"); ++var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); ++var ViewabilityTracker_1 = require("./ViewabilityTracker"); ++var ts_object_utils_1 = require("ts-object-utils"); ++var TSCast_1 = require("../utils/TSCast"); ++var VirtualRenderer = /** @class */ (function () { ++ function VirtualRenderer(renderStackChanged, scrollOnNextUpdate, fetchStableId, isRecyclingEnabled) { ++ var _this = this; ++ this._layoutProvider = TSCast_1.default.cast(null); //TSI ++ this._recyclePool = TSCast_1.default.cast(null); //TSI ++ this._layoutManager = null; ++ this._viewabilityTracker = null; ++ this._onVisibleItemsChanged = function (all, now, notNow) { ++ if (_this.onVisibleItemsChanged) { ++ _this.onVisibleItemsChanged(all, now, notNow); ++ } ++ }; ++ this._onEngagedItemsChanged = function (all, now, notNow) { ++ var count = notNow.length; ++ var resolvedKey; ++ var disengagedIndex = 0; ++ if (_this._isRecyclingEnabled) { ++ for (var i = 0; i < count; i++) { ++ disengagedIndex = notNow[i]; ++ delete _this._engagedIndexes[disengagedIndex]; ++ if (_this._params && disengagedIndex < _this._params.itemCount) { ++ //All the items which are now not visible can go to the recycle pool, the pool only needs to maintain keys since ++ //react can link a view to a key automatically ++ resolvedKey = _this._stableIdToRenderKeyMap[_this._fetchStableId(disengagedIndex)]; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(resolvedKey)) { ++ _this._recyclePool.putRecycledObject(_this._layoutProvider.getLayoutTypeForIndex(disengagedIndex), resolvedKey.key); ++ } ++ } ++ } ++ } ++ if (_this._updateRenderStack(now)) { ++ //Ask Recycler View to update itself ++ _this._renderStackChanged(_this._renderStack); ++ } ++ }; ++ //Keeps track of items that need to be rendered in the next render cycle ++ this._renderStack = {}; ++ this._fetchStableId = fetchStableId; ++ //Keeps track of keys of all the currently rendered indexes, can eventually replace renderStack as well if no new use cases come up ++ this._stableIdToRenderKeyMap = {}; ++ this._engagedIndexes = {}; ++ this._renderStackChanged = renderStackChanged; ++ this._scrollOnNextUpdate = scrollOnNextUpdate; ++ this._dimensions = null; ++ this._params = null; ++ this._isRecyclingEnabled = isRecyclingEnabled; ++ this._isViewTrackerRunning = false; ++ this._markDirty = false; ++ //Would be surprised if someone exceeds this ++ this._startKey = 0; ++ this.onVisibleItemsChanged = null; ++ } ++ VirtualRenderer.prototype.getLayoutDimension = function () { ++ if (this._layoutManager) { ++ return this._layoutManager.getContentDimension(); ++ } ++ return { height: 0, width: 0 }; ++ }; ++ VirtualRenderer.prototype.updateOffset = function (offsetX, offsetY, correction, isActual) { ++ if (this._viewabilityTracker) { ++ if (!this._isViewTrackerRunning) { ++ this.startViewabilityTracker(); ++ } ++ if (this._params && this._params.isHorizontal) { ++ this._viewabilityTracker.updateOffset(offsetX, correction, isActual); ++ } ++ else { ++ this._viewabilityTracker.updateOffset(offsetY, correction, isActual); ++ } ++ } ++ }; ++ VirtualRenderer.prototype.attachVisibleItemsListener = function (callback) { ++ this.onVisibleItemsChanged = callback; ++ }; ++ VirtualRenderer.prototype.removeVisibleItemsListener = function () { ++ this.onVisibleItemsChanged = null; ++ if (this._viewabilityTracker) { ++ this._viewabilityTracker.onVisibleRowsChanged = null; ++ } ++ }; ++ VirtualRenderer.prototype.getLayoutManager = function () { ++ return this._layoutManager; ++ }; ++ VirtualRenderer.prototype.setParamsAndDimensions = function (params, dim) { ++ this._params = params; ++ this._dimensions = dim; ++ }; ++ VirtualRenderer.prototype.setLayoutManager = function (layoutManager) { ++ this._layoutManager = layoutManager; ++ if (this._params) { ++ this._layoutManager.relayoutFromIndex(0, this._params.itemCount); ++ } ++ }; ++ VirtualRenderer.prototype.setLayoutProvider = function (layoutProvider) { ++ this._layoutProvider = layoutProvider; ++ }; ++ VirtualRenderer.prototype.getViewabilityTracker = function () { ++ return this._viewabilityTracker; ++ }; ++ VirtualRenderer.prototype.refreshWithAnchor = function () { ++ if (this._viewabilityTracker) { ++ var firstVisibleIndex = this._viewabilityTracker.findFirstLogicallyVisibleIndex(); ++ this._prepareViewabilityTracker(); ++ var offset = 0; ++ if (this._layoutManager && this._params) { ++ var point = this._layoutManager.getOffsetForIndex(firstVisibleIndex); ++ this._scrollOnNextUpdate(point); ++ offset = this._params.isHorizontal ? point.x : point.y; ++ } ++ this._viewabilityTracker.forceRefreshWithOffset(offset); ++ } ++ }; ++ VirtualRenderer.prototype.refresh = function () { ++ if (this._viewabilityTracker) { ++ this._prepareViewabilityTracker(); ++ if (this._viewabilityTracker.forceRefresh()) { ++ if (this._params && this._params.isHorizontal) { ++ this._scrollOnNextUpdate({ x: this._viewabilityTracker.getLastActualOffset(), y: 0 }); ++ } ++ else { ++ this._scrollOnNextUpdate({ x: 0, y: this._viewabilityTracker.getLastActualOffset() }); ++ } ++ } ++ } ++ }; ++ VirtualRenderer.prototype.getInitialOffset = function () { ++ var offset = { x: 0, y: 0 }; ++ if (this._params) { ++ var initialRenderIndex = ts_object_utils_1.Default.value(this._params.initialRenderIndex, 0); ++ if (initialRenderIndex > 0 && this._layoutManager) { ++ offset = this._layoutManager.getOffsetForIndex(initialRenderIndex); ++ this._params.initialOffset = this._params.isHorizontal ? offset.x : offset.y; ++ } ++ else { ++ if (this._params.isHorizontal) { ++ offset.x = ts_object_utils_1.Default.value(this._params.initialOffset, 0); ++ offset.y = 0; ++ } ++ else { ++ offset.y = ts_object_utils_1.Default.value(this._params.initialOffset, 0); ++ offset.x = 0; ++ } ++ } ++ } ++ return offset; ++ }; ++ VirtualRenderer.prototype.init = function () { ++ this.getInitialOffset(); ++ this._recyclePool = new RecycleItemPool_1.default(); ++ if (this._params) { ++ this._viewabilityTracker = new ViewabilityTracker_1.default(ts_object_utils_1.Default.value(this._params.renderAheadOffset, 0), ts_object_utils_1.Default.value(this._params.initialOffset, 0)); ++ } ++ else { ++ this._viewabilityTracker = new ViewabilityTracker_1.default(0, 0); ++ } ++ this._prepareViewabilityTracker(); ++ }; ++ VirtualRenderer.prototype.startViewabilityTracker = function () { ++ if (this._viewabilityTracker) { ++ this._isViewTrackerRunning = true; ++ this._viewabilityTracker.init(); ++ } ++ }; ++ VirtualRenderer.prototype.syncAndGetKey = function (index, overrideStableIdProvider, newRenderStack) { ++ var getStableId = overrideStableIdProvider ? overrideStableIdProvider : this._fetchStableId; ++ var renderStack = newRenderStack ? newRenderStack : this._renderStack; ++ var stableIdItem = this._stableIdToRenderKeyMap[getStableId(index)]; ++ var key = stableIdItem ? stableIdItem.key : undefined; ++ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { ++ var type = this._layoutProvider.getLayoutTypeForIndex(index); ++ key = this._recyclePool.getRecycledObject(type); ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { ++ var itemMeta = renderStack[key]; ++ if (itemMeta) { ++ var oldIndex = itemMeta.dataIndex; ++ itemMeta.dataIndex = index; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(oldIndex) && oldIndex !== index) { ++ delete this._stableIdToRenderKeyMap[getStableId(oldIndex)]; ++ } ++ } ++ else { ++ renderStack[key] = { dataIndex: index }; ++ } ++ } ++ else { ++ key = getStableId(index); ++ if (renderStack[key]) { ++ //Probable collision, warn and avoid ++ //TODO: Disabled incorrectly triggering in some cases ++ //console.warn("Possible stableId collision @", index); //tslint:disable-line ++ key = this._getCollisionAvoidingKey(); ++ } ++ renderStack[key] = { dataIndex: index }; ++ } ++ this._markDirty = true; ++ this._stableIdToRenderKeyMap[getStableId(index)] = { key: key, type: type }; ++ } ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { ++ this._recyclePool.removeFromPool(key); ++ } ++ var stackItem = renderStack[key]; ++ if (stackItem && stackItem.dataIndex !== index) { ++ //Probable collision, warn ++ console.warn("Possible stableId collision @", index); //tslint:disable-line ++ } ++ return key; ++ }; ++ //Further optimize in later revision, pretty fast for now considering this is a low frequency event ++ VirtualRenderer.prototype.handleDataSetChange = function (newDataProvider, shouldOptimizeForAnimations) { ++ var getStableId = newDataProvider.getStableId; ++ var maxIndex = newDataProvider.getSize() - 1; ++ var activeStableIds = {}; ++ var newRenderStack = {}; ++ //Compute active stable ids and stale active keys and resync render stack ++ for (var key in this._renderStack) { ++ if (this._renderStack.hasOwnProperty(key)) { ++ var index = this._renderStack[key].dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { ++ if (index <= maxIndex) { ++ var stableId = getStableId(index); ++ activeStableIds[stableId] = 1; ++ } ++ } ++ } ++ } ++ //Clean stable id to key map ++ var oldActiveStableIds = Object.keys(this._stableIdToRenderKeyMap); ++ var oldActiveStableIdsCount = oldActiveStableIds.length; ++ for (var i = 0; i < oldActiveStableIdsCount; i++) { ++ var key = oldActiveStableIds[i]; ++ if (!activeStableIds[key]) { ++ if (!shouldOptimizeForAnimations && this._isRecyclingEnabled) { ++ var stableIdItem = this._stableIdToRenderKeyMap[key]; ++ if (stableIdItem) { ++ this._recyclePool.putRecycledObject(stableIdItem.type, stableIdItem.key); ++ } ++ } ++ delete this._stableIdToRenderKeyMap[key]; ++ } ++ } ++ for (var key in this._renderStack) { ++ if (this._renderStack.hasOwnProperty(key)) { ++ var index = this._renderStack[key].dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { ++ if (index <= maxIndex) { ++ var newKey = this.syncAndGetKey(index, getStableId, newRenderStack); ++ var newStackItem = newRenderStack[newKey]; ++ if (!newStackItem) { ++ newRenderStack[newKey] = { dataIndex: index }; ++ } ++ else if (newStackItem.dataIndex !== index) { ++ var cllKey = this._getCollisionAvoidingKey(); ++ newRenderStack[cllKey] = { dataIndex: index }; ++ this._stableIdToRenderKeyMap[getStableId(index)] = { ++ key: cllKey, type: this._layoutProvider.getLayoutTypeForIndex(index), ++ }; ++ } ++ } ++ } ++ delete this._renderStack[key]; ++ } ++ } ++ Object.assign(this._renderStack, newRenderStack); ++ for (var key in this._renderStack) { ++ if (this._renderStack.hasOwnProperty(key)) { ++ var index = this._renderStack[key].dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index) && ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { ++ var type = this._layoutProvider.getLayoutTypeForIndex(index); ++ this._recyclePool.putRecycledObject(type, key); ++ } ++ } ++ } ++ }; ++ VirtualRenderer.prototype._getCollisionAvoidingKey = function () { ++ return "#" + this._startKey++ + "_rlv_c"; ++ }; ++ VirtualRenderer.prototype._prepareViewabilityTracker = function () { ++ if (this._viewabilityTracker && this._layoutManager && this._dimensions && this._params) { ++ this._viewabilityTracker.onEngagedRowsChanged = this._onEngagedItemsChanged; ++ if (this.onVisibleItemsChanged) { ++ this._viewabilityTracker.onVisibleRowsChanged = this._onVisibleItemsChanged; ++ } ++ this._viewabilityTracker.setLayouts(this._layoutManager.getLayouts(), this._params.isHorizontal ? ++ this._layoutManager.getContentDimension().width : ++ this._layoutManager.getContentDimension().height); ++ this._viewabilityTracker.setDimensions({ ++ height: this._dimensions.height, ++ width: this._dimensions.width, ++ }, ts_object_utils_1.Default.value(this._params.isHorizontal, false)); ++ } ++ else { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.initializationException); ++ } ++ }; ++ //Updates render stack and reports whether anything has changed ++ VirtualRenderer.prototype._updateRenderStack = function (itemIndexes) { ++ this._markDirty = false; ++ var count = itemIndexes.length; ++ var index = 0; ++ var hasRenderStackChanged = false; ++ for (var i = 0; i < count; i++) { ++ index = itemIndexes[i]; ++ this._engagedIndexes[index] = 1; ++ this.syncAndGetKey(index); ++ hasRenderStackChanged = this._markDirty; ++ } ++ this._markDirty = false; ++ return hasRenderStackChanged; ++ }; ++ return VirtualRenderer; ++}()); ++exports.default = VirtualRenderer; ++//# sourceMappingURL=VirtualRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js.map +new file mode 100644 +index 0000000..30876cc +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"VirtualRenderer.js","sourceRoot":"","sources":["../../../src/core/VirtualRenderer.ts"],"names":[],"mappings":";;AAAA,4DAAuD;AAEvD,wDAAmD;AACnD,sFAAiF;AAEjF,2DAAgF;AAChF,mDAAsD;AACtD,0CAAqC;AAyBrC;IAsBI,yBAAY,kBAAsD,EACtD,kBAA0C,EAC1C,aAA+B,EAC/B,kBAA2B;QAHvC,iBAyBC;QAjCO,oBAAe,GAAuB,gBAAM,CAAC,IAAI,CAAqB,IAAI,CAAC,CAAC,CAAC,KAAK;QAClF,iBAAY,GAAoB,gBAAM,CAAC,IAAI,CAAkB,IAAI,CAAC,CAAC,CAAC,KAAK;QAGzE,mBAAc,GAAyB,IAAI,CAAC;QAC5C,wBAAmB,GAA8B,IAAI,CAAC;QAiStD,2BAAsB,GAAG,UAAC,GAAa,EAAE,GAAa,EAAE,MAAgB;YAC5E,IAAI,KAAI,CAAC,qBAAqB,EAAE;gBAC5B,KAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;aAChD;QACL,CAAC,CAAA;QAEO,2BAAsB,GAAG,UAAC,GAAa,EAAE,GAAa,EAAE,MAAgB;YAC5E,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;YAC5B,IAAI,WAAW,CAAC;YAChB,IAAI,eAAe,GAAG,CAAC,CAAC;YACxB,IAAI,KAAI,CAAC,mBAAmB,EAAE;gBAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;oBAC5B,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;oBAC5B,OAAO,KAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;oBAC7C,IAAI,KAAI,CAAC,OAAO,IAAI,eAAe,GAAG,KAAI,CAAC,OAAO,CAAC,SAAS,EAAE;wBAC1D,gHAAgH;wBAChH,8CAA8C;wBAC9C,WAAW,GAAG,KAAI,CAAC,uBAAuB,CAAC,KAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC;wBACjF,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE;4BAC5C,KAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,KAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;yBACrH;qBACJ;iBACJ;aACJ;YACD,IAAI,KAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE;gBAC9B,oCAAoC;gBACpC,KAAI,CAAC,mBAAmB,CAAC,KAAI,CAAC,YAAY,CAAC,CAAC;aAC/C;QACL,CAAC,CAAA;QAtTG,wEAAwE;QACxE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QAEpC,mIAAmI;QACnI,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAE9C,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,4CAA4C;QAC5C,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAEnB,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;IACtC,CAAC;IAEM,4CAAkB,GAAzB;QACI,IAAI,IAAI,CAAC,cAAc,EAAE;YACrB,OAAO,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC;SACpD;QACD,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACnC,CAAC;IAEM,sCAAY,GAAnB,UAAoB,OAAe,EAAE,OAAe,EAAE,UAAkB,EAAE,QAAiB;QACvF,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;gBAC7B,IAAI,CAAC,uBAAuB,EAAE,CAAC;aAClC;YACD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;gBAC3C,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;aACxE;iBAAM;gBACH,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;aACxE;SACJ;IACL,CAAC;IAEM,oDAA0B,GAAjC,UAAkC,QAA8B;QAC5D,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC;IAC1C,CAAC;IAEM,oDAA0B,GAAjC;QACI,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAElC,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,mBAAmB,CAAC,oBAAoB,GAAG,IAAI,CAAC;SACxD;IACL,CAAC;IAEM,0CAAgB,GAAvB;QACI,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IAEM,gDAAsB,GAA7B,UAA8B,MAAyB,EAAE,GAAc;QACnE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IAC3B,CAAC;IAEM,0CAAgB,GAAvB,UAAwB,aAA4B;QAChD,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SACpE;IACL,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,cAAkC;QACvD,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;IAC1C,CAAC;IAEM,+CAAqB,GAA5B;QACI,OAAO,IAAI,CAAC,mBAAmB,CAAC;IACpC,CAAC;IAEM,2CAAiB,GAAxB;QACI,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAM,iBAAiB,GAAG,IAAI,CAAC,mBAAmB,CAAC,8BAA8B,EAAE,CAAC;YACpF,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAClC,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,EAAE;gBACrC,IAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;gBACvE,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;gBAChC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;aAC1D;YACD,IAAI,CAAC,mBAAmB,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;SAC3D;IACL,CAAC;IAEM,iCAAO,GAAd;QACI,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,EAAE;gBACzC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;oBAC3C,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;iBACzF;qBAAM;oBACH,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;iBACzF;aACJ;SACJ;IACL,CAAC;IAEM,0CAAgB,GAAvB;QACI,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,OAAO,EAAE;YACd,IAAM,kBAAkB,GAAG,yBAAO,CAAC,KAAK,CAAS,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;YACrF,IAAI,kBAAkB,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE;gBAC/C,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;gBACnE,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;aAChF;iBAAM;gBACH,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;oBAC3B,MAAM,CAAC,CAAC,GAAG,yBAAO,CAAC,KAAK,CAAS,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;oBAChE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;iBAChB;qBAAM;oBACH,MAAM,CAAC,CAAC,GAAG,yBAAO,CAAC,KAAK,CAAS,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;oBAChE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;iBAChB;aACJ;SACJ;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,8BAAI,GAAX;QACI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,yBAAe,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,mBAAmB,GAAG,IAAI,4BAAkB,CAC7C,yBAAO,CAAC,KAAK,CAAS,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,EACxD,yBAAO,CAAC,KAAK,CAAS,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;SAC7D;aAAM;YACH,IAAI,CAAC,mBAAmB,GAAG,IAAI,4BAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SAC3D;QACD,IAAI,CAAC,0BAA0B,EAAE,CAAC;IACtC,CAAC;IAEM,iDAAuB,GAA9B;QACI,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAClC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;SACnC;IACL,CAAC;IAEM,uCAAa,GAApB,UAAqB,KAAa,EAAE,wBAA2C,EAAE,cAA4B;QACzG,IAAM,WAAW,GAAG,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;QAC9F,IAAM,WAAW,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QACxE,IAAM,YAAY,GAAG,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,IAAI,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtD,IAAI,4BAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;YACnC,IAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAC/D,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;gBACpC,IAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,QAAQ,EAAE;oBACV,IAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC;oBACpC,QAAQ,CAAC,SAAS,GAAG,KAAK,CAAC;oBAC3B,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE;wBAC/D,OAAO,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;qBAC9D;iBACJ;qBAAM;oBACH,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;iBAC3C;aACJ;iBAAM;gBACH,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;gBACzB,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE;oBAClB,oCAAoC;oBACpC,qDAAqD;oBACrD,6EAA6E;oBAC7E,GAAG,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAC;iBACzC;gBACD,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;aAC3C;YACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAA,EAAE,IAAI,MAAA,EAAE,CAAC;SACpE;QACD,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE;YAC5D,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;SACzC;QACD,IAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,SAAS,IAAI,SAAS,CAAC,SAAS,KAAK,KAAK,EAAE;YAC5C,0BAA0B;YAC1B,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB;SAC9E;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED,mGAAmG;IAC5F,6CAAmB,GAA1B,UAA2B,eAAiC,EAAE,2BAAqC;QAC/F,IAAM,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC;QAChD,IAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAM,eAAe,GAA8B,EAAE,CAAC;QACtD,IAAM,cAAc,GAAgB,EAAE,CAAC;QAEvC,yEAAyE;QACzE,KAAK,IAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;YACjC,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;gBACvC,IAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;gBAC/C,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE;oBACtC,IAAI,KAAK,IAAI,QAAQ,EAAE;wBACnB,IAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;wBACpC,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;qBACjC;iBACJ;aACJ;SACJ;QAED,4BAA4B;QAC5B,IAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrE,IAAM,uBAAuB,GAAG,kBAAkB,CAAC,MAAM,CAAC;QAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,uBAAuB,EAAE,CAAC,EAAE,EAAE;YAC9C,IAAM,GAAG,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;gBACvB,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,mBAAmB,EAAE;oBAC1D,IAAM,YAAY,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;oBACvD,IAAI,YAAY,EAAE;wBACd,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;qBAC5E;iBACJ;gBACD,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;aAC5C;SACJ;QAED,KAAK,IAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;YACjC,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;gBACvC,IAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;gBAC/C,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE;oBACtC,IAAI,KAAK,IAAI,QAAQ,EAAE;wBACnB,IAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;wBACtE,IAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;wBAC5C,IAAI,CAAC,YAAY,EAAE;4BACf,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;yBACjD;6BAAM,IAAI,YAAY,CAAC,SAAS,KAAK,KAAK,EAAE;4BACzC,IAAM,MAAM,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAC;4BAC/C,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4BAC9C,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG;gCAC/C,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC;6BACvE,CAAC;yBACL;qBACJ;iBACJ;gBACD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;aACjC;SACJ;QACD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QAEjD,KAAK,IAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;YACjC,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;gBACvC,IAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;gBAC/C,IAAI,CAAC,4BAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,4BAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE;oBACnG,IAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;oBAC/D,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;iBAClD;aACJ;SACJ;IACL,CAAC;IAEO,kDAAwB,GAAhC;QACI,OAAO,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,CAAC;IAC7C,CAAC;IAEO,oDAA0B,GAAlC;QACI,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE;YACrF,IAAI,CAAC,mBAAmB,CAAC,oBAAoB,GAAG,IAAI,CAAC,sBAAsB,CAAC;YAC5E,IAAI,IAAI,CAAC,qBAAqB,EAAE;gBAC5B,IAAI,CAAC,mBAAmB,CAAC,oBAAoB,GAAG,IAAI,CAAC,sBAAsB,CAAC;aAC/E;YACD,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC7F,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC,KAAK,CAAC,CAAC;gBACjD,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAAC,CAAC;YACtD,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC;gBACnC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;gBAC/B,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK;aAChC,EAAE,yBAAO,CAAC,KAAK,CAAU,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;SAChE;aAAM;YACH,MAAM,IAAI,qBAAW,CAAC,oCAA0B,CAAC,uBAAuB,CAAC,CAAC;SAC7E;IACL,CAAC;IAgCD,+DAA+D;IACvD,4CAAkB,GAA1B,UAA2B,WAAqB;QAC5C,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC;QACjC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,qBAAqB,GAAG,KAAK,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC5B,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC1B,qBAAqB,GAAG,IAAI,CAAC,UAAU,CAAC;SAC3C;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,OAAO,qBAAqB,CAAC;IACjC,CAAC;IACL,sBAAC;AAAD,CAAC,AAjWD,IAiWC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.d.ts +new file mode 100644 +index 0000000..977bb6a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.d.ts +@@ -0,0 +1,3 @@ ++export declare const Constants: { ++ [key: string]: string; ++}; +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js +new file mode 100644 +index 0000000..c3323a1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js +@@ -0,0 +1,7 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++exports.Constants = { ++ CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX: "_offset", ++ CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX: "_layouts", ++}; ++//# sourceMappingURL=Constants.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js.map b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js.map +new file mode 100644 +index 0000000..e0d93e2 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../../../src/core/constants/Constants.ts"],"names":[],"mappings":";;AAAa,QAAA,SAAS,GAA4B;IAC9C,kCAAkC,EAAG,SAAS;IAC9C,kCAAkC,EAAE,UAAU;CACjD,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.d.ts +new file mode 100644 +index 0000000..d211558 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.d.ts +@@ -0,0 +1,3 @@ ++export declare const Messages: { ++ [key: string]: string; ++}; +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js +new file mode 100644 +index 0000000..51baf1f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js +@@ -0,0 +1,10 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++exports.Messages = { ++ ERROR_LISTVIEW_VALIDATION: "missing datasource or layout provider, cannot proceed without it", ++ WARN_SCROLL_TO_INDEX: "scrollTo was called before RecyclerListView was measured, please wait for the mount to finish", ++ WARN_NO_DATA: "You have mounted RecyclerListView with an empty data provider (Size in 0). Please mount only if there is atleast one item " + ++ "to ensure optimal performance and to avoid unexpected behavior", ++ VISIBLE_INDEXES_CHANGED_DEPRECATED: "onVisibleIndexesChanged deprecated. Please use onVisibleIndicesChanged instead.", ++}; ++//# sourceMappingURL=Messages.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js.map b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js.map +new file mode 100644 +index 0000000..9695650 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../../src/core/constants/Messages.ts"],"names":[],"mappings":";;AAAa,QAAA,QAAQ,GAA4B;IAC7C,yBAAyB,EAAG,kEAAkE;IAC9F,oBAAoB,EAAE,+FAA+F;IACrH,YAAY,EAAE,4HAA4H;QAC5H,gEAAgE;IAC9E,kCAAkC,EAAE,iFAAiF;CACxH,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.d.ts +new file mode 100644 +index 0000000..98abef9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.d.ts +@@ -0,0 +1,13 @@ ++/*** ++ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, ++ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you ++ * can instantly jump to any location. ++ * ++ * Use this interface and implement the given methods to preserve context. ++ */ ++export default abstract class ContextProvider { ++ abstract getUniqueKey(): string; ++ abstract save(key: string, value: string | number): void; ++ abstract get(key: string): string | number; ++ abstract remove(key: string): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js +new file mode 100644 +index 0000000..724fa5a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js +@@ -0,0 +1,16 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++/*** ++ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, ++ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you ++ * can instantly jump to any location. ++ * ++ * Use this interface and implement the given methods to preserve context. ++ */ ++var ContextProvider = /** @class */ (function () { ++ function ContextProvider() { ++ } ++ return ContextProvider; ++}()); ++exports.default = ContextProvider; ++//# sourceMappingURL=ContextProvider.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js.map b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js.map +new file mode 100644 +index 0000000..27659b2 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ContextProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/ContextProvider.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH;IAAA;IAYA,CAAC;IAAD,sBAAC;AAAD,CAAC,AAZD,IAYC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.d.ts +new file mode 100644 +index 0000000..0844963 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.d.ts +@@ -0,0 +1,25 @@ ++/*** ++ * You can create a new instance or inherit and override default methods ++ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. ++ */ ++export declare abstract class BaseDataProvider { ++ rowHasChanged: (r1: any, r2: any) => boolean; ++ getStableId: (index: number) => string; ++ private _firstIndexToProcess; ++ private _size; ++ private _data; ++ private _hasStableIds; ++ private _requiresDataChangeHandling; ++ constructor(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string); ++ abstract newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string): BaseDataProvider; ++ getDataForIndex(index: number): any; ++ getAllData(): any[]; ++ getSize(): number; ++ hasStableIds(): boolean; ++ requiresDataChangeHandling(): boolean; ++ getFirstIndexToProcessInternal(): number; ++ cloneWithRows(newData: any[], firstModifiedIndex?: number): DataProvider; ++} ++export default class DataProvider extends BaseDataProvider { ++ newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: ((index: number) => string) | undefined): BaseDataProvider; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js +new file mode 100644 +index 0000000..ee37484 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js +@@ -0,0 +1,94 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ts_object_utils_1 = require("ts-object-utils"); ++/*** ++ * You can create a new instance or inherit and override default methods ++ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. ++ */ ++var BaseDataProvider = /** @class */ (function () { ++ function BaseDataProvider(rowHasChanged, getStableId) { ++ this._firstIndexToProcess = 0; ++ this._size = 0; ++ this._data = []; ++ this._hasStableIds = false; ++ this._requiresDataChangeHandling = false; ++ this.rowHasChanged = rowHasChanged; ++ if (getStableId) { ++ this.getStableId = getStableId; ++ this._hasStableIds = true; ++ } ++ else { ++ this.getStableId = function (index) { return index.toString(); }; ++ } ++ } ++ BaseDataProvider.prototype.getDataForIndex = function (index) { ++ return this._data[index]; ++ }; ++ BaseDataProvider.prototype.getAllData = function () { ++ return this._data; ++ }; ++ BaseDataProvider.prototype.getSize = function () { ++ return this._size; ++ }; ++ BaseDataProvider.prototype.hasStableIds = function () { ++ return this._hasStableIds; ++ }; ++ BaseDataProvider.prototype.requiresDataChangeHandling = function () { ++ return this._requiresDataChangeHandling; ++ }; ++ BaseDataProvider.prototype.getFirstIndexToProcessInternal = function () { ++ return this._firstIndexToProcess; ++ }; ++ //No need to override this one ++ //If you already know the first row where rowHasChanged will be false pass it upfront to avoid loop ++ BaseDataProvider.prototype.cloneWithRows = function (newData, firstModifiedIndex) { ++ var dp = this.newInstance(this.rowHasChanged, this.getStableId); ++ var newSize = newData.length; ++ var iterCount = Math.min(this._size, newSize); ++ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(firstModifiedIndex)) { ++ var i = 0; ++ for (i = 0; i < iterCount; i++) { ++ if (this.rowHasChanged(this._data[i], newData[i])) { ++ break; ++ } ++ } ++ dp._firstIndexToProcess = i; ++ } ++ else { ++ dp._firstIndexToProcess = Math.max(Math.min(firstModifiedIndex, this._data.length), 0); ++ } ++ if (dp._firstIndexToProcess !== this._data.length) { ++ dp._requiresDataChangeHandling = true; ++ } ++ dp._data = newData; ++ dp._size = newSize; ++ return dp; ++ }; ++ return BaseDataProvider; ++}()); ++exports.BaseDataProvider = BaseDataProvider; ++var DataProvider = /** @class */ (function (_super) { ++ __extends(DataProvider, _super); ++ function DataProvider() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ DataProvider.prototype.newInstance = function (rowHasChanged, getStableId) { ++ return new DataProvider(rowHasChanged, getStableId); ++ }; ++ return DataProvider; ++}(BaseDataProvider)); ++exports.default = DataProvider; ++//# sourceMappingURL=DataProvider.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js.map b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js.map +new file mode 100644 +index 0000000..fd7dedf +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DataProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/DataProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mDAA6C;AAE7C;;;GAGG;AACH;IAWI,0BAAY,aAA4C,EAAE,WAAuC;QANzF,yBAAoB,GAAW,CAAC,CAAC;QACjC,UAAK,GAAW,CAAC,CAAC;QAClB,UAAK,GAAU,EAAE,CAAC;QAClB,kBAAa,GAAG,KAAK,CAAC;QACtB,gCAA2B,GAAG,KAAK,CAAC;QAGxC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,WAAW,EAAE;YACb,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC7B;aAAM;YACH,IAAI,CAAC,WAAW,GAAG,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,QAAQ,EAAE,EAAhB,CAAgB,CAAC;SAClD;IACL,CAAC;IAIM,0CAAe,GAAtB,UAAuB,KAAa;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAEM,qCAAU,GAAjB;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,kCAAO,GAAd;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,uCAAY,GAAnB;QACI,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEM,qDAA0B,GAAjC;QACI,OAAO,IAAI,CAAC,2BAA2B,CAAC;IAC5C,CAAC;IAEM,yDAA8B,GAArC;QACI,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACrC,CAAC;IAED,8BAA8B;IAC9B,mGAAmG;IAC5F,wCAAa,GAApB,UAAqB,OAAc,EAAE,kBAA2B;QAC5D,IAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClE,IAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/B,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,4BAAU,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE;YAClD,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;gBAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC/C,MAAM;iBACT;aACJ;YACD,EAAE,CAAC,oBAAoB,GAAG,CAAC,CAAC;SAC/B;aAAM;YACH,EAAE,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1F;QACD,IAAI,EAAE,CAAC,oBAAoB,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAC/C,EAAE,CAAC,2BAA2B,GAAG,IAAI,CAAC;SACzC;QACD,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,OAAO,EAAE,CAAC;IACd,CAAC;IACL,uBAAC;AAAD,CAAC,AAvED,IAuEC;AAvEqB,4CAAgB;AAyEtC;IAA0C,gCAAgB;IAA1D;;IAIA,CAAC;IAHU,kCAAW,GAAlB,UAAmB,aAA4C,EAAE,WAAqD;QAClH,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC;IACL,mBAAC;AAAD,CAAC,AAJD,CAA0C,gBAAgB,GAIzD"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.d.ts +new file mode 100644 +index 0000000..e832379 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.d.ts +@@ -0,0 +1,35 @@ ++import { Layout, LayoutManager } from "../layoutmanager/LayoutManager"; ++/** ++ * Created by talha.naqvi on 05/04/17. ++ * You can create a new instance or inherit and override default methods ++ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider ++ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all ++ * data upfront will only limit possibilites in the future. ++ * ++ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates ++ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. ++ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. ++ * ++ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. ++ */ ++export declare abstract class BaseLayoutProvider { ++ shouldRefreshWithAnchoring: boolean; ++ abstract newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; ++ abstract getLayoutTypeForIndex(index: number): string | number; ++ abstract checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; ++} ++export declare class LayoutProvider extends BaseLayoutProvider { ++ private _getLayoutTypeForIndex; ++ private _setLayoutForType; ++ private _tempDim; ++ private _lastLayoutManager; ++ constructor(getLayoutTypeForIndex: (index: number) => string | number, setLayoutForType: (type: string | number, dim: Dimension, index: number) => void); ++ newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; ++ getLayoutTypeForIndex(index: number): string | number; ++ setComputedLayout(type: string | number, dimension: Dimension, index: number): void; ++ checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; ++} ++export interface Dimension { ++ height: number; ++ width: number; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js +new file mode 100644 +index 0000000..4f5dbdf +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js +@@ -0,0 +1,72 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var LayoutManager_1 = require("../layoutmanager/LayoutManager"); ++/** ++ * Created by talha.naqvi on 05/04/17. ++ * You can create a new instance or inherit and override default methods ++ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider ++ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all ++ * data upfront will only limit possibilites in the future. ++ * ++ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates ++ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. ++ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. ++ * ++ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. ++ */ ++var BaseLayoutProvider = /** @class */ (function () { ++ function BaseLayoutProvider() { ++ //Unset if your new layout provider doesn't require firstVisibleIndex preservation on application ++ this.shouldRefreshWithAnchoring = true; ++ } ++ return BaseLayoutProvider; ++}()); ++exports.BaseLayoutProvider = BaseLayoutProvider; ++var LayoutProvider = /** @class */ (function (_super) { ++ __extends(LayoutProvider, _super); ++ function LayoutProvider(getLayoutTypeForIndex, setLayoutForType) { ++ var _this = _super.call(this) || this; ++ _this._getLayoutTypeForIndex = getLayoutTypeForIndex; ++ _this._setLayoutForType = setLayoutForType; ++ _this._tempDim = { height: 0, width: 0 }; ++ return _this; ++ } ++ LayoutProvider.prototype.newLayoutManager = function (renderWindowSize, isHorizontal, cachedLayouts) { ++ this._lastLayoutManager = new LayoutManager_1.WrapGridLayoutManager(this, renderWindowSize, isHorizontal, cachedLayouts); ++ return this._lastLayoutManager; ++ }; ++ //Provide a type for index, something which identifies the template of view about to load ++ LayoutProvider.prototype.getLayoutTypeForIndex = function (index) { ++ return this._getLayoutTypeForIndex(index); ++ }; ++ //Given a type and dimension set the dimension values on given dimension object ++ //You can also get index here if you add an extra argument but we don't recommend using it. ++ LayoutProvider.prototype.setComputedLayout = function (type, dimension, index) { ++ return this._setLayoutForType(type, dimension, index); ++ }; ++ LayoutProvider.prototype.checkDimensionDiscrepancy = function (dimension, type, index) { ++ var dimension1 = dimension; ++ this.setComputedLayout(type, this._tempDim, index); ++ var dimension2 = this._tempDim; ++ if (this._lastLayoutManager) { ++ this._lastLayoutManager.setMaxBounds(dimension2); ++ } ++ return dimension1.height !== dimension2.height || dimension1.width !== dimension2.width; ++ }; ++ return LayoutProvider; ++}(BaseLayoutProvider)); ++exports.LayoutProvider = LayoutProvider; ++//# sourceMappingURL=LayoutProvider.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js.map b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js.map +new file mode 100644 +index 0000000..d2bed0e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"LayoutProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/LayoutProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gEAA8F;AAE9F;;;;;;;;;;;;GAYG;AAEH;IAAA;QACI,iGAAiG;QAC1F,+BAA0B,GAAY,IAAI,CAAC;IAYtD,CAAC;IAAD,yBAAC;AAAD,CAAC,AAdD,IAcC;AAdqB,gDAAkB;AAgBxC;IAAoC,kCAAkB;IAOlD,wBAAY,qBAAyD,EAAE,gBAAgF;QAAvJ,YACI,iBAAO,SAIV;QAHG,KAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;QACpD,KAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QAC1C,KAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;IAC5C,CAAC;IAEM,yCAAgB,GAAvB,UAAwB,gBAA2B,EAAE,YAAsB,EAAE,aAAwB;QACjG,IAAI,CAAC,kBAAkB,GAAG,IAAI,qCAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACzG,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED,yFAAyF;IAClF,8CAAqB,GAA5B,UAA6B,KAAa;QACtC,OAAO,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,+EAA+E;IAC/E,2FAA2F;IACpF,0CAAiB,GAAxB,UAAyB,IAAqB,EAAE,SAAoB,EAAE,KAAa;QAC/E,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1D,CAAC;IAEM,kDAAyB,GAAhC,UAAiC,SAAoB,EAAE,IAAqB,EAAE,KAAa;QACvF,IAAM,UAAU,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,IAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;SACpD;QACD,OAAO,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC;IAC5F,CAAC;IACL,qBAAC;AAAD,CAAC,AAvCD,CAAoC,kBAAkB,GAuCrD;AAvCY,wCAAc"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.d.ts +new file mode 100644 +index 0000000..d6e7c73 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.d.ts +@@ -0,0 +1,4 @@ ++import ResizeDebugHandler from "./resize/ResizeDebugHandler"; ++export interface DebugHandlers { ++ resizeDebugHandler?: ResizeDebugHandler; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js +new file mode 100644 +index 0000000..fe8175c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js +@@ -0,0 +1,3 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++//# sourceMappingURL=DebugHandlers.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js.map b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js.map +new file mode 100644 +index 0000000..332282c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DebugHandlers.js","sourceRoot":"","sources":["../../../../../src/core/devutils/debughandlers/DebugHandlers.ts"],"names":[],"mappings":""} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts +new file mode 100644 +index 0000000..e32b3c6 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts +@@ -0,0 +1,8 @@ ++import { Dimension } from "../../../.."; ++import ResizeDebugHandler from "./ResizeDebugHandler"; ++export default class DefaultResizeDebugHandler implements ResizeDebugHandler { ++ private readonly relaxation; ++ private readonly onRelaxationViolation; ++ constructor(relaxation: Dimension, onRelaxationViolation: (expectedDim: Dimension, actualDim: Dimension, index: number) => void); ++ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js +new file mode 100644 +index 0000000..258b921 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js +@@ -0,0 +1,25 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var DefaultResizeDebugHandler = /** @class */ (function () { ++ // Relaxation is the Dimension object where it accepts the relaxation to allow for each dimension. ++ // Any of the dimension (height or width) whose value for relaxation is less than 0 would be ignored. ++ function DefaultResizeDebugHandler(relaxation, onRelaxationViolation) { ++ this.relaxation = relaxation; ++ this.onRelaxationViolation = onRelaxationViolation; ++ } ++ DefaultResizeDebugHandler.prototype.resizeDebug = function (oldDim, newDim, index) { ++ var isViolated = false; ++ if (this.relaxation.height >= 0 && Math.abs(newDim.height - oldDim.height) >= this.relaxation.height) { ++ isViolated = true; ++ } ++ if (!isViolated && this.relaxation.width >= 0 && Math.abs(newDim.width - oldDim.width) >= this.relaxation.width) { ++ isViolated = true; ++ } ++ if (isViolated) { ++ this.onRelaxationViolation(oldDim, newDim, index); ++ } ++ }; ++ return DefaultResizeDebugHandler; ++}()); ++exports.default = DefaultResizeDebugHandler; ++//# sourceMappingURL=DefaultResizeDebugHandler.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map +new file mode 100644 +index 0000000..ccbb28c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.ts"],"names":[],"mappings":";;AAGA;IAII,kGAAkG;IAClG,qGAAqG;IACrG,mCAAmB,UAAqB,EAAE,qBAA4F;QAClI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACvD,CAAC;IAEM,+CAAW,GAAlB,UAAmB,MAAiB,EAAE,MAAiB,EAAE,KAAa;QAClE,IAAI,UAAU,GAAY,KAAK,CAAC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClG,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;YAC7G,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,UAAU,EAAE;YACZ,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;SACrD;IACL,CAAC;IACL,gCAAC;AAAD,CAAC,AAzBD,IAyBC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts +new file mode 100644 +index 0000000..654f89d +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts +@@ -0,0 +1,4 @@ ++import { Dimension } from "../../../.."; ++export default interface ResizeDebugHandler { ++ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js +new file mode 100644 +index 0000000..697bdb8 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js +@@ -0,0 +1,3 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++//# sourceMappingURL=ResizeDebugHandler.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map +new file mode 100644 +index 0000000..2122fce +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/ResizeDebugHandler.ts"],"names":[],"mappings":""} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.d.ts +new file mode 100644 +index 0000000..67ab42e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.d.ts +@@ -0,0 +1,7 @@ ++export default class CustomError extends Error { ++ constructor(exception: Exception); ++} ++export interface Exception { ++ type: string; ++ message: string; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js +new file mode 100644 +index 0000000..6a6b17c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js +@@ -0,0 +1,26 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var CustomError = /** @class */ (function (_super) { ++ __extends(CustomError, _super); ++ function CustomError(exception) { ++ var _this = _super.call(this, exception.message) || this; ++ _this.name = exception.type; ++ return _this; ++ } ++ return CustomError; ++}(Error)); ++exports.default = CustomError; ++//# sourceMappingURL=CustomError.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js.map b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js.map +new file mode 100644 +index 0000000..bbff8bd +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"CustomError.js","sourceRoot":"","sources":["../../../../src/core/exceptions/CustomError.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;IAAyC,+BAAK;IAC1C,qBAAY,SAAoB;QAAhC,YACI,kBAAM,SAAS,CAAC,OAAO,CAAC,SAE3B;QADG,KAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;;IAC/B,CAAC;IACL,kBAAC;AAAD,CAAC,AALD,CAAyC,KAAK,GAK7C"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.d.ts +new file mode 100644 +index 0000000..7db4997 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.d.ts +@@ -0,0 +1,5 @@ ++import { Exception } from "./CustomError"; ++declare const RecyclerListViewExceptions: { ++ [key: string]: Exception; ++}; ++export default RecyclerListViewExceptions; +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js +new file mode 100644 +index 0000000..26413ac +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js +@@ -0,0 +1,48 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecyclerListViewExceptions = { ++ initializationException: { ++ message: "Parameters required for initializing the module are missing", ++ type: "Initialization essentials missing", ++ }, ++ itemBoundsException: { ++ message: "Dimensions cannot be undefined or null, check if LayoutProvider returns irregular values", ++ type: "ItemBoundsException", ++ }, ++ itemTypeNullException: { ++ message: "RecyclerListView items always require a type, check if LayoutProvider returns irregular values", ++ type: "ItemTypeNullException", ++ }, ++ layoutException: { ++ message: "RecyclerListView needs to have a bounded size. Currently height or, width is 0." + ++ "Consider adding style={{flex:1}} or, fixed dimensions", ++ type: "LayoutException", ++ }, ++ platformNotDetectedException: { ++ message: "Unable to detect the running platform, if you're trying to run recyclerlistview " + ++ "in browser make sure process.env.RLV_ENV is set to browser in webpack config", ++ type: "PlatformNotDetectedException", ++ }, ++ unresolvedDependenciesException: { ++ message: "missing datasource or layout provider, cannot proceed without it", ++ type: "UnresolvedDependenciesException", ++ }, ++ refNotAsFunctionException: { ++ message: "When using StickyContainer, RecyclerListView needs to use ref as a function and not as a string.", ++ type: "RefNotAsFunctionException", ++ }, ++ wrongStickyChildTypeException: { ++ message: "StickyContainer can only have a single child of type RecyclerListView.", ++ type: "WrongStickyChildTypeException", ++ }, ++ usingOldVisibleIndexesChangedParam: { ++ message: "onVisibleIndexesChanged has been deprecated. Please use onVisibleIndicesChanged instead.", ++ type: "usingOldVisibleIndexesChangedParam", ++ }, ++ stickyIndicesArraySortError: { ++ message: "The sticky indices array passed to StickyContainer isn't sorted in ascending order.", ++ type: "stickyIndicesArraySortError", ++ }, ++}; ++exports.default = RecyclerListViewExceptions; ++//# sourceMappingURL=RecyclerListViewExceptions.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js.map b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js.map +new file mode 100644 +index 0000000..75634b0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"RecyclerListViewExceptions.js","sourceRoot":"","sources":["../../../../src/core/exceptions/RecyclerListViewExceptions.ts"],"names":[],"mappings":";;AAEA,IAAM,0BAA0B,GAA+B;IAC3D,uBAAuB,EAAE;QACrB,OAAO,EAAE,6DAA6D;QACtE,IAAI,EAAE,mCAAmC;KAC5C;IACD,mBAAmB,EAAE;QACjB,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,qBAAqB;KAC9B;IACD,qBAAqB,EAAE;QACnB,OAAO,EAAE,gGAAgG;QACzG,IAAI,EAAE,uBAAuB;KAChC;IACD,eAAe,EAAE;QACb,OAAO,EAAE,iFAAiF;YAC9E,uDAAuD;QACnE,IAAI,EAAE,iBAAiB;KAC1B;IACD,4BAA4B,EAAE;QAC1B,OAAO,EAAE,kFAAkF;YAC3F,8EAA8E;QAC9E,IAAI,EAAE,8BAA8B;KACvC;IACD,+BAA+B,EAAE;QAC7B,OAAO,EAAE,kEAAkE;QAC3E,IAAI,EAAE,iCAAiC;KAC1C;IACD,yBAAyB,EAAE;QACvB,OAAO,EAAE,kGAAkG;QAC3G,IAAI,EAAE,2BAA2B;KACpC;IACD,6BAA6B,EAAE;QAC3B,OAAO,EAAE,wEAAwE;QACjF,IAAI,EAAE,+BAA+B;KACxC;IACD,kCAAkC,EAAE;QAChC,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,oCAAoC;KAC7C;IACD,2BAA2B,EAAE;QACzB,OAAO,EAAE,qFAAqF;QAC9F,IAAI,EAAE,6BAA6B;KACtC;CACJ,CAAC;AACF,kBAAe,0BAA0B,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.d.ts +new file mode 100644 +index 0000000..51b60d7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.d.ts +@@ -0,0 +1,40 @@ ++/*** ++ * Computes the positions and dimensions of items that will be rendered by the list. The output from this is utilized by viewability tracker to compute the ++ * lists of visible/hidden item. ++ */ ++import { Dimension, LayoutProvider } from "../dependencies/LayoutProvider"; ++export declare abstract class LayoutManager { ++ getOffsetForIndex(index: number): Point; ++ getStyleOverridesForIndex(index: number): object | undefined; ++ abstract getContentDimension(): Dimension; ++ abstract getLayouts(): Layout[]; ++ abstract overrideLayout(index: number, dim: Dimension): boolean; ++ abstract relayoutFromIndex(startIndex: number, itemCount: number): void; ++} ++export declare class WrapGridLayoutManager extends LayoutManager { ++ private _layoutProvider; ++ private _window; ++ private _totalHeight; ++ private _totalWidth; ++ private _isHorizontal; ++ private _layouts; ++ constructor(layoutProvider: LayoutProvider, renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]); ++ getContentDimension(): Dimension; ++ getLayouts(): Layout[]; ++ getOffsetForIndex(index: number): Point; ++ overrideLayout(index: number, dim: Dimension): boolean; ++ setMaxBounds(itemDim: Dimension): void; ++ relayoutFromIndex(startIndex: number, itemCount: number): void; ++ private _pointDimensionsToRect; ++ private _setFinalDimensions; ++ private _locateFirstNeighbourIndex; ++ private _checkBounds; ++} ++export interface Layout extends Dimension, Point { ++ isOverridden?: boolean; ++ type: string | number; ++} ++export interface Point { ++ x: number; ++ y: number; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js +new file mode 100644 +index 0000000..23075a0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js +@@ -0,0 +1,196 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var CustomError_1 = require("../exceptions/CustomError"); ++var LayoutManager = /** @class */ (function () { ++ function LayoutManager() { ++ } ++ LayoutManager.prototype.getOffsetForIndex = function (index) { ++ var layouts = this.getLayouts(); ++ if (layouts.length > index) { ++ return { x: layouts[index].x, y: layouts[index].y }; ++ } ++ else { ++ throw new CustomError_1.default({ ++ message: "No layout available for index: " + index, ++ type: "LayoutUnavailableException", ++ }); ++ } ++ }; ++ //You can ovveride this incase you want to override style in some cases e.g, say you want to enfore width but not height ++ LayoutManager.prototype.getStyleOverridesForIndex = function (index) { ++ return undefined; ++ }; ++ return LayoutManager; ++}()); ++exports.LayoutManager = LayoutManager; ++var WrapGridLayoutManager = /** @class */ (function (_super) { ++ __extends(WrapGridLayoutManager, _super); ++ function WrapGridLayoutManager(layoutProvider, renderWindowSize, isHorizontal, cachedLayouts) { ++ if (isHorizontal === void 0) { isHorizontal = false; } ++ var _this = _super.call(this) || this; ++ _this._layoutProvider = layoutProvider; ++ _this._window = renderWindowSize; ++ _this._totalHeight = 0; ++ _this._totalWidth = 0; ++ _this._isHorizontal = !!isHorizontal; ++ _this._layouts = cachedLayouts ? cachedLayouts : []; ++ return _this; ++ } ++ WrapGridLayoutManager.prototype.getContentDimension = function () { ++ return { height: this._totalHeight, width: this._totalWidth }; ++ }; ++ WrapGridLayoutManager.prototype.getLayouts = function () { ++ return this._layouts; ++ }; ++ WrapGridLayoutManager.prototype.getOffsetForIndex = function (index) { ++ if (this._layouts.length > index) { ++ return { x: this._layouts[index].x, y: this._layouts[index].y }; ++ } ++ else { ++ throw new CustomError_1.default({ ++ message: "No layout available for index: " + index, ++ type: "LayoutUnavailableException", ++ }); ++ } ++ }; ++ WrapGridLayoutManager.prototype.overrideLayout = function (index, dim) { ++ var layout = this._layouts[index]; ++ if (layout) { ++ layout.isOverridden = true; ++ layout.width = dim.width; ++ layout.height = dim.height; ++ } ++ return true; ++ }; ++ WrapGridLayoutManager.prototype.setMaxBounds = function (itemDim) { ++ if (this._isHorizontal) { ++ itemDim.height = Math.min(this._window.height, itemDim.height); ++ } ++ else { ++ itemDim.width = Math.min(this._window.width, itemDim.width); ++ } ++ }; ++ //TODO:Talha laziliy calculate in future revisions ++ WrapGridLayoutManager.prototype.relayoutFromIndex = function (startIndex, itemCount) { ++ startIndex = this._locateFirstNeighbourIndex(startIndex); ++ var startX = 0; ++ var startY = 0; ++ var maxBound = 0; ++ var startVal = this._layouts[startIndex]; ++ if (startVal) { ++ startX = startVal.x; ++ startY = startVal.y; ++ this._pointDimensionsToRect(startVal); ++ } ++ var oldItemCount = this._layouts.length; ++ var itemDim = { height: 0, width: 0 }; ++ var itemRect = null; ++ var oldLayout = null; ++ for (var i = startIndex; i < itemCount; i++) { ++ oldLayout = this._layouts[i]; ++ var layoutType = this._layoutProvider.getLayoutTypeForIndex(i); ++ if (oldLayout && oldLayout.isOverridden && oldLayout.type === layoutType) { ++ itemDim.height = oldLayout.height; ++ itemDim.width = oldLayout.width; ++ } ++ else { ++ this._layoutProvider.setComputedLayout(layoutType, itemDim, i); ++ } ++ this.setMaxBounds(itemDim); ++ while (!this._checkBounds(startX, startY, itemDim, this._isHorizontal)) { ++ if (this._isHorizontal) { ++ startX += maxBound; ++ startY = 0; ++ this._totalWidth += maxBound; ++ } ++ else { ++ startX = 0; ++ startY += maxBound; ++ this._totalHeight += maxBound; ++ } ++ maxBound = 0; ++ } ++ maxBound = this._isHorizontal ? Math.max(maxBound, itemDim.width) : Math.max(maxBound, itemDim.height); ++ //TODO: Talha creating array upfront will speed this up ++ if (i > oldItemCount - 1) { ++ this._layouts.push({ x: startX, y: startY, height: itemDim.height, width: itemDim.width, type: layoutType }); ++ } ++ else { ++ itemRect = this._layouts[i]; ++ itemRect.x = startX; ++ itemRect.y = startY; ++ itemRect.type = layoutType; ++ itemRect.width = itemDim.width; ++ itemRect.height = itemDim.height; ++ } ++ if (this._isHorizontal) { ++ startY += itemDim.height; ++ } ++ else { ++ startX += itemDim.width; ++ } ++ } ++ if (oldItemCount > itemCount) { ++ this._layouts.splice(itemCount, oldItemCount - itemCount); ++ } ++ this._setFinalDimensions(maxBound); ++ }; ++ WrapGridLayoutManager.prototype._pointDimensionsToRect = function (itemRect) { ++ if (this._isHorizontal) { ++ this._totalWidth = itemRect.x; ++ } ++ else { ++ this._totalHeight = itemRect.y; ++ } ++ }; ++ WrapGridLayoutManager.prototype._setFinalDimensions = function (maxBound) { ++ if (this._isHorizontal) { ++ this._totalHeight = this._window.height; ++ this._totalWidth += maxBound; ++ } ++ else { ++ this._totalWidth = this._window.width; ++ this._totalHeight += maxBound; ++ } ++ }; ++ WrapGridLayoutManager.prototype._locateFirstNeighbourIndex = function (startIndex) { ++ if (startIndex === 0) { ++ return 0; ++ } ++ var i = startIndex - 1; ++ for (; i >= 0; i--) { ++ if (!this._layouts[i]) { ++ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line ++ continue; ++ } ++ if (this._isHorizontal) { ++ if (this._layouts[i].y === 0) { ++ break; ++ } ++ } ++ else if (this._layouts[i].x === 0) { ++ break; ++ } ++ } ++ return i; ++ }; ++ WrapGridLayoutManager.prototype._checkBounds = function (itemX, itemY, itemDim, isHorizontal) { ++ return isHorizontal ? (itemY + itemDim.height <= this._window.height) : (itemX + itemDim.width <= this._window.width); ++ }; ++ return WrapGridLayoutManager; ++}(LayoutManager)); ++exports.WrapGridLayoutManager = WrapGridLayoutManager; ++//# sourceMappingURL=LayoutManager.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js.map b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js.map +new file mode 100644 +index 0000000..3129d8e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"LayoutManager.js","sourceRoot":"","sources":["../../../../src/core/layoutmanager/LayoutManager.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.d.ts +new file mode 100644 +index 0000000..fbf1ac9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.d.ts +@@ -0,0 +1,21 @@ ++import * as React from "react"; ++import { Dimension } from "../dependencies/LayoutProvider"; ++import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./BaseScrollView"; ++export interface ScrollComponentProps { ++ onSizeChanged: (dimensions: Dimension) => void; ++ onScroll: (offsetX: number, offsetY: number, rawEvent: ScrollEvent) => void; ++ contentHeight: number; ++ contentWidth: number; ++ canChangeSize?: boolean; ++ externalScrollView?: { ++ new (props: ScrollViewDefaultProps): BaseScrollView; ++ }; ++ isHorizontal?: boolean; ++ renderFooter?: () => JSX.Element | JSX.Element[] | null; ++ scrollThrottle?: number; ++ useWindowScroll?: boolean; ++ onLayout?: any; ++} ++export default abstract class BaseScrollComponent extends React.Component { ++ abstract scrollTo(x: number, y: number, animate: boolean): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js +new file mode 100644 +index 0000000..821b8f8 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js +@@ -0,0 +1,25 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollComponent = /** @class */ (function (_super) { ++ __extends(BaseScrollComponent, _super); ++ function BaseScrollComponent() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ return BaseScrollComponent; ++}(React.Component)); ++exports.default = BaseScrollComponent; ++//# sourceMappingURL=BaseScrollComponent.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js.map b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js.map +new file mode 100644 +index 0000000..1be170f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BaseScrollComponent.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAiB/B;IAA0D,uCAAyC;IAAnG;;IAEA,CAAC;IAAD,0BAAC;AAAD,CAAC,AAFD,CAA0D,KAAK,CAAC,SAAS,GAExE"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.d.ts +new file mode 100644 +index 0000000..d29def1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.d.ts +@@ -0,0 +1,29 @@ ++import * as React from "react"; ++import { CSSProperties } from "react"; ++import { Dimension } from "../dependencies/LayoutProvider"; ++export interface ScrollViewDefaultProps { ++ onScroll: (event: ScrollEvent) => void; ++ onSizeChanged: (dimensions: Dimension) => void; ++ horizontal: boolean; ++ canChangeSize: boolean; ++ style?: CSSProperties | null; ++ useWindowScroll: boolean; ++} ++export interface ScrollEvent { ++ nativeEvent: { ++ contentOffset: { ++ x: number; ++ y: number; ++ }; ++ layoutMeasurement?: Dimension; ++ contentSize?: Dimension; ++ }; ++} ++export default abstract class BaseScrollView extends React.Component { ++ constructor(props: ScrollViewDefaultProps); ++ abstract scrollTo(scrollInput: { ++ x: number; ++ y: number; ++ animated: boolean; ++ }): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js +new file mode 100644 +index 0000000..694e0ae +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js +@@ -0,0 +1,25 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollView = /** @class */ (function (_super) { ++ __extends(BaseScrollView, _super); ++ function BaseScrollView(props) { ++ return _super.call(this, props) || this; ++ } ++ return BaseScrollView; ++}(React.Component)); ++exports.default = BaseScrollView; ++//# sourceMappingURL=BaseScrollView.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js.map b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js.map +new file mode 100644 +index 0000000..4230976 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BaseScrollView.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAsB/B;IAAqD,kCAA2C;IAC5F,wBAAY,KAA6B;eACrC,kBAAM,KAAK,CAAC;IAChB,CAAC;IAGL,qBAAC;AAAD,CAAC,AAND,CAAqD,KAAK,CAAC,SAAS,GAMnE"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.d.ts +new file mode 100644 +index 0000000..a7af807 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.d.ts +@@ -0,0 +1,13 @@ ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; ++export default class StickyFooter

extends StickyObject { ++ constructor(props: P, context?: any); ++ protected initStickyParams(): void; ++ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, _smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; ++ protected getNextYd(nextY: number, nextHeight: number): number; ++ protected getCurrentYd(currentY: number, currentHeight: number): number; ++ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; ++ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js +new file mode 100644 +index 0000000..1a1b02f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js +@@ -0,0 +1,70 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var StickyObject_1 = require("./StickyObject"); ++var BinarySearch_1 = require("../../utils/BinarySearch"); ++var StickyFooter = /** @class */ (function (_super) { ++ __extends(StickyFooter, _super); ++ function StickyFooter(props, context) { ++ return _super.call(this, props, context) || this; ++ } ++ StickyFooter.prototype.initStickyParams = function () { ++ this.stickyType = StickyObject_1.StickyType.FOOTER; ++ this.stickyTypeMultiplier = -1; ++ this.containerPosition = { bottom: 0 }; ++ this.bounceScrolling = false; ++ }; ++ StickyFooter.prototype.calculateVisibleStickyIndex = function (stickyIndices, _smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow, windowBound) { ++ if (stickyIndices && largestVisibleIndex) { ++ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); ++ if (largestVisibleIndex > stickyIndices[stickyIndices.length - 1] || this.bounceScrolling) { ++ this.stickyVisiblity = false; ++ } ++ else { ++ this.stickyVisiblity = true; ++ var valueAndIndex = BinarySearch_1.default.findValueLargerThanTarget(stickyIndices, largestVisibleIndex); ++ if (valueAndIndex) { ++ this.currentIndex = valueAndIndex.index; ++ this.currentStickyIndex = valueAndIndex.value; ++ } ++ else { ++ console.log("Footer sticky index calculation gone wrong."); //tslint:disable-line ++ } ++ } ++ } ++ }; ++ StickyFooter.prototype.getNextYd = function (nextY, nextHeight) { ++ return -1 * (nextY + nextHeight); ++ }; ++ StickyFooter.prototype.getCurrentYd = function (currentY, currentHeight) { ++ return -1 * (currentY + currentHeight); ++ }; ++ StickyFooter.prototype.getScrollY = function (offsetY, scrollableHeight) { ++ return scrollableHeight ? -1 * (offsetY + scrollableHeight) : undefined; ++ }; ++ StickyFooter.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, windowBound) { ++ if (windowBound) { ++ var endReachedMargin = Math.round(offsetY - (windowBound + distanceFromWindow)); ++ return endReachedMargin >= 0; ++ } ++ return false; ++ }; ++ return StickyFooter; ++}(StickyObject_1.default)); ++exports.default = StickyFooter; ++//# sourceMappingURL=StickyFooter.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js.map b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js.map +new file mode 100644 +index 0000000..1c899a7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyFooter.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyFooter.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAC,MAAM,EAAE,CAAC,EAAC,CAAC;QACrC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IACjC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,qBAA6B,EAAE,mBAA2B,EAC/F,OAAe,EAAE,kBAA0B,EAAE,WAAqB;QAElE,IAAI,aAAa,IAAI,mBAAmB,EAAE;YACtC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;YACzF,IAAI,mBAAmB,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACvF,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,yBAAyB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;gBAC5H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC;IACrC,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC;IAC3C,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,WAAoB;QAC1F,IAAI,WAAW,EAAE;YACb,IAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC;YAClF,OAAO,gBAAgB,IAAI,CAAC,CAAC;SAChC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IACL,mBAAC;AAAD,CAAC,AApDD,CAAoG,sBAAY,GAoD/G"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.d.ts +new file mode 100644 +index 0000000..08481a0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.d.ts +@@ -0,0 +1,13 @@ ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; ++export default class StickyHeader

extends StickyObject { ++ constructor(props: P, context?: any); ++ protected initStickyParams(): void; ++ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number): void; ++ protected getNextYd(nextY: number, nextHeight: number): number; ++ protected getCurrentYd(currentY: number, currentHeight: number): number; ++ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; ++ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, _windowBound?: number): boolean; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js +new file mode 100644 +index 0000000..5e72f6e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js +@@ -0,0 +1,68 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var StickyObject_1 = require("./StickyObject"); ++var BinarySearch_1 = require("../../utils/BinarySearch"); ++var StickyHeader = /** @class */ (function (_super) { ++ __extends(StickyHeader, _super); ++ function StickyHeader(props, context) { ++ return _super.call(this, props, context) || this; ++ } ++ StickyHeader.prototype.initStickyParams = function () { ++ this.stickyType = StickyObject_1.StickyType.HEADER; ++ this.stickyTypeMultiplier = 1; ++ this.containerPosition = { top: 0 }; ++ // Kept as true contrary to as in StickyFooter because in case of initialOffset not given, onScroll isn't called and boundaryProcessing isn't done. ++ // Default behaviour in that case will be sticky header hidden. ++ this.bounceScrolling = true; ++ }; ++ StickyHeader.prototype.calculateVisibleStickyIndex = function (stickyIndices, smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow) { ++ if (stickyIndices && smallestVisibleIndex !== undefined) { ++ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow); ++ if (smallestVisibleIndex < stickyIndices[0] || this.bounceScrolling) { ++ this.stickyVisiblity = false; ++ } ++ else { ++ this.stickyVisiblity = true; ++ var valueAndIndex = BinarySearch_1.default.findValueSmallerThanTarget(stickyIndices, smallestVisibleIndex); ++ if (valueAndIndex) { ++ this.currentIndex = valueAndIndex.index; ++ this.currentStickyIndex = valueAndIndex.value; ++ } ++ else { ++ console.log("Header sticky index calculation gone wrong."); //tslint:disable-line ++ } ++ } ++ } ++ }; ++ StickyHeader.prototype.getNextYd = function (nextY, nextHeight) { ++ return nextY; ++ }; ++ StickyHeader.prototype.getCurrentYd = function (currentY, currentHeight) { ++ return currentY; ++ }; ++ StickyHeader.prototype.getScrollY = function (offsetY, scrollableHeight) { ++ return offsetY; ++ }; ++ StickyHeader.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, _windowBound) { ++ return offsetY < distanceFromWindow; ++ }; ++ return StickyHeader; ++}(StickyObject_1.default)); ++exports.default = StickyHeader; ++//# sourceMappingURL=StickyHeader.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js.map b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js.map +new file mode 100644 +index 0000000..aef0aaa +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyHeader.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyHeader.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,iBAAiB,GAAG,EAAC,GAAG,EAAE,CAAC,EAAC,CAAC;QAElC,mJAAmJ;QACnJ,+DAA+D;QAC/D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAChC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,oBAA4B,EAAE,mBAA2B,EAAE,OAAe,EAAE,kBAA0B;QAE3I,IAAI,aAAa,IAAI,oBAAoB,KAAK,SAAS,EAAE;YACrD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC5E,IAAI,oBAAoB,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACjE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,0BAA0B,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;gBAC9H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,QAAQ,CAAC;IACpB,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,OAAO,CAAC;IACnB,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,YAAqB;QAC3F,OAAO,OAAO,GAAG,kBAAkB,CAAC;IACxC,CAAC;IACL,mBAAC;AAAD,CAAC,AAlDD,CAAoG,sBAAY,GAkD/G"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.d.ts +new file mode 100644 +index 0000000..ed5976f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.d.ts +@@ -0,0 +1,74 @@ ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++import * as React from "react"; ++import { StyleProp, ViewStyle } from "react-native"; ++import { Layout } from "../layoutmanager/LayoutManager"; ++import { Dimension } from "../dependencies/LayoutProvider"; ++export declare enum StickyType { ++ HEADER = 0, ++ FOOTER = 1 ++} ++export interface StickyObjectProps { ++ stickyIndices: number[] | undefined; ++ getLayoutForIndex: (index: number) => Layout | undefined; ++ getDataForIndex: (index: number) => any; ++ getLayoutTypeForIndex: (index: number) => string | number; ++ getExtendedState: () => object | undefined; ++ getRLVRenderedSize: () => Dimension | undefined; ++ getContentDimension: () => Dimension | undefined; ++ getRowRenderer: () => ((type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null); ++ getDistanceFromWindow: () => number; ++ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++} ++export interface StickyObjectState { ++ visibility: boolean; ++} ++export default abstract class StickyObject

extends React.Component { ++ protected stickyType: StickyType; ++ protected stickyTypeMultiplier: number; ++ protected stickyVisiblity: boolean; ++ protected visibility: boolean; ++ protected containerPosition: StyleProp; ++ protected currentIndex: number; ++ protected currentStickyIndex: number; ++ protected visibleIndices: number[]; ++ protected bounceScrolling: boolean; ++ private _previousLayout; ++ private _previousHeight; ++ private _nextLayout; ++ private _nextY; ++ private _nextHeight; ++ private _currentLayout; ++ private _currentY; ++ private _currentHeight; ++ private _nextYd; ++ private _currentYd; ++ private _scrollableHeight; ++ private _scrollableWidth; ++ private _windowBound; ++ private _stickyViewOffset; ++ private _previousStickyIndex; ++ private _nextStickyIndex; ++ private _firstCompute; ++ private _smallestVisibleIndex; ++ private _largestVisibleIndex; ++ private _offsetY; ++ constructor(props: P, context?: any); ++ componentWillReceiveProps(newProps: StickyObjectProps): void; ++ render(): JSX.Element | null; ++ onVisibleIndicesChanged(all: number[]): void; ++ onScroll(offsetY: number): void; ++ protected abstract hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; ++ protected abstract initStickyParams(): void; ++ protected abstract calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; ++ protected abstract getNextYd(_nextY: number, nextHeight: number): number; ++ protected abstract getCurrentYd(currentY: number, currentHeight: number): number; ++ protected abstract getScrollY(offsetY: number, scrollableHeight?: number): number | undefined; ++ protected stickyViewVisible(_visible: boolean): void; ++ protected boundaryProcessing(offsetY: number, distanceFromWindow: number, windowBound?: number): void; ++ private _initParams; ++ private _computeLayouts; ++ private _setSmallestAndLargestVisibleIndices; ++ private _renderSticky; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js +new file mode 100644 +index 0000000..4964223 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js +@@ -0,0 +1,203 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var react_native_1 = require("react-native"); ++var RecyclerListViewExceptions_1 = require("../exceptions/RecyclerListViewExceptions"); ++var CustomError_1 = require("../exceptions/CustomError"); ++var StickyType; ++(function (StickyType) { ++ StickyType[StickyType["HEADER"] = 0] = "HEADER"; ++ StickyType[StickyType["FOOTER"] = 1] = "FOOTER"; ++})(StickyType = exports.StickyType || (exports.StickyType = {})); ++var StickyObject = /** @class */ (function (_super) { ++ __extends(StickyObject, _super); ++ function StickyObject(props, context) { ++ var _this = _super.call(this, props, context) || this; ++ _this.stickyType = StickyType.HEADER; ++ _this.stickyTypeMultiplier = 1; ++ _this.stickyVisiblity = false; ++ _this.visibility = false; ++ _this.currentIndex = 0; ++ _this.currentStickyIndex = 0; ++ _this.visibleIndices = []; ++ _this.bounceScrolling = false; ++ _this._stickyViewOffset = new react_native_1.Animated.Value(0); ++ _this._previousStickyIndex = 0; ++ _this._nextStickyIndex = 0; ++ _this._firstCompute = true; ++ _this._smallestVisibleIndex = 0; ++ _this._largestVisibleIndex = 0; ++ _this._offsetY = 0; ++ _this.state = { ++ visibility: true, ++ }; ++ return _this; ++ } ++ StickyObject.prototype.componentWillReceiveProps = function (newProps) { ++ this._initParams(); ++ this.calculateVisibleStickyIndex(newProps.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, newProps.getDistanceFromWindow(), this._windowBound); ++ this._computeLayouts(newProps.stickyIndices); ++ this.stickyViewVisible(this.stickyVisiblity); ++ }; ++ StickyObject.prototype.render = function () { ++ return (React.createElement(react_native_1.Animated.View, { style: [ ++ { position: "absolute", width: this._scrollableWidth, transform: [{ translateY: this._stickyViewOffset }] }, ++ this.containerPosition, ++ ] }, this.visibility ? ++ this._renderSticky() ++ : null)); ++ }; ++ StickyObject.prototype.onVisibleIndicesChanged = function (all) { ++ if (this._firstCompute) { ++ this.initStickyParams(); ++ this._firstCompute = false; ++ } ++ this._initParams(); ++ this._setSmallestAndLargestVisibleIndices(all); ++ this.calculateVisibleStickyIndex(this.props.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, this.props.getDistanceFromWindow(), this._windowBound); ++ this._computeLayouts(); ++ this.stickyViewVisible(this.stickyVisiblity); ++ }; ++ StickyObject.prototype.onScroll = function (offsetY) { ++ var prevVisibility = this.visibility; ++ if (offsetY < 0 && prevVisibility === true || this._smallestVisibleIndex < this.currentStickyIndex) { ++ this.visibility = false; ++ } ++ else if (offsetY >= 0 && prevVisibility === false) { ++ this.visibility = true; ++ } ++ if (prevVisibility !== this.visibility) { ++ this.render(); ++ } ++ this._initParams(); ++ this._offsetY = offsetY; ++ this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); ++ if (this._previousStickyIndex !== undefined) { ++ if (this._previousStickyIndex * this.stickyTypeMultiplier >= this.currentStickyIndex * this.stickyTypeMultiplier) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); ++ } ++ var scrollY_1 = this.getScrollY(offsetY, this._scrollableHeight); ++ if (this._previousHeight && this._currentYd && scrollY_1 && scrollY_1 < this._currentYd) { ++ if (scrollY_1 > this._currentYd - this._previousHeight) { ++ this.currentIndex -= this.stickyTypeMultiplier; ++ var translate = (scrollY_1 - this._currentYd + this._previousHeight) * (-1 * this.stickyTypeMultiplier); ++ this._stickyViewOffset.setValue(translate); ++ this._computeLayouts(); ++ this.stickyViewVisible(true); ++ } ++ } ++ else { ++ this._stickyViewOffset.setValue(0); ++ } ++ } ++ if (this._nextStickyIndex !== undefined) { ++ if (this._nextStickyIndex * this.stickyTypeMultiplier <= this.currentStickyIndex * this.stickyTypeMultiplier) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); ++ } ++ var scrollY_2 = this.getScrollY(offsetY, this._scrollableHeight); ++ if (this._currentHeight && this._nextYd && scrollY_2 && scrollY_2 + this._currentHeight > this._nextYd) { ++ if (scrollY_2 <= this._nextYd) { ++ var translate = (scrollY_2 - this._nextYd + this._currentHeight) * (-1 * this.stickyTypeMultiplier); ++ this._stickyViewOffset.setValue(translate); ++ } ++ else if (scrollY_2 > this._nextYd) { ++ this.currentIndex += this.stickyTypeMultiplier; ++ this._stickyViewOffset.setValue(0); ++ this._computeLayouts(); ++ this.stickyViewVisible(true); ++ } ++ } ++ else { ++ this._stickyViewOffset.setValue(0); ++ } ++ } ++ }; ++ StickyObject.prototype.stickyViewVisible = function (_visible) { ++ this.setState({ ++ visibility: _visible, ++ }); ++ }; ++ StickyObject.prototype.boundaryProcessing = function (offsetY, distanceFromWindow, windowBound) { ++ var hasReachedBoundary = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); ++ if (this.bounceScrolling !== hasReachedBoundary) { ++ this.bounceScrolling = hasReachedBoundary; ++ if (this.bounceScrolling) { ++ this.stickyViewVisible(false); ++ } ++ else { ++ this.onVisibleIndicesChanged(this.visibleIndices); ++ } ++ } ++ }; ++ StickyObject.prototype._initParams = function () { ++ var rlvDimension = this.props.getRLVRenderedSize(); ++ if (rlvDimension) { ++ this._scrollableHeight = rlvDimension.height; ++ this._scrollableWidth = rlvDimension.width; ++ } ++ var contentDimension = this.props.getContentDimension(); ++ if (contentDimension && this._scrollableHeight) { ++ this._windowBound = contentDimension.height - this._scrollableHeight; ++ } ++ }; ++ StickyObject.prototype._computeLayouts = function (newStickyIndices) { ++ var stickyIndices = newStickyIndices ? newStickyIndices : this.props.stickyIndices; ++ if (stickyIndices) { ++ this.currentStickyIndex = stickyIndices[this.currentIndex]; ++ this._previousStickyIndex = stickyIndices[this.currentIndex - this.stickyTypeMultiplier]; ++ this._nextStickyIndex = stickyIndices[this.currentIndex + this.stickyTypeMultiplier]; ++ if (this.currentStickyIndex !== undefined) { ++ this._currentLayout = this.props.getLayoutForIndex(this.currentStickyIndex); ++ this._currentY = this._currentLayout ? this._currentLayout.y : undefined; ++ this._currentHeight = this._currentLayout ? this._currentLayout.height : undefined; ++ this._currentYd = this._currentY && this._currentHeight ? this.getCurrentYd(this._currentY, this._currentHeight) : undefined; ++ } ++ if (this._previousStickyIndex !== undefined) { ++ this._previousLayout = this.props.getLayoutForIndex(this._previousStickyIndex); ++ this._previousHeight = this._previousLayout ? this._previousLayout.height : undefined; ++ } ++ if (this._nextStickyIndex !== undefined) { ++ this._nextLayout = this.props.getLayoutForIndex(this._nextStickyIndex); ++ this._nextY = this._nextLayout ? this._nextLayout.y : undefined; ++ this._nextHeight = this._nextLayout ? this._nextLayout.height : undefined; ++ this._nextYd = this._nextY && this._nextHeight ? this.getNextYd(this._nextY, this._nextHeight) : undefined; ++ } ++ } ++ }; ++ StickyObject.prototype._setSmallestAndLargestVisibleIndices = function (indicesArray) { ++ this.visibleIndices = indicesArray; ++ this._smallestVisibleIndex = indicesArray[0]; ++ this._largestVisibleIndex = indicesArray[indicesArray.length - 1]; ++ }; ++ StickyObject.prototype._renderSticky = function () { ++ var _stickyData = this.props.getDataForIndex(this.currentStickyIndex); ++ var _stickyLayoutType = this.props.getLayoutTypeForIndex(this.currentStickyIndex); ++ var _extendedState = this.props.getExtendedState(); ++ var _rowRenderer = this.props.getRowRenderer(); ++ if (this.props.overrideRowRenderer) { ++ return this.props.overrideRowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); ++ } ++ else { ++ return _rowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); ++ } ++ }; ++ return StickyObject; ++}(React.Component)); ++exports.default = StickyObject; ++//# sourceMappingURL=StickyObject.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js.map b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js.map +new file mode 100644 +index 0000000..82b71ae +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyObject.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyObject.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.d.ts +new file mode 100644 +index 0000000..400f352 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.d.ts +@@ -0,0 +1,37 @@ ++import * as React from "react"; ++import { Dimension, BaseLayoutProvider } from "../dependencies/LayoutProvider"; ++import ItemAnimator from "../ItemAnimator"; ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++export interface ViewRendererProps { ++ x: number; ++ y: number; ++ height: number; ++ width: number; ++ childRenderer: (type: string | number, data: T, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++ layoutType: string | number; ++ dataHasChanged: (r1: T, r2: T) => boolean; ++ onSizeChanged: (dim: Dimension, index: number) => void; ++ data: any; ++ index: number; ++ itemAnimator: ItemAnimator; ++ styleOverrides?: object; ++ forceNonDeterministicRendering?: boolean; ++ isHorizontal?: boolean; ++ extendedState?: object; ++ internalSnapshot?: object; ++ layoutProvider?: BaseLayoutProvider; ++} ++export default abstract class BaseViewRenderer extends React.Component, {}> { ++ protected animatorStyleOverrides: object | undefined; ++ shouldComponentUpdate(newProps: ViewRendererProps): boolean; ++ componentDidMount(): void; ++ componentWillMount(): void; ++ componentWillUnmount(): void; ++ protected abstract getRef(): object | null; ++ protected renderChild(): JSX.Element | JSX.Element[] | null; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js +new file mode 100644 +index 0000000..f584ea7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js +@@ -0,0 +1,55 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseViewRenderer = /** @class */ (function (_super) { ++ __extends(BaseViewRenderer, _super); ++ function BaseViewRenderer() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ BaseViewRenderer.prototype.shouldComponentUpdate = function (newProps) { ++ var hasMoved = this.props.x !== newProps.x || this.props.y !== newProps.y; ++ var hasSizeChanged = !newProps.forceNonDeterministicRendering && ++ (this.props.width !== newProps.width || this.props.height !== newProps.height) || ++ this.props.layoutProvider !== newProps.layoutProvider; ++ var hasExtendedStateChanged = this.props.extendedState !== newProps.extendedState; ++ var hasInternalSnapshotChanged = this.props.internalSnapshot !== newProps.internalSnapshot; ++ var hasDataChanged = (this.props.dataHasChanged && this.props.dataHasChanged(this.props.data, newProps.data)); ++ var shouldUpdate = hasSizeChanged || hasDataChanged || hasExtendedStateChanged || hasInternalSnapshotChanged; ++ if (shouldUpdate) { ++ newProps.itemAnimator.animateWillUpdate(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); ++ } ++ else if (hasMoved) { ++ shouldUpdate = !newProps.itemAnimator.animateShift(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); ++ } ++ return shouldUpdate; ++ }; ++ BaseViewRenderer.prototype.componentDidMount = function () { ++ this.animatorStyleOverrides = undefined; ++ this.props.itemAnimator.animateDidMount(this.props.x, this.props.y, this.getRef(), this.props.index); ++ }; ++ BaseViewRenderer.prototype.componentWillMount = function () { ++ this.animatorStyleOverrides = this.props.itemAnimator.animateWillMount(this.props.x, this.props.y, this.props.index); ++ }; ++ BaseViewRenderer.prototype.componentWillUnmount = function () { ++ this.props.itemAnimator.animateWillUnmount(this.props.x, this.props.y, this.getRef(), this.props.index); ++ }; ++ BaseViewRenderer.prototype.renderChild = function () { ++ return this.props.childRenderer(this.props.layoutType, this.props.data, this.props.index, this.props.extendedState); ++ }; ++ return BaseViewRenderer; ++}(React.Component)); ++exports.default = BaseViewRenderer; ++//# sourceMappingURL=BaseViewRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js.map +new file mode 100644 +index 0000000..451d377 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BaseViewRenderer.js","sourceRoot":"","sources":["../../../../src/core/viewrenderer/BaseViewRenderer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/index.d.ts b/node_modules/recyclerlistview/dist/reactnative/index.d.ts +new file mode 100644 +index 0000000..230e231 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/index.d.ts +@@ -0,0 +1,11 @@ ++import ContextProvider from "./core/dependencies/ContextProvider"; ++import DataProvider, { BaseDataProvider } from "./core/dependencies/DataProvider"; ++import { BaseLayoutProvider, Dimension, LayoutProvider } from "./core/dependencies/LayoutProvider"; ++import RecyclerListView, { OnRecreateParams } from "./core/RecyclerListView"; ++import BaseScrollView from "./core/scrollcomponent/BaseScrollView"; ++import { BaseItemAnimator } from "./core/ItemAnimator"; ++import { AutoScroll } from "./utils/AutoScroll"; ++import { Layout, LayoutManager, Point, WrapGridLayoutManager } from "./core/layoutmanager/LayoutManager"; ++import ProgressiveListView from "./core/ProgressiveListView"; ++import { DebugHandlers } from "./core/devutils/debughandlers/DebugHandlers"; ++export { ContextProvider, DataProvider, LayoutProvider, BaseLayoutProvider, LayoutManager, WrapGridLayoutManager, RecyclerListView, ProgressiveListView, BaseItemAnimator, BaseScrollView, AutoScroll, Dimension, Point, Layout, OnRecreateParams, DebugHandlers, BaseDataProvider, }; +diff --git a/node_modules/recyclerlistview/dist/reactnative/index.js b/node_modules/recyclerlistview/dist/reactnative/index.js +new file mode 100644 +index 0000000..2faf787 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/index.js +@@ -0,0 +1,24 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ContextProvider_1 = require("./core/dependencies/ContextProvider"); ++exports.ContextProvider = ContextProvider_1.default; ++var DataProvider_1 = require("./core/dependencies/DataProvider"); ++exports.DataProvider = DataProvider_1.default; ++exports.BaseDataProvider = DataProvider_1.BaseDataProvider; ++var LayoutProvider_1 = require("./core/dependencies/LayoutProvider"); ++exports.BaseLayoutProvider = LayoutProvider_1.BaseLayoutProvider; ++exports.LayoutProvider = LayoutProvider_1.LayoutProvider; ++var RecyclerListView_1 = require("./core/RecyclerListView"); ++exports.RecyclerListView = RecyclerListView_1.default; ++var BaseScrollView_1 = require("./core/scrollcomponent/BaseScrollView"); ++exports.BaseScrollView = BaseScrollView_1.default; ++var ItemAnimator_1 = require("./core/ItemAnimator"); ++exports.BaseItemAnimator = ItemAnimator_1.BaseItemAnimator; ++var AutoScroll_1 = require("./utils/AutoScroll"); ++exports.AutoScroll = AutoScroll_1.AutoScroll; ++var LayoutManager_1 = require("./core/layoutmanager/LayoutManager"); ++exports.LayoutManager = LayoutManager_1.LayoutManager; ++exports.WrapGridLayoutManager = LayoutManager_1.WrapGridLayoutManager; ++var ProgressiveListView_1 = require("./core/ProgressiveListView"); ++exports.ProgressiveListView = ProgressiveListView_1.default; ++//# sourceMappingURL=index.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/index.js.map b/node_modules/recyclerlistview/dist/reactnative/index.js.map +new file mode 100644 +index 0000000..9e60fb9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/index.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;AAAA,uEAAkE;AAY9D,0BAZG,yBAAe,CAYH;AAXnB,iEAAkF;AAY9E,uBAZG,sBAAY,CAYH;AAeZ,2BA3BmB,+BAAgB,CA2BnB;AA1BpB,qEAAmG;AAa/F,6BAbK,mCAAkB,CAaL;AADlB,yBAZoC,+BAAc,CAYpC;AAXlB,4DAA6E;AAezE,2BAfG,0BAAgB,CAeH;AAdpB,wEAAmE;AAiB/D,yBAjBG,wBAAc,CAiBH;AAhBlB,oDAAuD;AAenD,2BAfK,+BAAgB,CAeL;AAdpB,iDAAgD;AAgB5C,qBAhBK,uBAAU,CAgBL;AAfd,oEAAyG;AASrG,wBATa,6BAAa,CASb;AACb,gCAVmC,qCAAqB,CAUnC;AATzB,kEAA6D;AAWzD,8BAXG,6BAAmB,CAWH"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts +new file mode 100644 +index 0000000..693e3a0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts +@@ -0,0 +1,12 @@ ++import { BaseItemAnimator } from "../../../core/ItemAnimator"; ++export declare class DefaultNativeItemAnimator implements BaseItemAnimator { ++ shouldAnimateOnce: boolean; ++ private _hasAnimatedOnce; ++ private _isTimerOn; ++ constructor(); ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js +new file mode 100644 +index 0000000..9ac03d1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js +@@ -0,0 +1,48 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var react_native_1 = require("react-native"); ++var DefaultNativeItemAnimator = /** @class */ (function () { ++ function DefaultNativeItemAnimator() { ++ this.shouldAnimateOnce = true; ++ this._hasAnimatedOnce = false; ++ this._isTimerOn = false; ++ if (react_native_1.Platform.OS === "android" && react_native_1.UIManager.setLayoutAnimationEnabledExperimental) { ++ react_native_1.UIManager.setLayoutAnimationEnabledExperimental(true); ++ } ++ } ++ DefaultNativeItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ DefaultNativeItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ DefaultNativeItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ this._hasAnimatedOnce = true; ++ }; ++ DefaultNativeItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ var _this = this; ++ if (fromX !== toX || fromY !== toY) { ++ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { ++ react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut); ++ this._hasAnimatedOnce = true; ++ } ++ } ++ else { ++ if (!this._isTimerOn) { ++ this._isTimerOn = true; ++ if (!this._hasAnimatedOnce) { ++ setTimeout(function () { ++ _this._hasAnimatedOnce = true; ++ }, 1000); ++ } ++ } ++ } ++ return false; ++ }; ++ DefaultNativeItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ return DefaultNativeItemAnimator; ++}()); ++exports.DefaultNativeItemAnimator = DefaultNativeItemAnimator; ++//# sourceMappingURL=DefaultNativeItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map +new file mode 100644 +index 0000000..50ecf5a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultNativeItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/itemanimators/DefaultNativeItemAnimator.ts"],"names":[],"mappings":";;AAAA,6CAAoE;AAGpE;IAII;QAHO,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;QAEhC,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,wBAAS,CAAC,qCAAqC,EAAE;YAC9E,wBAAS,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC;SACzD;IACL,CAAC;IACM,oDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,mDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,qDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,gDAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAiBC;QAhBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,8BAAe,CAAC,aAAa,CAAC,8BAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACrE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;aAChC;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,sDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,gCAAC;AAAD,CAAC,AA1CD,IA0CC;AA1CY,8DAAyB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts +new file mode 100644 +index 0000000..e3a83b3 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts +@@ -0,0 +1,19 @@ ++import { BaseItemAnimator } from "../../../../core/ItemAnimator"; ++/** ++ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator ++ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite ++ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if ++ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is ++ * hardly customizable. ++ */ ++export declare class DefaultJSItemAnimator implements BaseItemAnimator { ++ shouldAnimateOnce: boolean; ++ private _hasAnimatedOnce; ++ private _isTimerOn; ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ private _getNativePropObject; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js +new file mode 100644 +index 0000000..1b8b812 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js +@@ -0,0 +1,77 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var react_native_1 = require("react-native"); ++var ItemAnimator_1 = require("../../../../core/ItemAnimator"); ++/** ++ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator ++ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite ++ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if ++ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is ++ * hardly customizable. ++ */ ++var DefaultJSItemAnimator = /** @class */ (function () { ++ function DefaultJSItemAnimator() { ++ this.shouldAnimateOnce = true; ++ this._hasAnimatedOnce = false; ++ this._isTimerOn = false; ++ } ++ DefaultJSItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ DefaultJSItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ DefaultJSItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ this._hasAnimatedOnce = true; ++ }; ++ DefaultJSItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ var _this = this; ++ if (fromX !== toX || fromY !== toY) { ++ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { ++ var viewRef_1 = itemRef; ++ var animXY_1 = new react_native_1.Animated.ValueXY({ x: fromX, y: fromY }); ++ animXY_1.addListener(function (value) { ++ if (viewRef_1._isUnmountedForRecyclerListView || (_this.shouldAnimateOnce && _this._hasAnimatedOnce)) { ++ animXY_1.stopAnimation(); ++ return; ++ } ++ viewRef_1.setNativeProps(_this._getNativePropObject(value.x, value.y)); ++ }); ++ if (viewRef_1._lastAnimVal) { ++ viewRef_1._lastAnimVal.stopAnimation(); ++ } ++ viewRef_1._lastAnimVal = animXY_1; ++ react_native_1.Animated.timing(animXY_1, { ++ toValue: { x: toX, y: toY }, ++ duration: 200, ++ easing: react_native_1.Easing.out(react_native_1.Easing.ease), ++ useNativeDriver: ItemAnimator_1.BaseItemAnimator.USE_NATIVE_DRIVER, ++ }).start(function () { ++ viewRef_1._lastAnimVal = null; ++ _this._hasAnimatedOnce = true; ++ }); ++ return true; ++ } ++ } ++ else { ++ if (!this._isTimerOn) { ++ this._isTimerOn = true; ++ if (!this._hasAnimatedOnce) { ++ setTimeout(function () { ++ _this._hasAnimatedOnce = true; ++ }, 1000); ++ } ++ } ++ } ++ return false; ++ }; ++ DefaultJSItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ itemRef._isUnmountedForRecyclerListView = true; ++ }; ++ DefaultJSItemAnimator.prototype._getNativePropObject = function (x, y) { ++ return { style: { left: x, top: y } }; ++ }; ++ return DefaultJSItemAnimator; ++}()); ++exports.DefaultJSItemAnimator = DefaultJSItemAnimator; ++//# sourceMappingURL=DefaultJSItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map +new file mode 100644 +index 0000000..6a6881e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultJSItemAnimator.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts +new file mode 100644 +index 0000000..63ab9e4 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts +@@ -0,0 +1,2 @@ ++import { DefaultWebItemAnimator } from "../../../web/itemanimators/DefaultWebItemAnimator"; ++export { DefaultWebItemAnimator as DefaultJSItemAnimator }; +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js +new file mode 100644 +index 0000000..53a8a28 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js +@@ -0,0 +1,5 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var DefaultWebItemAnimator_1 = require("../../../web/itemanimators/DefaultWebItemAnimator"); ++exports.DefaultJSItemAnimator = DefaultWebItemAnimator_1.DefaultWebItemAnimator; ++//# sourceMappingURL=DefaultJSItemAnimator.web.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map +new file mode 100644 +index 0000000..ee1f03d +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultJSItemAnimator.web.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.ts"],"names":[],"mappings":";;AAAA,4FAA2F;AACxD,gCAD1B,+CAAsB,CACyB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.d.ts +new file mode 100644 +index 0000000..8e9f3e1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.d.ts +@@ -0,0 +1,26 @@ ++/// ++import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++export default class ScrollComponent extends BaseScrollComponent { ++ static defaultProps: { ++ contentHeight: number; ++ contentWidth: number; ++ externalScrollView: {}; ++ isHorizontal: boolean; ++ scrollThrottle: number; ++ }; ++ private _height; ++ private _width; ++ private _isSizeChangedCalledOnce; ++ private _scrollViewRef; ++ constructor(args: ScrollComponentProps); ++ scrollTo(x: number, y: number, isAnimated: boolean): void; ++ render(): JSX.Element; ++ private _getScrollViewRef; ++ private _onScroll; ++ private _onLayout; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js +new file mode 100644 +index 0000000..0cda95e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js +@@ -0,0 +1,102 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var react_native_1 = require("react-native"); ++var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); ++var TSCast_1 = require("../../../utils/TSCast"); ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++var ScrollComponent = /** @class */ (function (_super) { ++ __extends(ScrollComponent, _super); ++ function ScrollComponent(args) { ++ var _this = _super.call(this, args) || this; ++ _this._scrollViewRef = null; ++ _this._getScrollViewRef = function (scrollView) { _this._scrollViewRef = scrollView; }; ++ _this._onScroll = function (event) { ++ if (event) { ++ _this.props.onScroll(event.nativeEvent.contentOffset.x, event.nativeEvent.contentOffset.y, event); ++ } ++ }; ++ _this._onLayout = function (event) { ++ if (_this._height !== event.nativeEvent.layout.height || _this._width !== event.nativeEvent.layout.width) { ++ _this._height = event.nativeEvent.layout.height; ++ _this._width = event.nativeEvent.layout.width; ++ if (_this.props.onSizeChanged) { ++ _this._isSizeChangedCalledOnce = true; ++ _this.props.onSizeChanged(event.nativeEvent.layout); ++ } ++ } ++ if (_this.props.onLayout) { ++ _this.props.onLayout(event); ++ } ++ }; ++ _this._height = 0; ++ _this._width = 0; ++ _this._isSizeChangedCalledOnce = false; ++ return _this; ++ } ++ ScrollComponent.prototype.scrollTo = function (x, y, isAnimated) { ++ if (this._scrollViewRef) { ++ this._scrollViewRef.scrollTo({ x: x, y: y, animated: isAnimated }); ++ } ++ }; ++ ScrollComponent.prototype.render = function () { ++ var Scroller = TSCast_1.default.cast(this.props.externalScrollView); //TSI ++ //TODO:Talha ++ // const { ++ // useWindowScroll, ++ // contentHeight, ++ // contentWidth, ++ // externalScrollView, ++ // canChangeSize, ++ // renderFooter, ++ // isHorizontal, ++ // scrollThrottle, ++ // ...props, ++ // } = this.props; ++ return (React.createElement(Scroller, __assign({ ref: this._getScrollViewRef, removeClippedSubviews: false, scrollEventThrottle: this.props.scrollThrottle }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onLayout: (!this._isSizeChangedCalledOnce || this.props.canChangeSize) ? this._onLayout : this.props.onLayout }), ++ React.createElement(react_native_1.View, { style: { flexDirection: this.props.isHorizontal ? "row" : "column" } }, ++ React.createElement(react_native_1.View, { style: { ++ height: this.props.contentHeight, ++ width: this.props.contentWidth, ++ } }, this.props.children), ++ this.props.renderFooter ? this.props.renderFooter() : null))); ++ }; ++ ScrollComponent.defaultProps = { ++ contentHeight: 0, ++ contentWidth: 0, ++ externalScrollView: TSCast_1.default.cast(react_native_1.ScrollView), ++ isHorizontal: false, ++ scrollThrottle: 16, ++ }; ++ return ScrollComponent; ++}(BaseScrollComponent_1.default)); ++exports.default = ScrollComponent; ++//# sourceMappingURL=ScrollComponent.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js.map +new file mode 100644 +index 0000000..16bf1fd +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.d.ts +new file mode 100644 +index 0000000..fe95fc1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.d.ts +@@ -0,0 +1,16 @@ ++/// ++import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++export default class ViewRenderer extends BaseViewRenderer { ++ private _dim; ++ private _viewRef; ++ render(): JSX.Element; ++ protected getRef(): object | null; ++ private _setRef; ++ private _onLayout; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js +new file mode 100644 +index 0000000..5b56fd5 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js +@@ -0,0 +1,70 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var react_native_1 = require("react-native"); ++var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++var ViewRenderer = /** @class */ (function (_super) { ++ __extends(ViewRenderer, _super); ++ function ViewRenderer() { ++ var _this = _super !== null && _super.apply(this, arguments) || this; ++ _this._dim = { width: 0, height: 0 }; ++ _this._viewRef = null; ++ _this._setRef = function (view) { ++ _this._viewRef = view; ++ }; ++ _this._onLayout = function (event) { ++ //Preventing layout thrashing in super fast scrolls where RN messes up onLayout event ++ var xDiff = Math.abs(_this.props.x - event.nativeEvent.layout.x); ++ var yDiff = Math.abs(_this.props.y - event.nativeEvent.layout.y); ++ if (xDiff < 1 && yDiff < 1 && ++ (_this.props.height !== event.nativeEvent.layout.height || ++ _this.props.width !== event.nativeEvent.layout.width)) { ++ _this._dim.height = event.nativeEvent.layout.height; ++ _this._dim.width = event.nativeEvent.layout.width; ++ if (_this.props.onSizeChanged) { ++ _this.props.onSizeChanged(_this._dim, _this.props.index); ++ } ++ } ++ }; ++ return _this; ++ } ++ ViewRenderer.prototype.render = function () { ++ return this.props.forceNonDeterministicRendering ? (React.createElement(react_native_1.View, { ref: this._setRef, onLayout: this._onLayout, style: __assign({ flexDirection: this.props.isHorizontal ? "column" : "row", left: this.props.x, position: "absolute", top: this.props.y }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())) : (React.createElement(react_native_1.View, { ref: this._setRef, style: __assign({ left: this.props.x, position: "absolute", top: this.props.y, height: this.props.height, width: this.props.width }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())); ++ }; ++ ViewRenderer.prototype.getRef = function () { ++ return this._viewRef; ++ }; ++ return ViewRenderer; ++}(BaseViewRenderer_1.default)); ++exports.default = ViewRenderer; ++//# sourceMappingURL=ViewRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js.map +new file mode 100644 +index 0000000..ceacfb9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAC/B,6CAAuE;AAEvE,gFAAkG;AAElG;;;;;GAKG;AACH;IAA0C,gCAAqB;IAA/D;QAAA,qEAuDC;QAtDW,UAAI,GAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1C,cAAQ,GAAiE,IAAI,CAAC;QAmC9E,aAAO,GAAG,UAAC,IAAkE;YACjF,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,CAAC,CAAA;QAEO,eAAS,GAAG,UAAC,KAAwB;YACzC,qFAAqF;YACrF,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC;gBACtB,CAAC,KAAI,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;oBAClD,KAAI,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAC1D,KAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACnD,KAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;gBACjD,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;oBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAI,CAAC,IAAI,EAAE,KAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;iBACzD;aACJ;QACL,CAAC,CAAA;;IACL,CAAC;IApDU,6BAAM,GAAb;QACI,OAAO,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAC/C,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACvB,QAAQ,EAAE,IAAI,CAAC,SAAS,EACpB,KAAK,aACD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EACzD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IACd,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC,CAAC,CAAC,CACI,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACnB,KAAK,aACD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EACzB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IACpB,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC;IACV,CAAC;IAES,6BAAM,GAAhB;QACI,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAoBL,mBAAC;AAAD,CAAC,AAvDD,CAA0C,0BAAgB,GAuDzD"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts +new file mode 100644 +index 0000000..30681d9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts +@@ -0,0 +1,2 @@ ++import ViewRenderer from "../../web/viewrenderer/ViewRenderer"; ++export default ViewRenderer; +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js +new file mode 100644 +index 0000000..75c2c66 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js +@@ -0,0 +1,5 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ViewRenderer_1 = require("../../web/viewrenderer/ViewRenderer"); ++exports.default = ViewRenderer_1.default; ++//# sourceMappingURL=ViewRenderer.web.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js.map +new file mode 100644 +index 0000000..f50f385 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewRenderer.web.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.web.tsx"],"names":[],"mappings":";;AAAA,oEAA+D;AAC/D,kBAAe,sBAAY,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.d.ts +new file mode 100644 +index 0000000..1c1db85 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.d.ts +@@ -0,0 +1,15 @@ ++import { BaseItemAnimator } from "../../../core/ItemAnimator"; ++/** ++ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all ++ * shift events. ++ */ ++export declare class DefaultWebItemAnimator implements BaseItemAnimator { ++ shouldAnimateOnce: boolean; ++ private _hasAnimatedOnce; ++ private _isTimerOn; ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js +new file mode 100644 +index 0000000..3db93b4 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js +@@ -0,0 +1,54 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++/** ++ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all ++ * shift events. ++ */ ++var DefaultWebItemAnimator = /** @class */ (function () { ++ function DefaultWebItemAnimator() { ++ this.shouldAnimateOnce = true; ++ this._hasAnimatedOnce = false; ++ this._isTimerOn = false; ++ } ++ DefaultWebItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ DefaultWebItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ DefaultWebItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ this._hasAnimatedOnce = true; ++ }; ++ DefaultWebItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ var _this = this; ++ if (fromX !== toX || fromY !== toY) { ++ var element_1 = itemRef; ++ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { ++ var transitionEndCallback_1 = function (event) { ++ element_1.style.transition = ""; ++ element_1.removeEventListener("transitionend", transitionEndCallback_1); ++ _this._hasAnimatedOnce = true; ++ }; ++ element_1.style.transition = "transform 0.15s ease-out"; ++ element_1.addEventListener("transitionend", transitionEndCallback_1, false); ++ } ++ } ++ else { ++ if (!this._isTimerOn) { ++ this._isTimerOn = true; ++ if (!this._hasAnimatedOnce) { ++ setTimeout(function () { ++ _this._hasAnimatedOnce = true; ++ }, 1000); ++ } ++ } ++ } ++ return false; ++ }; ++ DefaultWebItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ return DefaultWebItemAnimator; ++}()); ++exports.DefaultWebItemAnimator = DefaultWebItemAnimator; ++//# sourceMappingURL=DefaultWebItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js.map +new file mode 100644 +index 0000000..44c688a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultWebItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/web/itemanimators/DefaultWebItemAnimator.ts"],"names":[],"mappings":";;AAEA;;;GAGG;AACH;IAAA;QACW,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;IAwCxC,CAAC;IAvCU,iDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,gDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,kDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,6CAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAuBC;QAtBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAM,SAAO,GAAG,OAAyB,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,IAAM,uBAAqB,GAAkB,UAAC,KAAK;oBAC/C,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;oBAC9B,SAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,uBAAqB,CAAC,CAAC;oBACpE,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACjC,CAAC,CAAC;gBACF,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,0BAA0B,CAAC;gBACtD,SAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,uBAAqB,EAAE,KAAK,CAAC,CAAC;aAC3E;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,mDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,6BAAC;AAAD,CAAC,AA3CD,IA2CC;AA3CY,wDAAsB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.d.ts +new file mode 100644 +index 0000000..2188791 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.d.ts +@@ -0,0 +1,26 @@ ++/// ++import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; ++import ScrollViewer from "./ScrollViewer"; ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++export default class ScrollComponent extends BaseScrollComponent { ++ static defaultProps: { ++ contentHeight: number; ++ contentWidth: number; ++ externalScrollView: typeof ScrollViewer; ++ isHorizontal: boolean; ++ scrollThrottle: number; ++ canChangeSize: boolean; ++ }; ++ private _height; ++ private _width; ++ private _scrollViewRef; ++ constructor(args: ScrollComponentProps); ++ scrollTo(x: number, y: number, animated: boolean): void; ++ render(): JSX.Element; ++ private _onScroll; ++ private _onSizeChanged; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js +new file mode 100644 +index 0000000..dca7ab7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js +@@ -0,0 +1,82 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); ++var ScrollViewer_1 = require("./ScrollViewer"); ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++var ScrollComponent = /** @class */ (function (_super) { ++ __extends(ScrollComponent, _super); ++ function ScrollComponent(args) { ++ var _this = _super.call(this, args) || this; ++ _this._scrollViewRef = null; ++ _this._onScroll = function (e) { ++ _this.props.onScroll(e.nativeEvent.contentOffset.x, e.nativeEvent.contentOffset.y, e); ++ }; ++ _this._onSizeChanged = function (event) { ++ if (_this.props.onSizeChanged) { ++ _this.props.onSizeChanged(event); ++ } ++ }; ++ _this._height = 0; ++ _this._width = 0; ++ return _this; ++ } ++ ScrollComponent.prototype.scrollTo = function (x, y, animated) { ++ if (this._scrollViewRef) { ++ this._scrollViewRef.scrollTo({ x: x, y: y, animated: animated }); ++ } ++ }; ++ ScrollComponent.prototype.render = function () { ++ var _this = this; ++ var Scroller = this.props.externalScrollView; //TSI ++ return (React.createElement(Scroller, __assign({ ref: function (scrollView) { return _this._scrollViewRef = scrollView; } }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onSizeChanged: this._onSizeChanged }), ++ React.createElement("div", { style: { ++ height: this.props.contentHeight, ++ width: this.props.contentWidth, ++ } }, this.props.children), ++ this.props.renderFooter ? React.createElement("div", { style: this.props.isHorizontal ? { ++ left: this.props.contentWidth, ++ position: "absolute", ++ top: 0, ++ } : undefined }, this.props.renderFooter()) : null)); ++ }; ++ ScrollComponent.defaultProps = { ++ contentHeight: 0, ++ contentWidth: 0, ++ externalScrollView: ScrollViewer_1.default, ++ isHorizontal: false, ++ scrollThrottle: 16, ++ canChangeSize: false, ++ }; ++ return ScrollComponent; ++}(BaseScrollComponent_1.default)); ++exports.default = ScrollComponent; ++//# sourceMappingURL=ScrollComponent.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js.map +new file mode 100644 +index 0000000..5436601 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAE/B,yFAA8G;AAE9G,+CAA0C;AAC1C;;;;GAIG;AAEH;IAA6C,mCAAmB;IAa5D,yBAAY,IAA0B;QAAtC,YACI,kBAAM,IAAI,CAAC,SAGd;QANO,oBAAc,GAA0B,IAAI,CAAC;QAwC7C,eAAS,GAAG,UAAC,CAAc;YAC/B,KAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC,CAAA;QAEO,oBAAc,GAAG,UAAC,KAAgB;YACtC,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;gBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;aACnC;QACL,CAAC,CAAA;QA5CG,KAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,KAAI,CAAC,MAAM,GAAG,CAAC,CAAC;;IACpB,CAAC;IAEM,kCAAQ,GAAf,UAAgB,CAAS,EAAE,CAAS,EAAE,QAAiB;QACnD,IAAI,IAAI,CAAC,cAAc,EAAE;YACrB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE,QAAQ,UAAA,EAAE,CAAC,CAAC;SACpD;IACL,CAAC;IAEM,gCAAM,GAAb;QAAA,iBAwBC;QAvBG,IAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAyB,CAAC,CAAC,KAAK;QAC5D,OAAO,CACH,oBAAC,QAAQ,aAAC,GAAG,EAAE,UAAC,UAA0B,IAAK,OAAA,KAAI,CAAC,cAAc,GAAG,UAAqC,EAA3D,CAA2D,IAClG,IAAI,CAAC,KAAK,IACd,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EACnC,QAAQ,EAAE,IAAI,CAAC,SAAS,EACxB,aAAa,EAAE,IAAI,CAAC,cAAc;YAElC,6BAAK,KAAK,EAAE;oBACR,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;oBAChC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;iBACjC,IACI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAClB;YACL,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,6BAAK,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC7D,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;oBAC7B,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,CAAC;iBACT,CAAC,CAAC,CAAC,SAAS,IACR,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CACxB,CAAC,CAAC,CAAC,IAAI,CACN,CACd,CAAC;IACN,CAAC;IAhDa,4BAAY,GAAG;QACzB,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,kBAAkB,EAAE,sBAAY;QAChC,YAAY,EAAE,KAAK;QACnB,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,KAAK;KACvB,CAAC;IAoDN,sBAAC;CAAA,AA5DD,CAA6C,6BAAmB,GA4D/D;kBA5DoB,eAAe"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts +new file mode 100644 +index 0000000..5551eef +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts +@@ -0,0 +1,6 @@ ++import { ScrollEvent } from "../../../core/scrollcomponent/BaseScrollView"; ++export declare class ScrollEventNormalizer { ++ divEvent: ScrollEvent; ++ windowEvent: ScrollEvent; ++ constructor(target: HTMLDivElement); ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js +new file mode 100644 +index 0000000..d930364 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js +@@ -0,0 +1,65 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ScrollEventNormalizer = /** @class */ (function () { ++ function ScrollEventNormalizer(target) { ++ this.divEvent = { ++ nativeEvent: { ++ contentOffset: { ++ get x() { ++ return target.scrollLeft; ++ }, ++ get y() { ++ return target.scrollTop; ++ }, ++ }, ++ contentSize: { ++ get height() { ++ return target.scrollHeight; ++ }, ++ get width() { ++ return target.scrollWidth; ++ }, ++ }, ++ layoutMeasurement: { ++ get height() { ++ return target.offsetHeight; ++ }, ++ get width() { ++ return target.offsetWidth; ++ }, ++ }, ++ }, ++ }; ++ this.windowEvent = { ++ nativeEvent: { ++ contentOffset: { ++ get x() { ++ return window.scrollX === undefined ? window.pageXOffset : window.scrollX; ++ }, ++ get y() { ++ return window.scrollY === undefined ? window.pageYOffset : window.scrollY; ++ }, ++ }, ++ contentSize: { ++ get height() { ++ return target.offsetHeight; ++ }, ++ get width() { ++ return target.offsetWidth; ++ }, ++ }, ++ layoutMeasurement: { ++ get height() { ++ return window.innerHeight; ++ }, ++ get width() { ++ return window.innerWidth; ++ }, ++ }, ++ }, ++ }; ++ } ++ return ScrollEventNormalizer; ++}()); ++exports.ScrollEventNormalizer = ScrollEventNormalizer; ++//# sourceMappingURL=ScrollEventNormalizer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js.map +new file mode 100644 +index 0000000..52347ab +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollEventNormalizer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollEventNormalizer.ts"],"names":[],"mappings":";;AAEA;IAGI,+BAAY,MAAsB;QAC9B,IAAI,CAAC,QAAQ,GAAG;YACZ,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,SAAS,CAAC;oBAC5B,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;aACJ;SACJ,CAAC;QACF,IAAI,CAAC,WAAW,GAAG;YACf,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;iBACJ;aACJ;SACJ,CAAC;IACN,CAAC;IACL,4BAAC;AAAD,CAAC,AA7DD,IA6DC;AA7DY,sDAAqB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.d.ts +new file mode 100644 +index 0000000..069cc18 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.d.ts +@@ -0,0 +1,38 @@ ++/// ++import BaseScrollView from "../../../core/scrollcomponent/BaseScrollView"; ++/*** ++ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. ++ * Supports both window scroll and scrollable divs inside other divs. ++ */ ++export default class ScrollViewer extends BaseScrollView { ++ static defaultProps: { ++ canChangeSize: boolean; ++ horizontal: boolean; ++ style: null; ++ useWindowScroll: boolean; ++ }; ++ private scrollEndEventSimulator; ++ private _mainDivRef; ++ private _isScrolling; ++ private _scrollEventNormalizer; ++ componentDidMount(): void; ++ componentWillUnmount(): void; ++ scrollTo(scrollInput: { ++ x: number; ++ y: number; ++ animated: boolean; ++ }): void; ++ render(): JSX.Element; ++ private _setDivRef; ++ private _getRelevantOffset; ++ private _setRelevantOffset; ++ private _isScrollEnd; ++ private _trackScrollOccurence; ++ private _doAnimatedScroll; ++ private _startListeningToDivEvents; ++ private _startListeningToWindowEvents; ++ private _onWindowResize; ++ private _windowOnScroll; ++ private _onScroll; ++ private _easeInOut; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js +new file mode 100644 +index 0000000..bdfd4e8 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js +@@ -0,0 +1,214 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollView_1 = require("../../../core/scrollcomponent/BaseScrollView"); ++var debounce = require("lodash.debounce"); ++var ScrollEventNormalizer_1 = require("./ScrollEventNormalizer"); ++/*** ++ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. ++ * Supports both window scroll and scrollable divs inside other divs. ++ */ ++var ScrollViewer = /** @class */ (function (_super) { ++ __extends(ScrollViewer, _super); ++ function ScrollViewer() { ++ var _this = _super !== null && _super.apply(this, arguments) || this; ++ _this.scrollEndEventSimulator = debounce(function (executable) { ++ executable(); ++ }, 1200); ++ _this._mainDivRef = null; ++ _this._isScrolling = false; ++ _this._scrollEventNormalizer = null; ++ _this._setDivRef = function (div) { ++ _this._mainDivRef = div; ++ if (div) { ++ _this._scrollEventNormalizer = new ScrollEventNormalizer_1.ScrollEventNormalizer(div); ++ } ++ else { ++ _this._scrollEventNormalizer = null; ++ } ++ }; ++ _this._getRelevantOffset = function () { ++ if (!_this.props.useWindowScroll) { ++ if (_this._mainDivRef) { ++ if (_this.props.horizontal) { ++ return _this._mainDivRef.scrollLeft; ++ } ++ else { ++ return _this._mainDivRef.scrollTop; ++ } ++ } ++ return 0; ++ } ++ else { ++ if (_this.props.horizontal) { ++ return window.scrollX; ++ } ++ else { ++ return window.scrollY; ++ } ++ } ++ }; ++ _this._setRelevantOffset = function (offset) { ++ if (!_this.props.useWindowScroll) { ++ if (_this._mainDivRef) { ++ if (_this.props.horizontal) { ++ _this._mainDivRef.scrollLeft = offset; ++ } ++ else { ++ _this._mainDivRef.scrollTop = offset; ++ } ++ } ++ } ++ else { ++ if (_this.props.horizontal) { ++ window.scrollTo(offset, 0); ++ } ++ else { ++ window.scrollTo(0, offset); ++ } ++ } ++ }; ++ _this._isScrollEnd = function () { ++ if (_this._mainDivRef) { ++ _this._mainDivRef.style.pointerEvents = "auto"; ++ } ++ _this._isScrolling = false; ++ }; ++ _this._trackScrollOccurence = function () { ++ if (!_this._isScrolling) { ++ if (_this._mainDivRef) { ++ _this._mainDivRef.style.pointerEvents = "none"; ++ } ++ _this._isScrolling = true; ++ } ++ _this.scrollEndEventSimulator(_this._isScrollEnd); ++ }; ++ _this._onWindowResize = function () { ++ if (_this.props.onSizeChanged && _this.props.useWindowScroll) { ++ _this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); ++ } ++ }; ++ _this._windowOnScroll = function () { ++ if (_this.props.onScroll) { ++ if (_this._scrollEventNormalizer) { ++ _this.props.onScroll(_this._scrollEventNormalizer.windowEvent); ++ } ++ } ++ }; ++ _this._onScroll = function () { ++ if (_this.props.onScroll) { ++ if (_this._scrollEventNormalizer) { ++ _this.props.onScroll(_this._scrollEventNormalizer.divEvent); ++ } ++ } ++ }; ++ return _this; ++ } ++ ScrollViewer.prototype.componentDidMount = function () { ++ if (this.props.onSizeChanged) { ++ if (this.props.useWindowScroll) { ++ this._startListeningToWindowEvents(); ++ this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); ++ } ++ else if (this._mainDivRef) { ++ this._startListeningToDivEvents(); ++ this.props.onSizeChanged({ height: this._mainDivRef.clientHeight, width: this._mainDivRef.clientWidth }); ++ } ++ } ++ }; ++ ScrollViewer.prototype.componentWillUnmount = function () { ++ window.removeEventListener("scroll", this._windowOnScroll); ++ if (this._mainDivRef) { ++ this._mainDivRef.removeEventListener("scroll", this._onScroll); ++ } ++ window.removeEventListener("resize", this._onWindowResize); ++ }; ++ ScrollViewer.prototype.scrollTo = function (scrollInput) { ++ if (scrollInput.animated) { ++ this._doAnimatedScroll(this.props.horizontal ? scrollInput.x : scrollInput.y); ++ } ++ else { ++ this._setRelevantOffset(this.props.horizontal ? scrollInput.x : scrollInput.y); ++ } ++ }; ++ ScrollViewer.prototype.render = function () { ++ return !this.props.useWindowScroll ++ ? React.createElement("div", { ref: this._setDivRef, style: __assign({ WebkitOverflowScrolling: "touch", height: "100%", overflowX: this.props.horizontal ? "scroll" : "hidden", overflowY: !this.props.horizontal ? "scroll" : "hidden", width: "100%" }, this.props.style) }, ++ React.createElement("div", { style: { position: "relative" } }, this.props.children)) ++ : React.createElement("div", { ref: this._setDivRef, style: __assign({ position: "relative" }, this.props.style) }, this.props.children); ++ }; ++ ScrollViewer.prototype._doAnimatedScroll = function (offset) { ++ var _this = this; ++ var start = this._getRelevantOffset(); ++ if (offset > start) { ++ start = Math.max(offset - 800, start); ++ } ++ else { ++ start = Math.min(offset + 800, start); ++ } ++ var change = offset - start; ++ var increment = 20; ++ var duration = 200; ++ var animateScroll = function (elapsedTime) { ++ elapsedTime += increment; ++ var position = _this._easeInOut(elapsedTime, start, change, duration); ++ _this._setRelevantOffset(position); ++ if (elapsedTime < duration) { ++ window.setTimeout(function () { return animateScroll(elapsedTime); }, increment); ++ } ++ }; ++ animateScroll(0); ++ }; ++ ScrollViewer.prototype._startListeningToDivEvents = function () { ++ if (this._mainDivRef) { ++ this._mainDivRef.addEventListener("scroll", this._onScroll); ++ } ++ }; ++ ScrollViewer.prototype._startListeningToWindowEvents = function () { ++ window.addEventListener("scroll", this._windowOnScroll); ++ if (this.props.canChangeSize) { ++ window.addEventListener("resize", this._onWindowResize); ++ } ++ }; ++ ScrollViewer.prototype._easeInOut = function (currentTime, start, change, duration) { ++ currentTime /= duration / 2; ++ if (currentTime < 1) { ++ return change / 2 * currentTime * currentTime + start; ++ } ++ currentTime -= 1; ++ return (-change) / 2 * (currentTime * (currentTime - 2) - 1) + start; ++ }; ++ ScrollViewer.defaultProps = { ++ canChangeSize: false, ++ horizontal: false, ++ style: null, ++ useWindowScroll: false, ++ }; ++ return ScrollViewer; ++}(BaseScrollView_1.default)); ++exports.default = ScrollViewer; ++//# sourceMappingURL=ScrollViewer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js.map +new file mode 100644 +index 0000000..ea465a9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollViewer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollViewer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.d.ts +new file mode 100644 +index 0000000..76283f9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.d.ts +@@ -0,0 +1,19 @@ ++/// ++import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++export default class ViewRenderer extends BaseViewRenderer { ++ private _dim; ++ private _mainDiv; ++ componentDidMount(): void; ++ componentDidUpdate(): void; ++ render(): JSX.Element; ++ protected getRef(): object | null; ++ private _setRef; ++ private _getTransform; ++ private _checkSizeChange; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js +new file mode 100644 +index 0000000..81d8dc1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js +@@ -0,0 +1,98 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++var ViewRenderer = /** @class */ (function (_super) { ++ __extends(ViewRenderer, _super); ++ function ViewRenderer() { ++ var _this = _super !== null && _super.apply(this, arguments) || this; ++ _this._dim = { width: 0, height: 0 }; ++ _this._mainDiv = null; ++ _this._setRef = function (div) { ++ _this._mainDiv = div; ++ }; ++ return _this; ++ } ++ ViewRenderer.prototype.componentDidMount = function () { ++ if (_super.prototype.componentDidMount) { ++ _super.prototype.componentDidMount.call(this); ++ } ++ this._checkSizeChange(); ++ }; ++ ViewRenderer.prototype.componentDidUpdate = function () { ++ this._checkSizeChange(); ++ }; ++ ViewRenderer.prototype.render = function () { ++ var style = this.props.forceNonDeterministicRendering ++ ? __assign({ transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides) : __assign({ height: this.props.height, overflow: "hidden", width: this.props.width, transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides); ++ return (React.createElement("div", { ref: this._setRef, style: style }, this.renderChild())); ++ }; ++ ViewRenderer.prototype.getRef = function () { ++ return this._mainDiv; ++ }; ++ ViewRenderer.prototype._getTransform = function () { ++ return "translate(" + this.props.x + "px," + this.props.y + "px)"; ++ }; ++ ViewRenderer.prototype._checkSizeChange = function () { ++ if (this.props.forceNonDeterministicRendering && this.props.onSizeChanged) { ++ var mainDiv = this._mainDiv; ++ if (mainDiv) { ++ this._dim.width = mainDiv.clientWidth; ++ this._dim.height = mainDiv.clientHeight; ++ if (this.props.width !== this._dim.width || this.props.height !== this._dim.height) { ++ this.props.onSizeChanged(this._dim, this.props.index); ++ } ++ } ++ } ++ }; ++ return ViewRenderer; ++}(BaseViewRenderer_1.default)); ++exports.default = ViewRenderer; ++var styles = { ++ baseViewStyle: { ++ alignItems: "stretch", ++ borderWidth: 0, ++ borderStyle: "solid", ++ boxSizing: "border-box", ++ display: "flex", ++ flexDirection: "column", ++ margin: 0, ++ padding: 0, ++ position: "absolute", ++ minHeight: 0, ++ minWidth: 0, ++ left: 0, ++ top: 0, ++ }, ++}; ++//# sourceMappingURL=ViewRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js.map +new file mode 100644 +index 0000000..7810112 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/web/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.d.ts +new file mode 100644 +index 0000000..0bd1380 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.d.ts +@@ -0,0 +1,6 @@ ++export interface Scrollable { ++ scrollToOffset(x: number, y: number, animate: boolean): void; ++} ++export declare class AutoScroll { ++ static scrollNow(scrollable: Scrollable, fromX: number, fromY: number, toX: number, toY: number, speedMultiplier?: number): Promise; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js +new file mode 100644 +index 0000000..ab91ef0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js +@@ -0,0 +1,36 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var AutoScroll = /** @class */ (function () { ++ function AutoScroll() { ++ } ++ AutoScroll.scrollNow = function (scrollable, fromX, fromY, toX, toY, speedMultiplier) { ++ if (speedMultiplier === void 0) { speedMultiplier = 1; } ++ return new Promise(function (resolve) { ++ scrollable.scrollToOffset(fromX, fromY, false); ++ var incrementPerMs = 0.1 * speedMultiplier; ++ var startTime = Date.now(); ++ var startX = fromX; ++ var startY = fromY; ++ var animationLoop = function () { ++ requestAnimationFrame(function () { ++ var currentTime = Date.now(); ++ var timeElapsed = currentTime - startTime; ++ var distanceToCover = incrementPerMs * timeElapsed; ++ startX += distanceToCover; ++ startY += distanceToCover; ++ scrollable.scrollToOffset(Math.min(toX, startX), Math.min(toY, startY), false); ++ startTime = currentTime; ++ if (Math.min(toX, startX) !== toX || Math.min(toY, startY) !== toY) { ++ animationLoop(); ++ return; ++ } ++ resolve(); ++ }); ++ }; ++ animationLoop(); ++ }); ++ }; ++ return AutoScroll; ++}()); ++exports.AutoScroll = AutoScroll; ++//# sourceMappingURL=AutoScroll.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js.map +new file mode 100644 +index 0000000..86f9d26 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"AutoScroll.js","sourceRoot":"","sources":["../../../src/utils/AutoScroll.ts"],"names":[],"mappings":";;AAGA;IAAA;IA2BA,CAAC;IA1BiB,oBAAS,GAAvB,UAAwB,UAAsB,EAAE,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,eAA2B;QAA3B,gCAAA,EAAA,mBAA2B;QAC/H,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO;YACvB,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAM,cAAc,GAAG,GAAG,GAAG,eAAe,CAAC;YAC7C,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAM,aAAa,GAAG;gBAClB,qBAAqB,CAAC;oBAClB,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC/B,IAAM,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;oBAC5C,IAAM,eAAe,GAAG,cAAc,GAAG,WAAW,CAAC;oBACrD,MAAM,IAAI,eAAe,CAAC;oBAC1B,MAAM,IAAI,eAAe,CAAC;oBAC1B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;oBAC/E,SAAS,GAAG,WAAW,CAAC;oBACxB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE;wBAChE,aAAa,EAAE,CAAC;wBAChB,OAAO;qBACV;oBACD,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,aAAa,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IACL,iBAAC;AAAD,CAAC,AA3BD,IA2BC;AA3BY,gCAAU"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.d.ts +new file mode 100644 +index 0000000..9365580 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.d.ts +@@ -0,0 +1,17 @@ ++export interface ValueAndIndex { ++ value: number; ++ index: number; ++} ++export default class BinarySearch { ++ static findClosestHigherValueIndex(size: number, targetValue: number, valueExtractor: (index: number) => number): number; ++ static findClosestValueToTarget(values: number[], target: number): ValueAndIndex; ++ /** ++ * Largest value from given values that is smaller or equal to the target number. ++ */ ++ static findValueSmallerThanTarget(values: number[], target: number): ValueAndIndex | undefined; ++ /** ++ * Smallest value from given values that is larger or equal to the target number. ++ */ ++ static findValueLargerThanTarget(values: number[], target: number): ValueAndIndex | undefined; ++ static findIndexOf(array: number[], value: number): number; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js +new file mode 100644 +index 0000000..74f37c5 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js +@@ -0,0 +1,154 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var CustomError_1 = require("../core/exceptions/CustomError"); ++var BinarySearch = /** @class */ (function () { ++ function BinarySearch() { ++ } ++ BinarySearch.findClosestHigherValueIndex = function (size, targetValue, valueExtractor) { ++ var low = 0; ++ var high = size - 1; ++ var mid = Math.floor((low + high) / 2); ++ var lastValue = 0; ++ var absoluteLastDiff = Math.abs(valueExtractor(mid) - targetValue); ++ var result = mid; ++ var diff = 0; ++ var absoluteDiff = 0; ++ if (absoluteLastDiff === 0) { ++ return result; ++ } ++ if (high < 0) { ++ throw new CustomError_1.default({ ++ message: "The collection cannot be empty", ++ type: "InvalidStateException", ++ }); ++ } ++ while (low <= high) { ++ mid = Math.floor((low + high) / 2); ++ lastValue = valueExtractor(mid); ++ diff = lastValue - targetValue; ++ absoluteDiff = Math.abs(diff); ++ if (diff >= 0 && absoluteDiff < absoluteLastDiff) { ++ absoluteLastDiff = absoluteDiff; ++ result = mid; ++ } ++ if (targetValue < lastValue) { ++ high = mid - 1; ++ } ++ else if (targetValue > lastValue) { ++ low = mid + 1; ++ } ++ else { ++ return mid; ++ } ++ } ++ return result; ++ }; ++ BinarySearch.findClosestValueToTarget = function (values, target) { ++ var low = 0; ++ var high = values.length - 1; ++ var mid = Math.floor((low + high) / 2); ++ var midValue = values[mid]; ++ var lastMidValue = midValue + 1; ++ while (low <= high && midValue !== lastMidValue) { ++ if (midValue === target) { ++ break; ++ } ++ else if (midValue < target) { ++ low = mid; ++ } ++ else if (midValue > target) { ++ high = mid; ++ } ++ mid = Math.floor((low + high) / 2); ++ lastMidValue = midValue; ++ midValue = values[mid]; ++ } ++ return { ++ value: midValue, ++ index: mid, ++ }; ++ }; ++ /** ++ * Largest value from given values that is smaller or equal to the target number. ++ */ ++ BinarySearch.findValueSmallerThanTarget = function (values, target) { ++ var low = 0; ++ var high = values.length - 1; ++ if (target >= values[high]) { ++ return { ++ value: values[high], ++ index: high, ++ }; ++ } ++ else if (target < values[low]) { ++ return undefined; ++ } ++ var midValueAndIndex = this.findClosestValueToTarget(values, target); ++ var midValue = midValueAndIndex.value; ++ var mid = midValueAndIndex.index; ++ if (midValue <= target) { ++ return { ++ value: midValue, ++ index: mid, ++ }; ++ } ++ else { ++ return { ++ value: values[mid - 1], ++ index: mid - 1, ++ }; ++ } ++ }; ++ /** ++ * Smallest value from given values that is larger or equal to the target number. ++ */ ++ BinarySearch.findValueLargerThanTarget = function (values, target) { ++ var low = 0; ++ var high = values.length - 1; ++ if (target < values[low]) { ++ return { ++ value: values[low], ++ index: low, ++ }; ++ } ++ else if (target > values[high]) { ++ return undefined; ++ } ++ var midValueAndIndex = this.findClosestValueToTarget(values, target); ++ var midValue = midValueAndIndex.value; ++ var mid = midValueAndIndex.index; ++ if (midValue >= target) { ++ return { ++ value: midValue, ++ index: mid, ++ }; ++ } ++ else { ++ return { ++ value: values[mid + 1], ++ index: mid + 1, ++ }; ++ } ++ }; ++ BinarySearch.findIndexOf = function (array, value) { ++ var j = 0; ++ var length = array.length; ++ var i = 0; ++ while (j < length) { ++ i = length + j - 1 >> 1; ++ if (value > array[i]) { ++ j = i + 1; ++ } ++ else if (value < array[i]) { ++ length = i; ++ } ++ else { ++ return i; ++ } ++ } ++ return -1; ++ }; ++ return BinarySearch; ++}()); ++exports.default = BinarySearch; ++//# sourceMappingURL=BinarySearch.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js.map +new file mode 100644 +index 0000000..8684678 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BinarySearch.js","sourceRoot":"","sources":["../../../src/utils/BinarySearch.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.d.ts +new file mode 100644 +index 0000000..113cffc +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.d.ts +@@ -0,0 +1,15 @@ ++/*** ++ * Recycle pool for maintaining recyclable items, supports segregation by type as well. ++ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation ++ */ ++export default class RecycleItemPool { ++ private _recyclableObjectMap; ++ private _availabilitySet; ++ constructor(); ++ putRecycledObject(objectType: string | number, object: string): void; ++ getRecycledObject(objectType: string | number): string | undefined; ++ removeFromPool(object: string): boolean; ++ clearAll(): void; ++ private _getRelevantSet; ++ private _stringify; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js +new file mode 100644 +index 0000000..d1173ad +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js +@@ -0,0 +1,65 @@ ++"use strict"; ++/*** ++ * Recycle pool for maintaining recyclable items, supports segregation by type as well. ++ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation ++ */ ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecycleItemPool = /** @class */ (function () { ++ function RecycleItemPool() { ++ this._recyclableObjectMap = {}; ++ this._availabilitySet = {}; ++ } ++ RecycleItemPool.prototype.putRecycledObject = function (objectType, object) { ++ objectType = this._stringify(objectType); ++ var objectSet = this._getRelevantSet(objectType); ++ if (!this._availabilitySet[object]) { ++ objectSet[object] = null; ++ this._availabilitySet[object] = objectType; ++ } ++ }; ++ RecycleItemPool.prototype.getRecycledObject = function (objectType) { ++ objectType = this._stringify(objectType); ++ var objectSet = this._getRelevantSet(objectType); ++ var recycledObject; ++ for (var property in objectSet) { ++ if (objectSet.hasOwnProperty(property)) { ++ recycledObject = property; ++ break; ++ } ++ } ++ if (recycledObject) { ++ delete objectSet[recycledObject]; ++ delete this._availabilitySet[recycledObject]; ++ } ++ return recycledObject; ++ }; ++ RecycleItemPool.prototype.removeFromPool = function (object) { ++ if (this._availabilitySet[object]) { ++ delete this._getRelevantSet(this._availabilitySet[object])[object]; ++ delete this._availabilitySet[object]; ++ return true; ++ } ++ return false; ++ }; ++ RecycleItemPool.prototype.clearAll = function () { ++ this._recyclableObjectMap = {}; ++ this._availabilitySet = {}; ++ }; ++ RecycleItemPool.prototype._getRelevantSet = function (objectType) { ++ var objectSet = this._recyclableObjectMap[objectType]; ++ if (!objectSet) { ++ objectSet = {}; ++ this._recyclableObjectMap[objectType] = objectSet; ++ } ++ return objectSet; ++ }; ++ RecycleItemPool.prototype._stringify = function (objectType) { ++ if (typeof objectType === "number") { ++ objectType = objectType.toString(); ++ } ++ return objectType; ++ }; ++ return RecycleItemPool; ++}()); ++exports.default = RecycleItemPool; ++//# sourceMappingURL=RecycleItemPool.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js.map +new file mode 100644 +index 0000000..2dde95b +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"RecycleItemPool.js","sourceRoot":"","sources":["../../../src/utils/RecycleItemPool.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH;IAII;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B,EAAE,MAAc;QAChE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAChC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;SAC9C;IACL,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B;QAChD,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC;QACnB,KAAK,IAAM,QAAQ,IAAI,SAAS,EAAE;YAC9B,IAAI,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;gBACpC,cAAc,GAAG,QAAQ,CAAC;gBAC1B,MAAM;aACT;SACJ;QAED,IAAI,cAAc,EAAE;YAChB,OAAO,SAAS,CAAC,cAAc,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;SAChD;QACD,OAAO,cAAc,CAAC;IAC1B,CAAC;IAEM,wCAAc,GAArB,UAAsB,MAAc;QAChC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;SACf;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,kCAAQ,GAAf;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEO,yCAAe,GAAvB,UAAwB,UAAkB;QACtC,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE;YACZ,SAAS,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;SACrD;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,oCAAU,GAAlB,UAAmB,UAA2B;QAC1C,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;YAChC,UAAU,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC;SACtC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;IACL,sBAAC;AAAD,CAAC,AAjED,IAiEC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.d.ts +new file mode 100644 +index 0000000..d867c7e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.d.ts +@@ -0,0 +1,3 @@ ++export default class TSCast { ++ static cast(object: any): T; ++} +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js +new file mode 100644 +index 0000000..526f93a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js +@@ -0,0 +1,12 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var TSCast = /** @class */ (function () { ++ function TSCast() { ++ } ++ TSCast.cast = function (object) { ++ return object; ++ }; ++ return TSCast; ++}()); ++exports.default = TSCast; ++//# sourceMappingURL=TSCast.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js.map +new file mode 100644 +index 0000000..3384c98 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"TSCast.js","sourceRoot":"","sources":["../../../src/utils/TSCast.ts"],"names":[],"mappings":";;AAAA;IAAA;IAIA,CAAC;IAHiB,WAAI,GAAlB,UAAsB,MAAW;QAC7B,OAAO,MAAW,CAAC;IACvB,CAAC;IACL,aAAC;AAAD,CAAC,AAJD,IAIC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/ItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.d.ts +new file mode 100644 +index 0000000..dd0e11c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.d.ts +@@ -0,0 +1,15 @@ ++export default interface ItemAnimator { ++ animateWillMount: (atX: number, atY: number, itemIndex: number) => object | undefined; ++ animateDidMount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; ++ animateWillUpdate: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => void; ++ animateShift: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => boolean; ++ animateWillUnmount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; ++} ++export declare class BaseItemAnimator implements ItemAnimator { ++ static USE_NATIVE_DRIVER: boolean; ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js +new file mode 100644 +index 0000000..0ae5165 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js +@@ -0,0 +1,25 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var BaseItemAnimator = /** @class */ (function () { ++ function BaseItemAnimator() { ++ } ++ BaseItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ BaseItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ BaseItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ //no need ++ }; ++ BaseItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ return false; ++ }; ++ BaseItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ BaseItemAnimator.USE_NATIVE_DRIVER = true; ++ return BaseItemAnimator; ++}()); ++exports.BaseItemAnimator = BaseItemAnimator; ++//# sourceMappingURL=ItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js.map +new file mode 100644 +index 0000000..732604a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ItemAnimator.js","sourceRoot":"","sources":["../../../src/core/ItemAnimator.ts"],"names":[],"mappings":";;AAwBA;IAAA;IAoBA,CAAC;IAlBU,2CAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,0CAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,4CAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,SAAS;IACb,CAAC;IAEM,uCAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC1G,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,6CAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IAlBa,kCAAiB,GAAG,IAAI,CAAC;IAmB3C,uBAAC;CAAA,AApBD,IAoBC;AApBY,4CAAgB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.d.ts b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.d.ts +new file mode 100644 +index 0000000..c30743a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.d.ts +@@ -0,0 +1,27 @@ ++import RecyclerListView, { RecyclerListViewProps, RecyclerListViewState } from "./RecyclerListView"; ++export interface ProgressiveListViewProps extends RecyclerListViewProps { ++ maxRenderAhead?: number; ++ renderAheadStep?: number; ++} ++/** ++ * This will incremently update renderAhread distance and render the page progressively. ++ */ ++export default class ProgressiveListView extends RecyclerListView { ++ static defaultProps: { ++ maxRenderAhead: number; ++ renderAheadStep: number; ++ renderAheadOffset: number; ++ canChangeSize: boolean; ++ disableRecycling: boolean; ++ initialOffset: number; ++ initialRenderIndex: number; ++ isHorizontal: boolean; ++ onEndReachedThreshold: number; ++ distanceFromWindow: number; ++ }; ++ private renderAheadUdpateCallbackId?; ++ componentDidMount(): void; ++ private updateRenderAheadProgessively; ++ private incrementRenderAhead; ++ private cancelRenderAheadUpdate; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js +new file mode 100644 +index 0000000..9176a38 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js +@@ -0,0 +1,77 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecyclerListView_1 = require("./RecyclerListView"); ++/** ++ * This will incremently update renderAhread distance and render the page progressively. ++ */ ++var ProgressiveListView = /** @class */ (function (_super) { ++ __extends(ProgressiveListView, _super); ++ function ProgressiveListView() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ ProgressiveListView.prototype.componentDidMount = function () { ++ if (_super.prototype.componentDidMount) { ++ _super.prototype.componentDidMount.call(this); ++ } ++ this.updateRenderAheadProgessively(this.getCurrentRenderAheadOffset()); ++ }; ++ ProgressiveListView.prototype.updateRenderAheadProgessively = function (newVal) { ++ var _this = this; ++ this.cancelRenderAheadUpdate(); // Cancel any pending callback. ++ this.renderAheadUdpateCallbackId = requestAnimationFrame(function () { ++ if (!_this.updateRenderAheadOffset(newVal)) { ++ _this.updateRenderAheadProgessively(newVal); ++ } ++ else { ++ _this.incrementRenderAhead(); ++ } ++ }); ++ }; ++ ProgressiveListView.prototype.incrementRenderAhead = function () { ++ if (this.props.maxRenderAhead && this.props.renderAheadStep) { ++ var layoutManager = this.getVirtualRenderer().getLayoutManager(); ++ var currentRenderAheadOffset = this.getCurrentRenderAheadOffset(); ++ if (layoutManager) { ++ var contentDimension = layoutManager.getContentDimension(); ++ var maxContentSize = this.props.isHorizontal ? contentDimension.width : contentDimension.height; ++ if (currentRenderAheadOffset < maxContentSize && currentRenderAheadOffset < this.props.maxRenderAhead) { ++ var newRenderAheadOffset = currentRenderAheadOffset + this.props.renderAheadStep; ++ this.updateRenderAheadProgessively(newRenderAheadOffset); ++ } ++ } ++ } ++ }; ++ ProgressiveListView.prototype.cancelRenderAheadUpdate = function () { ++ if (this.renderAheadUdpateCallbackId) { ++ cancelAnimationFrame(this.renderAheadUdpateCallbackId); ++ } ++ }; ++ ProgressiveListView.defaultProps = __assign({}, RecyclerListView_1.default.defaultProps, { maxRenderAhead: Number.MAX_VALUE, renderAheadStep: 300, renderAheadOffset: 0 }); ++ return ProgressiveListView; ++}(RecyclerListView_1.default)); ++exports.default = ProgressiveListView; ++//# sourceMappingURL=ProgressiveListView.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js.map b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js.map +new file mode 100644 +index 0000000..c9c3fd6 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ProgressiveListView.js","sourceRoot":"","sources":["../../../src/core/ProgressiveListView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uDAAoG;AAKpG;;GAEG;AACH;IAAiD,uCAAiE;IAAlH;;IA+CA,CAAC;IAtCU,+CAAiB,GAAxB;QACI,IAAI,iBAAM,iBAAiB,EAAE;YACzB,iBAAM,iBAAiB,WAAE,CAAC;SAC7B;QACD,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,CAAC;IAC3E,CAAC;IAEO,2DAA6B,GAArC,UAAsC,MAAc;QAApD,iBASC;QARG,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,+BAA+B;QAC/D,IAAI,CAAC,2BAA2B,GAAG,qBAAqB,CAAC;YACrD,IAAI,CAAC,KAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE;gBACvC,KAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;aAC9C;iBAAM;gBACH,KAAI,CAAC,oBAAoB,EAAE,CAAC;aAC/B;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kDAAoB,GAA5B;QACI,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;YACzD,IAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACnE,IAAM,wBAAwB,GAAG,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACpE,IAAI,aAAa,EAAE;gBACf,IAAM,gBAAgB,GAAG,aAAa,CAAC,mBAAmB,EAAE,CAAC;gBAC7D,IAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAClG,IAAI,wBAAwB,GAAG,cAAc,IAAI,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;oBACnG,IAAM,oBAAoB,GAAG,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;oBACnF,IAAI,CAAC,6BAA6B,CAAC,oBAAoB,CAAC,CAAC;iBAC5D;aACJ;SACJ;IACL,CAAC;IAEO,qDAAuB,GAA/B;QACI,IAAI,IAAI,CAAC,2BAA2B,EAAE;YAClC,oBAAoB,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;SAC1D;IACL,CAAC;IA7Ca,gCAAY,gBACnB,0BAAgB,CAAC,YAAY,IAChC,cAAc,EAAE,MAAM,CAAC,SAAS,EAChC,eAAe,EAAE,GAAG,EACpB,iBAAiB,EAAE,CAAC,IACtB;IAyCN,0BAAC;CAAA,AA/CD,CAAiD,0BAAgB,GA+ChE;kBA/CoB,mBAAmB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/RecyclerListView.d.ts b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.d.ts +new file mode 100644 +index 0000000..0bd8189 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.d.ts +@@ -0,0 +1,126 @@ ++import * as React from "react"; ++import ContextProvider from "./dependencies/ContextProvider"; ++import { BaseDataProvider } from "./dependencies/DataProvider"; ++import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; ++import { Layout } from "./layoutmanager/LayoutManager"; ++import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./scrollcomponent/BaseScrollView"; ++import { TOnItemStatusChanged } from "./ViewabilityTracker"; ++import VirtualRenderer, { RenderStack } from "./VirtualRenderer"; ++import ItemAnimator from "./ItemAnimator"; ++import { DebugHandlers } from ".."; ++/*** ++ * This is the main component, please refer to samples to understand how to use. ++ * For advanced usage check out prop descriptions below. ++ * You also get common methods such as: scrollToIndex, scrollToItem, scrollToTop, scrollToEnd, scrollToOffset, getCurrentScrollOffset, ++ * findApproxFirstVisibleIndex. ++ * You'll need a ref to Recycler in order to call these ++ * Needs to have bounded size in all cases other than window scrolling (web). ++ * ++ * NOTE: React Native implementation uses ScrollView internally which means you get all ScrollView features as well such as Pull To Refresh, paging enabled ++ * You can easily create a recycling image flip view using one paging enabled flag. Read about ScrollView features in official ++ * react native documentation. ++ * NOTE: If you see blank space look at the renderAheadOffset prop and make sure your data provider has a good enough rowHasChanged method. ++ * Blanks are totally avoidable with this listview. ++ * NOTE: Also works on web (experimental) ++ * NOTE: For reflowability set canChangeSize to true (experimental) ++ */ ++export interface OnRecreateParams { ++ lastOffset?: number; ++} ++export interface RecyclerListViewProps { ++ layoutProvider: BaseLayoutProvider; ++ dataProvider: BaseDataProvider; ++ rowRenderer: (type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++ contextProvider?: ContextProvider; ++ renderAheadOffset?: number; ++ isHorizontal?: boolean; ++ onScroll?: (rawEvent: ScrollEvent, offsetX: number, offsetY: number) => void; ++ onRecreate?: (params: OnRecreateParams) => void; ++ onEndReached?: () => void; ++ onEndReachedThreshold?: number; ++ onVisibleIndexesChanged?: TOnItemStatusChanged; ++ onVisibleIndicesChanged?: TOnItemStatusChanged; ++ renderFooter?: () => JSX.Element | JSX.Element[] | null; ++ externalScrollView?: { ++ new (props: ScrollViewDefaultProps): BaseScrollView; ++ }; ++ initialOffset?: number; ++ initialRenderIndex?: number; ++ scrollThrottle?: number; ++ canChangeSize?: boolean; ++ distanceFromWindow?: number; ++ useWindowScroll?: boolean; ++ disableRecycling?: boolean; ++ forceNonDeterministicRendering?: boolean; ++ extendedState?: object; ++ itemAnimator?: ItemAnimator; ++ optimizeForInsertDeleteAnimations?: boolean; ++ style?: object | number; ++ debugHandlers?: DebugHandlers; ++ scrollViewProps?: object; ++} ++export interface RecyclerListViewState { ++ renderStack: RenderStack; ++ internalSnapshot: Record; ++} ++export default class RecyclerListView

extends React.Component { ++ static defaultProps: { ++ canChangeSize: boolean; ++ disableRecycling: boolean; ++ initialOffset: number; ++ initialRenderIndex: number; ++ isHorizontal: boolean; ++ onEndReachedThreshold: number; ++ distanceFromWindow: number; ++ renderAheadOffset: number; ++ }; ++ static propTypes: {}; ++ private refreshRequestDebouncer; ++ private _virtualRenderer; ++ private _onEndReachedCalled; ++ private _initComplete; ++ private _relayoutReqIndex; ++ private _params; ++ private _layout; ++ private _pendingScrollToOffset; ++ private _tempDim; ++ private _initialOffset; ++ private _cachedLayouts?; ++ private _scrollComponent; ++ private _defaultItemAnimator; ++ constructor(props: P, context?: any); ++ componentWillReceiveProps(newProps: RecyclerListViewProps): void; ++ componentDidUpdate(): void; ++ componentWillUnmount(): void; ++ componentWillMount(): void; ++ scrollToIndex(index: number, animate?: boolean): void; ++ scrollToItem(data: any, animate?: boolean): void; ++ getLayout(index: number): Layout | undefined; ++ scrollToTop(animate?: boolean): void; ++ scrollToEnd(animate?: boolean): void; ++ scrollToOffset: (x: number, y: number, animate?: boolean) => void; ++ updateRenderAheadOffset(renderAheadOffset: number): boolean; ++ getCurrentRenderAheadOffset(): number; ++ getCurrentScrollOffset(): number; ++ findApproxFirstVisibleIndex(): number; ++ getRenderedSize(): Dimension; ++ getContentDimension(): Dimension; ++ forceRerender(): void; ++ render(): JSX.Element; ++ protected getVirtualRenderer(): VirtualRenderer; ++ private _checkAndChangeLayouts; ++ private _refreshViewability; ++ private _queueStateRefresh; ++ private _onSizeChanged; ++ private _renderStackWhenReady; ++ private _initTrackers; ++ private _assertDependencyPresence; ++ private _assertType; ++ private _dataHasChanged; ++ private _renderRowUsingMeta; ++ private _onViewContainerSizeChange; ++ private _checkExpectedDimensionDiscrepancy; ++ private _generateRenderStack; ++ private _onScroll; ++ private _processOnEndReached; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js +new file mode 100644 +index 0000000..e27cdf6 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js +@@ -0,0 +1,586 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++/*** ++ * DONE: Reduce layout processing on data insert ++ * DONE: Add notify data set changed and notify data insert option in data source ++ * DONE: Add on end reached callback ++ * DONE: Make another class for render stack generator ++ * DONE: Simplify rendering a loading footer ++ * DONE: Anchor first visible index on any insert/delete data wise ++ * DONE: Build Scroll to index ++ * DONE: Give viewability callbacks ++ * DONE: Add full render logic in cases like change of dimensions ++ * DONE: Fix all proptypes ++ * DONE: Add Initial render Index support ++ * DONE: Add animated scroll to web scrollviewer ++ * DONE: Animate list view transition, including add/remove ++ * DONE: Implement sticky headers and footers ++ * TODO: Destroy less frequently used items in recycle pool, this will help in case of too many types. ++ * TODO: Make viewability callbacks configurable ++ * TODO: Observe size changes on web to optimize for reflowability ++ * TODO: Solve //TSI ++ */ ++var debounce = require("lodash.debounce"); ++var PropTypes = require("prop-types"); ++var React = require("react"); ++var ts_object_utils_1 = require("ts-object-utils"); ++var ContextProvider_1 = require("./dependencies/ContextProvider"); ++var DataProvider_1 = require("./dependencies/DataProvider"); ++var LayoutProvider_1 = require("./dependencies/LayoutProvider"); ++var CustomError_1 = require("./exceptions/CustomError"); ++var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); ++var Constants_1 = require("./constants/Constants"); ++var Messages_1 = require("./constants/Messages"); ++var VirtualRenderer_1 = require("./VirtualRenderer"); ++var ItemAnimator_1 = require("./ItemAnimator"); ++//#if [REACT-NATIVE] ++//import ScrollComponent from "../platform/reactnative/scrollcomponent/ScrollComponent"; ++//import ViewRenderer from "../platform/reactnative/viewrenderer/ViewRenderer"; ++//import { DefaultJSItemAnimator as DefaultItemAnimator } from "../platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator"; ++//import { Platform } from "react-native"; ++//const IS_WEB = !Platform || Platform.OS === "web"; ++//#endif ++/*** ++ * To use on web, start importing from recyclerlistview/web. To make it even easier specify an alias in you builder of choice. ++ */ ++//#if [WEB] ++var ScrollComponent_1 = require("../platform/web/scrollcomponent/ScrollComponent"); ++var ViewRenderer_1 = require("../platform/web/viewrenderer/ViewRenderer"); ++var DefaultWebItemAnimator_1 = require("../platform/web/itemanimators/DefaultWebItemAnimator"); ++var IS_WEB = true; ++var RecyclerListView = /** @class */ (function (_super) { ++ __extends(RecyclerListView, _super); ++ function RecyclerListView(props, context) { ++ var _this = _super.call(this, props, context) || this; ++ _this.refreshRequestDebouncer = debounce(function (executable) { ++ executable(); ++ }); ++ _this._onEndReachedCalled = false; ++ _this._initComplete = false; ++ _this._relayoutReqIndex = -1; ++ _this._params = { ++ initialOffset: 0, ++ initialRenderIndex: 0, ++ isHorizontal: false, ++ itemCount: 0, ++ renderAheadOffset: 250, ++ }; ++ _this._layout = { height: 0, width: 0 }; ++ _this._pendingScrollToOffset = null; ++ _this._tempDim = { height: 0, width: 0 }; ++ _this._initialOffset = 0; ++ _this._scrollComponent = null; ++ _this._defaultItemAnimator = new DefaultWebItemAnimator_1.DefaultWebItemAnimator(); ++ _this.scrollToOffset = function (x, y, animate) { ++ if (animate === void 0) { animate = false; } ++ if (_this._scrollComponent) { ++ if (_this.props.isHorizontal) { ++ y = 0; ++ } ++ else { ++ x = 0; ++ } ++ _this._scrollComponent.scrollTo(x, y, animate); ++ } ++ }; ++ _this._onSizeChanged = function (layout) { ++ var hasHeightChanged = _this._layout.height !== layout.height; ++ var hasWidthChanged = _this._layout.width !== layout.width; ++ _this._layout.height = layout.height; ++ _this._layout.width = layout.width; ++ if (layout.height === 0 || layout.width === 0) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.layoutException); ++ } ++ if (!_this._initComplete) { ++ _this._initComplete = true; ++ _this._initTrackers(); ++ _this._processOnEndReached(); ++ } ++ else { ++ if ((hasHeightChanged && hasWidthChanged) || ++ (hasHeightChanged && _this.props.isHorizontal) || ++ (hasWidthChanged && !_this.props.isHorizontal)) { ++ _this._checkAndChangeLayouts(_this.props, true); ++ } ++ else { ++ _this._refreshViewability(); ++ } ++ } ++ }; ++ _this._renderStackWhenReady = function (stack) { ++ _this.setState(function () { ++ return { renderStack: stack }; ++ }); ++ }; ++ _this._dataHasChanged = function (row1, row2) { ++ return _this.props.dataProvider.rowHasChanged(row1, row2); ++ }; ++ _this._onViewContainerSizeChange = function (dim, index) { ++ //Cannot be null here ++ var layoutManager = _this._virtualRenderer.getLayoutManager(); ++ if (_this.props.debugHandlers && _this.props.debugHandlers.resizeDebugHandler) { ++ var itemRect = layoutManager.getLayouts()[index]; ++ _this.props.debugHandlers.resizeDebugHandler.resizeDebug({ ++ width: itemRect.width, ++ height: itemRect.height, ++ }, dim, index); ++ } ++ if (layoutManager.overrideLayout(index, dim)) { ++ if (_this._relayoutReqIndex === -1) { ++ _this._relayoutReqIndex = index; ++ } ++ else { ++ _this._relayoutReqIndex = Math.min(_this._relayoutReqIndex, index); ++ } ++ _this._queueStateRefresh(); ++ } ++ }; ++ _this._onScroll = function (offsetX, offsetY, rawEvent) { ++ //Adjusting offsets using distanceFromWindow ++ _this._virtualRenderer.updateOffset(offsetX, offsetY, -_this.props.distanceFromWindow, true); ++ if (_this.props.onScroll) { ++ _this.props.onScroll(rawEvent, offsetX, offsetY); ++ } ++ _this._processOnEndReached(); ++ }; ++ _this._virtualRenderer = new VirtualRenderer_1.default(_this._renderStackWhenReady, function (offset) { ++ _this._pendingScrollToOffset = offset; ++ }, function (index) { ++ return _this.props.dataProvider.getStableId(index); ++ }, !props.disableRecycling); ++ _this.state = { ++ internalSnapshot: {}, ++ renderStack: {}, ++ }; ++ return _this; ++ } ++ RecyclerListView.prototype.componentWillReceiveProps = function (newProps) { ++ this._assertDependencyPresence(newProps); ++ this._checkAndChangeLayouts(newProps); ++ if (!this.props.onVisibleIndicesChanged) { ++ this._virtualRenderer.removeVisibleItemsListener(); ++ } ++ if (this.props.onVisibleIndexesChanged) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); ++ } ++ if (this.props.onVisibleIndicesChanged) { ++ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); ++ } ++ }; ++ RecyclerListView.prototype.componentDidUpdate = function () { ++ var _this = this; ++ if (this._pendingScrollToOffset) { ++ var offset_1 = this._pendingScrollToOffset; ++ this._pendingScrollToOffset = null; ++ if (this.props.isHorizontal) { ++ offset_1.y = 0; ++ } ++ else { ++ offset_1.x = 0; ++ } ++ setTimeout(function () { ++ _this.scrollToOffset(offset_1.x, offset_1.y, false); ++ }, 0); ++ } ++ this._processOnEndReached(); ++ this._checkAndChangeLayouts(this.props); ++ if (this.props.dataProvider.getSize() === 0) { ++ console.warn(Messages_1.Messages.WARN_NO_DATA); //tslint:disable-line ++ } ++ }; ++ RecyclerListView.prototype.componentWillUnmount = function () { ++ if (this.props.contextProvider) { ++ var uniqueKey = this.props.contextProvider.getUniqueKey(); ++ if (uniqueKey) { ++ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX, this.getCurrentScrollOffset()); ++ if (this.props.forceNonDeterministicRendering) { ++ if (this._virtualRenderer) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ var layoutsToCache = layoutManager.getLayouts(); ++ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX, JSON.stringify({ layoutArray: layoutsToCache })); ++ } ++ } ++ } ++ } ++ } ++ }; ++ RecyclerListView.prototype.componentWillMount = function () { ++ if (this.props.contextProvider) { ++ var uniqueKey = this.props.contextProvider.getUniqueKey(); ++ if (uniqueKey) { ++ var offset = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); ++ if (typeof offset === "number" && offset > 0) { ++ this._initialOffset = offset; ++ if (this.props.onRecreate) { ++ this.props.onRecreate({ lastOffset: this._initialOffset }); ++ } ++ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); ++ } ++ if (this.props.forceNonDeterministicRendering) { ++ var cachedLayouts = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); ++ if (cachedLayouts && typeof cachedLayouts === "string") { ++ this._cachedLayouts = JSON.parse(cachedLayouts).layoutArray; ++ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); ++ } ++ } ++ } ++ } ++ }; ++ RecyclerListView.prototype.scrollToIndex = function (index, animate) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ var offsets = layoutManager.getOffsetForIndex(index); ++ this.scrollToOffset(offsets.x, offsets.y, animate); ++ } ++ else { ++ console.warn(Messages_1.Messages.WARN_SCROLL_TO_INDEX); //tslint:disable-line ++ } ++ }; ++ RecyclerListView.prototype.scrollToItem = function (data, animate) { ++ var count = this.props.dataProvider.getSize(); ++ for (var i = 0; i < count; i++) { ++ if (this.props.dataProvider.getDataForIndex(i) === data) { ++ this.scrollToIndex(i, animate); ++ break; ++ } ++ } ++ }; ++ RecyclerListView.prototype.getLayout = function (index) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ return layoutManager ? layoutManager.getLayouts()[index] : undefined; ++ }; ++ RecyclerListView.prototype.scrollToTop = function (animate) { ++ this.scrollToOffset(0, 0, animate); ++ }; ++ RecyclerListView.prototype.scrollToEnd = function (animate) { ++ var lastIndex = this.props.dataProvider.getSize() - 1; ++ this.scrollToIndex(lastIndex, animate); ++ }; ++ // You can use requestAnimationFrame callback to change renderAhead in multiple frames to enable advanced progressive ++ // rendering when view types are very complex. This method returns a boolean saying if the update was committed. Retry in ++ // the next frame if you get a failure (if mount wasn't complete). Value should be greater than or equal to 0; ++ // Very useful when you have a page where you need a large renderAheadOffset. Setting it at once will slow down the load and ++ // this will help mitigate that. ++ RecyclerListView.prototype.updateRenderAheadOffset = function (renderAheadOffset) { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ if (viewabilityTracker) { ++ viewabilityTracker.updateRenderAheadOffset(renderAheadOffset); ++ return true; ++ } ++ return false; ++ }; ++ RecyclerListView.prototype.getCurrentRenderAheadOffset = function () { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ if (viewabilityTracker) { ++ return viewabilityTracker.getCurrentRenderAheadOffset(); ++ } ++ return this.props.renderAheadOffset; ++ }; ++ RecyclerListView.prototype.getCurrentScrollOffset = function () { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ return viewabilityTracker ? viewabilityTracker.getLastActualOffset() : 0; ++ }; ++ RecyclerListView.prototype.findApproxFirstVisibleIndex = function () { ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ return viewabilityTracker ? viewabilityTracker.findFirstLogicallyVisibleIndex() : 0; ++ }; ++ RecyclerListView.prototype.getRenderedSize = function () { ++ return this._layout; ++ }; ++ RecyclerListView.prototype.getContentDimension = function () { ++ return this._virtualRenderer.getLayoutDimension(); ++ }; ++ // Force Rerender forcefully to update view renderer. Use this in rare circumstances ++ RecyclerListView.prototype.forceRerender = function () { ++ this.setState({ ++ internalSnapshot: {}, ++ }); ++ }; ++ RecyclerListView.prototype.render = function () { ++ //TODO:Talha ++ // const { ++ // layoutProvider, ++ // dataProvider, ++ // contextProvider, ++ // renderAheadOffset, ++ // onEndReached, ++ // onEndReachedThreshold, ++ // onVisibleIndicesChanged, ++ // initialOffset, ++ // initialRenderIndex, ++ // disableRecycling, ++ // forceNonDeterministicRendering, ++ // extendedState, ++ // itemAnimator, ++ // rowRenderer, ++ // ...props, ++ // } = this.props; ++ var _this = this; ++ return (React.createElement(ScrollComponent_1.default, __assign({ ref: function (scrollComponent) { return _this._scrollComponent = scrollComponent; } }, this.props, this.props.scrollViewProps, { onScroll: this._onScroll, onSizeChanged: this._onSizeChanged, contentHeight: this._initComplete ? this._virtualRenderer.getLayoutDimension().height : 0, contentWidth: this._initComplete ? this._virtualRenderer.getLayoutDimension().width : 0 }), this._generateRenderStack())); ++ }; ++ RecyclerListView.prototype.getVirtualRenderer = function () { ++ return this._virtualRenderer; ++ }; ++ RecyclerListView.prototype._checkAndChangeLayouts = function (newProps, forceFullRender) { ++ this._params.isHorizontal = newProps.isHorizontal; ++ this._params.itemCount = newProps.dataProvider.getSize(); ++ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); ++ this._virtualRenderer.setLayoutProvider(newProps.layoutProvider); ++ if (newProps.dataProvider.hasStableIds() && this.props.dataProvider !== newProps.dataProvider && newProps.dataProvider.requiresDataChangeHandling()) { ++ this._virtualRenderer.handleDataSetChange(newProps.dataProvider, this.props.optimizeForInsertDeleteAnimations); ++ } ++ if (forceFullRender || this.props.layoutProvider !== newProps.layoutProvider || this.props.isHorizontal !== newProps.isHorizontal) { ++ //TODO:Talha use old layout manager ++ this._virtualRenderer.setLayoutManager(newProps.layoutProvider.newLayoutManager(this._layout, newProps.isHorizontal)); ++ if (newProps.layoutProvider.shouldRefreshWithAnchoring) { ++ this._virtualRenderer.refreshWithAnchor(); ++ } ++ else { ++ this._virtualRenderer.refresh(); ++ } ++ this._refreshViewability(); ++ } ++ else if (this.props.dataProvider !== newProps.dataProvider) { ++ this._onEndReachedCalled = false; ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ layoutManager.relayoutFromIndex(newProps.dataProvider.getFirstIndexToProcessInternal(), newProps.dataProvider.getSize()); ++ this._virtualRenderer.refresh(); ++ } ++ } ++ else if (this._relayoutReqIndex >= 0) { ++ var layoutManager = this._virtualRenderer.getLayoutManager(); ++ if (layoutManager) { ++ var dataProviderSize = newProps.dataProvider.getSize(); ++ layoutManager.relayoutFromIndex(Math.min(Math.max(dataProviderSize - 1, 0), this._relayoutReqIndex), dataProviderSize); ++ this._relayoutReqIndex = -1; ++ this._refreshViewability(); ++ } ++ } ++ }; ++ RecyclerListView.prototype._refreshViewability = function () { ++ this._virtualRenderer.refresh(); ++ this._queueStateRefresh(); ++ }; ++ RecyclerListView.prototype._queueStateRefresh = function () { ++ var _this = this; ++ this.refreshRequestDebouncer(function () { ++ _this.setState(function (prevState) { ++ return prevState; ++ }); ++ }); ++ }; ++ RecyclerListView.prototype._initTrackers = function () { ++ this._assertDependencyPresence(this.props); ++ if (this.props.onVisibleIndexesChanged) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); ++ } ++ if (this.props.onVisibleIndicesChanged) { ++ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); ++ } ++ this._params = { ++ initialOffset: this._initialOffset ? this._initialOffset : this.props.initialOffset, ++ initialRenderIndex: this.props.initialRenderIndex, ++ isHorizontal: this.props.isHorizontal, ++ itemCount: this.props.dataProvider.getSize(), ++ renderAheadOffset: this.props.renderAheadOffset, ++ }; ++ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); ++ var layoutManager = this.props.layoutProvider.newLayoutManager(this._layout, this.props.isHorizontal, this._cachedLayouts); ++ this._virtualRenderer.setLayoutManager(layoutManager); ++ this._virtualRenderer.setLayoutProvider(this.props.layoutProvider); ++ this._virtualRenderer.init(); ++ var offset = this._virtualRenderer.getInitialOffset(); ++ var contentDimension = layoutManager.getContentDimension(); ++ if ((offset.y > 0 && contentDimension.height > this._layout.height) || ++ (offset.x > 0 && contentDimension.width > this._layout.width)) { ++ this._pendingScrollToOffset = offset; ++ this.setState({}); ++ } ++ else { ++ this._virtualRenderer.startViewabilityTracker(); ++ } ++ }; ++ RecyclerListView.prototype._assertDependencyPresence = function (props) { ++ if (!props.dataProvider || !props.layoutProvider) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.unresolvedDependenciesException); ++ } ++ }; ++ RecyclerListView.prototype._assertType = function (type) { ++ if (!type && type !== 0) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.itemTypeNullException); ++ } ++ }; ++ RecyclerListView.prototype._renderRowUsingMeta = function (itemMeta) { ++ var dataSize = this.props.dataProvider.getSize(); ++ var dataIndex = itemMeta.dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(dataIndex) && dataIndex < dataSize) { ++ var itemRect = this._virtualRenderer.getLayoutManager().getLayouts()[dataIndex]; ++ var data = this.props.dataProvider.getDataForIndex(dataIndex); ++ var type = this.props.layoutProvider.getLayoutTypeForIndex(dataIndex); ++ var key = this._virtualRenderer.syncAndGetKey(dataIndex); ++ var styleOverrides = this._virtualRenderer.getLayoutManager().getStyleOverridesForIndex(dataIndex); ++ this._assertType(type); ++ if (!this.props.forceNonDeterministicRendering) { ++ this._checkExpectedDimensionDiscrepancy(itemRect, type, dataIndex); ++ } ++ return (React.createElement(ViewRenderer_1.default, { key: key, data: data, dataHasChanged: this._dataHasChanged, x: itemRect.x, y: itemRect.y, layoutType: type, index: dataIndex, styleOverrides: styleOverrides, layoutProvider: this.props.layoutProvider, forceNonDeterministicRendering: this.props.forceNonDeterministicRendering, isHorizontal: this.props.isHorizontal, onSizeChanged: this._onViewContainerSizeChange, childRenderer: this.props.rowRenderer, height: itemRect.height, width: itemRect.width, itemAnimator: ts_object_utils_1.Default.value(this.props.itemAnimator, this._defaultItemAnimator), extendedState: this.props.extendedState, internalSnapshot: this.state.internalSnapshot })); ++ } ++ return null; ++ }; ++ RecyclerListView.prototype._checkExpectedDimensionDiscrepancy = function (itemRect, type, index) { ++ if (this.props.layoutProvider.checkDimensionDiscrepancy(itemRect, type, index)) { ++ if (this._relayoutReqIndex === -1) { ++ this._relayoutReqIndex = index; ++ } ++ else { ++ this._relayoutReqIndex = Math.min(this._relayoutReqIndex, index); ++ } ++ } ++ }; ++ RecyclerListView.prototype._generateRenderStack = function () { ++ var renderedItems = []; ++ for (var key in this.state.renderStack) { ++ if (this.state.renderStack.hasOwnProperty(key)) { ++ renderedItems.push(this._renderRowUsingMeta(this.state.renderStack[key])); ++ } ++ } ++ return renderedItems; ++ }; ++ RecyclerListView.prototype._processOnEndReached = function () { ++ if (this.props.onEndReached && this._virtualRenderer) { ++ var layout = this._virtualRenderer.getLayoutDimension(); ++ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); ++ if (viewabilityTracker) { ++ var windowBound = this.props.isHorizontal ? layout.width - this._layout.width : layout.height - this._layout.height; ++ var lastOffset = viewabilityTracker ? viewabilityTracker.getLastOffset() : 0; ++ if (windowBound - lastOffset <= ts_object_utils_1.Default.value(this.props.onEndReachedThreshold, 0)) { ++ if (this.props.onEndReached && !this._onEndReachedCalled) { ++ this._onEndReachedCalled = true; ++ this.props.onEndReached(); ++ } ++ } ++ else { ++ this._onEndReachedCalled = false; ++ } ++ } ++ } ++ }; ++ RecyclerListView.defaultProps = { ++ canChangeSize: false, ++ disableRecycling: false, ++ initialOffset: 0, ++ initialRenderIndex: 0, ++ isHorizontal: false, ++ onEndReachedThreshold: 0, ++ distanceFromWindow: 0, ++ renderAheadOffset: IS_WEB ? 1000 : 250, ++ }; ++ RecyclerListView.propTypes = {}; ++ return RecyclerListView; ++}(React.Component)); ++exports.default = RecyclerListView; ++RecyclerListView.propTypes = { ++ //Refer the sample ++ layoutProvider: PropTypes.instanceOf(LayoutProvider_1.BaseLayoutProvider).isRequired, ++ //Refer the sample ++ dataProvider: PropTypes.instanceOf(DataProvider_1.BaseDataProvider).isRequired, ++ //Used to maintain scroll position in case view gets destroyed e.g, cases of back navigation ++ contextProvider: PropTypes.instanceOf(ContextProvider_1.default), ++ //Methods which returns react component to be rendered. You get type of view and data in the callback. ++ rowRenderer: PropTypes.func.isRequired, ++ //Initial offset you want to start rendering from, very useful if you want to maintain scroll context across pages. ++ initialOffset: PropTypes.number, ++ //Specify how many pixels in advance do you want views to be rendered. Increasing this value can help reduce blanks (if any). However keeping this as low ++ //as possible should be the intent. Higher values also increase re-render compute ++ renderAheadOffset: PropTypes.number, ++ //Whether the listview is horizontally scrollable. Both use staggeredGrid implementation ++ isHorizontal: PropTypes.bool, ++ //On scroll callback onScroll(rawEvent, offsetX, offsetY), note you get offsets no need to read scrollTop/scrollLeft ++ onScroll: PropTypes.func, ++ //callback onRecreate(params), when recreating recycler view from context provider. Gives you the initial params in the first ++ //frame itself to allow you to render content accordingly ++ onRecreate: PropTypes.func, ++ //Provide your own ScrollView Component. The contract for the scroll event should match the native scroll event contract, i.e. ++ // scrollEvent = { nativeEvent: { contentOffset: { x: offset, y: offset } } } ++ //Note: Please extend BaseScrollView to achieve expected behaviour ++ externalScrollView: PropTypes.func, ++ //Callback given when user scrolls to the end of the list or footer just becomes visible, useful in incremental loading scenarios ++ onEndReached: PropTypes.func, ++ //Specify how many pixels in advance you onEndReached callback ++ onEndReachedThreshold: PropTypes.number, ++ //Deprecated. Please use onVisibleIndicesChanged instead. ++ onVisibleIndexesChanged: PropTypes.func, ++ //Provides visible index, helpful in sending impression events etc, onVisibleIndicesChanged(all, now, notNow) ++ onVisibleIndicesChanged: PropTypes.func, ++ //Provide this method if you want to render a footer. Helpful in showing a loader while doing incremental loads. ++ renderFooter: PropTypes.func, ++ //Specify the initial item index you want rendering to start from. Preferred over initialOffset if both are specified. ++ initialRenderIndex: PropTypes.number, ++ //iOS only. Scroll throttle duration. ++ scrollThrottle: PropTypes.number, ++ //Specify if size can change, listview will automatically relayout items. For web, works only with useWindowScroll = true ++ canChangeSize: PropTypes.bool, ++ //Specify how far away the first list item is from start of the RecyclerListView. e.g, if you have content padding on top or left. ++ //This is an adjustment for optimization and to make sure onVisibileIndexesChanged callback is correct. ++ //Ideally try to avoid setting large padding values on RLV content. If you have to please correct offsets reported, handle ++ //them in a custom ScrollView and pass it as an externalScrollView. If you want this to be accounted in scrollToOffset please ++ //override the method and handle manually. ++ distanceFromWindow: PropTypes.number, ++ //Web only. Layout elements in window instead of a scrollable div. ++ useWindowScroll: PropTypes.bool, ++ //Turns off recycling. You still get progressive rendering and all other features. Good for lazy rendering. This should not be used in most cases. ++ disableRecycling: PropTypes.bool, ++ //Default is false, if enabled dimensions provided in layout provider will not be strictly enforced. ++ //Rendered dimensions will be used to relayout items. Slower if enabled. ++ forceNonDeterministicRendering: PropTypes.bool, ++ //In some cases the data passed at row level may not contain all the info that the item depends upon, you can keep all other info ++ //outside and pass it down via this prop. Changing this object will cause everything to re-render. Make sure you don't change ++ //it often to ensure performance. Re-renders are heavy. ++ extendedState: PropTypes.object, ++ //Enables animating RecyclerListView item cells e.g, shift, add, remove etc. This prop can be used to pass an external item animation implementation. ++ //Look into BaseItemAnimator/DefaultJSItemAnimator/DefaultNativeItemAnimator/DefaultWebItemAnimator for more info. ++ //By default there are few animations, to disable completely simply pass blank new BaseItemAnimator() object. Remember, create ++ //one object and keep it do not create multiple object of type BaseItemAnimator. ++ //Note: You might want to look into DefaultNativeItemAnimator to check an implementation based on LayoutAnimation. By default, ++ //animations are JS driven to avoid workflow interference. Also, please note LayoutAnimation is buggy on Android. ++ itemAnimator: PropTypes.instanceOf(ItemAnimator_1.BaseItemAnimator), ++ //Enables you to utilize layout animations better by unmounting removed items. Please note, this might increase unmounts ++ //on large data changes. ++ optimizeForInsertDeleteAnimations: PropTypes.bool, ++ //To pass down style to inner ScrollView ++ style: PropTypes.oneOfType([ ++ PropTypes.object, ++ PropTypes.number, ++ ]), ++ //For TS use case, not necessary with JS use. ++ //For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread ++ //and passed down. ++ scrollViewProps: PropTypes.object, ++}; ++//# sourceMappingURL=RecyclerListView.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js.map b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js.map +new file mode 100644 +index 0000000..c13a909 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"RecyclerListView.js","sourceRoot":"","sources":["../../../src/core/RecyclerListView.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/StickyContainer.d.ts b/node_modules/recyclerlistview/dist/web/core/StickyContainer.d.ts +new file mode 100644 +index 0000000..e712796 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/StickyContainer.d.ts +@@ -0,0 +1,49 @@ ++/** ++ * Created by ananya.chandra on 14/09/18. ++ */ ++import * as React from "react"; ++import { StyleProp, ViewStyle } from "react-native"; ++import { RecyclerListViewProps } from "./RecyclerListView"; ++export interface StickyContainerProps { ++ children: RecyclerChild; ++ stickyHeaderIndices?: number[]; ++ stickyFooterIndices?: number[]; ++ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++ style?: StyleProp; ++} ++export interface RecyclerChild extends React.ReactElement { ++ ref: (recyclerRef: any) => {}; ++ props: RecyclerListViewProps; ++} ++export default class StickyContainer

extends React.Component

{ ++ static propTypes: {}; ++ private _recyclerRef; ++ private _dataProvider; ++ private _layoutProvider; ++ private _extendedState; ++ private _rowRenderer; ++ private _distanceFromWindow; ++ private _stickyHeaderRef; ++ private _stickyFooterRef; ++ private _visibleIndicesAll; ++ constructor(props: P, context?: any); ++ componentWillReceiveProps(newProps: P): void; ++ render(): JSX.Element; ++ private _getRecyclerRef; ++ private _getStickyHeaderRef; ++ private _getStickyFooterRef; ++ private _onVisibleIndicesChanged; ++ private _callStickyObjectsOnVisibleIndicesChanged; ++ private _onScroll; ++ private _assertChildType; ++ private _isChildRecyclerInstance; ++ private _getLayoutForIndex; ++ private _getDataForIndex; ++ private _getLayoutTypeForIndex; ++ private _getExtendedState; ++ private _getRowRenderer; ++ private _getRLVRenderedSize; ++ private _getContentDimension; ++ private _getDistanceFromWindow; ++ private _initParams; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/StickyContainer.js b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js +new file mode 100644 +index 0000000..8de1ec4 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js +@@ -0,0 +1,187 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 14/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var PropTypes = require("prop-types"); ++var react_native_1 = require("react-native"); ++var StickyHeader_1 = require("./sticky/StickyHeader"); ++var StickyFooter_1 = require("./sticky/StickyFooter"); ++var CustomError_1 = require("./exceptions/CustomError"); ++var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); ++var StickyContainer = /** @class */ (function (_super) { ++ __extends(StickyContainer, _super); ++ function StickyContainer(props, context) { ++ var _this = _super.call(this, props, context) || this; ++ _this._recyclerRef = undefined; ++ _this._stickyHeaderRef = null; ++ _this._stickyFooterRef = null; ++ _this._visibleIndicesAll = []; ++ _this._getRecyclerRef = function (recycler) { ++ _this._recyclerRef = recycler; ++ if (_this.props.children.ref) { ++ if (typeof _this.props.children.ref === "function") { ++ (_this.props.children).ref(recycler); ++ } ++ else { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.refNotAsFunctionException); ++ } ++ } ++ }; ++ _this._getStickyHeaderRef = function (stickyHeaderRef) { ++ if (_this._stickyHeaderRef !== stickyHeaderRef) { ++ _this._stickyHeaderRef = stickyHeaderRef; ++ // TODO: Resetting state once ref is initialized. Can look for better solution. ++ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); ++ } ++ }; ++ _this._getStickyFooterRef = function (stickyFooterRef) { ++ if (_this._stickyFooterRef !== stickyFooterRef) { ++ _this._stickyFooterRef = stickyFooterRef; ++ // TODO: Resetting state once ref is initialized. Can look for better solution. ++ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); ++ } ++ }; ++ _this._onVisibleIndicesChanged = function (all, now, notNow) { ++ _this._visibleIndicesAll = all; ++ _this._callStickyObjectsOnVisibleIndicesChanged(all); ++ if (_this.props.children && _this.props.children.props && _this.props.children.props.onVisibleIndicesChanged) { ++ _this.props.children.props.onVisibleIndicesChanged(all, now, notNow); ++ } ++ }; ++ _this._callStickyObjectsOnVisibleIndicesChanged = function (all) { ++ if (_this._stickyHeaderRef) { ++ _this._stickyHeaderRef.onVisibleIndicesChanged(all); ++ } ++ if (_this._stickyFooterRef) { ++ _this._stickyFooterRef.onVisibleIndicesChanged(all); ++ } ++ }; ++ _this._onScroll = function (rawEvent, offsetX, offsetY) { ++ if (_this._stickyHeaderRef) { ++ _this._stickyHeaderRef.onScroll(offsetY); ++ } ++ if (_this._stickyFooterRef) { ++ _this._stickyFooterRef.onScroll(offsetY); ++ } ++ if (_this.props.children && _this.props.children.props.onScroll) { ++ _this.props.children.props.onScroll(rawEvent, offsetX, offsetY); ++ } ++ }; ++ _this._assertChildType = function () { ++ if (React.Children.count(_this.props.children) !== 1 || !_this._isChildRecyclerInstance()) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.wrongStickyChildTypeException); ++ } ++ }; ++ _this._isChildRecyclerInstance = function () { ++ return (_this.props.children.props.dataProvider ++ && _this.props.children.props.rowRenderer ++ && _this.props.children.props.layoutProvider); ++ }; ++ _this._getLayoutForIndex = function (index) { ++ if (_this._recyclerRef) { ++ return _this._recyclerRef.getLayout(index); ++ } ++ return undefined; ++ }; ++ _this._getDataForIndex = function (index) { ++ return _this._dataProvider.getDataForIndex(index); ++ }; ++ _this._getLayoutTypeForIndex = function (index) { ++ return _this._layoutProvider.getLayoutTypeForIndex(index); ++ }; ++ _this._getExtendedState = function () { ++ return _this._extendedState; ++ }; ++ _this._getRowRenderer = function () { ++ return _this._rowRenderer; ++ }; ++ _this._getRLVRenderedSize = function () { ++ if (_this._recyclerRef) { ++ return _this._recyclerRef.getRenderedSize(); ++ } ++ return undefined; ++ }; ++ _this._getContentDimension = function () { ++ if (_this._recyclerRef) { ++ return _this._recyclerRef.getContentDimension(); ++ } ++ return undefined; ++ }; ++ _this._getDistanceFromWindow = function () { ++ return _this._distanceFromWindow; ++ }; ++ _this._initParams = function (props) { ++ var childProps = props.children.props; ++ _this._dataProvider = childProps.dataProvider; ++ _this._layoutProvider = childProps.layoutProvider; ++ _this._extendedState = childProps.extendedState; ++ _this._rowRenderer = childProps.rowRenderer; ++ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; ++ }; ++ _this._assertChildType(); ++ var childProps = props.children.props; ++ _this._dataProvider = childProps.dataProvider; ++ _this._layoutProvider = childProps.layoutProvider; ++ _this._extendedState = childProps.extendedState; ++ _this._rowRenderer = childProps.rowRenderer; ++ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; ++ return _this; ++ } ++ StickyContainer.prototype.componentWillReceiveProps = function (newProps) { ++ this._initParams(newProps); ++ }; ++ StickyContainer.prototype.render = function () { ++ var _this = this; ++ this._assertChildType(); ++ var recycler = React.cloneElement(this.props.children, __assign({}, this.props.children.props, { ref: this._getRecyclerRef, onVisibleIndicesChanged: this._onVisibleIndicesChanged, onScroll: this._onScroll })); ++ return (React.createElement(react_native_1.View, { style: this.props.style ? this.props.style : { flex: 1 } }, ++ recycler, ++ this.props.stickyHeaderIndices ? (React.createElement(StickyHeader_1.default, { ref: function (stickyHeaderRef) { return _this._getStickyHeaderRef(stickyHeaderRef); }, stickyIndices: this.props.stickyHeaderIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null, ++ this.props.stickyFooterIndices ? (React.createElement(StickyFooter_1.default, { ref: function (stickyFooterRef) { return _this._getStickyFooterRef(stickyFooterRef); }, stickyIndices: this.props.stickyFooterIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null)); ++ }; ++ StickyContainer.propTypes = {}; ++ return StickyContainer; ++}(React.Component)); ++exports.default = StickyContainer; ++StickyContainer.propTypes = { ++ // Mandatory to pass a single child of RecyclerListView or any of its children classes. Exception will be thrown otherwise. ++ children: PropTypes.element.isRequired, ++ // Provide an array of indices whose corresponding items need to be stuck to the top of the recyclerView once the items scroll off the top. ++ // Every subsequent sticky index view will push the previous sticky view off the top to take its place. ++ // Note - Needs to be sorted ascending ++ stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), ++ // Works same as sticky headers, but for views to be stuck at the bottom of the recyclerView. ++ // Note - Needs to be sorted ascending ++ stickyFooterIndices: PropTypes.arrayOf(PropTypes.number), ++ // Will be called instead of rowRenderer for all sticky items. Any changes to the item for when they are stuck can be done here. ++ overrideRowRenderer: PropTypes.func, ++ // For all practical purposes, pass the style that is applied to the RecyclerListView component here. ++ style: PropTypes.object, ++}; ++//# sourceMappingURL=StickyContainer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/StickyContainer.js.map b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js.map +new file mode 100644 +index 0000000..4dc4cf2 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyContainer.js","sourceRoot":"","sources":["../../../src/core/StickyContainer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.d.ts b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.d.ts +new file mode 100644 +index 0000000..820022a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.d.ts +@@ -0,0 +1,61 @@ ++import { Dimension } from "./dependencies/LayoutProvider"; ++import { Layout } from "./layoutmanager/LayoutManager"; ++/*** ++ * Given an offset this utility can compute visible items. Also tracks previously visible items to compute items which get hidden or visible ++ * Virtual renderer uses callbacks from this utility to main recycle pool and the render stack. ++ * The utility optimizes finding visible indexes by using the last visible items. However, that can be slow if scrollToOffset is explicitly called. ++ * We use binary search to optimize in most cases like while finding first visible item or initial offset. In future we'll also be using BS to speed up ++ * scroll to offset. ++ */ ++export interface Range { ++ start: number; ++ end: number; ++} ++export declare type TOnItemStatusChanged = ((all: number[], now: number[], notNow: number[]) => void); ++export default class ViewabilityTracker { ++ onVisibleRowsChanged: TOnItemStatusChanged | null; ++ onEngagedRowsChanged: TOnItemStatusChanged | null; ++ private _currentOffset; ++ private _maxOffset; ++ private _renderAheadOffset; ++ private _visibleWindow; ++ private _engagedWindow; ++ private _relevantDim; ++ private _isHorizontal; ++ private _windowBound; ++ private _visibleIndexes; ++ private _engagedIndexes; ++ private _layouts; ++ private _actualOffset; ++ constructor(renderAheadOffset: number, initialOffset: number); ++ init(): void; ++ setLayouts(layouts: Layout[], maxOffset: number): void; ++ setDimensions(dimension: Dimension, isHorizontal: boolean): void; ++ forceRefresh(): boolean; ++ forceRefreshWithOffset(offset: number): void; ++ updateOffset(offset: number, correction: number, isActual: boolean): void; ++ getLastOffset(): number; ++ getLastActualOffset(): number; ++ getEngagedIndexes(): number[]; ++ findFirstLogicallyVisibleIndex(): number; ++ updateRenderAheadOffset(renderAheadOffset: number): void; ++ getCurrentRenderAheadOffset(): number; ++ private _findFirstVisibleIndexOptimally; ++ private _fitAndUpdate; ++ private _doInitialFit; ++ private _findFirstVisibleIndexLinearly; ++ private _findFirstVisibleIndexUsingBS; ++ private _valueExtractorForBinarySearch; ++ private _fitIndexes; ++ private _checkIntersectionAndReport; ++ private _setRelevantBounds; ++ private _isItemInBounds; ++ private _isItemBoundsBeyondWindow; ++ private _itemIntersectsWindow; ++ private _itemIntersectsEngagedWindow; ++ private _itemIntersectsVisibleWindow; ++ private _updateTrackingWindows; ++ private _diffUpdateOriginalIndexesAndRaiseEvents; ++ private _diffArraysAndCallFunc; ++ private _calculateArrayDiff; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js +new file mode 100644 +index 0000000..dc8271a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js +@@ -0,0 +1,266 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var BinarySearch_1 = require("../utils/BinarySearch"); ++var ViewabilityTracker = /** @class */ (function () { ++ function ViewabilityTracker(renderAheadOffset, initialOffset) { ++ var _this = this; ++ this._layouts = []; ++ this._valueExtractorForBinarySearch = function (index) { ++ var itemRect = _this._layouts[index]; ++ _this._setRelevantBounds(itemRect, _this._relevantDim); ++ return _this._relevantDim.end; ++ }; ++ this._currentOffset = Math.max(0, initialOffset); ++ this._maxOffset = 0; ++ this._actualOffset = 0; ++ this._renderAheadOffset = renderAheadOffset; ++ this._visibleWindow = { start: 0, end: 0 }; ++ this._engagedWindow = { start: 0, end: 0 }; ++ this._isHorizontal = false; ++ this._windowBound = 0; ++ this._visibleIndexes = []; //needs to be sorted ++ this._engagedIndexes = []; //needs to be sorted ++ this.onVisibleRowsChanged = null; ++ this.onEngagedRowsChanged = null; ++ this._relevantDim = { start: 0, end: 0 }; ++ } ++ ViewabilityTracker.prototype.init = function () { ++ this._doInitialFit(this._currentOffset); ++ }; ++ ViewabilityTracker.prototype.setLayouts = function (layouts, maxOffset) { ++ this._layouts = layouts; ++ this._maxOffset = maxOffset; ++ }; ++ ViewabilityTracker.prototype.setDimensions = function (dimension, isHorizontal) { ++ this._isHorizontal = isHorizontal; ++ this._windowBound = isHorizontal ? dimension.width : dimension.height; ++ }; ++ ViewabilityTracker.prototype.forceRefresh = function () { ++ this.forceRefreshWithOffset(this._currentOffset); ++ return false; ++ }; ++ ViewabilityTracker.prototype.forceRefreshWithOffset = function (offset) { ++ this._currentOffset = -1; ++ this.updateOffset(offset, 0, false); ++ }; ++ ViewabilityTracker.prototype.updateOffset = function (offset, correction, isActual) { ++ if (isActual) { ++ this._actualOffset = offset; ++ } ++ offset = Math.min(this._maxOffset, Math.max(0, offset + correction)); ++ if (this._currentOffset !== offset) { ++ this._currentOffset = offset; ++ this._updateTrackingWindows(offset); ++ var startIndex = 0; ++ if (this._visibleIndexes.length > 0) { ++ startIndex = this._visibleIndexes[0]; ++ } ++ this._fitAndUpdate(startIndex); ++ } ++ }; ++ ViewabilityTracker.prototype.getLastOffset = function () { ++ return this._currentOffset; ++ }; ++ ViewabilityTracker.prototype.getLastActualOffset = function () { ++ return this._actualOffset; ++ }; ++ ViewabilityTracker.prototype.getEngagedIndexes = function () { ++ return this._engagedIndexes; ++ }; ++ ViewabilityTracker.prototype.findFirstLogicallyVisibleIndex = function () { ++ var relevantIndex = this._findFirstVisibleIndexUsingBS(0.001); ++ var result = relevantIndex; ++ for (var i = relevantIndex - 1; i >= 0; i--) { ++ if (this._isHorizontal) { ++ if (this._layouts[relevantIndex].x !== this._layouts[i].x) { ++ break; ++ } ++ else { ++ result = i; ++ } ++ } ++ else { ++ if (this._layouts[relevantIndex].y !== this._layouts[i].y) { ++ break; ++ } ++ else { ++ result = i; ++ } ++ } ++ } ++ return result; ++ }; ++ ViewabilityTracker.prototype.updateRenderAheadOffset = function (renderAheadOffset) { ++ this._renderAheadOffset = Math.max(0, renderAheadOffset); ++ this.forceRefreshWithOffset(this._currentOffset); ++ }; ++ ViewabilityTracker.prototype.getCurrentRenderAheadOffset = function () { ++ return this._renderAheadOffset; ++ }; ++ ViewabilityTracker.prototype._findFirstVisibleIndexOptimally = function () { ++ var firstVisibleIndex = 0; ++ //TODO: Talha calculate this value smartly ++ if (this._currentOffset > 5000) { ++ firstVisibleIndex = this._findFirstVisibleIndexUsingBS(); ++ } ++ else if (this._currentOffset > 0) { ++ firstVisibleIndex = this._findFirstVisibleIndexLinearly(); ++ } ++ return firstVisibleIndex; ++ }; ++ ViewabilityTracker.prototype._fitAndUpdate = function (startIndex) { ++ var newVisibleItems = []; ++ var newEngagedItems = []; ++ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex, true); ++ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex + 1, false); ++ this._diffUpdateOriginalIndexesAndRaiseEvents(newVisibleItems, newEngagedItems); ++ }; ++ ViewabilityTracker.prototype._doInitialFit = function (offset) { ++ offset = Math.min(this._maxOffset, Math.max(0, offset)); ++ this._updateTrackingWindows(offset); ++ var firstVisibleIndex = this._findFirstVisibleIndexOptimally(); ++ this._fitAndUpdate(firstVisibleIndex); ++ }; ++ //TODO:Talha switch to binary search and remove atleast once logic in _fitIndexes ++ ViewabilityTracker.prototype._findFirstVisibleIndexLinearly = function () { ++ var count = this._layouts.length; ++ var itemRect = null; ++ var relevantDim = { start: 0, end: 0 }; ++ for (var i = 0; i < count; i++) { ++ itemRect = this._layouts[i]; ++ this._setRelevantBounds(itemRect, relevantDim); ++ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { ++ return i; ++ } ++ } ++ return 0; ++ }; ++ ViewabilityTracker.prototype._findFirstVisibleIndexUsingBS = function (bias) { ++ if (bias === void 0) { bias = 0; } ++ var count = this._layouts.length; ++ return BinarySearch_1.default.findClosestHigherValueIndex(count, this._visibleWindow.start + bias, this._valueExtractorForBinarySearch); ++ }; ++ //TODO:Talha Optimize further in later revisions, alteast once logic can be replace with a BS lookup ++ ViewabilityTracker.prototype._fitIndexes = function (newVisibleIndexes, newEngagedIndexes, startIndex, isReverse) { ++ var count = this._layouts.length; ++ var relevantDim = { start: 0, end: 0 }; ++ var i = 0; ++ var atLeastOneLocated = false; ++ if (startIndex < count) { ++ if (!isReverse) { ++ for (i = startIndex; i < count; i++) { ++ if (this._checkIntersectionAndReport(i, false, relevantDim, newVisibleIndexes, newEngagedIndexes)) { ++ atLeastOneLocated = true; ++ } ++ else { ++ if (atLeastOneLocated) { ++ break; ++ } ++ } ++ } ++ } ++ else { ++ for (i = startIndex; i >= 0; i--) { ++ if (this._checkIntersectionAndReport(i, true, relevantDim, newVisibleIndexes, newEngagedIndexes)) { ++ atLeastOneLocated = true; ++ } ++ else { ++ if (atLeastOneLocated) { ++ break; ++ } ++ } ++ } ++ } ++ } ++ }; ++ ViewabilityTracker.prototype._checkIntersectionAndReport = function (index, insertOnTop, relevantDim, newVisibleIndexes, newEngagedIndexes) { ++ var itemRect = this._layouts[index]; ++ var isFound = false; ++ this._setRelevantBounds(itemRect, relevantDim); ++ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { ++ if (insertOnTop) { ++ newVisibleIndexes.splice(0, 0, index); ++ newEngagedIndexes.splice(0, 0, index); ++ } ++ else { ++ newVisibleIndexes.push(index); ++ newEngagedIndexes.push(index); ++ } ++ isFound = true; ++ } ++ else if (this._itemIntersectsEngagedWindow(relevantDim.start, relevantDim.end)) { ++ //TODO: This needs to be optimized ++ if (insertOnTop) { ++ newEngagedIndexes.splice(0, 0, index); ++ } ++ else { ++ newEngagedIndexes.push(index); ++ } ++ isFound = true; ++ } ++ return isFound; ++ }; ++ ViewabilityTracker.prototype._setRelevantBounds = function (itemRect, relevantDim) { ++ if (this._isHorizontal) { ++ relevantDim.end = itemRect.x + itemRect.width; ++ relevantDim.start = itemRect.x; ++ } ++ else { ++ relevantDim.end = itemRect.y + itemRect.height; ++ relevantDim.start = itemRect.y; ++ } ++ }; ++ ViewabilityTracker.prototype._isItemInBounds = function (window, itemBound) { ++ return (window.start < itemBound && window.end > itemBound); ++ }; ++ ViewabilityTracker.prototype._isItemBoundsBeyondWindow = function (window, startBound, endBound) { ++ return (window.start >= startBound && window.end <= endBound); ++ }; ++ ViewabilityTracker.prototype._itemIntersectsWindow = function (window, startBound, endBound) { ++ return this._isItemInBounds(window, startBound) || ++ this._isItemInBounds(window, endBound) || ++ this._isItemBoundsBeyondWindow(window, startBound, endBound); ++ }; ++ ViewabilityTracker.prototype._itemIntersectsEngagedWindow = function (startBound, endBound) { ++ return this._itemIntersectsWindow(this._engagedWindow, startBound, endBound); ++ }; ++ ViewabilityTracker.prototype._itemIntersectsVisibleWindow = function (startBound, endBound) { ++ return this._itemIntersectsWindow(this._visibleWindow, startBound, endBound); ++ }; ++ ViewabilityTracker.prototype._updateTrackingWindows = function (newOffset) { ++ this._engagedWindow.start = Math.max(0, newOffset - this._renderAheadOffset); ++ this._engagedWindow.end = newOffset + this._windowBound + this._renderAheadOffset; ++ this._visibleWindow.start = newOffset; ++ this._visibleWindow.end = newOffset + this._windowBound; ++ }; ++ //TODO:Talha optimize this ++ ViewabilityTracker.prototype._diffUpdateOriginalIndexesAndRaiseEvents = function (newVisibleItems, newEngagedItems) { ++ this._diffArraysAndCallFunc(newVisibleItems, this._visibleIndexes, this.onVisibleRowsChanged); ++ this._diffArraysAndCallFunc(newEngagedItems, this._engagedIndexes, this.onEngagedRowsChanged); ++ this._visibleIndexes = newVisibleItems; ++ this._engagedIndexes = newEngagedItems; ++ }; ++ ViewabilityTracker.prototype._diffArraysAndCallFunc = function (newItems, oldItems, func) { ++ if (func) { ++ var now = this._calculateArrayDiff(newItems, oldItems); ++ var notNow = this._calculateArrayDiff(oldItems, newItems); ++ if (now.length > 0 || notNow.length > 0) { ++ func(newItems.slice(), now, notNow); ++ } ++ } ++ }; ++ //TODO:Talha since arrays are sorted this can be much faster ++ ViewabilityTracker.prototype._calculateArrayDiff = function (arr1, arr2) { ++ var len = arr1.length; ++ var diffArr = []; ++ for (var i = 0; i < len; i++) { ++ if (BinarySearch_1.default.findIndexOf(arr2, arr1[i]) === -1) { ++ diffArr.push(arr1[i]); ++ } ++ } ++ return diffArr; ++ }; ++ return ViewabilityTracker; ++}()); ++exports.default = ViewabilityTracker; ++//# sourceMappingURL=ViewabilityTracker.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js.map b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js.map +new file mode 100644 +index 0000000..ba78826 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewabilityTracker.js","sourceRoot":"","sources":["../../../src/core/ViewabilityTracker.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.d.ts b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.d.ts +new file mode 100644 +index 0000000..190e53a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.d.ts +@@ -0,0 +1,66 @@ ++import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; ++import { Point, LayoutManager } from "./layoutmanager/LayoutManager"; ++import ViewabilityTracker, { TOnItemStatusChanged } from "./ViewabilityTracker"; ++import { BaseDataProvider } from "./dependencies/DataProvider"; ++/*** ++ * Renderer which keeps track of recyclable items and the currently rendered items. Notifies list view to re render if something changes, like scroll offset ++ */ ++export interface RenderStackItem { ++ dataIndex?: number; ++} ++export interface StableIdMapItem { ++ key: string; ++ type: string | number; ++} ++export interface RenderStack { ++ [key: string]: RenderStackItem; ++} ++export interface RenderStackParams { ++ isHorizontal?: boolean; ++ itemCount: number; ++ initialOffset?: number; ++ initialRenderIndex?: number; ++ renderAheadOffset?: number; ++} ++export declare type StableIdProvider = (index: number) => string; ++export default class VirtualRenderer { ++ private onVisibleItemsChanged; ++ private _scrollOnNextUpdate; ++ private _stableIdToRenderKeyMap; ++ private _engagedIndexes; ++ private _renderStack; ++ private _renderStackChanged; ++ private _fetchStableId; ++ private _isRecyclingEnabled; ++ private _isViewTrackerRunning; ++ private _markDirty; ++ private _startKey; ++ private _layoutProvider; ++ private _recyclePool; ++ private _params; ++ private _layoutManager; ++ private _viewabilityTracker; ++ private _dimensions; ++ constructor(renderStackChanged: (renderStack: RenderStack) => void, scrollOnNextUpdate: (point: Point) => void, fetchStableId: StableIdProvider, isRecyclingEnabled: boolean); ++ getLayoutDimension(): Dimension; ++ updateOffset(offsetX: number, offsetY: number, correction: number, isActual: boolean): void; ++ attachVisibleItemsListener(callback: TOnItemStatusChanged): void; ++ removeVisibleItemsListener(): void; ++ getLayoutManager(): LayoutManager | null; ++ setParamsAndDimensions(params: RenderStackParams, dim: Dimension): void; ++ setLayoutManager(layoutManager: LayoutManager): void; ++ setLayoutProvider(layoutProvider: BaseLayoutProvider): void; ++ getViewabilityTracker(): ViewabilityTracker | null; ++ refreshWithAnchor(): void; ++ refresh(): void; ++ getInitialOffset(): Point; ++ init(): void; ++ startViewabilityTracker(): void; ++ syncAndGetKey(index: number, overrideStableIdProvider?: StableIdProvider, newRenderStack?: RenderStack): string; ++ handleDataSetChange(newDataProvider: BaseDataProvider, shouldOptimizeForAnimations?: boolean): void; ++ private _getCollisionAvoidingKey; ++ private _prepareViewabilityTracker; ++ private _onVisibleItemsChanged; ++ private _onEngagedItemsChanged; ++ private _updateRenderStack; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js +new file mode 100644 +index 0000000..921ccbc +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js +@@ -0,0 +1,321 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecycleItemPool_1 = require("../utils/RecycleItemPool"); ++var CustomError_1 = require("./exceptions/CustomError"); ++var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); ++var ViewabilityTracker_1 = require("./ViewabilityTracker"); ++var ts_object_utils_1 = require("ts-object-utils"); ++var TSCast_1 = require("../utils/TSCast"); ++var VirtualRenderer = /** @class */ (function () { ++ function VirtualRenderer(renderStackChanged, scrollOnNextUpdate, fetchStableId, isRecyclingEnabled) { ++ var _this = this; ++ this._layoutProvider = TSCast_1.default.cast(null); //TSI ++ this._recyclePool = TSCast_1.default.cast(null); //TSI ++ this._layoutManager = null; ++ this._viewabilityTracker = null; ++ this._onVisibleItemsChanged = function (all, now, notNow) { ++ if (_this.onVisibleItemsChanged) { ++ _this.onVisibleItemsChanged(all, now, notNow); ++ } ++ }; ++ this._onEngagedItemsChanged = function (all, now, notNow) { ++ var count = notNow.length; ++ var resolvedKey; ++ var disengagedIndex = 0; ++ if (_this._isRecyclingEnabled) { ++ for (var i = 0; i < count; i++) { ++ disengagedIndex = notNow[i]; ++ delete _this._engagedIndexes[disengagedIndex]; ++ if (_this._params && disengagedIndex < _this._params.itemCount) { ++ //All the items which are now not visible can go to the recycle pool, the pool only needs to maintain keys since ++ //react can link a view to a key automatically ++ resolvedKey = _this._stableIdToRenderKeyMap[_this._fetchStableId(disengagedIndex)]; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(resolvedKey)) { ++ _this._recyclePool.putRecycledObject(_this._layoutProvider.getLayoutTypeForIndex(disengagedIndex), resolvedKey.key); ++ } ++ } ++ } ++ } ++ if (_this._updateRenderStack(now)) { ++ //Ask Recycler View to update itself ++ _this._renderStackChanged(_this._renderStack); ++ } ++ }; ++ //Keeps track of items that need to be rendered in the next render cycle ++ this._renderStack = {}; ++ this._fetchStableId = fetchStableId; ++ //Keeps track of keys of all the currently rendered indexes, can eventually replace renderStack as well if no new use cases come up ++ this._stableIdToRenderKeyMap = {}; ++ this._engagedIndexes = {}; ++ this._renderStackChanged = renderStackChanged; ++ this._scrollOnNextUpdate = scrollOnNextUpdate; ++ this._dimensions = null; ++ this._params = null; ++ this._isRecyclingEnabled = isRecyclingEnabled; ++ this._isViewTrackerRunning = false; ++ this._markDirty = false; ++ //Would be surprised if someone exceeds this ++ this._startKey = 0; ++ this.onVisibleItemsChanged = null; ++ } ++ VirtualRenderer.prototype.getLayoutDimension = function () { ++ if (this._layoutManager) { ++ return this._layoutManager.getContentDimension(); ++ } ++ return { height: 0, width: 0 }; ++ }; ++ VirtualRenderer.prototype.updateOffset = function (offsetX, offsetY, correction, isActual) { ++ if (this._viewabilityTracker) { ++ if (!this._isViewTrackerRunning) { ++ this.startViewabilityTracker(); ++ } ++ if (this._params && this._params.isHorizontal) { ++ this._viewabilityTracker.updateOffset(offsetX, correction, isActual); ++ } ++ else { ++ this._viewabilityTracker.updateOffset(offsetY, correction, isActual); ++ } ++ } ++ }; ++ VirtualRenderer.prototype.attachVisibleItemsListener = function (callback) { ++ this.onVisibleItemsChanged = callback; ++ }; ++ VirtualRenderer.prototype.removeVisibleItemsListener = function () { ++ this.onVisibleItemsChanged = null; ++ if (this._viewabilityTracker) { ++ this._viewabilityTracker.onVisibleRowsChanged = null; ++ } ++ }; ++ VirtualRenderer.prototype.getLayoutManager = function () { ++ return this._layoutManager; ++ }; ++ VirtualRenderer.prototype.setParamsAndDimensions = function (params, dim) { ++ this._params = params; ++ this._dimensions = dim; ++ }; ++ VirtualRenderer.prototype.setLayoutManager = function (layoutManager) { ++ this._layoutManager = layoutManager; ++ if (this._params) { ++ this._layoutManager.relayoutFromIndex(0, this._params.itemCount); ++ } ++ }; ++ VirtualRenderer.prototype.setLayoutProvider = function (layoutProvider) { ++ this._layoutProvider = layoutProvider; ++ }; ++ VirtualRenderer.prototype.getViewabilityTracker = function () { ++ return this._viewabilityTracker; ++ }; ++ VirtualRenderer.prototype.refreshWithAnchor = function () { ++ if (this._viewabilityTracker) { ++ var firstVisibleIndex = this._viewabilityTracker.findFirstLogicallyVisibleIndex(); ++ this._prepareViewabilityTracker(); ++ var offset = 0; ++ if (this._layoutManager && this._params) { ++ var point = this._layoutManager.getOffsetForIndex(firstVisibleIndex); ++ this._scrollOnNextUpdate(point); ++ offset = this._params.isHorizontal ? point.x : point.y; ++ } ++ this._viewabilityTracker.forceRefreshWithOffset(offset); ++ } ++ }; ++ VirtualRenderer.prototype.refresh = function () { ++ if (this._viewabilityTracker) { ++ this._prepareViewabilityTracker(); ++ if (this._viewabilityTracker.forceRefresh()) { ++ if (this._params && this._params.isHorizontal) { ++ this._scrollOnNextUpdate({ x: this._viewabilityTracker.getLastActualOffset(), y: 0 }); ++ } ++ else { ++ this._scrollOnNextUpdate({ x: 0, y: this._viewabilityTracker.getLastActualOffset() }); ++ } ++ } ++ } ++ }; ++ VirtualRenderer.prototype.getInitialOffset = function () { ++ var offset = { x: 0, y: 0 }; ++ if (this._params) { ++ var initialRenderIndex = ts_object_utils_1.Default.value(this._params.initialRenderIndex, 0); ++ if (initialRenderIndex > 0 && this._layoutManager) { ++ offset = this._layoutManager.getOffsetForIndex(initialRenderIndex); ++ this._params.initialOffset = this._params.isHorizontal ? offset.x : offset.y; ++ } ++ else { ++ if (this._params.isHorizontal) { ++ offset.x = ts_object_utils_1.Default.value(this._params.initialOffset, 0); ++ offset.y = 0; ++ } ++ else { ++ offset.y = ts_object_utils_1.Default.value(this._params.initialOffset, 0); ++ offset.x = 0; ++ } ++ } ++ } ++ return offset; ++ }; ++ VirtualRenderer.prototype.init = function () { ++ this.getInitialOffset(); ++ this._recyclePool = new RecycleItemPool_1.default(); ++ if (this._params) { ++ this._viewabilityTracker = new ViewabilityTracker_1.default(ts_object_utils_1.Default.value(this._params.renderAheadOffset, 0), ts_object_utils_1.Default.value(this._params.initialOffset, 0)); ++ } ++ else { ++ this._viewabilityTracker = new ViewabilityTracker_1.default(0, 0); ++ } ++ this._prepareViewabilityTracker(); ++ }; ++ VirtualRenderer.prototype.startViewabilityTracker = function () { ++ if (this._viewabilityTracker) { ++ this._isViewTrackerRunning = true; ++ this._viewabilityTracker.init(); ++ } ++ }; ++ VirtualRenderer.prototype.syncAndGetKey = function (index, overrideStableIdProvider, newRenderStack) { ++ var getStableId = overrideStableIdProvider ? overrideStableIdProvider : this._fetchStableId; ++ var renderStack = newRenderStack ? newRenderStack : this._renderStack; ++ var stableIdItem = this._stableIdToRenderKeyMap[getStableId(index)]; ++ var key = stableIdItem ? stableIdItem.key : undefined; ++ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { ++ var type = this._layoutProvider.getLayoutTypeForIndex(index); ++ key = this._recyclePool.getRecycledObject(type); ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { ++ var itemMeta = renderStack[key]; ++ if (itemMeta) { ++ var oldIndex = itemMeta.dataIndex; ++ itemMeta.dataIndex = index; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(oldIndex) && oldIndex !== index) { ++ delete this._stableIdToRenderKeyMap[getStableId(oldIndex)]; ++ } ++ } ++ else { ++ renderStack[key] = { dataIndex: index }; ++ } ++ } ++ else { ++ key = getStableId(index); ++ if (renderStack[key]) { ++ //Probable collision, warn and avoid ++ //TODO: Disabled incorrectly triggering in some cases ++ //console.warn("Possible stableId collision @", index); //tslint:disable-line ++ key = this._getCollisionAvoidingKey(); ++ } ++ renderStack[key] = { dataIndex: index }; ++ } ++ this._markDirty = true; ++ this._stableIdToRenderKeyMap[getStableId(index)] = { key: key, type: type }; ++ } ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { ++ this._recyclePool.removeFromPool(key); ++ } ++ var stackItem = renderStack[key]; ++ if (stackItem && stackItem.dataIndex !== index) { ++ //Probable collision, warn ++ console.warn("Possible stableId collision @", index); //tslint:disable-line ++ } ++ return key; ++ }; ++ //Further optimize in later revision, pretty fast for now considering this is a low frequency event ++ VirtualRenderer.prototype.handleDataSetChange = function (newDataProvider, shouldOptimizeForAnimations) { ++ var getStableId = newDataProvider.getStableId; ++ var maxIndex = newDataProvider.getSize() - 1; ++ var activeStableIds = {}; ++ var newRenderStack = {}; ++ //Compute active stable ids and stale active keys and resync render stack ++ for (var key in this._renderStack) { ++ if (this._renderStack.hasOwnProperty(key)) { ++ var index = this._renderStack[key].dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { ++ if (index <= maxIndex) { ++ var stableId = getStableId(index); ++ activeStableIds[stableId] = 1; ++ } ++ } ++ } ++ } ++ //Clean stable id to key map ++ var oldActiveStableIds = Object.keys(this._stableIdToRenderKeyMap); ++ var oldActiveStableIdsCount = oldActiveStableIds.length; ++ for (var i = 0; i < oldActiveStableIdsCount; i++) { ++ var key = oldActiveStableIds[i]; ++ if (!activeStableIds[key]) { ++ if (!shouldOptimizeForAnimations && this._isRecyclingEnabled) { ++ var stableIdItem = this._stableIdToRenderKeyMap[key]; ++ if (stableIdItem) { ++ this._recyclePool.putRecycledObject(stableIdItem.type, stableIdItem.key); ++ } ++ } ++ delete this._stableIdToRenderKeyMap[key]; ++ } ++ } ++ for (var key in this._renderStack) { ++ if (this._renderStack.hasOwnProperty(key)) { ++ var index = this._renderStack[key].dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { ++ if (index <= maxIndex) { ++ var newKey = this.syncAndGetKey(index, getStableId, newRenderStack); ++ var newStackItem = newRenderStack[newKey]; ++ if (!newStackItem) { ++ newRenderStack[newKey] = { dataIndex: index }; ++ } ++ else if (newStackItem.dataIndex !== index) { ++ var cllKey = this._getCollisionAvoidingKey(); ++ newRenderStack[cllKey] = { dataIndex: index }; ++ this._stableIdToRenderKeyMap[getStableId(index)] = { ++ key: cllKey, type: this._layoutProvider.getLayoutTypeForIndex(index), ++ }; ++ } ++ } ++ } ++ delete this._renderStack[key]; ++ } ++ } ++ Object.assign(this._renderStack, newRenderStack); ++ for (var key in this._renderStack) { ++ if (this._renderStack.hasOwnProperty(key)) { ++ var index = this._renderStack[key].dataIndex; ++ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index) && ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { ++ var type = this._layoutProvider.getLayoutTypeForIndex(index); ++ this._recyclePool.putRecycledObject(type, key); ++ } ++ } ++ } ++ }; ++ VirtualRenderer.prototype._getCollisionAvoidingKey = function () { ++ return "#" + this._startKey++ + "_rlv_c"; ++ }; ++ VirtualRenderer.prototype._prepareViewabilityTracker = function () { ++ if (this._viewabilityTracker && this._layoutManager && this._dimensions && this._params) { ++ this._viewabilityTracker.onEngagedRowsChanged = this._onEngagedItemsChanged; ++ if (this.onVisibleItemsChanged) { ++ this._viewabilityTracker.onVisibleRowsChanged = this._onVisibleItemsChanged; ++ } ++ this._viewabilityTracker.setLayouts(this._layoutManager.getLayouts(), this._params.isHorizontal ? ++ this._layoutManager.getContentDimension().width : ++ this._layoutManager.getContentDimension().height); ++ this._viewabilityTracker.setDimensions({ ++ height: this._dimensions.height, ++ width: this._dimensions.width, ++ }, ts_object_utils_1.Default.value(this._params.isHorizontal, false)); ++ } ++ else { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.initializationException); ++ } ++ }; ++ //Updates render stack and reports whether anything has changed ++ VirtualRenderer.prototype._updateRenderStack = function (itemIndexes) { ++ this._markDirty = false; ++ var count = itemIndexes.length; ++ var index = 0; ++ var hasRenderStackChanged = false; ++ for (var i = 0; i < count; i++) { ++ index = itemIndexes[i]; ++ this._engagedIndexes[index] = 1; ++ this.syncAndGetKey(index); ++ hasRenderStackChanged = this._markDirty; ++ } ++ this._markDirty = false; ++ return hasRenderStackChanged; ++ }; ++ return VirtualRenderer; ++}()); ++exports.default = VirtualRenderer; ++//# sourceMappingURL=VirtualRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js.map b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js.map +new file mode 100644 +index 0000000..30876cc +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"VirtualRenderer.js","sourceRoot":"","sources":["../../../src/core/VirtualRenderer.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Constants.d.ts b/node_modules/recyclerlistview/dist/web/core/constants/Constants.d.ts +new file mode 100644 +index 0000000..977bb6a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/constants/Constants.d.ts +@@ -0,0 +1,3 @@ ++export declare const Constants: { ++ [key: string]: string; ++}; +diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Constants.js b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js +new file mode 100644 +index 0000000..c3323a1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js +@@ -0,0 +1,7 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++exports.Constants = { ++ CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX: "_offset", ++ CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX: "_layouts", ++}; ++//# sourceMappingURL=Constants.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Constants.js.map b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js.map +new file mode 100644 +index 0000000..e0d93e2 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../../../src/core/constants/Constants.ts"],"names":[],"mappings":";;AAAa,QAAA,SAAS,GAA4B;IAC9C,kCAAkC,EAAG,SAAS;IAC9C,kCAAkC,EAAE,UAAU;CACjD,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Messages.d.ts b/node_modules/recyclerlistview/dist/web/core/constants/Messages.d.ts +new file mode 100644 +index 0000000..d211558 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/constants/Messages.d.ts +@@ -0,0 +1,3 @@ ++export declare const Messages: { ++ [key: string]: string; ++}; +diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Messages.js b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js +new file mode 100644 +index 0000000..51baf1f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js +@@ -0,0 +1,10 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++exports.Messages = { ++ ERROR_LISTVIEW_VALIDATION: "missing datasource or layout provider, cannot proceed without it", ++ WARN_SCROLL_TO_INDEX: "scrollTo was called before RecyclerListView was measured, please wait for the mount to finish", ++ WARN_NO_DATA: "You have mounted RecyclerListView with an empty data provider (Size in 0). Please mount only if there is atleast one item " + ++ "to ensure optimal performance and to avoid unexpected behavior", ++ VISIBLE_INDEXES_CHANGED_DEPRECATED: "onVisibleIndexesChanged deprecated. Please use onVisibleIndicesChanged instead.", ++}; ++//# sourceMappingURL=Messages.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Messages.js.map b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js.map +new file mode 100644 +index 0000000..9695650 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../../src/core/constants/Messages.ts"],"names":[],"mappings":";;AAAa,QAAA,QAAQ,GAA4B;IAC7C,yBAAyB,EAAG,kEAAkE;IAC9F,oBAAoB,EAAE,+FAA+F;IACrH,YAAY,EAAE,4HAA4H;QAC5H,gEAAgE;IAC9E,kCAAkC,EAAE,iFAAiF;CACxH,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.d.ts b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.d.ts +new file mode 100644 +index 0000000..98abef9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.d.ts +@@ -0,0 +1,13 @@ ++/*** ++ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, ++ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you ++ * can instantly jump to any location. ++ * ++ * Use this interface and implement the given methods to preserve context. ++ */ ++export default abstract class ContextProvider { ++ abstract getUniqueKey(): string; ++ abstract save(key: string, value: string | number): void; ++ abstract get(key: string): string | number; ++ abstract remove(key: string): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js +new file mode 100644 +index 0000000..724fa5a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js +@@ -0,0 +1,16 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++/*** ++ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, ++ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you ++ * can instantly jump to any location. ++ * ++ * Use this interface and implement the given methods to preserve context. ++ */ ++var ContextProvider = /** @class */ (function () { ++ function ContextProvider() { ++ } ++ return ContextProvider; ++}()); ++exports.default = ContextProvider; ++//# sourceMappingURL=ContextProvider.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js.map b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js.map +new file mode 100644 +index 0000000..27659b2 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ContextProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/ContextProvider.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH;IAAA;IAYA,CAAC;IAAD,sBAAC;AAAD,CAAC,AAZD,IAYC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.d.ts b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.d.ts +new file mode 100644 +index 0000000..0844963 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.d.ts +@@ -0,0 +1,25 @@ ++/*** ++ * You can create a new instance or inherit and override default methods ++ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. ++ */ ++export declare abstract class BaseDataProvider { ++ rowHasChanged: (r1: any, r2: any) => boolean; ++ getStableId: (index: number) => string; ++ private _firstIndexToProcess; ++ private _size; ++ private _data; ++ private _hasStableIds; ++ private _requiresDataChangeHandling; ++ constructor(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string); ++ abstract newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string): BaseDataProvider; ++ getDataForIndex(index: number): any; ++ getAllData(): any[]; ++ getSize(): number; ++ hasStableIds(): boolean; ++ requiresDataChangeHandling(): boolean; ++ getFirstIndexToProcessInternal(): number; ++ cloneWithRows(newData: any[], firstModifiedIndex?: number): DataProvider; ++} ++export default class DataProvider extends BaseDataProvider { ++ newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: ((index: number) => string) | undefined): BaseDataProvider; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js +new file mode 100644 +index 0000000..ee37484 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js +@@ -0,0 +1,94 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ts_object_utils_1 = require("ts-object-utils"); ++/*** ++ * You can create a new instance or inherit and override default methods ++ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. ++ */ ++var BaseDataProvider = /** @class */ (function () { ++ function BaseDataProvider(rowHasChanged, getStableId) { ++ this._firstIndexToProcess = 0; ++ this._size = 0; ++ this._data = []; ++ this._hasStableIds = false; ++ this._requiresDataChangeHandling = false; ++ this.rowHasChanged = rowHasChanged; ++ if (getStableId) { ++ this.getStableId = getStableId; ++ this._hasStableIds = true; ++ } ++ else { ++ this.getStableId = function (index) { return index.toString(); }; ++ } ++ } ++ BaseDataProvider.prototype.getDataForIndex = function (index) { ++ return this._data[index]; ++ }; ++ BaseDataProvider.prototype.getAllData = function () { ++ return this._data; ++ }; ++ BaseDataProvider.prototype.getSize = function () { ++ return this._size; ++ }; ++ BaseDataProvider.prototype.hasStableIds = function () { ++ return this._hasStableIds; ++ }; ++ BaseDataProvider.prototype.requiresDataChangeHandling = function () { ++ return this._requiresDataChangeHandling; ++ }; ++ BaseDataProvider.prototype.getFirstIndexToProcessInternal = function () { ++ return this._firstIndexToProcess; ++ }; ++ //No need to override this one ++ //If you already know the first row where rowHasChanged will be false pass it upfront to avoid loop ++ BaseDataProvider.prototype.cloneWithRows = function (newData, firstModifiedIndex) { ++ var dp = this.newInstance(this.rowHasChanged, this.getStableId); ++ var newSize = newData.length; ++ var iterCount = Math.min(this._size, newSize); ++ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(firstModifiedIndex)) { ++ var i = 0; ++ for (i = 0; i < iterCount; i++) { ++ if (this.rowHasChanged(this._data[i], newData[i])) { ++ break; ++ } ++ } ++ dp._firstIndexToProcess = i; ++ } ++ else { ++ dp._firstIndexToProcess = Math.max(Math.min(firstModifiedIndex, this._data.length), 0); ++ } ++ if (dp._firstIndexToProcess !== this._data.length) { ++ dp._requiresDataChangeHandling = true; ++ } ++ dp._data = newData; ++ dp._size = newSize; ++ return dp; ++ }; ++ return BaseDataProvider; ++}()); ++exports.BaseDataProvider = BaseDataProvider; ++var DataProvider = /** @class */ (function (_super) { ++ __extends(DataProvider, _super); ++ function DataProvider() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ DataProvider.prototype.newInstance = function (rowHasChanged, getStableId) { ++ return new DataProvider(rowHasChanged, getStableId); ++ }; ++ return DataProvider; ++}(BaseDataProvider)); ++exports.default = DataProvider; ++//# sourceMappingURL=DataProvider.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js.map b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js.map +new file mode 100644 +index 0000000..fd7dedf +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DataProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/DataProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mDAA6C;AAE7C;;;GAGG;AACH;IAWI,0BAAY,aAA4C,EAAE,WAAuC;QANzF,yBAAoB,GAAW,CAAC,CAAC;QACjC,UAAK,GAAW,CAAC,CAAC;QAClB,UAAK,GAAU,EAAE,CAAC;QAClB,kBAAa,GAAG,KAAK,CAAC;QACtB,gCAA2B,GAAG,KAAK,CAAC;QAGxC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,WAAW,EAAE;YACb,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC7B;aAAM;YACH,IAAI,CAAC,WAAW,GAAG,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,QAAQ,EAAE,EAAhB,CAAgB,CAAC;SAClD;IACL,CAAC;IAIM,0CAAe,GAAtB,UAAuB,KAAa;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAEM,qCAAU,GAAjB;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,kCAAO,GAAd;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,uCAAY,GAAnB;QACI,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEM,qDAA0B,GAAjC;QACI,OAAO,IAAI,CAAC,2BAA2B,CAAC;IAC5C,CAAC;IAEM,yDAA8B,GAArC;QACI,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACrC,CAAC;IAED,8BAA8B;IAC9B,mGAAmG;IAC5F,wCAAa,GAApB,UAAqB,OAAc,EAAE,kBAA2B;QAC5D,IAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClE,IAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/B,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,4BAAU,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE;YAClD,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;gBAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC/C,MAAM;iBACT;aACJ;YACD,EAAE,CAAC,oBAAoB,GAAG,CAAC,CAAC;SAC/B;aAAM;YACH,EAAE,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1F;QACD,IAAI,EAAE,CAAC,oBAAoB,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAC/C,EAAE,CAAC,2BAA2B,GAAG,IAAI,CAAC;SACzC;QACD,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,OAAO,EAAE,CAAC;IACd,CAAC;IACL,uBAAC;AAAD,CAAC,AAvED,IAuEC;AAvEqB,4CAAgB;AAyEtC;IAA0C,gCAAgB;IAA1D;;IAIA,CAAC;IAHU,kCAAW,GAAlB,UAAmB,aAA4C,EAAE,WAAqD;QAClH,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC;IACL,mBAAC;AAAD,CAAC,AAJD,CAA0C,gBAAgB,GAIzD"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.d.ts b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.d.ts +new file mode 100644 +index 0000000..e832379 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.d.ts +@@ -0,0 +1,35 @@ ++import { Layout, LayoutManager } from "../layoutmanager/LayoutManager"; ++/** ++ * Created by talha.naqvi on 05/04/17. ++ * You can create a new instance or inherit and override default methods ++ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider ++ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all ++ * data upfront will only limit possibilites in the future. ++ * ++ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates ++ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. ++ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. ++ * ++ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. ++ */ ++export declare abstract class BaseLayoutProvider { ++ shouldRefreshWithAnchoring: boolean; ++ abstract newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; ++ abstract getLayoutTypeForIndex(index: number): string | number; ++ abstract checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; ++} ++export declare class LayoutProvider extends BaseLayoutProvider { ++ private _getLayoutTypeForIndex; ++ private _setLayoutForType; ++ private _tempDim; ++ private _lastLayoutManager; ++ constructor(getLayoutTypeForIndex: (index: number) => string | number, setLayoutForType: (type: string | number, dim: Dimension, index: number) => void); ++ newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; ++ getLayoutTypeForIndex(index: number): string | number; ++ setComputedLayout(type: string | number, dimension: Dimension, index: number): void; ++ checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; ++} ++export interface Dimension { ++ height: number; ++ width: number; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js +new file mode 100644 +index 0000000..4f5dbdf +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js +@@ -0,0 +1,72 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var LayoutManager_1 = require("../layoutmanager/LayoutManager"); ++/** ++ * Created by talha.naqvi on 05/04/17. ++ * You can create a new instance or inherit and override default methods ++ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider ++ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all ++ * data upfront will only limit possibilites in the future. ++ * ++ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates ++ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. ++ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. ++ * ++ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. ++ */ ++var BaseLayoutProvider = /** @class */ (function () { ++ function BaseLayoutProvider() { ++ //Unset if your new layout provider doesn't require firstVisibleIndex preservation on application ++ this.shouldRefreshWithAnchoring = true; ++ } ++ return BaseLayoutProvider; ++}()); ++exports.BaseLayoutProvider = BaseLayoutProvider; ++var LayoutProvider = /** @class */ (function (_super) { ++ __extends(LayoutProvider, _super); ++ function LayoutProvider(getLayoutTypeForIndex, setLayoutForType) { ++ var _this = _super.call(this) || this; ++ _this._getLayoutTypeForIndex = getLayoutTypeForIndex; ++ _this._setLayoutForType = setLayoutForType; ++ _this._tempDim = { height: 0, width: 0 }; ++ return _this; ++ } ++ LayoutProvider.prototype.newLayoutManager = function (renderWindowSize, isHorizontal, cachedLayouts) { ++ this._lastLayoutManager = new LayoutManager_1.WrapGridLayoutManager(this, renderWindowSize, isHorizontal, cachedLayouts); ++ return this._lastLayoutManager; ++ }; ++ //Provide a type for index, something which identifies the template of view about to load ++ LayoutProvider.prototype.getLayoutTypeForIndex = function (index) { ++ return this._getLayoutTypeForIndex(index); ++ }; ++ //Given a type and dimension set the dimension values on given dimension object ++ //You can also get index here if you add an extra argument but we don't recommend using it. ++ LayoutProvider.prototype.setComputedLayout = function (type, dimension, index) { ++ return this._setLayoutForType(type, dimension, index); ++ }; ++ LayoutProvider.prototype.checkDimensionDiscrepancy = function (dimension, type, index) { ++ var dimension1 = dimension; ++ this.setComputedLayout(type, this._tempDim, index); ++ var dimension2 = this._tempDim; ++ if (this._lastLayoutManager) { ++ this._lastLayoutManager.setMaxBounds(dimension2); ++ } ++ return dimension1.height !== dimension2.height || dimension1.width !== dimension2.width; ++ }; ++ return LayoutProvider; ++}(BaseLayoutProvider)); ++exports.LayoutProvider = LayoutProvider; ++//# sourceMappingURL=LayoutProvider.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js.map b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js.map +new file mode 100644 +index 0000000..d2bed0e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"LayoutProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/LayoutProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gEAA8F;AAE9F;;;;;;;;;;;;GAYG;AAEH;IAAA;QACI,iGAAiG;QAC1F,+BAA0B,GAAY,IAAI,CAAC;IAYtD,CAAC;IAAD,yBAAC;AAAD,CAAC,AAdD,IAcC;AAdqB,gDAAkB;AAgBxC;IAAoC,kCAAkB;IAOlD,wBAAY,qBAAyD,EAAE,gBAAgF;QAAvJ,YACI,iBAAO,SAIV;QAHG,KAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;QACpD,KAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QAC1C,KAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;IAC5C,CAAC;IAEM,yCAAgB,GAAvB,UAAwB,gBAA2B,EAAE,YAAsB,EAAE,aAAwB;QACjG,IAAI,CAAC,kBAAkB,GAAG,IAAI,qCAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACzG,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED,yFAAyF;IAClF,8CAAqB,GAA5B,UAA6B,KAAa;QACtC,OAAO,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,+EAA+E;IAC/E,2FAA2F;IACpF,0CAAiB,GAAxB,UAAyB,IAAqB,EAAE,SAAoB,EAAE,KAAa;QAC/E,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1D,CAAC;IAEM,kDAAyB,GAAhC,UAAiC,SAAoB,EAAE,IAAqB,EAAE,KAAa;QACvF,IAAM,UAAU,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,IAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;SACpD;QACD,OAAO,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC;IAC5F,CAAC;IACL,qBAAC;AAAD,CAAC,AAvCD,CAAoC,kBAAkB,GAuCrD;AAvCY,wCAAc"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.d.ts b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.d.ts +new file mode 100644 +index 0000000..d6e7c73 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.d.ts +@@ -0,0 +1,4 @@ ++import ResizeDebugHandler from "./resize/ResizeDebugHandler"; ++export interface DebugHandlers { ++ resizeDebugHandler?: ResizeDebugHandler; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js +new file mode 100644 +index 0000000..fe8175c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js +@@ -0,0 +1,3 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++//# sourceMappingURL=DebugHandlers.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js.map b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js.map +new file mode 100644 +index 0000000..332282c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DebugHandlers.js","sourceRoot":"","sources":["../../../../../src/core/devutils/debughandlers/DebugHandlers.ts"],"names":[],"mappings":""} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts +new file mode 100644 +index 0000000..e32b3c6 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts +@@ -0,0 +1,8 @@ ++import { Dimension } from "../../../.."; ++import ResizeDebugHandler from "./ResizeDebugHandler"; ++export default class DefaultResizeDebugHandler implements ResizeDebugHandler { ++ private readonly relaxation; ++ private readonly onRelaxationViolation; ++ constructor(relaxation: Dimension, onRelaxationViolation: (expectedDim: Dimension, actualDim: Dimension, index: number) => void); ++ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js +new file mode 100644 +index 0000000..258b921 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js +@@ -0,0 +1,25 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var DefaultResizeDebugHandler = /** @class */ (function () { ++ // Relaxation is the Dimension object where it accepts the relaxation to allow for each dimension. ++ // Any of the dimension (height or width) whose value for relaxation is less than 0 would be ignored. ++ function DefaultResizeDebugHandler(relaxation, onRelaxationViolation) { ++ this.relaxation = relaxation; ++ this.onRelaxationViolation = onRelaxationViolation; ++ } ++ DefaultResizeDebugHandler.prototype.resizeDebug = function (oldDim, newDim, index) { ++ var isViolated = false; ++ if (this.relaxation.height >= 0 && Math.abs(newDim.height - oldDim.height) >= this.relaxation.height) { ++ isViolated = true; ++ } ++ if (!isViolated && this.relaxation.width >= 0 && Math.abs(newDim.width - oldDim.width) >= this.relaxation.width) { ++ isViolated = true; ++ } ++ if (isViolated) { ++ this.onRelaxationViolation(oldDim, newDim, index); ++ } ++ }; ++ return DefaultResizeDebugHandler; ++}()); ++exports.default = DefaultResizeDebugHandler; ++//# sourceMappingURL=DefaultResizeDebugHandler.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map +new file mode 100644 +index 0000000..ccbb28c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.ts"],"names":[],"mappings":";;AAGA;IAII,kGAAkG;IAClG,qGAAqG;IACrG,mCAAmB,UAAqB,EAAE,qBAA4F;QAClI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACvD,CAAC;IAEM,+CAAW,GAAlB,UAAmB,MAAiB,EAAE,MAAiB,EAAE,KAAa;QAClE,IAAI,UAAU,GAAY,KAAK,CAAC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClG,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;YAC7G,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,UAAU,EAAE;YACZ,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;SACrD;IACL,CAAC;IACL,gCAAC;AAAD,CAAC,AAzBD,IAyBC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts +new file mode 100644 +index 0000000..654f89d +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts +@@ -0,0 +1,4 @@ ++import { Dimension } from "../../../.."; ++export default interface ResizeDebugHandler { ++ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js +new file mode 100644 +index 0000000..697bdb8 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js +@@ -0,0 +1,3 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++//# sourceMappingURL=ResizeDebugHandler.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map +new file mode 100644 +index 0000000..2122fce +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/ResizeDebugHandler.ts"],"names":[],"mappings":""} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.d.ts b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.d.ts +new file mode 100644 +index 0000000..67ab42e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.d.ts +@@ -0,0 +1,7 @@ ++export default class CustomError extends Error { ++ constructor(exception: Exception); ++} ++export interface Exception { ++ type: string; ++ message: string; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js +new file mode 100644 +index 0000000..6a6b17c +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js +@@ -0,0 +1,26 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var CustomError = /** @class */ (function (_super) { ++ __extends(CustomError, _super); ++ function CustomError(exception) { ++ var _this = _super.call(this, exception.message) || this; ++ _this.name = exception.type; ++ return _this; ++ } ++ return CustomError; ++}(Error)); ++exports.default = CustomError; ++//# sourceMappingURL=CustomError.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js.map b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js.map +new file mode 100644 +index 0000000..bbff8bd +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"CustomError.js","sourceRoot":"","sources":["../../../../src/core/exceptions/CustomError.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;IAAyC,+BAAK;IAC1C,qBAAY,SAAoB;QAAhC,YACI,kBAAM,SAAS,CAAC,OAAO,CAAC,SAE3B;QADG,KAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;;IAC/B,CAAC;IACL,kBAAC;AAAD,CAAC,AALD,CAAyC,KAAK,GAK7C"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.d.ts b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.d.ts +new file mode 100644 +index 0000000..7db4997 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.d.ts +@@ -0,0 +1,5 @@ ++import { Exception } from "./CustomError"; ++declare const RecyclerListViewExceptions: { ++ [key: string]: Exception; ++}; ++export default RecyclerListViewExceptions; +diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js +new file mode 100644 +index 0000000..26413ac +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js +@@ -0,0 +1,48 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecyclerListViewExceptions = { ++ initializationException: { ++ message: "Parameters required for initializing the module are missing", ++ type: "Initialization essentials missing", ++ }, ++ itemBoundsException: { ++ message: "Dimensions cannot be undefined or null, check if LayoutProvider returns irregular values", ++ type: "ItemBoundsException", ++ }, ++ itemTypeNullException: { ++ message: "RecyclerListView items always require a type, check if LayoutProvider returns irregular values", ++ type: "ItemTypeNullException", ++ }, ++ layoutException: { ++ message: "RecyclerListView needs to have a bounded size. Currently height or, width is 0." + ++ "Consider adding style={{flex:1}} or, fixed dimensions", ++ type: "LayoutException", ++ }, ++ platformNotDetectedException: { ++ message: "Unable to detect the running platform, if you're trying to run recyclerlistview " + ++ "in browser make sure process.env.RLV_ENV is set to browser in webpack config", ++ type: "PlatformNotDetectedException", ++ }, ++ unresolvedDependenciesException: { ++ message: "missing datasource or layout provider, cannot proceed without it", ++ type: "UnresolvedDependenciesException", ++ }, ++ refNotAsFunctionException: { ++ message: "When using StickyContainer, RecyclerListView needs to use ref as a function and not as a string.", ++ type: "RefNotAsFunctionException", ++ }, ++ wrongStickyChildTypeException: { ++ message: "StickyContainer can only have a single child of type RecyclerListView.", ++ type: "WrongStickyChildTypeException", ++ }, ++ usingOldVisibleIndexesChangedParam: { ++ message: "onVisibleIndexesChanged has been deprecated. Please use onVisibleIndicesChanged instead.", ++ type: "usingOldVisibleIndexesChangedParam", ++ }, ++ stickyIndicesArraySortError: { ++ message: "The sticky indices array passed to StickyContainer isn't sorted in ascending order.", ++ type: "stickyIndicesArraySortError", ++ }, ++}; ++exports.default = RecyclerListViewExceptions; ++//# sourceMappingURL=RecyclerListViewExceptions.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js.map b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js.map +new file mode 100644 +index 0000000..75634b0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"RecyclerListViewExceptions.js","sourceRoot":"","sources":["../../../../src/core/exceptions/RecyclerListViewExceptions.ts"],"names":[],"mappings":";;AAEA,IAAM,0BAA0B,GAA+B;IAC3D,uBAAuB,EAAE;QACrB,OAAO,EAAE,6DAA6D;QACtE,IAAI,EAAE,mCAAmC;KAC5C;IACD,mBAAmB,EAAE;QACjB,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,qBAAqB;KAC9B;IACD,qBAAqB,EAAE;QACnB,OAAO,EAAE,gGAAgG;QACzG,IAAI,EAAE,uBAAuB;KAChC;IACD,eAAe,EAAE;QACb,OAAO,EAAE,iFAAiF;YAC9E,uDAAuD;QACnE,IAAI,EAAE,iBAAiB;KAC1B;IACD,4BAA4B,EAAE;QAC1B,OAAO,EAAE,kFAAkF;YAC3F,8EAA8E;QAC9E,IAAI,EAAE,8BAA8B;KACvC;IACD,+BAA+B,EAAE;QAC7B,OAAO,EAAE,kEAAkE;QAC3E,IAAI,EAAE,iCAAiC;KAC1C;IACD,yBAAyB,EAAE;QACvB,OAAO,EAAE,kGAAkG;QAC3G,IAAI,EAAE,2BAA2B;KACpC;IACD,6BAA6B,EAAE;QAC3B,OAAO,EAAE,wEAAwE;QACjF,IAAI,EAAE,+BAA+B;KACxC;IACD,kCAAkC,EAAE;QAChC,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,oCAAoC;KAC7C;IACD,2BAA2B,EAAE;QACzB,OAAO,EAAE,qFAAqF;QAC9F,IAAI,EAAE,6BAA6B;KACtC;CACJ,CAAC;AACF,kBAAe,0BAA0B,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.d.ts b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.d.ts +new file mode 100644 +index 0000000..51b60d7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.d.ts +@@ -0,0 +1,40 @@ ++/*** ++ * Computes the positions and dimensions of items that will be rendered by the list. The output from this is utilized by viewability tracker to compute the ++ * lists of visible/hidden item. ++ */ ++import { Dimension, LayoutProvider } from "../dependencies/LayoutProvider"; ++export declare abstract class LayoutManager { ++ getOffsetForIndex(index: number): Point; ++ getStyleOverridesForIndex(index: number): object | undefined; ++ abstract getContentDimension(): Dimension; ++ abstract getLayouts(): Layout[]; ++ abstract overrideLayout(index: number, dim: Dimension): boolean; ++ abstract relayoutFromIndex(startIndex: number, itemCount: number): void; ++} ++export declare class WrapGridLayoutManager extends LayoutManager { ++ private _layoutProvider; ++ private _window; ++ private _totalHeight; ++ private _totalWidth; ++ private _isHorizontal; ++ private _layouts; ++ constructor(layoutProvider: LayoutProvider, renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]); ++ getContentDimension(): Dimension; ++ getLayouts(): Layout[]; ++ getOffsetForIndex(index: number): Point; ++ overrideLayout(index: number, dim: Dimension): boolean; ++ setMaxBounds(itemDim: Dimension): void; ++ relayoutFromIndex(startIndex: number, itemCount: number): void; ++ private _pointDimensionsToRect; ++ private _setFinalDimensions; ++ private _locateFirstNeighbourIndex; ++ private _checkBounds; ++} ++export interface Layout extends Dimension, Point { ++ isOverridden?: boolean; ++ type: string | number; ++} ++export interface Point { ++ x: number; ++ y: number; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js +new file mode 100644 +index 0000000..23075a0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js +@@ -0,0 +1,196 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var CustomError_1 = require("../exceptions/CustomError"); ++var LayoutManager = /** @class */ (function () { ++ function LayoutManager() { ++ } ++ LayoutManager.prototype.getOffsetForIndex = function (index) { ++ var layouts = this.getLayouts(); ++ if (layouts.length > index) { ++ return { x: layouts[index].x, y: layouts[index].y }; ++ } ++ else { ++ throw new CustomError_1.default({ ++ message: "No layout available for index: " + index, ++ type: "LayoutUnavailableException", ++ }); ++ } ++ }; ++ //You can ovveride this incase you want to override style in some cases e.g, say you want to enfore width but not height ++ LayoutManager.prototype.getStyleOverridesForIndex = function (index) { ++ return undefined; ++ }; ++ return LayoutManager; ++}()); ++exports.LayoutManager = LayoutManager; ++var WrapGridLayoutManager = /** @class */ (function (_super) { ++ __extends(WrapGridLayoutManager, _super); ++ function WrapGridLayoutManager(layoutProvider, renderWindowSize, isHorizontal, cachedLayouts) { ++ if (isHorizontal === void 0) { isHorizontal = false; } ++ var _this = _super.call(this) || this; ++ _this._layoutProvider = layoutProvider; ++ _this._window = renderWindowSize; ++ _this._totalHeight = 0; ++ _this._totalWidth = 0; ++ _this._isHorizontal = !!isHorizontal; ++ _this._layouts = cachedLayouts ? cachedLayouts : []; ++ return _this; ++ } ++ WrapGridLayoutManager.prototype.getContentDimension = function () { ++ return { height: this._totalHeight, width: this._totalWidth }; ++ }; ++ WrapGridLayoutManager.prototype.getLayouts = function () { ++ return this._layouts; ++ }; ++ WrapGridLayoutManager.prototype.getOffsetForIndex = function (index) { ++ if (this._layouts.length > index) { ++ return { x: this._layouts[index].x, y: this._layouts[index].y }; ++ } ++ else { ++ throw new CustomError_1.default({ ++ message: "No layout available for index: " + index, ++ type: "LayoutUnavailableException", ++ }); ++ } ++ }; ++ WrapGridLayoutManager.prototype.overrideLayout = function (index, dim) { ++ var layout = this._layouts[index]; ++ if (layout) { ++ layout.isOverridden = true; ++ layout.width = dim.width; ++ layout.height = dim.height; ++ } ++ return true; ++ }; ++ WrapGridLayoutManager.prototype.setMaxBounds = function (itemDim) { ++ if (this._isHorizontal) { ++ itemDim.height = Math.min(this._window.height, itemDim.height); ++ } ++ else { ++ itemDim.width = Math.min(this._window.width, itemDim.width); ++ } ++ }; ++ //TODO:Talha laziliy calculate in future revisions ++ WrapGridLayoutManager.prototype.relayoutFromIndex = function (startIndex, itemCount) { ++ startIndex = this._locateFirstNeighbourIndex(startIndex); ++ var startX = 0; ++ var startY = 0; ++ var maxBound = 0; ++ var startVal = this._layouts[startIndex]; ++ if (startVal) { ++ startX = startVal.x; ++ startY = startVal.y; ++ this._pointDimensionsToRect(startVal); ++ } ++ var oldItemCount = this._layouts.length; ++ var itemDim = { height: 0, width: 0 }; ++ var itemRect = null; ++ var oldLayout = null; ++ for (var i = startIndex; i < itemCount; i++) { ++ oldLayout = this._layouts[i]; ++ var layoutType = this._layoutProvider.getLayoutTypeForIndex(i); ++ if (oldLayout && oldLayout.isOverridden && oldLayout.type === layoutType) { ++ itemDim.height = oldLayout.height; ++ itemDim.width = oldLayout.width; ++ } ++ else { ++ this._layoutProvider.setComputedLayout(layoutType, itemDim, i); ++ } ++ this.setMaxBounds(itemDim); ++ while (!this._checkBounds(startX, startY, itemDim, this._isHorizontal)) { ++ if (this._isHorizontal) { ++ startX += maxBound; ++ startY = 0; ++ this._totalWidth += maxBound; ++ } ++ else { ++ startX = 0; ++ startY += maxBound; ++ this._totalHeight += maxBound; ++ } ++ maxBound = 0; ++ } ++ maxBound = this._isHorizontal ? Math.max(maxBound, itemDim.width) : Math.max(maxBound, itemDim.height); ++ //TODO: Talha creating array upfront will speed this up ++ if (i > oldItemCount - 1) { ++ this._layouts.push({ x: startX, y: startY, height: itemDim.height, width: itemDim.width, type: layoutType }); ++ } ++ else { ++ itemRect = this._layouts[i]; ++ itemRect.x = startX; ++ itemRect.y = startY; ++ itemRect.type = layoutType; ++ itemRect.width = itemDim.width; ++ itemRect.height = itemDim.height; ++ } ++ if (this._isHorizontal) { ++ startY += itemDim.height; ++ } ++ else { ++ startX += itemDim.width; ++ } ++ } ++ if (oldItemCount > itemCount) { ++ this._layouts.splice(itemCount, oldItemCount - itemCount); ++ } ++ this._setFinalDimensions(maxBound); ++ }; ++ WrapGridLayoutManager.prototype._pointDimensionsToRect = function (itemRect) { ++ if (this._isHorizontal) { ++ this._totalWidth = itemRect.x; ++ } ++ else { ++ this._totalHeight = itemRect.y; ++ } ++ }; ++ WrapGridLayoutManager.prototype._setFinalDimensions = function (maxBound) { ++ if (this._isHorizontal) { ++ this._totalHeight = this._window.height; ++ this._totalWidth += maxBound; ++ } ++ else { ++ this._totalWidth = this._window.width; ++ this._totalHeight += maxBound; ++ } ++ }; ++ WrapGridLayoutManager.prototype._locateFirstNeighbourIndex = function (startIndex) { ++ if (startIndex === 0) { ++ return 0; ++ } ++ var i = startIndex - 1; ++ for (; i >= 0; i--) { ++ if (!this._layouts[i]) { ++ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line ++ continue; ++ } ++ if (this._isHorizontal) { ++ if (this._layouts[i].y === 0) { ++ break; ++ } ++ } ++ else if (this._layouts[i].x === 0) { ++ break; ++ } ++ } ++ return i; ++ }; ++ WrapGridLayoutManager.prototype._checkBounds = function (itemX, itemY, itemDim, isHorizontal) { ++ return isHorizontal ? (itemY + itemDim.height <= this._window.height) : (itemX + itemDim.width <= this._window.width); ++ }; ++ return WrapGridLayoutManager; ++}(LayoutManager)); ++exports.WrapGridLayoutManager = WrapGridLayoutManager; ++//# sourceMappingURL=LayoutManager.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js.map b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js.map +new file mode 100644 +index 0000000..3129d8e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"LayoutManager.js","sourceRoot":"","sources":["../../../../src/core/layoutmanager/LayoutManager.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.d.ts b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.d.ts +new file mode 100644 +index 0000000..fbf1ac9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.d.ts +@@ -0,0 +1,21 @@ ++import * as React from "react"; ++import { Dimension } from "../dependencies/LayoutProvider"; ++import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./BaseScrollView"; ++export interface ScrollComponentProps { ++ onSizeChanged: (dimensions: Dimension) => void; ++ onScroll: (offsetX: number, offsetY: number, rawEvent: ScrollEvent) => void; ++ contentHeight: number; ++ contentWidth: number; ++ canChangeSize?: boolean; ++ externalScrollView?: { ++ new (props: ScrollViewDefaultProps): BaseScrollView; ++ }; ++ isHorizontal?: boolean; ++ renderFooter?: () => JSX.Element | JSX.Element[] | null; ++ scrollThrottle?: number; ++ useWindowScroll?: boolean; ++ onLayout?: any; ++} ++export default abstract class BaseScrollComponent extends React.Component { ++ abstract scrollTo(x: number, y: number, animate: boolean): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js +new file mode 100644 +index 0000000..821b8f8 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js +@@ -0,0 +1,25 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollComponent = /** @class */ (function (_super) { ++ __extends(BaseScrollComponent, _super); ++ function BaseScrollComponent() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ return BaseScrollComponent; ++}(React.Component)); ++exports.default = BaseScrollComponent; ++//# sourceMappingURL=BaseScrollComponent.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js.map b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js.map +new file mode 100644 +index 0000000..1be170f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BaseScrollComponent.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAiB/B;IAA0D,uCAAyC;IAAnG;;IAEA,CAAC;IAAD,0BAAC;AAAD,CAAC,AAFD,CAA0D,KAAK,CAAC,SAAS,GAExE"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.d.ts b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.d.ts +new file mode 100644 +index 0000000..d29def1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.d.ts +@@ -0,0 +1,29 @@ ++import * as React from "react"; ++import { CSSProperties } from "react"; ++import { Dimension } from "../dependencies/LayoutProvider"; ++export interface ScrollViewDefaultProps { ++ onScroll: (event: ScrollEvent) => void; ++ onSizeChanged: (dimensions: Dimension) => void; ++ horizontal: boolean; ++ canChangeSize: boolean; ++ style?: CSSProperties | null; ++ useWindowScroll: boolean; ++} ++export interface ScrollEvent { ++ nativeEvent: { ++ contentOffset: { ++ x: number; ++ y: number; ++ }; ++ layoutMeasurement?: Dimension; ++ contentSize?: Dimension; ++ }; ++} ++export default abstract class BaseScrollView extends React.Component { ++ constructor(props: ScrollViewDefaultProps); ++ abstract scrollTo(scrollInput: { ++ x: number; ++ y: number; ++ animated: boolean; ++ }): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js +new file mode 100644 +index 0000000..694e0ae +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js +@@ -0,0 +1,25 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollView = /** @class */ (function (_super) { ++ __extends(BaseScrollView, _super); ++ function BaseScrollView(props) { ++ return _super.call(this, props) || this; ++ } ++ return BaseScrollView; ++}(React.Component)); ++exports.default = BaseScrollView; ++//# sourceMappingURL=BaseScrollView.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js.map b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js.map +new file mode 100644 +index 0000000..4230976 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BaseScrollView.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAsB/B;IAAqD,kCAA2C;IAC5F,wBAAY,KAA6B;eACrC,kBAAM,KAAK,CAAC;IAChB,CAAC;IAGL,qBAAC;AAAD,CAAC,AAND,CAAqD,KAAK,CAAC,SAAS,GAMnE"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.d.ts b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.d.ts +new file mode 100644 +index 0000000..a7af807 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.d.ts +@@ -0,0 +1,13 @@ ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; ++export default class StickyFooter

extends StickyObject { ++ constructor(props: P, context?: any); ++ protected initStickyParams(): void; ++ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, _smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; ++ protected getNextYd(nextY: number, nextHeight: number): number; ++ protected getCurrentYd(currentY: number, currentHeight: number): number; ++ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; ++ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js +new file mode 100644 +index 0000000..1a1b02f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js +@@ -0,0 +1,70 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var StickyObject_1 = require("./StickyObject"); ++var BinarySearch_1 = require("../../utils/BinarySearch"); ++var StickyFooter = /** @class */ (function (_super) { ++ __extends(StickyFooter, _super); ++ function StickyFooter(props, context) { ++ return _super.call(this, props, context) || this; ++ } ++ StickyFooter.prototype.initStickyParams = function () { ++ this.stickyType = StickyObject_1.StickyType.FOOTER; ++ this.stickyTypeMultiplier = -1; ++ this.containerPosition = { bottom: 0 }; ++ this.bounceScrolling = false; ++ }; ++ StickyFooter.prototype.calculateVisibleStickyIndex = function (stickyIndices, _smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow, windowBound) { ++ if (stickyIndices && largestVisibleIndex) { ++ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); ++ if (largestVisibleIndex > stickyIndices[stickyIndices.length - 1] || this.bounceScrolling) { ++ this.stickyVisiblity = false; ++ } ++ else { ++ this.stickyVisiblity = true; ++ var valueAndIndex = BinarySearch_1.default.findValueLargerThanTarget(stickyIndices, largestVisibleIndex); ++ if (valueAndIndex) { ++ this.currentIndex = valueAndIndex.index; ++ this.currentStickyIndex = valueAndIndex.value; ++ } ++ else { ++ console.log("Footer sticky index calculation gone wrong."); //tslint:disable-line ++ } ++ } ++ } ++ }; ++ StickyFooter.prototype.getNextYd = function (nextY, nextHeight) { ++ return -1 * (nextY + nextHeight); ++ }; ++ StickyFooter.prototype.getCurrentYd = function (currentY, currentHeight) { ++ return -1 * (currentY + currentHeight); ++ }; ++ StickyFooter.prototype.getScrollY = function (offsetY, scrollableHeight) { ++ return scrollableHeight ? -1 * (offsetY + scrollableHeight) : undefined; ++ }; ++ StickyFooter.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, windowBound) { ++ if (windowBound) { ++ var endReachedMargin = Math.round(offsetY - (windowBound + distanceFromWindow)); ++ return endReachedMargin >= 0; ++ } ++ return false; ++ }; ++ return StickyFooter; ++}(StickyObject_1.default)); ++exports.default = StickyFooter; ++//# sourceMappingURL=StickyFooter.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js.map b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js.map +new file mode 100644 +index 0000000..1c899a7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyFooter.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyFooter.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAC,MAAM,EAAE,CAAC,EAAC,CAAC;QACrC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IACjC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,qBAA6B,EAAE,mBAA2B,EAC/F,OAAe,EAAE,kBAA0B,EAAE,WAAqB;QAElE,IAAI,aAAa,IAAI,mBAAmB,EAAE;YACtC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;YACzF,IAAI,mBAAmB,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACvF,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,yBAAyB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;gBAC5H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC;IACrC,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC;IAC3C,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,WAAoB;QAC1F,IAAI,WAAW,EAAE;YACb,IAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC;YAClF,OAAO,gBAAgB,IAAI,CAAC,CAAC;SAChC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IACL,mBAAC;AAAD,CAAC,AApDD,CAAoG,sBAAY,GAoD/G"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.d.ts b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.d.ts +new file mode 100644 +index 0000000..08481a0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.d.ts +@@ -0,0 +1,13 @@ ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; ++export default class StickyHeader

extends StickyObject { ++ constructor(props: P, context?: any); ++ protected initStickyParams(): void; ++ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number): void; ++ protected getNextYd(nextY: number, nextHeight: number): number; ++ protected getCurrentYd(currentY: number, currentHeight: number): number; ++ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; ++ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, _windowBound?: number): boolean; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js +new file mode 100644 +index 0000000..5e72f6e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js +@@ -0,0 +1,68 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var StickyObject_1 = require("./StickyObject"); ++var BinarySearch_1 = require("../../utils/BinarySearch"); ++var StickyHeader = /** @class */ (function (_super) { ++ __extends(StickyHeader, _super); ++ function StickyHeader(props, context) { ++ return _super.call(this, props, context) || this; ++ } ++ StickyHeader.prototype.initStickyParams = function () { ++ this.stickyType = StickyObject_1.StickyType.HEADER; ++ this.stickyTypeMultiplier = 1; ++ this.containerPosition = { top: 0 }; ++ // Kept as true contrary to as in StickyFooter because in case of initialOffset not given, onScroll isn't called and boundaryProcessing isn't done. ++ // Default behaviour in that case will be sticky header hidden. ++ this.bounceScrolling = true; ++ }; ++ StickyHeader.prototype.calculateVisibleStickyIndex = function (stickyIndices, smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow) { ++ if (stickyIndices && smallestVisibleIndex !== undefined) { ++ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow); ++ if (smallestVisibleIndex < stickyIndices[0] || this.bounceScrolling) { ++ this.stickyVisiblity = false; ++ } ++ else { ++ this.stickyVisiblity = true; ++ var valueAndIndex = BinarySearch_1.default.findValueSmallerThanTarget(stickyIndices, smallestVisibleIndex); ++ if (valueAndIndex) { ++ this.currentIndex = valueAndIndex.index; ++ this.currentStickyIndex = valueAndIndex.value; ++ } ++ else { ++ console.log("Header sticky index calculation gone wrong."); //tslint:disable-line ++ } ++ } ++ } ++ }; ++ StickyHeader.prototype.getNextYd = function (nextY, nextHeight) { ++ return nextY; ++ }; ++ StickyHeader.prototype.getCurrentYd = function (currentY, currentHeight) { ++ return currentY; ++ }; ++ StickyHeader.prototype.getScrollY = function (offsetY, scrollableHeight) { ++ return offsetY; ++ }; ++ StickyHeader.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, _windowBound) { ++ return offsetY < distanceFromWindow; ++ }; ++ return StickyHeader; ++}(StickyObject_1.default)); ++exports.default = StickyHeader; ++//# sourceMappingURL=StickyHeader.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js.map b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js.map +new file mode 100644 +index 0000000..aef0aaa +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyHeader.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyHeader.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,iBAAiB,GAAG,EAAC,GAAG,EAAE,CAAC,EAAC,CAAC;QAElC,mJAAmJ;QACnJ,+DAA+D;QAC/D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAChC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,oBAA4B,EAAE,mBAA2B,EAAE,OAAe,EAAE,kBAA0B;QAE3I,IAAI,aAAa,IAAI,oBAAoB,KAAK,SAAS,EAAE;YACrD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC5E,IAAI,oBAAoB,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACjE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,0BAA0B,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;gBAC9H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,QAAQ,CAAC;IACpB,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,OAAO,CAAC;IACnB,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,YAAqB;QAC3F,OAAO,OAAO,GAAG,kBAAkB,CAAC;IACxC,CAAC;IACL,mBAAC;AAAD,CAAC,AAlDD,CAAoG,sBAAY,GAkD/G"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.d.ts b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.d.ts +new file mode 100644 +index 0000000..ed5976f +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.d.ts +@@ -0,0 +1,74 @@ ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++import * as React from "react"; ++import { StyleProp, ViewStyle } from "react-native"; ++import { Layout } from "../layoutmanager/LayoutManager"; ++import { Dimension } from "../dependencies/LayoutProvider"; ++export declare enum StickyType { ++ HEADER = 0, ++ FOOTER = 1 ++} ++export interface StickyObjectProps { ++ stickyIndices: number[] | undefined; ++ getLayoutForIndex: (index: number) => Layout | undefined; ++ getDataForIndex: (index: number) => any; ++ getLayoutTypeForIndex: (index: number) => string | number; ++ getExtendedState: () => object | undefined; ++ getRLVRenderedSize: () => Dimension | undefined; ++ getContentDimension: () => Dimension | undefined; ++ getRowRenderer: () => ((type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null); ++ getDistanceFromWindow: () => number; ++ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++} ++export interface StickyObjectState { ++ visibility: boolean; ++} ++export default abstract class StickyObject

extends React.Component { ++ protected stickyType: StickyType; ++ protected stickyTypeMultiplier: number; ++ protected stickyVisiblity: boolean; ++ protected visibility: boolean; ++ protected containerPosition: StyleProp; ++ protected currentIndex: number; ++ protected currentStickyIndex: number; ++ protected visibleIndices: number[]; ++ protected bounceScrolling: boolean; ++ private _previousLayout; ++ private _previousHeight; ++ private _nextLayout; ++ private _nextY; ++ private _nextHeight; ++ private _currentLayout; ++ private _currentY; ++ private _currentHeight; ++ private _nextYd; ++ private _currentYd; ++ private _scrollableHeight; ++ private _scrollableWidth; ++ private _windowBound; ++ private _stickyViewOffset; ++ private _previousStickyIndex; ++ private _nextStickyIndex; ++ private _firstCompute; ++ private _smallestVisibleIndex; ++ private _largestVisibleIndex; ++ private _offsetY; ++ constructor(props: P, context?: any); ++ componentWillReceiveProps(newProps: StickyObjectProps): void; ++ render(): JSX.Element | null; ++ onVisibleIndicesChanged(all: number[]): void; ++ onScroll(offsetY: number): void; ++ protected abstract hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; ++ protected abstract initStickyParams(): void; ++ protected abstract calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; ++ protected abstract getNextYd(_nextY: number, nextHeight: number): number; ++ protected abstract getCurrentYd(currentY: number, currentHeight: number): number; ++ protected abstract getScrollY(offsetY: number, scrollableHeight?: number): number | undefined; ++ protected stickyViewVisible(_visible: boolean): void; ++ protected boundaryProcessing(offsetY: number, distanceFromWindow: number, windowBound?: number): void; ++ private _initParams; ++ private _computeLayouts; ++ private _setSmallestAndLargestVisibleIndices; ++ private _renderSticky; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js +new file mode 100644 +index 0000000..4964223 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js +@@ -0,0 +1,203 @@ ++"use strict"; ++/** ++ * Created by ananya.chandra on 20/09/18. ++ */ ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var react_native_1 = require("react-native"); ++var RecyclerListViewExceptions_1 = require("../exceptions/RecyclerListViewExceptions"); ++var CustomError_1 = require("../exceptions/CustomError"); ++var StickyType; ++(function (StickyType) { ++ StickyType[StickyType["HEADER"] = 0] = "HEADER"; ++ StickyType[StickyType["FOOTER"] = 1] = "FOOTER"; ++})(StickyType = exports.StickyType || (exports.StickyType = {})); ++var StickyObject = /** @class */ (function (_super) { ++ __extends(StickyObject, _super); ++ function StickyObject(props, context) { ++ var _this = _super.call(this, props, context) || this; ++ _this.stickyType = StickyType.HEADER; ++ _this.stickyTypeMultiplier = 1; ++ _this.stickyVisiblity = false; ++ _this.visibility = false; ++ _this.currentIndex = 0; ++ _this.currentStickyIndex = 0; ++ _this.visibleIndices = []; ++ _this.bounceScrolling = false; ++ _this._stickyViewOffset = new react_native_1.Animated.Value(0); ++ _this._previousStickyIndex = 0; ++ _this._nextStickyIndex = 0; ++ _this._firstCompute = true; ++ _this._smallestVisibleIndex = 0; ++ _this._largestVisibleIndex = 0; ++ _this._offsetY = 0; ++ _this.state = { ++ visibility: true, ++ }; ++ return _this; ++ } ++ StickyObject.prototype.componentWillReceiveProps = function (newProps) { ++ this._initParams(); ++ this.calculateVisibleStickyIndex(newProps.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, newProps.getDistanceFromWindow(), this._windowBound); ++ this._computeLayouts(newProps.stickyIndices); ++ this.stickyViewVisible(this.stickyVisiblity); ++ }; ++ StickyObject.prototype.render = function () { ++ return (React.createElement(react_native_1.Animated.View, { style: [ ++ { position: "absolute", width: this._scrollableWidth, transform: [{ translateY: this._stickyViewOffset }] }, ++ this.containerPosition, ++ ] }, this.visibility ? ++ this._renderSticky() ++ : null)); ++ }; ++ StickyObject.prototype.onVisibleIndicesChanged = function (all) { ++ if (this._firstCompute) { ++ this.initStickyParams(); ++ this._firstCompute = false; ++ } ++ this._initParams(); ++ this._setSmallestAndLargestVisibleIndices(all); ++ this.calculateVisibleStickyIndex(this.props.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, this.props.getDistanceFromWindow(), this._windowBound); ++ this._computeLayouts(); ++ this.stickyViewVisible(this.stickyVisiblity); ++ }; ++ StickyObject.prototype.onScroll = function (offsetY) { ++ var prevVisibility = this.visibility; ++ if (offsetY < 0 && prevVisibility === true || this._smallestVisibleIndex < this.currentStickyIndex) { ++ this.visibility = false; ++ } ++ else if (offsetY >= 0 && prevVisibility === false) { ++ this.visibility = true; ++ } ++ if (prevVisibility !== this.visibility) { ++ this.render(); ++ } ++ this._initParams(); ++ this._offsetY = offsetY; ++ this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); ++ if (this._previousStickyIndex !== undefined) { ++ if (this._previousStickyIndex * this.stickyTypeMultiplier >= this.currentStickyIndex * this.stickyTypeMultiplier) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); ++ } ++ var scrollY_1 = this.getScrollY(offsetY, this._scrollableHeight); ++ if (this._previousHeight && this._currentYd && scrollY_1 && scrollY_1 < this._currentYd) { ++ if (scrollY_1 > this._currentYd - this._previousHeight) { ++ this.currentIndex -= this.stickyTypeMultiplier; ++ var translate = (scrollY_1 - this._currentYd + this._previousHeight) * (-1 * this.stickyTypeMultiplier); ++ this._stickyViewOffset.setValue(translate); ++ this._computeLayouts(); ++ this.stickyViewVisible(true); ++ } ++ } ++ else { ++ this._stickyViewOffset.setValue(0); ++ } ++ } ++ if (this._nextStickyIndex !== undefined) { ++ if (this._nextStickyIndex * this.stickyTypeMultiplier <= this.currentStickyIndex * this.stickyTypeMultiplier) { ++ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); ++ } ++ var scrollY_2 = this.getScrollY(offsetY, this._scrollableHeight); ++ if (this._currentHeight && this._nextYd && scrollY_2 && scrollY_2 + this._currentHeight > this._nextYd) { ++ if (scrollY_2 <= this._nextYd) { ++ var translate = (scrollY_2 - this._nextYd + this._currentHeight) * (-1 * this.stickyTypeMultiplier); ++ this._stickyViewOffset.setValue(translate); ++ } ++ else if (scrollY_2 > this._nextYd) { ++ this.currentIndex += this.stickyTypeMultiplier; ++ this._stickyViewOffset.setValue(0); ++ this._computeLayouts(); ++ this.stickyViewVisible(true); ++ } ++ } ++ else { ++ this._stickyViewOffset.setValue(0); ++ } ++ } ++ }; ++ StickyObject.prototype.stickyViewVisible = function (_visible) { ++ this.setState({ ++ visibility: _visible, ++ }); ++ }; ++ StickyObject.prototype.boundaryProcessing = function (offsetY, distanceFromWindow, windowBound) { ++ var hasReachedBoundary = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); ++ if (this.bounceScrolling !== hasReachedBoundary) { ++ this.bounceScrolling = hasReachedBoundary; ++ if (this.bounceScrolling) { ++ this.stickyViewVisible(false); ++ } ++ else { ++ this.onVisibleIndicesChanged(this.visibleIndices); ++ } ++ } ++ }; ++ StickyObject.prototype._initParams = function () { ++ var rlvDimension = this.props.getRLVRenderedSize(); ++ if (rlvDimension) { ++ this._scrollableHeight = rlvDimension.height; ++ this._scrollableWidth = rlvDimension.width; ++ } ++ var contentDimension = this.props.getContentDimension(); ++ if (contentDimension && this._scrollableHeight) { ++ this._windowBound = contentDimension.height - this._scrollableHeight; ++ } ++ }; ++ StickyObject.prototype._computeLayouts = function (newStickyIndices) { ++ var stickyIndices = newStickyIndices ? newStickyIndices : this.props.stickyIndices; ++ if (stickyIndices) { ++ this.currentStickyIndex = stickyIndices[this.currentIndex]; ++ this._previousStickyIndex = stickyIndices[this.currentIndex - this.stickyTypeMultiplier]; ++ this._nextStickyIndex = stickyIndices[this.currentIndex + this.stickyTypeMultiplier]; ++ if (this.currentStickyIndex !== undefined) { ++ this._currentLayout = this.props.getLayoutForIndex(this.currentStickyIndex); ++ this._currentY = this._currentLayout ? this._currentLayout.y : undefined; ++ this._currentHeight = this._currentLayout ? this._currentLayout.height : undefined; ++ this._currentYd = this._currentY && this._currentHeight ? this.getCurrentYd(this._currentY, this._currentHeight) : undefined; ++ } ++ if (this._previousStickyIndex !== undefined) { ++ this._previousLayout = this.props.getLayoutForIndex(this._previousStickyIndex); ++ this._previousHeight = this._previousLayout ? this._previousLayout.height : undefined; ++ } ++ if (this._nextStickyIndex !== undefined) { ++ this._nextLayout = this.props.getLayoutForIndex(this._nextStickyIndex); ++ this._nextY = this._nextLayout ? this._nextLayout.y : undefined; ++ this._nextHeight = this._nextLayout ? this._nextLayout.height : undefined; ++ this._nextYd = this._nextY && this._nextHeight ? this.getNextYd(this._nextY, this._nextHeight) : undefined; ++ } ++ } ++ }; ++ StickyObject.prototype._setSmallestAndLargestVisibleIndices = function (indicesArray) { ++ this.visibleIndices = indicesArray; ++ this._smallestVisibleIndex = indicesArray[0]; ++ this._largestVisibleIndex = indicesArray[indicesArray.length - 1]; ++ }; ++ StickyObject.prototype._renderSticky = function () { ++ var _stickyData = this.props.getDataForIndex(this.currentStickyIndex); ++ var _stickyLayoutType = this.props.getLayoutTypeForIndex(this.currentStickyIndex); ++ var _extendedState = this.props.getExtendedState(); ++ var _rowRenderer = this.props.getRowRenderer(); ++ if (this.props.overrideRowRenderer) { ++ return this.props.overrideRowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); ++ } ++ else { ++ return _rowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); ++ } ++ }; ++ return StickyObject; ++}(React.Component)); ++exports.default = StickyObject; ++//# sourceMappingURL=StickyObject.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js.map b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js.map +new file mode 100644 +index 0000000..82b71ae +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"StickyObject.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyObject.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.d.ts b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.d.ts +new file mode 100644 +index 0000000..400f352 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.d.ts +@@ -0,0 +1,37 @@ ++import * as React from "react"; ++import { Dimension, BaseLayoutProvider } from "../dependencies/LayoutProvider"; ++import ItemAnimator from "../ItemAnimator"; ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++export interface ViewRendererProps { ++ x: number; ++ y: number; ++ height: number; ++ width: number; ++ childRenderer: (type: string | number, data: T, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; ++ layoutType: string | number; ++ dataHasChanged: (r1: T, r2: T) => boolean; ++ onSizeChanged: (dim: Dimension, index: number) => void; ++ data: any; ++ index: number; ++ itemAnimator: ItemAnimator; ++ styleOverrides?: object; ++ forceNonDeterministicRendering?: boolean; ++ isHorizontal?: boolean; ++ extendedState?: object; ++ internalSnapshot?: object; ++ layoutProvider?: BaseLayoutProvider; ++} ++export default abstract class BaseViewRenderer extends React.Component, {}> { ++ protected animatorStyleOverrides: object | undefined; ++ shouldComponentUpdate(newProps: ViewRendererProps): boolean; ++ componentDidMount(): void; ++ componentWillMount(): void; ++ componentWillUnmount(): void; ++ protected abstract getRef(): object | null; ++ protected renderChild(): JSX.Element | JSX.Element[] | null; ++} +diff --git a/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js +new file mode 100644 +index 0000000..f584ea7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js +@@ -0,0 +1,55 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseViewRenderer = /** @class */ (function (_super) { ++ __extends(BaseViewRenderer, _super); ++ function BaseViewRenderer() { ++ return _super !== null && _super.apply(this, arguments) || this; ++ } ++ BaseViewRenderer.prototype.shouldComponentUpdate = function (newProps) { ++ var hasMoved = this.props.x !== newProps.x || this.props.y !== newProps.y; ++ var hasSizeChanged = !newProps.forceNonDeterministicRendering && ++ (this.props.width !== newProps.width || this.props.height !== newProps.height) || ++ this.props.layoutProvider !== newProps.layoutProvider; ++ var hasExtendedStateChanged = this.props.extendedState !== newProps.extendedState; ++ var hasInternalSnapshotChanged = this.props.internalSnapshot !== newProps.internalSnapshot; ++ var hasDataChanged = (this.props.dataHasChanged && this.props.dataHasChanged(this.props.data, newProps.data)); ++ var shouldUpdate = hasSizeChanged || hasDataChanged || hasExtendedStateChanged || hasInternalSnapshotChanged; ++ if (shouldUpdate) { ++ newProps.itemAnimator.animateWillUpdate(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); ++ } ++ else if (hasMoved) { ++ shouldUpdate = !newProps.itemAnimator.animateShift(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); ++ } ++ return shouldUpdate; ++ }; ++ BaseViewRenderer.prototype.componentDidMount = function () { ++ this.animatorStyleOverrides = undefined; ++ this.props.itemAnimator.animateDidMount(this.props.x, this.props.y, this.getRef(), this.props.index); ++ }; ++ BaseViewRenderer.prototype.componentWillMount = function () { ++ this.animatorStyleOverrides = this.props.itemAnimator.animateWillMount(this.props.x, this.props.y, this.props.index); ++ }; ++ BaseViewRenderer.prototype.componentWillUnmount = function () { ++ this.props.itemAnimator.animateWillUnmount(this.props.x, this.props.y, this.getRef(), this.props.index); ++ }; ++ BaseViewRenderer.prototype.renderChild = function () { ++ return this.props.childRenderer(this.props.layoutType, this.props.data, this.props.index, this.props.extendedState); ++ }; ++ return BaseViewRenderer; ++}(React.Component)); ++exports.default = BaseViewRenderer; ++//# sourceMappingURL=BaseViewRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js.map b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js.map +new file mode 100644 +index 0000000..451d377 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BaseViewRenderer.js","sourceRoot":"","sources":["../../../../src/core/viewrenderer/BaseViewRenderer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/index.d.ts b/node_modules/recyclerlistview/dist/web/index.d.ts +new file mode 100644 +index 0000000..230e231 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/index.d.ts +@@ -0,0 +1,11 @@ ++import ContextProvider from "./core/dependencies/ContextProvider"; ++import DataProvider, { BaseDataProvider } from "./core/dependencies/DataProvider"; ++import { BaseLayoutProvider, Dimension, LayoutProvider } from "./core/dependencies/LayoutProvider"; ++import RecyclerListView, { OnRecreateParams } from "./core/RecyclerListView"; ++import BaseScrollView from "./core/scrollcomponent/BaseScrollView"; ++import { BaseItemAnimator } from "./core/ItemAnimator"; ++import { AutoScroll } from "./utils/AutoScroll"; ++import { Layout, LayoutManager, Point, WrapGridLayoutManager } from "./core/layoutmanager/LayoutManager"; ++import ProgressiveListView from "./core/ProgressiveListView"; ++import { DebugHandlers } from "./core/devutils/debughandlers/DebugHandlers"; ++export { ContextProvider, DataProvider, LayoutProvider, BaseLayoutProvider, LayoutManager, WrapGridLayoutManager, RecyclerListView, ProgressiveListView, BaseItemAnimator, BaseScrollView, AutoScroll, Dimension, Point, Layout, OnRecreateParams, DebugHandlers, BaseDataProvider, }; +diff --git a/node_modules/recyclerlistview/dist/web/index.js b/node_modules/recyclerlistview/dist/web/index.js +new file mode 100644 +index 0000000..2faf787 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/index.js +@@ -0,0 +1,24 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ContextProvider_1 = require("./core/dependencies/ContextProvider"); ++exports.ContextProvider = ContextProvider_1.default; ++var DataProvider_1 = require("./core/dependencies/DataProvider"); ++exports.DataProvider = DataProvider_1.default; ++exports.BaseDataProvider = DataProvider_1.BaseDataProvider; ++var LayoutProvider_1 = require("./core/dependencies/LayoutProvider"); ++exports.BaseLayoutProvider = LayoutProvider_1.BaseLayoutProvider; ++exports.LayoutProvider = LayoutProvider_1.LayoutProvider; ++var RecyclerListView_1 = require("./core/RecyclerListView"); ++exports.RecyclerListView = RecyclerListView_1.default; ++var BaseScrollView_1 = require("./core/scrollcomponent/BaseScrollView"); ++exports.BaseScrollView = BaseScrollView_1.default; ++var ItemAnimator_1 = require("./core/ItemAnimator"); ++exports.BaseItemAnimator = ItemAnimator_1.BaseItemAnimator; ++var AutoScroll_1 = require("./utils/AutoScroll"); ++exports.AutoScroll = AutoScroll_1.AutoScroll; ++var LayoutManager_1 = require("./core/layoutmanager/LayoutManager"); ++exports.LayoutManager = LayoutManager_1.LayoutManager; ++exports.WrapGridLayoutManager = LayoutManager_1.WrapGridLayoutManager; ++var ProgressiveListView_1 = require("./core/ProgressiveListView"); ++exports.ProgressiveListView = ProgressiveListView_1.default; ++//# sourceMappingURL=index.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/index.js.map b/node_modules/recyclerlistview/dist/web/index.js.map +new file mode 100644 +index 0000000..9e60fb9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/index.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;AAAA,uEAAkE;AAY9D,0BAZG,yBAAe,CAYH;AAXnB,iEAAkF;AAY9E,uBAZG,sBAAY,CAYH;AAeZ,2BA3BmB,+BAAgB,CA2BnB;AA1BpB,qEAAmG;AAa/F,6BAbK,mCAAkB,CAaL;AADlB,yBAZoC,+BAAc,CAYpC;AAXlB,4DAA6E;AAezE,2BAfG,0BAAgB,CAeH;AAdpB,wEAAmE;AAiB/D,yBAjBG,wBAAc,CAiBH;AAhBlB,oDAAuD;AAenD,2BAfK,+BAAgB,CAeL;AAdpB,iDAAgD;AAgB5C,qBAhBK,uBAAU,CAgBL;AAfd,oEAAyG;AASrG,wBATa,6BAAa,CASb;AACb,gCAVmC,qCAAqB,CAUnC;AATzB,kEAA6D;AAWzD,8BAXG,6BAAmB,CAWH"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts +new file mode 100644 +index 0000000..693e3a0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts +@@ -0,0 +1,12 @@ ++import { BaseItemAnimator } from "../../../core/ItemAnimator"; ++export declare class DefaultNativeItemAnimator implements BaseItemAnimator { ++ shouldAnimateOnce: boolean; ++ private _hasAnimatedOnce; ++ private _isTimerOn; ++ constructor(); ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js +new file mode 100644 +index 0000000..9ac03d1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js +@@ -0,0 +1,48 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var react_native_1 = require("react-native"); ++var DefaultNativeItemAnimator = /** @class */ (function () { ++ function DefaultNativeItemAnimator() { ++ this.shouldAnimateOnce = true; ++ this._hasAnimatedOnce = false; ++ this._isTimerOn = false; ++ if (react_native_1.Platform.OS === "android" && react_native_1.UIManager.setLayoutAnimationEnabledExperimental) { ++ react_native_1.UIManager.setLayoutAnimationEnabledExperimental(true); ++ } ++ } ++ DefaultNativeItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ DefaultNativeItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ DefaultNativeItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ this._hasAnimatedOnce = true; ++ }; ++ DefaultNativeItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ var _this = this; ++ if (fromX !== toX || fromY !== toY) { ++ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { ++ react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut); ++ this._hasAnimatedOnce = true; ++ } ++ } ++ else { ++ if (!this._isTimerOn) { ++ this._isTimerOn = true; ++ if (!this._hasAnimatedOnce) { ++ setTimeout(function () { ++ _this._hasAnimatedOnce = true; ++ }, 1000); ++ } ++ } ++ } ++ return false; ++ }; ++ DefaultNativeItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ return DefaultNativeItemAnimator; ++}()); ++exports.DefaultNativeItemAnimator = DefaultNativeItemAnimator; ++//# sourceMappingURL=DefaultNativeItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map +new file mode 100644 +index 0000000..50ecf5a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultNativeItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/itemanimators/DefaultNativeItemAnimator.ts"],"names":[],"mappings":";;AAAA,6CAAoE;AAGpE;IAII;QAHO,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;QAEhC,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,wBAAS,CAAC,qCAAqC,EAAE;YAC9E,wBAAS,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC;SACzD;IACL,CAAC;IACM,oDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,mDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,qDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,gDAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAiBC;QAhBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,8BAAe,CAAC,aAAa,CAAC,8BAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACrE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;aAChC;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,sDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,gCAAC;AAAD,CAAC,AA1CD,IA0CC;AA1CY,8DAAyB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts +new file mode 100644 +index 0000000..e3a83b3 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts +@@ -0,0 +1,19 @@ ++import { BaseItemAnimator } from "../../../../core/ItemAnimator"; ++/** ++ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator ++ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite ++ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if ++ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is ++ * hardly customizable. ++ */ ++export declare class DefaultJSItemAnimator implements BaseItemAnimator { ++ shouldAnimateOnce: boolean; ++ private _hasAnimatedOnce; ++ private _isTimerOn; ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ private _getNativePropObject; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js +new file mode 100644 +index 0000000..1b8b812 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js +@@ -0,0 +1,77 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var react_native_1 = require("react-native"); ++var ItemAnimator_1 = require("../../../../core/ItemAnimator"); ++/** ++ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator ++ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite ++ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if ++ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is ++ * hardly customizable. ++ */ ++var DefaultJSItemAnimator = /** @class */ (function () { ++ function DefaultJSItemAnimator() { ++ this.shouldAnimateOnce = true; ++ this._hasAnimatedOnce = false; ++ this._isTimerOn = false; ++ } ++ DefaultJSItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ DefaultJSItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ DefaultJSItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ this._hasAnimatedOnce = true; ++ }; ++ DefaultJSItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ var _this = this; ++ if (fromX !== toX || fromY !== toY) { ++ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { ++ var viewRef_1 = itemRef; ++ var animXY_1 = new react_native_1.Animated.ValueXY({ x: fromX, y: fromY }); ++ animXY_1.addListener(function (value) { ++ if (viewRef_1._isUnmountedForRecyclerListView || (_this.shouldAnimateOnce && _this._hasAnimatedOnce)) { ++ animXY_1.stopAnimation(); ++ return; ++ } ++ viewRef_1.setNativeProps(_this._getNativePropObject(value.x, value.y)); ++ }); ++ if (viewRef_1._lastAnimVal) { ++ viewRef_1._lastAnimVal.stopAnimation(); ++ } ++ viewRef_1._lastAnimVal = animXY_1; ++ react_native_1.Animated.timing(animXY_1, { ++ toValue: { x: toX, y: toY }, ++ duration: 200, ++ easing: react_native_1.Easing.out(react_native_1.Easing.ease), ++ useNativeDriver: ItemAnimator_1.BaseItemAnimator.USE_NATIVE_DRIVER, ++ }).start(function () { ++ viewRef_1._lastAnimVal = null; ++ _this._hasAnimatedOnce = true; ++ }); ++ return true; ++ } ++ } ++ else { ++ if (!this._isTimerOn) { ++ this._isTimerOn = true; ++ if (!this._hasAnimatedOnce) { ++ setTimeout(function () { ++ _this._hasAnimatedOnce = true; ++ }, 1000); ++ } ++ } ++ } ++ return false; ++ }; ++ DefaultJSItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ itemRef._isUnmountedForRecyclerListView = true; ++ }; ++ DefaultJSItemAnimator.prototype._getNativePropObject = function (x, y) { ++ return { style: { left: x, top: y } }; ++ }; ++ return DefaultJSItemAnimator; ++}()); ++exports.DefaultJSItemAnimator = DefaultJSItemAnimator; ++//# sourceMappingURL=DefaultJSItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map +new file mode 100644 +index 0000000..6a6881e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultJSItemAnimator.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.ts"],"names":[],"mappings":";;AAAA,6CAAsD;AACtD,8DAAiE;AAOjE;;;;;;GAMG;AACH;IAAA;QACW,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;IA2DxC,CAAC;IA1DU,gDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,+CAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,iDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,4CAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAsCC;QArCG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,IAAM,SAAO,GAAG,OAA2B,CAAC;gBAC5C,IAAM,QAAM,GAAG,IAAI,uBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC5D,QAAM,CAAC,WAAW,CAAC,UAAC,KAAK;oBACrB,IAAI,SAAO,CAAC,+BAA+B,IAAI,CAAC,KAAI,CAAC,iBAAiB,IAAI,KAAI,CAAC,gBAAgB,CAAC,EAAE;wBAC9F,QAAM,CAAC,aAAa,EAAE,CAAC;wBACvB,OAAO;qBACV;oBACD,SAAO,CAAC,cAAc,CAAC,KAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxE,CAAC,CAAC,CAAC;gBACH,IAAI,SAAO,CAAC,YAAY,EAAE;oBACtB,SAAO,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;iBACxC;gBACD,SAAO,CAAC,YAAY,GAAG,QAAM,CAAC;gBAC9B,uBAAQ,CAAC,MAAM,CAAC,QAAM,EAAE;oBACpB,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;oBAC3B,QAAQ,EAAE,GAAG;oBACb,MAAM,EAAE,qBAAM,CAAC,GAAG,CAAC,qBAAM,CAAC,IAAI,CAAC;oBAC/B,eAAe,EAAE,+BAAgB,CAAC,iBAAiB;iBACtD,CAAC,CAAC,KAAK,CAAC;oBACL,SAAO,CAAC,YAAY,GAAG,IAAI,CAAC;oBAC5B,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACjC,CAAC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;aACf;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,kDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QACjF,OAA4B,CAAC,+BAA+B,GAAG,IAAI,CAAC;IACzE,CAAC;IAEO,oDAAoB,GAA5B,UAA6B,CAAS,EAAE,CAAS;QAC7C,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAC1C,CAAC;IACL,4BAAC;AAAD,CAAC,AA9DD,IA8DC;AA9DY,sDAAqB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts +new file mode 100644 +index 0000000..63ab9e4 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts +@@ -0,0 +1,2 @@ ++import { DefaultWebItemAnimator } from "../../../web/itemanimators/DefaultWebItemAnimator"; ++export { DefaultWebItemAnimator as DefaultJSItemAnimator }; +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js +new file mode 100644 +index 0000000..53a8a28 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js +@@ -0,0 +1,5 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var DefaultWebItemAnimator_1 = require("../../../web/itemanimators/DefaultWebItemAnimator"); ++exports.DefaultJSItemAnimator = DefaultWebItemAnimator_1.DefaultWebItemAnimator; ++//# sourceMappingURL=DefaultJSItemAnimator.web.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map +new file mode 100644 +index 0000000..ee1f03d +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultJSItemAnimator.web.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.ts"],"names":[],"mappings":";;AAAA,4FAA2F;AACxD,gCAD1B,+CAAsB,CACyB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.d.ts +new file mode 100644 +index 0000000..8e9f3e1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.d.ts +@@ -0,0 +1,26 @@ ++/// ++import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++export default class ScrollComponent extends BaseScrollComponent { ++ static defaultProps: { ++ contentHeight: number; ++ contentWidth: number; ++ externalScrollView: {}; ++ isHorizontal: boolean; ++ scrollThrottle: number; ++ }; ++ private _height; ++ private _width; ++ private _isSizeChangedCalledOnce; ++ private _scrollViewRef; ++ constructor(args: ScrollComponentProps); ++ scrollTo(x: number, y: number, isAnimated: boolean): void; ++ render(): JSX.Element; ++ private _getScrollViewRef; ++ private _onScroll; ++ private _onLayout; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js +new file mode 100644 +index 0000000..0cda95e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js +@@ -0,0 +1,102 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var react_native_1 = require("react-native"); ++var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); ++var TSCast_1 = require("../../../utils/TSCast"); ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++var ScrollComponent = /** @class */ (function (_super) { ++ __extends(ScrollComponent, _super); ++ function ScrollComponent(args) { ++ var _this = _super.call(this, args) || this; ++ _this._scrollViewRef = null; ++ _this._getScrollViewRef = function (scrollView) { _this._scrollViewRef = scrollView; }; ++ _this._onScroll = function (event) { ++ if (event) { ++ _this.props.onScroll(event.nativeEvent.contentOffset.x, event.nativeEvent.contentOffset.y, event); ++ } ++ }; ++ _this._onLayout = function (event) { ++ if (_this._height !== event.nativeEvent.layout.height || _this._width !== event.nativeEvent.layout.width) { ++ _this._height = event.nativeEvent.layout.height; ++ _this._width = event.nativeEvent.layout.width; ++ if (_this.props.onSizeChanged) { ++ _this._isSizeChangedCalledOnce = true; ++ _this.props.onSizeChanged(event.nativeEvent.layout); ++ } ++ } ++ if (_this.props.onLayout) { ++ _this.props.onLayout(event); ++ } ++ }; ++ _this._height = 0; ++ _this._width = 0; ++ _this._isSizeChangedCalledOnce = false; ++ return _this; ++ } ++ ScrollComponent.prototype.scrollTo = function (x, y, isAnimated) { ++ if (this._scrollViewRef) { ++ this._scrollViewRef.scrollTo({ x: x, y: y, animated: isAnimated }); ++ } ++ }; ++ ScrollComponent.prototype.render = function () { ++ var Scroller = TSCast_1.default.cast(this.props.externalScrollView); //TSI ++ //TODO:Talha ++ // const { ++ // useWindowScroll, ++ // contentHeight, ++ // contentWidth, ++ // externalScrollView, ++ // canChangeSize, ++ // renderFooter, ++ // isHorizontal, ++ // scrollThrottle, ++ // ...props, ++ // } = this.props; ++ return (React.createElement(Scroller, __assign({ ref: this._getScrollViewRef, removeClippedSubviews: false, scrollEventThrottle: this.props.scrollThrottle }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onLayout: (!this._isSizeChangedCalledOnce || this.props.canChangeSize) ? this._onLayout : this.props.onLayout }), ++ React.createElement(react_native_1.View, { style: { flexDirection: this.props.isHorizontal ? "row" : "column" } }, ++ React.createElement(react_native_1.View, { style: { ++ height: this.props.contentHeight, ++ width: this.props.contentWidth, ++ } }, this.props.children), ++ this.props.renderFooter ? this.props.renderFooter() : null))); ++ }; ++ ScrollComponent.defaultProps = { ++ contentHeight: 0, ++ contentWidth: 0, ++ externalScrollView: TSCast_1.default.cast(react_native_1.ScrollView), ++ isHorizontal: false, ++ scrollThrottle: 16, ++ }; ++ return ScrollComponent; ++}(BaseScrollComponent_1.default)); ++exports.default = ScrollComponent; ++//# sourceMappingURL=ScrollComponent.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js.map +new file mode 100644 +index 0000000..16bf1fd +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.d.ts +new file mode 100644 +index 0000000..fe95fc1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.d.ts +@@ -0,0 +1,16 @@ ++/// ++import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++export default class ViewRenderer extends BaseViewRenderer { ++ private _dim; ++ private _viewRef; ++ render(): JSX.Element; ++ protected getRef(): object | null; ++ private _setRef; ++ private _onLayout; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js +new file mode 100644 +index 0000000..5b56fd5 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js +@@ -0,0 +1,70 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var react_native_1 = require("react-native"); ++var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++var ViewRenderer = /** @class */ (function (_super) { ++ __extends(ViewRenderer, _super); ++ function ViewRenderer() { ++ var _this = _super !== null && _super.apply(this, arguments) || this; ++ _this._dim = { width: 0, height: 0 }; ++ _this._viewRef = null; ++ _this._setRef = function (view) { ++ _this._viewRef = view; ++ }; ++ _this._onLayout = function (event) { ++ //Preventing layout thrashing in super fast scrolls where RN messes up onLayout event ++ var xDiff = Math.abs(_this.props.x - event.nativeEvent.layout.x); ++ var yDiff = Math.abs(_this.props.y - event.nativeEvent.layout.y); ++ if (xDiff < 1 && yDiff < 1 && ++ (_this.props.height !== event.nativeEvent.layout.height || ++ _this.props.width !== event.nativeEvent.layout.width)) { ++ _this._dim.height = event.nativeEvent.layout.height; ++ _this._dim.width = event.nativeEvent.layout.width; ++ if (_this.props.onSizeChanged) { ++ _this.props.onSizeChanged(_this._dim, _this.props.index); ++ } ++ } ++ }; ++ return _this; ++ } ++ ViewRenderer.prototype.render = function () { ++ return this.props.forceNonDeterministicRendering ? (React.createElement(react_native_1.View, { ref: this._setRef, onLayout: this._onLayout, style: __assign({ flexDirection: this.props.isHorizontal ? "column" : "row", left: this.props.x, position: "absolute", top: this.props.y }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())) : (React.createElement(react_native_1.View, { ref: this._setRef, style: __assign({ left: this.props.x, position: "absolute", top: this.props.y, height: this.props.height, width: this.props.width }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())); ++ }; ++ ViewRenderer.prototype.getRef = function () { ++ return this._viewRef; ++ }; ++ return ViewRenderer; ++}(BaseViewRenderer_1.default)); ++exports.default = ViewRenderer; ++//# sourceMappingURL=ViewRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js.map +new file mode 100644 +index 0000000..ceacfb9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAC/B,6CAAuE;AAEvE,gFAAkG;AAElG;;;;;GAKG;AACH;IAA0C,gCAAqB;IAA/D;QAAA,qEAuDC;QAtDW,UAAI,GAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1C,cAAQ,GAAiE,IAAI,CAAC;QAmC9E,aAAO,GAAG,UAAC,IAAkE;YACjF,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,CAAC,CAAA;QAEO,eAAS,GAAG,UAAC,KAAwB;YACzC,qFAAqF;YACrF,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC;gBACtB,CAAC,KAAI,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;oBAClD,KAAI,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAC1D,KAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACnD,KAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;gBACjD,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;oBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAI,CAAC,IAAI,EAAE,KAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;iBACzD;aACJ;QACL,CAAC,CAAA;;IACL,CAAC;IApDU,6BAAM,GAAb;QACI,OAAO,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAC/C,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACvB,QAAQ,EAAE,IAAI,CAAC,SAAS,EACpB,KAAK,aACD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EACzD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IACd,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC,CAAC,CAAC,CACI,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACnB,KAAK,aACD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EACzB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IACpB,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC;IACV,CAAC;IAES,6BAAM,GAAhB;QACI,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAoBL,mBAAC;AAAD,CAAC,AAvDD,CAA0C,0BAAgB,GAuDzD"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts +new file mode 100644 +index 0000000..30681d9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts +@@ -0,0 +1,2 @@ ++import ViewRenderer from "../../web/viewrenderer/ViewRenderer"; ++export default ViewRenderer; +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js +new file mode 100644 +index 0000000..75c2c66 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js +@@ -0,0 +1,5 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ViewRenderer_1 = require("../../web/viewrenderer/ViewRenderer"); ++exports.default = ViewRenderer_1.default; ++//# sourceMappingURL=ViewRenderer.web.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js.map +new file mode 100644 +index 0000000..f50f385 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewRenderer.web.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.web.tsx"],"names":[],"mappings":";;AAAA,oEAA+D;AAC/D,kBAAe,sBAAY,CAAC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.d.ts +new file mode 100644 +index 0000000..1c1db85 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.d.ts +@@ -0,0 +1,15 @@ ++import { BaseItemAnimator } from "../../../core/ItemAnimator"; ++/** ++ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all ++ * shift events. ++ */ ++export declare class DefaultWebItemAnimator implements BaseItemAnimator { ++ shouldAnimateOnce: boolean; ++ private _hasAnimatedOnce; ++ private _isTimerOn; ++ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; ++ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; ++ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; ++ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js +new file mode 100644 +index 0000000..3db93b4 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js +@@ -0,0 +1,54 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++/** ++ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all ++ * shift events. ++ */ ++var DefaultWebItemAnimator = /** @class */ (function () { ++ function DefaultWebItemAnimator() { ++ this.shouldAnimateOnce = true; ++ this._hasAnimatedOnce = false; ++ this._isTimerOn = false; ++ } ++ DefaultWebItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { ++ return undefined; ++ }; ++ DefaultWebItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ DefaultWebItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ this._hasAnimatedOnce = true; ++ }; ++ DefaultWebItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { ++ var _this = this; ++ if (fromX !== toX || fromY !== toY) { ++ var element_1 = itemRef; ++ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { ++ var transitionEndCallback_1 = function (event) { ++ element_1.style.transition = ""; ++ element_1.removeEventListener("transitionend", transitionEndCallback_1); ++ _this._hasAnimatedOnce = true; ++ }; ++ element_1.style.transition = "transform 0.15s ease-out"; ++ element_1.addEventListener("transitionend", transitionEndCallback_1, false); ++ } ++ } ++ else { ++ if (!this._isTimerOn) { ++ this._isTimerOn = true; ++ if (!this._hasAnimatedOnce) { ++ setTimeout(function () { ++ _this._hasAnimatedOnce = true; ++ }, 1000); ++ } ++ } ++ } ++ return false; ++ }; ++ DefaultWebItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { ++ //no need ++ }; ++ return DefaultWebItemAnimator; ++}()); ++exports.DefaultWebItemAnimator = DefaultWebItemAnimator; ++//# sourceMappingURL=DefaultWebItemAnimator.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js.map +new file mode 100644 +index 0000000..44c688a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"DefaultWebItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/web/itemanimators/DefaultWebItemAnimator.ts"],"names":[],"mappings":";;AAEA;;;GAGG;AACH;IAAA;QACW,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;IAwCxC,CAAC;IAvCU,iDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,gDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,kDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,6CAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAuBC;QAtBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAM,SAAO,GAAG,OAAyB,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,IAAM,uBAAqB,GAAkB,UAAC,KAAK;oBAC/C,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;oBAC9B,SAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,uBAAqB,CAAC,CAAC;oBACpE,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACjC,CAAC,CAAC;gBACF,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,0BAA0B,CAAC;gBACtD,SAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,uBAAqB,EAAE,KAAK,CAAC,CAAC;aAC3E;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,mDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,6BAAC;AAAD,CAAC,AA3CD,IA2CC;AA3CY,wDAAsB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.d.ts +new file mode 100644 +index 0000000..2188791 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.d.ts +@@ -0,0 +1,26 @@ ++/// ++import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; ++import ScrollViewer from "./ScrollViewer"; ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++export default class ScrollComponent extends BaseScrollComponent { ++ static defaultProps: { ++ contentHeight: number; ++ contentWidth: number; ++ externalScrollView: typeof ScrollViewer; ++ isHorizontal: boolean; ++ scrollThrottle: number; ++ canChangeSize: boolean; ++ }; ++ private _height; ++ private _width; ++ private _scrollViewRef; ++ constructor(args: ScrollComponentProps); ++ scrollTo(x: number, y: number, animated: boolean): void; ++ render(): JSX.Element; ++ private _onScroll; ++ private _onSizeChanged; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js +new file mode 100644 +index 0000000..dca7ab7 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js +@@ -0,0 +1,82 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); ++var ScrollViewer_1 = require("./ScrollViewer"); ++/*** ++ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. ++ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide ++ * another component written on top of web elements ++ */ ++var ScrollComponent = /** @class */ (function (_super) { ++ __extends(ScrollComponent, _super); ++ function ScrollComponent(args) { ++ var _this = _super.call(this, args) || this; ++ _this._scrollViewRef = null; ++ _this._onScroll = function (e) { ++ _this.props.onScroll(e.nativeEvent.contentOffset.x, e.nativeEvent.contentOffset.y, e); ++ }; ++ _this._onSizeChanged = function (event) { ++ if (_this.props.onSizeChanged) { ++ _this.props.onSizeChanged(event); ++ } ++ }; ++ _this._height = 0; ++ _this._width = 0; ++ return _this; ++ } ++ ScrollComponent.prototype.scrollTo = function (x, y, animated) { ++ if (this._scrollViewRef) { ++ this._scrollViewRef.scrollTo({ x: x, y: y, animated: animated }); ++ } ++ }; ++ ScrollComponent.prototype.render = function () { ++ var _this = this; ++ var Scroller = this.props.externalScrollView; //TSI ++ return (React.createElement(Scroller, __assign({ ref: function (scrollView) { return _this._scrollViewRef = scrollView; } }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onSizeChanged: this._onSizeChanged }), ++ React.createElement("div", { style: { ++ height: this.props.contentHeight, ++ width: this.props.contentWidth, ++ } }, this.props.children), ++ this.props.renderFooter ? React.createElement("div", { style: this.props.isHorizontal ? { ++ left: this.props.contentWidth, ++ position: "absolute", ++ top: 0, ++ } : undefined }, this.props.renderFooter()) : null)); ++ }; ++ ScrollComponent.defaultProps = { ++ contentHeight: 0, ++ contentWidth: 0, ++ externalScrollView: ScrollViewer_1.default, ++ isHorizontal: false, ++ scrollThrottle: 16, ++ canChangeSize: false, ++ }; ++ return ScrollComponent; ++}(BaseScrollComponent_1.default)); ++exports.default = ScrollComponent; ++//# sourceMappingURL=ScrollComponent.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js.map +new file mode 100644 +index 0000000..5436601 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAE/B,yFAA8G;AAE9G,+CAA0C;AAC1C;;;;GAIG;AAEH;IAA6C,mCAAmB;IAa5D,yBAAY,IAA0B;QAAtC,YACI,kBAAM,IAAI,CAAC,SAGd;QANO,oBAAc,GAA0B,IAAI,CAAC;QAwC7C,eAAS,GAAG,UAAC,CAAc;YAC/B,KAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC,CAAA;QAEO,oBAAc,GAAG,UAAC,KAAgB;YACtC,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;gBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;aACnC;QACL,CAAC,CAAA;QA5CG,KAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,KAAI,CAAC,MAAM,GAAG,CAAC,CAAC;;IACpB,CAAC;IAEM,kCAAQ,GAAf,UAAgB,CAAS,EAAE,CAAS,EAAE,QAAiB;QACnD,IAAI,IAAI,CAAC,cAAc,EAAE;YACrB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE,QAAQ,UAAA,EAAE,CAAC,CAAC;SACpD;IACL,CAAC;IAEM,gCAAM,GAAb;QAAA,iBAwBC;QAvBG,IAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAyB,CAAC,CAAC,KAAK;QAC5D,OAAO,CACH,oBAAC,QAAQ,aAAC,GAAG,EAAE,UAAC,UAA0B,IAAK,OAAA,KAAI,CAAC,cAAc,GAAG,UAAqC,EAA3D,CAA2D,IAClG,IAAI,CAAC,KAAK,IACd,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EACnC,QAAQ,EAAE,IAAI,CAAC,SAAS,EACxB,aAAa,EAAE,IAAI,CAAC,cAAc;YAElC,6BAAK,KAAK,EAAE;oBACR,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;oBAChC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;iBACjC,IACI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAClB;YACL,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,6BAAK,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC7D,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;oBAC7B,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,CAAC;iBACT,CAAC,CAAC,CAAC,SAAS,IACR,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CACxB,CAAC,CAAC,CAAC,IAAI,CACN,CACd,CAAC;IACN,CAAC;IAhDa,4BAAY,GAAG;QACzB,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,kBAAkB,EAAE,sBAAY;QAChC,YAAY,EAAE,KAAK;QACnB,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,KAAK;KACvB,CAAC;IAoDN,sBAAC;CAAA,AA5DD,CAA6C,6BAAmB,GA4D/D;kBA5DoB,eAAe"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts +new file mode 100644 +index 0000000..5551eef +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts +@@ -0,0 +1,6 @@ ++import { ScrollEvent } from "../../../core/scrollcomponent/BaseScrollView"; ++export declare class ScrollEventNormalizer { ++ divEvent: ScrollEvent; ++ windowEvent: ScrollEvent; ++ constructor(target: HTMLDivElement); ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js +new file mode 100644 +index 0000000..d930364 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js +@@ -0,0 +1,65 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var ScrollEventNormalizer = /** @class */ (function () { ++ function ScrollEventNormalizer(target) { ++ this.divEvent = { ++ nativeEvent: { ++ contentOffset: { ++ get x() { ++ return target.scrollLeft; ++ }, ++ get y() { ++ return target.scrollTop; ++ }, ++ }, ++ contentSize: { ++ get height() { ++ return target.scrollHeight; ++ }, ++ get width() { ++ return target.scrollWidth; ++ }, ++ }, ++ layoutMeasurement: { ++ get height() { ++ return target.offsetHeight; ++ }, ++ get width() { ++ return target.offsetWidth; ++ }, ++ }, ++ }, ++ }; ++ this.windowEvent = { ++ nativeEvent: { ++ contentOffset: { ++ get x() { ++ return window.scrollX === undefined ? window.pageXOffset : window.scrollX; ++ }, ++ get y() { ++ return window.scrollY === undefined ? window.pageYOffset : window.scrollY; ++ }, ++ }, ++ contentSize: { ++ get height() { ++ return target.offsetHeight; ++ }, ++ get width() { ++ return target.offsetWidth; ++ }, ++ }, ++ layoutMeasurement: { ++ get height() { ++ return window.innerHeight; ++ }, ++ get width() { ++ return window.innerWidth; ++ }, ++ }, ++ }, ++ }; ++ } ++ return ScrollEventNormalizer; ++}()); ++exports.ScrollEventNormalizer = ScrollEventNormalizer; ++//# sourceMappingURL=ScrollEventNormalizer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js.map b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js.map +new file mode 100644 +index 0000000..52347ab +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollEventNormalizer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollEventNormalizer.ts"],"names":[],"mappings":";;AAEA;IAGI,+BAAY,MAAsB;QAC9B,IAAI,CAAC,QAAQ,GAAG;YACZ,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,SAAS,CAAC;oBAC5B,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;aACJ;SACJ,CAAC;QACF,IAAI,CAAC,WAAW,GAAG;YACf,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;iBACJ;aACJ;SACJ,CAAC;IACN,CAAC;IACL,4BAAC;AAAD,CAAC,AA7DD,IA6DC;AA7DY,sDAAqB"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.d.ts +new file mode 100644 +index 0000000..069cc18 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.d.ts +@@ -0,0 +1,38 @@ ++/// ++import BaseScrollView from "../../../core/scrollcomponent/BaseScrollView"; ++/*** ++ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. ++ * Supports both window scroll and scrollable divs inside other divs. ++ */ ++export default class ScrollViewer extends BaseScrollView { ++ static defaultProps: { ++ canChangeSize: boolean; ++ horizontal: boolean; ++ style: null; ++ useWindowScroll: boolean; ++ }; ++ private scrollEndEventSimulator; ++ private _mainDivRef; ++ private _isScrolling; ++ private _scrollEventNormalizer; ++ componentDidMount(): void; ++ componentWillUnmount(): void; ++ scrollTo(scrollInput: { ++ x: number; ++ y: number; ++ animated: boolean; ++ }): void; ++ render(): JSX.Element; ++ private _setDivRef; ++ private _getRelevantOffset; ++ private _setRelevantOffset; ++ private _isScrollEnd; ++ private _trackScrollOccurence; ++ private _doAnimatedScroll; ++ private _startListeningToDivEvents; ++ private _startListeningToWindowEvents; ++ private _onWindowResize; ++ private _windowOnScroll; ++ private _onScroll; ++ private _easeInOut; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js +new file mode 100644 +index 0000000..bdfd4e8 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js +@@ -0,0 +1,214 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseScrollView_1 = require("../../../core/scrollcomponent/BaseScrollView"); ++var debounce = require("lodash.debounce"); ++var ScrollEventNormalizer_1 = require("./ScrollEventNormalizer"); ++/*** ++ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. ++ * Supports both window scroll and scrollable divs inside other divs. ++ */ ++var ScrollViewer = /** @class */ (function (_super) { ++ __extends(ScrollViewer, _super); ++ function ScrollViewer() { ++ var _this = _super !== null && _super.apply(this, arguments) || this; ++ _this.scrollEndEventSimulator = debounce(function (executable) { ++ executable(); ++ }, 1200); ++ _this._mainDivRef = null; ++ _this._isScrolling = false; ++ _this._scrollEventNormalizer = null; ++ _this._setDivRef = function (div) { ++ _this._mainDivRef = div; ++ if (div) { ++ _this._scrollEventNormalizer = new ScrollEventNormalizer_1.ScrollEventNormalizer(div); ++ } ++ else { ++ _this._scrollEventNormalizer = null; ++ } ++ }; ++ _this._getRelevantOffset = function () { ++ if (!_this.props.useWindowScroll) { ++ if (_this._mainDivRef) { ++ if (_this.props.horizontal) { ++ return _this._mainDivRef.scrollLeft; ++ } ++ else { ++ return _this._mainDivRef.scrollTop; ++ } ++ } ++ return 0; ++ } ++ else { ++ if (_this.props.horizontal) { ++ return window.scrollX; ++ } ++ else { ++ return window.scrollY; ++ } ++ } ++ }; ++ _this._setRelevantOffset = function (offset) { ++ if (!_this.props.useWindowScroll) { ++ if (_this._mainDivRef) { ++ if (_this.props.horizontal) { ++ _this._mainDivRef.scrollLeft = offset; ++ } ++ else { ++ _this._mainDivRef.scrollTop = offset; ++ } ++ } ++ } ++ else { ++ if (_this.props.horizontal) { ++ window.scrollTo(offset, 0); ++ } ++ else { ++ window.scrollTo(0, offset); ++ } ++ } ++ }; ++ _this._isScrollEnd = function () { ++ if (_this._mainDivRef) { ++ _this._mainDivRef.style.pointerEvents = "auto"; ++ } ++ _this._isScrolling = false; ++ }; ++ _this._trackScrollOccurence = function () { ++ if (!_this._isScrolling) { ++ if (_this._mainDivRef) { ++ _this._mainDivRef.style.pointerEvents = "none"; ++ } ++ _this._isScrolling = true; ++ } ++ _this.scrollEndEventSimulator(_this._isScrollEnd); ++ }; ++ _this._onWindowResize = function () { ++ if (_this.props.onSizeChanged && _this.props.useWindowScroll) { ++ _this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); ++ } ++ }; ++ _this._windowOnScroll = function () { ++ if (_this.props.onScroll) { ++ if (_this._scrollEventNormalizer) { ++ _this.props.onScroll(_this._scrollEventNormalizer.windowEvent); ++ } ++ } ++ }; ++ _this._onScroll = function () { ++ if (_this.props.onScroll) { ++ if (_this._scrollEventNormalizer) { ++ _this.props.onScroll(_this._scrollEventNormalizer.divEvent); ++ } ++ } ++ }; ++ return _this; ++ } ++ ScrollViewer.prototype.componentDidMount = function () { ++ if (this.props.onSizeChanged) { ++ if (this.props.useWindowScroll) { ++ this._startListeningToWindowEvents(); ++ this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); ++ } ++ else if (this._mainDivRef) { ++ this._startListeningToDivEvents(); ++ this.props.onSizeChanged({ height: this._mainDivRef.clientHeight, width: this._mainDivRef.clientWidth }); ++ } ++ } ++ }; ++ ScrollViewer.prototype.componentWillUnmount = function () { ++ window.removeEventListener("scroll", this._windowOnScroll); ++ if (this._mainDivRef) { ++ this._mainDivRef.removeEventListener("scroll", this._onScroll); ++ } ++ window.removeEventListener("resize", this._onWindowResize); ++ }; ++ ScrollViewer.prototype.scrollTo = function (scrollInput) { ++ if (scrollInput.animated) { ++ this._doAnimatedScroll(this.props.horizontal ? scrollInput.x : scrollInput.y); ++ } ++ else { ++ this._setRelevantOffset(this.props.horizontal ? scrollInput.x : scrollInput.y); ++ } ++ }; ++ ScrollViewer.prototype.render = function () { ++ return !this.props.useWindowScroll ++ ? React.createElement("div", { ref: this._setDivRef, style: __assign({ WebkitOverflowScrolling: "touch", height: "100%", overflowX: this.props.horizontal ? "scroll" : "hidden", overflowY: !this.props.horizontal ? "scroll" : "hidden", width: "100%" }, this.props.style) }, ++ React.createElement("div", { style: { position: "relative" } }, this.props.children)) ++ : React.createElement("div", { ref: this._setDivRef, style: __assign({ position: "relative" }, this.props.style) }, this.props.children); ++ }; ++ ScrollViewer.prototype._doAnimatedScroll = function (offset) { ++ var _this = this; ++ var start = this._getRelevantOffset(); ++ if (offset > start) { ++ start = Math.max(offset - 800, start); ++ } ++ else { ++ start = Math.min(offset + 800, start); ++ } ++ var change = offset - start; ++ var increment = 20; ++ var duration = 200; ++ var animateScroll = function (elapsedTime) { ++ elapsedTime += increment; ++ var position = _this._easeInOut(elapsedTime, start, change, duration); ++ _this._setRelevantOffset(position); ++ if (elapsedTime < duration) { ++ window.setTimeout(function () { return animateScroll(elapsedTime); }, increment); ++ } ++ }; ++ animateScroll(0); ++ }; ++ ScrollViewer.prototype._startListeningToDivEvents = function () { ++ if (this._mainDivRef) { ++ this._mainDivRef.addEventListener("scroll", this._onScroll); ++ } ++ }; ++ ScrollViewer.prototype._startListeningToWindowEvents = function () { ++ window.addEventListener("scroll", this._windowOnScroll); ++ if (this.props.canChangeSize) { ++ window.addEventListener("resize", this._onWindowResize); ++ } ++ }; ++ ScrollViewer.prototype._easeInOut = function (currentTime, start, change, duration) { ++ currentTime /= duration / 2; ++ if (currentTime < 1) { ++ return change / 2 * currentTime * currentTime + start; ++ } ++ currentTime -= 1; ++ return (-change) / 2 * (currentTime * (currentTime - 2) - 1) + start; ++ }; ++ ScrollViewer.defaultProps = { ++ canChangeSize: false, ++ horizontal: false, ++ style: null, ++ useWindowScroll: false, ++ }; ++ return ScrollViewer; ++}(BaseScrollView_1.default)); ++exports.default = ScrollViewer; ++//# sourceMappingURL=ScrollViewer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js.map b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js.map +new file mode 100644 +index 0000000..ea465a9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ScrollViewer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollViewer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.d.ts +new file mode 100644 +index 0000000..76283f9 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.d.ts +@@ -0,0 +1,19 @@ ++/// ++import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++export default class ViewRenderer extends BaseViewRenderer { ++ private _dim; ++ private _mainDiv; ++ componentDidMount(): void; ++ componentDidUpdate(): void; ++ render(): JSX.Element; ++ protected getRef(): object | null; ++ private _setRef; ++ private _getTransform; ++ private _checkSizeChange; ++} +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js +new file mode 100644 +index 0000000..81d8dc1 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js +@@ -0,0 +1,98 @@ ++"use strict"; ++var __extends = (this && this.__extends) || (function () { ++ var extendStatics = function (d, b) { ++ extendStatics = Object.setPrototypeOf || ++ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ++ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ++ return extendStatics(d, b); ++ }; ++ return function (d, b) { ++ extendStatics(d, b); ++ function __() { this.constructor = d; } ++ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); ++ }; ++})(); ++var __assign = (this && this.__assign) || function () { ++ __assign = Object.assign || function(t) { ++ for (var s, i = 1, n = arguments.length; i < n; i++) { ++ s = arguments[i]; ++ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) ++ t[p] = s[p]; ++ } ++ return t; ++ }; ++ return __assign.apply(this, arguments); ++}; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var React = require("react"); ++var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); ++/*** ++ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. ++ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. ++ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. ++ * This is second of the two things recycler works on. Implemented both for web and react native. ++ */ ++var ViewRenderer = /** @class */ (function (_super) { ++ __extends(ViewRenderer, _super); ++ function ViewRenderer() { ++ var _this = _super !== null && _super.apply(this, arguments) || this; ++ _this._dim = { width: 0, height: 0 }; ++ _this._mainDiv = null; ++ _this._setRef = function (div) { ++ _this._mainDiv = div; ++ }; ++ return _this; ++ } ++ ViewRenderer.prototype.componentDidMount = function () { ++ if (_super.prototype.componentDidMount) { ++ _super.prototype.componentDidMount.call(this); ++ } ++ this._checkSizeChange(); ++ }; ++ ViewRenderer.prototype.componentDidUpdate = function () { ++ this._checkSizeChange(); ++ }; ++ ViewRenderer.prototype.render = function () { ++ var style = this.props.forceNonDeterministicRendering ++ ? __assign({ transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides) : __assign({ height: this.props.height, overflow: "hidden", width: this.props.width, transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides); ++ return (React.createElement("div", { ref: this._setRef, style: style }, this.renderChild())); ++ }; ++ ViewRenderer.prototype.getRef = function () { ++ return this._mainDiv; ++ }; ++ ViewRenderer.prototype._getTransform = function () { ++ return "translate(" + this.props.x + "px," + this.props.y + "px)"; ++ }; ++ ViewRenderer.prototype._checkSizeChange = function () { ++ if (this.props.forceNonDeterministicRendering && this.props.onSizeChanged) { ++ var mainDiv = this._mainDiv; ++ if (mainDiv) { ++ this._dim.width = mainDiv.clientWidth; ++ this._dim.height = mainDiv.clientHeight; ++ if (this.props.width !== this._dim.width || this.props.height !== this._dim.height) { ++ this.props.onSizeChanged(this._dim, this.props.index); ++ } ++ } ++ } ++ }; ++ return ViewRenderer; ++}(BaseViewRenderer_1.default)); ++exports.default = ViewRenderer; ++var styles = { ++ baseViewStyle: { ++ alignItems: "stretch", ++ borderWidth: 0, ++ borderStyle: "solid", ++ boxSizing: "border-box", ++ display: "flex", ++ flexDirection: "column", ++ margin: 0, ++ padding: 0, ++ position: "absolute", ++ minHeight: 0, ++ minWidth: 0, ++ left: 0, ++ top: 0, ++ }, ++}; ++//# sourceMappingURL=ViewRenderer.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js.map +new file mode 100644 +index 0000000..7810112 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/web/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/AutoScroll.d.ts b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.d.ts +new file mode 100644 +index 0000000..0bd1380 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.d.ts +@@ -0,0 +1,6 @@ ++export interface Scrollable { ++ scrollToOffset(x: number, y: number, animate: boolean): void; ++} ++export declare class AutoScroll { ++ static scrollNow(scrollable: Scrollable, fromX: number, fromY: number, toX: number, toY: number, speedMultiplier?: number): Promise; ++} +diff --git a/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js +new file mode 100644 +index 0000000..ab91ef0 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js +@@ -0,0 +1,36 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var AutoScroll = /** @class */ (function () { ++ function AutoScroll() { ++ } ++ AutoScroll.scrollNow = function (scrollable, fromX, fromY, toX, toY, speedMultiplier) { ++ if (speedMultiplier === void 0) { speedMultiplier = 1; } ++ return new Promise(function (resolve) { ++ scrollable.scrollToOffset(fromX, fromY, false); ++ var incrementPerMs = 0.1 * speedMultiplier; ++ var startTime = Date.now(); ++ var startX = fromX; ++ var startY = fromY; ++ var animationLoop = function () { ++ requestAnimationFrame(function () { ++ var currentTime = Date.now(); ++ var timeElapsed = currentTime - startTime; ++ var distanceToCover = incrementPerMs * timeElapsed; ++ startX += distanceToCover; ++ startY += distanceToCover; ++ scrollable.scrollToOffset(Math.min(toX, startX), Math.min(toY, startY), false); ++ startTime = currentTime; ++ if (Math.min(toX, startX) !== toX || Math.min(toY, startY) !== toY) { ++ animationLoop(); ++ return; ++ } ++ resolve(); ++ }); ++ }; ++ animationLoop(); ++ }); ++ }; ++ return AutoScroll; ++}()); ++exports.AutoScroll = AutoScroll; ++//# sourceMappingURL=AutoScroll.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js.map b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js.map +new file mode 100644 +index 0000000..86f9d26 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"AutoScroll.js","sourceRoot":"","sources":["../../../src/utils/AutoScroll.ts"],"names":[],"mappings":";;AAGA;IAAA;IA2BA,CAAC;IA1BiB,oBAAS,GAAvB,UAAwB,UAAsB,EAAE,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,eAA2B;QAA3B,gCAAA,EAAA,mBAA2B;QAC/H,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO;YACvB,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAM,cAAc,GAAG,GAAG,GAAG,eAAe,CAAC;YAC7C,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAM,aAAa,GAAG;gBAClB,qBAAqB,CAAC;oBAClB,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC/B,IAAM,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;oBAC5C,IAAM,eAAe,GAAG,cAAc,GAAG,WAAW,CAAC;oBACrD,MAAM,IAAI,eAAe,CAAC;oBAC1B,MAAM,IAAI,eAAe,CAAC;oBAC1B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;oBAC/E,SAAS,GAAG,WAAW,CAAC;oBACxB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE;wBAChE,aAAa,EAAE,CAAC;wBAChB,OAAO;qBACV;oBACD,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,aAAa,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IACL,iBAAC;AAAD,CAAC,AA3BD,IA2BC;AA3BY,gCAAU"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/BinarySearch.d.ts b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.d.ts +new file mode 100644 +index 0000000..9365580 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.d.ts +@@ -0,0 +1,17 @@ ++export interface ValueAndIndex { ++ value: number; ++ index: number; ++} ++export default class BinarySearch { ++ static findClosestHigherValueIndex(size: number, targetValue: number, valueExtractor: (index: number) => number): number; ++ static findClosestValueToTarget(values: number[], target: number): ValueAndIndex; ++ /** ++ * Largest value from given values that is smaller or equal to the target number. ++ */ ++ static findValueSmallerThanTarget(values: number[], target: number): ValueAndIndex | undefined; ++ /** ++ * Smallest value from given values that is larger or equal to the target number. ++ */ ++ static findValueLargerThanTarget(values: number[], target: number): ValueAndIndex | undefined; ++ static findIndexOf(array: number[], value: number): number; ++} +diff --git a/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js +new file mode 100644 +index 0000000..74f37c5 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js +@@ -0,0 +1,154 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var CustomError_1 = require("../core/exceptions/CustomError"); ++var BinarySearch = /** @class */ (function () { ++ function BinarySearch() { ++ } ++ BinarySearch.findClosestHigherValueIndex = function (size, targetValue, valueExtractor) { ++ var low = 0; ++ var high = size - 1; ++ var mid = Math.floor((low + high) / 2); ++ var lastValue = 0; ++ var absoluteLastDiff = Math.abs(valueExtractor(mid) - targetValue); ++ var result = mid; ++ var diff = 0; ++ var absoluteDiff = 0; ++ if (absoluteLastDiff === 0) { ++ return result; ++ } ++ if (high < 0) { ++ throw new CustomError_1.default({ ++ message: "The collection cannot be empty", ++ type: "InvalidStateException", ++ }); ++ } ++ while (low <= high) { ++ mid = Math.floor((low + high) / 2); ++ lastValue = valueExtractor(mid); ++ diff = lastValue - targetValue; ++ absoluteDiff = Math.abs(diff); ++ if (diff >= 0 && absoluteDiff < absoluteLastDiff) { ++ absoluteLastDiff = absoluteDiff; ++ result = mid; ++ } ++ if (targetValue < lastValue) { ++ high = mid - 1; ++ } ++ else if (targetValue > lastValue) { ++ low = mid + 1; ++ } ++ else { ++ return mid; ++ } ++ } ++ return result; ++ }; ++ BinarySearch.findClosestValueToTarget = function (values, target) { ++ var low = 0; ++ var high = values.length - 1; ++ var mid = Math.floor((low + high) / 2); ++ var midValue = values[mid]; ++ var lastMidValue = midValue + 1; ++ while (low <= high && midValue !== lastMidValue) { ++ if (midValue === target) { ++ break; ++ } ++ else if (midValue < target) { ++ low = mid; ++ } ++ else if (midValue > target) { ++ high = mid; ++ } ++ mid = Math.floor((low + high) / 2); ++ lastMidValue = midValue; ++ midValue = values[mid]; ++ } ++ return { ++ value: midValue, ++ index: mid, ++ }; ++ }; ++ /** ++ * Largest value from given values that is smaller or equal to the target number. ++ */ ++ BinarySearch.findValueSmallerThanTarget = function (values, target) { ++ var low = 0; ++ var high = values.length - 1; ++ if (target >= values[high]) { ++ return { ++ value: values[high], ++ index: high, ++ }; ++ } ++ else if (target < values[low]) { ++ return undefined; ++ } ++ var midValueAndIndex = this.findClosestValueToTarget(values, target); ++ var midValue = midValueAndIndex.value; ++ var mid = midValueAndIndex.index; ++ if (midValue <= target) { ++ return { ++ value: midValue, ++ index: mid, ++ }; ++ } ++ else { ++ return { ++ value: values[mid - 1], ++ index: mid - 1, ++ }; ++ } ++ }; ++ /** ++ * Smallest value from given values that is larger or equal to the target number. ++ */ ++ BinarySearch.findValueLargerThanTarget = function (values, target) { ++ var low = 0; ++ var high = values.length - 1; ++ if (target < values[low]) { ++ return { ++ value: values[low], ++ index: low, ++ }; ++ } ++ else if (target > values[high]) { ++ return undefined; ++ } ++ var midValueAndIndex = this.findClosestValueToTarget(values, target); ++ var midValue = midValueAndIndex.value; ++ var mid = midValueAndIndex.index; ++ if (midValue >= target) { ++ return { ++ value: midValue, ++ index: mid, ++ }; ++ } ++ else { ++ return { ++ value: values[mid + 1], ++ index: mid + 1, ++ }; ++ } ++ }; ++ BinarySearch.findIndexOf = function (array, value) { ++ var j = 0; ++ var length = array.length; ++ var i = 0; ++ while (j < length) { ++ i = length + j - 1 >> 1; ++ if (value > array[i]) { ++ j = i + 1; ++ } ++ else if (value < array[i]) { ++ length = i; ++ } ++ else { ++ return i; ++ } ++ } ++ return -1; ++ }; ++ return BinarySearch; ++}()); ++exports.default = BinarySearch; ++//# sourceMappingURL=BinarySearch.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js.map b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js.map +new file mode 100644 +index 0000000..8684678 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"BinarySearch.js","sourceRoot":"","sources":["../../../src/utils/BinarySearch.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.d.ts b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.d.ts +new file mode 100644 +index 0000000..113cffc +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.d.ts +@@ -0,0 +1,15 @@ ++/*** ++ * Recycle pool for maintaining recyclable items, supports segregation by type as well. ++ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation ++ */ ++export default class RecycleItemPool { ++ private _recyclableObjectMap; ++ private _availabilitySet; ++ constructor(); ++ putRecycledObject(objectType: string | number, object: string): void; ++ getRecycledObject(objectType: string | number): string | undefined; ++ removeFromPool(object: string): boolean; ++ clearAll(): void; ++ private _getRelevantSet; ++ private _stringify; ++} +diff --git a/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js +new file mode 100644 +index 0000000..d1173ad +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js +@@ -0,0 +1,65 @@ ++"use strict"; ++/*** ++ * Recycle pool for maintaining recyclable items, supports segregation by type as well. ++ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation ++ */ ++Object.defineProperty(exports, "__esModule", { value: true }); ++var RecycleItemPool = /** @class */ (function () { ++ function RecycleItemPool() { ++ this._recyclableObjectMap = {}; ++ this._availabilitySet = {}; ++ } ++ RecycleItemPool.prototype.putRecycledObject = function (objectType, object) { ++ objectType = this._stringify(objectType); ++ var objectSet = this._getRelevantSet(objectType); ++ if (!this._availabilitySet[object]) { ++ objectSet[object] = null; ++ this._availabilitySet[object] = objectType; ++ } ++ }; ++ RecycleItemPool.prototype.getRecycledObject = function (objectType) { ++ objectType = this._stringify(objectType); ++ var objectSet = this._getRelevantSet(objectType); ++ var recycledObject; ++ for (var property in objectSet) { ++ if (objectSet.hasOwnProperty(property)) { ++ recycledObject = property; ++ break; ++ } ++ } ++ if (recycledObject) { ++ delete objectSet[recycledObject]; ++ delete this._availabilitySet[recycledObject]; ++ } ++ return recycledObject; ++ }; ++ RecycleItemPool.prototype.removeFromPool = function (object) { ++ if (this._availabilitySet[object]) { ++ delete this._getRelevantSet(this._availabilitySet[object])[object]; ++ delete this._availabilitySet[object]; ++ return true; ++ } ++ return false; ++ }; ++ RecycleItemPool.prototype.clearAll = function () { ++ this._recyclableObjectMap = {}; ++ this._availabilitySet = {}; ++ }; ++ RecycleItemPool.prototype._getRelevantSet = function (objectType) { ++ var objectSet = this._recyclableObjectMap[objectType]; ++ if (!objectSet) { ++ objectSet = {}; ++ this._recyclableObjectMap[objectType] = objectSet; ++ } ++ return objectSet; ++ }; ++ RecycleItemPool.prototype._stringify = function (objectType) { ++ if (typeof objectType === "number") { ++ objectType = objectType.toString(); ++ } ++ return objectType; ++ }; ++ return RecycleItemPool; ++}()); ++exports.default = RecycleItemPool; ++//# sourceMappingURL=RecycleItemPool.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js.map b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js.map +new file mode 100644 +index 0000000..2dde95b +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"RecycleItemPool.js","sourceRoot":"","sources":["../../../src/utils/RecycleItemPool.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH;IAII;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B,EAAE,MAAc;QAChE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAChC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;SAC9C;IACL,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B;QAChD,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC;QACnB,KAAK,IAAM,QAAQ,IAAI,SAAS,EAAE;YAC9B,IAAI,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;gBACpC,cAAc,GAAG,QAAQ,CAAC;gBAC1B,MAAM;aACT;SACJ;QAED,IAAI,cAAc,EAAE;YAChB,OAAO,SAAS,CAAC,cAAc,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;SAChD;QACD,OAAO,cAAc,CAAC;IAC1B,CAAC;IAEM,wCAAc,GAArB,UAAsB,MAAc;QAChC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;SACf;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,kCAAQ,GAAf;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEO,yCAAe,GAAvB,UAAwB,UAAkB;QACtC,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE;YACZ,SAAS,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;SACrD;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,oCAAU,GAAlB,UAAmB,UAA2B;QAC1C,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;YAChC,UAAU,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC;SACtC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;IACL,sBAAC;AAAD,CAAC,AAjED,IAiEC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/TSCast.d.ts b/node_modules/recyclerlistview/dist/web/utils/TSCast.d.ts +new file mode 100644 +index 0000000..d867c7e +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/TSCast.d.ts +@@ -0,0 +1,3 @@ ++export default class TSCast { ++ static cast(object: any): T; ++} +diff --git a/node_modules/recyclerlistview/dist/web/utils/TSCast.js b/node_modules/recyclerlistview/dist/web/utils/TSCast.js +new file mode 100644 +index 0000000..526f93a +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/TSCast.js +@@ -0,0 +1,12 @@ ++"use strict"; ++Object.defineProperty(exports, "__esModule", { value: true }); ++var TSCast = /** @class */ (function () { ++ function TSCast() { ++ } ++ TSCast.cast = function (object) { ++ return object; ++ }; ++ return TSCast; ++}()); ++exports.default = TSCast; ++//# sourceMappingURL=TSCast.js.map +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/dist/web/utils/TSCast.js.map b/node_modules/recyclerlistview/dist/web/utils/TSCast.js.map +new file mode 100644 +index 0000000..3384c98 +--- /dev/null ++++ b/node_modules/recyclerlistview/dist/web/utils/TSCast.js.map +@@ -0,0 +1 @@ ++{"version":3,"file":"TSCast.js","sourceRoot":"","sources":["../../../src/utils/TSCast.ts"],"names":[],"mappings":";;AAAA;IAAA;IAIA,CAAC;IAHiB,WAAI,GAAlB,UAAsB,MAAW;QAC7B,OAAO,MAAW,CAAC;IACvB,CAAC;IACL,aAAC;AAAD,CAAC,AAJD,IAIC"} +\ No newline at end of file +diff --git a/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts b/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts +index bdfa5fb..34e2a71 100644 +--- a/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts ++++ b/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts +@@ -66,9 +66,8 @@ export default class ViewabilityTracker { + } + + public forceRefresh(): boolean { +- const shouldForceScroll = this._currentOffset >= (this._maxOffset - this._windowBound); + this.forceRefreshWithOffset(this._currentOffset); +- return shouldForceScroll; ++ return false; + } + + public forceRefreshWithOffset(offset: number): void { +diff --git a/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts b/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts +index e9454a4..3ecd8ac 100644 +--- a/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts ++++ b/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts +@@ -189,6 +189,10 @@ export class WrapGridLayoutManager extends LayoutManager { + } + let i = startIndex - 1; + for (; i >= 0; i--) { ++ if (!this._layouts[i]) { ++ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line ++ continue; ++ } + if (this._isHorizontal) { + if (this._layouts[i].y === 0) { + break; +diff --git a/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx b/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx +index 22db8a2..6d91cc6 100644 +--- a/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx ++++ b/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx +@@ -53,6 +53,6 @@ export default class StickyHeader

JSX.Element | JSX.Element[] | null; + } + export interface StickyObjectState { +- visible: boolean; ++ visibility: boolean; + } + export default abstract class StickyObject

extends React.Component { + protected stickyType: StickyType = StickyType.HEADER; + protected stickyTypeMultiplier: number = 1; + protected stickyVisiblity: boolean = false; ++ protected visibility: boolean = false; + protected containerPosition: StyleProp; + protected currentIndex: number = 0; + protected currentStickyIndex: number = 0; +@@ -64,7 +65,7 @@ export default abstract class StickyObject

+- {this.state.visible ? ++ {this.visibility ? + this._renderSticky() + : null} + +@@ -103,6 +104,15 @@ export default abstract class StickyObject

= 0 && prevVisibility === false) { ++ this.visibility = true; ++ } ++ if (prevVisibility !== this.visibility) { ++ this.render(); ++ } + this._initParams(); + this._offsetY = offsetY; + this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); +@@ -156,7 +166,7 @@ export default abstract class StickyObject

= 2.1.2 < 3" ++ ++inflight@^1.0.4: ++ version "1.0.6" ++ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" ++ integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= ++ dependencies: ++ once "^1.3.0" ++ wrappy "1" ++ ++inherits@2: ++ version "2.0.4" ++ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" ++ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ++ ++is-stream@^1.0.1: ++ version "1.1.0" ++ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" ++ integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= ++ ++isomorphic-fetch@^2.1.1: ++ version "2.2.1" ++ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" ++ integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= ++ dependencies: ++ node-fetch "^1.0.1" ++ whatwg-fetch ">=0.10.0" ++ ++istextorbinary@^2.1.0: ++ version "2.5.1" ++ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.5.1.tgz#14a33824cf6b9d5d7743eac1be2bd2c310d0ccbd" ++ integrity sha512-pv/JNPWnfpwGjPx7JrtWTwsWsxkrK3fNzcEVnt92YKEIErps4Fsk49+qzCe9iQF2hjqK8Naqf8P9kzoeCuQI1g== ++ dependencies: ++ binaryextensions "^2.1.2" ++ editions "^2.1.3" ++ textextensions "^2.4.0" ++ ++"js-tokens@^3.0.0 || ^4.0.0": ++ version "4.0.0" ++ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" ++ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== ++ ++js-tokens@^3.0.2: ++ version "3.0.2" ++ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" ++ integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= ++ ++js-yaml@^3.7.0: ++ version "3.13.1" ++ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" ++ integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== ++ dependencies: ++ argparse "^1.0.7" ++ esprima "^4.0.0" ++ ++lodash.debounce@4.0.8: ++ version "4.0.8" ++ resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" ++ integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= ++ ++loose-envify@^1.0.0: ++ version "1.4.0" ++ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" ++ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== ++ dependencies: ++ js-tokens "^3.0.0 || ^4.0.0" ++ ++minimatch@^3.0.4: ++ version "3.0.4" ++ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" ++ integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== ++ dependencies: ++ brace-expansion "^1.1.7" ++ ++ncp@^2.0.0: ++ version "2.0.0" ++ resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" ++ integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= ++ ++node-fetch@^1.0.1: ++ version "1.7.3" ++ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" ++ integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== ++ dependencies: ++ encoding "^0.1.11" ++ is-stream "^1.0.1" ++ ++object-assign@^4.1.0: ++ version "4.1.1" ++ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" ++ integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= ++ ++once@^1.3.0: ++ version "1.4.0" ++ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" ++ integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= ++ dependencies: ++ wrappy "1" ++ ++path-is-absolute@^1.0.0: ++ version "1.0.1" ++ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" ++ integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= ++ ++path-parse@^1.0.6: ++ version "1.0.6" ++ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" ++ integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== ++ ++promise@^7.1.1: ++ version "7.3.1" ++ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" ++ integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== ++ dependencies: ++ asap "~2.0.3" ++ ++prop-types@15.5.8: ++ version "15.5.8" ++ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394" ++ integrity sha1-a3suFBCDvjjIWVqlH8VXdccZk5Q= ++ dependencies: ++ fbjs "^0.8.9" ++ ++resolve@^1.3.2: ++ version "1.12.0" ++ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" ++ integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== ++ dependencies: ++ path-parse "^1.0.6" ++ ++"safer-buffer@>= 2.1.2 < 3": ++ version "2.1.2" ++ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" ++ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== ++ ++semver@^5.3.0, semver@^5.6.0: ++ version "5.7.1" ++ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" ++ integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== ++ ++setimmediate@^1.0.5: ++ version "1.0.5" ++ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" ++ integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= ++ ++sprintf-js@~1.0.2: ++ version "1.0.3" ++ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" ++ integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= ++ ++strip-ansi@^3.0.0: ++ version "3.0.1" ++ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" ++ integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= ++ dependencies: ++ ansi-regex "^2.0.0" ++ ++supports-color@^2.0.0: ++ version "2.0.0" ++ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" ++ integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= ++ ++supports-color@^5.3.0: ++ version "5.5.0" ++ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" ++ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== ++ dependencies: ++ has-flag "^3.0.0" ++ ++textextensions@^2.4.0: ++ version "2.5.0" ++ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.5.0.tgz#e21d3831dafa37513dd80666dff541414e314293" ++ integrity sha512-1IkVr355eHcomgK7fgj1Xsokturx6L5S2JRT5WcRdA6v5shk9sxWuO/w/VbpQexwkXJMQIa/j1dBi3oo7+HhcA== ++ ++ts-object-utils@0.0.5: ++ version "0.0.5" ++ resolved "https://registry.yarnpkg.com/ts-object-utils/-/ts-object-utils-0.0.5.tgz#95361cdecd7e52167cfc5e634c76345e90a26077" ++ integrity sha1-lTYc3s1+UhZ8/F5jTHY0XpCiYHc= ++ ++tslib@^1.8.0, tslib@^1.8.1: ++ version "1.10.0" ++ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" ++ integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== ++ ++tslint@5.11.0: ++ version "5.11.0" ++ resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed" ++ integrity sha1-mPMMAurjzecAYgHkwzywi0hYHu0= ++ dependencies: ++ babel-code-frame "^6.22.0" ++ builtin-modules "^1.1.1" ++ chalk "^2.3.0" ++ commander "^2.12.1" ++ diff "^3.2.0" ++ glob "^7.1.1" ++ js-yaml "^3.7.0" ++ minimatch "^3.0.4" ++ resolve "^1.3.2" ++ semver "^5.3.0" ++ tslib "^1.8.0" ++ tsutils "^2.27.2" ++ ++tsutils@^2.27.2: ++ version "2.29.0" ++ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" ++ integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== ++ dependencies: ++ tslib "^1.8.1" ++ ++typescript@3.3.1: ++ version "3.3.1" ++ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b" ++ integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA== ++ ++ua-parser-js@^0.7.18: ++ version "0.7.20" ++ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" ++ integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== ++ ++whatwg-fetch@>=0.10.0: ++ version "3.0.0" ++ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" ++ integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== ++ ++wrappy@1: ++ version "1.0.2" ++ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" ++ integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= From cf5764dfbd5639c3b355899d3efe6dfbac7c129d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 15 Aug 2019 03:22:40 -0700 Subject: [PATCH 203/636] Improve perf + data loading of CurrencySelectModal + child lists --- src/components/asset-list/EmptyAssetList.js | 3 +- src/components/exchange/ExchangeAssetList.js | 61 ++--- src/components/exchange/ExchangeInput.js | 4 +- .../exchange/ExchangeModalHeader.js | 26 ++ src/components/exchange/ExchangeSearch.js | 25 +- src/components/exchange/index.js | 1 + src/components/icons/Icon.js | 2 + src/components/icons/svg/ClearInputIcon.js | 27 ++ .../layout/KeyboardFixedOpenLayout.js | 4 +- src/screens/CurrencySelectModal.js | 249 ++++++++++-------- src/screens/ExchangeModal.js | 71 ++--- src/utils/search.js | 2 +- 12 files changed, 285 insertions(+), 190 deletions(-) create mode 100644 src/components/exchange/ExchangeModalHeader.js create mode 100644 src/components/icons/svg/ClearInputIcon.js diff --git a/src/components/asset-list/EmptyAssetList.js b/src/components/asset-list/EmptyAssetList.js index 70802b6d412..a367368ae80 100644 --- a/src/components/asset-list/EmptyAssetList.js +++ b/src/components/asset-list/EmptyAssetList.js @@ -2,7 +2,6 @@ import lang from 'i18n-js'; import { times } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; -import { withNeverRerender } from '../../hoc'; import { position } from '../../styles'; import AddFundsInterstitial from '../AddFundsInterstitial'; import { FabWrapper } from '../fab'; @@ -48,4 +47,4 @@ EmptyAssetList.defaultProps = { skeletonCount: 5, }; -export default withNeverRerender(EmptyAssetList); +export default React.memo(EmptyAssetList); diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index d44b1111e2e..e8138bb17f6 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -1,19 +1,9 @@ -import { get } from 'lodash'; +import { get, property } from 'lodash'; import lang from 'i18n-js'; import PropTypes from 'prop-types'; -import React, { Fragment, Component, PureComponent } from 'react'; -import { LayoutAnimation } from 'react-native'; -import { - compose, - onlyUpdateForKeys, - shouldUpdate, - withHandlers, -} from 'recompact'; -import { - DataProvider, - LayoutProvider, - RecyclerListView, -} from "recyclerlistview"; +import React, { PureComponent } from 'react'; +import { View } from 'react-native'; +import { DataProvider, LayoutProvider, RecyclerListView } from "recyclerlistview"; import styled from 'styled-components/primitives'; import { deviceUtils, isNewValueForPath } from '../../utils'; import { colors } from '../../styles'; @@ -24,12 +14,13 @@ const ViewTypes = { COIN_ROW: 0, }; -const hasRowChanged = (r1, r2) => isNewValueForPath(r1, r2, 'uniqueId') +const hasRowChanged = (...rows) => isNewValueForPath(...rows, 'uniqueId'); + +const buildUniqueIdForListData = (items = []) => items.map(property('address')).join('_'); export default class ExchangeAssetList extends PureComponent { static propTypes = { items: PropTypes.arrayOf(PropTypes.object), - itemsCount: PropTypes.number, renderItem: PropTypes.func, } @@ -40,7 +31,9 @@ export default class ExchangeAssetList extends PureComponent { dataProvider: new DataProvider(hasRowChanged, this.getStableId), } - this.layoutProvider = new LayoutProvider((index) => { + // this.state.dataProvider._requiresDataChangeHandling = true; + + this.layoutProvider = new LayoutProvider(() => { return ViewTypes.COIN_ROW; }, (type, dim) => { if (type === ViewTypes.COIN_ROW) { @@ -53,12 +46,15 @@ export default class ExchangeAssetList extends PureComponent { }) } + rlvRef = React.createRef() + componentDidMount = () => { this.updateList(); } componentDidUpdate = (prevProps, prevState) => { - if (this.props.items !== prevProps.items) { + if (this.props.items.length !== prevProps.items.length) { + // this.rlvRef.current.forceRerender(); this.updateList(); } } @@ -73,20 +69,25 @@ export default class ExchangeAssetList extends PureComponent { renderRow = (type, data) => this.props.renderItem(data) - render = () => { - const { isEmpty, items, ...props } = this.props; - const { dataProvider } = this.state; - - console.log('dataProvider', dataProvider); - - return ( + render = () => ( + - ); - }; + + ) } diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index ce25e5d2fff..687df07d020 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -53,8 +53,10 @@ export default class ExchangeInput extends PureComponent { refInput={refInput} selectionColor={colors.appleBlue} style={[{ - fontFamily: fonts.family.SFMono, + fontFamily: fonts.family.SFProDisplay, fontSize: parseFloat(fontSize), + fontVariant: ['tabular-nums'], + fontWeight: fonts.weight.medium, }, style]} value={value} /> diff --git a/src/components/exchange/ExchangeModalHeader.js b/src/components/exchange/ExchangeModalHeader.js new file mode 100644 index 00000000000..b02ef4e2d45 --- /dev/null +++ b/src/components/exchange/ExchangeModalHeader.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { withNeverRerender } from '../../hoc'; +import { padding } from '../../styles'; +import { ColumnWithMargins } from '../layout'; +import { SheetHandle } from '../sheet'; +import { Text } from '../text'; + +const ExchangeModalHeader = () => ( + + + + Swap + + +); + +export default withNeverRerender(ExchangeModalHeader); diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 7c91e712173..884e96884fc 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -7,7 +7,7 @@ import { colors, margin, padding, position } from '../../styles'; import { Icon } from '../icons'; import { Input } from '../inputs'; import InnerBorder from '../InnerBorder'; -import { RowWithMargins } from '../layout'; +import { Centered, RowWithMargins } from '../layout'; const Container = styled(RowWithMargins).attrs({ margin: 6.5, @@ -54,6 +54,8 @@ class ExchangeSearch extends PureComponent { + + + ( + + + +); +/* eslint-disable max-len */ + +ClearInputIcon.propTypes = { + color: PropTypes.string, +}; + +ClearInputIcon.defaultProps = { + color: colors.black, +}; + +export default ClearInputIcon; diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index bad336c0a43..c7ba1230ab9 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -42,7 +42,9 @@ class KeyboardFixedOpenLayout extends PureComponent { clearKeyboardListeners = () => { if (this.willShowListener) { - this.willShowListener.remove(); + console.log('this.willShowListener', this.willShowListener); + + // this.willShowListener.remove(); } } diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index bee910bb644..e9ceb04c6a5 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,44 +1,30 @@ -import { - get, -} from 'lodash'; +import { get, map, property } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, PureComponent } from 'react'; -import { compose } from 'recompact'; +import { InteractionManager, View } from 'react-native'; +import { compose, mapProps, withProps } from 'recompact'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; -import { ReText } from 'react-native-redash'; import Animated from 'react-native-reanimated'; import styled from 'styled-components/primitives'; -import { - Centered, - Column, - FlexItem, - KeyboardFixedOpenLayout, - Row, -} from '../components/layout'; -import { safeAreaInsetValues } from '../utils'; -import { Modal } from '../components/modal'; -import { ExchangeCoinRow } from '../components/coin-row'; -import GestureBlocker from '../components/GestureBlocker'; -import { TruncatedText } from '../components/text'; import { withKeyboardFocusHistory, withTransitionProps, + withUniswapAssets, } from '../hoc'; import { borders, colors, position } from '../styles'; +import { isNewValueForPath, safeAreaInsetValues } from '../utils'; +import { filterList } from '../utils/search'; import { EmptyAssetList } from '../components/asset-list'; -import { BackButton } from '../components/header'; +import { ExchangeCoinRow } from '../components/coin-row'; import { ExchangeAssetList, ExchangeSearch } from '../components/exchange'; -import { filterList } from '../utils/search'; +import GestureBlocker from '../components/GestureBlocker'; +import { BackButton } from '../components/header'; +import { Centered, Column, KeyboardFixedOpenLayout } from '../components/layout'; +import { Modal } from '../components/modal'; +import { TruncatedText } from '../components/text'; import { exchangeModalBorderRadius } from './ExchangeModal'; -const HeaderContainer = styled(Centered).attrs({ - flex: 0, -})` - ${borders.buildRadius('top', 12)}; - background-color: ${colors.white}; - height: 60; - width: 100%; -`; +const EMPTY_ARRAY = []; const BackButtonWrapper = styled(Centered)` left: 0; @@ -46,73 +32,98 @@ const BackButtonWrapper = styled(Centered)` position: absolute; `; +const HeaderContainer = styled(Centered).attrs({ flex: 0 })` + ${borders.buildRadius('top', 12)}; + background-color: ${colors.white}; + height: 60; + width: 100%; +`; + +const HeaderTitle = withProps({ + height: 21, + letterSpacing: 'tighter', + lineHeight: 'loose', + size: 'large', + weight: 'bold', +})(TruncatedText); + const appendAssetWithSearchableKey = (asset) => ({ ...asset, uniqueId: `${asset.name} ${asset.symbol}`, }); -class CurrencySelectModal extends PureComponent { //Component { +const buildUniqueIdForListData = (items = EMPTY_ARRAY) => items.map(property('address')).join('_'); + +const normalizeAssetItems = (assetsArray) => map(assetsArray, appendAssetWithSearchableKey); + +export const CurrencySelectionTypes = { + input: 'input', + output: 'output', +}; + +class CurrencySelectModal extends PureComponent { static propTypes = { + assetsAvailableOnUniswap: PropTypes.arrayOf(PropTypes.object), + isFocused: PropTypes.bool, + isTransitioning: PropTypes.bool, navigation: PropTypes.object, + sortedUniswapAssets: PropTypes.array, + transitionPosition: PropTypes.object, + type: PropTypes.oneOf(Object.keys(CurrencySelectionTypes)), } state = { - assets: [], - searchResults: [], + searchQuery: '', } - headerTitle = 'Receive' + searchInputRef = React.createRef() - position = undefined + componentDidUpdate(prevProps) { + const { isFocused, isTransitioning } = this.props; - onChangeSearchText = (searchPhrase) => { - const searchResults = filterList(this.state.assets, searchPhrase, 'uniqueId'); - this.setState({ searchResults }); + if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { + if (this.searchInputRef.current) { + InteractionManager.runAfterInteractions(() => { + this.searchInputRef.current.focus(); + }); + } + } } - searchInputRef = React.createRef() - - componentDidMount() { - this.getDataFromParams(); - } + shouldComponentUpdate = (nextProps, nextState) => { + const currentTransitioning = this.props.isTransitioning; + const nextTransitioning = nextProps.isTransitioning; - componentDidUpdate(prevProps) { - const { - isFocused, - keyboardFocusHistory, - navigation, - transitionProps: { isTransitioning }, - } = this.props; + if (!currentTransitioning && nextTransitioning) { + return false; + } - const prevTransitioning = get(prevProps, 'transitionProps.isTransitioning'); + let currentAssets = this.props.sortedUniswapAssets; + let nextAssets = EMPTY_ARRAY; - if (isFocused && (!isTransitioning && prevTransitioning)) { - this.searchInputRef.current.focus(); + if (nextProps.type === CurrencySelectionTypes.input) { + currentAssets = this.props.assetsAvailableOnUniswap; + nextAssets = nextProps.assetsAvailableOnUniswap; + } else if (nextProps.type === CurrencySelectionTypes.output) { + nextAssets = nextProps.sortedUniswapAssets; } - this.getDataFromParams(); - } + const currentAssetsUniqueId = buildUniqueIdForListData(currentAssets); + const nextAssetsUniqueId = buildUniqueIdForListData(nextAssets); - getDataFromParams = () => { - const { navigation } = this.props; - // this.callback = ; - - this.headerTitle = navigation.getParam('headerTitle'); - // console.log('nav get params', navigation.getScreenProps()); - // console.log('nav get params', navigation); - - // console.log('getDataFromParams -- assets --', assets); - - if (!this.state.assets.length) { - const thing = navigation.getParam('assets', []).map(appendAssetWithSearchableKey); - // console.log('assets',assets ); - // console.log('THIGN', thing); - // console.log('this.state.assets', this.state.assets); - if (!!thing.length) { - // console.log('THE THING,,,,,, its happening') - this.setState({ assets: thing }); - } - } + const isNewAssets = currentAssetsUniqueId !== nextAssetsUniqueId; + const isNewFocus = isNewValueForPath(this.props, nextProps, 'isFocused'); + const isNewSearchQuery = isNewValueForPath(this.state, nextState, 'searchQuery'); + const isNewTransitioning = isNewValueForPath(this.props, nextProps, 'isTransitioning'); + const isNewType = isNewValueForPath(this.props, nextProps, 'type'); + + return ( + isNewAssets + || isNewSearchQuery + || isNewType + || isNewFocus + || isNewTransitioning + ); } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { @@ -136,7 +147,10 @@ class CurrencySelectModal extends PureComponent { //Component { navigation.navigate('MainExchangeScreen'); } - // {...itemProps} + onChangeSearchText = (searchQuery) => { + this.setState({ searchQuery }); + } + renderCurrencyItem = (item) => ( { const { - allAssets, - navigation, - transitionProps: { isTransitioning }, + assetsAvailableOnUniswap, + isFocused, + isTransitioning, + sortedUniswapAssets, + transitionPosition, + type, } = this.props; - const { assets, searchResults } = this.state; - const items = searchResults.length ? searchResults : assets; + const { searchQuery } = this.state; + + let headerTitle = ''; + let assets = sortedUniswapAssets; + if (type === CurrencySelectionTypes.input) { + headerTitle = 'Swap'; + assets = assetsAvailableOnUniswap; + } else if (type === CurrencySelectionTypes.output) { + headerTitle = 'Receive'; + } + + const listItems = filterList(assets, searchQuery, 'uniqueId'); + + const isLoading = ( + isTransitioning + || listItems.length === 0 + || !isFocused + ); return ( - - {this.headerTitle} - + + {headerTitle} + - {(items.length === 0) ? ( - - ) : ( - + - )} - + + @@ -226,16 +259,24 @@ class CurrencySelectModal extends PureComponent { //Component { } } - - - // - // - // flex={0} - // style={{ backgroundColor: 'blue', height: 400 }} - // paddingBottom={100} - // height={400} export default compose( withNavigationFocus, withTransitionProps, withKeyboardFocusHistory, + withUniswapAssets, + mapProps(({ + assetsAvailableOnUniswap, + navigation, + sortedUniswapAssets, + transitionProps: { isTransitioning }, + ...props, + }) => ({ + ...props, + assetsAvailableOnUniswap: normalizeAssetItems(assetsAvailableOnUniswap), + isTransitioning, + navigation, + sortedUniswapAssets: normalizeAssetItems(sortedUniswapAssets), + transitionPosition: get(navigation, 'state.params.position'), + type: get(navigation, 'state.params.type', null), + })), )(CurrencySelectModal); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index b2f7139fb8f..cb65d56c7f3 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -16,10 +16,10 @@ import { } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; -import { TextInput } from 'react-native'; +import { InteractionManager, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationActions, NavigationEvents, withNavigationFocus } from 'react-navigation'; -import { compose, toClass, withProps } from 'recompact'; +import { compose, mapProps, toClass, withProps } from 'recompact'; import { executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeDisplay, @@ -35,18 +35,16 @@ import { withAccountSettings, withBlockedHorizontalSwipe, withKeyboardFocusHistory, - withNeverRerender, withTransactionConfirmationScreen, withTransitionProps, - withUniswapAssets, } from '../hoc'; -import uniswapAssets from '../references/uniswap-pairs.json'; import { colors, padding, position } from '../styles'; import { deviceUtils, ethereumUtils, safeAreaInsetValues } from '../utils'; import { ConfirmExchangeButton, ExchangeGasFeeButton, ExchangeInputField, + ExchangeModalHeader, ExchangeOutputField, } from '../components/exchange'; import { FloatingPanel, FloatingPanels } from '../components/expanded-state'; @@ -54,34 +52,15 @@ import GestureBlocker from '../components/GestureBlocker'; import { Centered, Column, - ColumnWithMargins, KeyboardFixedOpenLayout, } from '../components/layout'; -import { SheetHandle } from '../components/sheet'; import { Text } from '../components/text'; +import { CurrencySelectionTypes } from './CurrencySelectModal'; export const exchangeModalBorderRadius = 30; const AnimatedFloatingPanels = Animated.createAnimatedComponent(toClass(FloatingPanels)); -const ExchangeModalHeader = withNeverRerender(() => ( - - - - Swap - - -)); - class ExchangeModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, @@ -92,7 +71,6 @@ class ExchangeModal extends PureComponent { nativeCurrency: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, - sortedUniswapAssets: PropTypes.array, tradeDetails: PropTypes.object, } @@ -108,25 +86,20 @@ class ExchangeModal extends PureComponent { tradeDetails: null, } - componentDidMount = () => { - // console.log('componentDidMount dangerouslyGetParent', this.props.navigation.dangerouslyGetParent()) - // console.log('this.props.navigation', this.props.navigation); - } - componentDidUpdate = (prevProps) => { const { isFocused, + isTransitioning, keyboardFocusHistory, - transitionProps: { isTransitioning }, } = this.props; - const prevTransitioning = get(prevProps, 'transitionProps.isTransitioning'); - - if (isFocused && (!isTransitioning && prevTransitioning)) { + if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; if (lastFocusedInput) { - TextInput.State.focusTextInput(lastFocusedInput); + InteractionManager.runAfterInteractions(() => { + TextInput.State.focusTextInput(lastFocusedInput); + }); } else { // console.log('ELSE') // this.inputFieldRef.focus(); @@ -258,11 +231,6 @@ class ExchangeModal extends PureComponent { } } - getAssetsAvailableOnUniswap = () => { - const uniswapAssetAddresses = map(keys(uniswapAssets), address => address.toLowerCase()); - return filter(this.props.allAssets, asset => findIndex(uniswapAssetAddresses, uniswapAddress => uniswapAddress === asset.address) > -1); - } - onPressMaxBalance = () => { const { inputCurrency } = this.state; const balance = get(inputCurrency, 'balance.amount', 0); @@ -272,16 +240,14 @@ class ExchangeModal extends PureComponent { handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { - assets: this.getAssetsAvailableOnUniswap(), - headerTitle: 'Swap', + type: CurrencySelectionTypes.input, onSelectCurrency: this.setInputCurrency, }); } handleSelectOutputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { - assets: this.props.sortedUniswapAssets, - headerTitle: 'Receive', + type: CurrencySelectionTypes.output, onSelectCurrency: this.setOutputCurrency, }); } @@ -340,7 +306,7 @@ class ExchangeModal extends PureComponent { nativeCurrency, navigation, onPressConfirmExchange, - transitionProps, + transitionPosition, } = this.props; const { @@ -366,7 +332,7 @@ class ExchangeModal extends PureComponent { > ({ + ...props, + isTransitioning, + navigation, + transitionPosition: get(navigation, 'state.params.position'), + })), )(ExchangeModal); diff --git a/src/utils/search.js b/src/utils/search.js index f1bbee9ae42..f44bb2738c1 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -3,7 +3,7 @@ export const filterList = (list, searchPhrase, searchParameter = false, separato if (list && searchPhrase.length > 0) { for (let i = 0; i < list.length; i++) { let searchedItem = searchParameter ? list[i][searchParameter] : list[i]; - const splitedWordList = searchedItem.split(separator); + const splitedWordList = (searchedItem || '').split(separator); splitedWordList.push(searchedItem); for (let j = 0; j < splitedWordList.length; j++) { if (splitedWordList[j].toLowerCase().startsWith(searchPhrase.toLowerCase())) { From 99a4a1bd934ae2b6d9ac28cca58454324878c742 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 15 Aug 2019 03:22:49 -0700 Subject: [PATCH 204/636] bump deps --- ios/Podfile.lock | 12 ++-- package.json | 14 ++--- yarn.lock | 140 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 141 insertions(+), 25 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 39911195799..c7708c0eb34 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -216,7 +216,7 @@ PODS: - react-native-fast-image (6.1.1): - React - SDWebImage (~> 5.0) - - react-native-netinfo (3.2.1): + - react-native-netinfo (4.1.4): - React - react-native-version-number (0.3.6): - React @@ -246,7 +246,7 @@ PODS: - RNAnalytics (1.0.1): - Analytics - React - - RNCAsyncStorage (1.5.0): + - RNCAsyncStorage (1.6.1): - React - RNCMaskedView (0.1.1): - React @@ -321,7 +321,7 @@ PODS: - React - RNLanguages (3.0.2): - React - - RNReanimated (1.2.0): + - RNReanimated (1.3.0-alpha): - React - RNScreens (1.0.0-alpha.23): - React @@ -621,7 +621,7 @@ SPEC CHECKSUMS: react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 - react-native-netinfo: 0da34082d2cec3100c9b5073bb217e35f1142bdd + react-native-netinfo: 2aa34e02a38ae66e583bcae8c489ae0edd32b31f react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e @@ -634,7 +634,7 @@ SPEC CHECKSUMS: React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0 React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 - RNCAsyncStorage: 9436928b444c5f5361960a7eea051a697c244b68 + RNCAsyncStorage: 2e2e3feb9bdadc752a026703d8c4065ca912e75a RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 <<<<<<< HEAD <<<<<<< HEAD @@ -704,7 +704,7 @@ SPEC CHECKSUMS: >>>>>>> dca19a02... very work in progress RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e - RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 + RNReanimated: da57ffa32f04cebe2107da0b281999a01c0d1ecc RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 <<<<<<< HEAD diff --git a/package.json b/package.json index 2614a4f1ff9..fe080cd8d8b 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "@hocs/omit-props": "^0.4.0", "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", - "@react-native-community/async-storage": "1.5.0", - "@react-native-community/blur": "@react-native-community/blur", + "@react-native-community/async-storage": "1.6.1", + "@react-native-community/blur": "^3.3.1", "@react-native-community/masked-view": "^0.1.1", - "@react-native-community/netinfo": "^3.2.1", + "@react-native-community/netinfo": "^4.1.4", "@segment/analytics-react-native": "^1.0.1", "@staltz/react-native-tcp": "^3.3.1", "@tradle/react-native-http": "^2.0.1", @@ -87,16 +87,16 @@ "react-native-qrcode-svg": "git+https://github.com/mikedemarais/react-native-qrcode-svg.git", "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", - "react-native-reanimated": "1.2.0", - "react-native-redash": "^7.5.0", + "react-native-reanimated": "1.3.0-alpha", + "react-native-redash": "^7.5.1", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "^9.5.3", + "react-native-svg": "^9.6.2", "react-native-tcp": "^3.3.0", - "react-native-text-input-mask": "^1.0.6", + "react-native-text-input-mask": "quixley/react-native-text-input-mask#development", "react-native-tooltip": "^5.2.0", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", diff --git a/yarn.lock b/yarn.lock index 30642a98ed9..e11d6cdfc72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1604,10 +1604,10 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@react-native-community/async-storage@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.5.0.tgz#647ffcd832272068b0be57332e08d73036ed391f" - integrity sha512-2yE4RzQ5IL+UTPhuMY0ykNRKHf1m90jOnmp8fcDPUun5U97cXlorjI4p66ovDgF0FuOv8ZpiUKvunGy3qqBxwg== +"@react-native-community/async-storage@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.6.1.tgz#19be07fc1d65c77bdeb20f46108ba12076aad1c5" + integrity sha512-1WA28xfdhG+unkTEk/lXnqI2izv6belo0CYw7UdvaeHm8TIYT6eTmIIdGR7oiCa2xSKEnaPQqRMH6h7gyLNbww== "@react-native-community/blur@@react-native-community/blur": version "3.3.1" @@ -1621,6 +1621,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" @@ -1675,6 +1676,9 @@ >>>>>>> 64f1594b... rebase cleanup ======= ======= +======= +"@react-native-community/cli-platform-android@^2.8.3": +>>>>>>> 9bae1b8d... bump deps version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== @@ -1756,6 +1760,7 @@ slash "^3.0.0" xmldoc "^1.1.2" +<<<<<<< HEAD "@react-native-community/cli-platform-ios@^2.8.0": <<<<<<< HEAD <<<<<<< HEAD @@ -1829,6 +1834,9 @@ ======= ======= >>>>>>> dca19a02... very work in progress +======= +"@react-native-community/cli-platform-ios@^2.8.3": +>>>>>>> 9bae1b8d... bump deps version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== @@ -1837,7 +1845,7 @@ chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-tools@^2.7.0", "@react-native-community/cli-tools@^2.8.3": +"@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== @@ -1896,6 +1904,7 @@ mime "^2.4.1" node-fetch "^2.5.0" +<<<<<<< HEAD <<<<<<< HEAD "@react-native-community/cli@2.9.0", "@react-native-community/cli@^2.6.0": version "2.9.0" @@ -1917,6 +1926,17 @@ "@react-native-community/cli-platform-ios" "^2.8.0" "@react-native-community/cli-tools" "^2.7.0" >>>>>>> 96db5a28... begin mike +======= +"@react-native-community/cli@2.8.3": + version "2.8.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.3.tgz#b59c4e44946a1ce6c464ae246328cf3a2ab47bd2" + integrity sha512-khlS6slD6fsIv8R6L0bbQvK2PQ/UJytmh8/XEZ835bDwgbn6U90Yqrf299r6JxKk2/tyckRu6QimQNAkEQxEHg== + dependencies: + "@hapi/joi" "^15.0.3" + "@react-native-community/cli-platform-android" "^2.8.3" + "@react-native-community/cli-platform-ios" "^2.8.3" + "@react-native-community/cli-tools" "^2.8.3" +>>>>>>> 9bae1b8d... bump deps chalk "^2.4.2" commander "^2.19.0" compression "^1.7.1" @@ -2022,10 +2042,10 @@ resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.1.tgz#dbcfc5ec08efbb02d4142dd9426c8d7a396829d7" integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== -"@react-native-community/netinfo@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-3.2.1.tgz#cd073b81a4b978f7f55f1a960a0b56c462813e02" - integrity sha512-A2qANOnlRDVe+8kMbKMwy3/0bOlOA2+y8DyWg2Rv2KHICIfin+oxixbG0ewAOLQdLkSEyyumZXRmIVl7VI/KJg== +"@react-native-community/netinfo@^4.1.4": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.4.tgz#512be0395bab6f2432c6e26d7a00ace3c78e05ff" + integrity sha512-Iry24dLG0/oDWa60pjYbCcKVxcnvIvOl9PiB1WHvC0Zsykl1gT7dVeW7bWY4X98ZUb6+gVd4CekZiP7URQBeLQ== "@react-navigation/core@~3.5.0": version "3.5.0" @@ -2323,6 +2343,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -2369,6 +2390,11 @@ version "12.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== +======= + version "12.7.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" + integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== +>>>>>>> 9bae1b8d... bump deps "@types/node@^10.3.2": version "10.14.15" @@ -3684,6 +3710,7 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: +<<<<<<< HEAD <<<<<<< HEAD version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" @@ -3693,6 +3720,11 @@ buffer@^5.0.0: resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.3.0.tgz#5f9fa5fefe3939888d0fdbf7d964e2a8531fd69c" integrity sha512-XykNc84nIOC32vZ9euOKbmGAP69JUkXDtBQfLq88c8/6J/gZi/t14A+l/p/9EM2TcT5xNC1MKPCrvO3LVUpVPw== >>>>>>> dca19a02... very work in progress +======= + version "5.4.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.0.tgz#33294f5c1f26e08461e528b69fa06de3c45cbd8c" + integrity sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g== +>>>>>>> 9bae1b8d... bump deps dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -5177,10 +5209,16 @@ electron-to-chromium@^1.3.191: >>>>>>> 908925bc... Cleanup ButtonPressAnimation ======= electron-to-chromium@^1.3.191: +<<<<<<< HEAD version "1.3.225" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.225.tgz#c6786475b5eb5f491ade01a78b82ba2c5bfdf72b" integrity sha512-7W/L3jw7HYE+tUPbcVOGBmnSrlUmyZ/Uyg24QS7Vx0a9KodtNrN0r0Q/LyGHrcYMtw2rv7E49F/vTXwlV/fuaA== >>>>>>> dca19a02... very work in progress +======= + version "1.3.228" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.228.tgz#8b1804bae329e2029ad6b25fbb15d9200fb12894" + integrity sha512-m3k/OYd9sCLFOAtvl6vqgXfzbG8iY1mLYg0fQjQGB46LpPudYDUFUmiSmj2meJsHEUABWXH1ZRSCeWj265v2RQ== +>>>>>>> 9bae1b8d... bump deps elliptic@6.3.3: version "6.3.3" @@ -6561,6 +6599,7 @@ got@^6.7.1: graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" @@ -6575,6 +6614,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d" integrity sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== +>>>>>>> 9bae1b8d... bump deps growl@1.10.5: version "1.10.5" @@ -8720,6 +8764,29 @@ metro-react-native-babel-preset@^0.56.0: "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" react-refresh "^0.4.0" +<<<<<<< HEAD +======= + +metro-react-native-babel-transformer@0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz#57a695e97a19d95de63c9633f9d0dc024ee8e99a" + integrity sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.0.1" + metro-babel-transformer "0.51.0" + metro-react-native-babel-preset "0.51.0" + +metro-react-native-babel-transformer@^0.51.0: + version "0.51.1" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.1.tgz#bac34f988c150c725cd1875c13701cc2032615f9" + integrity sha512-D0KU+JPb/Z76nUWt3+bkjKggOlGvqAVI2BpIH2JFKprpUyBjWaCRqHnkBfZGixYwUfmu93MIlKJWr6iKzzFrlg== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.0.1" + metro-babel-transformer "0.51.1" + metro-react-native-babel-preset "0.51.1" +>>>>>>> 9bae1b8d... bump deps metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" @@ -10439,6 +10506,18 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= +<<<<<<< HEAD +======= +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +>>>>>>> 9bae1b8d... bump deps randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -10856,6 +10935,7 @@ react-native-randombytes@^3.5.3: buffer "^4.9.1" sjcl "^1.0.3" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD ======= @@ -10876,6 +10956,17 @@ react-native-redash@^7.5.0: resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.0.tgz#fa72c7a23ad2f3f884a494ed76a0e79041ae70e1" integrity sha512-y2J19HbBYWOYq4kq+3U86wfbsDusxv1/ak4a6KqvfTmt/E3i85mnnUDIF+nk1Shqz0aYcwNMB2KD7bEWsVK/sw== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +react-native-reanimated@1.3.0-alpha: + version "1.3.0-alpha" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.3.0-alpha.tgz#d278128acef895cf72aa34c5c4bd1540632c2ac6" + integrity sha512-0tB+0ooycK0ULT2JXXle8EyA7niUOGmEGp/sGcf0985eSSI44FIYCZHTVkA3OkwLbiUR7g6neDmzp7C2NGRGfg== + +react-native-redash@^7.5.1: + version "7.5.1" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.1.tgz#79c52c9a629b8ddeeb17e73336216aba1cc2f689" + integrity sha512-NidcTKlK57BtjCMC9OKhXJnH50TDlfb+vel4oLUfaYHO2kGY56jGj+IS29V3joZgB5iO1X+U5K5FYWuQuDnepA== +>>>>>>> 9bae1b8d... bump deps dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -10956,6 +11047,7 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== +<<<<<<< HEAD <<<<<<< HEAD react-native-svg@^9.5.1: version "9.9.3" @@ -10963,6 +11055,9 @@ react-native-svg@^9.5.1: integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== ======= react-native-svg@^9.5.3: +======= +react-native-svg@^9.6.2: +>>>>>>> 9bae1b8d... bump deps version "9.6.2" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== @@ -11026,10 +11121,9 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" -react-native-text-input-mask@^1.0.6: +react-native-text-input-mask@quixley/react-native-text-input-mask#development: version "1.0.6" - resolved "https://registry.yarnpkg.com/react-native-text-input-mask/-/react-native-text-input-mask-1.0.6.tgz#21ca0c1886f5b547e9f6594ba2f4bb50d39fe3a1" - integrity sha512-pCTYEnqiKw1F9VuEwxOt42Roaigilpp0xjb2JhjIeuVlc6Cvf9IqA+vzAXLJTOzoxImOOAasGxrZpTgdFYMvOQ== + resolved "https://codeload.github.com/quixley/react-native-text-input-mask/tar.gz/76f7ce5cf57768aebc843051e98f8946a91ffd3e" react-native-tooltip@^5.2.0: version "5.2.0" @@ -11220,9 +11314,15 @@ react-redux@^5.0.7: react-lifecycles-compat "^3.0.0" react-refresh@^0.4.0: +<<<<<<< HEAD version "0.4.2" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.2.tgz#54a277a6caaac2803d88f1d6f13c1dcfbd81e334" integrity sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ== +======= + version "0.4.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.0.tgz#d421f9bd65e0e4b9822a399f14ac56bda9c92292" + integrity sha512-bacjSio8GOtzNZKZZM6EWqbhlbb6pr28JWJWFTLwEBKvPIBRo6/Ob68D2EWZA2VyTdQxAh+TRnCYOPNKsQiXTA== +>>>>>>> 9bae1b8d... bump deps react-spring@^5.7.2: version "5.9.2" @@ -11397,10 +11497,16 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" +<<<<<<< HEAD recyclerlistview@2.0.1-alpha.1: version "2.0.1-alpha.1" resolved "https://registry.yarnpkg.com/recyclerlistview/-/recyclerlistview-2.0.1-alpha.1.tgz#881955e6917911fb54a9b272004e39e5c0d64f4a" integrity sha512-UaeJyxG9LL8lcfiAqkp0kPLxvjbYg95Dcq1U/QUvzwXU4+H2khg/LAws/FssxPX6CXNMw7BLcT2YHAhkFElqRQ== +======= +recyclerlistview@Flipkart/recyclerlistview#master: + version "2.0.10" + resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/1d310dffc80d63e4303bf1213d2f6b0ce498c33a" +>>>>>>> 9bae1b8d... bump deps dependencies: lodash.debounce "4.0.8" prop-types "15.5.8" @@ -11748,11 +11854,15 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +<<<<<<< HEAD <<<<<<< HEAD rimraf@2.6.3: ======= rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@~2.6.2: >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +rimraf@2.6.3, rimraf@~2.6.2: +>>>>>>> 9bae1b8d... bump deps version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -12105,9 +12215,15 @@ shell-quote@1.6.1: jsonify "~0.0.0" shell-quote@^1.6.1: +<<<<<<< HEAD version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== +======= + version "1.7.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.1.tgz#3161d969886fb14f9140c65245a5dd19b6f0b06b" + integrity sha512-2kUqeAGnMAu6YrTPX4E3LfxacH9gKljzVjlkUeSqY0soGwK4KLl7TURXCem712tkhBCeeaFP9QK4dKn88s3Icg== +>>>>>>> 9bae1b8d... bump deps shell-utils@^1.0.9: version "1.0.10" From b0a75b9433329dac9ed373d2e7d2b8fde0ab1f97 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 19 Aug 2019 02:49:56 -0700 Subject: [PATCH 205/636] Move ExchangeModalNavigator to the /navigation directory --- src/hoc/withBlurTransitionProps.js | 4 +- src/hoc/withTransitionProps.js | 10 +++- src/navigation/ExchangeModalNavigator.js | 65 ++++++++++++++++++++++ src/navigation/index.js | 1 + src/navigation/transitions/expanded.js | 4 +- src/navigation/transitions/sheet.js | 4 +- src/redux/navigation.js | 25 ++++++--- src/screens/Routes.js | 69 +++--------------------- 8 files changed, 107 insertions(+), 75 deletions(-) create mode 100644 src/navigation/ExchangeModalNavigator.js diff --git a/src/hoc/withBlurTransitionProps.js b/src/hoc/withBlurTransitionProps.js index 6f054f4fb85..b9483141256 100644 --- a/src/hoc/withBlurTransitionProps.js +++ b/src/hoc/withBlurTransitionProps.js @@ -5,7 +5,7 @@ import withTransitionProps from './withTransitionProps'; const { interpolate, Value } = Animated; -const transitionPropsSelector = state => state.transitionProps; +const stackTransitionPropsSelector = state => state.stackTransitionProps; const withBlurTransitionProps = ({ isTransitioning, @@ -21,7 +21,7 @@ const withBlurTransitionProps = ({ }; const withBlurTransitionPropsSelector = createSelector( - [transitionPropsSelector], + [stackTransitionPropsSelector], withBlurTransitionProps, ); diff --git a/src/hoc/withTransitionProps.js b/src/hoc/withTransitionProps.js index 8fa94b887f0..f3a8a4459ca 100644 --- a/src/hoc/withTransitionProps.js +++ b/src/hoc/withTransitionProps.js @@ -1,6 +1,14 @@ import { connect } from 'react-redux'; -const mapStateToProps = ({ navigation: { transitionProps } }) => ({ transitionProps }); +const mapStateToProps = ({ + navigation: { + stackTransitionProps, + tabsTransitionProps, + }, +}) => ({ + stackTransitionProps, + tabsTransitionProps, +}); const withTransitionProps = Component => connect(mapStateToProps)(Component); diff --git a/src/navigation/ExchangeModalNavigator.js b/src/navigation/ExchangeModalNavigator.js new file mode 100644 index 00000000000..07d76e0ef9b --- /dev/null +++ b/src/navigation/ExchangeModalNavigator.js @@ -0,0 +1,65 @@ +import { get } from 'lodash'; +import React from 'react'; +import Animated from 'react-native-reanimated'; +import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; +import { updateTabsTransitionProps } from '../redux/navigation'; +import store from '../redux/store'; +import CurrencySelectModal from '../screens/CurrencySelectModal'; +import ExchangeModal from '../screens/ExchangeModal'; +import { colors } from '../styles'; +import { deviceUtils } from '../utils'; + +const onTransitionEnd = () => store.dispatch(updateTabsTransitionProps({ isTransitioning: false })); +const onTransitionStart = () => store.dispatch(updateTabsTransitionProps({ isTransitioning: true })); + +const ExchangeModalTabPosition = new Animated.Value(0); + +const ExchangeModalNavigator = createMaterialTopTabNavigator({ + MainExchangeScreen: { + params: { + position: ExchangeModalTabPosition, + }, + screen: ExchangeModal, + }, + CurrencySelectScreen: { + params: { + position: ExchangeModalTabPosition, + }, + screen: CurrencySelectModal, + }, +}, { + disableKeyboardHandling: true, + headerMode: 'none', + initialLayout: deviceUtils.dimensions, + keyboardDismissMode: 'none', + keyboardShouldPersistTaps: 'always', + mode: 'modal', + onTransitionEnd, + onTransitionStart, + position: ExchangeModalTabPosition, + springConfig: { + damping: 40, + mass: 1, + overshootClamping: false, + restDisplacementThreshold: 0.01, + restSpeedThreshold: 0.01, + stiffness: 300, + }, + swipeDistanceMinimum: 0, + swipeVelocityImpact: 1, + swipeVelocityScale: 1, + tabBarComponent: null, + transparentCard: true, +}); + +// I need it for changing navigationOptions dynamically +// for preventing swipe down to close on CurrencySelectScreen +const EnhancedExchangeModalNavigator = React.memo(props => ); + +EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; +EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ + ...navigation.state.params, + gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), +}); + +export default EnhancedExchangeModalNavigator; diff --git a/src/navigation/index.js b/src/navigation/index.js index 0d40aae2802..173a70eda2e 100644 --- a/src/navigation/index.js +++ b/src/navigation/index.js @@ -1,2 +1,3 @@ +export { default as ExchangeModalNavigator } from './ExchangeModalNavigator'; export { default as Navigation } from './Navigation'; export { default as SpringConfig } from './SpringConfig'; diff --git a/src/navigation/transitions/expanded.js b/src/navigation/transitions/expanded.js index 573c4958c77..550ff3f6cc8 100644 --- a/src/navigation/transitions/expanded.js +++ b/src/navigation/transitions/expanded.js @@ -1,6 +1,6 @@ import { get } from 'lodash'; import { Animated, Easing } from 'react-native'; -import { updateTransitionProps } from '../../redux/navigation'; +import { updateStackTransitionProps } from '../../redux/navigation'; import store from '../../redux/store'; import { colors } from '../../styles'; import { deviceUtils, statusBar } from '../../utils'; @@ -33,7 +33,7 @@ export default function expanded(navigation, transitionProps, prevTransitionProp scene, } = sceneProps; - store.dispatch(updateTransitionProps({ + store.dispatch(updateStackTransitionProps({ effect: transitionName, nextIndex, position, diff --git a/src/navigation/transitions/sheet.js b/src/navigation/transitions/sheet.js index 6aebefb54cd..17dbed569aa 100644 --- a/src/navigation/transitions/sheet.js +++ b/src/navigation/transitions/sheet.js @@ -1,7 +1,7 @@ import { get } from 'lodash'; import { Animated, Easing } from 'react-native'; import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; -import { updateTransitionProps } from '../../redux/navigation'; +import { updateStackTransitionProps } from '../../redux/navigation'; import store from '../../redux/store'; import { colors } from '../../styles'; import { deviceUtils, statusBar } from '../../utils'; @@ -38,7 +38,7 @@ export default function sheet(navigation, transitionProps, prevTransitionProps) scene, } = sceneProps; - store.dispatch(updateTransitionProps({ + store.dispatch(updateStackTransitionProps({ effect: transitionName, nextIndex, position, diff --git a/src/redux/navigation.js b/src/redux/navigation.js index 4ac8b2b80ca..bbd6eba29c8 100644 --- a/src/redux/navigation.js +++ b/src/redux/navigation.js @@ -4,24 +4,37 @@ import { Animated } from 'react-native'; const { Value } = Animated; // -- Constants --------------------------------------- // -const UPDATE_TRANSITION_PROPS = 'navigation/UPDATE_TRANSITION_PROPS'; +const UPDATE_STACK_TRANSITION_PROPS = 'navigation/UPDATE_STACK_TRANSITION_PROPS'; +const UPDATE_TABS_TRANSITION_PROPS = 'navigation/UPDATE_TABS_TRANSITION_PROPS'; -export const updateTransitionProps = (payload) => (dispatch) => { - dispatch({ payload, type: UPDATE_TRANSITION_PROPS }); +export const updateStackTransitionProps = (payload) => (dispatch) => { + dispatch({ payload, type: UPDATE_STACK_TRANSITION_PROPS }); +}; + +export const updateTabsTransitionProps = (payload) => (dispatch) => { + dispatch({ payload, type: UPDATE_TABS_TRANSITION_PROPS }); }; // -- Reducer ----------------------------------------- // const INITIAL_STATE = { - transitionProps: { + stackTransitionProps: { + blurColor: null, + effect: '', isTransitioning: false, position: new Value(0), }, + tabsTransitionProps: { + isTransitioning: false, + }, }; export default (state = INITIAL_STATE, action) => ( produce(state, draft => { - if (action.type === UPDATE_TRANSITION_PROPS) { - Object.assign(draft.transitionProps, action.payload); + if (action.type === UPDATE_STACK_TRANSITION_PROPS) { + Object.assign(draft.stackTransitionProps, action.payload); + } + if (action.type === UPDATE_TABS_TRANSITION_PROPS) { + Object.assign(draft.tabsTransitionProps, action.payload); } }) ); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index cb8f05bcb42..1b37557aa8f 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -7,9 +7,8 @@ import { createMaterialTopTabNavigator, } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; -import { createMaterialTopTabNavigator as newTopTabNavigator } from 'react-navigation-tabs'; -import { Navigation } from '../navigation'; -import { updateTransitionProps } from '../redux/navigation'; +import { ExchangeModalNavigator, Navigation } from '../navigation'; +import { updateStackTransitionProps } from '../redux/navigation'; import store from '../redux/store'; import { colors } from '../styles'; import { deviceUtils } from '../utils'; @@ -31,12 +30,9 @@ import { onTransitionStart as onTransitionStartEffect, } from '../navigation/transitions/effects'; import restoreKeyboard from './restoreKeyboard'; -import ExchangeModal from './ExchangeModal'; -import CurrencySelectModal from './CurrencySelectModal'; -const onTransitionEnd = () => store.dispatch(updateTransitionProps({ isTransitioning: false })); - -const onTransitionStart = () => store.dispatch(updateTransitionProps({ isTransitioning: true })); +const onTransitionEnd = () => store.dispatch(updateStackTransitionProps({ isTransitioning: false })); +const onTransitionStart = () => store.dispatch(updateStackTransitionProps({ isTransitioning: true })); const SwipeStack = createMaterialTopTabNavigator({ ProfileScreen: { @@ -70,57 +66,6 @@ const SwipeStack = createMaterialTopTabNavigator({ tabBarComponent: null, }); -const ExchangeModalTabPosition = new Animated.Value(0); - -const ExchangeModalNavigator = newTopTabNavigator({ - MainExchangeScreen: { - params: { - position: ExchangeModalTabPosition, - }, - screen: ExchangeModal, - }, - CurrencySelectScreen: { - params: { - position: ExchangeModalTabPosition, - }, - screen: CurrencySelectModal, - }, -}, { - disableKeyboardHandling: true, - headerMode: 'none', - initialLayout: deviceUtils.dimensions, - keyboardDismissMode: 'none', - keyboardShouldPersistTaps: 'always', - mode: 'modal', - // onSwipeEnd: onTransitionEnd, - // onSwipeStart: onTransitionStart, - onTransitionEnd, - onTransitionStart, - position: ExchangeModalTabPosition, - springConfig: { - damping: 40, - mass: 1, - overshootClamping: false, - restDisplacementThreshold: 0.01, - restSpeedThreshold: 0.01, - stiffness: 300, - }, - swipeDistanceMinimum: 0, - swipeVelocityImpact: 1, - swipeVelocityScale: 1, - tabBarComponent: null, - transparentCard: true, -}); - -// I need it for changing navigationOptions dynamically -// for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = props => ;//React.memo(); -EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; -EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ - ...navigation.state.params, - gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), -}); - const MainNavigator = createStackNavigator({ ConfirmRequest: { navigationOptions: { @@ -139,7 +84,7 @@ const MainNavigator = createStackNavigator({ params: { isGestureBlocked: false, }, - screen: EnhancedExchangeModalNavigator, + screen: ExchangeModalNavigator, }, ExpandedAssetScreen: { navigationOptions: { @@ -233,9 +178,9 @@ const AppContainerWithAnalytics = ({ ref, screenProps }) => ( let paramsToTrack = null; if (prevRouteName === 'MainExchangeScreen' && routeName === 'WalletScreen') { - store.dispatch(updateTransitionProps({ blurColor: null })); + store.dispatch(updateStackTransitionProps({ blurColor: null })); } else if (prevRouteName === 'WalletScreen' && routeName === 'MainExchangeScreen') { - store.dispatch(updateTransitionProps({ blurColor: colors.alpha(colors.black, 0.9) })); + store.dispatch(updateStackTransitionProps({ blurColor: colors.alpha(colors.black, 0.9) })); } if (routeName === 'ExpandedAssetScreen') { From 7847d0af564836c0736999a79885619fc1b3994d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 19 Aug 2019 02:51:23 -0700 Subject: [PATCH 206/636] Update WarningIcon --- src/components/icons/svg/WarningIcon.js | 6 ++--- src/components/text/ErrorText.js | 33 ++++++++++++++----------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/components/icons/svg/WarningIcon.js b/src/components/icons/svg/WarningIcon.js index e948336c008..a4a8539fa5a 100644 --- a/src/components/icons/svg/WarningIcon.js +++ b/src/components/icons/svg/WarningIcon.js @@ -6,11 +6,11 @@ import Svg from '../Svg'; /* eslint-disable max-len */ const WarningIcon = ({ color, ...props }) => ( - + ); diff --git a/src/components/text/ErrorText.js b/src/components/text/ErrorText.js index 01de9cfe855..f9b7fd7c0ff 100644 --- a/src/components/text/ErrorText.js +++ b/src/components/text/ErrorText.js @@ -1,21 +1,26 @@ import PropTypes from 'prop-types'; import React from 'react'; -import styled from 'styled-components/primitives'; -import Icon from '../icons/Icon'; -import { Row } from '../layout'; -import Monospace from './Monospace'; +import { withNeverRerender } from '../../hoc'; import { colors, fonts } from '../../styles'; - -const Text = styled(Monospace).attrs({ size: 'lmedium', weight: 'medium' })` - line-height: ${fonts.lineHeight.looser}; - margin-left: ${fonts.size.micro}; -`; +import { Icon } from '../icons'; +import { RowWithMargins } from '../layout'; +import Monospace from './Monospace'; const ErrorText = ({ color, error }) => ( - - - {error} - + + + + {error} + + ); ErrorText.propTypes = { @@ -27,4 +32,4 @@ ErrorText.defaultProps = { color: colors.red, }; -export default ErrorText; +export default withNeverRerender(ErrorText); From f23c9d3c86e8c83e1e0705de80f96e0810b00c55 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 19 Aug 2019 02:51:33 -0700 Subject: [PATCH 207/636] Create LockIcon --- src/components/icons/Icon.js | 2 ++ src/components/icons/svg/LockIcon.js | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/components/icons/svg/LockIcon.js diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index 43c3d252c90..ef00e955fb5 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -23,6 +23,7 @@ import FaceIdIcon from './svg/FaceIdIcon'; import GearIcon from './svg/GearIcon'; import HandleIcon from './svg/HandleIcon'; import InboxIcon from './svg/InboxIcon'; +import LockIcon from './svg/LockIcon'; import OfflineIcon from './svg/OfflineIcon'; import ProgressIcon from './svg/ProgressIcon'; import SearchIcon from './svg/SearchIcon'; @@ -62,6 +63,7 @@ Icon.IconTypes = { gear: GearIcon, handle: HandleIcon, inbox: InboxIcon, + lock: LockIcon, offline: OfflineIcon, progress: ProgressIcon, search: SearchIcon, diff --git a/src/components/icons/svg/LockIcon.js b/src/components/icons/svg/LockIcon.js new file mode 100644 index 00000000000..3447dbadb61 --- /dev/null +++ b/src/components/icons/svg/LockIcon.js @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Path } from 'svgs'; +import { colors } from '../../../styles'; +import Svg from '../Svg'; + +/* eslint-disable max-len */ +const LockIcon = ({ color, ...props }) => ( + + + +); +/* eslint-disable max-len */ + +LockIcon.propTypes = { + color: PropTypes.string, +}; + +LockIcon.defaultProps = { + color: colors.black, +}; + +export default LockIcon; From 90bc43a780b04fbeb63d176804ff83b8ed48a624 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 19 Aug 2019 02:51:56 -0700 Subject: [PATCH 208/636] Create EnDash html-entity component --- src/components/html-entities/EnDash.js | 8 ++++++++ src/components/html-entities/index.js | 1 + 2 files changed, 9 insertions(+) create mode 100644 src/components/html-entities/EnDash.js diff --git a/src/components/html-entities/EnDash.js b/src/components/html-entities/EnDash.js new file mode 100644 index 00000000000..c3c27574d0c --- /dev/null +++ b/src/components/html-entities/EnDash.js @@ -0,0 +1,8 @@ +import React from 'react'; +import { Text } from 'react-primitives'; + +const unicodeValue = '\u2013'; + +const EnDash = props => {unicodeValue}; +EnDash.unicode = unicodeValue; +export default EnDash; diff --git a/src/components/html-entities/index.js b/src/components/html-entities/index.js index a541bbc29ed..50af92eac0e 100644 --- a/src/components/html-entities/index.js +++ b/src/components/html-entities/index.js @@ -1,2 +1,3 @@ export { default as EmDash } from './EmDash'; +export { default as EnDash } from './EnDash'; export { default as Nbsp } from './Nbsp'; From 83251ae297023abe1cb53148822fa69a3ba041f8 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 19 Aug 2019 04:04:05 -0700 Subject: [PATCH 209/636] Progress on ExchangeModal UI components --- package.json | 1 + src/components/buttons/CoolButton.js | 10 +- src/components/coin-row/ExchangeCoinRow.js | 19 ++- .../exchange/ConfirmExchangeButton.js | 4 +- src/components/exchange/ExchangeAssetList.js | 47 ++++-- .../exchange/ExchangeGasFeeButton.js | 62 ++++--- src/components/exchange/ExchangeInput.js | 15 +- src/components/exchange/ExchangeInputField.js | 155 +++++++++++++----- .../exchange/ExchangeOutputField.js | 9 +- src/components/exchange/ExchangeSearch.js | 2 +- src/components/exchange/SlippageWarning.js | 93 +++++++++++ src/components/exchange/UnlockAssetButton.js | 64 ++++++++ src/components/exchange/index.js | 2 + .../expanded-state/FloatingPanels.js | 4 +- .../layout/KeyboardFixedOpenLayout.js | 4 +- src/helpers/utilities.js | 14 -- src/navigation/ExchangeModalNavigator.js | 2 +- src/references/native-currencies.json | 20 +-- src/screens/CurrencySelectModal.js | 23 +-- src/screens/ExchangeModal.js | 147 ++++++++++------- src/styles/colors.js | 2 + src/utils/ethereumUtils.js | 1 + yarn.lock | 12 ++ 23 files changed, 510 insertions(+), 202 deletions(-) create mode 100644 src/components/exchange/SlippageWarning.js create mode 100644 src/components/exchange/UnlockAssetButton.js diff --git a/package.json b/package.json index fe080cd8d8b..8da2ebe8f26 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "postinstall": "patch-package && rn-nodeify --install --hack" }, "dependencies": { + "@bankify/react-native-animate-number": "^0.2.1", "@hocs/omit-props": "^0.4.0", "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", diff --git a/src/components/buttons/CoolButton.js b/src/components/buttons/CoolButton.js index 9d9b6f66660..b43d421fa77 100644 --- a/src/components/buttons/CoolButton.js +++ b/src/components/buttons/CoolButton.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { compose, onlyUpdateForPropTypes, withProps } from 'recompact'; +import { compose, onlyUpdateForKeys, withProps } from 'recompact'; import { withNeverRerender } from '../../hoc'; import { colors, @@ -32,7 +32,9 @@ const CoolLabel = withProps({ weight: 'semibold', })(Text); -const CoolButton = ({ +const enhance = onlyUpdateForKeys(['children', 'color']); + +const CoolButton = enhance(({ borderRadius, children, color, @@ -59,7 +61,7 @@ const CoolButton = ({ -); +)); CoolButton.propTypes = { borderRadius: PropTypes.number, @@ -78,4 +80,4 @@ CoolButton.defaultProps = { ], }; -export default onlyUpdateForPropTypes(CoolButton); +export default CoolButton; diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 0d6e771fe1a..b7e77587019 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { View } from 'react-native'; +import { withNeverRerender } from '../../hoc'; import { colors, padding } from '../../styles'; import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; @@ -47,11 +48,17 @@ export default class ExchangeCoinRow extends Component { favorite: false, } - shouldComponentUpdate = (nextProps, nextState) => ( - isNewValueForPath(this.props, nextProps, 'uniqueId') - || isNewValueForPath(this.state, nextState, 'favorite') - || isNewValueForPath(this.state, nextState, 'emojiCount') - ) + shouldComponentUpdate = (nextProps, nextState) => { + const isNewAsset = isNewValueForPath(this.props, nextProps, 'uniqueId'); + const isNewFavorite = isNewValueForPath(this.state, nextState, 'favorite'); + const isNewEmojiCount = isNewValueForPath(this.state, nextState, 'emojiCount'); + + return ( + isNewAsset + || isNewFavorite + || isNewEmojiCount + ); + } handlePress = () => { const { item, onPress } = this.props; @@ -75,8 +82,6 @@ export default class ExchangeCoinRow extends Component { const { item, ...props } = this.props; const { emojiCount, favorite } = this.state; - // console.log('this.props', this.props); - return ( ( +const ConfirmExchangeButton = ({ disabled, onPress, ...props }) => ( ( [0, 1, 18, colors.black, 0.12], ]} theme="dark" + {...props} > {disabled ? 'Enter an amount' diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index e8138bb17f6..05ad5b13146 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -2,7 +2,7 @@ import { get, property } from 'lodash'; import lang from 'i18n-js'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { View } from 'react-native'; +import { LayoutAnimation, View } from 'react-native'; import { DataProvider, LayoutProvider, RecyclerListView } from "recyclerlistview"; import styled from 'styled-components/primitives'; import { deviceUtils, isNewValueForPath } from '../../utils'; @@ -14,10 +14,32 @@ const ViewTypes = { COIN_ROW: 0, }; -const hasRowChanged = (...rows) => isNewValueForPath(...rows, 'uniqueId'); +const NOOP = () => undefined; + +const layoutItemAnimator = { + animateDidMount: NOOP, + animateShift: () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')), + animateWillMount: NOOP, + animateWillUnmount: NOOP, + animateWillUpdate: NOOP, +}; const buildUniqueIdForListData = (items = []) => items.map(property('address')).join('_'); +const getLayoutTypeForIndex = () => ViewTypes.COIN_ROW; + +const hasRowChanged = (r1, r2) => isNewValueForPath(r1, r2, 'uniqueId'); + +const setLayoutForType = (type, dim) => { + if (type === ViewTypes.COIN_ROW) { + dim.width = deviceUtils.dimensions.width; + dim.height = CoinRow.height; + } else { + dim.width = 0; + dim.height = 0; + } +}; + export default class ExchangeAssetList extends PureComponent { static propTypes = { items: PropTypes.arrayOf(PropTypes.object), @@ -31,19 +53,9 @@ export default class ExchangeAssetList extends PureComponent { dataProvider: new DataProvider(hasRowChanged, this.getStableId), } - // this.state.dataProvider._requiresDataChangeHandling = true; - - this.layoutProvider = new LayoutProvider(() => { - return ViewTypes.COIN_ROW; - }, (type, dim) => { - if (type === ViewTypes.COIN_ROW) { - dim.width = deviceUtils.dimensions.width; - dim.height = CoinRow.height; - } else { - dim.width = 0; - dim.height = 0; - } - }) + this.state.dataProvider._requiresDataChangeHandling = true; + + this.layoutProvider = new LayoutProvider(getLayoutTypeForIndex, setLayoutForType) } rlvRef = React.createRef() @@ -54,7 +66,7 @@ export default class ExchangeAssetList extends PureComponent { componentDidUpdate = (prevProps, prevState) => { if (this.props.items.length !== prevProps.items.length) { - // this.rlvRef.current.forceRerender(); + this.rlvRef.current.forceRerender(); this.updateList(); } } @@ -75,11 +87,12 @@ export default class ExchangeAssetList extends PureComponent { {...this.props} dataProvider={this.state.dataProvider} layoutProvider={this.layoutProvider} + itemAnimator={layoutItemAnimator} onContentSizeChange={this.onContentSizeChange} onViewableItemsChanged={this.onViewableItemsChanged} optimizeForInsertDeleteAnimations={true} ref={this.rlvRef} - renderAheadOffset={deviceUtils.dimensions.height / 2} + renderAheadOffset={deviceUtils.dimensions.height} rowRenderer={this.renderRow} scrollViewProps={{ directionalLockEnabled: true, diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js index 403a1f3efe4..7c3e6dbe377 100644 --- a/src/components/exchange/ExchangeGasFeeButton.js +++ b/src/components/exchange/ExchangeGasFeeButton.js @@ -1,19 +1,25 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { compose, pure, withHandlers } from 'recompact'; +import { compose, pure, withHandlers, withProps } from 'recompact'; import styled from 'styled-components/primitives'; import { colors, padding, shadow } from '../../styles'; import { ButtonPressAnimation } from '../animations'; -import { RowWithMargins } from '../layout'; +import { Nbsp } from '../html-entities'; +import { Column, Row } from '../layout'; import { Emoji, Text } from '../text'; -const Container = styled(RowWithMargins)` - ${padding(5.5, 10)}; - ${shadow.build(0, 0, 1, colors.dark, 1)}; - border-color: ${colors.alpha(colors.white, 0.15)}; - border-radius: 16; - border-width: 1.75; -`; +const Label = withProps({ + color: colors.alpha(colors.white, 0.4), + size: 'smedium', + weight: 'medium', +})(Text); + +const Title = withProps({ + color: colors.white, + letterSpacing: 'tight', + size: 'lmedium', + weight: 'semibold', +})(Text); const enhance = compose( pure, @@ -28,21 +34,29 @@ const enhance = compose( const ExchangeGasFeeButton = enhance(({ gasPrice, onPress }) => ( - - - - {`Fee: ${gasPrice}`} - - + + + {gasPrice} + + + + + Normal + + + + + + + + + + + )); diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 687df07d020..3845faeff92 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -6,7 +6,10 @@ import { colors, fonts } from '../../styles'; export default class ExchangeInput extends PureComponent { static propTypes = { + disableTabularNums: PropTypes.bool, + fontFamily: PropTypes.string, fontSize: PropTypes.string, + fontWeight: PropTypes.number, mask: PropTypes.string, onChangeText: PropTypes.func, placeholder: PropTypes.string, @@ -16,7 +19,9 @@ export default class ExchangeInput extends PureComponent { } static defaultProps = { + fontFamily: fonts.family.SFProDisplay, fontSize: fonts.size.h2, + fontWeight: fonts.weight.medium, mask: '[099999999999].[9999999999999]', placeholder: '0', placeholderTextColor: colors.alpha(colors.blueGreyDark, 0.5), @@ -29,7 +34,10 @@ export default class ExchangeInput extends PureComponent { render = () => { const { + disableTabularNums, + fontFamily, fontSize, + fontWeight, mask, onChangeText, placeholder, @@ -53,10 +61,11 @@ export default class ExchangeInput extends PureComponent { refInput={refInput} selectionColor={colors.appleBlue} style={[{ - fontFamily: fonts.family.SFProDisplay, + color: colors.dark, + fontFamily, fontSize: parseFloat(fontSize), - fontVariant: ['tabular-nums'], - fontWeight: fonts.weight.medium, + fontVariant: disableTabularNums ? undefined : ['tabular-nums'], + fontWeight, }, style]} value={value} /> diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 5314758d3ea..d9b6f09c966 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -1,11 +1,13 @@ -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; import supportedNativeCurrencies from '../../references/native-currencies.json'; import { colors, fonts } from '../../styles'; +import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; +import { EnDash } from '../html-entities'; import { ColumnWithMargins, Row, @@ -13,13 +15,14 @@ import { } from '../layout'; import { Emoji, Text } from '../text'; import ExchangeInput from './ExchangeInput'; +import UnlockAssetButton from './UnlockAssetButton'; -export default class ExchangeInputField extends PureComponent { +export default class ExchangeInputField extends Component { static propTypes = { - autoFocus: PropTypes.bool, inputAmount: PropTypes.string, inputCurrency: PropTypes.string, inputFieldRef: PropTypes.func, + isAssetApproved: PropTypes.bool, nativeAmount: PropTypes.string, nativeCurrency: PropTypes.string, nativeFieldRef: PropTypes.func, @@ -34,12 +37,34 @@ export default class ExchangeInputField extends PureComponent { padding = 15 + shouldComponentUpdate = (nextProps, nextState) => { + const isNewInputAmount = isNewValueForPath(this.props, nextProps, 'inputAmount'); + const isNewInputCurrency = isNewValueForPath(this.props, nextProps, 'inputCurrency'); + const isNewAssetApproved = isNewValueForPath(this.props, nextProps, 'isAssetApproved'); + const isNewNativeAmount = isNewValueForPath(this.props, nextProps, 'nativeAmount'); + const isNewNativeCurrency = isNewValueForPath(this.props, nextProps, 'nativeCurrency'); + + return ( + isNewInputAmount + || isNewInputCurrency + || isNewAssetApproved + || isNewNativeAmount + || isNewNativeCurrency + ) + } + handleFocusInputField = () => { if (this.inputFieldRef) { this.inputFieldRef.focus(); } } + handleFocusNativeField = () => { + if (this.nativeFieldRef) { + this.nativeFieldRef.focus(); + } + } + handleInputFieldRef = (ref) => { this.inputFieldRef = ref; this.props.inputFieldRef(ref); @@ -50,23 +75,68 @@ export default class ExchangeInputField extends PureComponent { this.props.nativeFieldRef(ref); } - render = () => { + renderNativeField = () => { const { - autoFocus, - inputAmount, - inputCurrency, - inputFieldRef, nativeAmount, nativeCurrency, nativeFieldRef, onFocus, + setNativeAmount, + } = this.props; + + const { mask, placeholder, symbol } = supportedNativeCurrencies[nativeCurrency]; + + const symbolColor = ( + !!nativeAmount + ? colors.dark + : ExchangeInput.defaultProps.placeholderTextColor + ); + + return ( + + + + {symbol} + + + + + ); + } + + render = () => { + const { + inputAmount, + inputCurrency, + isAssetApproved, + onFocus, onPressMaxBalance, onPressSelectInputCurrency, + onPressUnlockAsset, setInputAmount, - setNativeAmount, } = this.props; - const { mask, placeholder } = supportedNativeCurrencies[nativeCurrency]; + const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); return ( @@ -78,15 +148,21 @@ export default class ExchangeInputField extends PureComponent { margin={11} paddingLeft={this.padding} > - - - - + + - - - - - - Max - - + + {this.renderNativeField()} + {isAssetApproved ? ( + + + + Max + + + ) : ( + + )} ); diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index ff513ad477d..1e50fdde601 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -4,7 +4,7 @@ import { withNeverRerender } from '../../hoc'; import { colors, padding, position, shadow } from '../../styles'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; -import { EmDash } from '../html-entities'; +import { EnDash } from '../html-entities'; import { Row, RowWithMargins } from '../layout'; import { ShadowStack } from '../shadow-stack'; import ExchangeInput from './ExchangeInput'; @@ -63,7 +63,6 @@ export default class ExchangeOutputField extends PureComponent { } = this.props; const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); - const placeholderColor = colors.alpha(colors.blueGreyDark, 0.5); return ( diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 884e96884fc..9babe391107 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -59,7 +59,7 @@ class ExchangeSearch extends PureComponent { color={colors.dark} flex={1} keyboardAppearance="dark" - keyboardType="default" + keyboardType="ascii-capable" lineHeight="loose" onChangeText={this.props.onChangeText} onFocus={this.props.onFocus} diff --git a/src/components/exchange/SlippageWarning.js b/src/components/exchange/SlippageWarning.js new file mode 100644 index 00000000000..0491fb342c3 --- /dev/null +++ b/src/components/exchange/SlippageWarning.js @@ -0,0 +1,93 @@ +import AnimateNumber from '@bankify/react-native-animate-number'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { + compose, + onlyUpdateForKeys, + withProps, +} from 'recompact'; +import styled from 'styled-components/primitives'; +import { colors, padding } from '../../styles'; +import { Icon } from '../icons'; +import { Row, RowWithMargins } from '../layout'; +import { Text } from '../text'; + +const SevereSlippageThreshold = 10; + +const Container = styled(Row).attrs({ + align: 'center', + justify: 'space-between', +})` + ${padding(19, 19, 2)}; + flex-shrink: 0; + width: 100%; +`; + +const formatSlippage = (slippage) => ( + slippage + ? parseFloat(slippage).toFixed(1) + : 0 +); + +const renderSlippageText = (displayValue) => ( + + {`${displayValue}% premium`} + +); + +const enhance = compose( + onlyUpdateForKeys(['slippage']), + withProps(({ slippage }) => { + const fixedSlippage = formatSlippage(slippage); + const isSevere = fixedSlippage > SevereSlippageThreshold; + + return { + isSevere, + severityColor: isSevere ? colors.brightRed : colors.brightOrange, + slippage: fixedSlippage, + }; + }), +); + +const SlippageWarning = enhance(({ + isSevere, + severityColor, + slippage, +}) => ( + (slippage < (SevereSlippageThreshold / 2)) + ? null + : ( + + + + + + + {isSevere + ? 'Please swap less' + : 'Consider swapping less' + } + + + ) +)); + +SlippageWarning.propTypes = { + isSevere: PropTypes.bool, + onPress: PropTypes.func, + severityColor: PropTypes.string, + slippage: PropTypes.string, +}; + +export default SlippageWarning; diff --git a/src/components/exchange/UnlockAssetButton.js b/src/components/exchange/UnlockAssetButton.js new file mode 100644 index 00000000000..a2bb8f7407a --- /dev/null +++ b/src/components/exchange/UnlockAssetButton.js @@ -0,0 +1,64 @@ +import React from 'react'; +import { withNeverRerender } from '../../hoc'; +import { + colors, + fonts, + margin, + padding, + position, +} from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { CoolButton } from '../buttons'; +import { Icon } from '../icons'; +import InnerBorder from '../InnerBorder'; +import { Row, RowWithMargins } from '../layout'; +import { ShadowStack } from '../shadow-stack'; +import { Text } from '../text'; + +const UnlockAssetButton = ({ + borderRadius, + children, + color, + onPress, + shadows, +}) => ( + + + + + + + Locked + + + + + +); + +UnlockAssetButton.propTypes = CoolButton.propTypes; + +UnlockAssetButton.defaultProps = CoolButton.defaultProps; + +export default withNeverRerender(UnlockAssetButton); diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js index a4ebe963aa5..cfa2adb013f 100644 --- a/src/components/exchange/index.js +++ b/src/components/exchange/index.js @@ -6,3 +6,5 @@ export { default as ExchangeInputField } from './ExchangeInputField'; export { default as ExchangeModalHeader } from './ExchangeModalHeader'; export { default as ExchangeOutputField } from './ExchangeOutputField'; export { default as ExchangeSearch } from './ExchangeSearch'; +export { default as SlippageWarning } from './SlippageWarning'; +export { default as UnlockAssetButton } from './UnlockAssetButton'; diff --git a/src/components/expanded-state/FloatingPanels.js b/src/components/expanded-state/FloatingPanels.js index bccf16707c1..a19dc014f51 100644 --- a/src/components/expanded-state/FloatingPanels.js +++ b/src/components/expanded-state/FloatingPanels.js @@ -6,9 +6,9 @@ const FloatingPanelsMargin = 20; const FloatingPanels = compose( setDisplayName('FloatingPanels'), - withProps(({ style }) => ({ + withProps(({ margin = FloatingPanelsMargin, style }) => ({ justify: 'center', - margin: FloatingPanelsMargin, + margin, pointerEvents: 'box-none', style: [position.sizeAsObject('100%'), style], })), diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index c7ba1230ab9..7b2788e683d 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -4,7 +4,7 @@ import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { compose, onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components/primitives'; import { withKeyboardHeight } from '../../hoc'; -import { colors, position } from '../../styles'; +import { colors, padding, position } from '../../styles'; import { deviceUtils, safeAreaInsetValues } from '../../utils'; import { Centered } from '../layout'; @@ -18,9 +18,9 @@ const Container = styled.View` `; const InnerWrapper = styled(Centered)` + ${padding(safeAreaInsetValues.top, 0, 10)}; ${position.size('100%')}; background-color: ${colors.transparent}; - padding-bottom: 10; `; class KeyboardFixedOpenLayout extends PureComponent { diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index f7480facab5..8682f4b50f5 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -341,20 +341,6 @@ export const convertAmountToNativeDisplay = (value, nativeCurrency, buffer) => { return `${display} ${nativeSelected.currency}`; }; -/** - * @desc convert to amount value from display formatted string - * @param {String} formatted native value - * @param {String} nativeCurrency - * @return {String} - */ -export const convertAmountFromNativeDisplay = (nativeDisplayValue, nativeCurrency) => { - const nativeSelected = supportedNativeCurrencies[nativeCurrency]; - if (nativeSelected.alignment === 'left') { - return nativeDisplayValue.trim().slice(1); - } - return split(nativeDisplayValue, ' ')[0]; -}; - /** * @desc convert from raw amount to decimal format * @param {String|Number} value diff --git a/src/navigation/ExchangeModalNavigator.js b/src/navigation/ExchangeModalNavigator.js index 07d76e0ef9b..963da9d9968 100644 --- a/src/navigation/ExchangeModalNavigator.js +++ b/src/navigation/ExchangeModalNavigator.js @@ -54,7 +54,7 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = React.memo(props => ); +const EnhancedExchangeModalNavigator = props => ;//React.memo(); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ diff --git a/src/references/native-currencies.json b/src/references/native-currencies.json index 74f824c7a4e..8f8aabc9a7d 100644 --- a/src/references/native-currencies.json +++ b/src/references/native-currencies.json @@ -6,8 +6,8 @@ "decimals": 2, "emojiName": "us", "label": "United States Dollar", - "mask": "{$}[099999999999]{.}[00]", - "placeholder": "$0.00", + "mask": "[099999999999]{.}[00]", + "placeholder": "0.00", "symbol": "$" }, "CNY": { @@ -17,8 +17,8 @@ "decimals": 2, "emojiName": "cn", "label": "Chinese Yuan", - "mask": "{¥}[099999999999]{.}[00]", - "placeholder": "¥0.00", + "mask": "[099999999999]{.}[00]", + "placeholder": "0.00", "symbol": "¥" }, "KRW": { @@ -28,8 +28,8 @@ "decimals": 0, "emojiName": "kr", "label": "South Korean Won", - "mask": "{₩}[099999999999]{.}[00]", - "placeholder": "₩0.00", + "mask": "[099999999999]{.}[00]", + "placeholder": "0.00", "symbol": "₩" }, "RUB": { @@ -39,8 +39,8 @@ "decimals": 2, "emojiName": "ru", "label": "Russian Ruble", - "mask": "{₽}[099999999999]{.}[00]", - "placeholder": "₽0.00", + "mask": "[099999999999]{.}[00]", + "placeholder": "0.00", "symbol": "₽" }, "EUR": { @@ -50,8 +50,8 @@ "decimals": 2, "emojiName": "flag-eu", "label": "Euro", - "mask": "{€}[099999999999]{.}[00]", - "placeholder": "€0.00", + "mask": "[099999999999]{.}[00]", + "placeholder": "0.00", "symbol": "€" }, "ETH": { diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index e9ceb04c6a5..6ec262e9fc0 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -94,9 +94,10 @@ class CurrencySelectModal extends PureComponent { const currentTransitioning = this.props.isTransitioning; const nextTransitioning = nextProps.isTransitioning; - if (!currentTransitioning && nextTransitioning) { - return false; - } + // if (currentTransitioning) { + // console.log('blocking'); + // return false; + // } let currentAssets = this.props.sortedUniswapAssets; let nextAssets = EMPTY_ARRAY; @@ -119,10 +120,10 @@ class CurrencySelectModal extends PureComponent { return ( isNewAssets - || isNewSearchQuery - || isNewType || isNewFocus + || isNewSearchQuery || isNewTransitioning + || isNewType ); } @@ -169,8 +170,8 @@ class CurrencySelectModal extends PureComponent { isFocused, isTransitioning, sortedUniswapAssets, - transitionPosition, type, + transitionPosition, } = this.props; const { searchQuery } = this.state; @@ -187,13 +188,13 @@ class CurrencySelectModal extends PureComponent { const listItems = filterList(assets, searchQuery, 'uniqueId'); const isLoading = ( - isTransitioning - || listItems.length === 0 - || !isFocused + isTransitioning || listItems.length === 0 ); + // console.log('isFocused', isFocused ? '👍️' : '👎️', ' ', isFocused); + return ( - + ({ ...props, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index cb65d56c7f3..8b6b02bdc69 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -16,13 +16,12 @@ import { } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; -import { InteractionManager, TextInput } from 'react-native'; +import { InteractionManager, LayoutAnimation, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationActions, NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, mapProps, toClass, withProps } from 'recompact'; import { executeSwap } from '../handlers/uniswap'; import { - convertAmountFromNativeDisplay, convertAmountFromNativeValue, convertAmountToNativeAmount, convertAmountToRawAmount, @@ -46,6 +45,7 @@ import { ExchangeInputField, ExchangeModalHeader, ExchangeOutputField, + SlippageWarning, } from '../components/exchange'; import { FloatingPanel, FloatingPanels } from '../components/expanded-state'; import GestureBlocker from '../components/GestureBlocker'; @@ -61,6 +61,16 @@ export const exchangeModalBorderRadius = 30; const AnimatedFloatingPanels = Animated.createAnimatedComponent(toClass(FloatingPanels)); +const isSameAsset = (firstAsset, secondAsset) => { + if (!firstAsset || !secondAsset) { + return false; + } + + const firstAddress = get(firstAsset, 'address', '').toLowerCase(); + const secondAddress = get(firstAsset, 'address', '').toLowerCase(); + return firstAddress === secondAddress; +} + class ExchangeModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, @@ -87,11 +97,8 @@ class ExchangeModal extends PureComponent { } componentDidUpdate = (prevProps) => { - const { - isFocused, - isTransitioning, - keyboardFocusHistory, - } = this.props; + const { isFocused, isTransitioning, keyboardFocusHistory} = this.props; + const { inputAmount, outputAmount, outputCurrency } = this.state; if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; @@ -106,7 +113,12 @@ class ExchangeModal extends PureComponent { } } - if (this.state.outputCurrency) { + if (inputAmount || outputAmount) { + LayoutAnimation.easeInEaseOut(); + } + + if (outputCurrency) { + console.log('should showConfirmButton'); this.setState({ showConfirmButton: true }); } } @@ -182,51 +194,63 @@ class ExchangeModal extends PureComponent { setInputAsExactAmount = (inputAsExactAmount) => this.setState({ inputAsExactAmount }) - setNativeAmount = async nativeAmountDisplay => { - this.setState({ nativeAmount: nativeAmountDisplay }); - const nativeAmount = convertAmountFromNativeDisplay(nativeAmountDisplay, this.props.nativeCurrency); - const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); - this.setState({ inputAmount }); + setNativeAmount = async (nativeAmount) => { + this.setState({ nativeAmount }); + const nativePrice = get(this.state.inputCurrency, 'native.price.amount', 0); + this.setState({ inputAmount: convertAmountFromNativeValue(nativeAmount, nativePrice) }); this.setInputAsExactAmount(true); await this.getMarketDetails(); } - setInputAmount = async inputAmount => { + setInputAmount = async (inputAmount) => { this.setState({ inputAmount }); - const nativeAmount = convertAmountToNativeAmount(inputAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); - this.setState({ nativeAmount }); + + let newNativeAmount = null; + if (inputAmount) { + const nativePrice = get(this.state.inputCurrency, 'native.price.amount', 0); + newNativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); + } + + this.setState({ nativeAmount: newNativeAmount }); this.setInputAsExactAmount(true); await this.getMarketDetails(); } - setOutputAmount = async outputAmount => { + setOutputAmount = async (outputAmount) => { this.setState({ outputAmount }); this.setInputAsExactAmount(false); await this.getMarketDetails(); } - setInputCurrency = inputCurrency => { - const previousInputCurrency = this.state.inputCurrency; - this.setState({ inputCurrency }); - if (inputCurrency && this.state.outputCurrency && inputCurrency.address === this.state.outputCurrency.address) { - if (this.state.outputCurrency !== null - && previousInputCurrency !== null) { - this.setOutputCurrency(previousInputCurrency); - } else { - this.setOutputCurrency(null); + setInputCurrency = (inputCurrencySelection, force) => { + const { inputCurrency, outputCurrency } = this.state; + + this.setState({ inputCurrency: inputCurrencySelection }); + + if (!force && isSameAsset(inputCurrency, outputCurrency)) { + if (outputCurrency !== null && inputCurrency !== null) { + return this.setOutputCurrency(null, true); } + + return this.setOutputCurrency(inputCurrency, true); } } - setOutputCurrency = outputCurrency => { - const previousOutputCurrency = this.state.outputCurrency; + setOutputCurrency = (outputCurrency, force) => { + const { allAssets } = this.props; + const { inputCurrency } = this.state; + this.setState({ outputCurrency }); - if (outputCurrency && this.state.inputCurrency && outputCurrency.address === this.state.inputCurrency.address) { - const asset = ethereumUtils.getAsset(this.props.allAssets, address); - if (this.state.inputCurrency !== null && previousOutputCurrency !== null && !isNil(asset)) { - this.setInputCurrency(previousOutputCurrency); + + if (!force && isSameAsset(inputCurrency, outputCurrency)) { + const asset = ethereumUtils.getAsset(allAssets, outputCurrency.address.toLowerCase()); + + console.log('asset', asset); + // + if (inputCurrency !== null && outputCurrency !== null && !isNil(asset)) { + this.setInputCurrency(null, true); } else { - this.setInputCurrency(null); + this.setInputCurrency(outputCurrency, true); } } } @@ -253,26 +277,25 @@ class ExchangeModal extends PureComponent { } handleSubmit = async () => { - const { tradeDetails } = this.state; + const { accountAddress, dataAddNewTransaction, navigation } = this.props; + const { inputAmount, inputCurrency, tradeDetails } = this.state; + try { const txn = await executeSwap(tradeDetails); if (txn) { - const txnDetails = { - amount: this.state.inputAmount, - asset: this.state.inputCurrency, - from: this.props.accountAddress, + dataAddNewTransaction({ + amount: inputAmount, + asset: inputCurrency, + from: accountAddress, hash: txn.hash, nonce: get(txn, 'nonce'), to: get(txn, 'to'), - }; - this.props.dataAddNewTransaction(txnDetails); - this.props.navigation.navigate('ProfileScreen'); - } else { - this.props.navigation.navigate('ProfileScreen'); + }); } + navigation.navigate('ProfileScreen'); } catch (error) { console.log('error submitting swap', error); - this.props.navigation.navigate('WalletScreen'); + navigation.navigate('WalletScreen'); } } @@ -316,6 +339,7 @@ class ExchangeModal extends PureComponent { outputAmount, outputCurrency, showConfirmButton, + slippage, } = this.state; return ( @@ -328,9 +352,9 @@ class ExchangeModal extends PureComponent { {...position.sizeAsObject('100%')} backgroundColor={colors.transparent} direction="column" - paddingTop={showConfirmButton ? 0 : 10} > - + - - - Slippage {this.state.slippage} - - - + {showConfirmButton && ( - + - {!!Number(inputAmount) && ( - - )} + )} + @@ -411,11 +433,16 @@ export default compose( withTransitionProps, mapProps(({ navigation, - transitionProps: { isTransitioning }, + tabsTransitionProps: { + isTransitioning: isTabsTransitioning, + }, + stackTransitionProps: { + isTransitioning: isStacksTransitioning, + }, ...props, }) => ({ ...props, - isTransitioning, + isTransitioning: isStacksTransitioning || isTabsTransitioning, navigation, transitionPosition: get(navigation, 'state.params.position'), })), diff --git a/src/styles/colors.js b/src/styles/colors.js index 3a467bdeac1..77cc9adc86a 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -11,6 +11,8 @@ const base = { blueGreyLightest: '#888D96', // '136, 141, 150' blueGreyMedium: '#636875', // '99, 104, 117' blueGreyMediumLight: '#7b7f8a', // '123, 127, 138' + brightOrange: '#FFB624', // '255, 182, 36' + brightRed: '#FF4B19', // '255, 75, 25' dark: '#25292E', // '37, 41, 46' darkGrey: '#71778a', // '113, 119, 138' dodgerBlue: '#575CFF', // '87, 92, 255' diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index 5b893abf932..297193d7fbc 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -100,6 +100,7 @@ export const transactionData = (assets, assetAmount, gasPrice) => { export default { getAsset, + getBalanceAmount, getChainIdFromNetwork, getDataString, getNetworkFromChainId, diff --git a/yarn.lock b/yarn.lock index e11d6cdfc72..140fd805ccf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1164,6 +1164,13 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@bankify/react-native-animate-number@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@bankify/react-native-animate-number/-/react-native-animate-number-0.2.1.tgz#80b2d700d0556b2d57ec1757a37454fcfbd968b8" + integrity sha512-rBIiZZWAU6Nfr7bqJ6Dc0vAqk8Xf0LU3otrad9jbrJQOUJRUSUf9nWttQVLW4/alKTYq1kXkGYJ1l4dsTQbLmA== + dependencies: + babel-plugin-syntax-async-functions "^6.8.0" + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -3321,6 +3328,11 @@ babel-plugin-rewire@^1.2.0: babel-plugin-syntax-jsx "^6.18.0" lodash "^4.17.11" +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" From 3aa1d061457e51f1f0a8c9443d7f2d2f2284afd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Mon, 26 Aug 2019 13:45:46 +0200 Subject: [PATCH 210/636] Remove leftovers from conflict --- android/app/build.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 487984e81f9..c7960730d32 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -153,16 +153,12 @@ android { } dependencies { -<<<<<<< HEAD - implementation project(':@react-native-community_masked-view') -======= - implementation project(':react-native-text-input-mask') ->>>>>>> d743296d... BREAK UP implementation project(':@segment_analytics-react-native') implementation project(':react-native-firebase') implementation project(':@staltz_react-native-tcp') implementation project(':@react-native-community_blur') implementation project(':@react-native-community_netinfo') + implementation project(':@react-native-community_masked-view') implementation project(':@react-native-community_async-storage') implementation project(':react-native-camera') compile project(':react-native-device-info') From 277abed5c63346c9a85c4048a48f00967af9133b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Mon, 26 Aug 2019 14:48:21 +0200 Subject: [PATCH 211/636] Update yarn.lock --- yarn.lock | 384 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 300 insertions(+), 84 deletions(-) diff --git a/yarn.lock b/yarn.lock index 140fd805ccf..943d6ed373f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1685,6 +1685,7 @@ ======= ======= "@react-native-community/cli-platform-android@^2.8.3": +<<<<<<< HEAD >>>>>>> 9bae1b8d... bump deps version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" @@ -1704,6 +1705,11 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== >>>>>>> dca19a02... very work in progress +======= + version "2.9.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" + integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -1712,6 +1718,7 @@ <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD logkitty "^0.6.0" slash "^3.0.0" @@ -1764,6 +1771,9 @@ ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch logkitty "^0.5.0" +======= + logkitty "^0.6.0" +>>>>>>> fabd9f7f... Update yarn.lock slash "^3.0.0" xmldoc "^1.1.2" @@ -1843,10 +1853,16 @@ >>>>>>> dca19a02... very work in progress ======= "@react-native-community/cli-platform-ios@^2.8.3": +<<<<<<< HEAD >>>>>>> 9bae1b8d... bump deps version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== +======= + version "2.9.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" + integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" @@ -2050,9 +2066,9 @@ integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== "@react-native-community/netinfo@^4.1.4": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.4.tgz#512be0395bab6f2432c6e26d7a00ace3c78e05ff" - integrity sha512-Iry24dLG0/oDWa60pjYbCcKVxcnvIvOl9PiB1WHvC0Zsykl1gT7dVeW7bWY4X98ZUb6+gVd4CekZiP7URQBeLQ== + version "4.1.5" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.5.tgz#4bb44842db6a1a18f00a0f061b0e3dcc638f67dd" + integrity sha512-lagdZr9UiVAccNXYfTEj+aUcPCx9ykbMe9puffeIyF3JsRuMmlu3BjHYx1klUHX7wNRmFNC8qVP0puxUt1sZ0A== "@react-navigation/core@~3.5.0": version "3.5.0" @@ -2064,10 +2080,17 @@ query-string "^6.4.2" react-is "^16.8.6" +<<<<<<< HEAD "@react-navigation/native@~3.6.1": version "3.6.2" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== +======= +"@react-navigation/native@~3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.0.tgz#dabf93382f75037c01dfdd2a03807e40b48a4d61" + integrity sha512-MmsEF4Gf3DD7rtZlbOLULQOBCxE2nGz6FdPYxtlEI+N/E2I5OrdxrTNAA7EGWsIiaJEapU4bp0a+tLjh/9PQpA== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -2404,6 +2427,7 @@ >>>>>>> 9bae1b8d... bump deps "@types/node@^10.3.2": +<<<<<<< HEAD version "10.14.15" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g== @@ -2475,6 +2499,16 @@ >>>>>>> 2216260a... Create Exchange related Input components ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= + version "10.14.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.16.tgz#4d690c96cbb7b2728afea0e260d680501b3da5cf" + integrity sha512-/opXIbfn0P+VLt+N8DE4l8Mn8rbhiJgabU96ZJ0p9mxOkIks5gh6RUnpHak7Yh0SFkyjO/ODbxsQQPV2bpMmyA== + +"@types/node@^8.0.7": + version "8.10.52" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.52.tgz#ef0ca1809994e20186090408b8cb7f2a6877d5f9" + integrity sha512-2RbW7WXeLex6RI+kQSxq6Ym0GiVcODeQ4Km7MnnTX5BHdOGQnqVa+s6AUmAW+OFYAJ8wv9QxvNZXm7/kBdGTVw== +>>>>>>> fabd9f7f... Update yarn.lock "@types/q@^1.5.1": version "1.5.2" @@ -2509,9 +2543,15 @@ "@types/vfile-message" "*" "@types/yargs-parser@*": +<<<<<<< HEAD version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== +======= + version "13.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" + integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== +>>>>>>> fabd9f7f... Update yarn.lock "@types/yargs@^13.0.0": version "13.0.2" @@ -2615,6 +2655,7 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" +<<<<<<< HEAD <<<<<<< HEAD >>>>>>> a1921ad8... further sdk hookup <<<<<<< HEAD @@ -2629,38 +2670,55 @@ version "1.0.0-beta.32" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== +======= +"@walletconnect/core@^1.0.0-beta.33": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.33.tgz#ba8c4d1682c00630124cfacd8c3ac28a37737ffc" + integrity sha512-VnipTAEiVJx0fKR7kVKQ/KIaEDCFjIEF4wGSl73uuhp+YPBZSN0fXQ0/joF00dGUxVY6RiwmCQlmz5ZKpcGWYw== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: - "@walletconnect/types" "^1.0.0-beta.32" - "@walletconnect/utils" "^1.0.0-beta.32" + "@walletconnect/types" "^1.0.0-beta.33" + "@walletconnect/utils" "^1.0.0-beta.33" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.32" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.32.tgz#4d6bd623a4687d658ae26ebe27f417b8ea83f897" - integrity sha512-6+Pamxq2c+K+Kz+q1oKJRZU58J5dg5U+SFJ5T5qkMpSsN0BCvpMvD3/6TPCzBYaFXCyjO5OJhvHsKmYa/IvA0g== + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.33.tgz#21542022f8204648e924a40c6f79c93bde109f5a" + integrity sha512-AFGiXFZXQ1HINGiQESRciMlu7R6s0e2s7LeC5g+EdQrtDDqSsEx9W6Lb8VMPQPnPREmcmcaz4B9L/wyUjNXXew== dependencies: - "@walletconnect/core" "^1.0.0-beta.32" - "@walletconnect/types" "^1.0.0-beta.32" - "@walletconnect/utils" "^1.0.0-beta.32" + "@walletconnect/core" "^1.0.0-beta.33" + "@walletconnect/types" "^1.0.0-beta.33" + "@walletconnect/utils" "^1.0.0-beta.33" -"@walletconnect/types@^1.0.0-beta.32": - version "1.0.0-beta.32" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.32.tgz#aeb3b41145a6028412b22c05d0fd63e23a7381db" - integrity sha512-vXBUHc51mOyFLaScrSzYyobS/ctPiNHFBWB6M0oydd43X29Ihl7C4c4B7ExDbfPlrBspebcZEkuKzHOZSZVKSg== +"@walletconnect/types@^1.0.0-beta.33": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.33.tgz#2c95191e0a2986b24e4f66baeeeaa79f87dc52f4" + integrity sha512-RGC5F4Qb9IApPaOIZwiQVzT4b6K+vmgh0mi/7qHICzSylMJ9BZmvdDOn61+jgSBCjzQ/lmJROsQeXAABCU08rw== +<<<<<<< HEAD "@walletconnect/utils@^1.0.0-beta.32": version "1.0.0-beta.32" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.32.tgz#f87841eaf60d62441b26e78603aafbd9b7bc7f2e" integrity sha512-ShnWCVPFv2fZcIKInNDhROCu/gEUD2+vjbBUCPTRB1M+ERTK8fyrMgl2vId8NOSTR/Sd3Ie4+hCbUluLZYvrGQ== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +"@walletconnect/utils@^1.0.0-beta.33": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.33.tgz#59ff7edc74608398a341264bad781f24b4cf599f" + integrity sha512-BAKV+tVoN5QGoMDzF/JleO0s80wLoeJFAsw8/IG9QCSnHi4swZsin0Zk2TRYVb+gC/ZuDmMvwMHVkmVUqz7fOg== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" +<<<<<<< HEAD <<<<<<< HEAD "@walletconnect/types" "^1.0.0-beta.35" ======= "@walletconnect/types" "^1.0.0-beta.32" >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + "@walletconnect/types" "^1.0.0-beta.33" +>>>>>>> fabd9f7f... Update yarn.lock bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -2736,7 +2794,11 @@ acorn-globals@^4.1.0: acorn "^6.0.1" acorn-walk "^6.0.1" +<<<<<<< HEAD acorn-jsx@^5.0.0: +======= +acorn-jsx@^5.0.2: +>>>>>>> fabd9f7f... Update yarn.lock version "5.0.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== @@ -2751,6 +2813,7 @@ acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== +<<<<<<< HEAD acorn@^6.0.1, acorn@^6.0.7: <<<<<<< HEAD <<<<<<< HEAD @@ -2787,11 +2850,19 @@ acorn@^6.0.1, acorn@^6.0.7: integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch ======= +======= +acorn@^6.0.1: +>>>>>>> fabd9f7f... Update yarn.lock version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== >>>>>>> dca19a02... very work in progress +acorn@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a" + integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ== + aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" @@ -2865,18 +2936,11 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0: +ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== -ansi-escapes@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" - integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== - dependencies: - type-fest "^0.5.2" - ansi-fragments@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansi-fragments/-/ansi-fragments-0.2.1.tgz#24409c56c4cc37817c3d7caa99d8969e2de5a05e" @@ -3194,16 +3258,16 @@ babel-eslint@10.0.1: eslint-visitor-keys "^1.0.0" babel-eslint@^10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.2.tgz#182d5ac204579ff0881684b040560fdcc1558456" - integrity sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q== + version "10.0.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" + integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" babel-jest@^24.8.0, babel-jest@^24.9.0: version "24.9.0" @@ -4105,13 +4169,6 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - cli-spinners@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" @@ -4676,9 +4733,15 @@ date-now@^0.1.4: integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= dayjs@^1.8.15: +<<<<<<< HEAD version "1.8.16" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== +======= + version "1.8.15" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.15.tgz#7121bc04e6a7f2621ed6db566be4a8aaf8c3913e" + integrity sha512-HYHCI1nohG52B45vCQg8Re3hNDZbMroWPkhz50yaX7Lu0ATyjGsTdoYZBpjED9ar6chqTx2dmSmM8A51mojnAg== +>>>>>>> fabd9f7f... Update yarn.lock debounce@^1.2.0: version "1.2.0" @@ -5167,6 +5230,7 @@ electron-to-chromium@^1.3.191: electron-to-chromium@^1.3.191: <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "1.3.200" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" @@ -5231,6 +5295,11 @@ electron-to-chromium@^1.3.191: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.228.tgz#8b1804bae329e2029ad6b25fbb15d9200fb12894" integrity sha512-m3k/OYd9sCLFOAtvl6vqgXfzbG8iY1mLYg0fQjQGB46LpPudYDUFUmiSmj2meJsHEUABWXH1ZRSCeWj265v2RQ== >>>>>>> 9bae1b8d... bump deps +======= + version "1.3.241" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.241.tgz#859dc49ab7f90773ed698767372d384190f60cb1" + integrity sha512-Gb9E6nWZlbgjDDNe5cAvMJixtn79krNJ70EDpq/M10lkGo7PGtBUe7Y0CYVHsBScRwi6ybCS+YetXAN9ysAHDg== +>>>>>>> fabd9f7f... Update yarn.lock elliptic@6.3.3: version "6.3.3" @@ -5652,22 +5721,26 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +<<<<<<< HEAD eslint-utils@^1.3.1: +======= +eslint-utils@^1.3.1, eslint-utils@^1.4.2: +>>>>>>> fabd9f7f... Update yarn.lock version "1.4.2" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== dependencies: eslint-visitor-keys "^1.0.0" -eslint-visitor-keys@^1.0.0: +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" - integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== + version "6.2.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" + integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -5676,9 +5749,9 @@ eslint@^6.1.0: debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^6.0.0" + eslint-utils "^1.4.2" + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -5707,14 +5780,14 @@ eslint@^6.1.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6" - integrity sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q== +espree@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" + integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" + acorn "^7.0.0" + acorn-jsx "^5.0.2" + eslint-visitor-keys "^1.1.0" esprima@3.x.x, esprima@^3.1.3: version "3.1.3" @@ -5774,10 +5847,16 @@ ethers@^4.0.27: >>>>>>> 751dba29... Replace navigation animations with new effects ======= ethers@^4.0.28, ethers@^4.0.33: +<<<<<<< HEAD version "4.0.33" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== >>>>>>> 9a1e3741... further sdk hookup +======= + version "4.0.36" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.36.tgz#96519fd3cc9317f938c8ee4d22050f34e3c2ef0e" + integrity sha512-rWdchEhUyXx01GiwexH6Sha97CQ9tJdQwe6FtYKxShC7VEZV41nuKt+lzCQ4OqvQwZK5PcAKaAZv2GDsCH33SA== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -5852,9 +5931,9 @@ execa@^1.0.0: strip-eof "^1.0.0" execa@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.3.tgz#4b84301b33042cfb622771e886ed0b10e5634642" - integrity sha512-iM124nlyGSrXmuyZF1EMe83ESY2chIYVyDRZKgmcDynid2Q2v/+GuE7gNMl6Sy9Niwf4MC0DDxagOxeMPjuLsw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.4.tgz#2f5cc589c81db316628627004ea4e37b93391d8e" + integrity sha512-VcQfhuGD51vQUQtKIq2fjGDLDbL6N1DTQVpYzxZ7LPIXw3HqTuIz6uxRmpV1qf8i31LHf2kjiaGI+GdHwRgbnQ== dependencies: cross-spawn "^6.0.5" get-stream "^5.0.0" @@ -5896,6 +5975,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +<<<<<<< HEAD +======= +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +>>>>>>> fabd9f7f... Update yarn.lock expect@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" @@ -6103,13 +6192,6 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -figures@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" - integrity sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" @@ -6894,6 +6976,7 @@ i18next@^17.0.3: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "17.0.14" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" @@ -6948,6 +7031,11 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.11.tgz#36424dc01f6de391fae87878d24f5ff713565c27" integrity sha512-O+yzoNi0usYcd4oi85EFY4WuwZ8NNsYJLauZ629YSjwgIi2D7eYDSQxy6aAR67V++b//GNuZEk7hx/i3L9Rxag== >>>>>>> dca19a02... very work in progress +======= + version "17.0.12" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.12.tgz#d732a6c1131fc3b02305a8241eac25ec0d1cf663" + integrity sha512-FoYYnORcAMNznVXSpwJ1zVGL8kXcv1JUmvTqoQyuPPRncBq9rd7Mi0I/oVXkGR3YIek5dDiunvA/NGG2o+mMuw== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: "@babel/runtime" "^7.3.1" @@ -7144,6 +7232,7 @@ inquirer@^6.2.2: integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== ======= inquirer@^6.4.1: +<<<<<<< HEAD <<<<<<< HEAD version "6.5.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" @@ -7154,18 +7243,23 @@ inquirer@^6.4.1: resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.1.tgz#8bfb7a5ac02dac6ff641ac4c5ff17da112fcdb42" integrity sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw== >>>>>>> dca19a02... very work in progress +======= + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: - ansi-escapes "^4.2.1" + ansi-escapes "^3.2.0" chalk "^2.4.2" - cli-cursor "^3.1.0" + cli-cursor "^2.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" run-async "^2.2.0" rxjs "^6.4.0" - string-width "^4.1.0" + string-width "^2.1.0" strip-ansi "^5.1.0" through "^2.3.6" @@ -7475,11 +7569,15 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +<<<<<<< HEAD <<<<<<< HEAD is-what@^3.3.1: ======= is-what@^3.2.4: >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +is-what@^3.3.1: +>>>>>>> fabd9f7f... Update yarn.lock version "3.3.1" resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.3.1.tgz#79502181f40226e2d8c09226999db90ef7c1bcbe" integrity sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA== @@ -7715,6 +7813,22 @@ jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== +<<<<<<< HEAD +======= + +jest-haste-map@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" + integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-serializer "^24.0.0-alpha.6" + jest-worker "^24.0.0-alpha.6" + micromatch "^2.3.11" + sane "^3.0.0" +>>>>>>> fabd9f7f... Update yarn.lock jest-haste-map@^24.7.1, jest-haste-map@^24.9.0: version "24.9.0" @@ -7885,6 +7999,14 @@ jest-serializer@^24.4.0, jest-serializer@^24.9.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== +<<<<<<< HEAD +======= +jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0, jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== + +>>>>>>> fabd9f7f... Update yarn.lock jest-snapshot@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" @@ -7947,7 +8069,18 @@ jest-watcher@^24.9.0: jest-util "^24.9.0" string-length "^2.0.0" +<<<<<<< HEAD jest-worker@^24.6.0, jest-worker@^24.9.0: +======= +jest-worker@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" + integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== + dependencies: + merge-stream "^1.0.1" + +jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0, jest-worker@^24.9.0: +>>>>>>> fabd9f7f... Update yarn.lock version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== @@ -8372,7 +8505,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -9045,9 +9178,15 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: +<<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== +======= + version "2.4.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.4.0.tgz#38f0af94f42fb6f34d3d7d82a90e2c99cd3ff485" + integrity sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -9152,11 +9291,6 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - mv@~2: version "2.1.1" resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" @@ -9172,9 +9306,15 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.0.3: +<<<<<<< HEAD version "2.1.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== +======= + version "2.0.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.4.tgz#4889355c9ce8e24efad7c65945a4a2875ac3e8f4" + integrity sha512-sOJnBmY3TJQBVIBqKHoifuwygrocXg3NjS9rZSMnVl05XWSHK7Qxb177AIZQyMDjP86bz+yneozj/h9qsPLcCA== +>>>>>>> fabd9f7f... Update yarn.lock nanomatch@^1.2.9: version "1.2.13" @@ -9279,16 +9419,22 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> fabd9f7f... Update yarn.lock node-notifier@^5.2.1, node-notifier@^5.4.2: version "5.4.3" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== +<<<<<<< HEAD ======= node-notifier@^5.2.1: version "5.4.1" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.1.tgz#7c0192cc63aedb25cd99619174daa27902b10903" integrity sha512-p52B+onAEHKW1OF9MGO/S7k/ahGEHfhP5/tvwYzog/5XLYOd8ZuD6vdNZdUuWMONRnKPneXV43v3s6Snx1wsCQ== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= +>>>>>>> fabd9f7f... Update yarn.lock dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -9326,10 +9472,16 @@ node-releases@^1.1.23: >>>>>>> 751dba29... Replace navigation animations with new effects ======= node-releases@^1.1.25: +<<<<<<< HEAD version "1.1.27" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.27.tgz#b19ec8add2afe9a826a99dceccc516104c1edaf4" integrity sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA== >>>>>>> dca19a02... very work in progress +======= + version "1.1.28" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.28.tgz#503c3c70d0e4732b84e7aaa2925fbdde10482d4a" + integrity sha512-AQw4emh6iSXnCpDiFe0phYcThiccmkNWMZnFZ+lDJjAP8J0m2fVd59duvUUyuTirQOhIAajTFkzG6FHCLBO59g== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: semver "^5.3.0" @@ -10308,6 +10460,17 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +<<<<<<< HEAD +======= +pretty-format@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" + integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== + dependencies: + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + +>>>>>>> fabd9f7f... Update yarn.lock pretty-format@^24.7.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" @@ -10906,6 +11069,7 @@ react-native-mail@^3.0.6: integrity sha512-FHe4kKJKAGuCPPWcDwaRSjdUhEE4IWIsVtTZ05dgD/MgOm00isYmM20zuJHla7oiHVQ2HmzGji76g6IuhIrCjw== react-native-os@^1.2.2: +<<<<<<< HEAD <<<<<<< HEAD version "1.2.5" resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" @@ -10915,6 +11079,11 @@ react-native-os@^1.2.2: resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.4.tgz#f9ea7423cc9a9e865bc9cad590941ce37b7a3aee" integrity sha512-ohlP5BxJxvWp8JZ99g8+xdZ2s8Z4bEoP6g99VDeytz04m+VYdVrCP7Xovy6FoEqA4qxyUbv4xeGHR+pzNnkZeg== >>>>>>> 751dba29... Replace navigation animations with new effects +======= + version "1.2.5" + resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" + integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== +>>>>>>> fabd9f7f... Update yarn.lock react-native-permissions@^1.1.1: version "1.2.0" @@ -11016,6 +11185,7 @@ react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: >>>>>>> 3984235a... Bump react-navigation stack to current master ======= react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: +<<<<<<< HEAD >>>>>>> e162a3d6... Fix merge mistakes version "0.14.6" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" @@ -11025,6 +11195,11 @@ react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== >>>>>>> dca19a02... very work in progress +======= + version "0.14.7" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" + integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: hoist-non-react-statics "^2.3.1" @@ -11069,6 +11244,7 @@ react-native-svg@^9.5.1: react-native-svg@^9.5.3: ======= react-native-svg@^9.6.2: +<<<<<<< HEAD >>>>>>> 9bae1b8d... bump deps version "9.6.2" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" @@ -11101,6 +11277,11 @@ react-native-svg@^9.6.2: >>>>>>> 908925bc... Cleanup ButtonPressAnimation ======= >>>>>>> dca19a02... very work in progress +======= + version "9.7.0" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.7.0.tgz#2d0bf1d31d5f1dd061587215b50deb29e626df18" + integrity sha512-8E1snfe2YYbfu6SP5DOoQgRhCdv7D0F4VewUAV+IgAn+IScrA/uuLB8LCodRdO+9U4Rm5dJ4yIwsVhPHRtuBkw== +>>>>>>> fabd9f7f... Update yarn.lock react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -11210,6 +11391,7 @@ react-navigation-drawer@~1.4.0: <<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD react-navigation-stack@~1.5.0: version "1.5.5" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" @@ -11260,6 +11442,18 @@ react-navigation-stack@^2.0.0-alpha.7: version "2.0.0-alpha.6" resolved "https://github.com/react-navigation/stack#2ddf3a4a3985047811c3c90f1d8263ea71994966" >>>>>>> 3984235a... Bump react-navigation stack to current master +======= +react-navigation-stack@^2.0.0-alpha.9: + version "2.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.9.tgz#6e0382f3f4e37235c94badf6712c7095415d4a6d" + integrity sha512-Lze5CuCDr9FtGIJyxG8e1YXbpyd77XjOgLnQN5PRG9qx7YNmAbkbybPrhsmlRVWiyosC8IEVFbnot0EDcR+O/w== + dependencies: + react-native-safe-area-view "^0.14.6" + +"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: + version "2.0.0-alpha.7" + resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" +>>>>>>> fabd9f7f... Update yarn.lock dependencies: react-native-safe-area-view "^0.14.6" >>>>>>> 751dba29... Replace navigation animations with new effects @@ -11273,23 +11467,39 @@ react-navigation-tabs@^2.3.0: react-lifecycles-compat "^3.0.4" react-native-tab-view "^2.9.0" +<<<<<<< HEAD react-navigation-tabs@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" integrity sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ== >>>>>>> 85ffae7a... Convert parts of the API to the new version +======= +react-navigation-tabs@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" + integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: hoist-non-react-statics "^2.5.0" prop-types "^15.6.1" react-native-tab-view "^1.4.1" react-navigation@^3.11.1: +<<<<<<< HEAD version "3.12.1" resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== dependencies: "@react-navigation/core" "~3.5.0" "@react-navigation/native" "~3.6.1" +======= + version "3.12.0" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.0.tgz#31cc6c7d778c968965e86a820f12f1e1a66e20b9" + integrity sha512-Lr0l0lbZsFsajUx040I1HYm0yIfa+F9SCEeaNkS1eiey6k2G04eY5hYGZfo4i3kaMj99Yi8tuRcSN7DS0QZu8w== + dependencies: + "@react-navigation/core" "~3.5.0" + "@react-navigation/native" "~3.6.0" +>>>>>>> fabd9f7f... Update yarn.lock react-navigation-drawer "~1.4.0" react-navigation-stack "~1.5.0" react-navigation-tabs "~1.2.0" @@ -11516,9 +11726,14 @@ recyclerlistview@2.0.1-alpha.1: integrity sha512-UaeJyxG9LL8lcfiAqkp0kPLxvjbYg95Dcq1U/QUvzwXU4+H2khg/LAws/FssxPX6CXNMw7BLcT2YHAhkFElqRQ== ======= recyclerlistview@Flipkart/recyclerlistview#master: +<<<<<<< HEAD version "2.0.10" resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/1d310dffc80d63e4303bf1213d2f6b0ce498c33a" >>>>>>> 9bae1b8d... bump deps +======= + version "2.0.13" + resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/6c191661214a53f6ba24567528f0de7902ffda6c" +>>>>>>> fabd9f7f... Update yarn.lock dependencies: lodash.debounce "4.0.8" prop-types "15.5.8" @@ -11825,7 +12040,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7, resolve@1.8.1, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1, resolve@^1.9.0: +resolve@1.1.7, resolve@1.8.1, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1, resolve@^1.9.0: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== @@ -11848,14 +12063,6 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -12097,11 +12304,15 @@ semver@5.5.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== +<<<<<<< HEAD <<<<<<< HEAD semver@^6.0.0, semver@^6.1.1, semver@^6.2.0: ======= semver@^6.0.0, semver@^6.1.1, semver@^6.1.2: >>>>>>> 96db5a28... begin mike +======= +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0: +>>>>>>> fabd9f7f... Update yarn.lock version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -12998,6 +13209,7 @@ symbol-tree@^3.2.2: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^5.2.3: +<<<<<<< HEAD <<<<<<< HEAD version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" @@ -13007,6 +13219,11 @@ table@^5.2.3: resolved "https://registry.yarnpkg.com/table/-/table-5.4.5.tgz#c8f4ea2d8fee08c0027fac27b0ec0a4fe01dfa42" integrity sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA== >>>>>>> e1a27438... Cleanup ButtonPressAnimation +======= + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +>>>>>>> fabd9f7f... Update yarn.lock dependencies: ajv "^6.10.2" lodash "^4.17.14" @@ -13340,11 +13557,6 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== -type-fest@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" - integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== - typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -14090,6 +14302,7 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" +<<<<<<< HEAD <<<<<<< HEAD yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: ======= @@ -14105,6 +14318,9 @@ yargs@^13.0.0, yargs@^13.2.4: >>>>>>> 2216260a... Create Exchange related Input components ======= >>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch +======= +yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: +>>>>>>> fabd9f7f... Update yarn.lock version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== From 0955365eb6067cc16ab6c8cf50658cba03ae82a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Tue, 27 Aug 2019 17:16:59 +0200 Subject: [PATCH 212/636] Block modal dismissing gestures over scroll list --- src/components/exchange/ExchangeAssetList.js | 44 +++++++++++--------- src/screens/ExchangeModal.js | 2 - 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index 05ad5b13146..f4ae3e3640b 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { LayoutAnimation, View } from 'react-native'; import { DataProvider, LayoutProvider, RecyclerListView } from "recyclerlistview"; +import { PanGestureHandler } from 'react-native-gesture-handler'; import styled from 'styled-components/primitives'; import { deviceUtils, isNewValueForPath } from '../../utils'; import { colors } from '../../styles'; @@ -74,7 +75,7 @@ export default class ExchangeAssetList extends PureComponent { updateList = () => { this.setState((prevState) => ({ dataProvider: prevState.dataProvider.cloneWithRows(this.props.items), - })) + })); } getStableId = (index) => get(this.state, `dataProvider._data[${index}].uniqueId`) @@ -83,24 +84,29 @@ export default class ExchangeAssetList extends PureComponent { render = () => ( - + + + ) } diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 8b6b02bdc69..1a60f7bbdef 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -363,7 +363,6 @@ class ExchangeModal extends PureComponent { }), }} > - @@ -408,7 +407,6 @@ class ExchangeModal extends PureComponent { /> )} - From e6e781069c4823bf6cfb8ca3327e938ee065418d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 00:04:37 -0400 Subject: [PATCH 213/636] Fixes after rebasing over latest develop --- android/app/build.gradle | 1 + .../java/com/rainbow/MainApplication.java | 2 + android/settings.gradle | 2 + ios/Podfile.lock | 414 +- ios/Rainbow.xcodeproj/project.pbxproj | 153 +- package.json | 10 +- patches/recyclerlistview+2.0.10.patch | 11088 ---------------- src/components/shadow-stack/ShadowStack.js | 4 - src/navigation/transitions/effects.js | 6 +- src/navigation/transitions/expanded.js | 116 - src/navigation/transitions/sheet.js | 241 - src/screens/Routes.js | 15 +- src/screens/WalletScreen.js | 5 - yarn.lock | 2899 +--- 14 files changed, 116 insertions(+), 14840 deletions(-) delete mode 100644 patches/recyclerlistview+2.0.10.patch delete mode 100644 src/navigation/transitions/expanded.js delete mode 100644 src/navigation/transitions/sheet.js diff --git a/android/app/build.gradle b/android/app/build.gradle index c7960730d32..bda4df2bb03 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -153,6 +153,7 @@ android { } dependencies { + implementation project(':react-native-text-input-mask') implementation project(':@segment_analytics-react-native') implementation project(':react-native-firebase') implementation project(':@staltz_react-native-tcp') diff --git a/android/app/src/main/java/com/rainbow/MainApplication.java b/android/app/src/main/java/com/rainbow/MainApplication.java index 8f4a5041bf9..503c6488d02 100644 --- a/android/app/src/main/java/com/rainbow/MainApplication.java +++ b/android/app/src/main/java/com/rainbow/MainApplication.java @@ -3,6 +3,7 @@ import android.app.Application; import com.facebook.react.ReactApplication; +import com.RNTextInputMask.RNTextInputMaskPackage; import org.reactnative.maskedview.RNCMaskedViewPackage; import com.RNTextInputMask.RNTextInputMaskPackage; import com.segment.analytics.reactnative.core.RNAnalyticsPackage; @@ -60,6 +61,7 @@ public boolean getUseDeveloperSupport() { protected List getPackages() { return Arrays.asList( new MainReactPackage(), + new RNTextInputMaskPackage(), new RNCMaskedViewPackage(), new RNTextInputMaskPackage(), new RNAnalyticsPackage(), diff --git a/android/settings.gradle b/android/settings.gradle index a637b2cdb8b..849798ec1fe 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'Rainbow' +include ':react-native-text-input-mask' +project(':react-native-text-input-mask').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-text-input-mask/android') include ':@react-native-community_masked-view' project(':@react-native-community_masked-view').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/masked-view/android') include ':react-native-text-input-mask' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c7708c0eb34..1fc9cb9db4c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -40,46 +40,16 @@ PODS: - DoubleConversion - glog - glog (0.3.5) -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> dca19a02... very work in progress - GoogleToolboxForMac/Defines (2.2.1) - GoogleToolboxForMac/Logger (2.2.1): - GoogleToolboxForMac/Defines (= 2.2.1) - "GoogleToolboxForMac/NSData+zlib (2.2.1)": - GoogleToolboxForMac/Defines (= 2.2.1) -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> dca19a02... very work in progress - libwebp (1.0.3): - libwebp/demux (= 1.0.3) - libwebp/mux (= 1.0.3) - libwebp/webp (= 1.0.3) - libwebp/demux (1.0.3): -<<<<<<< HEAD -======= -======= - - GoogleToolboxForMac/Defines (2.2.0) - - GoogleToolboxForMac/Logger (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSData+zlib (2.2.0)": - - GoogleToolboxForMac/Defines (= 2.2.0) ->>>>>>> 64f1594b... rebase cleanup - - libwebp (1.0.2): - - libwebp/core (= 1.0.2) - - libwebp/dec (= 1.0.2) - - libwebp/demux (= 1.0.2) - - libwebp/dsp (= 1.0.2) - - libwebp/enc (= 1.0.2) - - libwebp/mux (= 1.0.2) - - libwebp/utils (= 1.0.2) - - libwebp/webp (= 1.0.2) - - libwebp/core (1.0.2): ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> dca19a02... very work in progress - libwebp/webp - libwebp/mux (1.0.3): - libwebp/demux @@ -89,11 +59,7 @@ PODS: - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - Protobuf (3.9.0) -<<<<<<< HEAD - React (0.60.5): - React-Core (= 0.60.5) - React-DevSupport (= 0.60.5) @@ -139,70 +105,6 @@ PODS: - React-cxxreact (= 0.60.5) - React-jsi (= 0.60.5) - React-jsinspector (0.60.5) -======= - - React (0.59.9): - - React/Core (= 0.59.9) -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - - Protobuf (3.7.0) - - React (0.60.4): - - React-Core (= 0.60.4) - - React-DevSupport (= 0.60.4) - - React-RCTActionSheet (= 0.60.4) - - React-RCTAnimation (= 0.60.4) - - React-RCTBlob (= 0.60.4) - - React-RCTImage (= 0.60.4) - - React-RCTLinking (= 0.60.4) - - React-RCTNetwork (= 0.60.4) - - React-RCTSettings (= 0.60.4) - - React-RCTText (= 0.60.4) - - React-RCTVibration (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-Core (0.60.4): - - Folly (= 2018.10.22.00) - - React-cxxreact (= 0.60.4) - - React-jsiexecutor (= 0.60.4) - - yoga (= 0.60.4.React) - - React-cxxreact (0.60.4): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-jsinspector (= 0.60.4) - - React-DevSupport (0.60.4): - - React-Core (= 0.60.4) - - React-RCTWebSocket (= 0.60.4) - - React-fishhook (0.60.4) - - React-jsi (0.60.4): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-jsi/Default (= 0.60.4) - - React-jsi/Default (0.60.4): - - boost-for-react-native (= 1.63.0) - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-jsiexecutor (0.60.4): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-cxxreact (= 0.60.4) - - React-jsi (= 0.60.4) - - React-jsinspector (0.60.4) ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> 64f1594b... rebase cleanup -======= - - Protobuf (3.7.0) -======= - - Protobuf (3.9.0) ->>>>>>> dca19a02... very work in progress - - React (0.59.9): - - React/Core (= 0.59.9) ->>>>>>> a7347f4b... podfile lock for text input mask - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -216,7 +118,7 @@ PODS: - react-native-fast-image (6.1.1): - React - SDWebImage (~> 5.0) - - react-native-netinfo (4.1.4): + - react-native-netinfo (4.2.1): - React - react-native-version-number (0.3.6): - React @@ -250,72 +152,7 @@ PODS: - React - RNCMaskedView (0.1.1): - React -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - - RNDeviceInfo (2.3.2): -======= -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -<<<<<<< HEAD - - RNDeviceInfo (2.3.1): -======= - - RNDeviceInfo (2.3.0): -======= - - RNDeviceInfo (2.3.1): ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - - RNDeviceInfo (2.3.1): ->>>>>>> dc42f3f4... begin mike -<<<<<<< HEAD ->>>>>>> 96db5a28... begin mike -======= -======= - - RNDeviceInfo (2.3.2): ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - - RNDeviceInfo (2.3.2): ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - RNDeviceInfo (2.3.2): -======= - - RNDeviceInfo (2.3.0): -======= - - RNDeviceInfo (2.3.1): ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - - RNDeviceInfo (2.3.2): ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - - RNDeviceInfo (2.3.2): ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - - RNDeviceInfo (2.3.2): ->>>>>>> dca19a02... very work in progress - React - RNIOS11DeviceCheck (0.0.3): - React @@ -327,86 +164,10 @@ PODS: - React - RNStoreReview (0.1.5): - React -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) - SDWebImage/Core (5.1.1) - yoga (0.60.5.React) -======= - - SDWebImage (5.0.2): - - SDWebImage/Core (= 5.0.2) - - SDWebImage/Core (5.0.2) -======= -======= ->>>>>>> 96db5a28... begin mike - - SDWebImage (5.0.6): - - SDWebImage/Core (= 5.0.6) - - SDWebImage/Core (5.0.6) -======= - - SDWebImage (5.1.0): - - SDWebImage/Core (= 5.1.0) - - SDWebImage/Core (5.1.0) ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> a7347f4b... podfile lock for text input mask -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - - SDWebImage (5.1.0): - - SDWebImage/Core (= 5.1.0) - - SDWebImage/Core (5.1.0) -======= - - SDWebImage (5.0.2): - - SDWebImage/Core (= 5.0.2) - - SDWebImage/Core (5.0.2) -======= -======= ->>>>>>> a3543960... rebase cleanup - - SDWebImage (5.0.6): - - SDWebImage/Core (= 5.0.6) - - SDWebImage/Core (5.0.6) ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - - yoga (0.59.9.React) -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= -======= ->>>>>>> bdd78363... podfile lock for text input mask - - SDWebImage (5.0.2): - - SDWebImage/Core (= 5.0.2) - - SDWebImage/Core (5.0.2) -<<<<<<< HEAD -<<<<<<< HEAD - - yoga (0.60.4.React) ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> 64f1594b... rebase cleanup -======= -======= -======= - - SDWebImage (5.1.0): - - SDWebImage/Core (= 5.1.0) - - SDWebImage/Core (5.1.0) ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - - SDWebImage (5.1.0): - - SDWebImage/Core (= 5.1.0) - - SDWebImage/Core (5.1.0) ->>>>>>> dca19a02... very work in progress - - yoga (0.59.9.React) ->>>>>>> a7347f4b... podfile lock for text input mask DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -557,9 +318,6 @@ SPEC CHECKSUMS: FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 @@ -573,55 +331,10 @@ SPEC CHECKSUMS: React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 -======= -======= ->>>>>>> 64f1594b... rebase cleanup - Folly: de497beb10f102453a1afa9edbf8cf8a251890de - glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d - GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 - libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a - React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 - glog: 1f3da668190260b06b429bb211bfbee5cd790c28 -======= - Folly: de497beb10f102453a1afa9edbf8cf8a251890de - glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d -<<<<<<< HEAD ->>>>>>> a7347f4b... podfile lock for text input mask - GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d - libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a -<<<<<<< HEAD - React: ff7ee2ae5ee1c1d9ae2183b4111045b25294bb01 - React-Core: 8e0ea421cae5609d2562850f98421b15030476fa - React-cxxreact: 326880209990151a7182a813311054e9772ba510 - React-DevSupport: e9f10e6721e78e87622fc985db695c0c0168db8a - React-fishhook: 1f0e5b08449403fa75c3fb3881a0beefbada14af - React-jsi: 21d3153b1153fbf6510a92b6b11e33e725cb7432 - React-jsiexecutor: 7549641e48bafae7bfee3f3ea19bf4901639c5de - React-jsinspector: 73f24a02fa684ed6a2b828ba116874a2191ded88 ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> 64f1594b... rebase cleanup -======= -======= - GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 - libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a ->>>>>>> dca19a02... very work in progress - React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f ->>>>>>> a7347f4b... podfile lock for text input mask react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 - react-native-netinfo: 2aa34e02a38ae66e583bcae8c489ae0edd32b31f + react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e @@ -636,137 +349,14 @@ SPEC CHECKSUMS: RNAnalytics: d110195618296fed3907830911f01cb6e9be53d0 RNCAsyncStorage: 2e2e3feb9bdadc752a026703d8c4065ca912e75a RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 -======= -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -<<<<<<< HEAD - RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 -======= - RNDeviceInfo: 65106cc87ad6f6f71ef2ecc667f4c59b840888e2 -======= - RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 ->>>>>>> dc42f3f4... begin mike -<<<<<<< HEAD ->>>>>>> 96db5a28... begin mike -======= -======= - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 -======= - RNDeviceInfo: 65106cc87ad6f6f71ef2ecc667f4c59b840888e2 -======= - RNDeviceInfo: 74ee98a0b3ef57604ea9953f03eca549a9335160 ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 ->>>>>>> dca19a02... very work in progress RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNReanimated: da57ffa32f04cebe2107da0b281999a01c0d1ecc RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 -======= - SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 -======= -======= ->>>>>>> 96db5a28... begin mike - SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 -======= - SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> a7347f4b... podfile lock for text input mask -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f -======= - SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 -======= -======= ->>>>>>> a3543960... rebase cleanup - SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= -======= ->>>>>>> bdd78363... podfile lock for text input mask - SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 -<<<<<<< HEAD -<<<<<<< HEAD - yoga: c2c050f6ae6e222534760cc82f559b89214b67e2 ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> 64f1594b... rebase cleanup -======= -======= -======= - SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ->>>>>>> dca19a02... very work in progress - yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee ->>>>>>> a7347f4b... podfile lock for text input mask PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 9308b159b7a..f66651a3861 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -28,17 +28,17 @@ 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */; }; 23320186D7F747FEB02451C6 /* SF-Pro-Text-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */; }; 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B86CB964E3AA47029988138C /* libRNKeychain.a */; }; - 2440303322D6D5F70045D406 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2440303222D6D5F70045D406 /* InputMask.framework */; }; - 2440303422D6D5F70045D406 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2440303222D6D5F70045D406 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; }; + 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24979E7B20F84004007EB0DA /* FirebaseInstanceID.framework */; }; 24979E8920F84250007EB0DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24979E7720F84004007EB0DA /* GoogleService-Info.plist */; }; + 24FC7D82232F269400E938AB /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 24FC7D81232F267B00E938AB /* libRNTextInputMask.a */; }; 26095B12C30047F89592D463 /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */; }; 2D7BB74FB1A44EE2A2426373 /* SF-Pro-Text-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = E672AB1C5404435897615660 /* SF-Pro-Text-Light.otf */; }; 3049BEF5B7E0435F905556DD /* Graphik-ThinItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */; }; 3310F0AEC95F47189C2B19DD /* Graphik-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7CEEDA7A68C24426BBAA8D77 /* Graphik-BoldItalic.otf */; }; 340305B6506A4DDFB4EB98AA /* SF-Pro-Text-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = F62BBE10D6534F74B2180711 /* SF-Pro-Text-Bold.otf */; }; 35AD5968C62046E7BC7CF346 /* Graphik-Super.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */; }; - 387F40C9BD694ED8854578EC /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BEEA6222E09F4E33848CD812 /* libRNTextInputMask.a */; }; 396C4BA42EEC4D0985CEBB42 /* SF-Pro-Text-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */; }; 3C363E14D5DE4A028E43EA38 /* SF-Pro-Display-UltralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */; }; 3C41C1415A994234A0FF2589 /* SF-Pro-Text-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */; }; @@ -166,13 +166,6 @@ remoteGlobalIDString = FD751C4D229EB44C002BE1F4; remoteInfo = "FastImage-tvOS"; }; - 2440302922D6D3800045D406 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FF9837E923C848EDA99BFD7E /* RNTextInputMask.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNTextInputMask; - }; 244C64092108794F007A5856 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 1A7B7E90124047F8A3CA4B84 /* RNReactNativeHapticFeedback.xcodeproj */; @@ -376,6 +369,13 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RNGestureHandler; }; + 24FC7D80232F267B00E938AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 24FC7D7B232F267B00E938AB /* RNTextInputMask.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RNTextInputMask; + }; 2C867629211152560067D47A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */; @@ -397,20 +397,6 @@ remoteGlobalIDString = ADD01A681E09402E00F6D226; remoteInfo = "RCTBlob-tvOS"; }; - 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3DBE0D001F3B181A0099AA32; - remoteInfo = fishhook; - }; - 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32; - remoteInfo = "fishhook-tvOS"; - }; 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; @@ -582,13 +568,13 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 2440303522D6D5F80045D406 /* Embed Frameworks */ = { + 24122D56232F2B3300BA0B17 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 2440303422D6D5F70045D406 /* InputMask.framework in Embed Frameworks */, + 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -627,9 +613,7 @@ 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ToolTipMenu.xcodeproj; path = "../node_modules/react-native-tooltip/ToolTipMenu.xcodeproj"; sourceTree = ""; }; 22E39434CDDE4C54848FBFD5 /* libCodePush.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libCodePush.a; sourceTree = ""; }; 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Text-Heavy.otf"; sourceTree = ""; }; - 2440302B22D6D3BF0045D406 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 2440302F22D6D5970045D406 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 2440303222D6D5F70045D406 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 24122D53232F2B3200BA0B17 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24979E3620F84003007EB0DA /* Protobuf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Protobuf.framework; path = Frameworks/Protobuf.framework; sourceTree = ""; }; 24979E7420F84004007EB0DA /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 24979E7520F84004007EB0DA /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/FirebaseCore.framework; sourceTree = ""; }; @@ -644,6 +628,7 @@ 24979E7E20F84005007EB0DA /* nanopb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = nanopb.framework; path = Frameworks/nanopb.framework; sourceTree = ""; }; 249E5FA722613ABC0095F6B7 /* RNCAsyncStorage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNCAsyncStorage.xcodeproj; path = "../node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.xcodeproj"; sourceTree = ""; }; 24A867FF226181F9005DCF78 /* libFirebaseInstanceID.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libFirebaseInstanceID.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 24FC7D7B232F267B00E938AB /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; 25992DBB7F97481A95784B0F /* RNMailTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = RNMailTests.xctest; sourceTree = ""; }; 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ExtralightItalic.otf"; path = "../src/assets/fonts/Graphik-ExtralightItalic.otf"; sourceTree = ""; }; 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNRandomBytes.xcodeproj; path = "../node_modules/react-native-randombytes/RNRandomBytes.xcodeproj"; sourceTree = ""; }; @@ -721,7 +706,6 @@ BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNMail.xcodeproj; path = "../node_modules/react-native-mail/RNMail.xcodeproj"; sourceTree = ""; }; BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Black.otf"; path = "../src/assets/fonts/SF-Pro-Display-Black.otf"; sourceTree = ""; }; BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNOS.xcodeproj; path = "../node_modules/react-native-os/ios/RNOS.xcodeproj"; sourceTree = ""; }; - BEEA6222E09F4E33848CD812 /* libRNTextInputMask.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNTextInputMask.a; sourceTree = ""; }; C1324455238847F2AD5C08B4 /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = ""; }; C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-ThinItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-ThinItalic.otf"; sourceTree = ""; }; C779B11FB4664662AD0EBEA6 /* RNFirebase.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFirebase.xcodeproj; path = "../node_modules/react-native-firebase/ios/RNFirebase.xcodeproj"; sourceTree = ""; }; @@ -746,7 +730,6 @@ ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; F62BBE10D6534F74B2180711 /* SF-Pro-Text-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Bold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Bold.otf"; sourceTree = ""; }; FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-SemiboldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-SemiboldItalic.otf"; sourceTree = ""; }; - FF9837E923C848EDA99BFD7E /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -763,20 +746,6 @@ buildActionMask = 2147483647; files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 146834051AC3E58100842450 /* libReact.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, - 2440303322D6D5F70045D406 /* InputMask.framework in Frameworks */, - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */, 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */, 94822FBFCA7246168685FA85 /* libRNMail.a in Frameworks */, @@ -797,8 +766,9 @@ F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */, 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, - 387F40C9BD694ED8854578EC /* libRNTextInputMask.a in Frameworks */, 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */, + 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */, + 24FC7D82232F269400E938AB /* libRNTextInputMask.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -870,8 +840,6 @@ children = ( 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, - 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */, - 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */, ); name = Products; sourceTree = ""; @@ -914,14 +882,6 @@ name = Products; sourceTree = ""; }; - 2440302622D6D3800045D406 /* Products */ = { - isa = PBXGroup; - children = ( - 2440302A22D6D3800045D406 /* libRNTextInputMask.a */, - ); - name = Products; - sourceTree = ""; - }; 244C64062108794F007A5856 /* Products */ = { isa = PBXGroup; children = ( @@ -972,7 +932,6 @@ 22E39434CDDE4C54848FBFD5 /* libCodePush.a */, D755E71324B04FEE9C691D14 /* libRNFirebase.a */, 91A43F69E797469687978D51 /* libRNStoreReview.a */, - BEEA6222E09F4E33848CD812 /* libRNTextInputMask.a */, ); name = "Recovered References"; sourceTree = ""; @@ -1113,6 +1072,14 @@ name = Products; sourceTree = ""; }; + 24FC7D7C232F267B00E938AB /* Products */ = { + isa = PBXGroup; + children = ( + 24FC7D81232F267B00E938AB /* libRNTextInputMask.a */, + ); + name = Products; + sourceTree = ""; + }; 2C867625211152550067D47A /* Products */ = { isa = PBXGroup; children = ( @@ -1180,6 +1147,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + 24FC7D7B232F267B00E938AB /* RNTextInputMask.xcodeproj */, 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */, 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */, 3C39C266218BBE66004C763F /* FastImage.xcodeproj */, @@ -1212,7 +1180,6 @@ 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */, 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */, 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */, - FF9837E923C848EDA99BFD7E /* RNTextInputMask.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1229,9 +1196,7 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( - 2440303222D6D5F70045D406 /* InputMask.framework */, - 2440302F22D6D5970045D406 /* InputMask.framework */, - 2440302B22D6D3BF0045D406 /* InputMask.framework */, + 24122D53232F2B3200BA0B17 /* InputMask.framework */, 13B07FAE1A68108700A75B9A /* Rainbow */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* RainbowTests */, @@ -1367,7 +1332,7 @@ 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 3CF823D3218F310D0024B77B /* ShellScript */, - 2440303522D6D5F80045D406 /* Embed Frameworks */, + 24122D56232F2B3300BA0B17 /* Embed Frameworks */, ); buildRules = ( ); @@ -1525,8 +1490,8 @@ ProjectRef = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; }, { - ProductGroup = 2440302622D6D3800045D406 /* Products */; - ProjectRef = FF9837E923C848EDA99BFD7E /* RNTextInputMask.xcodeproj */; + ProductGroup = 24FC7D7C232F267B00E938AB /* Products */; + ProjectRef = 24FC7D7B232F267B00E938AB /* RNTextInputMask.xcodeproj */; }, { ProductGroup = 24979D5020F83E3E007EB0DA /* Products */; @@ -1625,13 +1590,6 @@ remoteRef = 24402FE722D6D3800045D406 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 2440302A22D6D3800045D406 /* libRNTextInputMask.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNTextInputMask.a; - remoteRef = 2440302922D6D3800045D406 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 244C640A2108794F007A5856 /* libRNReactNativeHapticFeedback.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1835,6 +1793,13 @@ remoteRef = 24D171E1212F57110090F180 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 24FC7D81232F267B00E938AB /* libRNTextInputMask.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNTextInputMask.a; + remoteRef = 24FC7D80232F267B00E938AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 2C86762A211152560067D47A /* libCodePush.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1856,20 +1821,6 @@ remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfishhook.a; - remoteRef = 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libfishhook-tvOS.a"; - remoteRef = 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -2241,16 +2192,11 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ( "-ObjC", "-lc++", @@ -2291,16 +2237,11 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ( "-ObjC", "-lc++", @@ -2350,7 +2291,6 @@ "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2406,7 +2346,6 @@ "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2497,7 +2436,6 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2543,16 +2481,11 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ( "-ObjC", "-lc++", @@ -2639,7 +2572,6 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2686,16 +2618,11 @@ "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = RainbowTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ( "-ObjC", "-lc++", diff --git a/package.json b/package.json index 8da2ebe8f26..2ad1be3f20f 100644 --- a/package.json +++ b/package.json @@ -97,13 +97,13 @@ "react-native-store-review": "^0.1.5", "react-native-svg": "^9.6.2", "react-native-tcp": "^3.3.0", - "react-native-text-input-mask": "quixley/react-native-text-input-mask#development", + "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", "react-native-tooltip": "^5.2.0", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", - "react-navigation-stack": "^2.0.0-alpha.9", + "react-navigation-stack": "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", "react-navigation-tabs": "^2.3.0", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", @@ -117,7 +117,7 @@ "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0", "reselect": "^4.0.0", - "rn-nodeify": "^10.0.1", + "rn-nodeify": "10.1.0", "socket.io-client": "^2.2.0", "stream-browserify": "^1.0.0", "string_decoder": "^0.10.31", @@ -160,7 +160,7 @@ }, "resolutions": { "**/eslint-plugin-import": "2.14.0", - "**/react-navigation-stack": "https://github.com/react-navigation/stack#master", + "**/react-navigation-stack": "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", "**/resolve": "1.8.1" }, "jest": { @@ -243,4 +243,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file diff --git a/patches/recyclerlistview+2.0.10.patch b/patches/recyclerlistview+2.0.10.patch deleted file mode 100644 index 682cb641f77..00000000000 --- a/patches/recyclerlistview+2.0.10.patch +++ /dev/null @@ -1,11088 +0,0 @@ -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.d.ts -new file mode 100644 -index 0000000..dd0e11c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.d.ts -@@ -0,0 +1,15 @@ -+export default interface ItemAnimator { -+ animateWillMount: (atX: number, atY: number, itemIndex: number) => object | undefined; -+ animateDidMount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; -+ animateWillUpdate: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => void; -+ animateShift: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => boolean; -+ animateWillUnmount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; -+} -+export declare class BaseItemAnimator implements ItemAnimator { -+ static USE_NATIVE_DRIVER: boolean; -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js -new file mode 100644 -index 0000000..0ae5165 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js -@@ -0,0 +1,25 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var BaseItemAnimator = /** @class */ (function () { -+ function BaseItemAnimator() { -+ } -+ BaseItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ BaseItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ BaseItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ //no need -+ }; -+ BaseItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ return false; -+ }; -+ BaseItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ BaseItemAnimator.USE_NATIVE_DRIVER = true; -+ return BaseItemAnimator; -+}()); -+exports.BaseItemAnimator = BaseItemAnimator; -+//# sourceMappingURL=ItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js.map -new file mode 100644 -index 0000000..732604a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ItemAnimator.js","sourceRoot":"","sources":["../../../src/core/ItemAnimator.ts"],"names":[],"mappings":";;AAwBA;IAAA;IAoBA,CAAC;IAlBU,2CAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,0CAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,4CAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,SAAS;IACb,CAAC;IAEM,uCAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC1G,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,6CAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IAlBa,kCAAiB,GAAG,IAAI,CAAC;IAmB3C,uBAAC;CAAA,AApBD,IAoBC;AApBY,4CAAgB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.d.ts -new file mode 100644 -index 0000000..c30743a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.d.ts -@@ -0,0 +1,27 @@ -+import RecyclerListView, { RecyclerListViewProps, RecyclerListViewState } from "./RecyclerListView"; -+export interface ProgressiveListViewProps extends RecyclerListViewProps { -+ maxRenderAhead?: number; -+ renderAheadStep?: number; -+} -+/** -+ * This will incremently update renderAhread distance and render the page progressively. -+ */ -+export default class ProgressiveListView extends RecyclerListView { -+ static defaultProps: { -+ maxRenderAhead: number; -+ renderAheadStep: number; -+ renderAheadOffset: number; -+ canChangeSize: boolean; -+ disableRecycling: boolean; -+ initialOffset: number; -+ initialRenderIndex: number; -+ isHorizontal: boolean; -+ onEndReachedThreshold: number; -+ distanceFromWindow: number; -+ }; -+ private renderAheadUdpateCallbackId?; -+ componentDidMount(): void; -+ private updateRenderAheadProgessively; -+ private incrementRenderAhead; -+ private cancelRenderAheadUpdate; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js -new file mode 100644 -index 0000000..9176a38 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js -@@ -0,0 +1,77 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecyclerListView_1 = require("./RecyclerListView"); -+/** -+ * This will incremently update renderAhread distance and render the page progressively. -+ */ -+var ProgressiveListView = /** @class */ (function (_super) { -+ __extends(ProgressiveListView, _super); -+ function ProgressiveListView() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ ProgressiveListView.prototype.componentDidMount = function () { -+ if (_super.prototype.componentDidMount) { -+ _super.prototype.componentDidMount.call(this); -+ } -+ this.updateRenderAheadProgessively(this.getCurrentRenderAheadOffset()); -+ }; -+ ProgressiveListView.prototype.updateRenderAheadProgessively = function (newVal) { -+ var _this = this; -+ this.cancelRenderAheadUpdate(); // Cancel any pending callback. -+ this.renderAheadUdpateCallbackId = requestAnimationFrame(function () { -+ if (!_this.updateRenderAheadOffset(newVal)) { -+ _this.updateRenderAheadProgessively(newVal); -+ } -+ else { -+ _this.incrementRenderAhead(); -+ } -+ }); -+ }; -+ ProgressiveListView.prototype.incrementRenderAhead = function () { -+ if (this.props.maxRenderAhead && this.props.renderAheadStep) { -+ var layoutManager = this.getVirtualRenderer().getLayoutManager(); -+ var currentRenderAheadOffset = this.getCurrentRenderAheadOffset(); -+ if (layoutManager) { -+ var contentDimension = layoutManager.getContentDimension(); -+ var maxContentSize = this.props.isHorizontal ? contentDimension.width : contentDimension.height; -+ if (currentRenderAheadOffset < maxContentSize && currentRenderAheadOffset < this.props.maxRenderAhead) { -+ var newRenderAheadOffset = currentRenderAheadOffset + this.props.renderAheadStep; -+ this.updateRenderAheadProgessively(newRenderAheadOffset); -+ } -+ } -+ } -+ }; -+ ProgressiveListView.prototype.cancelRenderAheadUpdate = function () { -+ if (this.renderAheadUdpateCallbackId) { -+ cancelAnimationFrame(this.renderAheadUdpateCallbackId); -+ } -+ }; -+ ProgressiveListView.defaultProps = __assign({}, RecyclerListView_1.default.defaultProps, { maxRenderAhead: Number.MAX_VALUE, renderAheadStep: 300, renderAheadOffset: 0 }); -+ return ProgressiveListView; -+}(RecyclerListView_1.default)); -+exports.default = ProgressiveListView; -+//# sourceMappingURL=ProgressiveListView.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js.map b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js.map -new file mode 100644 -index 0000000..c9c3fd6 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ProgressiveListView.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ProgressiveListView.js","sourceRoot":"","sources":["../../../src/core/ProgressiveListView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uDAAoG;AAKpG;;GAEG;AACH;IAAiD,uCAAiE;IAAlH;;IA+CA,CAAC;IAtCU,+CAAiB,GAAxB;QACI,IAAI,iBAAM,iBAAiB,EAAE;YACzB,iBAAM,iBAAiB,WAAE,CAAC;SAC7B;QACD,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,CAAC;IAC3E,CAAC;IAEO,2DAA6B,GAArC,UAAsC,MAAc;QAApD,iBASC;QARG,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,+BAA+B;QAC/D,IAAI,CAAC,2BAA2B,GAAG,qBAAqB,CAAC;YACrD,IAAI,CAAC,KAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE;gBACvC,KAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;aAC9C;iBAAM;gBACH,KAAI,CAAC,oBAAoB,EAAE,CAAC;aAC/B;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kDAAoB,GAA5B;QACI,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;YACzD,IAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACnE,IAAM,wBAAwB,GAAG,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACpE,IAAI,aAAa,EAAE;gBACf,IAAM,gBAAgB,GAAG,aAAa,CAAC,mBAAmB,EAAE,CAAC;gBAC7D,IAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAClG,IAAI,wBAAwB,GAAG,cAAc,IAAI,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;oBACnG,IAAM,oBAAoB,GAAG,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;oBACnF,IAAI,CAAC,6BAA6B,CAAC,oBAAoB,CAAC,CAAC;iBAC5D;aACJ;SACJ;IACL,CAAC;IAEO,qDAAuB,GAA/B;QACI,IAAI,IAAI,CAAC,2BAA2B,EAAE;YAClC,oBAAoB,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;SAC1D;IACL,CAAC;IA7Ca,gCAAY,gBACnB,0BAAgB,CAAC,YAAY,IAChC,cAAc,EAAE,MAAM,CAAC,SAAS,EAChC,eAAe,EAAE,GAAG,EACpB,iBAAiB,EAAE,CAAC,IACtB;IAyCN,0BAAC;CAAA,AA/CD,CAAiD,0BAAgB,GA+ChE;kBA/CoB,mBAAmB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.d.ts -new file mode 100644 -index 0000000..1a55b49 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.d.ts -@@ -0,0 +1,129 @@ -+import * as React from "react"; -+import ContextProvider from "./dependencies/ContextProvider"; -+import { BaseDataProvider } from "./dependencies/DataProvider"; -+import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; -+import { Layout } from "./layoutmanager/LayoutManager"; -+import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./scrollcomponent/BaseScrollView"; -+import { TOnItemStatusChanged } from "./ViewabilityTracker"; -+import VirtualRenderer, { RenderStack } from "./VirtualRenderer"; -+import ItemAnimator from "./ItemAnimator"; -+import { DebugHandlers } from ".."; -+/*** -+ * To use on web, start importing from recyclerlistview/web. To make it even easier specify an alias in you builder of choice. -+ */ -+/*** -+ * This is the main component, please refer to samples to understand how to use. -+ * For advanced usage check out prop descriptions below. -+ * You also get common methods such as: scrollToIndex, scrollToItem, scrollToTop, scrollToEnd, scrollToOffset, getCurrentScrollOffset, -+ * findApproxFirstVisibleIndex. -+ * You'll need a ref to Recycler in order to call these -+ * Needs to have bounded size in all cases other than window scrolling (web). -+ * -+ * NOTE: React Native implementation uses ScrollView internally which means you get all ScrollView features as well such as Pull To Refresh, paging enabled -+ * You can easily create a recycling image flip view using one paging enabled flag. Read about ScrollView features in official -+ * react native documentation. -+ * NOTE: If you see blank space look at the renderAheadOffset prop and make sure your data provider has a good enough rowHasChanged method. -+ * Blanks are totally avoidable with this listview. -+ * NOTE: Also works on web (experimental) -+ * NOTE: For reflowability set canChangeSize to true (experimental) -+ */ -+export interface OnRecreateParams { -+ lastOffset?: number; -+} -+export interface RecyclerListViewProps { -+ layoutProvider: BaseLayoutProvider; -+ dataProvider: BaseDataProvider; -+ rowRenderer: (type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+ contextProvider?: ContextProvider; -+ renderAheadOffset?: number; -+ isHorizontal?: boolean; -+ onScroll?: (rawEvent: ScrollEvent, offsetX: number, offsetY: number) => void; -+ onRecreate?: (params: OnRecreateParams) => void; -+ onEndReached?: () => void; -+ onEndReachedThreshold?: number; -+ onVisibleIndexesChanged?: TOnItemStatusChanged; -+ onVisibleIndicesChanged?: TOnItemStatusChanged; -+ renderFooter?: () => JSX.Element | JSX.Element[] | null; -+ externalScrollView?: { -+ new (props: ScrollViewDefaultProps): BaseScrollView; -+ }; -+ initialOffset?: number; -+ initialRenderIndex?: number; -+ scrollThrottle?: number; -+ canChangeSize?: boolean; -+ distanceFromWindow?: number; -+ useWindowScroll?: boolean; -+ disableRecycling?: boolean; -+ forceNonDeterministicRendering?: boolean; -+ extendedState?: object; -+ itemAnimator?: ItemAnimator; -+ optimizeForInsertDeleteAnimations?: boolean; -+ style?: object | number; -+ debugHandlers?: DebugHandlers; -+ scrollViewProps?: object; -+} -+export interface RecyclerListViewState { -+ renderStack: RenderStack; -+ internalSnapshot: Record; -+} -+export default class RecyclerListView

extends React.Component { -+ static defaultProps: { -+ canChangeSize: boolean; -+ disableRecycling: boolean; -+ initialOffset: number; -+ initialRenderIndex: number; -+ isHorizontal: boolean; -+ onEndReachedThreshold: number; -+ distanceFromWindow: number; -+ renderAheadOffset: number; -+ }; -+ static propTypes: {}; -+ private refreshRequestDebouncer; -+ private _virtualRenderer; -+ private _onEndReachedCalled; -+ private _initComplete; -+ private _relayoutReqIndex; -+ private _params; -+ private _layout; -+ private _pendingScrollToOffset; -+ private _tempDim; -+ private _initialOffset; -+ private _cachedLayouts?; -+ private _scrollComponent; -+ private _defaultItemAnimator; -+ constructor(props: P, context?: any); -+ componentWillReceiveProps(newProps: RecyclerListViewProps): void; -+ componentDidUpdate(): void; -+ componentWillUnmount(): void; -+ componentWillMount(): void; -+ scrollToIndex(index: number, animate?: boolean): void; -+ scrollToItem(data: any, animate?: boolean): void; -+ getLayout(index: number): Layout | undefined; -+ scrollToTop(animate?: boolean): void; -+ scrollToEnd(animate?: boolean): void; -+ scrollToOffset: (x: number, y: number, animate?: boolean) => void; -+ updateRenderAheadOffset(renderAheadOffset: number): boolean; -+ getCurrentRenderAheadOffset(): number; -+ getCurrentScrollOffset(): number; -+ findApproxFirstVisibleIndex(): number; -+ getRenderedSize(): Dimension; -+ getContentDimension(): Dimension; -+ forceRerender(): void; -+ render(): JSX.Element; -+ protected getVirtualRenderer(): VirtualRenderer; -+ private _checkAndChangeLayouts; -+ private _refreshViewability; -+ private _queueStateRefresh; -+ private _onSizeChanged; -+ private _renderStackWhenReady; -+ private _initTrackers; -+ private _assertDependencyPresence; -+ private _assertType; -+ private _dataHasChanged; -+ private _renderRowUsingMeta; -+ private _onViewContainerSizeChange; -+ private _checkExpectedDimensionDiscrepancy; -+ private _generateRenderStack; -+ private _onScroll; -+ private _processOnEndReached; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js -new file mode 100644 -index 0000000..a8c46fe ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js -@@ -0,0 +1,577 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+/*** -+ * DONE: Reduce layout processing on data insert -+ * DONE: Add notify data set changed and notify data insert option in data source -+ * DONE: Add on end reached callback -+ * DONE: Make another class for render stack generator -+ * DONE: Simplify rendering a loading footer -+ * DONE: Anchor first visible index on any insert/delete data wise -+ * DONE: Build Scroll to index -+ * DONE: Give viewability callbacks -+ * DONE: Add full render logic in cases like change of dimensions -+ * DONE: Fix all proptypes -+ * DONE: Add Initial render Index support -+ * DONE: Add animated scroll to web scrollviewer -+ * DONE: Animate list view transition, including add/remove -+ * DONE: Implement sticky headers and footers -+ * TODO: Destroy less frequently used items in recycle pool, this will help in case of too many types. -+ * TODO: Make viewability callbacks configurable -+ * TODO: Observe size changes on web to optimize for reflowability -+ * TODO: Solve //TSI -+ */ -+var debounce = require("lodash.debounce"); -+var PropTypes = require("prop-types"); -+var React = require("react"); -+var ts_object_utils_1 = require("ts-object-utils"); -+var ContextProvider_1 = require("./dependencies/ContextProvider"); -+var DataProvider_1 = require("./dependencies/DataProvider"); -+var LayoutProvider_1 = require("./dependencies/LayoutProvider"); -+var CustomError_1 = require("./exceptions/CustomError"); -+var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); -+var Constants_1 = require("./constants/Constants"); -+var Messages_1 = require("./constants/Messages"); -+var VirtualRenderer_1 = require("./VirtualRenderer"); -+var ItemAnimator_1 = require("./ItemAnimator"); -+//#if [REACT-NATIVE] -+var ScrollComponent_1 = require("../platform/reactnative/scrollcomponent/ScrollComponent"); -+var ViewRenderer_1 = require("../platform/reactnative/viewrenderer/ViewRenderer"); -+var DefaultJSItemAnimator_1 = require("../platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator"); -+var react_native_1 = require("react-native"); -+var IS_WEB = !react_native_1.Platform || react_native_1.Platform.OS === "web"; -+var RecyclerListView = /** @class */ (function (_super) { -+ __extends(RecyclerListView, _super); -+ function RecyclerListView(props, context) { -+ var _this = _super.call(this, props, context) || this; -+ _this.refreshRequestDebouncer = debounce(function (executable) { -+ executable(); -+ }); -+ _this._onEndReachedCalled = false; -+ _this._initComplete = false; -+ _this._relayoutReqIndex = -1; -+ _this._params = { -+ initialOffset: 0, -+ initialRenderIndex: 0, -+ isHorizontal: false, -+ itemCount: 0, -+ renderAheadOffset: 250, -+ }; -+ _this._layout = { height: 0, width: 0 }; -+ _this._pendingScrollToOffset = null; -+ _this._tempDim = { height: 0, width: 0 }; -+ _this._initialOffset = 0; -+ _this._scrollComponent = null; -+ _this._defaultItemAnimator = new DefaultJSItemAnimator_1.DefaultJSItemAnimator(); -+ _this.scrollToOffset = function (x, y, animate) { -+ if (animate === void 0) { animate = false; } -+ if (_this._scrollComponent) { -+ if (_this.props.isHorizontal) { -+ y = 0; -+ } -+ else { -+ x = 0; -+ } -+ _this._scrollComponent.scrollTo(x, y, animate); -+ } -+ }; -+ _this._onSizeChanged = function (layout) { -+ var hasHeightChanged = _this._layout.height !== layout.height; -+ var hasWidthChanged = _this._layout.width !== layout.width; -+ _this._layout.height = layout.height; -+ _this._layout.width = layout.width; -+ if (layout.height === 0 || layout.width === 0) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.layoutException); -+ } -+ if (!_this._initComplete) { -+ _this._initComplete = true; -+ _this._initTrackers(); -+ _this._processOnEndReached(); -+ } -+ else { -+ if ((hasHeightChanged && hasWidthChanged) || -+ (hasHeightChanged && _this.props.isHorizontal) || -+ (hasWidthChanged && !_this.props.isHorizontal)) { -+ _this._checkAndChangeLayouts(_this.props, true); -+ } -+ else { -+ _this._refreshViewability(); -+ } -+ } -+ }; -+ _this._renderStackWhenReady = function (stack) { -+ _this.setState(function () { -+ return { renderStack: stack }; -+ }); -+ }; -+ _this._dataHasChanged = function (row1, row2) { -+ return _this.props.dataProvider.rowHasChanged(row1, row2); -+ }; -+ _this._onViewContainerSizeChange = function (dim, index) { -+ //Cannot be null here -+ var layoutManager = _this._virtualRenderer.getLayoutManager(); -+ if (_this.props.debugHandlers && _this.props.debugHandlers.resizeDebugHandler) { -+ var itemRect = layoutManager.getLayouts()[index]; -+ _this.props.debugHandlers.resizeDebugHandler.resizeDebug({ -+ width: itemRect.width, -+ height: itemRect.height, -+ }, dim, index); -+ } -+ if (layoutManager.overrideLayout(index, dim)) { -+ if (_this._relayoutReqIndex === -1) { -+ _this._relayoutReqIndex = index; -+ } -+ else { -+ _this._relayoutReqIndex = Math.min(_this._relayoutReqIndex, index); -+ } -+ _this._queueStateRefresh(); -+ } -+ }; -+ _this._onScroll = function (offsetX, offsetY, rawEvent) { -+ //Adjusting offsets using distanceFromWindow -+ _this._virtualRenderer.updateOffset(offsetX, offsetY, -_this.props.distanceFromWindow, true); -+ if (_this.props.onScroll) { -+ _this.props.onScroll(rawEvent, offsetX, offsetY); -+ } -+ _this._processOnEndReached(); -+ }; -+ _this._virtualRenderer = new VirtualRenderer_1.default(_this._renderStackWhenReady, function (offset) { -+ _this._pendingScrollToOffset = offset; -+ }, function (index) { -+ return _this.props.dataProvider.getStableId(index); -+ }, !props.disableRecycling); -+ _this.state = { -+ internalSnapshot: {}, -+ renderStack: {}, -+ }; -+ return _this; -+ } -+ RecyclerListView.prototype.componentWillReceiveProps = function (newProps) { -+ this._assertDependencyPresence(newProps); -+ this._checkAndChangeLayouts(newProps); -+ if (!this.props.onVisibleIndicesChanged) { -+ this._virtualRenderer.removeVisibleItemsListener(); -+ } -+ if (this.props.onVisibleIndexesChanged) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); -+ } -+ if (this.props.onVisibleIndicesChanged) { -+ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); -+ } -+ }; -+ RecyclerListView.prototype.componentDidUpdate = function () { -+ var _this = this; -+ if (this._pendingScrollToOffset) { -+ var offset_1 = this._pendingScrollToOffset; -+ this._pendingScrollToOffset = null; -+ if (this.props.isHorizontal) { -+ offset_1.y = 0; -+ } -+ else { -+ offset_1.x = 0; -+ } -+ setTimeout(function () { -+ _this.scrollToOffset(offset_1.x, offset_1.y, false); -+ }, 0); -+ } -+ this._processOnEndReached(); -+ this._checkAndChangeLayouts(this.props); -+ if (this.props.dataProvider.getSize() === 0) { -+ console.warn(Messages_1.Messages.WARN_NO_DATA); //tslint:disable-line -+ } -+ }; -+ RecyclerListView.prototype.componentWillUnmount = function () { -+ if (this.props.contextProvider) { -+ var uniqueKey = this.props.contextProvider.getUniqueKey(); -+ if (uniqueKey) { -+ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX, this.getCurrentScrollOffset()); -+ if (this.props.forceNonDeterministicRendering) { -+ if (this._virtualRenderer) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ var layoutsToCache = layoutManager.getLayouts(); -+ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX, JSON.stringify({ layoutArray: layoutsToCache })); -+ } -+ } -+ } -+ } -+ } -+ }; -+ RecyclerListView.prototype.componentWillMount = function () { -+ if (this.props.contextProvider) { -+ var uniqueKey = this.props.contextProvider.getUniqueKey(); -+ if (uniqueKey) { -+ var offset = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); -+ if (typeof offset === "number" && offset > 0) { -+ this._initialOffset = offset; -+ if (this.props.onRecreate) { -+ this.props.onRecreate({ lastOffset: this._initialOffset }); -+ } -+ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); -+ } -+ if (this.props.forceNonDeterministicRendering) { -+ var cachedLayouts = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); -+ if (cachedLayouts && typeof cachedLayouts === "string") { -+ this._cachedLayouts = JSON.parse(cachedLayouts).layoutArray; -+ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); -+ } -+ } -+ } -+ } -+ }; -+ RecyclerListView.prototype.scrollToIndex = function (index, animate) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ var offsets = layoutManager.getOffsetForIndex(index); -+ this.scrollToOffset(offsets.x, offsets.y, animate); -+ } -+ else { -+ console.warn(Messages_1.Messages.WARN_SCROLL_TO_INDEX); //tslint:disable-line -+ } -+ }; -+ RecyclerListView.prototype.scrollToItem = function (data, animate) { -+ var count = this.props.dataProvider.getSize(); -+ for (var i = 0; i < count; i++) { -+ if (this.props.dataProvider.getDataForIndex(i) === data) { -+ this.scrollToIndex(i, animate); -+ break; -+ } -+ } -+ }; -+ RecyclerListView.prototype.getLayout = function (index) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ return layoutManager ? layoutManager.getLayouts()[index] : undefined; -+ }; -+ RecyclerListView.prototype.scrollToTop = function (animate) { -+ this.scrollToOffset(0, 0, animate); -+ }; -+ RecyclerListView.prototype.scrollToEnd = function (animate) { -+ var lastIndex = this.props.dataProvider.getSize() - 1; -+ this.scrollToIndex(lastIndex, animate); -+ }; -+ // You can use requestAnimationFrame callback to change renderAhead in multiple frames to enable advanced progressive -+ // rendering when view types are very complex. This method returns a boolean saying if the update was committed. Retry in -+ // the next frame if you get a failure (if mount wasn't complete). Value should be greater than or equal to 0; -+ // Very useful when you have a page where you need a large renderAheadOffset. Setting it at once will slow down the load and -+ // this will help mitigate that. -+ RecyclerListView.prototype.updateRenderAheadOffset = function (renderAheadOffset) { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ if (viewabilityTracker) { -+ viewabilityTracker.updateRenderAheadOffset(renderAheadOffset); -+ return true; -+ } -+ return false; -+ }; -+ RecyclerListView.prototype.getCurrentRenderAheadOffset = function () { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ if (viewabilityTracker) { -+ return viewabilityTracker.getCurrentRenderAheadOffset(); -+ } -+ return this.props.renderAheadOffset; -+ }; -+ RecyclerListView.prototype.getCurrentScrollOffset = function () { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ return viewabilityTracker ? viewabilityTracker.getLastActualOffset() : 0; -+ }; -+ RecyclerListView.prototype.findApproxFirstVisibleIndex = function () { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ return viewabilityTracker ? viewabilityTracker.findFirstLogicallyVisibleIndex() : 0; -+ }; -+ RecyclerListView.prototype.getRenderedSize = function () { -+ return this._layout; -+ }; -+ RecyclerListView.prototype.getContentDimension = function () { -+ return this._virtualRenderer.getLayoutDimension(); -+ }; -+ // Force Rerender forcefully to update view renderer. Use this in rare circumstances -+ RecyclerListView.prototype.forceRerender = function () { -+ this.setState({ -+ internalSnapshot: {}, -+ }); -+ }; -+ RecyclerListView.prototype.render = function () { -+ //TODO:Talha -+ // const { -+ // layoutProvider, -+ // dataProvider, -+ // contextProvider, -+ // renderAheadOffset, -+ // onEndReached, -+ // onEndReachedThreshold, -+ // onVisibleIndicesChanged, -+ // initialOffset, -+ // initialRenderIndex, -+ // disableRecycling, -+ // forceNonDeterministicRendering, -+ // extendedState, -+ // itemAnimator, -+ // rowRenderer, -+ // ...props, -+ // } = this.props; -+ var _this = this; -+ return (React.createElement(ScrollComponent_1.default, __assign({ ref: function (scrollComponent) { return _this._scrollComponent = scrollComponent; } }, this.props, this.props.scrollViewProps, { onScroll: this._onScroll, onSizeChanged: this._onSizeChanged, contentHeight: this._initComplete ? this._virtualRenderer.getLayoutDimension().height : 0, contentWidth: this._initComplete ? this._virtualRenderer.getLayoutDimension().width : 0 }), this._generateRenderStack())); -+ }; -+ RecyclerListView.prototype.getVirtualRenderer = function () { -+ return this._virtualRenderer; -+ }; -+ RecyclerListView.prototype._checkAndChangeLayouts = function (newProps, forceFullRender) { -+ this._params.isHorizontal = newProps.isHorizontal; -+ this._params.itemCount = newProps.dataProvider.getSize(); -+ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); -+ this._virtualRenderer.setLayoutProvider(newProps.layoutProvider); -+ if (newProps.dataProvider.hasStableIds() && this.props.dataProvider !== newProps.dataProvider && newProps.dataProvider.requiresDataChangeHandling()) { -+ this._virtualRenderer.handleDataSetChange(newProps.dataProvider, this.props.optimizeForInsertDeleteAnimations); -+ } -+ if (forceFullRender || this.props.layoutProvider !== newProps.layoutProvider || this.props.isHorizontal !== newProps.isHorizontal) { -+ //TODO:Talha use old layout manager -+ this._virtualRenderer.setLayoutManager(newProps.layoutProvider.newLayoutManager(this._layout, newProps.isHorizontal)); -+ if (newProps.layoutProvider.shouldRefreshWithAnchoring) { -+ this._virtualRenderer.refreshWithAnchor(); -+ } -+ else { -+ this._virtualRenderer.refresh(); -+ } -+ this._refreshViewability(); -+ } -+ else if (this.props.dataProvider !== newProps.dataProvider) { -+ this._onEndReachedCalled = false; -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ layoutManager.relayoutFromIndex(newProps.dataProvider.getFirstIndexToProcessInternal(), newProps.dataProvider.getSize()); -+ this._virtualRenderer.refresh(); -+ } -+ } -+ else if (this._relayoutReqIndex >= 0) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ var dataProviderSize = newProps.dataProvider.getSize(); -+ layoutManager.relayoutFromIndex(Math.min(Math.max(dataProviderSize - 1, 0), this._relayoutReqIndex), dataProviderSize); -+ this._relayoutReqIndex = -1; -+ this._refreshViewability(); -+ } -+ } -+ }; -+ RecyclerListView.prototype._refreshViewability = function () { -+ this._virtualRenderer.refresh(); -+ this._queueStateRefresh(); -+ }; -+ RecyclerListView.prototype._queueStateRefresh = function () { -+ var _this = this; -+ this.refreshRequestDebouncer(function () { -+ _this.setState(function (prevState) { -+ return prevState; -+ }); -+ }); -+ }; -+ RecyclerListView.prototype._initTrackers = function () { -+ this._assertDependencyPresence(this.props); -+ if (this.props.onVisibleIndexesChanged) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); -+ } -+ if (this.props.onVisibleIndicesChanged) { -+ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); -+ } -+ this._params = { -+ initialOffset: this._initialOffset ? this._initialOffset : this.props.initialOffset, -+ initialRenderIndex: this.props.initialRenderIndex, -+ isHorizontal: this.props.isHorizontal, -+ itemCount: this.props.dataProvider.getSize(), -+ renderAheadOffset: this.props.renderAheadOffset, -+ }; -+ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); -+ var layoutManager = this.props.layoutProvider.newLayoutManager(this._layout, this.props.isHorizontal, this._cachedLayouts); -+ this._virtualRenderer.setLayoutManager(layoutManager); -+ this._virtualRenderer.setLayoutProvider(this.props.layoutProvider); -+ this._virtualRenderer.init(); -+ var offset = this._virtualRenderer.getInitialOffset(); -+ var contentDimension = layoutManager.getContentDimension(); -+ if ((offset.y > 0 && contentDimension.height > this._layout.height) || -+ (offset.x > 0 && contentDimension.width > this._layout.width)) { -+ this._pendingScrollToOffset = offset; -+ this.setState({}); -+ } -+ else { -+ this._virtualRenderer.startViewabilityTracker(); -+ } -+ }; -+ RecyclerListView.prototype._assertDependencyPresence = function (props) { -+ if (!props.dataProvider || !props.layoutProvider) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.unresolvedDependenciesException); -+ } -+ }; -+ RecyclerListView.prototype._assertType = function (type) { -+ if (!type && type !== 0) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.itemTypeNullException); -+ } -+ }; -+ RecyclerListView.prototype._renderRowUsingMeta = function (itemMeta) { -+ var dataSize = this.props.dataProvider.getSize(); -+ var dataIndex = itemMeta.dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(dataIndex) && dataIndex < dataSize) { -+ var itemRect = this._virtualRenderer.getLayoutManager().getLayouts()[dataIndex]; -+ var data = this.props.dataProvider.getDataForIndex(dataIndex); -+ var type = this.props.layoutProvider.getLayoutTypeForIndex(dataIndex); -+ var key = this._virtualRenderer.syncAndGetKey(dataIndex); -+ var styleOverrides = this._virtualRenderer.getLayoutManager().getStyleOverridesForIndex(dataIndex); -+ this._assertType(type); -+ if (!this.props.forceNonDeterministicRendering) { -+ this._checkExpectedDimensionDiscrepancy(itemRect, type, dataIndex); -+ } -+ return (React.createElement(ViewRenderer_1.default, { key: key, data: data, dataHasChanged: this._dataHasChanged, x: itemRect.x, y: itemRect.y, layoutType: type, index: dataIndex, styleOverrides: styleOverrides, layoutProvider: this.props.layoutProvider, forceNonDeterministicRendering: this.props.forceNonDeterministicRendering, isHorizontal: this.props.isHorizontal, onSizeChanged: this._onViewContainerSizeChange, childRenderer: this.props.rowRenderer, height: itemRect.height, width: itemRect.width, itemAnimator: ts_object_utils_1.Default.value(this.props.itemAnimator, this._defaultItemAnimator), extendedState: this.props.extendedState, internalSnapshot: this.state.internalSnapshot })); -+ } -+ return null; -+ }; -+ RecyclerListView.prototype._checkExpectedDimensionDiscrepancy = function (itemRect, type, index) { -+ if (this.props.layoutProvider.checkDimensionDiscrepancy(itemRect, type, index)) { -+ if (this._relayoutReqIndex === -1) { -+ this._relayoutReqIndex = index; -+ } -+ else { -+ this._relayoutReqIndex = Math.min(this._relayoutReqIndex, index); -+ } -+ } -+ }; -+ RecyclerListView.prototype._generateRenderStack = function () { -+ var renderedItems = []; -+ for (var key in this.state.renderStack) { -+ if (this.state.renderStack.hasOwnProperty(key)) { -+ renderedItems.push(this._renderRowUsingMeta(this.state.renderStack[key])); -+ } -+ } -+ return renderedItems; -+ }; -+ RecyclerListView.prototype._processOnEndReached = function () { -+ if (this.props.onEndReached && this._virtualRenderer) { -+ var layout = this._virtualRenderer.getLayoutDimension(); -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ if (viewabilityTracker) { -+ var windowBound = this.props.isHorizontal ? layout.width - this._layout.width : layout.height - this._layout.height; -+ var lastOffset = viewabilityTracker ? viewabilityTracker.getLastOffset() : 0; -+ if (windowBound - lastOffset <= ts_object_utils_1.Default.value(this.props.onEndReachedThreshold, 0)) { -+ if (this.props.onEndReached && !this._onEndReachedCalled) { -+ this._onEndReachedCalled = true; -+ this.props.onEndReached(); -+ } -+ } -+ else { -+ this._onEndReachedCalled = false; -+ } -+ } -+ } -+ }; -+ RecyclerListView.defaultProps = { -+ canChangeSize: false, -+ disableRecycling: false, -+ initialOffset: 0, -+ initialRenderIndex: 0, -+ isHorizontal: false, -+ onEndReachedThreshold: 0, -+ distanceFromWindow: 0, -+ renderAheadOffset: IS_WEB ? 1000 : 250, -+ }; -+ RecyclerListView.propTypes = {}; -+ return RecyclerListView; -+}(React.Component)); -+exports.default = RecyclerListView; -+RecyclerListView.propTypes = { -+ //Refer the sample -+ layoutProvider: PropTypes.instanceOf(LayoutProvider_1.BaseLayoutProvider).isRequired, -+ //Refer the sample -+ dataProvider: PropTypes.instanceOf(DataProvider_1.BaseDataProvider).isRequired, -+ //Used to maintain scroll position in case view gets destroyed e.g, cases of back navigation -+ contextProvider: PropTypes.instanceOf(ContextProvider_1.default), -+ //Methods which returns react component to be rendered. You get type of view and data in the callback. -+ rowRenderer: PropTypes.func.isRequired, -+ //Initial offset you want to start rendering from, very useful if you want to maintain scroll context across pages. -+ initialOffset: PropTypes.number, -+ //Specify how many pixels in advance do you want views to be rendered. Increasing this value can help reduce blanks (if any). However keeping this as low -+ //as possible should be the intent. Higher values also increase re-render compute -+ renderAheadOffset: PropTypes.number, -+ //Whether the listview is horizontally scrollable. Both use staggeredGrid implementation -+ isHorizontal: PropTypes.bool, -+ //On scroll callback onScroll(rawEvent, offsetX, offsetY), note you get offsets no need to read scrollTop/scrollLeft -+ onScroll: PropTypes.func, -+ //callback onRecreate(params), when recreating recycler view from context provider. Gives you the initial params in the first -+ //frame itself to allow you to render content accordingly -+ onRecreate: PropTypes.func, -+ //Provide your own ScrollView Component. The contract for the scroll event should match the native scroll event contract, i.e. -+ // scrollEvent = { nativeEvent: { contentOffset: { x: offset, y: offset } } } -+ //Note: Please extend BaseScrollView to achieve expected behaviour -+ externalScrollView: PropTypes.func, -+ //Callback given when user scrolls to the end of the list or footer just becomes visible, useful in incremental loading scenarios -+ onEndReached: PropTypes.func, -+ //Specify how many pixels in advance you onEndReached callback -+ onEndReachedThreshold: PropTypes.number, -+ //Deprecated. Please use onVisibleIndicesChanged instead. -+ onVisibleIndexesChanged: PropTypes.func, -+ //Provides visible index, helpful in sending impression events etc, onVisibleIndicesChanged(all, now, notNow) -+ onVisibleIndicesChanged: PropTypes.func, -+ //Provide this method if you want to render a footer. Helpful in showing a loader while doing incremental loads. -+ renderFooter: PropTypes.func, -+ //Specify the initial item index you want rendering to start from. Preferred over initialOffset if both are specified. -+ initialRenderIndex: PropTypes.number, -+ //iOS only. Scroll throttle duration. -+ scrollThrottle: PropTypes.number, -+ //Specify if size can change, listview will automatically relayout items. For web, works only with useWindowScroll = true -+ canChangeSize: PropTypes.bool, -+ //Specify how far away the first list item is from start of the RecyclerListView. e.g, if you have content padding on top or left. -+ //This is an adjustment for optimization and to make sure onVisibileIndexesChanged callback is correct. -+ //Ideally try to avoid setting large padding values on RLV content. If you have to please correct offsets reported, handle -+ //them in a custom ScrollView and pass it as an externalScrollView. If you want this to be accounted in scrollToOffset please -+ //override the method and handle manually. -+ distanceFromWindow: PropTypes.number, -+ //Web only. Layout elements in window instead of a scrollable div. -+ useWindowScroll: PropTypes.bool, -+ //Turns off recycling. You still get progressive rendering and all other features. Good for lazy rendering. This should not be used in most cases. -+ disableRecycling: PropTypes.bool, -+ //Default is false, if enabled dimensions provided in layout provider will not be strictly enforced. -+ //Rendered dimensions will be used to relayout items. Slower if enabled. -+ forceNonDeterministicRendering: PropTypes.bool, -+ //In some cases the data passed at row level may not contain all the info that the item depends upon, you can keep all other info -+ //outside and pass it down via this prop. Changing this object will cause everything to re-render. Make sure you don't change -+ //it often to ensure performance. Re-renders are heavy. -+ extendedState: PropTypes.object, -+ //Enables animating RecyclerListView item cells e.g, shift, add, remove etc. This prop can be used to pass an external item animation implementation. -+ //Look into BaseItemAnimator/DefaultJSItemAnimator/DefaultNativeItemAnimator/DefaultWebItemAnimator for more info. -+ //By default there are few animations, to disable completely simply pass blank new BaseItemAnimator() object. Remember, create -+ //one object and keep it do not create multiple object of type BaseItemAnimator. -+ //Note: You might want to look into DefaultNativeItemAnimator to check an implementation based on LayoutAnimation. By default, -+ //animations are JS driven to avoid workflow interference. Also, please note LayoutAnimation is buggy on Android. -+ itemAnimator: PropTypes.instanceOf(ItemAnimator_1.BaseItemAnimator), -+ //Enables you to utilize layout animations better by unmounting removed items. Please note, this might increase unmounts -+ //on large data changes. -+ optimizeForInsertDeleteAnimations: PropTypes.bool, -+ //To pass down style to inner ScrollView -+ style: PropTypes.oneOfType([ -+ PropTypes.object, -+ PropTypes.number, -+ ]), -+ //For TS use case, not necessary with JS use. -+ //For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread -+ //and passed down. -+ scrollViewProps: PropTypes.object, -+}; -+//# sourceMappingURL=RecyclerListView.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js.map b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js.map -new file mode 100644 -index 0000000..4c15713 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/RecyclerListView.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"RecyclerListView.js","sourceRoot":"","sources":["../../../src/core/RecyclerListView.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.d.ts -new file mode 100644 -index 0000000..e712796 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.d.ts -@@ -0,0 +1,49 @@ -+/** -+ * Created by ananya.chandra on 14/09/18. -+ */ -+import * as React from "react"; -+import { StyleProp, ViewStyle } from "react-native"; -+import { RecyclerListViewProps } from "./RecyclerListView"; -+export interface StickyContainerProps { -+ children: RecyclerChild; -+ stickyHeaderIndices?: number[]; -+ stickyFooterIndices?: number[]; -+ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+ style?: StyleProp; -+} -+export interface RecyclerChild extends React.ReactElement { -+ ref: (recyclerRef: any) => {}; -+ props: RecyclerListViewProps; -+} -+export default class StickyContainer

extends React.Component

{ -+ static propTypes: {}; -+ private _recyclerRef; -+ private _dataProvider; -+ private _layoutProvider; -+ private _extendedState; -+ private _rowRenderer; -+ private _distanceFromWindow; -+ private _stickyHeaderRef; -+ private _stickyFooterRef; -+ private _visibleIndicesAll; -+ constructor(props: P, context?: any); -+ componentWillReceiveProps(newProps: P): void; -+ render(): JSX.Element; -+ private _getRecyclerRef; -+ private _getStickyHeaderRef; -+ private _getStickyFooterRef; -+ private _onVisibleIndicesChanged; -+ private _callStickyObjectsOnVisibleIndicesChanged; -+ private _onScroll; -+ private _assertChildType; -+ private _isChildRecyclerInstance; -+ private _getLayoutForIndex; -+ private _getDataForIndex; -+ private _getLayoutTypeForIndex; -+ private _getExtendedState; -+ private _getRowRenderer; -+ private _getRLVRenderedSize; -+ private _getContentDimension; -+ private _getDistanceFromWindow; -+ private _initParams; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js -new file mode 100644 -index 0000000..8de1ec4 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js -@@ -0,0 +1,187 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 14/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var PropTypes = require("prop-types"); -+var react_native_1 = require("react-native"); -+var StickyHeader_1 = require("./sticky/StickyHeader"); -+var StickyFooter_1 = require("./sticky/StickyFooter"); -+var CustomError_1 = require("./exceptions/CustomError"); -+var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); -+var StickyContainer = /** @class */ (function (_super) { -+ __extends(StickyContainer, _super); -+ function StickyContainer(props, context) { -+ var _this = _super.call(this, props, context) || this; -+ _this._recyclerRef = undefined; -+ _this._stickyHeaderRef = null; -+ _this._stickyFooterRef = null; -+ _this._visibleIndicesAll = []; -+ _this._getRecyclerRef = function (recycler) { -+ _this._recyclerRef = recycler; -+ if (_this.props.children.ref) { -+ if (typeof _this.props.children.ref === "function") { -+ (_this.props.children).ref(recycler); -+ } -+ else { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.refNotAsFunctionException); -+ } -+ } -+ }; -+ _this._getStickyHeaderRef = function (stickyHeaderRef) { -+ if (_this._stickyHeaderRef !== stickyHeaderRef) { -+ _this._stickyHeaderRef = stickyHeaderRef; -+ // TODO: Resetting state once ref is initialized. Can look for better solution. -+ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); -+ } -+ }; -+ _this._getStickyFooterRef = function (stickyFooterRef) { -+ if (_this._stickyFooterRef !== stickyFooterRef) { -+ _this._stickyFooterRef = stickyFooterRef; -+ // TODO: Resetting state once ref is initialized. Can look for better solution. -+ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); -+ } -+ }; -+ _this._onVisibleIndicesChanged = function (all, now, notNow) { -+ _this._visibleIndicesAll = all; -+ _this._callStickyObjectsOnVisibleIndicesChanged(all); -+ if (_this.props.children && _this.props.children.props && _this.props.children.props.onVisibleIndicesChanged) { -+ _this.props.children.props.onVisibleIndicesChanged(all, now, notNow); -+ } -+ }; -+ _this._callStickyObjectsOnVisibleIndicesChanged = function (all) { -+ if (_this._stickyHeaderRef) { -+ _this._stickyHeaderRef.onVisibleIndicesChanged(all); -+ } -+ if (_this._stickyFooterRef) { -+ _this._stickyFooterRef.onVisibleIndicesChanged(all); -+ } -+ }; -+ _this._onScroll = function (rawEvent, offsetX, offsetY) { -+ if (_this._stickyHeaderRef) { -+ _this._stickyHeaderRef.onScroll(offsetY); -+ } -+ if (_this._stickyFooterRef) { -+ _this._stickyFooterRef.onScroll(offsetY); -+ } -+ if (_this.props.children && _this.props.children.props.onScroll) { -+ _this.props.children.props.onScroll(rawEvent, offsetX, offsetY); -+ } -+ }; -+ _this._assertChildType = function () { -+ if (React.Children.count(_this.props.children) !== 1 || !_this._isChildRecyclerInstance()) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.wrongStickyChildTypeException); -+ } -+ }; -+ _this._isChildRecyclerInstance = function () { -+ return (_this.props.children.props.dataProvider -+ && _this.props.children.props.rowRenderer -+ && _this.props.children.props.layoutProvider); -+ }; -+ _this._getLayoutForIndex = function (index) { -+ if (_this._recyclerRef) { -+ return _this._recyclerRef.getLayout(index); -+ } -+ return undefined; -+ }; -+ _this._getDataForIndex = function (index) { -+ return _this._dataProvider.getDataForIndex(index); -+ }; -+ _this._getLayoutTypeForIndex = function (index) { -+ return _this._layoutProvider.getLayoutTypeForIndex(index); -+ }; -+ _this._getExtendedState = function () { -+ return _this._extendedState; -+ }; -+ _this._getRowRenderer = function () { -+ return _this._rowRenderer; -+ }; -+ _this._getRLVRenderedSize = function () { -+ if (_this._recyclerRef) { -+ return _this._recyclerRef.getRenderedSize(); -+ } -+ return undefined; -+ }; -+ _this._getContentDimension = function () { -+ if (_this._recyclerRef) { -+ return _this._recyclerRef.getContentDimension(); -+ } -+ return undefined; -+ }; -+ _this._getDistanceFromWindow = function () { -+ return _this._distanceFromWindow; -+ }; -+ _this._initParams = function (props) { -+ var childProps = props.children.props; -+ _this._dataProvider = childProps.dataProvider; -+ _this._layoutProvider = childProps.layoutProvider; -+ _this._extendedState = childProps.extendedState; -+ _this._rowRenderer = childProps.rowRenderer; -+ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; -+ }; -+ _this._assertChildType(); -+ var childProps = props.children.props; -+ _this._dataProvider = childProps.dataProvider; -+ _this._layoutProvider = childProps.layoutProvider; -+ _this._extendedState = childProps.extendedState; -+ _this._rowRenderer = childProps.rowRenderer; -+ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; -+ return _this; -+ } -+ StickyContainer.prototype.componentWillReceiveProps = function (newProps) { -+ this._initParams(newProps); -+ }; -+ StickyContainer.prototype.render = function () { -+ var _this = this; -+ this._assertChildType(); -+ var recycler = React.cloneElement(this.props.children, __assign({}, this.props.children.props, { ref: this._getRecyclerRef, onVisibleIndicesChanged: this._onVisibleIndicesChanged, onScroll: this._onScroll })); -+ return (React.createElement(react_native_1.View, { style: this.props.style ? this.props.style : { flex: 1 } }, -+ recycler, -+ this.props.stickyHeaderIndices ? (React.createElement(StickyHeader_1.default, { ref: function (stickyHeaderRef) { return _this._getStickyHeaderRef(stickyHeaderRef); }, stickyIndices: this.props.stickyHeaderIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null, -+ this.props.stickyFooterIndices ? (React.createElement(StickyFooter_1.default, { ref: function (stickyFooterRef) { return _this._getStickyFooterRef(stickyFooterRef); }, stickyIndices: this.props.stickyFooterIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null)); -+ }; -+ StickyContainer.propTypes = {}; -+ return StickyContainer; -+}(React.Component)); -+exports.default = StickyContainer; -+StickyContainer.propTypes = { -+ // Mandatory to pass a single child of RecyclerListView or any of its children classes. Exception will be thrown otherwise. -+ children: PropTypes.element.isRequired, -+ // Provide an array of indices whose corresponding items need to be stuck to the top of the recyclerView once the items scroll off the top. -+ // Every subsequent sticky index view will push the previous sticky view off the top to take its place. -+ // Note - Needs to be sorted ascending -+ stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), -+ // Works same as sticky headers, but for views to be stuck at the bottom of the recyclerView. -+ // Note - Needs to be sorted ascending -+ stickyFooterIndices: PropTypes.arrayOf(PropTypes.number), -+ // Will be called instead of rowRenderer for all sticky items. Any changes to the item for when they are stuck can be done here. -+ overrideRowRenderer: PropTypes.func, -+ // For all practical purposes, pass the style that is applied to the RecyclerListView component here. -+ style: PropTypes.object, -+}; -+//# sourceMappingURL=StickyContainer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js.map b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js.map -new file mode 100644 -index 0000000..4dc4cf2 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/StickyContainer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyContainer.js","sourceRoot":"","sources":["../../../src/core/StickyContainer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.d.ts -new file mode 100644 -index 0000000..820022a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.d.ts -@@ -0,0 +1,61 @@ -+import { Dimension } from "./dependencies/LayoutProvider"; -+import { Layout } from "./layoutmanager/LayoutManager"; -+/*** -+ * Given an offset this utility can compute visible items. Also tracks previously visible items to compute items which get hidden or visible -+ * Virtual renderer uses callbacks from this utility to main recycle pool and the render stack. -+ * The utility optimizes finding visible indexes by using the last visible items. However, that can be slow if scrollToOffset is explicitly called. -+ * We use binary search to optimize in most cases like while finding first visible item or initial offset. In future we'll also be using BS to speed up -+ * scroll to offset. -+ */ -+export interface Range { -+ start: number; -+ end: number; -+} -+export declare type TOnItemStatusChanged = ((all: number[], now: number[], notNow: number[]) => void); -+export default class ViewabilityTracker { -+ onVisibleRowsChanged: TOnItemStatusChanged | null; -+ onEngagedRowsChanged: TOnItemStatusChanged | null; -+ private _currentOffset; -+ private _maxOffset; -+ private _renderAheadOffset; -+ private _visibleWindow; -+ private _engagedWindow; -+ private _relevantDim; -+ private _isHorizontal; -+ private _windowBound; -+ private _visibleIndexes; -+ private _engagedIndexes; -+ private _layouts; -+ private _actualOffset; -+ constructor(renderAheadOffset: number, initialOffset: number); -+ init(): void; -+ setLayouts(layouts: Layout[], maxOffset: number): void; -+ setDimensions(dimension: Dimension, isHorizontal: boolean): void; -+ forceRefresh(): boolean; -+ forceRefreshWithOffset(offset: number): void; -+ updateOffset(offset: number, correction: number, isActual: boolean): void; -+ getLastOffset(): number; -+ getLastActualOffset(): number; -+ getEngagedIndexes(): number[]; -+ findFirstLogicallyVisibleIndex(): number; -+ updateRenderAheadOffset(renderAheadOffset: number): void; -+ getCurrentRenderAheadOffset(): number; -+ private _findFirstVisibleIndexOptimally; -+ private _fitAndUpdate; -+ private _doInitialFit; -+ private _findFirstVisibleIndexLinearly; -+ private _findFirstVisibleIndexUsingBS; -+ private _valueExtractorForBinarySearch; -+ private _fitIndexes; -+ private _checkIntersectionAndReport; -+ private _setRelevantBounds; -+ private _isItemInBounds; -+ private _isItemBoundsBeyondWindow; -+ private _itemIntersectsWindow; -+ private _itemIntersectsEngagedWindow; -+ private _itemIntersectsVisibleWindow; -+ private _updateTrackingWindows; -+ private _diffUpdateOriginalIndexesAndRaiseEvents; -+ private _diffArraysAndCallFunc; -+ private _calculateArrayDiff; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js -new file mode 100644 -index 0000000..dc8271a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js -@@ -0,0 +1,266 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var BinarySearch_1 = require("../utils/BinarySearch"); -+var ViewabilityTracker = /** @class */ (function () { -+ function ViewabilityTracker(renderAheadOffset, initialOffset) { -+ var _this = this; -+ this._layouts = []; -+ this._valueExtractorForBinarySearch = function (index) { -+ var itemRect = _this._layouts[index]; -+ _this._setRelevantBounds(itemRect, _this._relevantDim); -+ return _this._relevantDim.end; -+ }; -+ this._currentOffset = Math.max(0, initialOffset); -+ this._maxOffset = 0; -+ this._actualOffset = 0; -+ this._renderAheadOffset = renderAheadOffset; -+ this._visibleWindow = { start: 0, end: 0 }; -+ this._engagedWindow = { start: 0, end: 0 }; -+ this._isHorizontal = false; -+ this._windowBound = 0; -+ this._visibleIndexes = []; //needs to be sorted -+ this._engagedIndexes = []; //needs to be sorted -+ this.onVisibleRowsChanged = null; -+ this.onEngagedRowsChanged = null; -+ this._relevantDim = { start: 0, end: 0 }; -+ } -+ ViewabilityTracker.prototype.init = function () { -+ this._doInitialFit(this._currentOffset); -+ }; -+ ViewabilityTracker.prototype.setLayouts = function (layouts, maxOffset) { -+ this._layouts = layouts; -+ this._maxOffset = maxOffset; -+ }; -+ ViewabilityTracker.prototype.setDimensions = function (dimension, isHorizontal) { -+ this._isHorizontal = isHorizontal; -+ this._windowBound = isHorizontal ? dimension.width : dimension.height; -+ }; -+ ViewabilityTracker.prototype.forceRefresh = function () { -+ this.forceRefreshWithOffset(this._currentOffset); -+ return false; -+ }; -+ ViewabilityTracker.prototype.forceRefreshWithOffset = function (offset) { -+ this._currentOffset = -1; -+ this.updateOffset(offset, 0, false); -+ }; -+ ViewabilityTracker.prototype.updateOffset = function (offset, correction, isActual) { -+ if (isActual) { -+ this._actualOffset = offset; -+ } -+ offset = Math.min(this._maxOffset, Math.max(0, offset + correction)); -+ if (this._currentOffset !== offset) { -+ this._currentOffset = offset; -+ this._updateTrackingWindows(offset); -+ var startIndex = 0; -+ if (this._visibleIndexes.length > 0) { -+ startIndex = this._visibleIndexes[0]; -+ } -+ this._fitAndUpdate(startIndex); -+ } -+ }; -+ ViewabilityTracker.prototype.getLastOffset = function () { -+ return this._currentOffset; -+ }; -+ ViewabilityTracker.prototype.getLastActualOffset = function () { -+ return this._actualOffset; -+ }; -+ ViewabilityTracker.prototype.getEngagedIndexes = function () { -+ return this._engagedIndexes; -+ }; -+ ViewabilityTracker.prototype.findFirstLogicallyVisibleIndex = function () { -+ var relevantIndex = this._findFirstVisibleIndexUsingBS(0.001); -+ var result = relevantIndex; -+ for (var i = relevantIndex - 1; i >= 0; i--) { -+ if (this._isHorizontal) { -+ if (this._layouts[relevantIndex].x !== this._layouts[i].x) { -+ break; -+ } -+ else { -+ result = i; -+ } -+ } -+ else { -+ if (this._layouts[relevantIndex].y !== this._layouts[i].y) { -+ break; -+ } -+ else { -+ result = i; -+ } -+ } -+ } -+ return result; -+ }; -+ ViewabilityTracker.prototype.updateRenderAheadOffset = function (renderAheadOffset) { -+ this._renderAheadOffset = Math.max(0, renderAheadOffset); -+ this.forceRefreshWithOffset(this._currentOffset); -+ }; -+ ViewabilityTracker.prototype.getCurrentRenderAheadOffset = function () { -+ return this._renderAheadOffset; -+ }; -+ ViewabilityTracker.prototype._findFirstVisibleIndexOptimally = function () { -+ var firstVisibleIndex = 0; -+ //TODO: Talha calculate this value smartly -+ if (this._currentOffset > 5000) { -+ firstVisibleIndex = this._findFirstVisibleIndexUsingBS(); -+ } -+ else if (this._currentOffset > 0) { -+ firstVisibleIndex = this._findFirstVisibleIndexLinearly(); -+ } -+ return firstVisibleIndex; -+ }; -+ ViewabilityTracker.prototype._fitAndUpdate = function (startIndex) { -+ var newVisibleItems = []; -+ var newEngagedItems = []; -+ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex, true); -+ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex + 1, false); -+ this._diffUpdateOriginalIndexesAndRaiseEvents(newVisibleItems, newEngagedItems); -+ }; -+ ViewabilityTracker.prototype._doInitialFit = function (offset) { -+ offset = Math.min(this._maxOffset, Math.max(0, offset)); -+ this._updateTrackingWindows(offset); -+ var firstVisibleIndex = this._findFirstVisibleIndexOptimally(); -+ this._fitAndUpdate(firstVisibleIndex); -+ }; -+ //TODO:Talha switch to binary search and remove atleast once logic in _fitIndexes -+ ViewabilityTracker.prototype._findFirstVisibleIndexLinearly = function () { -+ var count = this._layouts.length; -+ var itemRect = null; -+ var relevantDim = { start: 0, end: 0 }; -+ for (var i = 0; i < count; i++) { -+ itemRect = this._layouts[i]; -+ this._setRelevantBounds(itemRect, relevantDim); -+ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { -+ return i; -+ } -+ } -+ return 0; -+ }; -+ ViewabilityTracker.prototype._findFirstVisibleIndexUsingBS = function (bias) { -+ if (bias === void 0) { bias = 0; } -+ var count = this._layouts.length; -+ return BinarySearch_1.default.findClosestHigherValueIndex(count, this._visibleWindow.start + bias, this._valueExtractorForBinarySearch); -+ }; -+ //TODO:Talha Optimize further in later revisions, alteast once logic can be replace with a BS lookup -+ ViewabilityTracker.prototype._fitIndexes = function (newVisibleIndexes, newEngagedIndexes, startIndex, isReverse) { -+ var count = this._layouts.length; -+ var relevantDim = { start: 0, end: 0 }; -+ var i = 0; -+ var atLeastOneLocated = false; -+ if (startIndex < count) { -+ if (!isReverse) { -+ for (i = startIndex; i < count; i++) { -+ if (this._checkIntersectionAndReport(i, false, relevantDim, newVisibleIndexes, newEngagedIndexes)) { -+ atLeastOneLocated = true; -+ } -+ else { -+ if (atLeastOneLocated) { -+ break; -+ } -+ } -+ } -+ } -+ else { -+ for (i = startIndex; i >= 0; i--) { -+ if (this._checkIntersectionAndReport(i, true, relevantDim, newVisibleIndexes, newEngagedIndexes)) { -+ atLeastOneLocated = true; -+ } -+ else { -+ if (atLeastOneLocated) { -+ break; -+ } -+ } -+ } -+ } -+ } -+ }; -+ ViewabilityTracker.prototype._checkIntersectionAndReport = function (index, insertOnTop, relevantDim, newVisibleIndexes, newEngagedIndexes) { -+ var itemRect = this._layouts[index]; -+ var isFound = false; -+ this._setRelevantBounds(itemRect, relevantDim); -+ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { -+ if (insertOnTop) { -+ newVisibleIndexes.splice(0, 0, index); -+ newEngagedIndexes.splice(0, 0, index); -+ } -+ else { -+ newVisibleIndexes.push(index); -+ newEngagedIndexes.push(index); -+ } -+ isFound = true; -+ } -+ else if (this._itemIntersectsEngagedWindow(relevantDim.start, relevantDim.end)) { -+ //TODO: This needs to be optimized -+ if (insertOnTop) { -+ newEngagedIndexes.splice(0, 0, index); -+ } -+ else { -+ newEngagedIndexes.push(index); -+ } -+ isFound = true; -+ } -+ return isFound; -+ }; -+ ViewabilityTracker.prototype._setRelevantBounds = function (itemRect, relevantDim) { -+ if (this._isHorizontal) { -+ relevantDim.end = itemRect.x + itemRect.width; -+ relevantDim.start = itemRect.x; -+ } -+ else { -+ relevantDim.end = itemRect.y + itemRect.height; -+ relevantDim.start = itemRect.y; -+ } -+ }; -+ ViewabilityTracker.prototype._isItemInBounds = function (window, itemBound) { -+ return (window.start < itemBound && window.end > itemBound); -+ }; -+ ViewabilityTracker.prototype._isItemBoundsBeyondWindow = function (window, startBound, endBound) { -+ return (window.start >= startBound && window.end <= endBound); -+ }; -+ ViewabilityTracker.prototype._itemIntersectsWindow = function (window, startBound, endBound) { -+ return this._isItemInBounds(window, startBound) || -+ this._isItemInBounds(window, endBound) || -+ this._isItemBoundsBeyondWindow(window, startBound, endBound); -+ }; -+ ViewabilityTracker.prototype._itemIntersectsEngagedWindow = function (startBound, endBound) { -+ return this._itemIntersectsWindow(this._engagedWindow, startBound, endBound); -+ }; -+ ViewabilityTracker.prototype._itemIntersectsVisibleWindow = function (startBound, endBound) { -+ return this._itemIntersectsWindow(this._visibleWindow, startBound, endBound); -+ }; -+ ViewabilityTracker.prototype._updateTrackingWindows = function (newOffset) { -+ this._engagedWindow.start = Math.max(0, newOffset - this._renderAheadOffset); -+ this._engagedWindow.end = newOffset + this._windowBound + this._renderAheadOffset; -+ this._visibleWindow.start = newOffset; -+ this._visibleWindow.end = newOffset + this._windowBound; -+ }; -+ //TODO:Talha optimize this -+ ViewabilityTracker.prototype._diffUpdateOriginalIndexesAndRaiseEvents = function (newVisibleItems, newEngagedItems) { -+ this._diffArraysAndCallFunc(newVisibleItems, this._visibleIndexes, this.onVisibleRowsChanged); -+ this._diffArraysAndCallFunc(newEngagedItems, this._engagedIndexes, this.onEngagedRowsChanged); -+ this._visibleIndexes = newVisibleItems; -+ this._engagedIndexes = newEngagedItems; -+ }; -+ ViewabilityTracker.prototype._diffArraysAndCallFunc = function (newItems, oldItems, func) { -+ if (func) { -+ var now = this._calculateArrayDiff(newItems, oldItems); -+ var notNow = this._calculateArrayDiff(oldItems, newItems); -+ if (now.length > 0 || notNow.length > 0) { -+ func(newItems.slice(), now, notNow); -+ } -+ } -+ }; -+ //TODO:Talha since arrays are sorted this can be much faster -+ ViewabilityTracker.prototype._calculateArrayDiff = function (arr1, arr2) { -+ var len = arr1.length; -+ var diffArr = []; -+ for (var i = 0; i < len; i++) { -+ if (BinarySearch_1.default.findIndexOf(arr2, arr1[i]) === -1) { -+ diffArr.push(arr1[i]); -+ } -+ } -+ return diffArr; -+ }; -+ return ViewabilityTracker; -+}()); -+exports.default = ViewabilityTracker; -+//# sourceMappingURL=ViewabilityTracker.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js.map b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js.map -new file mode 100644 -index 0000000..ba78826 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/ViewabilityTracker.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewabilityTracker.js","sourceRoot":"","sources":["../../../src/core/ViewabilityTracker.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.d.ts -new file mode 100644 -index 0000000..190e53a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.d.ts -@@ -0,0 +1,66 @@ -+import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; -+import { Point, LayoutManager } from "./layoutmanager/LayoutManager"; -+import ViewabilityTracker, { TOnItemStatusChanged } from "./ViewabilityTracker"; -+import { BaseDataProvider } from "./dependencies/DataProvider"; -+/*** -+ * Renderer which keeps track of recyclable items and the currently rendered items. Notifies list view to re render if something changes, like scroll offset -+ */ -+export interface RenderStackItem { -+ dataIndex?: number; -+} -+export interface StableIdMapItem { -+ key: string; -+ type: string | number; -+} -+export interface RenderStack { -+ [key: string]: RenderStackItem; -+} -+export interface RenderStackParams { -+ isHorizontal?: boolean; -+ itemCount: number; -+ initialOffset?: number; -+ initialRenderIndex?: number; -+ renderAheadOffset?: number; -+} -+export declare type StableIdProvider = (index: number) => string; -+export default class VirtualRenderer { -+ private onVisibleItemsChanged; -+ private _scrollOnNextUpdate; -+ private _stableIdToRenderKeyMap; -+ private _engagedIndexes; -+ private _renderStack; -+ private _renderStackChanged; -+ private _fetchStableId; -+ private _isRecyclingEnabled; -+ private _isViewTrackerRunning; -+ private _markDirty; -+ private _startKey; -+ private _layoutProvider; -+ private _recyclePool; -+ private _params; -+ private _layoutManager; -+ private _viewabilityTracker; -+ private _dimensions; -+ constructor(renderStackChanged: (renderStack: RenderStack) => void, scrollOnNextUpdate: (point: Point) => void, fetchStableId: StableIdProvider, isRecyclingEnabled: boolean); -+ getLayoutDimension(): Dimension; -+ updateOffset(offsetX: number, offsetY: number, correction: number, isActual: boolean): void; -+ attachVisibleItemsListener(callback: TOnItemStatusChanged): void; -+ removeVisibleItemsListener(): void; -+ getLayoutManager(): LayoutManager | null; -+ setParamsAndDimensions(params: RenderStackParams, dim: Dimension): void; -+ setLayoutManager(layoutManager: LayoutManager): void; -+ setLayoutProvider(layoutProvider: BaseLayoutProvider): void; -+ getViewabilityTracker(): ViewabilityTracker | null; -+ refreshWithAnchor(): void; -+ refresh(): void; -+ getInitialOffset(): Point; -+ init(): void; -+ startViewabilityTracker(): void; -+ syncAndGetKey(index: number, overrideStableIdProvider?: StableIdProvider, newRenderStack?: RenderStack): string; -+ handleDataSetChange(newDataProvider: BaseDataProvider, shouldOptimizeForAnimations?: boolean): void; -+ private _getCollisionAvoidingKey; -+ private _prepareViewabilityTracker; -+ private _onVisibleItemsChanged; -+ private _onEngagedItemsChanged; -+ private _updateRenderStack; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js -new file mode 100644 -index 0000000..921ccbc ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js -@@ -0,0 +1,321 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecycleItemPool_1 = require("../utils/RecycleItemPool"); -+var CustomError_1 = require("./exceptions/CustomError"); -+var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); -+var ViewabilityTracker_1 = require("./ViewabilityTracker"); -+var ts_object_utils_1 = require("ts-object-utils"); -+var TSCast_1 = require("../utils/TSCast"); -+var VirtualRenderer = /** @class */ (function () { -+ function VirtualRenderer(renderStackChanged, scrollOnNextUpdate, fetchStableId, isRecyclingEnabled) { -+ var _this = this; -+ this._layoutProvider = TSCast_1.default.cast(null); //TSI -+ this._recyclePool = TSCast_1.default.cast(null); //TSI -+ this._layoutManager = null; -+ this._viewabilityTracker = null; -+ this._onVisibleItemsChanged = function (all, now, notNow) { -+ if (_this.onVisibleItemsChanged) { -+ _this.onVisibleItemsChanged(all, now, notNow); -+ } -+ }; -+ this._onEngagedItemsChanged = function (all, now, notNow) { -+ var count = notNow.length; -+ var resolvedKey; -+ var disengagedIndex = 0; -+ if (_this._isRecyclingEnabled) { -+ for (var i = 0; i < count; i++) { -+ disengagedIndex = notNow[i]; -+ delete _this._engagedIndexes[disengagedIndex]; -+ if (_this._params && disengagedIndex < _this._params.itemCount) { -+ //All the items which are now not visible can go to the recycle pool, the pool only needs to maintain keys since -+ //react can link a view to a key automatically -+ resolvedKey = _this._stableIdToRenderKeyMap[_this._fetchStableId(disengagedIndex)]; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(resolvedKey)) { -+ _this._recyclePool.putRecycledObject(_this._layoutProvider.getLayoutTypeForIndex(disengagedIndex), resolvedKey.key); -+ } -+ } -+ } -+ } -+ if (_this._updateRenderStack(now)) { -+ //Ask Recycler View to update itself -+ _this._renderStackChanged(_this._renderStack); -+ } -+ }; -+ //Keeps track of items that need to be rendered in the next render cycle -+ this._renderStack = {}; -+ this._fetchStableId = fetchStableId; -+ //Keeps track of keys of all the currently rendered indexes, can eventually replace renderStack as well if no new use cases come up -+ this._stableIdToRenderKeyMap = {}; -+ this._engagedIndexes = {}; -+ this._renderStackChanged = renderStackChanged; -+ this._scrollOnNextUpdate = scrollOnNextUpdate; -+ this._dimensions = null; -+ this._params = null; -+ this._isRecyclingEnabled = isRecyclingEnabled; -+ this._isViewTrackerRunning = false; -+ this._markDirty = false; -+ //Would be surprised if someone exceeds this -+ this._startKey = 0; -+ this.onVisibleItemsChanged = null; -+ } -+ VirtualRenderer.prototype.getLayoutDimension = function () { -+ if (this._layoutManager) { -+ return this._layoutManager.getContentDimension(); -+ } -+ return { height: 0, width: 0 }; -+ }; -+ VirtualRenderer.prototype.updateOffset = function (offsetX, offsetY, correction, isActual) { -+ if (this._viewabilityTracker) { -+ if (!this._isViewTrackerRunning) { -+ this.startViewabilityTracker(); -+ } -+ if (this._params && this._params.isHorizontal) { -+ this._viewabilityTracker.updateOffset(offsetX, correction, isActual); -+ } -+ else { -+ this._viewabilityTracker.updateOffset(offsetY, correction, isActual); -+ } -+ } -+ }; -+ VirtualRenderer.prototype.attachVisibleItemsListener = function (callback) { -+ this.onVisibleItemsChanged = callback; -+ }; -+ VirtualRenderer.prototype.removeVisibleItemsListener = function () { -+ this.onVisibleItemsChanged = null; -+ if (this._viewabilityTracker) { -+ this._viewabilityTracker.onVisibleRowsChanged = null; -+ } -+ }; -+ VirtualRenderer.prototype.getLayoutManager = function () { -+ return this._layoutManager; -+ }; -+ VirtualRenderer.prototype.setParamsAndDimensions = function (params, dim) { -+ this._params = params; -+ this._dimensions = dim; -+ }; -+ VirtualRenderer.prototype.setLayoutManager = function (layoutManager) { -+ this._layoutManager = layoutManager; -+ if (this._params) { -+ this._layoutManager.relayoutFromIndex(0, this._params.itemCount); -+ } -+ }; -+ VirtualRenderer.prototype.setLayoutProvider = function (layoutProvider) { -+ this._layoutProvider = layoutProvider; -+ }; -+ VirtualRenderer.prototype.getViewabilityTracker = function () { -+ return this._viewabilityTracker; -+ }; -+ VirtualRenderer.prototype.refreshWithAnchor = function () { -+ if (this._viewabilityTracker) { -+ var firstVisibleIndex = this._viewabilityTracker.findFirstLogicallyVisibleIndex(); -+ this._prepareViewabilityTracker(); -+ var offset = 0; -+ if (this._layoutManager && this._params) { -+ var point = this._layoutManager.getOffsetForIndex(firstVisibleIndex); -+ this._scrollOnNextUpdate(point); -+ offset = this._params.isHorizontal ? point.x : point.y; -+ } -+ this._viewabilityTracker.forceRefreshWithOffset(offset); -+ } -+ }; -+ VirtualRenderer.prototype.refresh = function () { -+ if (this._viewabilityTracker) { -+ this._prepareViewabilityTracker(); -+ if (this._viewabilityTracker.forceRefresh()) { -+ if (this._params && this._params.isHorizontal) { -+ this._scrollOnNextUpdate({ x: this._viewabilityTracker.getLastActualOffset(), y: 0 }); -+ } -+ else { -+ this._scrollOnNextUpdate({ x: 0, y: this._viewabilityTracker.getLastActualOffset() }); -+ } -+ } -+ } -+ }; -+ VirtualRenderer.prototype.getInitialOffset = function () { -+ var offset = { x: 0, y: 0 }; -+ if (this._params) { -+ var initialRenderIndex = ts_object_utils_1.Default.value(this._params.initialRenderIndex, 0); -+ if (initialRenderIndex > 0 && this._layoutManager) { -+ offset = this._layoutManager.getOffsetForIndex(initialRenderIndex); -+ this._params.initialOffset = this._params.isHorizontal ? offset.x : offset.y; -+ } -+ else { -+ if (this._params.isHorizontal) { -+ offset.x = ts_object_utils_1.Default.value(this._params.initialOffset, 0); -+ offset.y = 0; -+ } -+ else { -+ offset.y = ts_object_utils_1.Default.value(this._params.initialOffset, 0); -+ offset.x = 0; -+ } -+ } -+ } -+ return offset; -+ }; -+ VirtualRenderer.prototype.init = function () { -+ this.getInitialOffset(); -+ this._recyclePool = new RecycleItemPool_1.default(); -+ if (this._params) { -+ this._viewabilityTracker = new ViewabilityTracker_1.default(ts_object_utils_1.Default.value(this._params.renderAheadOffset, 0), ts_object_utils_1.Default.value(this._params.initialOffset, 0)); -+ } -+ else { -+ this._viewabilityTracker = new ViewabilityTracker_1.default(0, 0); -+ } -+ this._prepareViewabilityTracker(); -+ }; -+ VirtualRenderer.prototype.startViewabilityTracker = function () { -+ if (this._viewabilityTracker) { -+ this._isViewTrackerRunning = true; -+ this._viewabilityTracker.init(); -+ } -+ }; -+ VirtualRenderer.prototype.syncAndGetKey = function (index, overrideStableIdProvider, newRenderStack) { -+ var getStableId = overrideStableIdProvider ? overrideStableIdProvider : this._fetchStableId; -+ var renderStack = newRenderStack ? newRenderStack : this._renderStack; -+ var stableIdItem = this._stableIdToRenderKeyMap[getStableId(index)]; -+ var key = stableIdItem ? stableIdItem.key : undefined; -+ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { -+ var type = this._layoutProvider.getLayoutTypeForIndex(index); -+ key = this._recyclePool.getRecycledObject(type); -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { -+ var itemMeta = renderStack[key]; -+ if (itemMeta) { -+ var oldIndex = itemMeta.dataIndex; -+ itemMeta.dataIndex = index; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(oldIndex) && oldIndex !== index) { -+ delete this._stableIdToRenderKeyMap[getStableId(oldIndex)]; -+ } -+ } -+ else { -+ renderStack[key] = { dataIndex: index }; -+ } -+ } -+ else { -+ key = getStableId(index); -+ if (renderStack[key]) { -+ //Probable collision, warn and avoid -+ //TODO: Disabled incorrectly triggering in some cases -+ //console.warn("Possible stableId collision @", index); //tslint:disable-line -+ key = this._getCollisionAvoidingKey(); -+ } -+ renderStack[key] = { dataIndex: index }; -+ } -+ this._markDirty = true; -+ this._stableIdToRenderKeyMap[getStableId(index)] = { key: key, type: type }; -+ } -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { -+ this._recyclePool.removeFromPool(key); -+ } -+ var stackItem = renderStack[key]; -+ if (stackItem && stackItem.dataIndex !== index) { -+ //Probable collision, warn -+ console.warn("Possible stableId collision @", index); //tslint:disable-line -+ } -+ return key; -+ }; -+ //Further optimize in later revision, pretty fast for now considering this is a low frequency event -+ VirtualRenderer.prototype.handleDataSetChange = function (newDataProvider, shouldOptimizeForAnimations) { -+ var getStableId = newDataProvider.getStableId; -+ var maxIndex = newDataProvider.getSize() - 1; -+ var activeStableIds = {}; -+ var newRenderStack = {}; -+ //Compute active stable ids and stale active keys and resync render stack -+ for (var key in this._renderStack) { -+ if (this._renderStack.hasOwnProperty(key)) { -+ var index = this._renderStack[key].dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { -+ if (index <= maxIndex) { -+ var stableId = getStableId(index); -+ activeStableIds[stableId] = 1; -+ } -+ } -+ } -+ } -+ //Clean stable id to key map -+ var oldActiveStableIds = Object.keys(this._stableIdToRenderKeyMap); -+ var oldActiveStableIdsCount = oldActiveStableIds.length; -+ for (var i = 0; i < oldActiveStableIdsCount; i++) { -+ var key = oldActiveStableIds[i]; -+ if (!activeStableIds[key]) { -+ if (!shouldOptimizeForAnimations && this._isRecyclingEnabled) { -+ var stableIdItem = this._stableIdToRenderKeyMap[key]; -+ if (stableIdItem) { -+ this._recyclePool.putRecycledObject(stableIdItem.type, stableIdItem.key); -+ } -+ } -+ delete this._stableIdToRenderKeyMap[key]; -+ } -+ } -+ for (var key in this._renderStack) { -+ if (this._renderStack.hasOwnProperty(key)) { -+ var index = this._renderStack[key].dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { -+ if (index <= maxIndex) { -+ var newKey = this.syncAndGetKey(index, getStableId, newRenderStack); -+ var newStackItem = newRenderStack[newKey]; -+ if (!newStackItem) { -+ newRenderStack[newKey] = { dataIndex: index }; -+ } -+ else if (newStackItem.dataIndex !== index) { -+ var cllKey = this._getCollisionAvoidingKey(); -+ newRenderStack[cllKey] = { dataIndex: index }; -+ this._stableIdToRenderKeyMap[getStableId(index)] = { -+ key: cllKey, type: this._layoutProvider.getLayoutTypeForIndex(index), -+ }; -+ } -+ } -+ } -+ delete this._renderStack[key]; -+ } -+ } -+ Object.assign(this._renderStack, newRenderStack); -+ for (var key in this._renderStack) { -+ if (this._renderStack.hasOwnProperty(key)) { -+ var index = this._renderStack[key].dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index) && ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { -+ var type = this._layoutProvider.getLayoutTypeForIndex(index); -+ this._recyclePool.putRecycledObject(type, key); -+ } -+ } -+ } -+ }; -+ VirtualRenderer.prototype._getCollisionAvoidingKey = function () { -+ return "#" + this._startKey++ + "_rlv_c"; -+ }; -+ VirtualRenderer.prototype._prepareViewabilityTracker = function () { -+ if (this._viewabilityTracker && this._layoutManager && this._dimensions && this._params) { -+ this._viewabilityTracker.onEngagedRowsChanged = this._onEngagedItemsChanged; -+ if (this.onVisibleItemsChanged) { -+ this._viewabilityTracker.onVisibleRowsChanged = this._onVisibleItemsChanged; -+ } -+ this._viewabilityTracker.setLayouts(this._layoutManager.getLayouts(), this._params.isHorizontal ? -+ this._layoutManager.getContentDimension().width : -+ this._layoutManager.getContentDimension().height); -+ this._viewabilityTracker.setDimensions({ -+ height: this._dimensions.height, -+ width: this._dimensions.width, -+ }, ts_object_utils_1.Default.value(this._params.isHorizontal, false)); -+ } -+ else { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.initializationException); -+ } -+ }; -+ //Updates render stack and reports whether anything has changed -+ VirtualRenderer.prototype._updateRenderStack = function (itemIndexes) { -+ this._markDirty = false; -+ var count = itemIndexes.length; -+ var index = 0; -+ var hasRenderStackChanged = false; -+ for (var i = 0; i < count; i++) { -+ index = itemIndexes[i]; -+ this._engagedIndexes[index] = 1; -+ this.syncAndGetKey(index); -+ hasRenderStackChanged = this._markDirty; -+ } -+ this._markDirty = false; -+ return hasRenderStackChanged; -+ }; -+ return VirtualRenderer; -+}()); -+exports.default = VirtualRenderer; -+//# sourceMappingURL=VirtualRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js.map -new file mode 100644 -index 0000000..30876cc ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/VirtualRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"VirtualRenderer.js","sourceRoot":"","sources":["../../../src/core/VirtualRenderer.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.d.ts -new file mode 100644 -index 0000000..977bb6a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.d.ts -@@ -0,0 +1,3 @@ -+export declare const Constants: { -+ [key: string]: string; -+}; -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js -new file mode 100644 -index 0000000..c3323a1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js -@@ -0,0 +1,7 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.Constants = { -+ CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX: "_offset", -+ CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX: "_layouts", -+}; -+//# sourceMappingURL=Constants.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js.map b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js.map -new file mode 100644 -index 0000000..e0d93e2 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Constants.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../../../src/core/constants/Constants.ts"],"names":[],"mappings":";;AAAa,QAAA,SAAS,GAA4B;IAC9C,kCAAkC,EAAG,SAAS;IAC9C,kCAAkC,EAAE,UAAU;CACjD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.d.ts -new file mode 100644 -index 0000000..d211558 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.d.ts -@@ -0,0 +1,3 @@ -+export declare const Messages: { -+ [key: string]: string; -+}; -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js -new file mode 100644 -index 0000000..51baf1f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js -@@ -0,0 +1,10 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.Messages = { -+ ERROR_LISTVIEW_VALIDATION: "missing datasource or layout provider, cannot proceed without it", -+ WARN_SCROLL_TO_INDEX: "scrollTo was called before RecyclerListView was measured, please wait for the mount to finish", -+ WARN_NO_DATA: "You have mounted RecyclerListView with an empty data provider (Size in 0). Please mount only if there is atleast one item " + -+ "to ensure optimal performance and to avoid unexpected behavior", -+ VISIBLE_INDEXES_CHANGED_DEPRECATED: "onVisibleIndexesChanged deprecated. Please use onVisibleIndicesChanged instead.", -+}; -+//# sourceMappingURL=Messages.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js.map b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js.map -new file mode 100644 -index 0000000..9695650 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/constants/Messages.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../../src/core/constants/Messages.ts"],"names":[],"mappings":";;AAAa,QAAA,QAAQ,GAA4B;IAC7C,yBAAyB,EAAG,kEAAkE;IAC9F,oBAAoB,EAAE,+FAA+F;IACrH,YAAY,EAAE,4HAA4H;QAC5H,gEAAgE;IAC9E,kCAAkC,EAAE,iFAAiF;CACxH,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.d.ts -new file mode 100644 -index 0000000..98abef9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.d.ts -@@ -0,0 +1,13 @@ -+/*** -+ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, -+ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you -+ * can instantly jump to any location. -+ * -+ * Use this interface and implement the given methods to preserve context. -+ */ -+export default abstract class ContextProvider { -+ abstract getUniqueKey(): string; -+ abstract save(key: string, value: string | number): void; -+ abstract get(key: string): string | number; -+ abstract remove(key: string): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js -new file mode 100644 -index 0000000..724fa5a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js -@@ -0,0 +1,16 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+/*** -+ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, -+ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you -+ * can instantly jump to any location. -+ * -+ * Use this interface and implement the given methods to preserve context. -+ */ -+var ContextProvider = /** @class */ (function () { -+ function ContextProvider() { -+ } -+ return ContextProvider; -+}()); -+exports.default = ContextProvider; -+//# sourceMappingURL=ContextProvider.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js.map b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js.map -new file mode 100644 -index 0000000..27659b2 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/ContextProvider.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ContextProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/ContextProvider.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH;IAAA;IAYA,CAAC;IAAD,sBAAC;AAAD,CAAC,AAZD,IAYC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.d.ts -new file mode 100644 -index 0000000..0844963 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.d.ts -@@ -0,0 +1,25 @@ -+/*** -+ * You can create a new instance or inherit and override default methods -+ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. -+ */ -+export declare abstract class BaseDataProvider { -+ rowHasChanged: (r1: any, r2: any) => boolean; -+ getStableId: (index: number) => string; -+ private _firstIndexToProcess; -+ private _size; -+ private _data; -+ private _hasStableIds; -+ private _requiresDataChangeHandling; -+ constructor(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string); -+ abstract newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string): BaseDataProvider; -+ getDataForIndex(index: number): any; -+ getAllData(): any[]; -+ getSize(): number; -+ hasStableIds(): boolean; -+ requiresDataChangeHandling(): boolean; -+ getFirstIndexToProcessInternal(): number; -+ cloneWithRows(newData: any[], firstModifiedIndex?: number): DataProvider; -+} -+export default class DataProvider extends BaseDataProvider { -+ newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: ((index: number) => string) | undefined): BaseDataProvider; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js -new file mode 100644 -index 0000000..ee37484 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js -@@ -0,0 +1,94 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ts_object_utils_1 = require("ts-object-utils"); -+/*** -+ * You can create a new instance or inherit and override default methods -+ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. -+ */ -+var BaseDataProvider = /** @class */ (function () { -+ function BaseDataProvider(rowHasChanged, getStableId) { -+ this._firstIndexToProcess = 0; -+ this._size = 0; -+ this._data = []; -+ this._hasStableIds = false; -+ this._requiresDataChangeHandling = false; -+ this.rowHasChanged = rowHasChanged; -+ if (getStableId) { -+ this.getStableId = getStableId; -+ this._hasStableIds = true; -+ } -+ else { -+ this.getStableId = function (index) { return index.toString(); }; -+ } -+ } -+ BaseDataProvider.prototype.getDataForIndex = function (index) { -+ return this._data[index]; -+ }; -+ BaseDataProvider.prototype.getAllData = function () { -+ return this._data; -+ }; -+ BaseDataProvider.prototype.getSize = function () { -+ return this._size; -+ }; -+ BaseDataProvider.prototype.hasStableIds = function () { -+ return this._hasStableIds; -+ }; -+ BaseDataProvider.prototype.requiresDataChangeHandling = function () { -+ return this._requiresDataChangeHandling; -+ }; -+ BaseDataProvider.prototype.getFirstIndexToProcessInternal = function () { -+ return this._firstIndexToProcess; -+ }; -+ //No need to override this one -+ //If you already know the first row where rowHasChanged will be false pass it upfront to avoid loop -+ BaseDataProvider.prototype.cloneWithRows = function (newData, firstModifiedIndex) { -+ var dp = this.newInstance(this.rowHasChanged, this.getStableId); -+ var newSize = newData.length; -+ var iterCount = Math.min(this._size, newSize); -+ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(firstModifiedIndex)) { -+ var i = 0; -+ for (i = 0; i < iterCount; i++) { -+ if (this.rowHasChanged(this._data[i], newData[i])) { -+ break; -+ } -+ } -+ dp._firstIndexToProcess = i; -+ } -+ else { -+ dp._firstIndexToProcess = Math.max(Math.min(firstModifiedIndex, this._data.length), 0); -+ } -+ if (dp._firstIndexToProcess !== this._data.length) { -+ dp._requiresDataChangeHandling = true; -+ } -+ dp._data = newData; -+ dp._size = newSize; -+ return dp; -+ }; -+ return BaseDataProvider; -+}()); -+exports.BaseDataProvider = BaseDataProvider; -+var DataProvider = /** @class */ (function (_super) { -+ __extends(DataProvider, _super); -+ function DataProvider() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ DataProvider.prototype.newInstance = function (rowHasChanged, getStableId) { -+ return new DataProvider(rowHasChanged, getStableId); -+ }; -+ return DataProvider; -+}(BaseDataProvider)); -+exports.default = DataProvider; -+//# sourceMappingURL=DataProvider.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js.map b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js.map -new file mode 100644 -index 0000000..fd7dedf ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/DataProvider.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DataProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/DataProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mDAA6C;AAE7C;;;GAGG;AACH;IAWI,0BAAY,aAA4C,EAAE,WAAuC;QANzF,yBAAoB,GAAW,CAAC,CAAC;QACjC,UAAK,GAAW,CAAC,CAAC;QAClB,UAAK,GAAU,EAAE,CAAC;QAClB,kBAAa,GAAG,KAAK,CAAC;QACtB,gCAA2B,GAAG,KAAK,CAAC;QAGxC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,WAAW,EAAE;YACb,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC7B;aAAM;YACH,IAAI,CAAC,WAAW,GAAG,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,QAAQ,EAAE,EAAhB,CAAgB,CAAC;SAClD;IACL,CAAC;IAIM,0CAAe,GAAtB,UAAuB,KAAa;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAEM,qCAAU,GAAjB;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,kCAAO,GAAd;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,uCAAY,GAAnB;QACI,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEM,qDAA0B,GAAjC;QACI,OAAO,IAAI,CAAC,2BAA2B,CAAC;IAC5C,CAAC;IAEM,yDAA8B,GAArC;QACI,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACrC,CAAC;IAED,8BAA8B;IAC9B,mGAAmG;IAC5F,wCAAa,GAApB,UAAqB,OAAc,EAAE,kBAA2B;QAC5D,IAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClE,IAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/B,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,4BAAU,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE;YAClD,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;gBAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC/C,MAAM;iBACT;aACJ;YACD,EAAE,CAAC,oBAAoB,GAAG,CAAC,CAAC;SAC/B;aAAM;YACH,EAAE,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1F;QACD,IAAI,EAAE,CAAC,oBAAoB,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAC/C,EAAE,CAAC,2BAA2B,GAAG,IAAI,CAAC;SACzC;QACD,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,OAAO,EAAE,CAAC;IACd,CAAC;IACL,uBAAC;AAAD,CAAC,AAvED,IAuEC;AAvEqB,4CAAgB;AAyEtC;IAA0C,gCAAgB;IAA1D;;IAIA,CAAC;IAHU,kCAAW,GAAlB,UAAmB,aAA4C,EAAE,WAAqD;QAClH,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC;IACL,mBAAC;AAAD,CAAC,AAJD,CAA0C,gBAAgB,GAIzD"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.d.ts -new file mode 100644 -index 0000000..e832379 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.d.ts -@@ -0,0 +1,35 @@ -+import { Layout, LayoutManager } from "../layoutmanager/LayoutManager"; -+/** -+ * Created by talha.naqvi on 05/04/17. -+ * You can create a new instance or inherit and override default methods -+ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider -+ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all -+ * data upfront will only limit possibilites in the future. -+ * -+ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates -+ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. -+ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. -+ * -+ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. -+ */ -+export declare abstract class BaseLayoutProvider { -+ shouldRefreshWithAnchoring: boolean; -+ abstract newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; -+ abstract getLayoutTypeForIndex(index: number): string | number; -+ abstract checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; -+} -+export declare class LayoutProvider extends BaseLayoutProvider { -+ private _getLayoutTypeForIndex; -+ private _setLayoutForType; -+ private _tempDim; -+ private _lastLayoutManager; -+ constructor(getLayoutTypeForIndex: (index: number) => string | number, setLayoutForType: (type: string | number, dim: Dimension, index: number) => void); -+ newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; -+ getLayoutTypeForIndex(index: number): string | number; -+ setComputedLayout(type: string | number, dimension: Dimension, index: number): void; -+ checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; -+} -+export interface Dimension { -+ height: number; -+ width: number; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js -new file mode 100644 -index 0000000..4f5dbdf ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js -@@ -0,0 +1,72 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var LayoutManager_1 = require("../layoutmanager/LayoutManager"); -+/** -+ * Created by talha.naqvi on 05/04/17. -+ * You can create a new instance or inherit and override default methods -+ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider -+ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all -+ * data upfront will only limit possibilites in the future. -+ * -+ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates -+ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. -+ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. -+ * -+ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. -+ */ -+var BaseLayoutProvider = /** @class */ (function () { -+ function BaseLayoutProvider() { -+ //Unset if your new layout provider doesn't require firstVisibleIndex preservation on application -+ this.shouldRefreshWithAnchoring = true; -+ } -+ return BaseLayoutProvider; -+}()); -+exports.BaseLayoutProvider = BaseLayoutProvider; -+var LayoutProvider = /** @class */ (function (_super) { -+ __extends(LayoutProvider, _super); -+ function LayoutProvider(getLayoutTypeForIndex, setLayoutForType) { -+ var _this = _super.call(this) || this; -+ _this._getLayoutTypeForIndex = getLayoutTypeForIndex; -+ _this._setLayoutForType = setLayoutForType; -+ _this._tempDim = { height: 0, width: 0 }; -+ return _this; -+ } -+ LayoutProvider.prototype.newLayoutManager = function (renderWindowSize, isHorizontal, cachedLayouts) { -+ this._lastLayoutManager = new LayoutManager_1.WrapGridLayoutManager(this, renderWindowSize, isHorizontal, cachedLayouts); -+ return this._lastLayoutManager; -+ }; -+ //Provide a type for index, something which identifies the template of view about to load -+ LayoutProvider.prototype.getLayoutTypeForIndex = function (index) { -+ return this._getLayoutTypeForIndex(index); -+ }; -+ //Given a type and dimension set the dimension values on given dimension object -+ //You can also get index here if you add an extra argument but we don't recommend using it. -+ LayoutProvider.prototype.setComputedLayout = function (type, dimension, index) { -+ return this._setLayoutForType(type, dimension, index); -+ }; -+ LayoutProvider.prototype.checkDimensionDiscrepancy = function (dimension, type, index) { -+ var dimension1 = dimension; -+ this.setComputedLayout(type, this._tempDim, index); -+ var dimension2 = this._tempDim; -+ if (this._lastLayoutManager) { -+ this._lastLayoutManager.setMaxBounds(dimension2); -+ } -+ return dimension1.height !== dimension2.height || dimension1.width !== dimension2.width; -+ }; -+ return LayoutProvider; -+}(BaseLayoutProvider)); -+exports.LayoutProvider = LayoutProvider; -+//# sourceMappingURL=LayoutProvider.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js.map b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js.map -new file mode 100644 -index 0000000..d2bed0e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/dependencies/LayoutProvider.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"LayoutProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/LayoutProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gEAA8F;AAE9F;;;;;;;;;;;;GAYG;AAEH;IAAA;QACI,iGAAiG;QAC1F,+BAA0B,GAAY,IAAI,CAAC;IAYtD,CAAC;IAAD,yBAAC;AAAD,CAAC,AAdD,IAcC;AAdqB,gDAAkB;AAgBxC;IAAoC,kCAAkB;IAOlD,wBAAY,qBAAyD,EAAE,gBAAgF;QAAvJ,YACI,iBAAO,SAIV;QAHG,KAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;QACpD,KAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QAC1C,KAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;IAC5C,CAAC;IAEM,yCAAgB,GAAvB,UAAwB,gBAA2B,EAAE,YAAsB,EAAE,aAAwB;QACjG,IAAI,CAAC,kBAAkB,GAAG,IAAI,qCAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACzG,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED,yFAAyF;IAClF,8CAAqB,GAA5B,UAA6B,KAAa;QACtC,OAAO,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,+EAA+E;IAC/E,2FAA2F;IACpF,0CAAiB,GAAxB,UAAyB,IAAqB,EAAE,SAAoB,EAAE,KAAa;QAC/E,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1D,CAAC;IAEM,kDAAyB,GAAhC,UAAiC,SAAoB,EAAE,IAAqB,EAAE,KAAa;QACvF,IAAM,UAAU,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,IAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;SACpD;QACD,OAAO,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC;IAC5F,CAAC;IACL,qBAAC;AAAD,CAAC,AAvCD,CAAoC,kBAAkB,GAuCrD;AAvCY,wCAAc"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.d.ts -new file mode 100644 -index 0000000..d6e7c73 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.d.ts -@@ -0,0 +1,4 @@ -+import ResizeDebugHandler from "./resize/ResizeDebugHandler"; -+export interface DebugHandlers { -+ resizeDebugHandler?: ResizeDebugHandler; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js -new file mode 100644 -index 0000000..fe8175c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js -@@ -0,0 +1,3 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+//# sourceMappingURL=DebugHandlers.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js.map b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js.map -new file mode 100644 -index 0000000..332282c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/DebugHandlers.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DebugHandlers.js","sourceRoot":"","sources":["../../../../../src/core/devutils/debughandlers/DebugHandlers.ts"],"names":[],"mappings":""} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts -new file mode 100644 -index 0000000..e32b3c6 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts -@@ -0,0 +1,8 @@ -+import { Dimension } from "../../../.."; -+import ResizeDebugHandler from "./ResizeDebugHandler"; -+export default class DefaultResizeDebugHandler implements ResizeDebugHandler { -+ private readonly relaxation; -+ private readonly onRelaxationViolation; -+ constructor(relaxation: Dimension, onRelaxationViolation: (expectedDim: Dimension, actualDim: Dimension, index: number) => void); -+ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js -new file mode 100644 -index 0000000..258b921 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js -@@ -0,0 +1,25 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var DefaultResizeDebugHandler = /** @class */ (function () { -+ // Relaxation is the Dimension object where it accepts the relaxation to allow for each dimension. -+ // Any of the dimension (height or width) whose value for relaxation is less than 0 would be ignored. -+ function DefaultResizeDebugHandler(relaxation, onRelaxationViolation) { -+ this.relaxation = relaxation; -+ this.onRelaxationViolation = onRelaxationViolation; -+ } -+ DefaultResizeDebugHandler.prototype.resizeDebug = function (oldDim, newDim, index) { -+ var isViolated = false; -+ if (this.relaxation.height >= 0 && Math.abs(newDim.height - oldDim.height) >= this.relaxation.height) { -+ isViolated = true; -+ } -+ if (!isViolated && this.relaxation.width >= 0 && Math.abs(newDim.width - oldDim.width) >= this.relaxation.width) { -+ isViolated = true; -+ } -+ if (isViolated) { -+ this.onRelaxationViolation(oldDim, newDim, index); -+ } -+ }; -+ return DefaultResizeDebugHandler; -+}()); -+exports.default = DefaultResizeDebugHandler; -+//# sourceMappingURL=DefaultResizeDebugHandler.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map -new file mode 100644 -index 0000000..ccbb28c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.ts"],"names":[],"mappings":";;AAGA;IAII,kGAAkG;IAClG,qGAAqG;IACrG,mCAAmB,UAAqB,EAAE,qBAA4F;QAClI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACvD,CAAC;IAEM,+CAAW,GAAlB,UAAmB,MAAiB,EAAE,MAAiB,EAAE,KAAa;QAClE,IAAI,UAAU,GAAY,KAAK,CAAC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClG,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;YAC7G,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,UAAU,EAAE;YACZ,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;SACrD;IACL,CAAC;IACL,gCAAC;AAAD,CAAC,AAzBD,IAyBC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts -new file mode 100644 -index 0000000..654f89d ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts -@@ -0,0 +1,4 @@ -+import { Dimension } from "../../../.."; -+export default interface ResizeDebugHandler { -+ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js -new file mode 100644 -index 0000000..697bdb8 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js -@@ -0,0 +1,3 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+//# sourceMappingURL=ResizeDebugHandler.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map -new file mode 100644 -index 0000000..2122fce ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/ResizeDebugHandler.ts"],"names":[],"mappings":""} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.d.ts -new file mode 100644 -index 0000000..67ab42e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.d.ts -@@ -0,0 +1,7 @@ -+export default class CustomError extends Error { -+ constructor(exception: Exception); -+} -+export interface Exception { -+ type: string; -+ message: string; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js -new file mode 100644 -index 0000000..6a6b17c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js -@@ -0,0 +1,26 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var CustomError = /** @class */ (function (_super) { -+ __extends(CustomError, _super); -+ function CustomError(exception) { -+ var _this = _super.call(this, exception.message) || this; -+ _this.name = exception.type; -+ return _this; -+ } -+ return CustomError; -+}(Error)); -+exports.default = CustomError; -+//# sourceMappingURL=CustomError.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js.map b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js.map -new file mode 100644 -index 0000000..bbff8bd ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/CustomError.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"CustomError.js","sourceRoot":"","sources":["../../../../src/core/exceptions/CustomError.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;IAAyC,+BAAK;IAC1C,qBAAY,SAAoB;QAAhC,YACI,kBAAM,SAAS,CAAC,OAAO,CAAC,SAE3B;QADG,KAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;;IAC/B,CAAC;IACL,kBAAC;AAAD,CAAC,AALD,CAAyC,KAAK,GAK7C"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.d.ts -new file mode 100644 -index 0000000..7db4997 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.d.ts -@@ -0,0 +1,5 @@ -+import { Exception } from "./CustomError"; -+declare const RecyclerListViewExceptions: { -+ [key: string]: Exception; -+}; -+export default RecyclerListViewExceptions; -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js -new file mode 100644 -index 0000000..26413ac ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js -@@ -0,0 +1,48 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecyclerListViewExceptions = { -+ initializationException: { -+ message: "Parameters required for initializing the module are missing", -+ type: "Initialization essentials missing", -+ }, -+ itemBoundsException: { -+ message: "Dimensions cannot be undefined or null, check if LayoutProvider returns irregular values", -+ type: "ItemBoundsException", -+ }, -+ itemTypeNullException: { -+ message: "RecyclerListView items always require a type, check if LayoutProvider returns irregular values", -+ type: "ItemTypeNullException", -+ }, -+ layoutException: { -+ message: "RecyclerListView needs to have a bounded size. Currently height or, width is 0." + -+ "Consider adding style={{flex:1}} or, fixed dimensions", -+ type: "LayoutException", -+ }, -+ platformNotDetectedException: { -+ message: "Unable to detect the running platform, if you're trying to run recyclerlistview " + -+ "in browser make sure process.env.RLV_ENV is set to browser in webpack config", -+ type: "PlatformNotDetectedException", -+ }, -+ unresolvedDependenciesException: { -+ message: "missing datasource or layout provider, cannot proceed without it", -+ type: "UnresolvedDependenciesException", -+ }, -+ refNotAsFunctionException: { -+ message: "When using StickyContainer, RecyclerListView needs to use ref as a function and not as a string.", -+ type: "RefNotAsFunctionException", -+ }, -+ wrongStickyChildTypeException: { -+ message: "StickyContainer can only have a single child of type RecyclerListView.", -+ type: "WrongStickyChildTypeException", -+ }, -+ usingOldVisibleIndexesChangedParam: { -+ message: "onVisibleIndexesChanged has been deprecated. Please use onVisibleIndicesChanged instead.", -+ type: "usingOldVisibleIndexesChangedParam", -+ }, -+ stickyIndicesArraySortError: { -+ message: "The sticky indices array passed to StickyContainer isn't sorted in ascending order.", -+ type: "stickyIndicesArraySortError", -+ }, -+}; -+exports.default = RecyclerListViewExceptions; -+//# sourceMappingURL=RecyclerListViewExceptions.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js.map b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js.map -new file mode 100644 -index 0000000..75634b0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/exceptions/RecyclerListViewExceptions.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"RecyclerListViewExceptions.js","sourceRoot":"","sources":["../../../../src/core/exceptions/RecyclerListViewExceptions.ts"],"names":[],"mappings":";;AAEA,IAAM,0BAA0B,GAA+B;IAC3D,uBAAuB,EAAE;QACrB,OAAO,EAAE,6DAA6D;QACtE,IAAI,EAAE,mCAAmC;KAC5C;IACD,mBAAmB,EAAE;QACjB,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,qBAAqB;KAC9B;IACD,qBAAqB,EAAE;QACnB,OAAO,EAAE,gGAAgG;QACzG,IAAI,EAAE,uBAAuB;KAChC;IACD,eAAe,EAAE;QACb,OAAO,EAAE,iFAAiF;YAC9E,uDAAuD;QACnE,IAAI,EAAE,iBAAiB;KAC1B;IACD,4BAA4B,EAAE;QAC1B,OAAO,EAAE,kFAAkF;YAC3F,8EAA8E;QAC9E,IAAI,EAAE,8BAA8B;KACvC;IACD,+BAA+B,EAAE;QAC7B,OAAO,EAAE,kEAAkE;QAC3E,IAAI,EAAE,iCAAiC;KAC1C;IACD,yBAAyB,EAAE;QACvB,OAAO,EAAE,kGAAkG;QAC3G,IAAI,EAAE,2BAA2B;KACpC;IACD,6BAA6B,EAAE;QAC3B,OAAO,EAAE,wEAAwE;QACjF,IAAI,EAAE,+BAA+B;KACxC;IACD,kCAAkC,EAAE;QAChC,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,oCAAoC;KAC7C;IACD,2BAA2B,EAAE;QACzB,OAAO,EAAE,qFAAqF;QAC9F,IAAI,EAAE,6BAA6B;KACtC;CACJ,CAAC;AACF,kBAAe,0BAA0B,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.d.ts -new file mode 100644 -index 0000000..51b60d7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.d.ts -@@ -0,0 +1,40 @@ -+/*** -+ * Computes the positions and dimensions of items that will be rendered by the list. The output from this is utilized by viewability tracker to compute the -+ * lists of visible/hidden item. -+ */ -+import { Dimension, LayoutProvider } from "../dependencies/LayoutProvider"; -+export declare abstract class LayoutManager { -+ getOffsetForIndex(index: number): Point; -+ getStyleOverridesForIndex(index: number): object | undefined; -+ abstract getContentDimension(): Dimension; -+ abstract getLayouts(): Layout[]; -+ abstract overrideLayout(index: number, dim: Dimension): boolean; -+ abstract relayoutFromIndex(startIndex: number, itemCount: number): void; -+} -+export declare class WrapGridLayoutManager extends LayoutManager { -+ private _layoutProvider; -+ private _window; -+ private _totalHeight; -+ private _totalWidth; -+ private _isHorizontal; -+ private _layouts; -+ constructor(layoutProvider: LayoutProvider, renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]); -+ getContentDimension(): Dimension; -+ getLayouts(): Layout[]; -+ getOffsetForIndex(index: number): Point; -+ overrideLayout(index: number, dim: Dimension): boolean; -+ setMaxBounds(itemDim: Dimension): void; -+ relayoutFromIndex(startIndex: number, itemCount: number): void; -+ private _pointDimensionsToRect; -+ private _setFinalDimensions; -+ private _locateFirstNeighbourIndex; -+ private _checkBounds; -+} -+export interface Layout extends Dimension, Point { -+ isOverridden?: boolean; -+ type: string | number; -+} -+export interface Point { -+ x: number; -+ y: number; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js -new file mode 100644 -index 0000000..23075a0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js -@@ -0,0 +1,196 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var CustomError_1 = require("../exceptions/CustomError"); -+var LayoutManager = /** @class */ (function () { -+ function LayoutManager() { -+ } -+ LayoutManager.prototype.getOffsetForIndex = function (index) { -+ var layouts = this.getLayouts(); -+ if (layouts.length > index) { -+ return { x: layouts[index].x, y: layouts[index].y }; -+ } -+ else { -+ throw new CustomError_1.default({ -+ message: "No layout available for index: " + index, -+ type: "LayoutUnavailableException", -+ }); -+ } -+ }; -+ //You can ovveride this incase you want to override style in some cases e.g, say you want to enfore width but not height -+ LayoutManager.prototype.getStyleOverridesForIndex = function (index) { -+ return undefined; -+ }; -+ return LayoutManager; -+}()); -+exports.LayoutManager = LayoutManager; -+var WrapGridLayoutManager = /** @class */ (function (_super) { -+ __extends(WrapGridLayoutManager, _super); -+ function WrapGridLayoutManager(layoutProvider, renderWindowSize, isHorizontal, cachedLayouts) { -+ if (isHorizontal === void 0) { isHorizontal = false; } -+ var _this = _super.call(this) || this; -+ _this._layoutProvider = layoutProvider; -+ _this._window = renderWindowSize; -+ _this._totalHeight = 0; -+ _this._totalWidth = 0; -+ _this._isHorizontal = !!isHorizontal; -+ _this._layouts = cachedLayouts ? cachedLayouts : []; -+ return _this; -+ } -+ WrapGridLayoutManager.prototype.getContentDimension = function () { -+ return { height: this._totalHeight, width: this._totalWidth }; -+ }; -+ WrapGridLayoutManager.prototype.getLayouts = function () { -+ return this._layouts; -+ }; -+ WrapGridLayoutManager.prototype.getOffsetForIndex = function (index) { -+ if (this._layouts.length > index) { -+ return { x: this._layouts[index].x, y: this._layouts[index].y }; -+ } -+ else { -+ throw new CustomError_1.default({ -+ message: "No layout available for index: " + index, -+ type: "LayoutUnavailableException", -+ }); -+ } -+ }; -+ WrapGridLayoutManager.prototype.overrideLayout = function (index, dim) { -+ var layout = this._layouts[index]; -+ if (layout) { -+ layout.isOverridden = true; -+ layout.width = dim.width; -+ layout.height = dim.height; -+ } -+ return true; -+ }; -+ WrapGridLayoutManager.prototype.setMaxBounds = function (itemDim) { -+ if (this._isHorizontal) { -+ itemDim.height = Math.min(this._window.height, itemDim.height); -+ } -+ else { -+ itemDim.width = Math.min(this._window.width, itemDim.width); -+ } -+ }; -+ //TODO:Talha laziliy calculate in future revisions -+ WrapGridLayoutManager.prototype.relayoutFromIndex = function (startIndex, itemCount) { -+ startIndex = this._locateFirstNeighbourIndex(startIndex); -+ var startX = 0; -+ var startY = 0; -+ var maxBound = 0; -+ var startVal = this._layouts[startIndex]; -+ if (startVal) { -+ startX = startVal.x; -+ startY = startVal.y; -+ this._pointDimensionsToRect(startVal); -+ } -+ var oldItemCount = this._layouts.length; -+ var itemDim = { height: 0, width: 0 }; -+ var itemRect = null; -+ var oldLayout = null; -+ for (var i = startIndex; i < itemCount; i++) { -+ oldLayout = this._layouts[i]; -+ var layoutType = this._layoutProvider.getLayoutTypeForIndex(i); -+ if (oldLayout && oldLayout.isOverridden && oldLayout.type === layoutType) { -+ itemDim.height = oldLayout.height; -+ itemDim.width = oldLayout.width; -+ } -+ else { -+ this._layoutProvider.setComputedLayout(layoutType, itemDim, i); -+ } -+ this.setMaxBounds(itemDim); -+ while (!this._checkBounds(startX, startY, itemDim, this._isHorizontal)) { -+ if (this._isHorizontal) { -+ startX += maxBound; -+ startY = 0; -+ this._totalWidth += maxBound; -+ } -+ else { -+ startX = 0; -+ startY += maxBound; -+ this._totalHeight += maxBound; -+ } -+ maxBound = 0; -+ } -+ maxBound = this._isHorizontal ? Math.max(maxBound, itemDim.width) : Math.max(maxBound, itemDim.height); -+ //TODO: Talha creating array upfront will speed this up -+ if (i > oldItemCount - 1) { -+ this._layouts.push({ x: startX, y: startY, height: itemDim.height, width: itemDim.width, type: layoutType }); -+ } -+ else { -+ itemRect = this._layouts[i]; -+ itemRect.x = startX; -+ itemRect.y = startY; -+ itemRect.type = layoutType; -+ itemRect.width = itemDim.width; -+ itemRect.height = itemDim.height; -+ } -+ if (this._isHorizontal) { -+ startY += itemDim.height; -+ } -+ else { -+ startX += itemDim.width; -+ } -+ } -+ if (oldItemCount > itemCount) { -+ this._layouts.splice(itemCount, oldItemCount - itemCount); -+ } -+ this._setFinalDimensions(maxBound); -+ }; -+ WrapGridLayoutManager.prototype._pointDimensionsToRect = function (itemRect) { -+ if (this._isHorizontal) { -+ this._totalWidth = itemRect.x; -+ } -+ else { -+ this._totalHeight = itemRect.y; -+ } -+ }; -+ WrapGridLayoutManager.prototype._setFinalDimensions = function (maxBound) { -+ if (this._isHorizontal) { -+ this._totalHeight = this._window.height; -+ this._totalWidth += maxBound; -+ } -+ else { -+ this._totalWidth = this._window.width; -+ this._totalHeight += maxBound; -+ } -+ }; -+ WrapGridLayoutManager.prototype._locateFirstNeighbourIndex = function (startIndex) { -+ if (startIndex === 0) { -+ return 0; -+ } -+ var i = startIndex - 1; -+ for (; i >= 0; i--) { -+ if (!this._layouts[i]) { -+ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line -+ continue; -+ } -+ if (this._isHorizontal) { -+ if (this._layouts[i].y === 0) { -+ break; -+ } -+ } -+ else if (this._layouts[i].x === 0) { -+ break; -+ } -+ } -+ return i; -+ }; -+ WrapGridLayoutManager.prototype._checkBounds = function (itemX, itemY, itemDim, isHorizontal) { -+ return isHorizontal ? (itemY + itemDim.height <= this._window.height) : (itemX + itemDim.width <= this._window.width); -+ }; -+ return WrapGridLayoutManager; -+}(LayoutManager)); -+exports.WrapGridLayoutManager = WrapGridLayoutManager; -+//# sourceMappingURL=LayoutManager.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js.map b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js.map -new file mode 100644 -index 0000000..3129d8e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/layoutmanager/LayoutManager.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"LayoutManager.js","sourceRoot":"","sources":["../../../../src/core/layoutmanager/LayoutManager.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.d.ts -new file mode 100644 -index 0000000..fbf1ac9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.d.ts -@@ -0,0 +1,21 @@ -+import * as React from "react"; -+import { Dimension } from "../dependencies/LayoutProvider"; -+import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./BaseScrollView"; -+export interface ScrollComponentProps { -+ onSizeChanged: (dimensions: Dimension) => void; -+ onScroll: (offsetX: number, offsetY: number, rawEvent: ScrollEvent) => void; -+ contentHeight: number; -+ contentWidth: number; -+ canChangeSize?: boolean; -+ externalScrollView?: { -+ new (props: ScrollViewDefaultProps): BaseScrollView; -+ }; -+ isHorizontal?: boolean; -+ renderFooter?: () => JSX.Element | JSX.Element[] | null; -+ scrollThrottle?: number; -+ useWindowScroll?: boolean; -+ onLayout?: any; -+} -+export default abstract class BaseScrollComponent extends React.Component { -+ abstract scrollTo(x: number, y: number, animate: boolean): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js -new file mode 100644 -index 0000000..821b8f8 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js -@@ -0,0 +1,25 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollComponent = /** @class */ (function (_super) { -+ __extends(BaseScrollComponent, _super); -+ function BaseScrollComponent() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ return BaseScrollComponent; -+}(React.Component)); -+exports.default = BaseScrollComponent; -+//# sourceMappingURL=BaseScrollComponent.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js.map b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js.map -new file mode 100644 -index 0000000..1be170f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollComponent.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BaseScrollComponent.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAiB/B;IAA0D,uCAAyC;IAAnG;;IAEA,CAAC;IAAD,0BAAC;AAAD,CAAC,AAFD,CAA0D,KAAK,CAAC,SAAS,GAExE"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.d.ts -new file mode 100644 -index 0000000..d29def1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.d.ts -@@ -0,0 +1,29 @@ -+import * as React from "react"; -+import { CSSProperties } from "react"; -+import { Dimension } from "../dependencies/LayoutProvider"; -+export interface ScrollViewDefaultProps { -+ onScroll: (event: ScrollEvent) => void; -+ onSizeChanged: (dimensions: Dimension) => void; -+ horizontal: boolean; -+ canChangeSize: boolean; -+ style?: CSSProperties | null; -+ useWindowScroll: boolean; -+} -+export interface ScrollEvent { -+ nativeEvent: { -+ contentOffset: { -+ x: number; -+ y: number; -+ }; -+ layoutMeasurement?: Dimension; -+ contentSize?: Dimension; -+ }; -+} -+export default abstract class BaseScrollView extends React.Component { -+ constructor(props: ScrollViewDefaultProps); -+ abstract scrollTo(scrollInput: { -+ x: number; -+ y: number; -+ animated: boolean; -+ }): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js -new file mode 100644 -index 0000000..694e0ae ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js -@@ -0,0 +1,25 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollView = /** @class */ (function (_super) { -+ __extends(BaseScrollView, _super); -+ function BaseScrollView(props) { -+ return _super.call(this, props) || this; -+ } -+ return BaseScrollView; -+}(React.Component)); -+exports.default = BaseScrollView; -+//# sourceMappingURL=BaseScrollView.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js.map b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js.map -new file mode 100644 -index 0000000..4230976 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/scrollcomponent/BaseScrollView.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BaseScrollView.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAsB/B;IAAqD,kCAA2C;IAC5F,wBAAY,KAA6B;eACrC,kBAAM,KAAK,CAAC;IAChB,CAAC;IAGL,qBAAC;AAAD,CAAC,AAND,CAAqD,KAAK,CAAC,SAAS,GAMnE"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.d.ts -new file mode 100644 -index 0000000..a7af807 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.d.ts -@@ -0,0 +1,13 @@ -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; -+export default class StickyFooter

extends StickyObject { -+ constructor(props: P, context?: any); -+ protected initStickyParams(): void; -+ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, _smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; -+ protected getNextYd(nextY: number, nextHeight: number): number; -+ protected getCurrentYd(currentY: number, currentHeight: number): number; -+ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; -+ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js -new file mode 100644 -index 0000000..1a1b02f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js -@@ -0,0 +1,70 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var StickyObject_1 = require("./StickyObject"); -+var BinarySearch_1 = require("../../utils/BinarySearch"); -+var StickyFooter = /** @class */ (function (_super) { -+ __extends(StickyFooter, _super); -+ function StickyFooter(props, context) { -+ return _super.call(this, props, context) || this; -+ } -+ StickyFooter.prototype.initStickyParams = function () { -+ this.stickyType = StickyObject_1.StickyType.FOOTER; -+ this.stickyTypeMultiplier = -1; -+ this.containerPosition = { bottom: 0 }; -+ this.bounceScrolling = false; -+ }; -+ StickyFooter.prototype.calculateVisibleStickyIndex = function (stickyIndices, _smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow, windowBound) { -+ if (stickyIndices && largestVisibleIndex) { -+ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); -+ if (largestVisibleIndex > stickyIndices[stickyIndices.length - 1] || this.bounceScrolling) { -+ this.stickyVisiblity = false; -+ } -+ else { -+ this.stickyVisiblity = true; -+ var valueAndIndex = BinarySearch_1.default.findValueLargerThanTarget(stickyIndices, largestVisibleIndex); -+ if (valueAndIndex) { -+ this.currentIndex = valueAndIndex.index; -+ this.currentStickyIndex = valueAndIndex.value; -+ } -+ else { -+ console.log("Footer sticky index calculation gone wrong."); //tslint:disable-line -+ } -+ } -+ } -+ }; -+ StickyFooter.prototype.getNextYd = function (nextY, nextHeight) { -+ return -1 * (nextY + nextHeight); -+ }; -+ StickyFooter.prototype.getCurrentYd = function (currentY, currentHeight) { -+ return -1 * (currentY + currentHeight); -+ }; -+ StickyFooter.prototype.getScrollY = function (offsetY, scrollableHeight) { -+ return scrollableHeight ? -1 * (offsetY + scrollableHeight) : undefined; -+ }; -+ StickyFooter.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, windowBound) { -+ if (windowBound) { -+ var endReachedMargin = Math.round(offsetY - (windowBound + distanceFromWindow)); -+ return endReachedMargin >= 0; -+ } -+ return false; -+ }; -+ return StickyFooter; -+}(StickyObject_1.default)); -+exports.default = StickyFooter; -+//# sourceMappingURL=StickyFooter.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js.map b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js.map -new file mode 100644 -index 0000000..1c899a7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyFooter.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyFooter.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyFooter.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAC,MAAM,EAAE,CAAC,EAAC,CAAC;QACrC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IACjC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,qBAA6B,EAAE,mBAA2B,EAC/F,OAAe,EAAE,kBAA0B,EAAE,WAAqB;QAElE,IAAI,aAAa,IAAI,mBAAmB,EAAE;YACtC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;YACzF,IAAI,mBAAmB,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACvF,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,yBAAyB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;gBAC5H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC;IACrC,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC;IAC3C,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,WAAoB;QAC1F,IAAI,WAAW,EAAE;YACb,IAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC;YAClF,OAAO,gBAAgB,IAAI,CAAC,CAAC;SAChC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IACL,mBAAC;AAAD,CAAC,AApDD,CAAoG,sBAAY,GAoD/G"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.d.ts -new file mode 100644 -index 0000000..08481a0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.d.ts -@@ -0,0 +1,13 @@ -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; -+export default class StickyHeader

extends StickyObject { -+ constructor(props: P, context?: any); -+ protected initStickyParams(): void; -+ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number): void; -+ protected getNextYd(nextY: number, nextHeight: number): number; -+ protected getCurrentYd(currentY: number, currentHeight: number): number; -+ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; -+ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, _windowBound?: number): boolean; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js -new file mode 100644 -index 0000000..5e72f6e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js -@@ -0,0 +1,68 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var StickyObject_1 = require("./StickyObject"); -+var BinarySearch_1 = require("../../utils/BinarySearch"); -+var StickyHeader = /** @class */ (function (_super) { -+ __extends(StickyHeader, _super); -+ function StickyHeader(props, context) { -+ return _super.call(this, props, context) || this; -+ } -+ StickyHeader.prototype.initStickyParams = function () { -+ this.stickyType = StickyObject_1.StickyType.HEADER; -+ this.stickyTypeMultiplier = 1; -+ this.containerPosition = { top: 0 }; -+ // Kept as true contrary to as in StickyFooter because in case of initialOffset not given, onScroll isn't called and boundaryProcessing isn't done. -+ // Default behaviour in that case will be sticky header hidden. -+ this.bounceScrolling = true; -+ }; -+ StickyHeader.prototype.calculateVisibleStickyIndex = function (stickyIndices, smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow) { -+ if (stickyIndices && smallestVisibleIndex !== undefined) { -+ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow); -+ if (smallestVisibleIndex < stickyIndices[0] || this.bounceScrolling) { -+ this.stickyVisiblity = false; -+ } -+ else { -+ this.stickyVisiblity = true; -+ var valueAndIndex = BinarySearch_1.default.findValueSmallerThanTarget(stickyIndices, smallestVisibleIndex); -+ if (valueAndIndex) { -+ this.currentIndex = valueAndIndex.index; -+ this.currentStickyIndex = valueAndIndex.value; -+ } -+ else { -+ console.log("Header sticky index calculation gone wrong."); //tslint:disable-line -+ } -+ } -+ } -+ }; -+ StickyHeader.prototype.getNextYd = function (nextY, nextHeight) { -+ return nextY; -+ }; -+ StickyHeader.prototype.getCurrentYd = function (currentY, currentHeight) { -+ return currentY; -+ }; -+ StickyHeader.prototype.getScrollY = function (offsetY, scrollableHeight) { -+ return offsetY; -+ }; -+ StickyHeader.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, _windowBound) { -+ return offsetY < distanceFromWindow; -+ }; -+ return StickyHeader; -+}(StickyObject_1.default)); -+exports.default = StickyHeader; -+//# sourceMappingURL=StickyHeader.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js.map b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js.map -new file mode 100644 -index 0000000..aef0aaa ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyHeader.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyHeader.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyHeader.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,iBAAiB,GAAG,EAAC,GAAG,EAAE,CAAC,EAAC,CAAC;QAElC,mJAAmJ;QACnJ,+DAA+D;QAC/D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAChC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,oBAA4B,EAAE,mBAA2B,EAAE,OAAe,EAAE,kBAA0B;QAE3I,IAAI,aAAa,IAAI,oBAAoB,KAAK,SAAS,EAAE;YACrD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC5E,IAAI,oBAAoB,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACjE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,0BAA0B,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;gBAC9H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,QAAQ,CAAC;IACpB,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,OAAO,CAAC;IACnB,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,YAAqB;QAC3F,OAAO,OAAO,GAAG,kBAAkB,CAAC;IACxC,CAAC;IACL,mBAAC;AAAD,CAAC,AAlDD,CAAoG,sBAAY,GAkD/G"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.d.ts -new file mode 100644 -index 0000000..ed5976f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.d.ts -@@ -0,0 +1,74 @@ -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+import * as React from "react"; -+import { StyleProp, ViewStyle } from "react-native"; -+import { Layout } from "../layoutmanager/LayoutManager"; -+import { Dimension } from "../dependencies/LayoutProvider"; -+export declare enum StickyType { -+ HEADER = 0, -+ FOOTER = 1 -+} -+export interface StickyObjectProps { -+ stickyIndices: number[] | undefined; -+ getLayoutForIndex: (index: number) => Layout | undefined; -+ getDataForIndex: (index: number) => any; -+ getLayoutTypeForIndex: (index: number) => string | number; -+ getExtendedState: () => object | undefined; -+ getRLVRenderedSize: () => Dimension | undefined; -+ getContentDimension: () => Dimension | undefined; -+ getRowRenderer: () => ((type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null); -+ getDistanceFromWindow: () => number; -+ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+} -+export interface StickyObjectState { -+ visibility: boolean; -+} -+export default abstract class StickyObject

extends React.Component { -+ protected stickyType: StickyType; -+ protected stickyTypeMultiplier: number; -+ protected stickyVisiblity: boolean; -+ protected visibility: boolean; -+ protected containerPosition: StyleProp; -+ protected currentIndex: number; -+ protected currentStickyIndex: number; -+ protected visibleIndices: number[]; -+ protected bounceScrolling: boolean; -+ private _previousLayout; -+ private _previousHeight; -+ private _nextLayout; -+ private _nextY; -+ private _nextHeight; -+ private _currentLayout; -+ private _currentY; -+ private _currentHeight; -+ private _nextYd; -+ private _currentYd; -+ private _scrollableHeight; -+ private _scrollableWidth; -+ private _windowBound; -+ private _stickyViewOffset; -+ private _previousStickyIndex; -+ private _nextStickyIndex; -+ private _firstCompute; -+ private _smallestVisibleIndex; -+ private _largestVisibleIndex; -+ private _offsetY; -+ constructor(props: P, context?: any); -+ componentWillReceiveProps(newProps: StickyObjectProps): void; -+ render(): JSX.Element | null; -+ onVisibleIndicesChanged(all: number[]): void; -+ onScroll(offsetY: number): void; -+ protected abstract hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; -+ protected abstract initStickyParams(): void; -+ protected abstract calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; -+ protected abstract getNextYd(_nextY: number, nextHeight: number): number; -+ protected abstract getCurrentYd(currentY: number, currentHeight: number): number; -+ protected abstract getScrollY(offsetY: number, scrollableHeight?: number): number | undefined; -+ protected stickyViewVisible(_visible: boolean): void; -+ protected boundaryProcessing(offsetY: number, distanceFromWindow: number, windowBound?: number): void; -+ private _initParams; -+ private _computeLayouts; -+ private _setSmallestAndLargestVisibleIndices; -+ private _renderSticky; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js -new file mode 100644 -index 0000000..4964223 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js -@@ -0,0 +1,203 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var react_native_1 = require("react-native"); -+var RecyclerListViewExceptions_1 = require("../exceptions/RecyclerListViewExceptions"); -+var CustomError_1 = require("../exceptions/CustomError"); -+var StickyType; -+(function (StickyType) { -+ StickyType[StickyType["HEADER"] = 0] = "HEADER"; -+ StickyType[StickyType["FOOTER"] = 1] = "FOOTER"; -+})(StickyType = exports.StickyType || (exports.StickyType = {})); -+var StickyObject = /** @class */ (function (_super) { -+ __extends(StickyObject, _super); -+ function StickyObject(props, context) { -+ var _this = _super.call(this, props, context) || this; -+ _this.stickyType = StickyType.HEADER; -+ _this.stickyTypeMultiplier = 1; -+ _this.stickyVisiblity = false; -+ _this.visibility = false; -+ _this.currentIndex = 0; -+ _this.currentStickyIndex = 0; -+ _this.visibleIndices = []; -+ _this.bounceScrolling = false; -+ _this._stickyViewOffset = new react_native_1.Animated.Value(0); -+ _this._previousStickyIndex = 0; -+ _this._nextStickyIndex = 0; -+ _this._firstCompute = true; -+ _this._smallestVisibleIndex = 0; -+ _this._largestVisibleIndex = 0; -+ _this._offsetY = 0; -+ _this.state = { -+ visibility: true, -+ }; -+ return _this; -+ } -+ StickyObject.prototype.componentWillReceiveProps = function (newProps) { -+ this._initParams(); -+ this.calculateVisibleStickyIndex(newProps.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, newProps.getDistanceFromWindow(), this._windowBound); -+ this._computeLayouts(newProps.stickyIndices); -+ this.stickyViewVisible(this.stickyVisiblity); -+ }; -+ StickyObject.prototype.render = function () { -+ return (React.createElement(react_native_1.Animated.View, { style: [ -+ { position: "absolute", width: this._scrollableWidth, transform: [{ translateY: this._stickyViewOffset }] }, -+ this.containerPosition, -+ ] }, this.visibility ? -+ this._renderSticky() -+ : null)); -+ }; -+ StickyObject.prototype.onVisibleIndicesChanged = function (all) { -+ if (this._firstCompute) { -+ this.initStickyParams(); -+ this._firstCompute = false; -+ } -+ this._initParams(); -+ this._setSmallestAndLargestVisibleIndices(all); -+ this.calculateVisibleStickyIndex(this.props.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, this.props.getDistanceFromWindow(), this._windowBound); -+ this._computeLayouts(); -+ this.stickyViewVisible(this.stickyVisiblity); -+ }; -+ StickyObject.prototype.onScroll = function (offsetY) { -+ var prevVisibility = this.visibility; -+ if (offsetY < 0 && prevVisibility === true || this._smallestVisibleIndex < this.currentStickyIndex) { -+ this.visibility = false; -+ } -+ else if (offsetY >= 0 && prevVisibility === false) { -+ this.visibility = true; -+ } -+ if (prevVisibility !== this.visibility) { -+ this.render(); -+ } -+ this._initParams(); -+ this._offsetY = offsetY; -+ this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); -+ if (this._previousStickyIndex !== undefined) { -+ if (this._previousStickyIndex * this.stickyTypeMultiplier >= this.currentStickyIndex * this.stickyTypeMultiplier) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); -+ } -+ var scrollY_1 = this.getScrollY(offsetY, this._scrollableHeight); -+ if (this._previousHeight && this._currentYd && scrollY_1 && scrollY_1 < this._currentYd) { -+ if (scrollY_1 > this._currentYd - this._previousHeight) { -+ this.currentIndex -= this.stickyTypeMultiplier; -+ var translate = (scrollY_1 - this._currentYd + this._previousHeight) * (-1 * this.stickyTypeMultiplier); -+ this._stickyViewOffset.setValue(translate); -+ this._computeLayouts(); -+ this.stickyViewVisible(true); -+ } -+ } -+ else { -+ this._stickyViewOffset.setValue(0); -+ } -+ } -+ if (this._nextStickyIndex !== undefined) { -+ if (this._nextStickyIndex * this.stickyTypeMultiplier <= this.currentStickyIndex * this.stickyTypeMultiplier) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); -+ } -+ var scrollY_2 = this.getScrollY(offsetY, this._scrollableHeight); -+ if (this._currentHeight && this._nextYd && scrollY_2 && scrollY_2 + this._currentHeight > this._nextYd) { -+ if (scrollY_2 <= this._nextYd) { -+ var translate = (scrollY_2 - this._nextYd + this._currentHeight) * (-1 * this.stickyTypeMultiplier); -+ this._stickyViewOffset.setValue(translate); -+ } -+ else if (scrollY_2 > this._nextYd) { -+ this.currentIndex += this.stickyTypeMultiplier; -+ this._stickyViewOffset.setValue(0); -+ this._computeLayouts(); -+ this.stickyViewVisible(true); -+ } -+ } -+ else { -+ this._stickyViewOffset.setValue(0); -+ } -+ } -+ }; -+ StickyObject.prototype.stickyViewVisible = function (_visible) { -+ this.setState({ -+ visibility: _visible, -+ }); -+ }; -+ StickyObject.prototype.boundaryProcessing = function (offsetY, distanceFromWindow, windowBound) { -+ var hasReachedBoundary = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); -+ if (this.bounceScrolling !== hasReachedBoundary) { -+ this.bounceScrolling = hasReachedBoundary; -+ if (this.bounceScrolling) { -+ this.stickyViewVisible(false); -+ } -+ else { -+ this.onVisibleIndicesChanged(this.visibleIndices); -+ } -+ } -+ }; -+ StickyObject.prototype._initParams = function () { -+ var rlvDimension = this.props.getRLVRenderedSize(); -+ if (rlvDimension) { -+ this._scrollableHeight = rlvDimension.height; -+ this._scrollableWidth = rlvDimension.width; -+ } -+ var contentDimension = this.props.getContentDimension(); -+ if (contentDimension && this._scrollableHeight) { -+ this._windowBound = contentDimension.height - this._scrollableHeight; -+ } -+ }; -+ StickyObject.prototype._computeLayouts = function (newStickyIndices) { -+ var stickyIndices = newStickyIndices ? newStickyIndices : this.props.stickyIndices; -+ if (stickyIndices) { -+ this.currentStickyIndex = stickyIndices[this.currentIndex]; -+ this._previousStickyIndex = stickyIndices[this.currentIndex - this.stickyTypeMultiplier]; -+ this._nextStickyIndex = stickyIndices[this.currentIndex + this.stickyTypeMultiplier]; -+ if (this.currentStickyIndex !== undefined) { -+ this._currentLayout = this.props.getLayoutForIndex(this.currentStickyIndex); -+ this._currentY = this._currentLayout ? this._currentLayout.y : undefined; -+ this._currentHeight = this._currentLayout ? this._currentLayout.height : undefined; -+ this._currentYd = this._currentY && this._currentHeight ? this.getCurrentYd(this._currentY, this._currentHeight) : undefined; -+ } -+ if (this._previousStickyIndex !== undefined) { -+ this._previousLayout = this.props.getLayoutForIndex(this._previousStickyIndex); -+ this._previousHeight = this._previousLayout ? this._previousLayout.height : undefined; -+ } -+ if (this._nextStickyIndex !== undefined) { -+ this._nextLayout = this.props.getLayoutForIndex(this._nextStickyIndex); -+ this._nextY = this._nextLayout ? this._nextLayout.y : undefined; -+ this._nextHeight = this._nextLayout ? this._nextLayout.height : undefined; -+ this._nextYd = this._nextY && this._nextHeight ? this.getNextYd(this._nextY, this._nextHeight) : undefined; -+ } -+ } -+ }; -+ StickyObject.prototype._setSmallestAndLargestVisibleIndices = function (indicesArray) { -+ this.visibleIndices = indicesArray; -+ this._smallestVisibleIndex = indicesArray[0]; -+ this._largestVisibleIndex = indicesArray[indicesArray.length - 1]; -+ }; -+ StickyObject.prototype._renderSticky = function () { -+ var _stickyData = this.props.getDataForIndex(this.currentStickyIndex); -+ var _stickyLayoutType = this.props.getLayoutTypeForIndex(this.currentStickyIndex); -+ var _extendedState = this.props.getExtendedState(); -+ var _rowRenderer = this.props.getRowRenderer(); -+ if (this.props.overrideRowRenderer) { -+ return this.props.overrideRowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); -+ } -+ else { -+ return _rowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); -+ } -+ }; -+ return StickyObject; -+}(React.Component)); -+exports.default = StickyObject; -+//# sourceMappingURL=StickyObject.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js.map b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js.map -new file mode 100644 -index 0000000..82b71ae ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/sticky/StickyObject.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyObject.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyObject.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.d.ts -new file mode 100644 -index 0000000..400f352 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.d.ts -@@ -0,0 +1,37 @@ -+import * as React from "react"; -+import { Dimension, BaseLayoutProvider } from "../dependencies/LayoutProvider"; -+import ItemAnimator from "../ItemAnimator"; -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+export interface ViewRendererProps { -+ x: number; -+ y: number; -+ height: number; -+ width: number; -+ childRenderer: (type: string | number, data: T, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+ layoutType: string | number; -+ dataHasChanged: (r1: T, r2: T) => boolean; -+ onSizeChanged: (dim: Dimension, index: number) => void; -+ data: any; -+ index: number; -+ itemAnimator: ItemAnimator; -+ styleOverrides?: object; -+ forceNonDeterministicRendering?: boolean; -+ isHorizontal?: boolean; -+ extendedState?: object; -+ internalSnapshot?: object; -+ layoutProvider?: BaseLayoutProvider; -+} -+export default abstract class BaseViewRenderer extends React.Component, {}> { -+ protected animatorStyleOverrides: object | undefined; -+ shouldComponentUpdate(newProps: ViewRendererProps): boolean; -+ componentDidMount(): void; -+ componentWillMount(): void; -+ componentWillUnmount(): void; -+ protected abstract getRef(): object | null; -+ protected renderChild(): JSX.Element | JSX.Element[] | null; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js -new file mode 100644 -index 0000000..f584ea7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js -@@ -0,0 +1,55 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseViewRenderer = /** @class */ (function (_super) { -+ __extends(BaseViewRenderer, _super); -+ function BaseViewRenderer() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ BaseViewRenderer.prototype.shouldComponentUpdate = function (newProps) { -+ var hasMoved = this.props.x !== newProps.x || this.props.y !== newProps.y; -+ var hasSizeChanged = !newProps.forceNonDeterministicRendering && -+ (this.props.width !== newProps.width || this.props.height !== newProps.height) || -+ this.props.layoutProvider !== newProps.layoutProvider; -+ var hasExtendedStateChanged = this.props.extendedState !== newProps.extendedState; -+ var hasInternalSnapshotChanged = this.props.internalSnapshot !== newProps.internalSnapshot; -+ var hasDataChanged = (this.props.dataHasChanged && this.props.dataHasChanged(this.props.data, newProps.data)); -+ var shouldUpdate = hasSizeChanged || hasDataChanged || hasExtendedStateChanged || hasInternalSnapshotChanged; -+ if (shouldUpdate) { -+ newProps.itemAnimator.animateWillUpdate(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); -+ } -+ else if (hasMoved) { -+ shouldUpdate = !newProps.itemAnimator.animateShift(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); -+ } -+ return shouldUpdate; -+ }; -+ BaseViewRenderer.prototype.componentDidMount = function () { -+ this.animatorStyleOverrides = undefined; -+ this.props.itemAnimator.animateDidMount(this.props.x, this.props.y, this.getRef(), this.props.index); -+ }; -+ BaseViewRenderer.prototype.componentWillMount = function () { -+ this.animatorStyleOverrides = this.props.itemAnimator.animateWillMount(this.props.x, this.props.y, this.props.index); -+ }; -+ BaseViewRenderer.prototype.componentWillUnmount = function () { -+ this.props.itemAnimator.animateWillUnmount(this.props.x, this.props.y, this.getRef(), this.props.index); -+ }; -+ BaseViewRenderer.prototype.renderChild = function () { -+ return this.props.childRenderer(this.props.layoutType, this.props.data, this.props.index, this.props.extendedState); -+ }; -+ return BaseViewRenderer; -+}(React.Component)); -+exports.default = BaseViewRenderer; -+//# sourceMappingURL=BaseViewRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js.map -new file mode 100644 -index 0000000..451d377 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/core/viewrenderer/BaseViewRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BaseViewRenderer.js","sourceRoot":"","sources":["../../../../src/core/viewrenderer/BaseViewRenderer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/index.d.ts b/node_modules/recyclerlistview/dist/reactnative/index.d.ts -new file mode 100644 -index 0000000..230e231 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/index.d.ts -@@ -0,0 +1,11 @@ -+import ContextProvider from "./core/dependencies/ContextProvider"; -+import DataProvider, { BaseDataProvider } from "./core/dependencies/DataProvider"; -+import { BaseLayoutProvider, Dimension, LayoutProvider } from "./core/dependencies/LayoutProvider"; -+import RecyclerListView, { OnRecreateParams } from "./core/RecyclerListView"; -+import BaseScrollView from "./core/scrollcomponent/BaseScrollView"; -+import { BaseItemAnimator } from "./core/ItemAnimator"; -+import { AutoScroll } from "./utils/AutoScroll"; -+import { Layout, LayoutManager, Point, WrapGridLayoutManager } from "./core/layoutmanager/LayoutManager"; -+import ProgressiveListView from "./core/ProgressiveListView"; -+import { DebugHandlers } from "./core/devutils/debughandlers/DebugHandlers"; -+export { ContextProvider, DataProvider, LayoutProvider, BaseLayoutProvider, LayoutManager, WrapGridLayoutManager, RecyclerListView, ProgressiveListView, BaseItemAnimator, BaseScrollView, AutoScroll, Dimension, Point, Layout, OnRecreateParams, DebugHandlers, BaseDataProvider, }; -diff --git a/node_modules/recyclerlistview/dist/reactnative/index.js b/node_modules/recyclerlistview/dist/reactnative/index.js -new file mode 100644 -index 0000000..2faf787 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/index.js -@@ -0,0 +1,24 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ContextProvider_1 = require("./core/dependencies/ContextProvider"); -+exports.ContextProvider = ContextProvider_1.default; -+var DataProvider_1 = require("./core/dependencies/DataProvider"); -+exports.DataProvider = DataProvider_1.default; -+exports.BaseDataProvider = DataProvider_1.BaseDataProvider; -+var LayoutProvider_1 = require("./core/dependencies/LayoutProvider"); -+exports.BaseLayoutProvider = LayoutProvider_1.BaseLayoutProvider; -+exports.LayoutProvider = LayoutProvider_1.LayoutProvider; -+var RecyclerListView_1 = require("./core/RecyclerListView"); -+exports.RecyclerListView = RecyclerListView_1.default; -+var BaseScrollView_1 = require("./core/scrollcomponent/BaseScrollView"); -+exports.BaseScrollView = BaseScrollView_1.default; -+var ItemAnimator_1 = require("./core/ItemAnimator"); -+exports.BaseItemAnimator = ItemAnimator_1.BaseItemAnimator; -+var AutoScroll_1 = require("./utils/AutoScroll"); -+exports.AutoScroll = AutoScroll_1.AutoScroll; -+var LayoutManager_1 = require("./core/layoutmanager/LayoutManager"); -+exports.LayoutManager = LayoutManager_1.LayoutManager; -+exports.WrapGridLayoutManager = LayoutManager_1.WrapGridLayoutManager; -+var ProgressiveListView_1 = require("./core/ProgressiveListView"); -+exports.ProgressiveListView = ProgressiveListView_1.default; -+//# sourceMappingURL=index.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/index.js.map b/node_modules/recyclerlistview/dist/reactnative/index.js.map -new file mode 100644 -index 0000000..9e60fb9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/index.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;AAAA,uEAAkE;AAY9D,0BAZG,yBAAe,CAYH;AAXnB,iEAAkF;AAY9E,uBAZG,sBAAY,CAYH;AAeZ,2BA3BmB,+BAAgB,CA2BnB;AA1BpB,qEAAmG;AAa/F,6BAbK,mCAAkB,CAaL;AADlB,yBAZoC,+BAAc,CAYpC;AAXlB,4DAA6E;AAezE,2BAfG,0BAAgB,CAeH;AAdpB,wEAAmE;AAiB/D,yBAjBG,wBAAc,CAiBH;AAhBlB,oDAAuD;AAenD,2BAfK,+BAAgB,CAeL;AAdpB,iDAAgD;AAgB5C,qBAhBK,uBAAU,CAgBL;AAfd,oEAAyG;AASrG,wBATa,6BAAa,CASb;AACb,gCAVmC,qCAAqB,CAUnC;AATzB,kEAA6D;AAWzD,8BAXG,6BAAmB,CAWH"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts -new file mode 100644 -index 0000000..693e3a0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts -@@ -0,0 +1,12 @@ -+import { BaseItemAnimator } from "../../../core/ItemAnimator"; -+export declare class DefaultNativeItemAnimator implements BaseItemAnimator { -+ shouldAnimateOnce: boolean; -+ private _hasAnimatedOnce; -+ private _isTimerOn; -+ constructor(); -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js -new file mode 100644 -index 0000000..9ac03d1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js -@@ -0,0 +1,48 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var react_native_1 = require("react-native"); -+var DefaultNativeItemAnimator = /** @class */ (function () { -+ function DefaultNativeItemAnimator() { -+ this.shouldAnimateOnce = true; -+ this._hasAnimatedOnce = false; -+ this._isTimerOn = false; -+ if (react_native_1.Platform.OS === "android" && react_native_1.UIManager.setLayoutAnimationEnabledExperimental) { -+ react_native_1.UIManager.setLayoutAnimationEnabledExperimental(true); -+ } -+ } -+ DefaultNativeItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ DefaultNativeItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ DefaultNativeItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ this._hasAnimatedOnce = true; -+ }; -+ DefaultNativeItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ var _this = this; -+ if (fromX !== toX || fromY !== toY) { -+ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { -+ react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut); -+ this._hasAnimatedOnce = true; -+ } -+ } -+ else { -+ if (!this._isTimerOn) { -+ this._isTimerOn = true; -+ if (!this._hasAnimatedOnce) { -+ setTimeout(function () { -+ _this._hasAnimatedOnce = true; -+ }, 1000); -+ } -+ } -+ } -+ return false; -+ }; -+ DefaultNativeItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ return DefaultNativeItemAnimator; -+}()); -+exports.DefaultNativeItemAnimator = DefaultNativeItemAnimator; -+//# sourceMappingURL=DefaultNativeItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map -new file mode 100644 -index 0000000..50ecf5a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultNativeItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/itemanimators/DefaultNativeItemAnimator.ts"],"names":[],"mappings":";;AAAA,6CAAoE;AAGpE;IAII;QAHO,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;QAEhC,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,wBAAS,CAAC,qCAAqC,EAAE;YAC9E,wBAAS,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC;SACzD;IACL,CAAC;IACM,oDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,mDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,qDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,gDAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAiBC;QAhBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,8BAAe,CAAC,aAAa,CAAC,8BAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACrE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;aAChC;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,sDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,gCAAC;AAAD,CAAC,AA1CD,IA0CC;AA1CY,8DAAyB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts -new file mode 100644 -index 0000000..e3a83b3 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts -@@ -0,0 +1,19 @@ -+import { BaseItemAnimator } from "../../../../core/ItemAnimator"; -+/** -+ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator -+ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite -+ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if -+ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is -+ * hardly customizable. -+ */ -+export declare class DefaultJSItemAnimator implements BaseItemAnimator { -+ shouldAnimateOnce: boolean; -+ private _hasAnimatedOnce; -+ private _isTimerOn; -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ private _getNativePropObject; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js -new file mode 100644 -index 0000000..1b8b812 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js -@@ -0,0 +1,77 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var react_native_1 = require("react-native"); -+var ItemAnimator_1 = require("../../../../core/ItemAnimator"); -+/** -+ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator -+ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite -+ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if -+ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is -+ * hardly customizable. -+ */ -+var DefaultJSItemAnimator = /** @class */ (function () { -+ function DefaultJSItemAnimator() { -+ this.shouldAnimateOnce = true; -+ this._hasAnimatedOnce = false; -+ this._isTimerOn = false; -+ } -+ DefaultJSItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ DefaultJSItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ DefaultJSItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ this._hasAnimatedOnce = true; -+ }; -+ DefaultJSItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ var _this = this; -+ if (fromX !== toX || fromY !== toY) { -+ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { -+ var viewRef_1 = itemRef; -+ var animXY_1 = new react_native_1.Animated.ValueXY({ x: fromX, y: fromY }); -+ animXY_1.addListener(function (value) { -+ if (viewRef_1._isUnmountedForRecyclerListView || (_this.shouldAnimateOnce && _this._hasAnimatedOnce)) { -+ animXY_1.stopAnimation(); -+ return; -+ } -+ viewRef_1.setNativeProps(_this._getNativePropObject(value.x, value.y)); -+ }); -+ if (viewRef_1._lastAnimVal) { -+ viewRef_1._lastAnimVal.stopAnimation(); -+ } -+ viewRef_1._lastAnimVal = animXY_1; -+ react_native_1.Animated.timing(animXY_1, { -+ toValue: { x: toX, y: toY }, -+ duration: 200, -+ easing: react_native_1.Easing.out(react_native_1.Easing.ease), -+ useNativeDriver: ItemAnimator_1.BaseItemAnimator.USE_NATIVE_DRIVER, -+ }).start(function () { -+ viewRef_1._lastAnimVal = null; -+ _this._hasAnimatedOnce = true; -+ }); -+ return true; -+ } -+ } -+ else { -+ if (!this._isTimerOn) { -+ this._isTimerOn = true; -+ if (!this._hasAnimatedOnce) { -+ setTimeout(function () { -+ _this._hasAnimatedOnce = true; -+ }, 1000); -+ } -+ } -+ } -+ return false; -+ }; -+ DefaultJSItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ itemRef._isUnmountedForRecyclerListView = true; -+ }; -+ DefaultJSItemAnimator.prototype._getNativePropObject = function (x, y) { -+ return { style: { left: x, top: y } }; -+ }; -+ return DefaultJSItemAnimator; -+}()); -+exports.DefaultJSItemAnimator = DefaultJSItemAnimator; -+//# sourceMappingURL=DefaultJSItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map -new file mode 100644 -index 0000000..6a6881e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultJSItemAnimator.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.ts"],"names":[],"mappings":";;AAAA,6CAAsD;AACtD,8DAAiE;AAOjE;;;;;;GAMG;AACH;IAAA;QACW,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;IA2DxC,CAAC;IA1DU,gDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,+CAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,iDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,4CAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAsCC;QArCG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,IAAM,SAAO,GAAG,OAA2B,CAAC;gBAC5C,IAAM,QAAM,GAAG,IAAI,uBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC5D,QAAM,CAAC,WAAW,CAAC,UAAC,KAAK;oBACrB,IAAI,SAAO,CAAC,+BAA+B,IAAI,CAAC,KAAI,CAAC,iBAAiB,IAAI,KAAI,CAAC,gBAAgB,CAAC,EAAE;wBAC9F,QAAM,CAAC,aAAa,EAAE,CAAC;wBACvB,OAAO;qBACV;oBACD,SAAO,CAAC,cAAc,CAAC,KAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxE,CAAC,CAAC,CAAC;gBACH,IAAI,SAAO,CAAC,YAAY,EAAE;oBACtB,SAAO,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;iBACxC;gBACD,SAAO,CAAC,YAAY,GAAG,QAAM,CAAC;gBAC9B,uBAAQ,CAAC,MAAM,CAAC,QAAM,EAAE;oBACpB,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;oBAC3B,QAAQ,EAAE,GAAG;oBACb,MAAM,EAAE,qBAAM,CAAC,GAAG,CAAC,qBAAM,CAAC,IAAI,CAAC;oBAC/B,eAAe,EAAE,+BAAgB,CAAC,iBAAiB;iBACtD,CAAC,CAAC,KAAK,CAAC;oBACL,SAAO,CAAC,YAAY,GAAG,IAAI,CAAC;oBAC5B,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACjC,CAAC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;aACf;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,kDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QACjF,OAA4B,CAAC,+BAA+B,GAAG,IAAI,CAAC;IACzE,CAAC;IAEO,oDAAoB,GAA5B,UAA6B,CAAS,EAAE,CAAS;QAC7C,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAC1C,CAAC;IACL,4BAAC;AAAD,CAAC,AA9DD,IA8DC;AA9DY,sDAAqB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts -new file mode 100644 -index 0000000..63ab9e4 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts -@@ -0,0 +1,2 @@ -+import { DefaultWebItemAnimator } from "../../../web/itemanimators/DefaultWebItemAnimator"; -+export { DefaultWebItemAnimator as DefaultJSItemAnimator }; -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js -new file mode 100644 -index 0000000..53a8a28 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js -@@ -0,0 +1,5 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var DefaultWebItemAnimator_1 = require("../../../web/itemanimators/DefaultWebItemAnimator"); -+exports.DefaultJSItemAnimator = DefaultWebItemAnimator_1.DefaultWebItemAnimator; -+//# sourceMappingURL=DefaultJSItemAnimator.web.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map -new file mode 100644 -index 0000000..ee1f03d ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultJSItemAnimator.web.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.ts"],"names":[],"mappings":";;AAAA,4FAA2F;AACxD,gCAD1B,+CAAsB,CACyB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.d.ts -new file mode 100644 -index 0000000..8e9f3e1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.d.ts -@@ -0,0 +1,26 @@ -+/// -+import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+export default class ScrollComponent extends BaseScrollComponent { -+ static defaultProps: { -+ contentHeight: number; -+ contentWidth: number; -+ externalScrollView: {}; -+ isHorizontal: boolean; -+ scrollThrottle: number; -+ }; -+ private _height; -+ private _width; -+ private _isSizeChangedCalledOnce; -+ private _scrollViewRef; -+ constructor(args: ScrollComponentProps); -+ scrollTo(x: number, y: number, isAnimated: boolean): void; -+ render(): JSX.Element; -+ private _getScrollViewRef; -+ private _onScroll; -+ private _onLayout; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js -new file mode 100644 -index 0000000..0cda95e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js -@@ -0,0 +1,102 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var react_native_1 = require("react-native"); -+var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); -+var TSCast_1 = require("../../../utils/TSCast"); -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+var ScrollComponent = /** @class */ (function (_super) { -+ __extends(ScrollComponent, _super); -+ function ScrollComponent(args) { -+ var _this = _super.call(this, args) || this; -+ _this._scrollViewRef = null; -+ _this._getScrollViewRef = function (scrollView) { _this._scrollViewRef = scrollView; }; -+ _this._onScroll = function (event) { -+ if (event) { -+ _this.props.onScroll(event.nativeEvent.contentOffset.x, event.nativeEvent.contentOffset.y, event); -+ } -+ }; -+ _this._onLayout = function (event) { -+ if (_this._height !== event.nativeEvent.layout.height || _this._width !== event.nativeEvent.layout.width) { -+ _this._height = event.nativeEvent.layout.height; -+ _this._width = event.nativeEvent.layout.width; -+ if (_this.props.onSizeChanged) { -+ _this._isSizeChangedCalledOnce = true; -+ _this.props.onSizeChanged(event.nativeEvent.layout); -+ } -+ } -+ if (_this.props.onLayout) { -+ _this.props.onLayout(event); -+ } -+ }; -+ _this._height = 0; -+ _this._width = 0; -+ _this._isSizeChangedCalledOnce = false; -+ return _this; -+ } -+ ScrollComponent.prototype.scrollTo = function (x, y, isAnimated) { -+ if (this._scrollViewRef) { -+ this._scrollViewRef.scrollTo({ x: x, y: y, animated: isAnimated }); -+ } -+ }; -+ ScrollComponent.prototype.render = function () { -+ var Scroller = TSCast_1.default.cast(this.props.externalScrollView); //TSI -+ //TODO:Talha -+ // const { -+ // useWindowScroll, -+ // contentHeight, -+ // contentWidth, -+ // externalScrollView, -+ // canChangeSize, -+ // renderFooter, -+ // isHorizontal, -+ // scrollThrottle, -+ // ...props, -+ // } = this.props; -+ return (React.createElement(Scroller, __assign({ ref: this._getScrollViewRef, removeClippedSubviews: false, scrollEventThrottle: this.props.scrollThrottle }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onLayout: (!this._isSizeChangedCalledOnce || this.props.canChangeSize) ? this._onLayout : this.props.onLayout }), -+ React.createElement(react_native_1.View, { style: { flexDirection: this.props.isHorizontal ? "row" : "column" } }, -+ React.createElement(react_native_1.View, { style: { -+ height: this.props.contentHeight, -+ width: this.props.contentWidth, -+ } }, this.props.children), -+ this.props.renderFooter ? this.props.renderFooter() : null))); -+ }; -+ ScrollComponent.defaultProps = { -+ contentHeight: 0, -+ contentWidth: 0, -+ externalScrollView: TSCast_1.default.cast(react_native_1.ScrollView), -+ isHorizontal: false, -+ scrollThrottle: 16, -+ }; -+ return ScrollComponent; -+}(BaseScrollComponent_1.default)); -+exports.default = ScrollComponent; -+//# sourceMappingURL=ScrollComponent.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js.map -new file mode 100644 -index 0000000..16bf1fd ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/scrollcomponent/ScrollComponent.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.d.ts -new file mode 100644 -index 0000000..fe95fc1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.d.ts -@@ -0,0 +1,16 @@ -+/// -+import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+export default class ViewRenderer extends BaseViewRenderer { -+ private _dim; -+ private _viewRef; -+ render(): JSX.Element; -+ protected getRef(): object | null; -+ private _setRef; -+ private _onLayout; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js -new file mode 100644 -index 0000000..5b56fd5 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js -@@ -0,0 +1,70 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var react_native_1 = require("react-native"); -+var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+var ViewRenderer = /** @class */ (function (_super) { -+ __extends(ViewRenderer, _super); -+ function ViewRenderer() { -+ var _this = _super !== null && _super.apply(this, arguments) || this; -+ _this._dim = { width: 0, height: 0 }; -+ _this._viewRef = null; -+ _this._setRef = function (view) { -+ _this._viewRef = view; -+ }; -+ _this._onLayout = function (event) { -+ //Preventing layout thrashing in super fast scrolls where RN messes up onLayout event -+ var xDiff = Math.abs(_this.props.x - event.nativeEvent.layout.x); -+ var yDiff = Math.abs(_this.props.y - event.nativeEvent.layout.y); -+ if (xDiff < 1 && yDiff < 1 && -+ (_this.props.height !== event.nativeEvent.layout.height || -+ _this.props.width !== event.nativeEvent.layout.width)) { -+ _this._dim.height = event.nativeEvent.layout.height; -+ _this._dim.width = event.nativeEvent.layout.width; -+ if (_this.props.onSizeChanged) { -+ _this.props.onSizeChanged(_this._dim, _this.props.index); -+ } -+ } -+ }; -+ return _this; -+ } -+ ViewRenderer.prototype.render = function () { -+ return this.props.forceNonDeterministicRendering ? (React.createElement(react_native_1.View, { ref: this._setRef, onLayout: this._onLayout, style: __assign({ flexDirection: this.props.isHorizontal ? "column" : "row", left: this.props.x, position: "absolute", top: this.props.y }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())) : (React.createElement(react_native_1.View, { ref: this._setRef, style: __assign({ left: this.props.x, position: "absolute", top: this.props.y, height: this.props.height, width: this.props.width }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())); -+ }; -+ ViewRenderer.prototype.getRef = function () { -+ return this._viewRef; -+ }; -+ return ViewRenderer; -+}(BaseViewRenderer_1.default)); -+exports.default = ViewRenderer; -+//# sourceMappingURL=ViewRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js.map -new file mode 100644 -index 0000000..ceacfb9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAC/B,6CAAuE;AAEvE,gFAAkG;AAElG;;;;;GAKG;AACH;IAA0C,gCAAqB;IAA/D;QAAA,qEAuDC;QAtDW,UAAI,GAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1C,cAAQ,GAAiE,IAAI,CAAC;QAmC9E,aAAO,GAAG,UAAC,IAAkE;YACjF,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,CAAC,CAAA;QAEO,eAAS,GAAG,UAAC,KAAwB;YACzC,qFAAqF;YACrF,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC;gBACtB,CAAC,KAAI,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;oBAClD,KAAI,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAC1D,KAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACnD,KAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;gBACjD,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;oBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAI,CAAC,IAAI,EAAE,KAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;iBACzD;aACJ;QACL,CAAC,CAAA;;IACL,CAAC;IApDU,6BAAM,GAAb;QACI,OAAO,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAC/C,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACvB,QAAQ,EAAE,IAAI,CAAC,SAAS,EACpB,KAAK,aACD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EACzD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IACd,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC,CAAC,CAAC,CACI,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACnB,KAAK,aACD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EACzB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IACpB,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC;IACV,CAAC;IAES,6BAAM,GAAhB;QACI,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAoBL,mBAAC;AAAD,CAAC,AAvDD,CAA0C,0BAAgB,GAuDzD"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts -new file mode 100644 -index 0000000..30681d9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts -@@ -0,0 +1,2 @@ -+import ViewRenderer from "../../web/viewrenderer/ViewRenderer"; -+export default ViewRenderer; -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js -new file mode 100644 -index 0000000..75c2c66 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js -@@ -0,0 +1,5 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ViewRenderer_1 = require("../../web/viewrenderer/ViewRenderer"); -+exports.default = ViewRenderer_1.default; -+//# sourceMappingURL=ViewRenderer.web.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js.map -new file mode 100644 -index 0000000..f50f385 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/reactnative/viewrenderer/ViewRenderer.web.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewRenderer.web.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.web.tsx"],"names":[],"mappings":";;AAAA,oEAA+D;AAC/D,kBAAe,sBAAY,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.d.ts -new file mode 100644 -index 0000000..1c1db85 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.d.ts -@@ -0,0 +1,15 @@ -+import { BaseItemAnimator } from "../../../core/ItemAnimator"; -+/** -+ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all -+ * shift events. -+ */ -+export declare class DefaultWebItemAnimator implements BaseItemAnimator { -+ shouldAnimateOnce: boolean; -+ private _hasAnimatedOnce; -+ private _isTimerOn; -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js -new file mode 100644 -index 0000000..3db93b4 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js -@@ -0,0 +1,54 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+/** -+ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all -+ * shift events. -+ */ -+var DefaultWebItemAnimator = /** @class */ (function () { -+ function DefaultWebItemAnimator() { -+ this.shouldAnimateOnce = true; -+ this._hasAnimatedOnce = false; -+ this._isTimerOn = false; -+ } -+ DefaultWebItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ DefaultWebItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ DefaultWebItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ this._hasAnimatedOnce = true; -+ }; -+ DefaultWebItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ var _this = this; -+ if (fromX !== toX || fromY !== toY) { -+ var element_1 = itemRef; -+ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { -+ var transitionEndCallback_1 = function (event) { -+ element_1.style.transition = ""; -+ element_1.removeEventListener("transitionend", transitionEndCallback_1); -+ _this._hasAnimatedOnce = true; -+ }; -+ element_1.style.transition = "transform 0.15s ease-out"; -+ element_1.addEventListener("transitionend", transitionEndCallback_1, false); -+ } -+ } -+ else { -+ if (!this._isTimerOn) { -+ this._isTimerOn = true; -+ if (!this._hasAnimatedOnce) { -+ setTimeout(function () { -+ _this._hasAnimatedOnce = true; -+ }, 1000); -+ } -+ } -+ } -+ return false; -+ }; -+ DefaultWebItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ return DefaultWebItemAnimator; -+}()); -+exports.DefaultWebItemAnimator = DefaultWebItemAnimator; -+//# sourceMappingURL=DefaultWebItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js.map -new file mode 100644 -index 0000000..44c688a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/itemanimators/DefaultWebItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultWebItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/web/itemanimators/DefaultWebItemAnimator.ts"],"names":[],"mappings":";;AAEA;;;GAGG;AACH;IAAA;QACW,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;IAwCxC,CAAC;IAvCU,iDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,gDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,kDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,6CAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAuBC;QAtBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAM,SAAO,GAAG,OAAyB,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,IAAM,uBAAqB,GAAkB,UAAC,KAAK;oBAC/C,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;oBAC9B,SAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,uBAAqB,CAAC,CAAC;oBACpE,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACjC,CAAC,CAAC;gBACF,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,0BAA0B,CAAC;gBACtD,SAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,uBAAqB,EAAE,KAAK,CAAC,CAAC;aAC3E;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,mDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,6BAAC;AAAD,CAAC,AA3CD,IA2CC;AA3CY,wDAAsB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.d.ts -new file mode 100644 -index 0000000..2188791 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.d.ts -@@ -0,0 +1,26 @@ -+/// -+import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; -+import ScrollViewer from "./ScrollViewer"; -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+export default class ScrollComponent extends BaseScrollComponent { -+ static defaultProps: { -+ contentHeight: number; -+ contentWidth: number; -+ externalScrollView: typeof ScrollViewer; -+ isHorizontal: boolean; -+ scrollThrottle: number; -+ canChangeSize: boolean; -+ }; -+ private _height; -+ private _width; -+ private _scrollViewRef; -+ constructor(args: ScrollComponentProps); -+ scrollTo(x: number, y: number, animated: boolean): void; -+ render(): JSX.Element; -+ private _onScroll; -+ private _onSizeChanged; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js -new file mode 100644 -index 0000000..dca7ab7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js -@@ -0,0 +1,82 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); -+var ScrollViewer_1 = require("./ScrollViewer"); -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+var ScrollComponent = /** @class */ (function (_super) { -+ __extends(ScrollComponent, _super); -+ function ScrollComponent(args) { -+ var _this = _super.call(this, args) || this; -+ _this._scrollViewRef = null; -+ _this._onScroll = function (e) { -+ _this.props.onScroll(e.nativeEvent.contentOffset.x, e.nativeEvent.contentOffset.y, e); -+ }; -+ _this._onSizeChanged = function (event) { -+ if (_this.props.onSizeChanged) { -+ _this.props.onSizeChanged(event); -+ } -+ }; -+ _this._height = 0; -+ _this._width = 0; -+ return _this; -+ } -+ ScrollComponent.prototype.scrollTo = function (x, y, animated) { -+ if (this._scrollViewRef) { -+ this._scrollViewRef.scrollTo({ x: x, y: y, animated: animated }); -+ } -+ }; -+ ScrollComponent.prototype.render = function () { -+ var _this = this; -+ var Scroller = this.props.externalScrollView; //TSI -+ return (React.createElement(Scroller, __assign({ ref: function (scrollView) { return _this._scrollViewRef = scrollView; } }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onSizeChanged: this._onSizeChanged }), -+ React.createElement("div", { style: { -+ height: this.props.contentHeight, -+ width: this.props.contentWidth, -+ } }, this.props.children), -+ this.props.renderFooter ? React.createElement("div", { style: this.props.isHorizontal ? { -+ left: this.props.contentWidth, -+ position: "absolute", -+ top: 0, -+ } : undefined }, this.props.renderFooter()) : null)); -+ }; -+ ScrollComponent.defaultProps = { -+ contentHeight: 0, -+ contentWidth: 0, -+ externalScrollView: ScrollViewer_1.default, -+ isHorizontal: false, -+ scrollThrottle: 16, -+ canChangeSize: false, -+ }; -+ return ScrollComponent; -+}(BaseScrollComponent_1.default)); -+exports.default = ScrollComponent; -+//# sourceMappingURL=ScrollComponent.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js.map -new file mode 100644 -index 0000000..5436601 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollComponent.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAE/B,yFAA8G;AAE9G,+CAA0C;AAC1C;;;;GAIG;AAEH;IAA6C,mCAAmB;IAa5D,yBAAY,IAA0B;QAAtC,YACI,kBAAM,IAAI,CAAC,SAGd;QANO,oBAAc,GAA0B,IAAI,CAAC;QAwC7C,eAAS,GAAG,UAAC,CAAc;YAC/B,KAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC,CAAA;QAEO,oBAAc,GAAG,UAAC,KAAgB;YACtC,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;gBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;aACnC;QACL,CAAC,CAAA;QA5CG,KAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,KAAI,CAAC,MAAM,GAAG,CAAC,CAAC;;IACpB,CAAC;IAEM,kCAAQ,GAAf,UAAgB,CAAS,EAAE,CAAS,EAAE,QAAiB;QACnD,IAAI,IAAI,CAAC,cAAc,EAAE;YACrB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE,QAAQ,UAAA,EAAE,CAAC,CAAC;SACpD;IACL,CAAC;IAEM,gCAAM,GAAb;QAAA,iBAwBC;QAvBG,IAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAyB,CAAC,CAAC,KAAK;QAC5D,OAAO,CACH,oBAAC,QAAQ,aAAC,GAAG,EAAE,UAAC,UAA0B,IAAK,OAAA,KAAI,CAAC,cAAc,GAAG,UAAqC,EAA3D,CAA2D,IAClG,IAAI,CAAC,KAAK,IACd,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EACnC,QAAQ,EAAE,IAAI,CAAC,SAAS,EACxB,aAAa,EAAE,IAAI,CAAC,cAAc;YAElC,6BAAK,KAAK,EAAE;oBACR,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;oBAChC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;iBACjC,IACI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAClB;YACL,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,6BAAK,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC7D,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;oBAC7B,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,CAAC;iBACT,CAAC,CAAC,CAAC,SAAS,IACR,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CACxB,CAAC,CAAC,CAAC,IAAI,CACN,CACd,CAAC;IACN,CAAC;IAhDa,4BAAY,GAAG;QACzB,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,kBAAkB,EAAE,sBAAY;QAChC,YAAY,EAAE,KAAK;QACnB,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,KAAK;KACvB,CAAC;IAoDN,sBAAC;CAAA,AA5DD,CAA6C,6BAAmB,GA4D/D;kBA5DoB,eAAe"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts -new file mode 100644 -index 0000000..5551eef ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts -@@ -0,0 +1,6 @@ -+import { ScrollEvent } from "../../../core/scrollcomponent/BaseScrollView"; -+export declare class ScrollEventNormalizer { -+ divEvent: ScrollEvent; -+ windowEvent: ScrollEvent; -+ constructor(target: HTMLDivElement); -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js -new file mode 100644 -index 0000000..d930364 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js -@@ -0,0 +1,65 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ScrollEventNormalizer = /** @class */ (function () { -+ function ScrollEventNormalizer(target) { -+ this.divEvent = { -+ nativeEvent: { -+ contentOffset: { -+ get x() { -+ return target.scrollLeft; -+ }, -+ get y() { -+ return target.scrollTop; -+ }, -+ }, -+ contentSize: { -+ get height() { -+ return target.scrollHeight; -+ }, -+ get width() { -+ return target.scrollWidth; -+ }, -+ }, -+ layoutMeasurement: { -+ get height() { -+ return target.offsetHeight; -+ }, -+ get width() { -+ return target.offsetWidth; -+ }, -+ }, -+ }, -+ }; -+ this.windowEvent = { -+ nativeEvent: { -+ contentOffset: { -+ get x() { -+ return window.scrollX === undefined ? window.pageXOffset : window.scrollX; -+ }, -+ get y() { -+ return window.scrollY === undefined ? window.pageYOffset : window.scrollY; -+ }, -+ }, -+ contentSize: { -+ get height() { -+ return target.offsetHeight; -+ }, -+ get width() { -+ return target.offsetWidth; -+ }, -+ }, -+ layoutMeasurement: { -+ get height() { -+ return window.innerHeight; -+ }, -+ get width() { -+ return window.innerWidth; -+ }, -+ }, -+ }, -+ }; -+ } -+ return ScrollEventNormalizer; -+}()); -+exports.ScrollEventNormalizer = ScrollEventNormalizer; -+//# sourceMappingURL=ScrollEventNormalizer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js.map -new file mode 100644 -index 0000000..52347ab ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollEventNormalizer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollEventNormalizer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollEventNormalizer.ts"],"names":[],"mappings":";;AAEA;IAGI,+BAAY,MAAsB;QAC9B,IAAI,CAAC,QAAQ,GAAG;YACZ,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,SAAS,CAAC;oBAC5B,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;aACJ;SACJ,CAAC;QACF,IAAI,CAAC,WAAW,GAAG;YACf,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;iBACJ;aACJ;SACJ,CAAC;IACN,CAAC;IACL,4BAAC;AAAD,CAAC,AA7DD,IA6DC;AA7DY,sDAAqB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.d.ts -new file mode 100644 -index 0000000..069cc18 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.d.ts -@@ -0,0 +1,38 @@ -+/// -+import BaseScrollView from "../../../core/scrollcomponent/BaseScrollView"; -+/*** -+ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. -+ * Supports both window scroll and scrollable divs inside other divs. -+ */ -+export default class ScrollViewer extends BaseScrollView { -+ static defaultProps: { -+ canChangeSize: boolean; -+ horizontal: boolean; -+ style: null; -+ useWindowScroll: boolean; -+ }; -+ private scrollEndEventSimulator; -+ private _mainDivRef; -+ private _isScrolling; -+ private _scrollEventNormalizer; -+ componentDidMount(): void; -+ componentWillUnmount(): void; -+ scrollTo(scrollInput: { -+ x: number; -+ y: number; -+ animated: boolean; -+ }): void; -+ render(): JSX.Element; -+ private _setDivRef; -+ private _getRelevantOffset; -+ private _setRelevantOffset; -+ private _isScrollEnd; -+ private _trackScrollOccurence; -+ private _doAnimatedScroll; -+ private _startListeningToDivEvents; -+ private _startListeningToWindowEvents; -+ private _onWindowResize; -+ private _windowOnScroll; -+ private _onScroll; -+ private _easeInOut; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js -new file mode 100644 -index 0000000..bdfd4e8 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js -@@ -0,0 +1,214 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollView_1 = require("../../../core/scrollcomponent/BaseScrollView"); -+var debounce = require("lodash.debounce"); -+var ScrollEventNormalizer_1 = require("./ScrollEventNormalizer"); -+/*** -+ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. -+ * Supports both window scroll and scrollable divs inside other divs. -+ */ -+var ScrollViewer = /** @class */ (function (_super) { -+ __extends(ScrollViewer, _super); -+ function ScrollViewer() { -+ var _this = _super !== null && _super.apply(this, arguments) || this; -+ _this.scrollEndEventSimulator = debounce(function (executable) { -+ executable(); -+ }, 1200); -+ _this._mainDivRef = null; -+ _this._isScrolling = false; -+ _this._scrollEventNormalizer = null; -+ _this._setDivRef = function (div) { -+ _this._mainDivRef = div; -+ if (div) { -+ _this._scrollEventNormalizer = new ScrollEventNormalizer_1.ScrollEventNormalizer(div); -+ } -+ else { -+ _this._scrollEventNormalizer = null; -+ } -+ }; -+ _this._getRelevantOffset = function () { -+ if (!_this.props.useWindowScroll) { -+ if (_this._mainDivRef) { -+ if (_this.props.horizontal) { -+ return _this._mainDivRef.scrollLeft; -+ } -+ else { -+ return _this._mainDivRef.scrollTop; -+ } -+ } -+ return 0; -+ } -+ else { -+ if (_this.props.horizontal) { -+ return window.scrollX; -+ } -+ else { -+ return window.scrollY; -+ } -+ } -+ }; -+ _this._setRelevantOffset = function (offset) { -+ if (!_this.props.useWindowScroll) { -+ if (_this._mainDivRef) { -+ if (_this.props.horizontal) { -+ _this._mainDivRef.scrollLeft = offset; -+ } -+ else { -+ _this._mainDivRef.scrollTop = offset; -+ } -+ } -+ } -+ else { -+ if (_this.props.horizontal) { -+ window.scrollTo(offset, 0); -+ } -+ else { -+ window.scrollTo(0, offset); -+ } -+ } -+ }; -+ _this._isScrollEnd = function () { -+ if (_this._mainDivRef) { -+ _this._mainDivRef.style.pointerEvents = "auto"; -+ } -+ _this._isScrolling = false; -+ }; -+ _this._trackScrollOccurence = function () { -+ if (!_this._isScrolling) { -+ if (_this._mainDivRef) { -+ _this._mainDivRef.style.pointerEvents = "none"; -+ } -+ _this._isScrolling = true; -+ } -+ _this.scrollEndEventSimulator(_this._isScrollEnd); -+ }; -+ _this._onWindowResize = function () { -+ if (_this.props.onSizeChanged && _this.props.useWindowScroll) { -+ _this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); -+ } -+ }; -+ _this._windowOnScroll = function () { -+ if (_this.props.onScroll) { -+ if (_this._scrollEventNormalizer) { -+ _this.props.onScroll(_this._scrollEventNormalizer.windowEvent); -+ } -+ } -+ }; -+ _this._onScroll = function () { -+ if (_this.props.onScroll) { -+ if (_this._scrollEventNormalizer) { -+ _this.props.onScroll(_this._scrollEventNormalizer.divEvent); -+ } -+ } -+ }; -+ return _this; -+ } -+ ScrollViewer.prototype.componentDidMount = function () { -+ if (this.props.onSizeChanged) { -+ if (this.props.useWindowScroll) { -+ this._startListeningToWindowEvents(); -+ this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); -+ } -+ else if (this._mainDivRef) { -+ this._startListeningToDivEvents(); -+ this.props.onSizeChanged({ height: this._mainDivRef.clientHeight, width: this._mainDivRef.clientWidth }); -+ } -+ } -+ }; -+ ScrollViewer.prototype.componentWillUnmount = function () { -+ window.removeEventListener("scroll", this._windowOnScroll); -+ if (this._mainDivRef) { -+ this._mainDivRef.removeEventListener("scroll", this._onScroll); -+ } -+ window.removeEventListener("resize", this._onWindowResize); -+ }; -+ ScrollViewer.prototype.scrollTo = function (scrollInput) { -+ if (scrollInput.animated) { -+ this._doAnimatedScroll(this.props.horizontal ? scrollInput.x : scrollInput.y); -+ } -+ else { -+ this._setRelevantOffset(this.props.horizontal ? scrollInput.x : scrollInput.y); -+ } -+ }; -+ ScrollViewer.prototype.render = function () { -+ return !this.props.useWindowScroll -+ ? React.createElement("div", { ref: this._setDivRef, style: __assign({ WebkitOverflowScrolling: "touch", height: "100%", overflowX: this.props.horizontal ? "scroll" : "hidden", overflowY: !this.props.horizontal ? "scroll" : "hidden", width: "100%" }, this.props.style) }, -+ React.createElement("div", { style: { position: "relative" } }, this.props.children)) -+ : React.createElement("div", { ref: this._setDivRef, style: __assign({ position: "relative" }, this.props.style) }, this.props.children); -+ }; -+ ScrollViewer.prototype._doAnimatedScroll = function (offset) { -+ var _this = this; -+ var start = this._getRelevantOffset(); -+ if (offset > start) { -+ start = Math.max(offset - 800, start); -+ } -+ else { -+ start = Math.min(offset + 800, start); -+ } -+ var change = offset - start; -+ var increment = 20; -+ var duration = 200; -+ var animateScroll = function (elapsedTime) { -+ elapsedTime += increment; -+ var position = _this._easeInOut(elapsedTime, start, change, duration); -+ _this._setRelevantOffset(position); -+ if (elapsedTime < duration) { -+ window.setTimeout(function () { return animateScroll(elapsedTime); }, increment); -+ } -+ }; -+ animateScroll(0); -+ }; -+ ScrollViewer.prototype._startListeningToDivEvents = function () { -+ if (this._mainDivRef) { -+ this._mainDivRef.addEventListener("scroll", this._onScroll); -+ } -+ }; -+ ScrollViewer.prototype._startListeningToWindowEvents = function () { -+ window.addEventListener("scroll", this._windowOnScroll); -+ if (this.props.canChangeSize) { -+ window.addEventListener("resize", this._onWindowResize); -+ } -+ }; -+ ScrollViewer.prototype._easeInOut = function (currentTime, start, change, duration) { -+ currentTime /= duration / 2; -+ if (currentTime < 1) { -+ return change / 2 * currentTime * currentTime + start; -+ } -+ currentTime -= 1; -+ return (-change) / 2 * (currentTime * (currentTime - 2) - 1) + start; -+ }; -+ ScrollViewer.defaultProps = { -+ canChangeSize: false, -+ horizontal: false, -+ style: null, -+ useWindowScroll: false, -+ }; -+ return ScrollViewer; -+}(BaseScrollView_1.default)); -+exports.default = ScrollViewer; -+//# sourceMappingURL=ScrollViewer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js.map -new file mode 100644 -index 0000000..ea465a9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/scrollcomponent/ScrollViewer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollViewer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollViewer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.d.ts -new file mode 100644 -index 0000000..76283f9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.d.ts -@@ -0,0 +1,19 @@ -+/// -+import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+export default class ViewRenderer extends BaseViewRenderer { -+ private _dim; -+ private _mainDiv; -+ componentDidMount(): void; -+ componentDidUpdate(): void; -+ render(): JSX.Element; -+ protected getRef(): object | null; -+ private _setRef; -+ private _getTransform; -+ private _checkSizeChange; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js -new file mode 100644 -index 0000000..81d8dc1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js -@@ -0,0 +1,98 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+var ViewRenderer = /** @class */ (function (_super) { -+ __extends(ViewRenderer, _super); -+ function ViewRenderer() { -+ var _this = _super !== null && _super.apply(this, arguments) || this; -+ _this._dim = { width: 0, height: 0 }; -+ _this._mainDiv = null; -+ _this._setRef = function (div) { -+ _this._mainDiv = div; -+ }; -+ return _this; -+ } -+ ViewRenderer.prototype.componentDidMount = function () { -+ if (_super.prototype.componentDidMount) { -+ _super.prototype.componentDidMount.call(this); -+ } -+ this._checkSizeChange(); -+ }; -+ ViewRenderer.prototype.componentDidUpdate = function () { -+ this._checkSizeChange(); -+ }; -+ ViewRenderer.prototype.render = function () { -+ var style = this.props.forceNonDeterministicRendering -+ ? __assign({ transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides) : __assign({ height: this.props.height, overflow: "hidden", width: this.props.width, transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides); -+ return (React.createElement("div", { ref: this._setRef, style: style }, this.renderChild())); -+ }; -+ ViewRenderer.prototype.getRef = function () { -+ return this._mainDiv; -+ }; -+ ViewRenderer.prototype._getTransform = function () { -+ return "translate(" + this.props.x + "px," + this.props.y + "px)"; -+ }; -+ ViewRenderer.prototype._checkSizeChange = function () { -+ if (this.props.forceNonDeterministicRendering && this.props.onSizeChanged) { -+ var mainDiv = this._mainDiv; -+ if (mainDiv) { -+ this._dim.width = mainDiv.clientWidth; -+ this._dim.height = mainDiv.clientHeight; -+ if (this.props.width !== this._dim.width || this.props.height !== this._dim.height) { -+ this.props.onSizeChanged(this._dim, this.props.index); -+ } -+ } -+ } -+ }; -+ return ViewRenderer; -+}(BaseViewRenderer_1.default)); -+exports.default = ViewRenderer; -+var styles = { -+ baseViewStyle: { -+ alignItems: "stretch", -+ borderWidth: 0, -+ borderStyle: "solid", -+ boxSizing: "border-box", -+ display: "flex", -+ flexDirection: "column", -+ margin: 0, -+ padding: 0, -+ position: "absolute", -+ minHeight: 0, -+ minWidth: 0, -+ left: 0, -+ top: 0, -+ }, -+}; -+//# sourceMappingURL=ViewRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js.map -new file mode 100644 -index 0000000..7810112 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/platform/web/viewrenderer/ViewRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/web/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.d.ts -new file mode 100644 -index 0000000..0bd1380 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.d.ts -@@ -0,0 +1,6 @@ -+export interface Scrollable { -+ scrollToOffset(x: number, y: number, animate: boolean): void; -+} -+export declare class AutoScroll { -+ static scrollNow(scrollable: Scrollable, fromX: number, fromY: number, toX: number, toY: number, speedMultiplier?: number): Promise; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js -new file mode 100644 -index 0000000..ab91ef0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js -@@ -0,0 +1,36 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var AutoScroll = /** @class */ (function () { -+ function AutoScroll() { -+ } -+ AutoScroll.scrollNow = function (scrollable, fromX, fromY, toX, toY, speedMultiplier) { -+ if (speedMultiplier === void 0) { speedMultiplier = 1; } -+ return new Promise(function (resolve) { -+ scrollable.scrollToOffset(fromX, fromY, false); -+ var incrementPerMs = 0.1 * speedMultiplier; -+ var startTime = Date.now(); -+ var startX = fromX; -+ var startY = fromY; -+ var animationLoop = function () { -+ requestAnimationFrame(function () { -+ var currentTime = Date.now(); -+ var timeElapsed = currentTime - startTime; -+ var distanceToCover = incrementPerMs * timeElapsed; -+ startX += distanceToCover; -+ startY += distanceToCover; -+ scrollable.scrollToOffset(Math.min(toX, startX), Math.min(toY, startY), false); -+ startTime = currentTime; -+ if (Math.min(toX, startX) !== toX || Math.min(toY, startY) !== toY) { -+ animationLoop(); -+ return; -+ } -+ resolve(); -+ }); -+ }; -+ animationLoop(); -+ }); -+ }; -+ return AutoScroll; -+}()); -+exports.AutoScroll = AutoScroll; -+//# sourceMappingURL=AutoScroll.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js.map -new file mode 100644 -index 0000000..86f9d26 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/AutoScroll.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"AutoScroll.js","sourceRoot":"","sources":["../../../src/utils/AutoScroll.ts"],"names":[],"mappings":";;AAGA;IAAA;IA2BA,CAAC;IA1BiB,oBAAS,GAAvB,UAAwB,UAAsB,EAAE,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,eAA2B;QAA3B,gCAAA,EAAA,mBAA2B;QAC/H,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO;YACvB,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAM,cAAc,GAAG,GAAG,GAAG,eAAe,CAAC;YAC7C,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAM,aAAa,GAAG;gBAClB,qBAAqB,CAAC;oBAClB,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC/B,IAAM,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;oBAC5C,IAAM,eAAe,GAAG,cAAc,GAAG,WAAW,CAAC;oBACrD,MAAM,IAAI,eAAe,CAAC;oBAC1B,MAAM,IAAI,eAAe,CAAC;oBAC1B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;oBAC/E,SAAS,GAAG,WAAW,CAAC;oBACxB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE;wBAChE,aAAa,EAAE,CAAC;wBAChB,OAAO;qBACV;oBACD,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,aAAa,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IACL,iBAAC;AAAD,CAAC,AA3BD,IA2BC;AA3BY,gCAAU"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.d.ts -new file mode 100644 -index 0000000..9365580 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.d.ts -@@ -0,0 +1,17 @@ -+export interface ValueAndIndex { -+ value: number; -+ index: number; -+} -+export default class BinarySearch { -+ static findClosestHigherValueIndex(size: number, targetValue: number, valueExtractor: (index: number) => number): number; -+ static findClosestValueToTarget(values: number[], target: number): ValueAndIndex; -+ /** -+ * Largest value from given values that is smaller or equal to the target number. -+ */ -+ static findValueSmallerThanTarget(values: number[], target: number): ValueAndIndex | undefined; -+ /** -+ * Smallest value from given values that is larger or equal to the target number. -+ */ -+ static findValueLargerThanTarget(values: number[], target: number): ValueAndIndex | undefined; -+ static findIndexOf(array: number[], value: number): number; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js -new file mode 100644 -index 0000000..74f37c5 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js -@@ -0,0 +1,154 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var CustomError_1 = require("../core/exceptions/CustomError"); -+var BinarySearch = /** @class */ (function () { -+ function BinarySearch() { -+ } -+ BinarySearch.findClosestHigherValueIndex = function (size, targetValue, valueExtractor) { -+ var low = 0; -+ var high = size - 1; -+ var mid = Math.floor((low + high) / 2); -+ var lastValue = 0; -+ var absoluteLastDiff = Math.abs(valueExtractor(mid) - targetValue); -+ var result = mid; -+ var diff = 0; -+ var absoluteDiff = 0; -+ if (absoluteLastDiff === 0) { -+ return result; -+ } -+ if (high < 0) { -+ throw new CustomError_1.default({ -+ message: "The collection cannot be empty", -+ type: "InvalidStateException", -+ }); -+ } -+ while (low <= high) { -+ mid = Math.floor((low + high) / 2); -+ lastValue = valueExtractor(mid); -+ diff = lastValue - targetValue; -+ absoluteDiff = Math.abs(diff); -+ if (diff >= 0 && absoluteDiff < absoluteLastDiff) { -+ absoluteLastDiff = absoluteDiff; -+ result = mid; -+ } -+ if (targetValue < lastValue) { -+ high = mid - 1; -+ } -+ else if (targetValue > lastValue) { -+ low = mid + 1; -+ } -+ else { -+ return mid; -+ } -+ } -+ return result; -+ }; -+ BinarySearch.findClosestValueToTarget = function (values, target) { -+ var low = 0; -+ var high = values.length - 1; -+ var mid = Math.floor((low + high) / 2); -+ var midValue = values[mid]; -+ var lastMidValue = midValue + 1; -+ while (low <= high && midValue !== lastMidValue) { -+ if (midValue === target) { -+ break; -+ } -+ else if (midValue < target) { -+ low = mid; -+ } -+ else if (midValue > target) { -+ high = mid; -+ } -+ mid = Math.floor((low + high) / 2); -+ lastMidValue = midValue; -+ midValue = values[mid]; -+ } -+ return { -+ value: midValue, -+ index: mid, -+ }; -+ }; -+ /** -+ * Largest value from given values that is smaller or equal to the target number. -+ */ -+ BinarySearch.findValueSmallerThanTarget = function (values, target) { -+ var low = 0; -+ var high = values.length - 1; -+ if (target >= values[high]) { -+ return { -+ value: values[high], -+ index: high, -+ }; -+ } -+ else if (target < values[low]) { -+ return undefined; -+ } -+ var midValueAndIndex = this.findClosestValueToTarget(values, target); -+ var midValue = midValueAndIndex.value; -+ var mid = midValueAndIndex.index; -+ if (midValue <= target) { -+ return { -+ value: midValue, -+ index: mid, -+ }; -+ } -+ else { -+ return { -+ value: values[mid - 1], -+ index: mid - 1, -+ }; -+ } -+ }; -+ /** -+ * Smallest value from given values that is larger or equal to the target number. -+ */ -+ BinarySearch.findValueLargerThanTarget = function (values, target) { -+ var low = 0; -+ var high = values.length - 1; -+ if (target < values[low]) { -+ return { -+ value: values[low], -+ index: low, -+ }; -+ } -+ else if (target > values[high]) { -+ return undefined; -+ } -+ var midValueAndIndex = this.findClosestValueToTarget(values, target); -+ var midValue = midValueAndIndex.value; -+ var mid = midValueAndIndex.index; -+ if (midValue >= target) { -+ return { -+ value: midValue, -+ index: mid, -+ }; -+ } -+ else { -+ return { -+ value: values[mid + 1], -+ index: mid + 1, -+ }; -+ } -+ }; -+ BinarySearch.findIndexOf = function (array, value) { -+ var j = 0; -+ var length = array.length; -+ var i = 0; -+ while (j < length) { -+ i = length + j - 1 >> 1; -+ if (value > array[i]) { -+ j = i + 1; -+ } -+ else if (value < array[i]) { -+ length = i; -+ } -+ else { -+ return i; -+ } -+ } -+ return -1; -+ }; -+ return BinarySearch; -+}()); -+exports.default = BinarySearch; -+//# sourceMappingURL=BinarySearch.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js.map -new file mode 100644 -index 0000000..8684678 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/BinarySearch.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BinarySearch.js","sourceRoot":"","sources":["../../../src/utils/BinarySearch.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.d.ts -new file mode 100644 -index 0000000..113cffc ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.d.ts -@@ -0,0 +1,15 @@ -+/*** -+ * Recycle pool for maintaining recyclable items, supports segregation by type as well. -+ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation -+ */ -+export default class RecycleItemPool { -+ private _recyclableObjectMap; -+ private _availabilitySet; -+ constructor(); -+ putRecycledObject(objectType: string | number, object: string): void; -+ getRecycledObject(objectType: string | number): string | undefined; -+ removeFromPool(object: string): boolean; -+ clearAll(): void; -+ private _getRelevantSet; -+ private _stringify; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js -new file mode 100644 -index 0000000..d1173ad ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js -@@ -0,0 +1,65 @@ -+"use strict"; -+/*** -+ * Recycle pool for maintaining recyclable items, supports segregation by type as well. -+ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation -+ */ -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecycleItemPool = /** @class */ (function () { -+ function RecycleItemPool() { -+ this._recyclableObjectMap = {}; -+ this._availabilitySet = {}; -+ } -+ RecycleItemPool.prototype.putRecycledObject = function (objectType, object) { -+ objectType = this._stringify(objectType); -+ var objectSet = this._getRelevantSet(objectType); -+ if (!this._availabilitySet[object]) { -+ objectSet[object] = null; -+ this._availabilitySet[object] = objectType; -+ } -+ }; -+ RecycleItemPool.prototype.getRecycledObject = function (objectType) { -+ objectType = this._stringify(objectType); -+ var objectSet = this._getRelevantSet(objectType); -+ var recycledObject; -+ for (var property in objectSet) { -+ if (objectSet.hasOwnProperty(property)) { -+ recycledObject = property; -+ break; -+ } -+ } -+ if (recycledObject) { -+ delete objectSet[recycledObject]; -+ delete this._availabilitySet[recycledObject]; -+ } -+ return recycledObject; -+ }; -+ RecycleItemPool.prototype.removeFromPool = function (object) { -+ if (this._availabilitySet[object]) { -+ delete this._getRelevantSet(this._availabilitySet[object])[object]; -+ delete this._availabilitySet[object]; -+ return true; -+ } -+ return false; -+ }; -+ RecycleItemPool.prototype.clearAll = function () { -+ this._recyclableObjectMap = {}; -+ this._availabilitySet = {}; -+ }; -+ RecycleItemPool.prototype._getRelevantSet = function (objectType) { -+ var objectSet = this._recyclableObjectMap[objectType]; -+ if (!objectSet) { -+ objectSet = {}; -+ this._recyclableObjectMap[objectType] = objectSet; -+ } -+ return objectSet; -+ }; -+ RecycleItemPool.prototype._stringify = function (objectType) { -+ if (typeof objectType === "number") { -+ objectType = objectType.toString(); -+ } -+ return objectType; -+ }; -+ return RecycleItemPool; -+}()); -+exports.default = RecycleItemPool; -+//# sourceMappingURL=RecycleItemPool.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js.map -new file mode 100644 -index 0000000..2dde95b ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/RecycleItemPool.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"RecycleItemPool.js","sourceRoot":"","sources":["../../../src/utils/RecycleItemPool.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH;IAII;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B,EAAE,MAAc;QAChE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAChC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;SAC9C;IACL,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B;QAChD,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC;QACnB,KAAK,IAAM,QAAQ,IAAI,SAAS,EAAE;YAC9B,IAAI,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;gBACpC,cAAc,GAAG,QAAQ,CAAC;gBAC1B,MAAM;aACT;SACJ;QAED,IAAI,cAAc,EAAE;YAChB,OAAO,SAAS,CAAC,cAAc,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;SAChD;QACD,OAAO,cAAc,CAAC;IAC1B,CAAC;IAEM,wCAAc,GAArB,UAAsB,MAAc;QAChC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;SACf;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,kCAAQ,GAAf;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEO,yCAAe,GAAvB,UAAwB,UAAkB;QACtC,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE;YACZ,SAAS,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;SACrD;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,oCAAU,GAAlB,UAAmB,UAA2B;QAC1C,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;YAChC,UAAU,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC;SACtC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;IACL,sBAAC;AAAD,CAAC,AAjED,IAiEC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.d.ts b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.d.ts -new file mode 100644 -index 0000000..d867c7e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.d.ts -@@ -0,0 +1,3 @@ -+export default class TSCast { -+ static cast(object: any): T; -+} -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js -new file mode 100644 -index 0000000..526f93a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js -@@ -0,0 +1,12 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var TSCast = /** @class */ (function () { -+ function TSCast() { -+ } -+ TSCast.cast = function (object) { -+ return object; -+ }; -+ return TSCast; -+}()); -+exports.default = TSCast; -+//# sourceMappingURL=TSCast.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js.map b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js.map -new file mode 100644 -index 0000000..3384c98 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/reactnative/utils/TSCast.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"TSCast.js","sourceRoot":"","sources":["../../../src/utils/TSCast.ts"],"names":[],"mappings":";;AAAA;IAAA;IAIA,CAAC;IAHiB,WAAI,GAAlB,UAAsB,MAAW;QAC7B,OAAO,MAAW,CAAC;IACvB,CAAC;IACL,aAAC;AAAD,CAAC,AAJD,IAIC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/ItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.d.ts -new file mode 100644 -index 0000000..dd0e11c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.d.ts -@@ -0,0 +1,15 @@ -+export default interface ItemAnimator { -+ animateWillMount: (atX: number, atY: number, itemIndex: number) => object | undefined; -+ animateDidMount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; -+ animateWillUpdate: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => void; -+ animateShift: (fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number) => boolean; -+ animateWillUnmount: (atX: number, atY: number, itemRef: object, itemIndex: number) => void; -+} -+export declare class BaseItemAnimator implements ItemAnimator { -+ static USE_NATIVE_DRIVER: boolean; -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js -new file mode 100644 -index 0000000..0ae5165 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js -@@ -0,0 +1,25 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var BaseItemAnimator = /** @class */ (function () { -+ function BaseItemAnimator() { -+ } -+ BaseItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ BaseItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ BaseItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ //no need -+ }; -+ BaseItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ return false; -+ }; -+ BaseItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ BaseItemAnimator.USE_NATIVE_DRIVER = true; -+ return BaseItemAnimator; -+}()); -+exports.BaseItemAnimator = BaseItemAnimator; -+//# sourceMappingURL=ItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js.map -new file mode 100644 -index 0000000..732604a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ItemAnimator.js","sourceRoot":"","sources":["../../../src/core/ItemAnimator.ts"],"names":[],"mappings":";;AAwBA;IAAA;IAoBA,CAAC;IAlBU,2CAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,0CAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,4CAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,SAAS;IACb,CAAC;IAEM,uCAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC1G,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,6CAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IAlBa,kCAAiB,GAAG,IAAI,CAAC;IAmB3C,uBAAC;CAAA,AApBD,IAoBC;AApBY,4CAAgB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.d.ts b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.d.ts -new file mode 100644 -index 0000000..c30743a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.d.ts -@@ -0,0 +1,27 @@ -+import RecyclerListView, { RecyclerListViewProps, RecyclerListViewState } from "./RecyclerListView"; -+export interface ProgressiveListViewProps extends RecyclerListViewProps { -+ maxRenderAhead?: number; -+ renderAheadStep?: number; -+} -+/** -+ * This will incremently update renderAhread distance and render the page progressively. -+ */ -+export default class ProgressiveListView extends RecyclerListView { -+ static defaultProps: { -+ maxRenderAhead: number; -+ renderAheadStep: number; -+ renderAheadOffset: number; -+ canChangeSize: boolean; -+ disableRecycling: boolean; -+ initialOffset: number; -+ initialRenderIndex: number; -+ isHorizontal: boolean; -+ onEndReachedThreshold: number; -+ distanceFromWindow: number; -+ }; -+ private renderAheadUdpateCallbackId?; -+ componentDidMount(): void; -+ private updateRenderAheadProgessively; -+ private incrementRenderAhead; -+ private cancelRenderAheadUpdate; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js -new file mode 100644 -index 0000000..9176a38 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js -@@ -0,0 +1,77 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecyclerListView_1 = require("./RecyclerListView"); -+/** -+ * This will incremently update renderAhread distance and render the page progressively. -+ */ -+var ProgressiveListView = /** @class */ (function (_super) { -+ __extends(ProgressiveListView, _super); -+ function ProgressiveListView() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ ProgressiveListView.prototype.componentDidMount = function () { -+ if (_super.prototype.componentDidMount) { -+ _super.prototype.componentDidMount.call(this); -+ } -+ this.updateRenderAheadProgessively(this.getCurrentRenderAheadOffset()); -+ }; -+ ProgressiveListView.prototype.updateRenderAheadProgessively = function (newVal) { -+ var _this = this; -+ this.cancelRenderAheadUpdate(); // Cancel any pending callback. -+ this.renderAheadUdpateCallbackId = requestAnimationFrame(function () { -+ if (!_this.updateRenderAheadOffset(newVal)) { -+ _this.updateRenderAheadProgessively(newVal); -+ } -+ else { -+ _this.incrementRenderAhead(); -+ } -+ }); -+ }; -+ ProgressiveListView.prototype.incrementRenderAhead = function () { -+ if (this.props.maxRenderAhead && this.props.renderAheadStep) { -+ var layoutManager = this.getVirtualRenderer().getLayoutManager(); -+ var currentRenderAheadOffset = this.getCurrentRenderAheadOffset(); -+ if (layoutManager) { -+ var contentDimension = layoutManager.getContentDimension(); -+ var maxContentSize = this.props.isHorizontal ? contentDimension.width : contentDimension.height; -+ if (currentRenderAheadOffset < maxContentSize && currentRenderAheadOffset < this.props.maxRenderAhead) { -+ var newRenderAheadOffset = currentRenderAheadOffset + this.props.renderAheadStep; -+ this.updateRenderAheadProgessively(newRenderAheadOffset); -+ } -+ } -+ } -+ }; -+ ProgressiveListView.prototype.cancelRenderAheadUpdate = function () { -+ if (this.renderAheadUdpateCallbackId) { -+ cancelAnimationFrame(this.renderAheadUdpateCallbackId); -+ } -+ }; -+ ProgressiveListView.defaultProps = __assign({}, RecyclerListView_1.default.defaultProps, { maxRenderAhead: Number.MAX_VALUE, renderAheadStep: 300, renderAheadOffset: 0 }); -+ return ProgressiveListView; -+}(RecyclerListView_1.default)); -+exports.default = ProgressiveListView; -+//# sourceMappingURL=ProgressiveListView.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js.map b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js.map -new file mode 100644 -index 0000000..c9c3fd6 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ProgressiveListView.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ProgressiveListView.js","sourceRoot":"","sources":["../../../src/core/ProgressiveListView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uDAAoG;AAKpG;;GAEG;AACH;IAAiD,uCAAiE;IAAlH;;IA+CA,CAAC;IAtCU,+CAAiB,GAAxB;QACI,IAAI,iBAAM,iBAAiB,EAAE;YACzB,iBAAM,iBAAiB,WAAE,CAAC;SAC7B;QACD,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,CAAC;IAC3E,CAAC;IAEO,2DAA6B,GAArC,UAAsC,MAAc;QAApD,iBASC;QARG,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,+BAA+B;QAC/D,IAAI,CAAC,2BAA2B,GAAG,qBAAqB,CAAC;YACrD,IAAI,CAAC,KAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE;gBACvC,KAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;aAC9C;iBAAM;gBACH,KAAI,CAAC,oBAAoB,EAAE,CAAC;aAC/B;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kDAAoB,GAA5B;QACI,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;YACzD,IAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACnE,IAAM,wBAAwB,GAAG,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACpE,IAAI,aAAa,EAAE;gBACf,IAAM,gBAAgB,GAAG,aAAa,CAAC,mBAAmB,EAAE,CAAC;gBAC7D,IAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAClG,IAAI,wBAAwB,GAAG,cAAc,IAAI,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;oBACnG,IAAM,oBAAoB,GAAG,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;oBACnF,IAAI,CAAC,6BAA6B,CAAC,oBAAoB,CAAC,CAAC;iBAC5D;aACJ;SACJ;IACL,CAAC;IAEO,qDAAuB,GAA/B;QACI,IAAI,IAAI,CAAC,2BAA2B,EAAE;YAClC,oBAAoB,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;SAC1D;IACL,CAAC;IA7Ca,gCAAY,gBACnB,0BAAgB,CAAC,YAAY,IAChC,cAAc,EAAE,MAAM,CAAC,SAAS,EAChC,eAAe,EAAE,GAAG,EACpB,iBAAiB,EAAE,CAAC,IACtB;IAyCN,0BAAC;CAAA,AA/CD,CAAiD,0BAAgB,GA+ChE;kBA/CoB,mBAAmB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/RecyclerListView.d.ts b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.d.ts -new file mode 100644 -index 0000000..0bd8189 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.d.ts -@@ -0,0 +1,126 @@ -+import * as React from "react"; -+import ContextProvider from "./dependencies/ContextProvider"; -+import { BaseDataProvider } from "./dependencies/DataProvider"; -+import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; -+import { Layout } from "./layoutmanager/LayoutManager"; -+import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./scrollcomponent/BaseScrollView"; -+import { TOnItemStatusChanged } from "./ViewabilityTracker"; -+import VirtualRenderer, { RenderStack } from "./VirtualRenderer"; -+import ItemAnimator from "./ItemAnimator"; -+import { DebugHandlers } from ".."; -+/*** -+ * This is the main component, please refer to samples to understand how to use. -+ * For advanced usage check out prop descriptions below. -+ * You also get common methods such as: scrollToIndex, scrollToItem, scrollToTop, scrollToEnd, scrollToOffset, getCurrentScrollOffset, -+ * findApproxFirstVisibleIndex. -+ * You'll need a ref to Recycler in order to call these -+ * Needs to have bounded size in all cases other than window scrolling (web). -+ * -+ * NOTE: React Native implementation uses ScrollView internally which means you get all ScrollView features as well such as Pull To Refresh, paging enabled -+ * You can easily create a recycling image flip view using one paging enabled flag. Read about ScrollView features in official -+ * react native documentation. -+ * NOTE: If you see blank space look at the renderAheadOffset prop and make sure your data provider has a good enough rowHasChanged method. -+ * Blanks are totally avoidable with this listview. -+ * NOTE: Also works on web (experimental) -+ * NOTE: For reflowability set canChangeSize to true (experimental) -+ */ -+export interface OnRecreateParams { -+ lastOffset?: number; -+} -+export interface RecyclerListViewProps { -+ layoutProvider: BaseLayoutProvider; -+ dataProvider: BaseDataProvider; -+ rowRenderer: (type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+ contextProvider?: ContextProvider; -+ renderAheadOffset?: number; -+ isHorizontal?: boolean; -+ onScroll?: (rawEvent: ScrollEvent, offsetX: number, offsetY: number) => void; -+ onRecreate?: (params: OnRecreateParams) => void; -+ onEndReached?: () => void; -+ onEndReachedThreshold?: number; -+ onVisibleIndexesChanged?: TOnItemStatusChanged; -+ onVisibleIndicesChanged?: TOnItemStatusChanged; -+ renderFooter?: () => JSX.Element | JSX.Element[] | null; -+ externalScrollView?: { -+ new (props: ScrollViewDefaultProps): BaseScrollView; -+ }; -+ initialOffset?: number; -+ initialRenderIndex?: number; -+ scrollThrottle?: number; -+ canChangeSize?: boolean; -+ distanceFromWindow?: number; -+ useWindowScroll?: boolean; -+ disableRecycling?: boolean; -+ forceNonDeterministicRendering?: boolean; -+ extendedState?: object; -+ itemAnimator?: ItemAnimator; -+ optimizeForInsertDeleteAnimations?: boolean; -+ style?: object | number; -+ debugHandlers?: DebugHandlers; -+ scrollViewProps?: object; -+} -+export interface RecyclerListViewState { -+ renderStack: RenderStack; -+ internalSnapshot: Record; -+} -+export default class RecyclerListView

extends React.Component { -+ static defaultProps: { -+ canChangeSize: boolean; -+ disableRecycling: boolean; -+ initialOffset: number; -+ initialRenderIndex: number; -+ isHorizontal: boolean; -+ onEndReachedThreshold: number; -+ distanceFromWindow: number; -+ renderAheadOffset: number; -+ }; -+ static propTypes: {}; -+ private refreshRequestDebouncer; -+ private _virtualRenderer; -+ private _onEndReachedCalled; -+ private _initComplete; -+ private _relayoutReqIndex; -+ private _params; -+ private _layout; -+ private _pendingScrollToOffset; -+ private _tempDim; -+ private _initialOffset; -+ private _cachedLayouts?; -+ private _scrollComponent; -+ private _defaultItemAnimator; -+ constructor(props: P, context?: any); -+ componentWillReceiveProps(newProps: RecyclerListViewProps): void; -+ componentDidUpdate(): void; -+ componentWillUnmount(): void; -+ componentWillMount(): void; -+ scrollToIndex(index: number, animate?: boolean): void; -+ scrollToItem(data: any, animate?: boolean): void; -+ getLayout(index: number): Layout | undefined; -+ scrollToTop(animate?: boolean): void; -+ scrollToEnd(animate?: boolean): void; -+ scrollToOffset: (x: number, y: number, animate?: boolean) => void; -+ updateRenderAheadOffset(renderAheadOffset: number): boolean; -+ getCurrentRenderAheadOffset(): number; -+ getCurrentScrollOffset(): number; -+ findApproxFirstVisibleIndex(): number; -+ getRenderedSize(): Dimension; -+ getContentDimension(): Dimension; -+ forceRerender(): void; -+ render(): JSX.Element; -+ protected getVirtualRenderer(): VirtualRenderer; -+ private _checkAndChangeLayouts; -+ private _refreshViewability; -+ private _queueStateRefresh; -+ private _onSizeChanged; -+ private _renderStackWhenReady; -+ private _initTrackers; -+ private _assertDependencyPresence; -+ private _assertType; -+ private _dataHasChanged; -+ private _renderRowUsingMeta; -+ private _onViewContainerSizeChange; -+ private _checkExpectedDimensionDiscrepancy; -+ private _generateRenderStack; -+ private _onScroll; -+ private _processOnEndReached; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js -new file mode 100644 -index 0000000..e27cdf6 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js -@@ -0,0 +1,586 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+/*** -+ * DONE: Reduce layout processing on data insert -+ * DONE: Add notify data set changed and notify data insert option in data source -+ * DONE: Add on end reached callback -+ * DONE: Make another class for render stack generator -+ * DONE: Simplify rendering a loading footer -+ * DONE: Anchor first visible index on any insert/delete data wise -+ * DONE: Build Scroll to index -+ * DONE: Give viewability callbacks -+ * DONE: Add full render logic in cases like change of dimensions -+ * DONE: Fix all proptypes -+ * DONE: Add Initial render Index support -+ * DONE: Add animated scroll to web scrollviewer -+ * DONE: Animate list view transition, including add/remove -+ * DONE: Implement sticky headers and footers -+ * TODO: Destroy less frequently used items in recycle pool, this will help in case of too many types. -+ * TODO: Make viewability callbacks configurable -+ * TODO: Observe size changes on web to optimize for reflowability -+ * TODO: Solve //TSI -+ */ -+var debounce = require("lodash.debounce"); -+var PropTypes = require("prop-types"); -+var React = require("react"); -+var ts_object_utils_1 = require("ts-object-utils"); -+var ContextProvider_1 = require("./dependencies/ContextProvider"); -+var DataProvider_1 = require("./dependencies/DataProvider"); -+var LayoutProvider_1 = require("./dependencies/LayoutProvider"); -+var CustomError_1 = require("./exceptions/CustomError"); -+var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); -+var Constants_1 = require("./constants/Constants"); -+var Messages_1 = require("./constants/Messages"); -+var VirtualRenderer_1 = require("./VirtualRenderer"); -+var ItemAnimator_1 = require("./ItemAnimator"); -+//#if [REACT-NATIVE] -+//import ScrollComponent from "../platform/reactnative/scrollcomponent/ScrollComponent"; -+//import ViewRenderer from "../platform/reactnative/viewrenderer/ViewRenderer"; -+//import { DefaultJSItemAnimator as DefaultItemAnimator } from "../platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator"; -+//import { Platform } from "react-native"; -+//const IS_WEB = !Platform || Platform.OS === "web"; -+//#endif -+/*** -+ * To use on web, start importing from recyclerlistview/web. To make it even easier specify an alias in you builder of choice. -+ */ -+//#if [WEB] -+var ScrollComponent_1 = require("../platform/web/scrollcomponent/ScrollComponent"); -+var ViewRenderer_1 = require("../platform/web/viewrenderer/ViewRenderer"); -+var DefaultWebItemAnimator_1 = require("../platform/web/itemanimators/DefaultWebItemAnimator"); -+var IS_WEB = true; -+var RecyclerListView = /** @class */ (function (_super) { -+ __extends(RecyclerListView, _super); -+ function RecyclerListView(props, context) { -+ var _this = _super.call(this, props, context) || this; -+ _this.refreshRequestDebouncer = debounce(function (executable) { -+ executable(); -+ }); -+ _this._onEndReachedCalled = false; -+ _this._initComplete = false; -+ _this._relayoutReqIndex = -1; -+ _this._params = { -+ initialOffset: 0, -+ initialRenderIndex: 0, -+ isHorizontal: false, -+ itemCount: 0, -+ renderAheadOffset: 250, -+ }; -+ _this._layout = { height: 0, width: 0 }; -+ _this._pendingScrollToOffset = null; -+ _this._tempDim = { height: 0, width: 0 }; -+ _this._initialOffset = 0; -+ _this._scrollComponent = null; -+ _this._defaultItemAnimator = new DefaultWebItemAnimator_1.DefaultWebItemAnimator(); -+ _this.scrollToOffset = function (x, y, animate) { -+ if (animate === void 0) { animate = false; } -+ if (_this._scrollComponent) { -+ if (_this.props.isHorizontal) { -+ y = 0; -+ } -+ else { -+ x = 0; -+ } -+ _this._scrollComponent.scrollTo(x, y, animate); -+ } -+ }; -+ _this._onSizeChanged = function (layout) { -+ var hasHeightChanged = _this._layout.height !== layout.height; -+ var hasWidthChanged = _this._layout.width !== layout.width; -+ _this._layout.height = layout.height; -+ _this._layout.width = layout.width; -+ if (layout.height === 0 || layout.width === 0) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.layoutException); -+ } -+ if (!_this._initComplete) { -+ _this._initComplete = true; -+ _this._initTrackers(); -+ _this._processOnEndReached(); -+ } -+ else { -+ if ((hasHeightChanged && hasWidthChanged) || -+ (hasHeightChanged && _this.props.isHorizontal) || -+ (hasWidthChanged && !_this.props.isHorizontal)) { -+ _this._checkAndChangeLayouts(_this.props, true); -+ } -+ else { -+ _this._refreshViewability(); -+ } -+ } -+ }; -+ _this._renderStackWhenReady = function (stack) { -+ _this.setState(function () { -+ return { renderStack: stack }; -+ }); -+ }; -+ _this._dataHasChanged = function (row1, row2) { -+ return _this.props.dataProvider.rowHasChanged(row1, row2); -+ }; -+ _this._onViewContainerSizeChange = function (dim, index) { -+ //Cannot be null here -+ var layoutManager = _this._virtualRenderer.getLayoutManager(); -+ if (_this.props.debugHandlers && _this.props.debugHandlers.resizeDebugHandler) { -+ var itemRect = layoutManager.getLayouts()[index]; -+ _this.props.debugHandlers.resizeDebugHandler.resizeDebug({ -+ width: itemRect.width, -+ height: itemRect.height, -+ }, dim, index); -+ } -+ if (layoutManager.overrideLayout(index, dim)) { -+ if (_this._relayoutReqIndex === -1) { -+ _this._relayoutReqIndex = index; -+ } -+ else { -+ _this._relayoutReqIndex = Math.min(_this._relayoutReqIndex, index); -+ } -+ _this._queueStateRefresh(); -+ } -+ }; -+ _this._onScroll = function (offsetX, offsetY, rawEvent) { -+ //Adjusting offsets using distanceFromWindow -+ _this._virtualRenderer.updateOffset(offsetX, offsetY, -_this.props.distanceFromWindow, true); -+ if (_this.props.onScroll) { -+ _this.props.onScroll(rawEvent, offsetX, offsetY); -+ } -+ _this._processOnEndReached(); -+ }; -+ _this._virtualRenderer = new VirtualRenderer_1.default(_this._renderStackWhenReady, function (offset) { -+ _this._pendingScrollToOffset = offset; -+ }, function (index) { -+ return _this.props.dataProvider.getStableId(index); -+ }, !props.disableRecycling); -+ _this.state = { -+ internalSnapshot: {}, -+ renderStack: {}, -+ }; -+ return _this; -+ } -+ RecyclerListView.prototype.componentWillReceiveProps = function (newProps) { -+ this._assertDependencyPresence(newProps); -+ this._checkAndChangeLayouts(newProps); -+ if (!this.props.onVisibleIndicesChanged) { -+ this._virtualRenderer.removeVisibleItemsListener(); -+ } -+ if (this.props.onVisibleIndexesChanged) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); -+ } -+ if (this.props.onVisibleIndicesChanged) { -+ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); -+ } -+ }; -+ RecyclerListView.prototype.componentDidUpdate = function () { -+ var _this = this; -+ if (this._pendingScrollToOffset) { -+ var offset_1 = this._pendingScrollToOffset; -+ this._pendingScrollToOffset = null; -+ if (this.props.isHorizontal) { -+ offset_1.y = 0; -+ } -+ else { -+ offset_1.x = 0; -+ } -+ setTimeout(function () { -+ _this.scrollToOffset(offset_1.x, offset_1.y, false); -+ }, 0); -+ } -+ this._processOnEndReached(); -+ this._checkAndChangeLayouts(this.props); -+ if (this.props.dataProvider.getSize() === 0) { -+ console.warn(Messages_1.Messages.WARN_NO_DATA); //tslint:disable-line -+ } -+ }; -+ RecyclerListView.prototype.componentWillUnmount = function () { -+ if (this.props.contextProvider) { -+ var uniqueKey = this.props.contextProvider.getUniqueKey(); -+ if (uniqueKey) { -+ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX, this.getCurrentScrollOffset()); -+ if (this.props.forceNonDeterministicRendering) { -+ if (this._virtualRenderer) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ var layoutsToCache = layoutManager.getLayouts(); -+ this.props.contextProvider.save(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX, JSON.stringify({ layoutArray: layoutsToCache })); -+ } -+ } -+ } -+ } -+ } -+ }; -+ RecyclerListView.prototype.componentWillMount = function () { -+ if (this.props.contextProvider) { -+ var uniqueKey = this.props.contextProvider.getUniqueKey(); -+ if (uniqueKey) { -+ var offset = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); -+ if (typeof offset === "number" && offset > 0) { -+ this._initialOffset = offset; -+ if (this.props.onRecreate) { -+ this.props.onRecreate({ lastOffset: this._initialOffset }); -+ } -+ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX); -+ } -+ if (this.props.forceNonDeterministicRendering) { -+ var cachedLayouts = this.props.contextProvider.get(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); -+ if (cachedLayouts && typeof cachedLayouts === "string") { -+ this._cachedLayouts = JSON.parse(cachedLayouts).layoutArray; -+ this.props.contextProvider.remove(uniqueKey + Constants_1.Constants.CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX); -+ } -+ } -+ } -+ } -+ }; -+ RecyclerListView.prototype.scrollToIndex = function (index, animate) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ var offsets = layoutManager.getOffsetForIndex(index); -+ this.scrollToOffset(offsets.x, offsets.y, animate); -+ } -+ else { -+ console.warn(Messages_1.Messages.WARN_SCROLL_TO_INDEX); //tslint:disable-line -+ } -+ }; -+ RecyclerListView.prototype.scrollToItem = function (data, animate) { -+ var count = this.props.dataProvider.getSize(); -+ for (var i = 0; i < count; i++) { -+ if (this.props.dataProvider.getDataForIndex(i) === data) { -+ this.scrollToIndex(i, animate); -+ break; -+ } -+ } -+ }; -+ RecyclerListView.prototype.getLayout = function (index) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ return layoutManager ? layoutManager.getLayouts()[index] : undefined; -+ }; -+ RecyclerListView.prototype.scrollToTop = function (animate) { -+ this.scrollToOffset(0, 0, animate); -+ }; -+ RecyclerListView.prototype.scrollToEnd = function (animate) { -+ var lastIndex = this.props.dataProvider.getSize() - 1; -+ this.scrollToIndex(lastIndex, animate); -+ }; -+ // You can use requestAnimationFrame callback to change renderAhead in multiple frames to enable advanced progressive -+ // rendering when view types are very complex. This method returns a boolean saying if the update was committed. Retry in -+ // the next frame if you get a failure (if mount wasn't complete). Value should be greater than or equal to 0; -+ // Very useful when you have a page where you need a large renderAheadOffset. Setting it at once will slow down the load and -+ // this will help mitigate that. -+ RecyclerListView.prototype.updateRenderAheadOffset = function (renderAheadOffset) { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ if (viewabilityTracker) { -+ viewabilityTracker.updateRenderAheadOffset(renderAheadOffset); -+ return true; -+ } -+ return false; -+ }; -+ RecyclerListView.prototype.getCurrentRenderAheadOffset = function () { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ if (viewabilityTracker) { -+ return viewabilityTracker.getCurrentRenderAheadOffset(); -+ } -+ return this.props.renderAheadOffset; -+ }; -+ RecyclerListView.prototype.getCurrentScrollOffset = function () { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ return viewabilityTracker ? viewabilityTracker.getLastActualOffset() : 0; -+ }; -+ RecyclerListView.prototype.findApproxFirstVisibleIndex = function () { -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ return viewabilityTracker ? viewabilityTracker.findFirstLogicallyVisibleIndex() : 0; -+ }; -+ RecyclerListView.prototype.getRenderedSize = function () { -+ return this._layout; -+ }; -+ RecyclerListView.prototype.getContentDimension = function () { -+ return this._virtualRenderer.getLayoutDimension(); -+ }; -+ // Force Rerender forcefully to update view renderer. Use this in rare circumstances -+ RecyclerListView.prototype.forceRerender = function () { -+ this.setState({ -+ internalSnapshot: {}, -+ }); -+ }; -+ RecyclerListView.prototype.render = function () { -+ //TODO:Talha -+ // const { -+ // layoutProvider, -+ // dataProvider, -+ // contextProvider, -+ // renderAheadOffset, -+ // onEndReached, -+ // onEndReachedThreshold, -+ // onVisibleIndicesChanged, -+ // initialOffset, -+ // initialRenderIndex, -+ // disableRecycling, -+ // forceNonDeterministicRendering, -+ // extendedState, -+ // itemAnimator, -+ // rowRenderer, -+ // ...props, -+ // } = this.props; -+ var _this = this; -+ return (React.createElement(ScrollComponent_1.default, __assign({ ref: function (scrollComponent) { return _this._scrollComponent = scrollComponent; } }, this.props, this.props.scrollViewProps, { onScroll: this._onScroll, onSizeChanged: this._onSizeChanged, contentHeight: this._initComplete ? this._virtualRenderer.getLayoutDimension().height : 0, contentWidth: this._initComplete ? this._virtualRenderer.getLayoutDimension().width : 0 }), this._generateRenderStack())); -+ }; -+ RecyclerListView.prototype.getVirtualRenderer = function () { -+ return this._virtualRenderer; -+ }; -+ RecyclerListView.prototype._checkAndChangeLayouts = function (newProps, forceFullRender) { -+ this._params.isHorizontal = newProps.isHorizontal; -+ this._params.itemCount = newProps.dataProvider.getSize(); -+ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); -+ this._virtualRenderer.setLayoutProvider(newProps.layoutProvider); -+ if (newProps.dataProvider.hasStableIds() && this.props.dataProvider !== newProps.dataProvider && newProps.dataProvider.requiresDataChangeHandling()) { -+ this._virtualRenderer.handleDataSetChange(newProps.dataProvider, this.props.optimizeForInsertDeleteAnimations); -+ } -+ if (forceFullRender || this.props.layoutProvider !== newProps.layoutProvider || this.props.isHorizontal !== newProps.isHorizontal) { -+ //TODO:Talha use old layout manager -+ this._virtualRenderer.setLayoutManager(newProps.layoutProvider.newLayoutManager(this._layout, newProps.isHorizontal)); -+ if (newProps.layoutProvider.shouldRefreshWithAnchoring) { -+ this._virtualRenderer.refreshWithAnchor(); -+ } -+ else { -+ this._virtualRenderer.refresh(); -+ } -+ this._refreshViewability(); -+ } -+ else if (this.props.dataProvider !== newProps.dataProvider) { -+ this._onEndReachedCalled = false; -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ layoutManager.relayoutFromIndex(newProps.dataProvider.getFirstIndexToProcessInternal(), newProps.dataProvider.getSize()); -+ this._virtualRenderer.refresh(); -+ } -+ } -+ else if (this._relayoutReqIndex >= 0) { -+ var layoutManager = this._virtualRenderer.getLayoutManager(); -+ if (layoutManager) { -+ var dataProviderSize = newProps.dataProvider.getSize(); -+ layoutManager.relayoutFromIndex(Math.min(Math.max(dataProviderSize - 1, 0), this._relayoutReqIndex), dataProviderSize); -+ this._relayoutReqIndex = -1; -+ this._refreshViewability(); -+ } -+ } -+ }; -+ RecyclerListView.prototype._refreshViewability = function () { -+ this._virtualRenderer.refresh(); -+ this._queueStateRefresh(); -+ }; -+ RecyclerListView.prototype._queueStateRefresh = function () { -+ var _this = this; -+ this.refreshRequestDebouncer(function () { -+ _this.setState(function (prevState) { -+ return prevState; -+ }); -+ }); -+ }; -+ RecyclerListView.prototype._initTrackers = function () { -+ this._assertDependencyPresence(this.props); -+ if (this.props.onVisibleIndexesChanged) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.usingOldVisibleIndexesChangedParam); -+ } -+ if (this.props.onVisibleIndicesChanged) { -+ this._virtualRenderer.attachVisibleItemsListener(this.props.onVisibleIndicesChanged); -+ } -+ this._params = { -+ initialOffset: this._initialOffset ? this._initialOffset : this.props.initialOffset, -+ initialRenderIndex: this.props.initialRenderIndex, -+ isHorizontal: this.props.isHorizontal, -+ itemCount: this.props.dataProvider.getSize(), -+ renderAheadOffset: this.props.renderAheadOffset, -+ }; -+ this._virtualRenderer.setParamsAndDimensions(this._params, this._layout); -+ var layoutManager = this.props.layoutProvider.newLayoutManager(this._layout, this.props.isHorizontal, this._cachedLayouts); -+ this._virtualRenderer.setLayoutManager(layoutManager); -+ this._virtualRenderer.setLayoutProvider(this.props.layoutProvider); -+ this._virtualRenderer.init(); -+ var offset = this._virtualRenderer.getInitialOffset(); -+ var contentDimension = layoutManager.getContentDimension(); -+ if ((offset.y > 0 && contentDimension.height > this._layout.height) || -+ (offset.x > 0 && contentDimension.width > this._layout.width)) { -+ this._pendingScrollToOffset = offset; -+ this.setState({}); -+ } -+ else { -+ this._virtualRenderer.startViewabilityTracker(); -+ } -+ }; -+ RecyclerListView.prototype._assertDependencyPresence = function (props) { -+ if (!props.dataProvider || !props.layoutProvider) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.unresolvedDependenciesException); -+ } -+ }; -+ RecyclerListView.prototype._assertType = function (type) { -+ if (!type && type !== 0) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.itemTypeNullException); -+ } -+ }; -+ RecyclerListView.prototype._renderRowUsingMeta = function (itemMeta) { -+ var dataSize = this.props.dataProvider.getSize(); -+ var dataIndex = itemMeta.dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(dataIndex) && dataIndex < dataSize) { -+ var itemRect = this._virtualRenderer.getLayoutManager().getLayouts()[dataIndex]; -+ var data = this.props.dataProvider.getDataForIndex(dataIndex); -+ var type = this.props.layoutProvider.getLayoutTypeForIndex(dataIndex); -+ var key = this._virtualRenderer.syncAndGetKey(dataIndex); -+ var styleOverrides = this._virtualRenderer.getLayoutManager().getStyleOverridesForIndex(dataIndex); -+ this._assertType(type); -+ if (!this.props.forceNonDeterministicRendering) { -+ this._checkExpectedDimensionDiscrepancy(itemRect, type, dataIndex); -+ } -+ return (React.createElement(ViewRenderer_1.default, { key: key, data: data, dataHasChanged: this._dataHasChanged, x: itemRect.x, y: itemRect.y, layoutType: type, index: dataIndex, styleOverrides: styleOverrides, layoutProvider: this.props.layoutProvider, forceNonDeterministicRendering: this.props.forceNonDeterministicRendering, isHorizontal: this.props.isHorizontal, onSizeChanged: this._onViewContainerSizeChange, childRenderer: this.props.rowRenderer, height: itemRect.height, width: itemRect.width, itemAnimator: ts_object_utils_1.Default.value(this.props.itemAnimator, this._defaultItemAnimator), extendedState: this.props.extendedState, internalSnapshot: this.state.internalSnapshot })); -+ } -+ return null; -+ }; -+ RecyclerListView.prototype._checkExpectedDimensionDiscrepancy = function (itemRect, type, index) { -+ if (this.props.layoutProvider.checkDimensionDiscrepancy(itemRect, type, index)) { -+ if (this._relayoutReqIndex === -1) { -+ this._relayoutReqIndex = index; -+ } -+ else { -+ this._relayoutReqIndex = Math.min(this._relayoutReqIndex, index); -+ } -+ } -+ }; -+ RecyclerListView.prototype._generateRenderStack = function () { -+ var renderedItems = []; -+ for (var key in this.state.renderStack) { -+ if (this.state.renderStack.hasOwnProperty(key)) { -+ renderedItems.push(this._renderRowUsingMeta(this.state.renderStack[key])); -+ } -+ } -+ return renderedItems; -+ }; -+ RecyclerListView.prototype._processOnEndReached = function () { -+ if (this.props.onEndReached && this._virtualRenderer) { -+ var layout = this._virtualRenderer.getLayoutDimension(); -+ var viewabilityTracker = this._virtualRenderer.getViewabilityTracker(); -+ if (viewabilityTracker) { -+ var windowBound = this.props.isHorizontal ? layout.width - this._layout.width : layout.height - this._layout.height; -+ var lastOffset = viewabilityTracker ? viewabilityTracker.getLastOffset() : 0; -+ if (windowBound - lastOffset <= ts_object_utils_1.Default.value(this.props.onEndReachedThreshold, 0)) { -+ if (this.props.onEndReached && !this._onEndReachedCalled) { -+ this._onEndReachedCalled = true; -+ this.props.onEndReached(); -+ } -+ } -+ else { -+ this._onEndReachedCalled = false; -+ } -+ } -+ } -+ }; -+ RecyclerListView.defaultProps = { -+ canChangeSize: false, -+ disableRecycling: false, -+ initialOffset: 0, -+ initialRenderIndex: 0, -+ isHorizontal: false, -+ onEndReachedThreshold: 0, -+ distanceFromWindow: 0, -+ renderAheadOffset: IS_WEB ? 1000 : 250, -+ }; -+ RecyclerListView.propTypes = {}; -+ return RecyclerListView; -+}(React.Component)); -+exports.default = RecyclerListView; -+RecyclerListView.propTypes = { -+ //Refer the sample -+ layoutProvider: PropTypes.instanceOf(LayoutProvider_1.BaseLayoutProvider).isRequired, -+ //Refer the sample -+ dataProvider: PropTypes.instanceOf(DataProvider_1.BaseDataProvider).isRequired, -+ //Used to maintain scroll position in case view gets destroyed e.g, cases of back navigation -+ contextProvider: PropTypes.instanceOf(ContextProvider_1.default), -+ //Methods which returns react component to be rendered. You get type of view and data in the callback. -+ rowRenderer: PropTypes.func.isRequired, -+ //Initial offset you want to start rendering from, very useful if you want to maintain scroll context across pages. -+ initialOffset: PropTypes.number, -+ //Specify how many pixels in advance do you want views to be rendered. Increasing this value can help reduce blanks (if any). However keeping this as low -+ //as possible should be the intent. Higher values also increase re-render compute -+ renderAheadOffset: PropTypes.number, -+ //Whether the listview is horizontally scrollable. Both use staggeredGrid implementation -+ isHorizontal: PropTypes.bool, -+ //On scroll callback onScroll(rawEvent, offsetX, offsetY), note you get offsets no need to read scrollTop/scrollLeft -+ onScroll: PropTypes.func, -+ //callback onRecreate(params), when recreating recycler view from context provider. Gives you the initial params in the first -+ //frame itself to allow you to render content accordingly -+ onRecreate: PropTypes.func, -+ //Provide your own ScrollView Component. The contract for the scroll event should match the native scroll event contract, i.e. -+ // scrollEvent = { nativeEvent: { contentOffset: { x: offset, y: offset } } } -+ //Note: Please extend BaseScrollView to achieve expected behaviour -+ externalScrollView: PropTypes.func, -+ //Callback given when user scrolls to the end of the list or footer just becomes visible, useful in incremental loading scenarios -+ onEndReached: PropTypes.func, -+ //Specify how many pixels in advance you onEndReached callback -+ onEndReachedThreshold: PropTypes.number, -+ //Deprecated. Please use onVisibleIndicesChanged instead. -+ onVisibleIndexesChanged: PropTypes.func, -+ //Provides visible index, helpful in sending impression events etc, onVisibleIndicesChanged(all, now, notNow) -+ onVisibleIndicesChanged: PropTypes.func, -+ //Provide this method if you want to render a footer. Helpful in showing a loader while doing incremental loads. -+ renderFooter: PropTypes.func, -+ //Specify the initial item index you want rendering to start from. Preferred over initialOffset if both are specified. -+ initialRenderIndex: PropTypes.number, -+ //iOS only. Scroll throttle duration. -+ scrollThrottle: PropTypes.number, -+ //Specify if size can change, listview will automatically relayout items. For web, works only with useWindowScroll = true -+ canChangeSize: PropTypes.bool, -+ //Specify how far away the first list item is from start of the RecyclerListView. e.g, if you have content padding on top or left. -+ //This is an adjustment for optimization and to make sure onVisibileIndexesChanged callback is correct. -+ //Ideally try to avoid setting large padding values on RLV content. If you have to please correct offsets reported, handle -+ //them in a custom ScrollView and pass it as an externalScrollView. If you want this to be accounted in scrollToOffset please -+ //override the method and handle manually. -+ distanceFromWindow: PropTypes.number, -+ //Web only. Layout elements in window instead of a scrollable div. -+ useWindowScroll: PropTypes.bool, -+ //Turns off recycling. You still get progressive rendering and all other features. Good for lazy rendering. This should not be used in most cases. -+ disableRecycling: PropTypes.bool, -+ //Default is false, if enabled dimensions provided in layout provider will not be strictly enforced. -+ //Rendered dimensions will be used to relayout items. Slower if enabled. -+ forceNonDeterministicRendering: PropTypes.bool, -+ //In some cases the data passed at row level may not contain all the info that the item depends upon, you can keep all other info -+ //outside and pass it down via this prop. Changing this object will cause everything to re-render. Make sure you don't change -+ //it often to ensure performance. Re-renders are heavy. -+ extendedState: PropTypes.object, -+ //Enables animating RecyclerListView item cells e.g, shift, add, remove etc. This prop can be used to pass an external item animation implementation. -+ //Look into BaseItemAnimator/DefaultJSItemAnimator/DefaultNativeItemAnimator/DefaultWebItemAnimator for more info. -+ //By default there are few animations, to disable completely simply pass blank new BaseItemAnimator() object. Remember, create -+ //one object and keep it do not create multiple object of type BaseItemAnimator. -+ //Note: You might want to look into DefaultNativeItemAnimator to check an implementation based on LayoutAnimation. By default, -+ //animations are JS driven to avoid workflow interference. Also, please note LayoutAnimation is buggy on Android. -+ itemAnimator: PropTypes.instanceOf(ItemAnimator_1.BaseItemAnimator), -+ //Enables you to utilize layout animations better by unmounting removed items. Please note, this might increase unmounts -+ //on large data changes. -+ optimizeForInsertDeleteAnimations: PropTypes.bool, -+ //To pass down style to inner ScrollView -+ style: PropTypes.oneOfType([ -+ PropTypes.object, -+ PropTypes.number, -+ ]), -+ //For TS use case, not necessary with JS use. -+ //For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread -+ //and passed down. -+ scrollViewProps: PropTypes.object, -+}; -+//# sourceMappingURL=RecyclerListView.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js.map b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js.map -new file mode 100644 -index 0000000..c13a909 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/RecyclerListView.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"RecyclerListView.js","sourceRoot":"","sources":["../../../src/core/RecyclerListView.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/StickyContainer.d.ts b/node_modules/recyclerlistview/dist/web/core/StickyContainer.d.ts -new file mode 100644 -index 0000000..e712796 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/StickyContainer.d.ts -@@ -0,0 +1,49 @@ -+/** -+ * Created by ananya.chandra on 14/09/18. -+ */ -+import * as React from "react"; -+import { StyleProp, ViewStyle } from "react-native"; -+import { RecyclerListViewProps } from "./RecyclerListView"; -+export interface StickyContainerProps { -+ children: RecyclerChild; -+ stickyHeaderIndices?: number[]; -+ stickyFooterIndices?: number[]; -+ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+ style?: StyleProp; -+} -+export interface RecyclerChild extends React.ReactElement { -+ ref: (recyclerRef: any) => {}; -+ props: RecyclerListViewProps; -+} -+export default class StickyContainer

extends React.Component

{ -+ static propTypes: {}; -+ private _recyclerRef; -+ private _dataProvider; -+ private _layoutProvider; -+ private _extendedState; -+ private _rowRenderer; -+ private _distanceFromWindow; -+ private _stickyHeaderRef; -+ private _stickyFooterRef; -+ private _visibleIndicesAll; -+ constructor(props: P, context?: any); -+ componentWillReceiveProps(newProps: P): void; -+ render(): JSX.Element; -+ private _getRecyclerRef; -+ private _getStickyHeaderRef; -+ private _getStickyFooterRef; -+ private _onVisibleIndicesChanged; -+ private _callStickyObjectsOnVisibleIndicesChanged; -+ private _onScroll; -+ private _assertChildType; -+ private _isChildRecyclerInstance; -+ private _getLayoutForIndex; -+ private _getDataForIndex; -+ private _getLayoutTypeForIndex; -+ private _getExtendedState; -+ private _getRowRenderer; -+ private _getRLVRenderedSize; -+ private _getContentDimension; -+ private _getDistanceFromWindow; -+ private _initParams; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/StickyContainer.js b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js -new file mode 100644 -index 0000000..8de1ec4 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js -@@ -0,0 +1,187 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 14/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var PropTypes = require("prop-types"); -+var react_native_1 = require("react-native"); -+var StickyHeader_1 = require("./sticky/StickyHeader"); -+var StickyFooter_1 = require("./sticky/StickyFooter"); -+var CustomError_1 = require("./exceptions/CustomError"); -+var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); -+var StickyContainer = /** @class */ (function (_super) { -+ __extends(StickyContainer, _super); -+ function StickyContainer(props, context) { -+ var _this = _super.call(this, props, context) || this; -+ _this._recyclerRef = undefined; -+ _this._stickyHeaderRef = null; -+ _this._stickyFooterRef = null; -+ _this._visibleIndicesAll = []; -+ _this._getRecyclerRef = function (recycler) { -+ _this._recyclerRef = recycler; -+ if (_this.props.children.ref) { -+ if (typeof _this.props.children.ref === "function") { -+ (_this.props.children).ref(recycler); -+ } -+ else { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.refNotAsFunctionException); -+ } -+ } -+ }; -+ _this._getStickyHeaderRef = function (stickyHeaderRef) { -+ if (_this._stickyHeaderRef !== stickyHeaderRef) { -+ _this._stickyHeaderRef = stickyHeaderRef; -+ // TODO: Resetting state once ref is initialized. Can look for better solution. -+ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); -+ } -+ }; -+ _this._getStickyFooterRef = function (stickyFooterRef) { -+ if (_this._stickyFooterRef !== stickyFooterRef) { -+ _this._stickyFooterRef = stickyFooterRef; -+ // TODO: Resetting state once ref is initialized. Can look for better solution. -+ _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); -+ } -+ }; -+ _this._onVisibleIndicesChanged = function (all, now, notNow) { -+ _this._visibleIndicesAll = all; -+ _this._callStickyObjectsOnVisibleIndicesChanged(all); -+ if (_this.props.children && _this.props.children.props && _this.props.children.props.onVisibleIndicesChanged) { -+ _this.props.children.props.onVisibleIndicesChanged(all, now, notNow); -+ } -+ }; -+ _this._callStickyObjectsOnVisibleIndicesChanged = function (all) { -+ if (_this._stickyHeaderRef) { -+ _this._stickyHeaderRef.onVisibleIndicesChanged(all); -+ } -+ if (_this._stickyFooterRef) { -+ _this._stickyFooterRef.onVisibleIndicesChanged(all); -+ } -+ }; -+ _this._onScroll = function (rawEvent, offsetX, offsetY) { -+ if (_this._stickyHeaderRef) { -+ _this._stickyHeaderRef.onScroll(offsetY); -+ } -+ if (_this._stickyFooterRef) { -+ _this._stickyFooterRef.onScroll(offsetY); -+ } -+ if (_this.props.children && _this.props.children.props.onScroll) { -+ _this.props.children.props.onScroll(rawEvent, offsetX, offsetY); -+ } -+ }; -+ _this._assertChildType = function () { -+ if (React.Children.count(_this.props.children) !== 1 || !_this._isChildRecyclerInstance()) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.wrongStickyChildTypeException); -+ } -+ }; -+ _this._isChildRecyclerInstance = function () { -+ return (_this.props.children.props.dataProvider -+ && _this.props.children.props.rowRenderer -+ && _this.props.children.props.layoutProvider); -+ }; -+ _this._getLayoutForIndex = function (index) { -+ if (_this._recyclerRef) { -+ return _this._recyclerRef.getLayout(index); -+ } -+ return undefined; -+ }; -+ _this._getDataForIndex = function (index) { -+ return _this._dataProvider.getDataForIndex(index); -+ }; -+ _this._getLayoutTypeForIndex = function (index) { -+ return _this._layoutProvider.getLayoutTypeForIndex(index); -+ }; -+ _this._getExtendedState = function () { -+ return _this._extendedState; -+ }; -+ _this._getRowRenderer = function () { -+ return _this._rowRenderer; -+ }; -+ _this._getRLVRenderedSize = function () { -+ if (_this._recyclerRef) { -+ return _this._recyclerRef.getRenderedSize(); -+ } -+ return undefined; -+ }; -+ _this._getContentDimension = function () { -+ if (_this._recyclerRef) { -+ return _this._recyclerRef.getContentDimension(); -+ } -+ return undefined; -+ }; -+ _this._getDistanceFromWindow = function () { -+ return _this._distanceFromWindow; -+ }; -+ _this._initParams = function (props) { -+ var childProps = props.children.props; -+ _this._dataProvider = childProps.dataProvider; -+ _this._layoutProvider = childProps.layoutProvider; -+ _this._extendedState = childProps.extendedState; -+ _this._rowRenderer = childProps.rowRenderer; -+ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; -+ }; -+ _this._assertChildType(); -+ var childProps = props.children.props; -+ _this._dataProvider = childProps.dataProvider; -+ _this._layoutProvider = childProps.layoutProvider; -+ _this._extendedState = childProps.extendedState; -+ _this._rowRenderer = childProps.rowRenderer; -+ _this._distanceFromWindow = childProps.distanceFromWindow ? childProps.distanceFromWindow : 0; -+ return _this; -+ } -+ StickyContainer.prototype.componentWillReceiveProps = function (newProps) { -+ this._initParams(newProps); -+ }; -+ StickyContainer.prototype.render = function () { -+ var _this = this; -+ this._assertChildType(); -+ var recycler = React.cloneElement(this.props.children, __assign({}, this.props.children.props, { ref: this._getRecyclerRef, onVisibleIndicesChanged: this._onVisibleIndicesChanged, onScroll: this._onScroll })); -+ return (React.createElement(react_native_1.View, { style: this.props.style ? this.props.style : { flex: 1 } }, -+ recycler, -+ this.props.stickyHeaderIndices ? (React.createElement(StickyHeader_1.default, { ref: function (stickyHeaderRef) { return _this._getStickyHeaderRef(stickyHeaderRef); }, stickyIndices: this.props.stickyHeaderIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null, -+ this.props.stickyFooterIndices ? (React.createElement(StickyFooter_1.default, { ref: function (stickyFooterRef) { return _this._getStickyFooterRef(stickyFooterRef); }, stickyIndices: this.props.stickyFooterIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, getDistanceFromWindow: this._getDistanceFromWindow, overrideRowRenderer: this.props.overrideRowRenderer })) : null)); -+ }; -+ StickyContainer.propTypes = {}; -+ return StickyContainer; -+}(React.Component)); -+exports.default = StickyContainer; -+StickyContainer.propTypes = { -+ // Mandatory to pass a single child of RecyclerListView or any of its children classes. Exception will be thrown otherwise. -+ children: PropTypes.element.isRequired, -+ // Provide an array of indices whose corresponding items need to be stuck to the top of the recyclerView once the items scroll off the top. -+ // Every subsequent sticky index view will push the previous sticky view off the top to take its place. -+ // Note - Needs to be sorted ascending -+ stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), -+ // Works same as sticky headers, but for views to be stuck at the bottom of the recyclerView. -+ // Note - Needs to be sorted ascending -+ stickyFooterIndices: PropTypes.arrayOf(PropTypes.number), -+ // Will be called instead of rowRenderer for all sticky items. Any changes to the item for when they are stuck can be done here. -+ overrideRowRenderer: PropTypes.func, -+ // For all practical purposes, pass the style that is applied to the RecyclerListView component here. -+ style: PropTypes.object, -+}; -+//# sourceMappingURL=StickyContainer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/StickyContainer.js.map b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js.map -new file mode 100644 -index 0000000..4dc4cf2 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/StickyContainer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyContainer.js","sourceRoot":"","sources":["../../../src/core/StickyContainer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.d.ts b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.d.ts -new file mode 100644 -index 0000000..820022a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.d.ts -@@ -0,0 +1,61 @@ -+import { Dimension } from "./dependencies/LayoutProvider"; -+import { Layout } from "./layoutmanager/LayoutManager"; -+/*** -+ * Given an offset this utility can compute visible items. Also tracks previously visible items to compute items which get hidden or visible -+ * Virtual renderer uses callbacks from this utility to main recycle pool and the render stack. -+ * The utility optimizes finding visible indexes by using the last visible items. However, that can be slow if scrollToOffset is explicitly called. -+ * We use binary search to optimize in most cases like while finding first visible item or initial offset. In future we'll also be using BS to speed up -+ * scroll to offset. -+ */ -+export interface Range { -+ start: number; -+ end: number; -+} -+export declare type TOnItemStatusChanged = ((all: number[], now: number[], notNow: number[]) => void); -+export default class ViewabilityTracker { -+ onVisibleRowsChanged: TOnItemStatusChanged | null; -+ onEngagedRowsChanged: TOnItemStatusChanged | null; -+ private _currentOffset; -+ private _maxOffset; -+ private _renderAheadOffset; -+ private _visibleWindow; -+ private _engagedWindow; -+ private _relevantDim; -+ private _isHorizontal; -+ private _windowBound; -+ private _visibleIndexes; -+ private _engagedIndexes; -+ private _layouts; -+ private _actualOffset; -+ constructor(renderAheadOffset: number, initialOffset: number); -+ init(): void; -+ setLayouts(layouts: Layout[], maxOffset: number): void; -+ setDimensions(dimension: Dimension, isHorizontal: boolean): void; -+ forceRefresh(): boolean; -+ forceRefreshWithOffset(offset: number): void; -+ updateOffset(offset: number, correction: number, isActual: boolean): void; -+ getLastOffset(): number; -+ getLastActualOffset(): number; -+ getEngagedIndexes(): number[]; -+ findFirstLogicallyVisibleIndex(): number; -+ updateRenderAheadOffset(renderAheadOffset: number): void; -+ getCurrentRenderAheadOffset(): number; -+ private _findFirstVisibleIndexOptimally; -+ private _fitAndUpdate; -+ private _doInitialFit; -+ private _findFirstVisibleIndexLinearly; -+ private _findFirstVisibleIndexUsingBS; -+ private _valueExtractorForBinarySearch; -+ private _fitIndexes; -+ private _checkIntersectionAndReport; -+ private _setRelevantBounds; -+ private _isItemInBounds; -+ private _isItemBoundsBeyondWindow; -+ private _itemIntersectsWindow; -+ private _itemIntersectsEngagedWindow; -+ private _itemIntersectsVisibleWindow; -+ private _updateTrackingWindows; -+ private _diffUpdateOriginalIndexesAndRaiseEvents; -+ private _diffArraysAndCallFunc; -+ private _calculateArrayDiff; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js -new file mode 100644 -index 0000000..dc8271a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js -@@ -0,0 +1,266 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var BinarySearch_1 = require("../utils/BinarySearch"); -+var ViewabilityTracker = /** @class */ (function () { -+ function ViewabilityTracker(renderAheadOffset, initialOffset) { -+ var _this = this; -+ this._layouts = []; -+ this._valueExtractorForBinarySearch = function (index) { -+ var itemRect = _this._layouts[index]; -+ _this._setRelevantBounds(itemRect, _this._relevantDim); -+ return _this._relevantDim.end; -+ }; -+ this._currentOffset = Math.max(0, initialOffset); -+ this._maxOffset = 0; -+ this._actualOffset = 0; -+ this._renderAheadOffset = renderAheadOffset; -+ this._visibleWindow = { start: 0, end: 0 }; -+ this._engagedWindow = { start: 0, end: 0 }; -+ this._isHorizontal = false; -+ this._windowBound = 0; -+ this._visibleIndexes = []; //needs to be sorted -+ this._engagedIndexes = []; //needs to be sorted -+ this.onVisibleRowsChanged = null; -+ this.onEngagedRowsChanged = null; -+ this._relevantDim = { start: 0, end: 0 }; -+ } -+ ViewabilityTracker.prototype.init = function () { -+ this._doInitialFit(this._currentOffset); -+ }; -+ ViewabilityTracker.prototype.setLayouts = function (layouts, maxOffset) { -+ this._layouts = layouts; -+ this._maxOffset = maxOffset; -+ }; -+ ViewabilityTracker.prototype.setDimensions = function (dimension, isHorizontal) { -+ this._isHorizontal = isHorizontal; -+ this._windowBound = isHorizontal ? dimension.width : dimension.height; -+ }; -+ ViewabilityTracker.prototype.forceRefresh = function () { -+ this.forceRefreshWithOffset(this._currentOffset); -+ return false; -+ }; -+ ViewabilityTracker.prototype.forceRefreshWithOffset = function (offset) { -+ this._currentOffset = -1; -+ this.updateOffset(offset, 0, false); -+ }; -+ ViewabilityTracker.prototype.updateOffset = function (offset, correction, isActual) { -+ if (isActual) { -+ this._actualOffset = offset; -+ } -+ offset = Math.min(this._maxOffset, Math.max(0, offset + correction)); -+ if (this._currentOffset !== offset) { -+ this._currentOffset = offset; -+ this._updateTrackingWindows(offset); -+ var startIndex = 0; -+ if (this._visibleIndexes.length > 0) { -+ startIndex = this._visibleIndexes[0]; -+ } -+ this._fitAndUpdate(startIndex); -+ } -+ }; -+ ViewabilityTracker.prototype.getLastOffset = function () { -+ return this._currentOffset; -+ }; -+ ViewabilityTracker.prototype.getLastActualOffset = function () { -+ return this._actualOffset; -+ }; -+ ViewabilityTracker.prototype.getEngagedIndexes = function () { -+ return this._engagedIndexes; -+ }; -+ ViewabilityTracker.prototype.findFirstLogicallyVisibleIndex = function () { -+ var relevantIndex = this._findFirstVisibleIndexUsingBS(0.001); -+ var result = relevantIndex; -+ for (var i = relevantIndex - 1; i >= 0; i--) { -+ if (this._isHorizontal) { -+ if (this._layouts[relevantIndex].x !== this._layouts[i].x) { -+ break; -+ } -+ else { -+ result = i; -+ } -+ } -+ else { -+ if (this._layouts[relevantIndex].y !== this._layouts[i].y) { -+ break; -+ } -+ else { -+ result = i; -+ } -+ } -+ } -+ return result; -+ }; -+ ViewabilityTracker.prototype.updateRenderAheadOffset = function (renderAheadOffset) { -+ this._renderAheadOffset = Math.max(0, renderAheadOffset); -+ this.forceRefreshWithOffset(this._currentOffset); -+ }; -+ ViewabilityTracker.prototype.getCurrentRenderAheadOffset = function () { -+ return this._renderAheadOffset; -+ }; -+ ViewabilityTracker.prototype._findFirstVisibleIndexOptimally = function () { -+ var firstVisibleIndex = 0; -+ //TODO: Talha calculate this value smartly -+ if (this._currentOffset > 5000) { -+ firstVisibleIndex = this._findFirstVisibleIndexUsingBS(); -+ } -+ else if (this._currentOffset > 0) { -+ firstVisibleIndex = this._findFirstVisibleIndexLinearly(); -+ } -+ return firstVisibleIndex; -+ }; -+ ViewabilityTracker.prototype._fitAndUpdate = function (startIndex) { -+ var newVisibleItems = []; -+ var newEngagedItems = []; -+ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex, true); -+ this._fitIndexes(newVisibleItems, newEngagedItems, startIndex + 1, false); -+ this._diffUpdateOriginalIndexesAndRaiseEvents(newVisibleItems, newEngagedItems); -+ }; -+ ViewabilityTracker.prototype._doInitialFit = function (offset) { -+ offset = Math.min(this._maxOffset, Math.max(0, offset)); -+ this._updateTrackingWindows(offset); -+ var firstVisibleIndex = this._findFirstVisibleIndexOptimally(); -+ this._fitAndUpdate(firstVisibleIndex); -+ }; -+ //TODO:Talha switch to binary search and remove atleast once logic in _fitIndexes -+ ViewabilityTracker.prototype._findFirstVisibleIndexLinearly = function () { -+ var count = this._layouts.length; -+ var itemRect = null; -+ var relevantDim = { start: 0, end: 0 }; -+ for (var i = 0; i < count; i++) { -+ itemRect = this._layouts[i]; -+ this._setRelevantBounds(itemRect, relevantDim); -+ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { -+ return i; -+ } -+ } -+ return 0; -+ }; -+ ViewabilityTracker.prototype._findFirstVisibleIndexUsingBS = function (bias) { -+ if (bias === void 0) { bias = 0; } -+ var count = this._layouts.length; -+ return BinarySearch_1.default.findClosestHigherValueIndex(count, this._visibleWindow.start + bias, this._valueExtractorForBinarySearch); -+ }; -+ //TODO:Talha Optimize further in later revisions, alteast once logic can be replace with a BS lookup -+ ViewabilityTracker.prototype._fitIndexes = function (newVisibleIndexes, newEngagedIndexes, startIndex, isReverse) { -+ var count = this._layouts.length; -+ var relevantDim = { start: 0, end: 0 }; -+ var i = 0; -+ var atLeastOneLocated = false; -+ if (startIndex < count) { -+ if (!isReverse) { -+ for (i = startIndex; i < count; i++) { -+ if (this._checkIntersectionAndReport(i, false, relevantDim, newVisibleIndexes, newEngagedIndexes)) { -+ atLeastOneLocated = true; -+ } -+ else { -+ if (atLeastOneLocated) { -+ break; -+ } -+ } -+ } -+ } -+ else { -+ for (i = startIndex; i >= 0; i--) { -+ if (this._checkIntersectionAndReport(i, true, relevantDim, newVisibleIndexes, newEngagedIndexes)) { -+ atLeastOneLocated = true; -+ } -+ else { -+ if (atLeastOneLocated) { -+ break; -+ } -+ } -+ } -+ } -+ } -+ }; -+ ViewabilityTracker.prototype._checkIntersectionAndReport = function (index, insertOnTop, relevantDim, newVisibleIndexes, newEngagedIndexes) { -+ var itemRect = this._layouts[index]; -+ var isFound = false; -+ this._setRelevantBounds(itemRect, relevantDim); -+ if (this._itemIntersectsVisibleWindow(relevantDim.start, relevantDim.end)) { -+ if (insertOnTop) { -+ newVisibleIndexes.splice(0, 0, index); -+ newEngagedIndexes.splice(0, 0, index); -+ } -+ else { -+ newVisibleIndexes.push(index); -+ newEngagedIndexes.push(index); -+ } -+ isFound = true; -+ } -+ else if (this._itemIntersectsEngagedWindow(relevantDim.start, relevantDim.end)) { -+ //TODO: This needs to be optimized -+ if (insertOnTop) { -+ newEngagedIndexes.splice(0, 0, index); -+ } -+ else { -+ newEngagedIndexes.push(index); -+ } -+ isFound = true; -+ } -+ return isFound; -+ }; -+ ViewabilityTracker.prototype._setRelevantBounds = function (itemRect, relevantDim) { -+ if (this._isHorizontal) { -+ relevantDim.end = itemRect.x + itemRect.width; -+ relevantDim.start = itemRect.x; -+ } -+ else { -+ relevantDim.end = itemRect.y + itemRect.height; -+ relevantDim.start = itemRect.y; -+ } -+ }; -+ ViewabilityTracker.prototype._isItemInBounds = function (window, itemBound) { -+ return (window.start < itemBound && window.end > itemBound); -+ }; -+ ViewabilityTracker.prototype._isItemBoundsBeyondWindow = function (window, startBound, endBound) { -+ return (window.start >= startBound && window.end <= endBound); -+ }; -+ ViewabilityTracker.prototype._itemIntersectsWindow = function (window, startBound, endBound) { -+ return this._isItemInBounds(window, startBound) || -+ this._isItemInBounds(window, endBound) || -+ this._isItemBoundsBeyondWindow(window, startBound, endBound); -+ }; -+ ViewabilityTracker.prototype._itemIntersectsEngagedWindow = function (startBound, endBound) { -+ return this._itemIntersectsWindow(this._engagedWindow, startBound, endBound); -+ }; -+ ViewabilityTracker.prototype._itemIntersectsVisibleWindow = function (startBound, endBound) { -+ return this._itemIntersectsWindow(this._visibleWindow, startBound, endBound); -+ }; -+ ViewabilityTracker.prototype._updateTrackingWindows = function (newOffset) { -+ this._engagedWindow.start = Math.max(0, newOffset - this._renderAheadOffset); -+ this._engagedWindow.end = newOffset + this._windowBound + this._renderAheadOffset; -+ this._visibleWindow.start = newOffset; -+ this._visibleWindow.end = newOffset + this._windowBound; -+ }; -+ //TODO:Talha optimize this -+ ViewabilityTracker.prototype._diffUpdateOriginalIndexesAndRaiseEvents = function (newVisibleItems, newEngagedItems) { -+ this._diffArraysAndCallFunc(newVisibleItems, this._visibleIndexes, this.onVisibleRowsChanged); -+ this._diffArraysAndCallFunc(newEngagedItems, this._engagedIndexes, this.onEngagedRowsChanged); -+ this._visibleIndexes = newVisibleItems; -+ this._engagedIndexes = newEngagedItems; -+ }; -+ ViewabilityTracker.prototype._diffArraysAndCallFunc = function (newItems, oldItems, func) { -+ if (func) { -+ var now = this._calculateArrayDiff(newItems, oldItems); -+ var notNow = this._calculateArrayDiff(oldItems, newItems); -+ if (now.length > 0 || notNow.length > 0) { -+ func(newItems.slice(), now, notNow); -+ } -+ } -+ }; -+ //TODO:Talha since arrays are sorted this can be much faster -+ ViewabilityTracker.prototype._calculateArrayDiff = function (arr1, arr2) { -+ var len = arr1.length; -+ var diffArr = []; -+ for (var i = 0; i < len; i++) { -+ if (BinarySearch_1.default.findIndexOf(arr2, arr1[i]) === -1) { -+ diffArr.push(arr1[i]); -+ } -+ } -+ return diffArr; -+ }; -+ return ViewabilityTracker; -+}()); -+exports.default = ViewabilityTracker; -+//# sourceMappingURL=ViewabilityTracker.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js.map b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js.map -new file mode 100644 -index 0000000..ba78826 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/ViewabilityTracker.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewabilityTracker.js","sourceRoot":"","sources":["../../../src/core/ViewabilityTracker.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.d.ts b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.d.ts -new file mode 100644 -index 0000000..190e53a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.d.ts -@@ -0,0 +1,66 @@ -+import { Dimension, BaseLayoutProvider } from "./dependencies/LayoutProvider"; -+import { Point, LayoutManager } from "./layoutmanager/LayoutManager"; -+import ViewabilityTracker, { TOnItemStatusChanged } from "./ViewabilityTracker"; -+import { BaseDataProvider } from "./dependencies/DataProvider"; -+/*** -+ * Renderer which keeps track of recyclable items and the currently rendered items. Notifies list view to re render if something changes, like scroll offset -+ */ -+export interface RenderStackItem { -+ dataIndex?: number; -+} -+export interface StableIdMapItem { -+ key: string; -+ type: string | number; -+} -+export interface RenderStack { -+ [key: string]: RenderStackItem; -+} -+export interface RenderStackParams { -+ isHorizontal?: boolean; -+ itemCount: number; -+ initialOffset?: number; -+ initialRenderIndex?: number; -+ renderAheadOffset?: number; -+} -+export declare type StableIdProvider = (index: number) => string; -+export default class VirtualRenderer { -+ private onVisibleItemsChanged; -+ private _scrollOnNextUpdate; -+ private _stableIdToRenderKeyMap; -+ private _engagedIndexes; -+ private _renderStack; -+ private _renderStackChanged; -+ private _fetchStableId; -+ private _isRecyclingEnabled; -+ private _isViewTrackerRunning; -+ private _markDirty; -+ private _startKey; -+ private _layoutProvider; -+ private _recyclePool; -+ private _params; -+ private _layoutManager; -+ private _viewabilityTracker; -+ private _dimensions; -+ constructor(renderStackChanged: (renderStack: RenderStack) => void, scrollOnNextUpdate: (point: Point) => void, fetchStableId: StableIdProvider, isRecyclingEnabled: boolean); -+ getLayoutDimension(): Dimension; -+ updateOffset(offsetX: number, offsetY: number, correction: number, isActual: boolean): void; -+ attachVisibleItemsListener(callback: TOnItemStatusChanged): void; -+ removeVisibleItemsListener(): void; -+ getLayoutManager(): LayoutManager | null; -+ setParamsAndDimensions(params: RenderStackParams, dim: Dimension): void; -+ setLayoutManager(layoutManager: LayoutManager): void; -+ setLayoutProvider(layoutProvider: BaseLayoutProvider): void; -+ getViewabilityTracker(): ViewabilityTracker | null; -+ refreshWithAnchor(): void; -+ refresh(): void; -+ getInitialOffset(): Point; -+ init(): void; -+ startViewabilityTracker(): void; -+ syncAndGetKey(index: number, overrideStableIdProvider?: StableIdProvider, newRenderStack?: RenderStack): string; -+ handleDataSetChange(newDataProvider: BaseDataProvider, shouldOptimizeForAnimations?: boolean): void; -+ private _getCollisionAvoidingKey; -+ private _prepareViewabilityTracker; -+ private _onVisibleItemsChanged; -+ private _onEngagedItemsChanged; -+ private _updateRenderStack; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js -new file mode 100644 -index 0000000..921ccbc ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js -@@ -0,0 +1,321 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecycleItemPool_1 = require("../utils/RecycleItemPool"); -+var CustomError_1 = require("./exceptions/CustomError"); -+var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); -+var ViewabilityTracker_1 = require("./ViewabilityTracker"); -+var ts_object_utils_1 = require("ts-object-utils"); -+var TSCast_1 = require("../utils/TSCast"); -+var VirtualRenderer = /** @class */ (function () { -+ function VirtualRenderer(renderStackChanged, scrollOnNextUpdate, fetchStableId, isRecyclingEnabled) { -+ var _this = this; -+ this._layoutProvider = TSCast_1.default.cast(null); //TSI -+ this._recyclePool = TSCast_1.default.cast(null); //TSI -+ this._layoutManager = null; -+ this._viewabilityTracker = null; -+ this._onVisibleItemsChanged = function (all, now, notNow) { -+ if (_this.onVisibleItemsChanged) { -+ _this.onVisibleItemsChanged(all, now, notNow); -+ } -+ }; -+ this._onEngagedItemsChanged = function (all, now, notNow) { -+ var count = notNow.length; -+ var resolvedKey; -+ var disengagedIndex = 0; -+ if (_this._isRecyclingEnabled) { -+ for (var i = 0; i < count; i++) { -+ disengagedIndex = notNow[i]; -+ delete _this._engagedIndexes[disengagedIndex]; -+ if (_this._params && disengagedIndex < _this._params.itemCount) { -+ //All the items which are now not visible can go to the recycle pool, the pool only needs to maintain keys since -+ //react can link a view to a key automatically -+ resolvedKey = _this._stableIdToRenderKeyMap[_this._fetchStableId(disengagedIndex)]; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(resolvedKey)) { -+ _this._recyclePool.putRecycledObject(_this._layoutProvider.getLayoutTypeForIndex(disengagedIndex), resolvedKey.key); -+ } -+ } -+ } -+ } -+ if (_this._updateRenderStack(now)) { -+ //Ask Recycler View to update itself -+ _this._renderStackChanged(_this._renderStack); -+ } -+ }; -+ //Keeps track of items that need to be rendered in the next render cycle -+ this._renderStack = {}; -+ this._fetchStableId = fetchStableId; -+ //Keeps track of keys of all the currently rendered indexes, can eventually replace renderStack as well if no new use cases come up -+ this._stableIdToRenderKeyMap = {}; -+ this._engagedIndexes = {}; -+ this._renderStackChanged = renderStackChanged; -+ this._scrollOnNextUpdate = scrollOnNextUpdate; -+ this._dimensions = null; -+ this._params = null; -+ this._isRecyclingEnabled = isRecyclingEnabled; -+ this._isViewTrackerRunning = false; -+ this._markDirty = false; -+ //Would be surprised if someone exceeds this -+ this._startKey = 0; -+ this.onVisibleItemsChanged = null; -+ } -+ VirtualRenderer.prototype.getLayoutDimension = function () { -+ if (this._layoutManager) { -+ return this._layoutManager.getContentDimension(); -+ } -+ return { height: 0, width: 0 }; -+ }; -+ VirtualRenderer.prototype.updateOffset = function (offsetX, offsetY, correction, isActual) { -+ if (this._viewabilityTracker) { -+ if (!this._isViewTrackerRunning) { -+ this.startViewabilityTracker(); -+ } -+ if (this._params && this._params.isHorizontal) { -+ this._viewabilityTracker.updateOffset(offsetX, correction, isActual); -+ } -+ else { -+ this._viewabilityTracker.updateOffset(offsetY, correction, isActual); -+ } -+ } -+ }; -+ VirtualRenderer.prototype.attachVisibleItemsListener = function (callback) { -+ this.onVisibleItemsChanged = callback; -+ }; -+ VirtualRenderer.prototype.removeVisibleItemsListener = function () { -+ this.onVisibleItemsChanged = null; -+ if (this._viewabilityTracker) { -+ this._viewabilityTracker.onVisibleRowsChanged = null; -+ } -+ }; -+ VirtualRenderer.prototype.getLayoutManager = function () { -+ return this._layoutManager; -+ }; -+ VirtualRenderer.prototype.setParamsAndDimensions = function (params, dim) { -+ this._params = params; -+ this._dimensions = dim; -+ }; -+ VirtualRenderer.prototype.setLayoutManager = function (layoutManager) { -+ this._layoutManager = layoutManager; -+ if (this._params) { -+ this._layoutManager.relayoutFromIndex(0, this._params.itemCount); -+ } -+ }; -+ VirtualRenderer.prototype.setLayoutProvider = function (layoutProvider) { -+ this._layoutProvider = layoutProvider; -+ }; -+ VirtualRenderer.prototype.getViewabilityTracker = function () { -+ return this._viewabilityTracker; -+ }; -+ VirtualRenderer.prototype.refreshWithAnchor = function () { -+ if (this._viewabilityTracker) { -+ var firstVisibleIndex = this._viewabilityTracker.findFirstLogicallyVisibleIndex(); -+ this._prepareViewabilityTracker(); -+ var offset = 0; -+ if (this._layoutManager && this._params) { -+ var point = this._layoutManager.getOffsetForIndex(firstVisibleIndex); -+ this._scrollOnNextUpdate(point); -+ offset = this._params.isHorizontal ? point.x : point.y; -+ } -+ this._viewabilityTracker.forceRefreshWithOffset(offset); -+ } -+ }; -+ VirtualRenderer.prototype.refresh = function () { -+ if (this._viewabilityTracker) { -+ this._prepareViewabilityTracker(); -+ if (this._viewabilityTracker.forceRefresh()) { -+ if (this._params && this._params.isHorizontal) { -+ this._scrollOnNextUpdate({ x: this._viewabilityTracker.getLastActualOffset(), y: 0 }); -+ } -+ else { -+ this._scrollOnNextUpdate({ x: 0, y: this._viewabilityTracker.getLastActualOffset() }); -+ } -+ } -+ } -+ }; -+ VirtualRenderer.prototype.getInitialOffset = function () { -+ var offset = { x: 0, y: 0 }; -+ if (this._params) { -+ var initialRenderIndex = ts_object_utils_1.Default.value(this._params.initialRenderIndex, 0); -+ if (initialRenderIndex > 0 && this._layoutManager) { -+ offset = this._layoutManager.getOffsetForIndex(initialRenderIndex); -+ this._params.initialOffset = this._params.isHorizontal ? offset.x : offset.y; -+ } -+ else { -+ if (this._params.isHorizontal) { -+ offset.x = ts_object_utils_1.Default.value(this._params.initialOffset, 0); -+ offset.y = 0; -+ } -+ else { -+ offset.y = ts_object_utils_1.Default.value(this._params.initialOffset, 0); -+ offset.x = 0; -+ } -+ } -+ } -+ return offset; -+ }; -+ VirtualRenderer.prototype.init = function () { -+ this.getInitialOffset(); -+ this._recyclePool = new RecycleItemPool_1.default(); -+ if (this._params) { -+ this._viewabilityTracker = new ViewabilityTracker_1.default(ts_object_utils_1.Default.value(this._params.renderAheadOffset, 0), ts_object_utils_1.Default.value(this._params.initialOffset, 0)); -+ } -+ else { -+ this._viewabilityTracker = new ViewabilityTracker_1.default(0, 0); -+ } -+ this._prepareViewabilityTracker(); -+ }; -+ VirtualRenderer.prototype.startViewabilityTracker = function () { -+ if (this._viewabilityTracker) { -+ this._isViewTrackerRunning = true; -+ this._viewabilityTracker.init(); -+ } -+ }; -+ VirtualRenderer.prototype.syncAndGetKey = function (index, overrideStableIdProvider, newRenderStack) { -+ var getStableId = overrideStableIdProvider ? overrideStableIdProvider : this._fetchStableId; -+ var renderStack = newRenderStack ? newRenderStack : this._renderStack; -+ var stableIdItem = this._stableIdToRenderKeyMap[getStableId(index)]; -+ var key = stableIdItem ? stableIdItem.key : undefined; -+ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { -+ var type = this._layoutProvider.getLayoutTypeForIndex(index); -+ key = this._recyclePool.getRecycledObject(type); -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(key)) { -+ var itemMeta = renderStack[key]; -+ if (itemMeta) { -+ var oldIndex = itemMeta.dataIndex; -+ itemMeta.dataIndex = index; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(oldIndex) && oldIndex !== index) { -+ delete this._stableIdToRenderKeyMap[getStableId(oldIndex)]; -+ } -+ } -+ else { -+ renderStack[key] = { dataIndex: index }; -+ } -+ } -+ else { -+ key = getStableId(index); -+ if (renderStack[key]) { -+ //Probable collision, warn and avoid -+ //TODO: Disabled incorrectly triggering in some cases -+ //console.warn("Possible stableId collision @", index); //tslint:disable-line -+ key = this._getCollisionAvoidingKey(); -+ } -+ renderStack[key] = { dataIndex: index }; -+ } -+ this._markDirty = true; -+ this._stableIdToRenderKeyMap[getStableId(index)] = { key: key, type: type }; -+ } -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { -+ this._recyclePool.removeFromPool(key); -+ } -+ var stackItem = renderStack[key]; -+ if (stackItem && stackItem.dataIndex !== index) { -+ //Probable collision, warn -+ console.warn("Possible stableId collision @", index); //tslint:disable-line -+ } -+ return key; -+ }; -+ //Further optimize in later revision, pretty fast for now considering this is a low frequency event -+ VirtualRenderer.prototype.handleDataSetChange = function (newDataProvider, shouldOptimizeForAnimations) { -+ var getStableId = newDataProvider.getStableId; -+ var maxIndex = newDataProvider.getSize() - 1; -+ var activeStableIds = {}; -+ var newRenderStack = {}; -+ //Compute active stable ids and stale active keys and resync render stack -+ for (var key in this._renderStack) { -+ if (this._renderStack.hasOwnProperty(key)) { -+ var index = this._renderStack[key].dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { -+ if (index <= maxIndex) { -+ var stableId = getStableId(index); -+ activeStableIds[stableId] = 1; -+ } -+ } -+ } -+ } -+ //Clean stable id to key map -+ var oldActiveStableIds = Object.keys(this._stableIdToRenderKeyMap); -+ var oldActiveStableIdsCount = oldActiveStableIds.length; -+ for (var i = 0; i < oldActiveStableIdsCount; i++) { -+ var key = oldActiveStableIds[i]; -+ if (!activeStableIds[key]) { -+ if (!shouldOptimizeForAnimations && this._isRecyclingEnabled) { -+ var stableIdItem = this._stableIdToRenderKeyMap[key]; -+ if (stableIdItem) { -+ this._recyclePool.putRecycledObject(stableIdItem.type, stableIdItem.key); -+ } -+ } -+ delete this._stableIdToRenderKeyMap[key]; -+ } -+ } -+ for (var key in this._renderStack) { -+ if (this._renderStack.hasOwnProperty(key)) { -+ var index = this._renderStack[key].dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index)) { -+ if (index <= maxIndex) { -+ var newKey = this.syncAndGetKey(index, getStableId, newRenderStack); -+ var newStackItem = newRenderStack[newKey]; -+ if (!newStackItem) { -+ newRenderStack[newKey] = { dataIndex: index }; -+ } -+ else if (newStackItem.dataIndex !== index) { -+ var cllKey = this._getCollisionAvoidingKey(); -+ newRenderStack[cllKey] = { dataIndex: index }; -+ this._stableIdToRenderKeyMap[getStableId(index)] = { -+ key: cllKey, type: this._layoutProvider.getLayoutTypeForIndex(index), -+ }; -+ } -+ } -+ } -+ delete this._renderStack[key]; -+ } -+ } -+ Object.assign(this._renderStack, newRenderStack); -+ for (var key in this._renderStack) { -+ if (this._renderStack.hasOwnProperty(key)) { -+ var index = this._renderStack[key].dataIndex; -+ if (!ts_object_utils_1.ObjectUtil.isNullOrUndefined(index) && ts_object_utils_1.ObjectUtil.isNullOrUndefined(this._engagedIndexes[index])) { -+ var type = this._layoutProvider.getLayoutTypeForIndex(index); -+ this._recyclePool.putRecycledObject(type, key); -+ } -+ } -+ } -+ }; -+ VirtualRenderer.prototype._getCollisionAvoidingKey = function () { -+ return "#" + this._startKey++ + "_rlv_c"; -+ }; -+ VirtualRenderer.prototype._prepareViewabilityTracker = function () { -+ if (this._viewabilityTracker && this._layoutManager && this._dimensions && this._params) { -+ this._viewabilityTracker.onEngagedRowsChanged = this._onEngagedItemsChanged; -+ if (this.onVisibleItemsChanged) { -+ this._viewabilityTracker.onVisibleRowsChanged = this._onVisibleItemsChanged; -+ } -+ this._viewabilityTracker.setLayouts(this._layoutManager.getLayouts(), this._params.isHorizontal ? -+ this._layoutManager.getContentDimension().width : -+ this._layoutManager.getContentDimension().height); -+ this._viewabilityTracker.setDimensions({ -+ height: this._dimensions.height, -+ width: this._dimensions.width, -+ }, ts_object_utils_1.Default.value(this._params.isHorizontal, false)); -+ } -+ else { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.initializationException); -+ } -+ }; -+ //Updates render stack and reports whether anything has changed -+ VirtualRenderer.prototype._updateRenderStack = function (itemIndexes) { -+ this._markDirty = false; -+ var count = itemIndexes.length; -+ var index = 0; -+ var hasRenderStackChanged = false; -+ for (var i = 0; i < count; i++) { -+ index = itemIndexes[i]; -+ this._engagedIndexes[index] = 1; -+ this.syncAndGetKey(index); -+ hasRenderStackChanged = this._markDirty; -+ } -+ this._markDirty = false; -+ return hasRenderStackChanged; -+ }; -+ return VirtualRenderer; -+}()); -+exports.default = VirtualRenderer; -+//# sourceMappingURL=VirtualRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js.map b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js.map -new file mode 100644 -index 0000000..30876cc ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/VirtualRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"VirtualRenderer.js","sourceRoot":"","sources":["../../../src/core/VirtualRenderer.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Constants.d.ts b/node_modules/recyclerlistview/dist/web/core/constants/Constants.d.ts -new file mode 100644 -index 0000000..977bb6a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/constants/Constants.d.ts -@@ -0,0 +1,3 @@ -+export declare const Constants: { -+ [key: string]: string; -+}; -diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Constants.js b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js -new file mode 100644 -index 0000000..c3323a1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js -@@ -0,0 +1,7 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.Constants = { -+ CONTEXT_PROVIDER_OFFSET_KEY_SUFFIX: "_offset", -+ CONTEXT_PROVIDER_LAYOUT_KEY_SUFFIX: "_layouts", -+}; -+//# sourceMappingURL=Constants.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Constants.js.map b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js.map -new file mode 100644 -index 0000000..e0d93e2 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/constants/Constants.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../../../src/core/constants/Constants.ts"],"names":[],"mappings":";;AAAa,QAAA,SAAS,GAA4B;IAC9C,kCAAkC,EAAG,SAAS;IAC9C,kCAAkC,EAAE,UAAU;CACjD,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Messages.d.ts b/node_modules/recyclerlistview/dist/web/core/constants/Messages.d.ts -new file mode 100644 -index 0000000..d211558 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/constants/Messages.d.ts -@@ -0,0 +1,3 @@ -+export declare const Messages: { -+ [key: string]: string; -+}; -diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Messages.js b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js -new file mode 100644 -index 0000000..51baf1f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js -@@ -0,0 +1,10 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+exports.Messages = { -+ ERROR_LISTVIEW_VALIDATION: "missing datasource or layout provider, cannot proceed without it", -+ WARN_SCROLL_TO_INDEX: "scrollTo was called before RecyclerListView was measured, please wait for the mount to finish", -+ WARN_NO_DATA: "You have mounted RecyclerListView with an empty data provider (Size in 0). Please mount only if there is atleast one item " + -+ "to ensure optimal performance and to avoid unexpected behavior", -+ VISIBLE_INDEXES_CHANGED_DEPRECATED: "onVisibleIndexesChanged deprecated. Please use onVisibleIndicesChanged instead.", -+}; -+//# sourceMappingURL=Messages.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/constants/Messages.js.map b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js.map -new file mode 100644 -index 0000000..9695650 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/constants/Messages.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../../src/core/constants/Messages.ts"],"names":[],"mappings":";;AAAa,QAAA,QAAQ,GAA4B;IAC7C,yBAAyB,EAAG,kEAAkE;IAC9F,oBAAoB,EAAE,+FAA+F;IACrH,YAAY,EAAE,4HAA4H;QAC5H,gEAAgE;IAC9E,kCAAkC,EAAE,iFAAiF;CACxH,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.d.ts b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.d.ts -new file mode 100644 -index 0000000..98abef9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.d.ts -@@ -0,0 +1,13 @@ -+/*** -+ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, -+ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you -+ * can instantly jump to any location. -+ * -+ * Use this interface and implement the given methods to preserve context. -+ */ -+export default abstract class ContextProvider { -+ abstract getUniqueKey(): string; -+ abstract save(key: string, value: string | number): void; -+ abstract get(key: string): string | number; -+ abstract remove(key: string): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js -new file mode 100644 -index 0000000..724fa5a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js -@@ -0,0 +1,16 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+/*** -+ * Context provider is useful in cases where your view gets destroyed and you want to maintain scroll position when recyclerlistview is recreated e.g, -+ * back navigation in android when previous fragments onDestroyView has already been called. Since recyclerlistview only renders visible items you -+ * can instantly jump to any location. -+ * -+ * Use this interface and implement the given methods to preserve context. -+ */ -+var ContextProvider = /** @class */ (function () { -+ function ContextProvider() { -+ } -+ return ContextProvider; -+}()); -+exports.default = ContextProvider; -+//# sourceMappingURL=ContextProvider.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js.map b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js.map -new file mode 100644 -index 0000000..27659b2 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/ContextProvider.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ContextProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/ContextProvider.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH;IAAA;IAYA,CAAC;IAAD,sBAAC;AAAD,CAAC,AAZD,IAYC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.d.ts b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.d.ts -new file mode 100644 -index 0000000..0844963 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.d.ts -@@ -0,0 +1,25 @@ -+/*** -+ * You can create a new instance or inherit and override default methods -+ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. -+ */ -+export declare abstract class BaseDataProvider { -+ rowHasChanged: (r1: any, r2: any) => boolean; -+ getStableId: (index: number) => string; -+ private _firstIndexToProcess; -+ private _size; -+ private _data; -+ private _hasStableIds; -+ private _requiresDataChangeHandling; -+ constructor(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string); -+ abstract newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: (index: number) => string): BaseDataProvider; -+ getDataForIndex(index: number): any; -+ getAllData(): any[]; -+ getSize(): number; -+ hasStableIds(): boolean; -+ requiresDataChangeHandling(): boolean; -+ getFirstIndexToProcessInternal(): number; -+ cloneWithRows(newData: any[], firstModifiedIndex?: number): DataProvider; -+} -+export default class DataProvider extends BaseDataProvider { -+ newInstance(rowHasChanged: (r1: any, r2: any) => boolean, getStableId?: ((index: number) => string) | undefined): BaseDataProvider; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js -new file mode 100644 -index 0000000..ee37484 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js -@@ -0,0 +1,94 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ts_object_utils_1 = require("ts-object-utils"); -+/*** -+ * You can create a new instance or inherit and override default methods -+ * Allows access to data and size. Clone with rows creates a new data provider and let listview know where to calculate row layout from. -+ */ -+var BaseDataProvider = /** @class */ (function () { -+ function BaseDataProvider(rowHasChanged, getStableId) { -+ this._firstIndexToProcess = 0; -+ this._size = 0; -+ this._data = []; -+ this._hasStableIds = false; -+ this._requiresDataChangeHandling = false; -+ this.rowHasChanged = rowHasChanged; -+ if (getStableId) { -+ this.getStableId = getStableId; -+ this._hasStableIds = true; -+ } -+ else { -+ this.getStableId = function (index) { return index.toString(); }; -+ } -+ } -+ BaseDataProvider.prototype.getDataForIndex = function (index) { -+ return this._data[index]; -+ }; -+ BaseDataProvider.prototype.getAllData = function () { -+ return this._data; -+ }; -+ BaseDataProvider.prototype.getSize = function () { -+ return this._size; -+ }; -+ BaseDataProvider.prototype.hasStableIds = function () { -+ return this._hasStableIds; -+ }; -+ BaseDataProvider.prototype.requiresDataChangeHandling = function () { -+ return this._requiresDataChangeHandling; -+ }; -+ BaseDataProvider.prototype.getFirstIndexToProcessInternal = function () { -+ return this._firstIndexToProcess; -+ }; -+ //No need to override this one -+ //If you already know the first row where rowHasChanged will be false pass it upfront to avoid loop -+ BaseDataProvider.prototype.cloneWithRows = function (newData, firstModifiedIndex) { -+ var dp = this.newInstance(this.rowHasChanged, this.getStableId); -+ var newSize = newData.length; -+ var iterCount = Math.min(this._size, newSize); -+ if (ts_object_utils_1.ObjectUtil.isNullOrUndefined(firstModifiedIndex)) { -+ var i = 0; -+ for (i = 0; i < iterCount; i++) { -+ if (this.rowHasChanged(this._data[i], newData[i])) { -+ break; -+ } -+ } -+ dp._firstIndexToProcess = i; -+ } -+ else { -+ dp._firstIndexToProcess = Math.max(Math.min(firstModifiedIndex, this._data.length), 0); -+ } -+ if (dp._firstIndexToProcess !== this._data.length) { -+ dp._requiresDataChangeHandling = true; -+ } -+ dp._data = newData; -+ dp._size = newSize; -+ return dp; -+ }; -+ return BaseDataProvider; -+}()); -+exports.BaseDataProvider = BaseDataProvider; -+var DataProvider = /** @class */ (function (_super) { -+ __extends(DataProvider, _super); -+ function DataProvider() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ DataProvider.prototype.newInstance = function (rowHasChanged, getStableId) { -+ return new DataProvider(rowHasChanged, getStableId); -+ }; -+ return DataProvider; -+}(BaseDataProvider)); -+exports.default = DataProvider; -+//# sourceMappingURL=DataProvider.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js.map b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js.map -new file mode 100644 -index 0000000..fd7dedf ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/DataProvider.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DataProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/DataProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mDAA6C;AAE7C;;;GAGG;AACH;IAWI,0BAAY,aAA4C,EAAE,WAAuC;QANzF,yBAAoB,GAAW,CAAC,CAAC;QACjC,UAAK,GAAW,CAAC,CAAC;QAClB,UAAK,GAAU,EAAE,CAAC;QAClB,kBAAa,GAAG,KAAK,CAAC;QACtB,gCAA2B,GAAG,KAAK,CAAC;QAGxC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,WAAW,EAAE;YACb,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;SAC7B;aAAM;YACH,IAAI,CAAC,WAAW,GAAG,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,QAAQ,EAAE,EAAhB,CAAgB,CAAC;SAClD;IACL,CAAC;IAIM,0CAAe,GAAtB,UAAuB,KAAa;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAEM,qCAAU,GAAjB;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,kCAAO,GAAd;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,uCAAY,GAAnB;QACI,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEM,qDAA0B,GAAjC;QACI,OAAO,IAAI,CAAC,2BAA2B,CAAC;IAC5C,CAAC;IAEM,yDAA8B,GAArC;QACI,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACrC,CAAC;IAED,8BAA8B;IAC9B,mGAAmG;IAC5F,wCAAa,GAApB,UAAqB,OAAc,EAAE,kBAA2B;QAC5D,IAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClE,IAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/B,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,4BAAU,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE;YAClD,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;gBAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC/C,MAAM;iBACT;aACJ;YACD,EAAE,CAAC,oBAAoB,GAAG,CAAC,CAAC;SAC/B;aAAM;YACH,EAAE,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1F;QACD,IAAI,EAAE,CAAC,oBAAoB,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAC/C,EAAE,CAAC,2BAA2B,GAAG,IAAI,CAAC;SACzC;QACD,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC;QACnB,OAAO,EAAE,CAAC;IACd,CAAC;IACL,uBAAC;AAAD,CAAC,AAvED,IAuEC;AAvEqB,4CAAgB;AAyEtC;IAA0C,gCAAgB;IAA1D;;IAIA,CAAC;IAHU,kCAAW,GAAlB,UAAmB,aAA4C,EAAE,WAAqD;QAClH,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC;IACL,mBAAC;AAAD,CAAC,AAJD,CAA0C,gBAAgB,GAIzD"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.d.ts b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.d.ts -new file mode 100644 -index 0000000..e832379 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.d.ts -@@ -0,0 +1,35 @@ -+import { Layout, LayoutManager } from "../layoutmanager/LayoutManager"; -+/** -+ * Created by talha.naqvi on 05/04/17. -+ * You can create a new instance or inherit and override default methods -+ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider -+ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all -+ * data upfront will only limit possibilites in the future. -+ * -+ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates -+ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. -+ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. -+ * -+ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. -+ */ -+export declare abstract class BaseLayoutProvider { -+ shouldRefreshWithAnchoring: boolean; -+ abstract newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; -+ abstract getLayoutTypeForIndex(index: number): string | number; -+ abstract checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; -+} -+export declare class LayoutProvider extends BaseLayoutProvider { -+ private _getLayoutTypeForIndex; -+ private _setLayoutForType; -+ private _tempDim; -+ private _lastLayoutManager; -+ constructor(getLayoutTypeForIndex: (index: number) => string | number, setLayoutForType: (type: string | number, dim: Dimension, index: number) => void); -+ newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager; -+ getLayoutTypeForIndex(index: number): string | number; -+ setComputedLayout(type: string | number, dimension: Dimension, index: number): void; -+ checkDimensionDiscrepancy(dimension: Dimension, type: string | number, index: number): boolean; -+} -+export interface Dimension { -+ height: number; -+ width: number; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js -new file mode 100644 -index 0000000..4f5dbdf ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js -@@ -0,0 +1,72 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var LayoutManager_1 = require("../layoutmanager/LayoutManager"); -+/** -+ * Created by talha.naqvi on 05/04/17. -+ * You can create a new instance or inherit and override default methods -+ * You may need access to data provider here, it might make sense to pass a function which lets you fetch the latest data provider -+ * Why only indexes? The answer is to allow data virtualization in the future. Since layouts are accessed much before the actual render assuming having all -+ * data upfront will only limit possibilites in the future. -+ * -+ * By design LayoutProvider forces you to think in terms of view types. What that means is that you'll always be dealing with a finite set of view templates -+ * with deterministic dimensions. We want to eliminate unnecessary re-layouts that happen when height, by mistake, is not taken into consideration. -+ * This patters ensures that your scrolling is as smooth as it gets. You can always increase the number of types to handle non deterministic scenarios. -+ * -+ * NOTE: You can also implement features such as ListView/GridView switch by simple changing your layout provider. -+ */ -+var BaseLayoutProvider = /** @class */ (function () { -+ function BaseLayoutProvider() { -+ //Unset if your new layout provider doesn't require firstVisibleIndex preservation on application -+ this.shouldRefreshWithAnchoring = true; -+ } -+ return BaseLayoutProvider; -+}()); -+exports.BaseLayoutProvider = BaseLayoutProvider; -+var LayoutProvider = /** @class */ (function (_super) { -+ __extends(LayoutProvider, _super); -+ function LayoutProvider(getLayoutTypeForIndex, setLayoutForType) { -+ var _this = _super.call(this) || this; -+ _this._getLayoutTypeForIndex = getLayoutTypeForIndex; -+ _this._setLayoutForType = setLayoutForType; -+ _this._tempDim = { height: 0, width: 0 }; -+ return _this; -+ } -+ LayoutProvider.prototype.newLayoutManager = function (renderWindowSize, isHorizontal, cachedLayouts) { -+ this._lastLayoutManager = new LayoutManager_1.WrapGridLayoutManager(this, renderWindowSize, isHorizontal, cachedLayouts); -+ return this._lastLayoutManager; -+ }; -+ //Provide a type for index, something which identifies the template of view about to load -+ LayoutProvider.prototype.getLayoutTypeForIndex = function (index) { -+ return this._getLayoutTypeForIndex(index); -+ }; -+ //Given a type and dimension set the dimension values on given dimension object -+ //You can also get index here if you add an extra argument but we don't recommend using it. -+ LayoutProvider.prototype.setComputedLayout = function (type, dimension, index) { -+ return this._setLayoutForType(type, dimension, index); -+ }; -+ LayoutProvider.prototype.checkDimensionDiscrepancy = function (dimension, type, index) { -+ var dimension1 = dimension; -+ this.setComputedLayout(type, this._tempDim, index); -+ var dimension2 = this._tempDim; -+ if (this._lastLayoutManager) { -+ this._lastLayoutManager.setMaxBounds(dimension2); -+ } -+ return dimension1.height !== dimension2.height || dimension1.width !== dimension2.width; -+ }; -+ return LayoutProvider; -+}(BaseLayoutProvider)); -+exports.LayoutProvider = LayoutProvider; -+//# sourceMappingURL=LayoutProvider.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js.map b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js.map -new file mode 100644 -index 0000000..d2bed0e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/dependencies/LayoutProvider.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"LayoutProvider.js","sourceRoot":"","sources":["../../../../src/core/dependencies/LayoutProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gEAA8F;AAE9F;;;;;;;;;;;;GAYG;AAEH;IAAA;QACI,iGAAiG;QAC1F,+BAA0B,GAAY,IAAI,CAAC;IAYtD,CAAC;IAAD,yBAAC;AAAD,CAAC,AAdD,IAcC;AAdqB,gDAAkB;AAgBxC;IAAoC,kCAAkB;IAOlD,wBAAY,qBAAyD,EAAE,gBAAgF;QAAvJ,YACI,iBAAO,SAIV;QAHG,KAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;QACpD,KAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QAC1C,KAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;IAC5C,CAAC;IAEM,yCAAgB,GAAvB,UAAwB,gBAA2B,EAAE,YAAsB,EAAE,aAAwB;QACjG,IAAI,CAAC,kBAAkB,GAAG,IAAI,qCAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACzG,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED,yFAAyF;IAClF,8CAAqB,GAA5B,UAA6B,KAAa;QACtC,OAAO,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,+EAA+E;IAC/E,2FAA2F;IACpF,0CAAiB,GAAxB,UAAyB,IAAqB,EAAE,SAAoB,EAAE,KAAa;QAC/E,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1D,CAAC;IAEM,kDAAyB,GAAhC,UAAiC,SAAoB,EAAE,IAAqB,EAAE,KAAa;QACvF,IAAM,UAAU,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,IAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;SACpD;QACD,OAAO,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC;IAC5F,CAAC;IACL,qBAAC;AAAD,CAAC,AAvCD,CAAoC,kBAAkB,GAuCrD;AAvCY,wCAAc"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.d.ts b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.d.ts -new file mode 100644 -index 0000000..d6e7c73 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.d.ts -@@ -0,0 +1,4 @@ -+import ResizeDebugHandler from "./resize/ResizeDebugHandler"; -+export interface DebugHandlers { -+ resizeDebugHandler?: ResizeDebugHandler; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js -new file mode 100644 -index 0000000..fe8175c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js -@@ -0,0 +1,3 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+//# sourceMappingURL=DebugHandlers.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js.map b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js.map -new file mode 100644 -index 0000000..332282c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/DebugHandlers.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DebugHandlers.js","sourceRoot":"","sources":["../../../../../src/core/devutils/debughandlers/DebugHandlers.ts"],"names":[],"mappings":""} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts -new file mode 100644 -index 0000000..e32b3c6 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.d.ts -@@ -0,0 +1,8 @@ -+import { Dimension } from "../../../.."; -+import ResizeDebugHandler from "./ResizeDebugHandler"; -+export default class DefaultResizeDebugHandler implements ResizeDebugHandler { -+ private readonly relaxation; -+ private readonly onRelaxationViolation; -+ constructor(relaxation: Dimension, onRelaxationViolation: (expectedDim: Dimension, actualDim: Dimension, index: number) => void); -+ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js -new file mode 100644 -index 0000000..258b921 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js -@@ -0,0 +1,25 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var DefaultResizeDebugHandler = /** @class */ (function () { -+ // Relaxation is the Dimension object where it accepts the relaxation to allow for each dimension. -+ // Any of the dimension (height or width) whose value for relaxation is less than 0 would be ignored. -+ function DefaultResizeDebugHandler(relaxation, onRelaxationViolation) { -+ this.relaxation = relaxation; -+ this.onRelaxationViolation = onRelaxationViolation; -+ } -+ DefaultResizeDebugHandler.prototype.resizeDebug = function (oldDim, newDim, index) { -+ var isViolated = false; -+ if (this.relaxation.height >= 0 && Math.abs(newDim.height - oldDim.height) >= this.relaxation.height) { -+ isViolated = true; -+ } -+ if (!isViolated && this.relaxation.width >= 0 && Math.abs(newDim.width - oldDim.width) >= this.relaxation.width) { -+ isViolated = true; -+ } -+ if (isViolated) { -+ this.onRelaxationViolation(oldDim, newDim, index); -+ } -+ }; -+ return DefaultResizeDebugHandler; -+}()); -+exports.default = DefaultResizeDebugHandler; -+//# sourceMappingURL=DefaultResizeDebugHandler.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map -new file mode 100644 -index 0000000..ccbb28c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/DefaultResizeDebugHandler.ts"],"names":[],"mappings":";;AAGA;IAII,kGAAkG;IAClG,qGAAqG;IACrG,mCAAmB,UAAqB,EAAE,qBAA4F;QAClI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACvD,CAAC;IAEM,+CAAW,GAAlB,UAAmB,MAAiB,EAAE,MAAiB,EAAE,KAAa;QAClE,IAAI,UAAU,GAAY,KAAK,CAAC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClG,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;YAC7G,UAAU,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,UAAU,EAAE;YACZ,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;SACrD;IACL,CAAC;IACL,gCAAC;AAAD,CAAC,AAzBD,IAyBC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts -new file mode 100644 -index 0000000..654f89d ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.d.ts -@@ -0,0 +1,4 @@ -+import { Dimension } from "../../../.."; -+export default interface ResizeDebugHandler { -+ resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js -new file mode 100644 -index 0000000..697bdb8 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js -@@ -0,0 +1,3 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+//# sourceMappingURL=ResizeDebugHandler.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map -new file mode 100644 -index 0000000..2122fce ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/devutils/debughandlers/resize/ResizeDebugHandler.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ResizeDebugHandler.js","sourceRoot":"","sources":["../../../../../../src/core/devutils/debughandlers/resize/ResizeDebugHandler.ts"],"names":[],"mappings":""} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.d.ts b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.d.ts -new file mode 100644 -index 0000000..67ab42e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.d.ts -@@ -0,0 +1,7 @@ -+export default class CustomError extends Error { -+ constructor(exception: Exception); -+} -+export interface Exception { -+ type: string; -+ message: string; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js -new file mode 100644 -index 0000000..6a6b17c ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js -@@ -0,0 +1,26 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var CustomError = /** @class */ (function (_super) { -+ __extends(CustomError, _super); -+ function CustomError(exception) { -+ var _this = _super.call(this, exception.message) || this; -+ _this.name = exception.type; -+ return _this; -+ } -+ return CustomError; -+}(Error)); -+exports.default = CustomError; -+//# sourceMappingURL=CustomError.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js.map b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js.map -new file mode 100644 -index 0000000..bbff8bd ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/exceptions/CustomError.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"CustomError.js","sourceRoot":"","sources":["../../../../src/core/exceptions/CustomError.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;IAAyC,+BAAK;IAC1C,qBAAY,SAAoB;QAAhC,YACI,kBAAM,SAAS,CAAC,OAAO,CAAC,SAE3B;QADG,KAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;;IAC/B,CAAC;IACL,kBAAC;AAAD,CAAC,AALD,CAAyC,KAAK,GAK7C"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.d.ts b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.d.ts -new file mode 100644 -index 0000000..7db4997 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.d.ts -@@ -0,0 +1,5 @@ -+import { Exception } from "./CustomError"; -+declare const RecyclerListViewExceptions: { -+ [key: string]: Exception; -+}; -+export default RecyclerListViewExceptions; -diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js -new file mode 100644 -index 0000000..26413ac ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js -@@ -0,0 +1,48 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecyclerListViewExceptions = { -+ initializationException: { -+ message: "Parameters required for initializing the module are missing", -+ type: "Initialization essentials missing", -+ }, -+ itemBoundsException: { -+ message: "Dimensions cannot be undefined or null, check if LayoutProvider returns irregular values", -+ type: "ItemBoundsException", -+ }, -+ itemTypeNullException: { -+ message: "RecyclerListView items always require a type, check if LayoutProvider returns irregular values", -+ type: "ItemTypeNullException", -+ }, -+ layoutException: { -+ message: "RecyclerListView needs to have a bounded size. Currently height or, width is 0." + -+ "Consider adding style={{flex:1}} or, fixed dimensions", -+ type: "LayoutException", -+ }, -+ platformNotDetectedException: { -+ message: "Unable to detect the running platform, if you're trying to run recyclerlistview " + -+ "in browser make sure process.env.RLV_ENV is set to browser in webpack config", -+ type: "PlatformNotDetectedException", -+ }, -+ unresolvedDependenciesException: { -+ message: "missing datasource or layout provider, cannot proceed without it", -+ type: "UnresolvedDependenciesException", -+ }, -+ refNotAsFunctionException: { -+ message: "When using StickyContainer, RecyclerListView needs to use ref as a function and not as a string.", -+ type: "RefNotAsFunctionException", -+ }, -+ wrongStickyChildTypeException: { -+ message: "StickyContainer can only have a single child of type RecyclerListView.", -+ type: "WrongStickyChildTypeException", -+ }, -+ usingOldVisibleIndexesChangedParam: { -+ message: "onVisibleIndexesChanged has been deprecated. Please use onVisibleIndicesChanged instead.", -+ type: "usingOldVisibleIndexesChangedParam", -+ }, -+ stickyIndicesArraySortError: { -+ message: "The sticky indices array passed to StickyContainer isn't sorted in ascending order.", -+ type: "stickyIndicesArraySortError", -+ }, -+}; -+exports.default = RecyclerListViewExceptions; -+//# sourceMappingURL=RecyclerListViewExceptions.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js.map b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js.map -new file mode 100644 -index 0000000..75634b0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/exceptions/RecyclerListViewExceptions.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"RecyclerListViewExceptions.js","sourceRoot":"","sources":["../../../../src/core/exceptions/RecyclerListViewExceptions.ts"],"names":[],"mappings":";;AAEA,IAAM,0BAA0B,GAA+B;IAC3D,uBAAuB,EAAE;QACrB,OAAO,EAAE,6DAA6D;QACtE,IAAI,EAAE,mCAAmC;KAC5C;IACD,mBAAmB,EAAE;QACjB,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,qBAAqB;KAC9B;IACD,qBAAqB,EAAE;QACnB,OAAO,EAAE,gGAAgG;QACzG,IAAI,EAAE,uBAAuB;KAChC;IACD,eAAe,EAAE;QACb,OAAO,EAAE,iFAAiF;YAC9E,uDAAuD;QACnE,IAAI,EAAE,iBAAiB;KAC1B;IACD,4BAA4B,EAAE;QAC1B,OAAO,EAAE,kFAAkF;YAC3F,8EAA8E;QAC9E,IAAI,EAAE,8BAA8B;KACvC;IACD,+BAA+B,EAAE;QAC7B,OAAO,EAAE,kEAAkE;QAC3E,IAAI,EAAE,iCAAiC;KAC1C;IACD,yBAAyB,EAAE;QACvB,OAAO,EAAE,kGAAkG;QAC3G,IAAI,EAAE,2BAA2B;KACpC;IACD,6BAA6B,EAAE;QAC3B,OAAO,EAAE,wEAAwE;QACjF,IAAI,EAAE,+BAA+B;KACxC;IACD,kCAAkC,EAAE;QAChC,OAAO,EAAE,0FAA0F;QACnG,IAAI,EAAE,oCAAoC;KAC7C;IACD,2BAA2B,EAAE;QACzB,OAAO,EAAE,qFAAqF;QAC9F,IAAI,EAAE,6BAA6B;KACtC;CACJ,CAAC;AACF,kBAAe,0BAA0B,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.d.ts b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.d.ts -new file mode 100644 -index 0000000..51b60d7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.d.ts -@@ -0,0 +1,40 @@ -+/*** -+ * Computes the positions and dimensions of items that will be rendered by the list. The output from this is utilized by viewability tracker to compute the -+ * lists of visible/hidden item. -+ */ -+import { Dimension, LayoutProvider } from "../dependencies/LayoutProvider"; -+export declare abstract class LayoutManager { -+ getOffsetForIndex(index: number): Point; -+ getStyleOverridesForIndex(index: number): object | undefined; -+ abstract getContentDimension(): Dimension; -+ abstract getLayouts(): Layout[]; -+ abstract overrideLayout(index: number, dim: Dimension): boolean; -+ abstract relayoutFromIndex(startIndex: number, itemCount: number): void; -+} -+export declare class WrapGridLayoutManager extends LayoutManager { -+ private _layoutProvider; -+ private _window; -+ private _totalHeight; -+ private _totalWidth; -+ private _isHorizontal; -+ private _layouts; -+ constructor(layoutProvider: LayoutProvider, renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]); -+ getContentDimension(): Dimension; -+ getLayouts(): Layout[]; -+ getOffsetForIndex(index: number): Point; -+ overrideLayout(index: number, dim: Dimension): boolean; -+ setMaxBounds(itemDim: Dimension): void; -+ relayoutFromIndex(startIndex: number, itemCount: number): void; -+ private _pointDimensionsToRect; -+ private _setFinalDimensions; -+ private _locateFirstNeighbourIndex; -+ private _checkBounds; -+} -+export interface Layout extends Dimension, Point { -+ isOverridden?: boolean; -+ type: string | number; -+} -+export interface Point { -+ x: number; -+ y: number; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js -new file mode 100644 -index 0000000..23075a0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js -@@ -0,0 +1,196 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var CustomError_1 = require("../exceptions/CustomError"); -+var LayoutManager = /** @class */ (function () { -+ function LayoutManager() { -+ } -+ LayoutManager.prototype.getOffsetForIndex = function (index) { -+ var layouts = this.getLayouts(); -+ if (layouts.length > index) { -+ return { x: layouts[index].x, y: layouts[index].y }; -+ } -+ else { -+ throw new CustomError_1.default({ -+ message: "No layout available for index: " + index, -+ type: "LayoutUnavailableException", -+ }); -+ } -+ }; -+ //You can ovveride this incase you want to override style in some cases e.g, say you want to enfore width but not height -+ LayoutManager.prototype.getStyleOverridesForIndex = function (index) { -+ return undefined; -+ }; -+ return LayoutManager; -+}()); -+exports.LayoutManager = LayoutManager; -+var WrapGridLayoutManager = /** @class */ (function (_super) { -+ __extends(WrapGridLayoutManager, _super); -+ function WrapGridLayoutManager(layoutProvider, renderWindowSize, isHorizontal, cachedLayouts) { -+ if (isHorizontal === void 0) { isHorizontal = false; } -+ var _this = _super.call(this) || this; -+ _this._layoutProvider = layoutProvider; -+ _this._window = renderWindowSize; -+ _this._totalHeight = 0; -+ _this._totalWidth = 0; -+ _this._isHorizontal = !!isHorizontal; -+ _this._layouts = cachedLayouts ? cachedLayouts : []; -+ return _this; -+ } -+ WrapGridLayoutManager.prototype.getContentDimension = function () { -+ return { height: this._totalHeight, width: this._totalWidth }; -+ }; -+ WrapGridLayoutManager.prototype.getLayouts = function () { -+ return this._layouts; -+ }; -+ WrapGridLayoutManager.prototype.getOffsetForIndex = function (index) { -+ if (this._layouts.length > index) { -+ return { x: this._layouts[index].x, y: this._layouts[index].y }; -+ } -+ else { -+ throw new CustomError_1.default({ -+ message: "No layout available for index: " + index, -+ type: "LayoutUnavailableException", -+ }); -+ } -+ }; -+ WrapGridLayoutManager.prototype.overrideLayout = function (index, dim) { -+ var layout = this._layouts[index]; -+ if (layout) { -+ layout.isOverridden = true; -+ layout.width = dim.width; -+ layout.height = dim.height; -+ } -+ return true; -+ }; -+ WrapGridLayoutManager.prototype.setMaxBounds = function (itemDim) { -+ if (this._isHorizontal) { -+ itemDim.height = Math.min(this._window.height, itemDim.height); -+ } -+ else { -+ itemDim.width = Math.min(this._window.width, itemDim.width); -+ } -+ }; -+ //TODO:Talha laziliy calculate in future revisions -+ WrapGridLayoutManager.prototype.relayoutFromIndex = function (startIndex, itemCount) { -+ startIndex = this._locateFirstNeighbourIndex(startIndex); -+ var startX = 0; -+ var startY = 0; -+ var maxBound = 0; -+ var startVal = this._layouts[startIndex]; -+ if (startVal) { -+ startX = startVal.x; -+ startY = startVal.y; -+ this._pointDimensionsToRect(startVal); -+ } -+ var oldItemCount = this._layouts.length; -+ var itemDim = { height: 0, width: 0 }; -+ var itemRect = null; -+ var oldLayout = null; -+ for (var i = startIndex; i < itemCount; i++) { -+ oldLayout = this._layouts[i]; -+ var layoutType = this._layoutProvider.getLayoutTypeForIndex(i); -+ if (oldLayout && oldLayout.isOverridden && oldLayout.type === layoutType) { -+ itemDim.height = oldLayout.height; -+ itemDim.width = oldLayout.width; -+ } -+ else { -+ this._layoutProvider.setComputedLayout(layoutType, itemDim, i); -+ } -+ this.setMaxBounds(itemDim); -+ while (!this._checkBounds(startX, startY, itemDim, this._isHorizontal)) { -+ if (this._isHorizontal) { -+ startX += maxBound; -+ startY = 0; -+ this._totalWidth += maxBound; -+ } -+ else { -+ startX = 0; -+ startY += maxBound; -+ this._totalHeight += maxBound; -+ } -+ maxBound = 0; -+ } -+ maxBound = this._isHorizontal ? Math.max(maxBound, itemDim.width) : Math.max(maxBound, itemDim.height); -+ //TODO: Talha creating array upfront will speed this up -+ if (i > oldItemCount - 1) { -+ this._layouts.push({ x: startX, y: startY, height: itemDim.height, width: itemDim.width, type: layoutType }); -+ } -+ else { -+ itemRect = this._layouts[i]; -+ itemRect.x = startX; -+ itemRect.y = startY; -+ itemRect.type = layoutType; -+ itemRect.width = itemDim.width; -+ itemRect.height = itemDim.height; -+ } -+ if (this._isHorizontal) { -+ startY += itemDim.height; -+ } -+ else { -+ startX += itemDim.width; -+ } -+ } -+ if (oldItemCount > itemCount) { -+ this._layouts.splice(itemCount, oldItemCount - itemCount); -+ } -+ this._setFinalDimensions(maxBound); -+ }; -+ WrapGridLayoutManager.prototype._pointDimensionsToRect = function (itemRect) { -+ if (this._isHorizontal) { -+ this._totalWidth = itemRect.x; -+ } -+ else { -+ this._totalHeight = itemRect.y; -+ } -+ }; -+ WrapGridLayoutManager.prototype._setFinalDimensions = function (maxBound) { -+ if (this._isHorizontal) { -+ this._totalHeight = this._window.height; -+ this._totalWidth += maxBound; -+ } -+ else { -+ this._totalWidth = this._window.width; -+ this._totalHeight += maxBound; -+ } -+ }; -+ WrapGridLayoutManager.prototype._locateFirstNeighbourIndex = function (startIndex) { -+ if (startIndex === 0) { -+ return 0; -+ } -+ var i = startIndex - 1; -+ for (; i >= 0; i--) { -+ if (!this._layouts[i]) { -+ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line -+ continue; -+ } -+ if (this._isHorizontal) { -+ if (this._layouts[i].y === 0) { -+ break; -+ } -+ } -+ else if (this._layouts[i].x === 0) { -+ break; -+ } -+ } -+ return i; -+ }; -+ WrapGridLayoutManager.prototype._checkBounds = function (itemX, itemY, itemDim, isHorizontal) { -+ return isHorizontal ? (itemY + itemDim.height <= this._window.height) : (itemX + itemDim.width <= this._window.width); -+ }; -+ return WrapGridLayoutManager; -+}(LayoutManager)); -+exports.WrapGridLayoutManager = WrapGridLayoutManager; -+//# sourceMappingURL=LayoutManager.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js.map b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js.map -new file mode 100644 -index 0000000..3129d8e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/layoutmanager/LayoutManager.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"LayoutManager.js","sourceRoot":"","sources":["../../../../src/core/layoutmanager/LayoutManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAKA,yDAAoD;AAEpD;IAAA;IAiCA,CAAC;IAhCU,yCAAiB,GAAxB,UAAyB,KAAa;QAClC,IAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,EAAE;YACxB,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD;aAAM;YACH,MAAM,IAAI,qBAAW,CAAC;gBAClB,OAAO,EAAE,iCAAiC,GAAG,KAAK;gBAClD,IAAI,EAAE,4BAA4B;aACrC,CAAC,CAAC;SACN;IACL,CAAC;IAED,wHAAwH;IACjH,iDAAyB,GAAhC,UAAiC,KAAa;QAC1C,OAAO,SAAS,CAAC;IACrB,CAAC;IAiBL,oBAAC;AAAD,CAAC,AAjCD,IAiCC;AAjCqB,sCAAa;AAmCnC;IAA2C,yCAAa;IAQpD,+BAAY,cAA8B,EAAE,gBAA2B,EAAE,YAA6B,EAAE,aAAwB;QAAvD,6BAAA,EAAA,oBAA6B;QAAtG,YACI,iBAAO,SAOV;QANG,KAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,KAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC;QAChC,KAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,KAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,KAAI,CAAC,aAAa,GAAG,CAAC,CAAC,YAAY,CAAC;QACpC,KAAI,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;;IACvD,CAAC;IAEM,mDAAmB,GAA1B;QACI,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;IAClE,CAAC;IAEM,0CAAU,GAAjB;QACI,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEM,iDAAiB,GAAxB,UAAyB,KAAa;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,EAAE;YAC9B,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE;aAAM;YACH,MAAM,IAAI,qBAAW,CAAC;gBAClB,OAAO,EAAE,iCAAiC,GAAG,KAAK;gBAClD,IAAI,EAAE,4BAA4B;aACrC,CAAC,CAAC;SACN;IACL,CAAC;IAEM,8CAAc,GAArB,UAAsB,KAAa,EAAE,GAAc;QAC/C,IAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,MAAM,EAAE;YACR,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACzB,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;SAC9B;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,4CAAY,GAAnB,UAAoB,OAAkB;QAClC,IAAI,IAAI,CAAC,aAAa,EAAE;YACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;SAClE;aAAM;YACH,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;SAC/D;IACL,CAAC;IAED,kDAAkD;IAC3C,iDAAiB,GAAxB,UAAyB,UAAkB,EAAE,SAAiB;QAC1D,UAAU,GAAG,IAAI,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,IAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,QAAQ,EAAE;YACV,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;YACpB,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;SACzC;QAED,IAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1C,IAAM,OAAO,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACxC,IAAI,QAAQ,GAAG,IAAI,CAAC;QAEpB,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YACzC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACjE,IAAI,SAAS,IAAI,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE;gBACtE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;gBAClC,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;aACnC;iBAAM;gBACH,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;aAClE;YACD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE;gBACpE,IAAI,IAAI,CAAC,aAAa,EAAE;oBACpB,MAAM,IAAI,QAAQ,CAAC;oBACnB,MAAM,GAAG,CAAC,CAAC;oBACX,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC;iBAChC;qBAAM;oBACH,MAAM,GAAG,CAAC,CAAC;oBACX,MAAM,IAAI,QAAQ,CAAC;oBACnB,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;iBACjC;gBACD,QAAQ,GAAG,CAAC,CAAC;aAChB;YAED,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAEvG,uDAAuD;YACvD,IAAI,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE;gBACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;aAChH;iBAAM;gBACH,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC5B,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC;gBACpB,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC;gBACpB,QAAQ,CAAC,IAAI,GAAG,UAAU,CAAC;gBAC3B,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBAC/B,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;aACpC;YAED,IAAI,IAAI,CAAC,aAAa,EAAE;gBACpB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;aAC5B;iBAAM;gBACH,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC;aAC3B;SACJ;QACD,IAAI,YAAY,GAAG,SAAS,EAAE;YAC1B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC;SAC7D;QACD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAEO,sDAAsB,GAA9B,UAA+B,QAAgB;QAC3C,IAAI,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC;SACjC;aAAM;YACH,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC;SAClC;IACL,CAAC;IAEO,mDAAmB,GAA3B,UAA4B,QAAgB;QACxC,IAAI,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACxC,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC;SAChC;aAAM;YACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACtC,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;SACjC;IACL,CAAC;IAEO,0DAA0B,GAAlC,UAAmC,UAAkB;QACjD,IAAI,UAAU,KAAK,CAAC,EAAE;YAClB,OAAO,CAAC,CAAC;SACZ;QACD,IAAI,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;YAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;gBACnB,OAAO,CAAC,IAAI,CAAC,uCAAuC,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,qBAAqB;gBACjG,SAAS;aACZ;YACD,IAAI,IAAI,CAAC,aAAa,EAAE;gBACpB,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;oBAC1B,MAAM;iBACT;aACJ;iBAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;gBACjC,MAAM;aACT;SACJ;QACD,OAAO,CAAC,CAAC;IACb,CAAC;IAEO,4CAAY,GAApB,UAAqB,KAAa,EAAE,KAAa,EAAE,OAAkB,EAAE,YAAqB;QACxF,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1H,CAAC;IACL,4BAAC;AAAD,CAAC,AAvKD,CAA2C,aAAa,GAuKvD;AAvKY,sDAAqB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.d.ts b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.d.ts -new file mode 100644 -index 0000000..fbf1ac9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.d.ts -@@ -0,0 +1,21 @@ -+import * as React from "react"; -+import { Dimension } from "../dependencies/LayoutProvider"; -+import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./BaseScrollView"; -+export interface ScrollComponentProps { -+ onSizeChanged: (dimensions: Dimension) => void; -+ onScroll: (offsetX: number, offsetY: number, rawEvent: ScrollEvent) => void; -+ contentHeight: number; -+ contentWidth: number; -+ canChangeSize?: boolean; -+ externalScrollView?: { -+ new (props: ScrollViewDefaultProps): BaseScrollView; -+ }; -+ isHorizontal?: boolean; -+ renderFooter?: () => JSX.Element | JSX.Element[] | null; -+ scrollThrottle?: number; -+ useWindowScroll?: boolean; -+ onLayout?: any; -+} -+export default abstract class BaseScrollComponent extends React.Component { -+ abstract scrollTo(x: number, y: number, animate: boolean): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js -new file mode 100644 -index 0000000..821b8f8 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js -@@ -0,0 +1,25 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollComponent = /** @class */ (function (_super) { -+ __extends(BaseScrollComponent, _super); -+ function BaseScrollComponent() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ return BaseScrollComponent; -+}(React.Component)); -+exports.default = BaseScrollComponent; -+//# sourceMappingURL=BaseScrollComponent.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js.map b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js.map -new file mode 100644 -index 0000000..1be170f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollComponent.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BaseScrollComponent.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAiB/B;IAA0D,uCAAyC;IAAnG;;IAEA,CAAC;IAAD,0BAAC;AAAD,CAAC,AAFD,CAA0D,KAAK,CAAC,SAAS,GAExE"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.d.ts b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.d.ts -new file mode 100644 -index 0000000..d29def1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.d.ts -@@ -0,0 +1,29 @@ -+import * as React from "react"; -+import { CSSProperties } from "react"; -+import { Dimension } from "../dependencies/LayoutProvider"; -+export interface ScrollViewDefaultProps { -+ onScroll: (event: ScrollEvent) => void; -+ onSizeChanged: (dimensions: Dimension) => void; -+ horizontal: boolean; -+ canChangeSize: boolean; -+ style?: CSSProperties | null; -+ useWindowScroll: boolean; -+} -+export interface ScrollEvent { -+ nativeEvent: { -+ contentOffset: { -+ x: number; -+ y: number; -+ }; -+ layoutMeasurement?: Dimension; -+ contentSize?: Dimension; -+ }; -+} -+export default abstract class BaseScrollView extends React.Component { -+ constructor(props: ScrollViewDefaultProps); -+ abstract scrollTo(scrollInput: { -+ x: number; -+ y: number; -+ animated: boolean; -+ }): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js -new file mode 100644 -index 0000000..694e0ae ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js -@@ -0,0 +1,25 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollView = /** @class */ (function (_super) { -+ __extends(BaseScrollView, _super); -+ function BaseScrollView(props) { -+ return _super.call(this, props) || this; -+ } -+ return BaseScrollView; -+}(React.Component)); -+exports.default = BaseScrollView; -+//# sourceMappingURL=BaseScrollView.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js.map b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js.map -new file mode 100644 -index 0000000..4230976 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/scrollcomponent/BaseScrollView.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BaseScrollView.js","sourceRoot":"","sources":["../../../../src/core/scrollcomponent/BaseScrollView.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AAsB/B;IAAqD,kCAA2C;IAC5F,wBAAY,KAA6B;eACrC,kBAAM,KAAK,CAAC;IAChB,CAAC;IAGL,qBAAC;AAAD,CAAC,AAND,CAAqD,KAAK,CAAC,SAAS,GAMnE"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.d.ts b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.d.ts -new file mode 100644 -index 0000000..a7af807 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.d.ts -@@ -0,0 +1,13 @@ -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; -+export default class StickyFooter

extends StickyObject { -+ constructor(props: P, context?: any); -+ protected initStickyParams(): void; -+ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, _smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; -+ protected getNextYd(nextY: number, nextHeight: number): number; -+ protected getCurrentYd(currentY: number, currentHeight: number): number; -+ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; -+ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js -new file mode 100644 -index 0000000..1a1b02f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js -@@ -0,0 +1,70 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var StickyObject_1 = require("./StickyObject"); -+var BinarySearch_1 = require("../../utils/BinarySearch"); -+var StickyFooter = /** @class */ (function (_super) { -+ __extends(StickyFooter, _super); -+ function StickyFooter(props, context) { -+ return _super.call(this, props, context) || this; -+ } -+ StickyFooter.prototype.initStickyParams = function () { -+ this.stickyType = StickyObject_1.StickyType.FOOTER; -+ this.stickyTypeMultiplier = -1; -+ this.containerPosition = { bottom: 0 }; -+ this.bounceScrolling = false; -+ }; -+ StickyFooter.prototype.calculateVisibleStickyIndex = function (stickyIndices, _smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow, windowBound) { -+ if (stickyIndices && largestVisibleIndex) { -+ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); -+ if (largestVisibleIndex > stickyIndices[stickyIndices.length - 1] || this.bounceScrolling) { -+ this.stickyVisiblity = false; -+ } -+ else { -+ this.stickyVisiblity = true; -+ var valueAndIndex = BinarySearch_1.default.findValueLargerThanTarget(stickyIndices, largestVisibleIndex); -+ if (valueAndIndex) { -+ this.currentIndex = valueAndIndex.index; -+ this.currentStickyIndex = valueAndIndex.value; -+ } -+ else { -+ console.log("Footer sticky index calculation gone wrong."); //tslint:disable-line -+ } -+ } -+ } -+ }; -+ StickyFooter.prototype.getNextYd = function (nextY, nextHeight) { -+ return -1 * (nextY + nextHeight); -+ }; -+ StickyFooter.prototype.getCurrentYd = function (currentY, currentHeight) { -+ return -1 * (currentY + currentHeight); -+ }; -+ StickyFooter.prototype.getScrollY = function (offsetY, scrollableHeight) { -+ return scrollableHeight ? -1 * (offsetY + scrollableHeight) : undefined; -+ }; -+ StickyFooter.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, windowBound) { -+ if (windowBound) { -+ var endReachedMargin = Math.round(offsetY - (windowBound + distanceFromWindow)); -+ return endReachedMargin >= 0; -+ } -+ return false; -+ }; -+ return StickyFooter; -+}(StickyObject_1.default)); -+exports.default = StickyFooter; -+//# sourceMappingURL=StickyFooter.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js.map b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js.map -new file mode 100644 -index 0000000..1c899a7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyFooter.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyFooter.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyFooter.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAC,MAAM,EAAE,CAAC,EAAC,CAAC;QACrC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IACjC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,qBAA6B,EAAE,mBAA2B,EAC/F,OAAe,EAAE,kBAA0B,EAAE,WAAqB;QAElE,IAAI,aAAa,IAAI,mBAAmB,EAAE;YACtC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;YACzF,IAAI,mBAAmB,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACvF,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,yBAAyB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;gBAC5H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC;IACrC,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC;IAC3C,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,WAAoB;QAC1F,IAAI,WAAW,EAAE;YACb,IAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC;YAClF,OAAO,gBAAgB,IAAI,CAAC,CAAC;SAChC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IACL,mBAAC;AAAD,CAAC,AApDD,CAAoG,sBAAY,GAoD/G"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.d.ts b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.d.ts -new file mode 100644 -index 0000000..08481a0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.d.ts -@@ -0,0 +1,13 @@ -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+import StickyObject, { StickyObjectProps, StickyObjectState } from "./StickyObject"; -+export default class StickyHeader

extends StickyObject { -+ constructor(props: P, context?: any); -+ protected initStickyParams(): void; -+ protected calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number): void; -+ protected getNextYd(nextY: number, nextHeight: number): number; -+ protected getCurrentYd(currentY: number, currentHeight: number): number; -+ protected getScrollY(offsetY: number, scrollableHeight: number): number | undefined; -+ protected hasReachedBoundary(offsetY: number, distanceFromWindow: number, _windowBound?: number): boolean; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js -new file mode 100644 -index 0000000..5e72f6e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js -@@ -0,0 +1,68 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var StickyObject_1 = require("./StickyObject"); -+var BinarySearch_1 = require("../../utils/BinarySearch"); -+var StickyHeader = /** @class */ (function (_super) { -+ __extends(StickyHeader, _super); -+ function StickyHeader(props, context) { -+ return _super.call(this, props, context) || this; -+ } -+ StickyHeader.prototype.initStickyParams = function () { -+ this.stickyType = StickyObject_1.StickyType.HEADER; -+ this.stickyTypeMultiplier = 1; -+ this.containerPosition = { top: 0 }; -+ // Kept as true contrary to as in StickyFooter because in case of initialOffset not given, onScroll isn't called and boundaryProcessing isn't done. -+ // Default behaviour in that case will be sticky header hidden. -+ this.bounceScrolling = true; -+ }; -+ StickyHeader.prototype.calculateVisibleStickyIndex = function (stickyIndices, smallestVisibleIndex, largestVisibleIndex, offsetY, distanceFromWindow) { -+ if (stickyIndices && smallestVisibleIndex !== undefined) { -+ this.bounceScrolling = this.hasReachedBoundary(offsetY, distanceFromWindow); -+ if (smallestVisibleIndex < stickyIndices[0] || this.bounceScrolling) { -+ this.stickyVisiblity = false; -+ } -+ else { -+ this.stickyVisiblity = true; -+ var valueAndIndex = BinarySearch_1.default.findValueSmallerThanTarget(stickyIndices, smallestVisibleIndex); -+ if (valueAndIndex) { -+ this.currentIndex = valueAndIndex.index; -+ this.currentStickyIndex = valueAndIndex.value; -+ } -+ else { -+ console.log("Header sticky index calculation gone wrong."); //tslint:disable-line -+ } -+ } -+ } -+ }; -+ StickyHeader.prototype.getNextYd = function (nextY, nextHeight) { -+ return nextY; -+ }; -+ StickyHeader.prototype.getCurrentYd = function (currentY, currentHeight) { -+ return currentY; -+ }; -+ StickyHeader.prototype.getScrollY = function (offsetY, scrollableHeight) { -+ return offsetY; -+ }; -+ StickyHeader.prototype.hasReachedBoundary = function (offsetY, distanceFromWindow, _windowBound) { -+ return offsetY < distanceFromWindow; -+ }; -+ return StickyHeader; -+}(StickyObject_1.default)); -+exports.default = StickyHeader; -+//# sourceMappingURL=StickyHeader.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js.map b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js.map -new file mode 100644 -index 0000000..aef0aaa ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyHeader.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyHeader.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyHeader.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,+CAA8F;AAC9F,yDAAqE;AAErE;IAAoG,gCAAkB;IAClH,sBAAY,KAAQ,EAAE,OAAa;eAC/B,kBAAM,KAAK,EAAE,OAAO,CAAC;IACzB,CAAC;IAES,uCAAgB,GAA1B;QACI,IAAI,CAAC,UAAU,GAAG,yBAAU,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,iBAAiB,GAAG,EAAC,GAAG,EAAE,CAAC,EAAC,CAAC;QAElC,mJAAmJ;QACnJ,+DAA+D;QAC/D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAChC,CAAC;IAES,kDAA2B,GAArC,UACI,aAAmC,EAAE,oBAA4B,EAAE,mBAA2B,EAAE,OAAe,EAAE,kBAA0B;QAE3I,IAAI,aAAa,IAAI,oBAAoB,KAAK,SAAS,EAAE;YACrD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC5E,IAAI,oBAAoB,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE;gBACjE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;aAChC;iBAAM;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAM,aAAa,GAA8B,sBAAY,CAAC,0BAA0B,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;gBAC9H,IAAI,aAAa,EAAE;oBACf,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;oBACxC,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;iBACjD;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC,qBAAqB;iBACpF;aACJ;SACJ;IACL,CAAC;IAES,gCAAS,GAAnB,UAAoB,KAAa,EAAE,UAAkB;QACjD,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,mCAAY,GAAtB,UAAuB,QAAgB,EAAE,aAAqB;QAC1D,OAAO,QAAQ,CAAC;IACpB,CAAC;IAES,iCAAU,GAApB,UAAqB,OAAe,EAAE,gBAAwB;QAC1D,OAAO,OAAO,CAAC;IACnB,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,YAAqB;QAC3F,OAAO,OAAO,GAAG,kBAAkB,CAAC;IACxC,CAAC;IACL,mBAAC;AAAD,CAAC,AAlDD,CAAoG,sBAAY,GAkD/G"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.d.ts b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.d.ts -new file mode 100644 -index 0000000..ed5976f ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.d.ts -@@ -0,0 +1,74 @@ -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+import * as React from "react"; -+import { StyleProp, ViewStyle } from "react-native"; -+import { Layout } from "../layoutmanager/LayoutManager"; -+import { Dimension } from "../dependencies/LayoutProvider"; -+export declare enum StickyType { -+ HEADER = 0, -+ FOOTER = 1 -+} -+export interface StickyObjectProps { -+ stickyIndices: number[] | undefined; -+ getLayoutForIndex: (index: number) => Layout | undefined; -+ getDataForIndex: (index: number) => any; -+ getLayoutTypeForIndex: (index: number) => string | number; -+ getExtendedState: () => object | undefined; -+ getRLVRenderedSize: () => Dimension | undefined; -+ getContentDimension: () => Dimension | undefined; -+ getRowRenderer: () => ((type: string | number, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null); -+ getDistanceFromWindow: () => number; -+ overrideRowRenderer?: (type: string | number | undefined, data: any, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+} -+export interface StickyObjectState { -+ visibility: boolean; -+} -+export default abstract class StickyObject

extends React.Component { -+ protected stickyType: StickyType; -+ protected stickyTypeMultiplier: number; -+ protected stickyVisiblity: boolean; -+ protected visibility: boolean; -+ protected containerPosition: StyleProp; -+ protected currentIndex: number; -+ protected currentStickyIndex: number; -+ protected visibleIndices: number[]; -+ protected bounceScrolling: boolean; -+ private _previousLayout; -+ private _previousHeight; -+ private _nextLayout; -+ private _nextY; -+ private _nextHeight; -+ private _currentLayout; -+ private _currentY; -+ private _currentHeight; -+ private _nextYd; -+ private _currentYd; -+ private _scrollableHeight; -+ private _scrollableWidth; -+ private _windowBound; -+ private _stickyViewOffset; -+ private _previousStickyIndex; -+ private _nextStickyIndex; -+ private _firstCompute; -+ private _smallestVisibleIndex; -+ private _largestVisibleIndex; -+ private _offsetY; -+ constructor(props: P, context?: any); -+ componentWillReceiveProps(newProps: StickyObjectProps): void; -+ render(): JSX.Element | null; -+ onVisibleIndicesChanged(all: number[]): void; -+ onScroll(offsetY: number): void; -+ protected abstract hasReachedBoundary(offsetY: number, distanceFromWindow: number, windowBound?: number): boolean; -+ protected abstract initStickyParams(): void; -+ protected abstract calculateVisibleStickyIndex(stickyIndices: number[] | undefined, smallestVisibleIndex: number, largestVisibleIndex: number, offsetY: number, distanceFromWindow: number, windowBound?: number): void; -+ protected abstract getNextYd(_nextY: number, nextHeight: number): number; -+ protected abstract getCurrentYd(currentY: number, currentHeight: number): number; -+ protected abstract getScrollY(offsetY: number, scrollableHeight?: number): number | undefined; -+ protected stickyViewVisible(_visible: boolean): void; -+ protected boundaryProcessing(offsetY: number, distanceFromWindow: number, windowBound?: number): void; -+ private _initParams; -+ private _computeLayouts; -+ private _setSmallestAndLargestVisibleIndices; -+ private _renderSticky; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js -new file mode 100644 -index 0000000..4964223 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js -@@ -0,0 +1,203 @@ -+"use strict"; -+/** -+ * Created by ananya.chandra on 20/09/18. -+ */ -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var react_native_1 = require("react-native"); -+var RecyclerListViewExceptions_1 = require("../exceptions/RecyclerListViewExceptions"); -+var CustomError_1 = require("../exceptions/CustomError"); -+var StickyType; -+(function (StickyType) { -+ StickyType[StickyType["HEADER"] = 0] = "HEADER"; -+ StickyType[StickyType["FOOTER"] = 1] = "FOOTER"; -+})(StickyType = exports.StickyType || (exports.StickyType = {})); -+var StickyObject = /** @class */ (function (_super) { -+ __extends(StickyObject, _super); -+ function StickyObject(props, context) { -+ var _this = _super.call(this, props, context) || this; -+ _this.stickyType = StickyType.HEADER; -+ _this.stickyTypeMultiplier = 1; -+ _this.stickyVisiblity = false; -+ _this.visibility = false; -+ _this.currentIndex = 0; -+ _this.currentStickyIndex = 0; -+ _this.visibleIndices = []; -+ _this.bounceScrolling = false; -+ _this._stickyViewOffset = new react_native_1.Animated.Value(0); -+ _this._previousStickyIndex = 0; -+ _this._nextStickyIndex = 0; -+ _this._firstCompute = true; -+ _this._smallestVisibleIndex = 0; -+ _this._largestVisibleIndex = 0; -+ _this._offsetY = 0; -+ _this.state = { -+ visibility: true, -+ }; -+ return _this; -+ } -+ StickyObject.prototype.componentWillReceiveProps = function (newProps) { -+ this._initParams(); -+ this.calculateVisibleStickyIndex(newProps.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, newProps.getDistanceFromWindow(), this._windowBound); -+ this._computeLayouts(newProps.stickyIndices); -+ this.stickyViewVisible(this.stickyVisiblity); -+ }; -+ StickyObject.prototype.render = function () { -+ return (React.createElement(react_native_1.Animated.View, { style: [ -+ { position: "absolute", width: this._scrollableWidth, transform: [{ translateY: this._stickyViewOffset }] }, -+ this.containerPosition, -+ ] }, this.visibility ? -+ this._renderSticky() -+ : null)); -+ }; -+ StickyObject.prototype.onVisibleIndicesChanged = function (all) { -+ if (this._firstCompute) { -+ this.initStickyParams(); -+ this._firstCompute = false; -+ } -+ this._initParams(); -+ this._setSmallestAndLargestVisibleIndices(all); -+ this.calculateVisibleStickyIndex(this.props.stickyIndices, this._smallestVisibleIndex, this._largestVisibleIndex, this._offsetY, this.props.getDistanceFromWindow(), this._windowBound); -+ this._computeLayouts(); -+ this.stickyViewVisible(this.stickyVisiblity); -+ }; -+ StickyObject.prototype.onScroll = function (offsetY) { -+ var prevVisibility = this.visibility; -+ if (offsetY < 0 && prevVisibility === true || this._smallestVisibleIndex < this.currentStickyIndex) { -+ this.visibility = false; -+ } -+ else if (offsetY >= 0 && prevVisibility === false) { -+ this.visibility = true; -+ } -+ if (prevVisibility !== this.visibility) { -+ this.render(); -+ } -+ this._initParams(); -+ this._offsetY = offsetY; -+ this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); -+ if (this._previousStickyIndex !== undefined) { -+ if (this._previousStickyIndex * this.stickyTypeMultiplier >= this.currentStickyIndex * this.stickyTypeMultiplier) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); -+ } -+ var scrollY_1 = this.getScrollY(offsetY, this._scrollableHeight); -+ if (this._previousHeight && this._currentYd && scrollY_1 && scrollY_1 < this._currentYd) { -+ if (scrollY_1 > this._currentYd - this._previousHeight) { -+ this.currentIndex -= this.stickyTypeMultiplier; -+ var translate = (scrollY_1 - this._currentYd + this._previousHeight) * (-1 * this.stickyTypeMultiplier); -+ this._stickyViewOffset.setValue(translate); -+ this._computeLayouts(); -+ this.stickyViewVisible(true); -+ } -+ } -+ else { -+ this._stickyViewOffset.setValue(0); -+ } -+ } -+ if (this._nextStickyIndex !== undefined) { -+ if (this._nextStickyIndex * this.stickyTypeMultiplier <= this.currentStickyIndex * this.stickyTypeMultiplier) { -+ throw new CustomError_1.default(RecyclerListViewExceptions_1.default.stickyIndicesArraySortError); -+ } -+ var scrollY_2 = this.getScrollY(offsetY, this._scrollableHeight); -+ if (this._currentHeight && this._nextYd && scrollY_2 && scrollY_2 + this._currentHeight > this._nextYd) { -+ if (scrollY_2 <= this._nextYd) { -+ var translate = (scrollY_2 - this._nextYd + this._currentHeight) * (-1 * this.stickyTypeMultiplier); -+ this._stickyViewOffset.setValue(translate); -+ } -+ else if (scrollY_2 > this._nextYd) { -+ this.currentIndex += this.stickyTypeMultiplier; -+ this._stickyViewOffset.setValue(0); -+ this._computeLayouts(); -+ this.stickyViewVisible(true); -+ } -+ } -+ else { -+ this._stickyViewOffset.setValue(0); -+ } -+ } -+ }; -+ StickyObject.prototype.stickyViewVisible = function (_visible) { -+ this.setState({ -+ visibility: _visible, -+ }); -+ }; -+ StickyObject.prototype.boundaryProcessing = function (offsetY, distanceFromWindow, windowBound) { -+ var hasReachedBoundary = this.hasReachedBoundary(offsetY, distanceFromWindow, windowBound); -+ if (this.bounceScrolling !== hasReachedBoundary) { -+ this.bounceScrolling = hasReachedBoundary; -+ if (this.bounceScrolling) { -+ this.stickyViewVisible(false); -+ } -+ else { -+ this.onVisibleIndicesChanged(this.visibleIndices); -+ } -+ } -+ }; -+ StickyObject.prototype._initParams = function () { -+ var rlvDimension = this.props.getRLVRenderedSize(); -+ if (rlvDimension) { -+ this._scrollableHeight = rlvDimension.height; -+ this._scrollableWidth = rlvDimension.width; -+ } -+ var contentDimension = this.props.getContentDimension(); -+ if (contentDimension && this._scrollableHeight) { -+ this._windowBound = contentDimension.height - this._scrollableHeight; -+ } -+ }; -+ StickyObject.prototype._computeLayouts = function (newStickyIndices) { -+ var stickyIndices = newStickyIndices ? newStickyIndices : this.props.stickyIndices; -+ if (stickyIndices) { -+ this.currentStickyIndex = stickyIndices[this.currentIndex]; -+ this._previousStickyIndex = stickyIndices[this.currentIndex - this.stickyTypeMultiplier]; -+ this._nextStickyIndex = stickyIndices[this.currentIndex + this.stickyTypeMultiplier]; -+ if (this.currentStickyIndex !== undefined) { -+ this._currentLayout = this.props.getLayoutForIndex(this.currentStickyIndex); -+ this._currentY = this._currentLayout ? this._currentLayout.y : undefined; -+ this._currentHeight = this._currentLayout ? this._currentLayout.height : undefined; -+ this._currentYd = this._currentY && this._currentHeight ? this.getCurrentYd(this._currentY, this._currentHeight) : undefined; -+ } -+ if (this._previousStickyIndex !== undefined) { -+ this._previousLayout = this.props.getLayoutForIndex(this._previousStickyIndex); -+ this._previousHeight = this._previousLayout ? this._previousLayout.height : undefined; -+ } -+ if (this._nextStickyIndex !== undefined) { -+ this._nextLayout = this.props.getLayoutForIndex(this._nextStickyIndex); -+ this._nextY = this._nextLayout ? this._nextLayout.y : undefined; -+ this._nextHeight = this._nextLayout ? this._nextLayout.height : undefined; -+ this._nextYd = this._nextY && this._nextHeight ? this.getNextYd(this._nextY, this._nextHeight) : undefined; -+ } -+ } -+ }; -+ StickyObject.prototype._setSmallestAndLargestVisibleIndices = function (indicesArray) { -+ this.visibleIndices = indicesArray; -+ this._smallestVisibleIndex = indicesArray[0]; -+ this._largestVisibleIndex = indicesArray[indicesArray.length - 1]; -+ }; -+ StickyObject.prototype._renderSticky = function () { -+ var _stickyData = this.props.getDataForIndex(this.currentStickyIndex); -+ var _stickyLayoutType = this.props.getLayoutTypeForIndex(this.currentStickyIndex); -+ var _extendedState = this.props.getExtendedState(); -+ var _rowRenderer = this.props.getRowRenderer(); -+ if (this.props.overrideRowRenderer) { -+ return this.props.overrideRowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); -+ } -+ else { -+ return _rowRenderer(_stickyLayoutType, _stickyData, this.currentStickyIndex, _extendedState); -+ } -+ }; -+ return StickyObject; -+}(React.Component)); -+exports.default = StickyObject; -+//# sourceMappingURL=StickyObject.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js.map b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js.map -new file mode 100644 -index 0000000..82b71ae ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/sticky/StickyObject.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"StickyObject.js","sourceRoot":"","sources":["../../../../src/core/sticky/StickyObject.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;AAEH,6BAA+B;AAC/B,6CAA4D;AAG5D,uFAAkF;AAClF,yDAAoD;AAEpD,IAAY,UAGX;AAHD,WAAY,UAAU;IAClB,+CAAM,CAAA;IACN,+CAAM,CAAA;AACV,CAAC,EAHW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAGrB;AAgBD;IAA6G,gCAAqB;IAkC9H,sBAAY,KAAQ,EAAE,OAAa;QAAnC,YACI,kBAAM,KAAK,EAAE,OAAO,CAAC,SAIxB;QAtCS,gBAAU,GAAe,UAAU,CAAC,MAAM,CAAC;QAC3C,0BAAoB,GAAW,CAAC,CAAC;QACjC,qBAAe,GAAY,KAAK,CAAC;QACjC,gBAAU,GAAY,KAAK,CAAC;QAE5B,kBAAY,GAAW,CAAC,CAAC;QACzB,wBAAkB,GAAW,CAAC,CAAC;QAC/B,oBAAc,GAAa,EAAE,CAAC;QAC9B,qBAAe,GAAY,KAAK,CAAC;QAiBnC,uBAAiB,GAAmB,IAAI,uBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1D,0BAAoB,GAAW,CAAC,CAAC;QACjC,sBAAgB,GAAW,CAAC,CAAC;QAC7B,mBAAa,GAAY,IAAI,CAAC;QAC9B,2BAAqB,GAAW,CAAC,CAAC;QAClC,0BAAoB,GAAW,CAAC,CAAC;QACjC,cAAQ,GAAW,CAAC,CAAC;QAIzB,KAAI,CAAC,KAAK,GAAG;YACT,UAAU,EAAE,IAAI;SACd,CAAC;;IACX,CAAC;IAEM,gDAAyB,GAAhC,UAAiC,QAA2B;QACxD,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,oBAAoB,EAC1G,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,qBAAqB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACxE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC7C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IAEM,6BAAM,GAAb;QACI,OAAO,CACH,oBAAC,uBAAQ,CAAC,IAAI,IAAC,KAAK,EAAE;gBAClB,EAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,EAAE,CAAC,EAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAC,CAAC,EAAC;gBACvG,IAAI,CAAC,iBAAiB;aACzB,IACI,IAAI,CAAC,UAAU,CAAC,CAAC;YACd,IAAI,CAAC,aAAa,EAAE;YACxB,CAAC,CAAC,IAAI,CACM,CACnB,CAAC;IACN,CAAC;IAEM,8CAAuB,GAA9B,UAA+B,GAAa;QACxC,IAAI,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;SAC9B;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,oCAAoC,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,oBAAoB,EAC5G,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1E,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IAEM,+BAAQ,GAAf,UAAgB,OAAe;QAC3B,IAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC;QACvC,IAAI,OAAO,GAAG,CAAC,IAAI,cAAc,KAAK,IAAI,IAAI,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,kBAAkB,EAAE;YAChG,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;SAC3B;aAAM,IAAI,OAAO,IAAI,CAAC,IAAI,cAAc,KAAK,KAAK,EAAE;YACjD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;SAC1B;QACD,IAAI,cAAc,KAAK,IAAI,CAAC,UAAU,EAAE;YACpC,IAAI,CAAC,MAAM,EAAE,CAAC;SACjB;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACxF,IAAI,IAAI,CAAC,oBAAoB,KAAK,SAAS,EAAE;YACzC,IAAI,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,oBAAoB,EAAE;gBAC9G,MAAM,IAAI,qBAAW,CAAC,oCAA0B,CAAC,2BAA2B,CAAC,CAAC;aACjF;YACD,IAAM,SAAO,GAAuB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACrF,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,UAAU,IAAI,SAAO,IAAI,SAAO,GAAG,IAAI,CAAC,UAAU,EAAE;gBACjF,IAAI,SAAO,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE;oBAClD,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,oBAAoB,CAAC;oBAC/C,IAAM,SAAS,GAAG,CAAC,SAAO,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;oBACxG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;oBAC3C,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;iBAChC;aACJ;iBAAM;gBACH,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;aACtC;SACJ;QACD,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE;YACrC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,oBAAoB,EAAE;gBAC1G,MAAM,IAAI,qBAAW,CAAC,oCAA0B,CAAC,2BAA2B,CAAC,CAAC;aACjF;YACD,IAAM,SAAO,GAAuB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACrF,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,IAAI,SAAO,IAAI,SAAO,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE;gBAChG,IAAI,SAAO,IAAI,IAAI,CAAC,OAAO,EAAE;oBACzB,IAAM,SAAS,GAAG,CAAC,SAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;oBACpG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;iBAC9C;qBAAM,IAAI,SAAO,GAAG,IAAI,CAAC,OAAO,EAAE;oBAC/B,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,oBAAoB,CAAC;oBAC/C,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACnC,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;iBAChC;aACJ;iBAAM;gBACH,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;aACtC;SACJ;IACL,CAAC;IAYS,wCAAiB,GAA3B,UAA4B,QAAiB;QACzC,IAAI,CAAC,QAAQ,CAAC;YACV,UAAU,EAAE,QAAQ;SACvB,CAAC,CAAC;IACP,CAAC;IAES,yCAAkB,GAA5B,UAA6B,OAAe,EAAE,kBAA0B,EAAE,WAAoB;QAC1F,IAAM,kBAAkB,GAAY,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;QACtG,IAAI,IAAI,CAAC,eAAe,KAAK,kBAAkB,EAAE;YAC7C,IAAI,CAAC,eAAe,GAAG,kBAAkB,CAAC;YAC1C,IAAI,IAAI,CAAC,eAAe,EAAE;gBACtB,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;aACjC;iBAAM;gBACH,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;aACrD;SACJ;IACL,CAAC;IAEO,kCAAW,GAAnB;QACI,IAAM,YAAY,GAA0B,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC5E,IAAI,YAAY,EAAE;YACd,IAAI,CAAC,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC;YAC7C,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC,KAAK,CAAC;SAC9C;QACD,IAAM,gBAAgB,GAA0B,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;QACjF,IAAI,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,EAAE;YAC5C,IAAI,CAAC,YAAY,GAAG,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC;SACxE;IACL,CAAC;IAEO,sCAAe,GAAvB,UAAwB,gBAA2B;QAC/C,IAAM,aAAa,GAAyB,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;QAC3G,IAAI,aAAa,EAAE;YACf,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3D,IAAI,CAAC,oBAAoB,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACzF,IAAI,CAAC,gBAAgB,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACrF,IAAI,IAAI,CAAC,kBAAkB,KAAK,SAAS,EAAE;gBACvC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBAC5E,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACzE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;gBACnF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;aAChI;YACD,IAAI,IAAI,CAAC,oBAAoB,KAAK,SAAS,EAAE;gBACzC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAC/E,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;aACzF;YACD,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE;gBACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBACvE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAChE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC1E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;aAC9G;SACJ;IACL,CAAC;IAEO,2DAAoC,GAA5C,UAA6C,YAAsB;QAC/D,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;QACnC,IAAI,CAAC,qBAAqB,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,oBAAoB,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IAEO,oCAAa,GAArB;QACI,IAAM,WAAW,GAAQ,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC7E,IAAM,iBAAiB,GAAoB,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACrG,IAAM,cAAc,GAAuB,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACzE,IAAM,YAAY,GAC2B,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QACzE,IAAI,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE;YAChC,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;SAClH;aAAM;YACH,OAAO,YAAY,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;SAChG;IACL,CAAC;IACL,mBAAC;AAAD,CAAC,AAjND,CAA6G,KAAK,CAAC,SAAS,GAiN3H"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.d.ts b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.d.ts -new file mode 100644 -index 0000000..400f352 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.d.ts -@@ -0,0 +1,37 @@ -+import * as React from "react"; -+import { Dimension, BaseLayoutProvider } from "../dependencies/LayoutProvider"; -+import ItemAnimator from "../ItemAnimator"; -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+export interface ViewRendererProps { -+ x: number; -+ y: number; -+ height: number; -+ width: number; -+ childRenderer: (type: string | number, data: T, index: number, extendedState?: object) => JSX.Element | JSX.Element[] | null; -+ layoutType: string | number; -+ dataHasChanged: (r1: T, r2: T) => boolean; -+ onSizeChanged: (dim: Dimension, index: number) => void; -+ data: any; -+ index: number; -+ itemAnimator: ItemAnimator; -+ styleOverrides?: object; -+ forceNonDeterministicRendering?: boolean; -+ isHorizontal?: boolean; -+ extendedState?: object; -+ internalSnapshot?: object; -+ layoutProvider?: BaseLayoutProvider; -+} -+export default abstract class BaseViewRenderer extends React.Component, {}> { -+ protected animatorStyleOverrides: object | undefined; -+ shouldComponentUpdate(newProps: ViewRendererProps): boolean; -+ componentDidMount(): void; -+ componentWillMount(): void; -+ componentWillUnmount(): void; -+ protected abstract getRef(): object | null; -+ protected renderChild(): JSX.Element | JSX.Element[] | null; -+} -diff --git a/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js -new file mode 100644 -index 0000000..f584ea7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js -@@ -0,0 +1,55 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseViewRenderer = /** @class */ (function (_super) { -+ __extends(BaseViewRenderer, _super); -+ function BaseViewRenderer() { -+ return _super !== null && _super.apply(this, arguments) || this; -+ } -+ BaseViewRenderer.prototype.shouldComponentUpdate = function (newProps) { -+ var hasMoved = this.props.x !== newProps.x || this.props.y !== newProps.y; -+ var hasSizeChanged = !newProps.forceNonDeterministicRendering && -+ (this.props.width !== newProps.width || this.props.height !== newProps.height) || -+ this.props.layoutProvider !== newProps.layoutProvider; -+ var hasExtendedStateChanged = this.props.extendedState !== newProps.extendedState; -+ var hasInternalSnapshotChanged = this.props.internalSnapshot !== newProps.internalSnapshot; -+ var hasDataChanged = (this.props.dataHasChanged && this.props.dataHasChanged(this.props.data, newProps.data)); -+ var shouldUpdate = hasSizeChanged || hasDataChanged || hasExtendedStateChanged || hasInternalSnapshotChanged; -+ if (shouldUpdate) { -+ newProps.itemAnimator.animateWillUpdate(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); -+ } -+ else if (hasMoved) { -+ shouldUpdate = !newProps.itemAnimator.animateShift(this.props.x, this.props.y, newProps.x, newProps.y, this.getRef(), newProps.index); -+ } -+ return shouldUpdate; -+ }; -+ BaseViewRenderer.prototype.componentDidMount = function () { -+ this.animatorStyleOverrides = undefined; -+ this.props.itemAnimator.animateDidMount(this.props.x, this.props.y, this.getRef(), this.props.index); -+ }; -+ BaseViewRenderer.prototype.componentWillMount = function () { -+ this.animatorStyleOverrides = this.props.itemAnimator.animateWillMount(this.props.x, this.props.y, this.props.index); -+ }; -+ BaseViewRenderer.prototype.componentWillUnmount = function () { -+ this.props.itemAnimator.animateWillUnmount(this.props.x, this.props.y, this.getRef(), this.props.index); -+ }; -+ BaseViewRenderer.prototype.renderChild = function () { -+ return this.props.childRenderer(this.props.layoutType, this.props.data, this.props.index, this.props.extendedState); -+ }; -+ return BaseViewRenderer; -+}(React.Component)); -+exports.default = BaseViewRenderer; -+//# sourceMappingURL=BaseViewRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js.map b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js.map -new file mode 100644 -index 0000000..451d377 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/core/viewrenderer/BaseViewRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BaseViewRenderer.js","sourceRoot":"","sources":["../../../../src/core/viewrenderer/BaseViewRenderer.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6BAA+B;AA8B/B;IAA0D,oCAAyC;IAAnG;;IAmCA,CAAC;IAhCU,gDAAqB,GAA5B,UAA6B,QAAgC;QACzD,IAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;QAE5E,IAAM,cAAc,GAAG,CAAC,QAAQ,CAAC,8BAA8B;YAC3D,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;YAC9E,IAAI,CAAC,KAAK,CAAC,cAAc,KAAK,QAAQ,CAAC,cAAc,CAAC;QAE1D,IAAM,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,aAAa,CAAC;QACpF,IAAM,0BAA0B,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,KAAK,QAAQ,CAAC,gBAAgB,CAAC;QAC7F,IAAM,cAAc,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAChH,IAAI,YAAY,GAAG,cAAc,IAAI,cAAc,IAAI,uBAAuB,IAAI,0BAA0B,CAAC;QAC7G,IAAI,YAAY,EAAE;YACd,QAAQ,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;SACxI;aAAM,IAAI,QAAQ,EAAE;YACjB,YAAY,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;SACnJ;QACD,OAAO,YAAY,CAAC;IACxB,CAAC;IACM,4CAAiB,GAAxB;QACI,IAAI,CAAC,sBAAsB,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnH,CAAC;IACM,6CAAkB,GAAzB;QACI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzH,CAAC;IACM,+CAAoB,GAA3B;QACI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtH,CAAC;IAES,sCAAW,GAArB;QACI,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACxH,CAAC;IACL,uBAAC;AAAD,CAAC,AAnCD,CAA0D,KAAK,CAAC,SAAS,GAmCxE"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/index.d.ts b/node_modules/recyclerlistview/dist/web/index.d.ts -new file mode 100644 -index 0000000..230e231 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/index.d.ts -@@ -0,0 +1,11 @@ -+import ContextProvider from "./core/dependencies/ContextProvider"; -+import DataProvider, { BaseDataProvider } from "./core/dependencies/DataProvider"; -+import { BaseLayoutProvider, Dimension, LayoutProvider } from "./core/dependencies/LayoutProvider"; -+import RecyclerListView, { OnRecreateParams } from "./core/RecyclerListView"; -+import BaseScrollView from "./core/scrollcomponent/BaseScrollView"; -+import { BaseItemAnimator } from "./core/ItemAnimator"; -+import { AutoScroll } from "./utils/AutoScroll"; -+import { Layout, LayoutManager, Point, WrapGridLayoutManager } from "./core/layoutmanager/LayoutManager"; -+import ProgressiveListView from "./core/ProgressiveListView"; -+import { DebugHandlers } from "./core/devutils/debughandlers/DebugHandlers"; -+export { ContextProvider, DataProvider, LayoutProvider, BaseLayoutProvider, LayoutManager, WrapGridLayoutManager, RecyclerListView, ProgressiveListView, BaseItemAnimator, BaseScrollView, AutoScroll, Dimension, Point, Layout, OnRecreateParams, DebugHandlers, BaseDataProvider, }; -diff --git a/node_modules/recyclerlistview/dist/web/index.js b/node_modules/recyclerlistview/dist/web/index.js -new file mode 100644 -index 0000000..2faf787 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/index.js -@@ -0,0 +1,24 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ContextProvider_1 = require("./core/dependencies/ContextProvider"); -+exports.ContextProvider = ContextProvider_1.default; -+var DataProvider_1 = require("./core/dependencies/DataProvider"); -+exports.DataProvider = DataProvider_1.default; -+exports.BaseDataProvider = DataProvider_1.BaseDataProvider; -+var LayoutProvider_1 = require("./core/dependencies/LayoutProvider"); -+exports.BaseLayoutProvider = LayoutProvider_1.BaseLayoutProvider; -+exports.LayoutProvider = LayoutProvider_1.LayoutProvider; -+var RecyclerListView_1 = require("./core/RecyclerListView"); -+exports.RecyclerListView = RecyclerListView_1.default; -+var BaseScrollView_1 = require("./core/scrollcomponent/BaseScrollView"); -+exports.BaseScrollView = BaseScrollView_1.default; -+var ItemAnimator_1 = require("./core/ItemAnimator"); -+exports.BaseItemAnimator = ItemAnimator_1.BaseItemAnimator; -+var AutoScroll_1 = require("./utils/AutoScroll"); -+exports.AutoScroll = AutoScroll_1.AutoScroll; -+var LayoutManager_1 = require("./core/layoutmanager/LayoutManager"); -+exports.LayoutManager = LayoutManager_1.LayoutManager; -+exports.WrapGridLayoutManager = LayoutManager_1.WrapGridLayoutManager; -+var ProgressiveListView_1 = require("./core/ProgressiveListView"); -+exports.ProgressiveListView = ProgressiveListView_1.default; -+//# sourceMappingURL=index.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/index.js.map b/node_modules/recyclerlistview/dist/web/index.js.map -new file mode 100644 -index 0000000..9e60fb9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/index.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;AAAA,uEAAkE;AAY9D,0BAZG,yBAAe,CAYH;AAXnB,iEAAkF;AAY9E,uBAZG,sBAAY,CAYH;AAeZ,2BA3BmB,+BAAgB,CA2BnB;AA1BpB,qEAAmG;AAa/F,6BAbK,mCAAkB,CAaL;AADlB,yBAZoC,+BAAc,CAYpC;AAXlB,4DAA6E;AAezE,2BAfG,0BAAgB,CAeH;AAdpB,wEAAmE;AAiB/D,yBAjBG,wBAAc,CAiBH;AAhBlB,oDAAuD;AAenD,2BAfK,+BAAgB,CAeL;AAdpB,iDAAgD;AAgB5C,qBAhBK,uBAAU,CAgBL;AAfd,oEAAyG;AASrG,wBATa,6BAAa,CASb;AACb,gCAVmC,qCAAqB,CAUnC;AATzB,kEAA6D;AAWzD,8BAXG,6BAAmB,CAWH"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts -new file mode 100644 -index 0000000..693e3a0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.d.ts -@@ -0,0 +1,12 @@ -+import { BaseItemAnimator } from "../../../core/ItemAnimator"; -+export declare class DefaultNativeItemAnimator implements BaseItemAnimator { -+ shouldAnimateOnce: boolean; -+ private _hasAnimatedOnce; -+ private _isTimerOn; -+ constructor(); -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js -new file mode 100644 -index 0000000..9ac03d1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js -@@ -0,0 +1,48 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var react_native_1 = require("react-native"); -+var DefaultNativeItemAnimator = /** @class */ (function () { -+ function DefaultNativeItemAnimator() { -+ this.shouldAnimateOnce = true; -+ this._hasAnimatedOnce = false; -+ this._isTimerOn = false; -+ if (react_native_1.Platform.OS === "android" && react_native_1.UIManager.setLayoutAnimationEnabledExperimental) { -+ react_native_1.UIManager.setLayoutAnimationEnabledExperimental(true); -+ } -+ } -+ DefaultNativeItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ DefaultNativeItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ DefaultNativeItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ this._hasAnimatedOnce = true; -+ }; -+ DefaultNativeItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ var _this = this; -+ if (fromX !== toX || fromY !== toY) { -+ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { -+ react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut); -+ this._hasAnimatedOnce = true; -+ } -+ } -+ else { -+ if (!this._isTimerOn) { -+ this._isTimerOn = true; -+ if (!this._hasAnimatedOnce) { -+ setTimeout(function () { -+ _this._hasAnimatedOnce = true; -+ }, 1000); -+ } -+ } -+ } -+ return false; -+ }; -+ DefaultNativeItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ return DefaultNativeItemAnimator; -+}()); -+exports.DefaultNativeItemAnimator = DefaultNativeItemAnimator; -+//# sourceMappingURL=DefaultNativeItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map -new file mode 100644 -index 0000000..50ecf5a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/DefaultNativeItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultNativeItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/itemanimators/DefaultNativeItemAnimator.ts"],"names":[],"mappings":";;AAAA,6CAAoE;AAGpE;IAII;QAHO,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;QAEhC,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,wBAAS,CAAC,qCAAqC,EAAE;YAC9E,wBAAS,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC;SACzD;IACL,CAAC;IACM,oDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,mDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,qDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,gDAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAiBC;QAhBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,8BAAe,CAAC,aAAa,CAAC,8BAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACrE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;aAChC;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,sDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,gCAAC;AAAD,CAAC,AA1CD,IA0CC;AA1CY,8DAAyB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts -new file mode 100644 -index 0000000..e3a83b3 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.d.ts -@@ -0,0 +1,19 @@ -+import { BaseItemAnimator } from "../../../../core/ItemAnimator"; -+/** -+ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator -+ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite -+ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if -+ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is -+ * hardly customizable. -+ */ -+export declare class DefaultJSItemAnimator implements BaseItemAnimator { -+ shouldAnimateOnce: boolean; -+ private _hasAnimatedOnce; -+ private _isTimerOn; -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ private _getNativePropObject; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js -new file mode 100644 -index 0000000..1b8b812 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js -@@ -0,0 +1,77 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var react_native_1 = require("react-native"); -+var ItemAnimator_1 = require("../../../../core/ItemAnimator"); -+/** -+ * Default implementation of RLV layout animations for react native. These ones are purely JS driven. Also, check out DefaultNativeItemAnimator -+ * for an implementation on top of LayoutAnimation. We didn't use it by default due the fact that LayoutAnimation is quite -+ * unstable on Android and to avoid unnecessary interference with developer flow. It would be very easy to do so manually if -+ * you need to. Check DefaultNativeItemAnimator for inspiration. LayoutAnimation definitely gives better performance but is -+ * hardly customizable. -+ */ -+var DefaultJSItemAnimator = /** @class */ (function () { -+ function DefaultJSItemAnimator() { -+ this.shouldAnimateOnce = true; -+ this._hasAnimatedOnce = false; -+ this._isTimerOn = false; -+ } -+ DefaultJSItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ DefaultJSItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ DefaultJSItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ this._hasAnimatedOnce = true; -+ }; -+ DefaultJSItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ var _this = this; -+ if (fromX !== toX || fromY !== toY) { -+ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { -+ var viewRef_1 = itemRef; -+ var animXY_1 = new react_native_1.Animated.ValueXY({ x: fromX, y: fromY }); -+ animXY_1.addListener(function (value) { -+ if (viewRef_1._isUnmountedForRecyclerListView || (_this.shouldAnimateOnce && _this._hasAnimatedOnce)) { -+ animXY_1.stopAnimation(); -+ return; -+ } -+ viewRef_1.setNativeProps(_this._getNativePropObject(value.x, value.y)); -+ }); -+ if (viewRef_1._lastAnimVal) { -+ viewRef_1._lastAnimVal.stopAnimation(); -+ } -+ viewRef_1._lastAnimVal = animXY_1; -+ react_native_1.Animated.timing(animXY_1, { -+ toValue: { x: toX, y: toY }, -+ duration: 200, -+ easing: react_native_1.Easing.out(react_native_1.Easing.ease), -+ useNativeDriver: ItemAnimator_1.BaseItemAnimator.USE_NATIVE_DRIVER, -+ }).start(function () { -+ viewRef_1._lastAnimVal = null; -+ _this._hasAnimatedOnce = true; -+ }); -+ return true; -+ } -+ } -+ else { -+ if (!this._isTimerOn) { -+ this._isTimerOn = true; -+ if (!this._hasAnimatedOnce) { -+ setTimeout(function () { -+ _this._hasAnimatedOnce = true; -+ }, 1000); -+ } -+ } -+ } -+ return false; -+ }; -+ DefaultJSItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ itemRef._isUnmountedForRecyclerListView = true; -+ }; -+ DefaultJSItemAnimator.prototype._getNativePropObject = function (x, y) { -+ return { style: { left: x, top: y } }; -+ }; -+ return DefaultJSItemAnimator; -+}()); -+exports.DefaultJSItemAnimator = DefaultJSItemAnimator; -+//# sourceMappingURL=DefaultJSItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map -new file mode 100644 -index 0000000..6a6881e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultJSItemAnimator.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts -new file mode 100644 -index 0000000..63ab9e4 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.d.ts -@@ -0,0 +1,2 @@ -+import { DefaultWebItemAnimator } from "../../../web/itemanimators/DefaultWebItemAnimator"; -+export { DefaultWebItemAnimator as DefaultJSItemAnimator }; -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js -new file mode 100644 -index 0000000..53a8a28 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js -@@ -0,0 +1,5 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var DefaultWebItemAnimator_1 = require("../../../web/itemanimators/DefaultWebItemAnimator"); -+exports.DefaultJSItemAnimator = DefaultWebItemAnimator_1.DefaultWebItemAnimator; -+//# sourceMappingURL=DefaultJSItemAnimator.web.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map -new file mode 100644 -index 0000000..ee1f03d ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultJSItemAnimator.web.js","sourceRoot":"","sources":["../../../../../../src/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator.web.ts"],"names":[],"mappings":";;AAAA,4FAA2F;AACxD,gCAD1B,+CAAsB,CACyB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.d.ts -new file mode 100644 -index 0000000..8e9f3e1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.d.ts -@@ -0,0 +1,26 @@ -+/// -+import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+export default class ScrollComponent extends BaseScrollComponent { -+ static defaultProps: { -+ contentHeight: number; -+ contentWidth: number; -+ externalScrollView: {}; -+ isHorizontal: boolean; -+ scrollThrottle: number; -+ }; -+ private _height; -+ private _width; -+ private _isSizeChangedCalledOnce; -+ private _scrollViewRef; -+ constructor(args: ScrollComponentProps); -+ scrollTo(x: number, y: number, isAnimated: boolean): void; -+ render(): JSX.Element; -+ private _getScrollViewRef; -+ private _onScroll; -+ private _onLayout; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js -new file mode 100644 -index 0000000..0cda95e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js -@@ -0,0 +1,102 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var react_native_1 = require("react-native"); -+var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); -+var TSCast_1 = require("../../../utils/TSCast"); -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+var ScrollComponent = /** @class */ (function (_super) { -+ __extends(ScrollComponent, _super); -+ function ScrollComponent(args) { -+ var _this = _super.call(this, args) || this; -+ _this._scrollViewRef = null; -+ _this._getScrollViewRef = function (scrollView) { _this._scrollViewRef = scrollView; }; -+ _this._onScroll = function (event) { -+ if (event) { -+ _this.props.onScroll(event.nativeEvent.contentOffset.x, event.nativeEvent.contentOffset.y, event); -+ } -+ }; -+ _this._onLayout = function (event) { -+ if (_this._height !== event.nativeEvent.layout.height || _this._width !== event.nativeEvent.layout.width) { -+ _this._height = event.nativeEvent.layout.height; -+ _this._width = event.nativeEvent.layout.width; -+ if (_this.props.onSizeChanged) { -+ _this._isSizeChangedCalledOnce = true; -+ _this.props.onSizeChanged(event.nativeEvent.layout); -+ } -+ } -+ if (_this.props.onLayout) { -+ _this.props.onLayout(event); -+ } -+ }; -+ _this._height = 0; -+ _this._width = 0; -+ _this._isSizeChangedCalledOnce = false; -+ return _this; -+ } -+ ScrollComponent.prototype.scrollTo = function (x, y, isAnimated) { -+ if (this._scrollViewRef) { -+ this._scrollViewRef.scrollTo({ x: x, y: y, animated: isAnimated }); -+ } -+ }; -+ ScrollComponent.prototype.render = function () { -+ var Scroller = TSCast_1.default.cast(this.props.externalScrollView); //TSI -+ //TODO:Talha -+ // const { -+ // useWindowScroll, -+ // contentHeight, -+ // contentWidth, -+ // externalScrollView, -+ // canChangeSize, -+ // renderFooter, -+ // isHorizontal, -+ // scrollThrottle, -+ // ...props, -+ // } = this.props; -+ return (React.createElement(Scroller, __assign({ ref: this._getScrollViewRef, removeClippedSubviews: false, scrollEventThrottle: this.props.scrollThrottle }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onLayout: (!this._isSizeChangedCalledOnce || this.props.canChangeSize) ? this._onLayout : this.props.onLayout }), -+ React.createElement(react_native_1.View, { style: { flexDirection: this.props.isHorizontal ? "row" : "column" } }, -+ React.createElement(react_native_1.View, { style: { -+ height: this.props.contentHeight, -+ width: this.props.contentWidth, -+ } }, this.props.children), -+ this.props.renderFooter ? this.props.renderFooter() : null))); -+ }; -+ ScrollComponent.defaultProps = { -+ contentHeight: 0, -+ contentWidth: 0, -+ externalScrollView: TSCast_1.default.cast(react_native_1.ScrollView), -+ isHorizontal: false, -+ scrollThrottle: 16, -+ }; -+ return ScrollComponent; -+}(BaseScrollComponent_1.default)); -+exports.default = ScrollComponent; -+//# sourceMappingURL=ScrollComponent.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js.map -new file mode 100644 -index 0000000..16bf1fd ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/scrollcomponent/ScrollComponent.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.d.ts -new file mode 100644 -index 0000000..fe95fc1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.d.ts -@@ -0,0 +1,16 @@ -+/// -+import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+export default class ViewRenderer extends BaseViewRenderer { -+ private _dim; -+ private _viewRef; -+ render(): JSX.Element; -+ protected getRef(): object | null; -+ private _setRef; -+ private _onLayout; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js -new file mode 100644 -index 0000000..5b56fd5 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js -@@ -0,0 +1,70 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var react_native_1 = require("react-native"); -+var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+var ViewRenderer = /** @class */ (function (_super) { -+ __extends(ViewRenderer, _super); -+ function ViewRenderer() { -+ var _this = _super !== null && _super.apply(this, arguments) || this; -+ _this._dim = { width: 0, height: 0 }; -+ _this._viewRef = null; -+ _this._setRef = function (view) { -+ _this._viewRef = view; -+ }; -+ _this._onLayout = function (event) { -+ //Preventing layout thrashing in super fast scrolls where RN messes up onLayout event -+ var xDiff = Math.abs(_this.props.x - event.nativeEvent.layout.x); -+ var yDiff = Math.abs(_this.props.y - event.nativeEvent.layout.y); -+ if (xDiff < 1 && yDiff < 1 && -+ (_this.props.height !== event.nativeEvent.layout.height || -+ _this.props.width !== event.nativeEvent.layout.width)) { -+ _this._dim.height = event.nativeEvent.layout.height; -+ _this._dim.width = event.nativeEvent.layout.width; -+ if (_this.props.onSizeChanged) { -+ _this.props.onSizeChanged(_this._dim, _this.props.index); -+ } -+ } -+ }; -+ return _this; -+ } -+ ViewRenderer.prototype.render = function () { -+ return this.props.forceNonDeterministicRendering ? (React.createElement(react_native_1.View, { ref: this._setRef, onLayout: this._onLayout, style: __assign({ flexDirection: this.props.isHorizontal ? "column" : "row", left: this.props.x, position: "absolute", top: this.props.y }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())) : (React.createElement(react_native_1.View, { ref: this._setRef, style: __assign({ left: this.props.x, position: "absolute", top: this.props.y, height: this.props.height, width: this.props.width }, this.props.styleOverrides, this.animatorStyleOverrides) }, this.renderChild())); -+ }; -+ ViewRenderer.prototype.getRef = function () { -+ return this._viewRef; -+ }; -+ return ViewRenderer; -+}(BaseViewRenderer_1.default)); -+exports.default = ViewRenderer; -+//# sourceMappingURL=ViewRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js.map -new file mode 100644 -index 0000000..ceacfb9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAC/B,6CAAuE;AAEvE,gFAAkG;AAElG;;;;;GAKG;AACH;IAA0C,gCAAqB;IAA/D;QAAA,qEAuDC;QAtDW,UAAI,GAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1C,cAAQ,GAAiE,IAAI,CAAC;QAmC9E,aAAO,GAAG,UAAC,IAAkE;YACjF,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,CAAC,CAAA;QAEO,eAAS,GAAG,UAAC,KAAwB;YACzC,qFAAqF;YACrF,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClE,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC;gBACtB,CAAC,KAAI,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;oBAClD,KAAI,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAC1D,KAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACnD,KAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;gBACjD,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;oBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAI,CAAC,IAAI,EAAE,KAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;iBACzD;aACJ;QACL,CAAC,CAAA;;IACL,CAAC;IApDU,6BAAM,GAAb;QACI,OAAO,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAC/C,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACvB,QAAQ,EAAE,IAAI,CAAC,SAAS,EACpB,KAAK,aACD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EACzD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IACd,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC,CAAC,CAAC,CACI,oBAAC,mBAAI,IAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EACnB,KAAK,aACD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAClB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EACzB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IACpB,IAAI,CAAC,KAAK,CAAC,cAAc,EACzB,IAAI,CAAC,sBAAsB,KAEjC,IAAI,CAAC,WAAW,EAAE,CAChB,CACV,CAAC;IACV,CAAC;IAES,6BAAM,GAAhB;QACI,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAoBL,mBAAC;AAAD,CAAC,AAvDD,CAA0C,0BAAgB,GAuDzD"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts -new file mode 100644 -index 0000000..30681d9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.d.ts -@@ -0,0 +1,2 @@ -+import ViewRenderer from "../../web/viewrenderer/ViewRenderer"; -+export default ViewRenderer; -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js -new file mode 100644 -index 0000000..75c2c66 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js -@@ -0,0 +1,5 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ViewRenderer_1 = require("../../web/viewrenderer/ViewRenderer"); -+exports.default = ViewRenderer_1.default; -+//# sourceMappingURL=ViewRenderer.web.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js.map b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js.map -new file mode 100644 -index 0000000..f50f385 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/reactnative/viewrenderer/ViewRenderer.web.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewRenderer.web.js","sourceRoot":"","sources":["../../../../../src/platform/reactnative/viewrenderer/ViewRenderer.web.tsx"],"names":[],"mappings":";;AAAA,oEAA+D;AAC/D,kBAAe,sBAAY,CAAC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.d.ts -new file mode 100644 -index 0000000..1c1db85 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.d.ts -@@ -0,0 +1,15 @@ -+import { BaseItemAnimator } from "../../../core/ItemAnimator"; -+/** -+ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all -+ * shift events. -+ */ -+export declare class DefaultWebItemAnimator implements BaseItemAnimator { -+ shouldAnimateOnce: boolean; -+ private _hasAnimatedOnce; -+ private _isTimerOn; -+ animateWillMount(atX: number, atY: number, itemIndex: number): object | undefined; -+ animateDidMount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+ animateWillUpdate(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): void; -+ animateShift(fromX: number, fromY: number, toX: number, toY: number, itemRef: object, itemIndex: number): boolean; -+ animateWillUnmount(atX: number, atY: number, itemRef: object, itemIndex: number): void; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js -new file mode 100644 -index 0000000..3db93b4 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js -@@ -0,0 +1,54 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+/** -+ * Default implementation of RLV layout animations for web. We simply hook in transform transitions to beautifully animate all -+ * shift events. -+ */ -+var DefaultWebItemAnimator = /** @class */ (function () { -+ function DefaultWebItemAnimator() { -+ this.shouldAnimateOnce = true; -+ this._hasAnimatedOnce = false; -+ this._isTimerOn = false; -+ } -+ DefaultWebItemAnimator.prototype.animateWillMount = function (atX, atY, itemIndex) { -+ return undefined; -+ }; -+ DefaultWebItemAnimator.prototype.animateDidMount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ DefaultWebItemAnimator.prototype.animateWillUpdate = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ this._hasAnimatedOnce = true; -+ }; -+ DefaultWebItemAnimator.prototype.animateShift = function (fromX, fromY, toX, toY, itemRef, itemIndex) { -+ var _this = this; -+ if (fromX !== toX || fromY !== toY) { -+ var element_1 = itemRef; -+ if (!this.shouldAnimateOnce || this.shouldAnimateOnce && !this._hasAnimatedOnce) { -+ var transitionEndCallback_1 = function (event) { -+ element_1.style.transition = ""; -+ element_1.removeEventListener("transitionend", transitionEndCallback_1); -+ _this._hasAnimatedOnce = true; -+ }; -+ element_1.style.transition = "transform 0.15s ease-out"; -+ element_1.addEventListener("transitionend", transitionEndCallback_1, false); -+ } -+ } -+ else { -+ if (!this._isTimerOn) { -+ this._isTimerOn = true; -+ if (!this._hasAnimatedOnce) { -+ setTimeout(function () { -+ _this._hasAnimatedOnce = true; -+ }, 1000); -+ } -+ } -+ } -+ return false; -+ }; -+ DefaultWebItemAnimator.prototype.animateWillUnmount = function (atX, atY, itemRef, itemIndex) { -+ //no need -+ }; -+ return DefaultWebItemAnimator; -+}()); -+exports.DefaultWebItemAnimator = DefaultWebItemAnimator; -+//# sourceMappingURL=DefaultWebItemAnimator.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js.map b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js.map -new file mode 100644 -index 0000000..44c688a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/itemanimators/DefaultWebItemAnimator.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"DefaultWebItemAnimator.js","sourceRoot":"","sources":["../../../../../src/platform/web/itemanimators/DefaultWebItemAnimator.ts"],"names":[],"mappings":";;AAEA;;;GAGG;AACH;IAAA;QACW,sBAAiB,GAAY,IAAI,CAAC;QACjC,qBAAgB,GAAY,KAAK,CAAC;QAClC,eAAU,GAAY,KAAK,CAAC;IAwCxC,CAAC;IAvCU,iDAAgB,GAAvB,UAAwB,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IACM,gDAAe,GAAtB,UAAuB,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/E,SAAS;IACb,CAAC;IAEM,kDAAiB,GAAxB,UAAyB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAC/G,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,6CAAY,GAAnB,UAAoB,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAA9G,iBAuBC;QAtBG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,IAAM,SAAO,GAAG,OAAyB,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7E,IAAM,uBAAqB,GAAkB,UAAC,KAAK;oBAC/C,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;oBAC9B,SAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,uBAAqB,CAAC,CAAC;oBACpE,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACjC,CAAC,CAAC;gBACF,SAAO,CAAC,KAAK,CAAC,UAAU,GAAG,0BAA0B,CAAC;gBACtD,SAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,uBAAqB,EAAE,KAAK,CAAC,CAAC;aAC3E;SACJ;aAAM;YACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBACxB,UAAU,CAAC;wBACP,KAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;iBACZ;aACJ;SACJ;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,mDAAkB,GAAzB,UAA0B,GAAW,EAAE,GAAW,EAAE,OAAe,EAAE,SAAiB;QAClF,SAAS;IACb,CAAC;IACL,6BAAC;AAAD,CAAC,AA3CD,IA2CC;AA3CY,wDAAsB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.d.ts -new file mode 100644 -index 0000000..2188791 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.d.ts -@@ -0,0 +1,26 @@ -+/// -+import BaseScrollComponent, { ScrollComponentProps } from "../../../core/scrollcomponent/BaseScrollComponent"; -+import ScrollViewer from "./ScrollViewer"; -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+export default class ScrollComponent extends BaseScrollComponent { -+ static defaultProps: { -+ contentHeight: number; -+ contentWidth: number; -+ externalScrollView: typeof ScrollViewer; -+ isHorizontal: boolean; -+ scrollThrottle: number; -+ canChangeSize: boolean; -+ }; -+ private _height; -+ private _width; -+ private _scrollViewRef; -+ constructor(args: ScrollComponentProps); -+ scrollTo(x: number, y: number, animated: boolean): void; -+ render(): JSX.Element; -+ private _onScroll; -+ private _onSizeChanged; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js -new file mode 100644 -index 0000000..dca7ab7 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js -@@ -0,0 +1,82 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollComponent_1 = require("../../../core/scrollcomponent/BaseScrollComponent"); -+var ScrollViewer_1 = require("./ScrollViewer"); -+/*** -+ * The responsibility of a scroll component is to report its size, scroll events and provide a way to scroll to a given offset. -+ * RecyclerListView works on top of this interface and doesn't care about the implementation. To support web we only had to provide -+ * another component written on top of web elements -+ */ -+var ScrollComponent = /** @class */ (function (_super) { -+ __extends(ScrollComponent, _super); -+ function ScrollComponent(args) { -+ var _this = _super.call(this, args) || this; -+ _this._scrollViewRef = null; -+ _this._onScroll = function (e) { -+ _this.props.onScroll(e.nativeEvent.contentOffset.x, e.nativeEvent.contentOffset.y, e); -+ }; -+ _this._onSizeChanged = function (event) { -+ if (_this.props.onSizeChanged) { -+ _this.props.onSizeChanged(event); -+ } -+ }; -+ _this._height = 0; -+ _this._width = 0; -+ return _this; -+ } -+ ScrollComponent.prototype.scrollTo = function (x, y, animated) { -+ if (this._scrollViewRef) { -+ this._scrollViewRef.scrollTo({ x: x, y: y, animated: animated }); -+ } -+ }; -+ ScrollComponent.prototype.render = function () { -+ var _this = this; -+ var Scroller = this.props.externalScrollView; //TSI -+ return (React.createElement(Scroller, __assign({ ref: function (scrollView) { return _this._scrollViewRef = scrollView; } }, this.props, { horizontal: this.props.isHorizontal, onScroll: this._onScroll, onSizeChanged: this._onSizeChanged }), -+ React.createElement("div", { style: { -+ height: this.props.contentHeight, -+ width: this.props.contentWidth, -+ } }, this.props.children), -+ this.props.renderFooter ? React.createElement("div", { style: this.props.isHorizontal ? { -+ left: this.props.contentWidth, -+ position: "absolute", -+ top: 0, -+ } : undefined }, this.props.renderFooter()) : null)); -+ }; -+ ScrollComponent.defaultProps = { -+ contentHeight: 0, -+ contentWidth: 0, -+ externalScrollView: ScrollViewer_1.default, -+ isHorizontal: false, -+ scrollThrottle: 16, -+ canChangeSize: false, -+ }; -+ return ScrollComponent; -+}(BaseScrollComponent_1.default)); -+exports.default = ScrollComponent; -+//# sourceMappingURL=ScrollComponent.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js.map b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js.map -new file mode 100644 -index 0000000..5436601 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollComponent.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollComponent.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA+B;AAE/B,yFAA8G;AAE9G,+CAA0C;AAC1C;;;;GAIG;AAEH;IAA6C,mCAAmB;IAa5D,yBAAY,IAA0B;QAAtC,YACI,kBAAM,IAAI,CAAC,SAGd;QANO,oBAAc,GAA0B,IAAI,CAAC;QAwC7C,eAAS,GAAG,UAAC,CAAc;YAC/B,KAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC,CAAA;QAEO,oBAAc,GAAG,UAAC,KAAgB;YACtC,IAAI,KAAI,CAAC,KAAK,CAAC,aAAa,EAAE;gBAC1B,KAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;aACnC;QACL,CAAC,CAAA;QA5CG,KAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,KAAI,CAAC,MAAM,GAAG,CAAC,CAAC;;IACpB,CAAC;IAEM,kCAAQ,GAAf,UAAgB,CAAS,EAAE,CAAS,EAAE,QAAiB;QACnD,IAAI,IAAI,CAAC,cAAc,EAAE;YACrB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE,QAAQ,UAAA,EAAE,CAAC,CAAC;SACpD;IACL,CAAC;IAEM,gCAAM,GAAb;QAAA,iBAwBC;QAvBG,IAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAyB,CAAC,CAAC,KAAK;QAC5D,OAAO,CACH,oBAAC,QAAQ,aAAC,GAAG,EAAE,UAAC,UAA0B,IAAK,OAAA,KAAI,CAAC,cAAc,GAAG,UAAqC,EAA3D,CAA2D,IAClG,IAAI,CAAC,KAAK,IACd,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EACnC,QAAQ,EAAE,IAAI,CAAC,SAAS,EACxB,aAAa,EAAE,IAAI,CAAC,cAAc;YAElC,6BAAK,KAAK,EAAE;oBACR,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;oBAChC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;iBACjC,IACI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAClB;YACL,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,6BAAK,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC7D,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;oBAC7B,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,CAAC;iBACT,CAAC,CAAC,CAAC,SAAS,IACR,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CACxB,CAAC,CAAC,CAAC,IAAI,CACN,CACd,CAAC;IACN,CAAC;IAhDa,4BAAY,GAAG;QACzB,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,kBAAkB,EAAE,sBAAY;QAChC,YAAY,EAAE,KAAK;QACnB,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,KAAK;KACvB,CAAC;IAoDN,sBAAC;CAAA,AA5DD,CAA6C,6BAAmB,GA4D/D;kBA5DoB,eAAe"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts -new file mode 100644 -index 0000000..5551eef ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.d.ts -@@ -0,0 +1,6 @@ -+import { ScrollEvent } from "../../../core/scrollcomponent/BaseScrollView"; -+export declare class ScrollEventNormalizer { -+ divEvent: ScrollEvent; -+ windowEvent: ScrollEvent; -+ constructor(target: HTMLDivElement); -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js -new file mode 100644 -index 0000000..d930364 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js -@@ -0,0 +1,65 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var ScrollEventNormalizer = /** @class */ (function () { -+ function ScrollEventNormalizer(target) { -+ this.divEvent = { -+ nativeEvent: { -+ contentOffset: { -+ get x() { -+ return target.scrollLeft; -+ }, -+ get y() { -+ return target.scrollTop; -+ }, -+ }, -+ contentSize: { -+ get height() { -+ return target.scrollHeight; -+ }, -+ get width() { -+ return target.scrollWidth; -+ }, -+ }, -+ layoutMeasurement: { -+ get height() { -+ return target.offsetHeight; -+ }, -+ get width() { -+ return target.offsetWidth; -+ }, -+ }, -+ }, -+ }; -+ this.windowEvent = { -+ nativeEvent: { -+ contentOffset: { -+ get x() { -+ return window.scrollX === undefined ? window.pageXOffset : window.scrollX; -+ }, -+ get y() { -+ return window.scrollY === undefined ? window.pageYOffset : window.scrollY; -+ }, -+ }, -+ contentSize: { -+ get height() { -+ return target.offsetHeight; -+ }, -+ get width() { -+ return target.offsetWidth; -+ }, -+ }, -+ layoutMeasurement: { -+ get height() { -+ return window.innerHeight; -+ }, -+ get width() { -+ return window.innerWidth; -+ }, -+ }, -+ }, -+ }; -+ } -+ return ScrollEventNormalizer; -+}()); -+exports.ScrollEventNormalizer = ScrollEventNormalizer; -+//# sourceMappingURL=ScrollEventNormalizer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js.map b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js.map -new file mode 100644 -index 0000000..52347ab ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollEventNormalizer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollEventNormalizer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollEventNormalizer.ts"],"names":[],"mappings":";;AAEA;IAGI,+BAAY,MAAsB;QAC9B,IAAI,CAAC,QAAQ,GAAG;YACZ,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,SAAS,CAAC;oBAC5B,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;aACJ;SACJ,CAAC;QACF,IAAI,CAAC,WAAW,GAAG;YACf,WAAW,EAAE;gBACT,aAAa,EAAE;oBACX,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;oBACD,IAAI,CAAC;wBACD,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;oBAC9E,CAAC;iBACJ;gBACD,WAAW,EAAE;oBACT,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,YAAY,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;iBACJ;gBACD,iBAAiB,EAAE;oBACf,IAAI,MAAM;wBACN,OAAO,MAAM,CAAC,WAAW,CAAC;oBAC9B,CAAC;oBACD,IAAI,KAAK;wBACL,OAAO,MAAM,CAAC,UAAU,CAAC;oBAC7B,CAAC;iBACJ;aACJ;SACJ,CAAC;IACN,CAAC;IACL,4BAAC;AAAD,CAAC,AA7DD,IA6DC;AA7DY,sDAAqB"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.d.ts -new file mode 100644 -index 0000000..069cc18 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.d.ts -@@ -0,0 +1,38 @@ -+/// -+import BaseScrollView from "../../../core/scrollcomponent/BaseScrollView"; -+/*** -+ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. -+ * Supports both window scroll and scrollable divs inside other divs. -+ */ -+export default class ScrollViewer extends BaseScrollView { -+ static defaultProps: { -+ canChangeSize: boolean; -+ horizontal: boolean; -+ style: null; -+ useWindowScroll: boolean; -+ }; -+ private scrollEndEventSimulator; -+ private _mainDivRef; -+ private _isScrolling; -+ private _scrollEventNormalizer; -+ componentDidMount(): void; -+ componentWillUnmount(): void; -+ scrollTo(scrollInput: { -+ x: number; -+ y: number; -+ animated: boolean; -+ }): void; -+ render(): JSX.Element; -+ private _setDivRef; -+ private _getRelevantOffset; -+ private _setRelevantOffset; -+ private _isScrollEnd; -+ private _trackScrollOccurence; -+ private _doAnimatedScroll; -+ private _startListeningToDivEvents; -+ private _startListeningToWindowEvents; -+ private _onWindowResize; -+ private _windowOnScroll; -+ private _onScroll; -+ private _easeInOut; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js -new file mode 100644 -index 0000000..bdfd4e8 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js -@@ -0,0 +1,214 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseScrollView_1 = require("../../../core/scrollcomponent/BaseScrollView"); -+var debounce = require("lodash.debounce"); -+var ScrollEventNormalizer_1 = require("./ScrollEventNormalizer"); -+/*** -+ * A scrollviewer that mimics react native scrollview. Additionally on web it can start listening to window scroll events optionally. -+ * Supports both window scroll and scrollable divs inside other divs. -+ */ -+var ScrollViewer = /** @class */ (function (_super) { -+ __extends(ScrollViewer, _super); -+ function ScrollViewer() { -+ var _this = _super !== null && _super.apply(this, arguments) || this; -+ _this.scrollEndEventSimulator = debounce(function (executable) { -+ executable(); -+ }, 1200); -+ _this._mainDivRef = null; -+ _this._isScrolling = false; -+ _this._scrollEventNormalizer = null; -+ _this._setDivRef = function (div) { -+ _this._mainDivRef = div; -+ if (div) { -+ _this._scrollEventNormalizer = new ScrollEventNormalizer_1.ScrollEventNormalizer(div); -+ } -+ else { -+ _this._scrollEventNormalizer = null; -+ } -+ }; -+ _this._getRelevantOffset = function () { -+ if (!_this.props.useWindowScroll) { -+ if (_this._mainDivRef) { -+ if (_this.props.horizontal) { -+ return _this._mainDivRef.scrollLeft; -+ } -+ else { -+ return _this._mainDivRef.scrollTop; -+ } -+ } -+ return 0; -+ } -+ else { -+ if (_this.props.horizontal) { -+ return window.scrollX; -+ } -+ else { -+ return window.scrollY; -+ } -+ } -+ }; -+ _this._setRelevantOffset = function (offset) { -+ if (!_this.props.useWindowScroll) { -+ if (_this._mainDivRef) { -+ if (_this.props.horizontal) { -+ _this._mainDivRef.scrollLeft = offset; -+ } -+ else { -+ _this._mainDivRef.scrollTop = offset; -+ } -+ } -+ } -+ else { -+ if (_this.props.horizontal) { -+ window.scrollTo(offset, 0); -+ } -+ else { -+ window.scrollTo(0, offset); -+ } -+ } -+ }; -+ _this._isScrollEnd = function () { -+ if (_this._mainDivRef) { -+ _this._mainDivRef.style.pointerEvents = "auto"; -+ } -+ _this._isScrolling = false; -+ }; -+ _this._trackScrollOccurence = function () { -+ if (!_this._isScrolling) { -+ if (_this._mainDivRef) { -+ _this._mainDivRef.style.pointerEvents = "none"; -+ } -+ _this._isScrolling = true; -+ } -+ _this.scrollEndEventSimulator(_this._isScrollEnd); -+ }; -+ _this._onWindowResize = function () { -+ if (_this.props.onSizeChanged && _this.props.useWindowScroll) { -+ _this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); -+ } -+ }; -+ _this._windowOnScroll = function () { -+ if (_this.props.onScroll) { -+ if (_this._scrollEventNormalizer) { -+ _this.props.onScroll(_this._scrollEventNormalizer.windowEvent); -+ } -+ } -+ }; -+ _this._onScroll = function () { -+ if (_this.props.onScroll) { -+ if (_this._scrollEventNormalizer) { -+ _this.props.onScroll(_this._scrollEventNormalizer.divEvent); -+ } -+ } -+ }; -+ return _this; -+ } -+ ScrollViewer.prototype.componentDidMount = function () { -+ if (this.props.onSizeChanged) { -+ if (this.props.useWindowScroll) { -+ this._startListeningToWindowEvents(); -+ this.props.onSizeChanged({ height: window.innerHeight, width: window.innerWidth }); -+ } -+ else if (this._mainDivRef) { -+ this._startListeningToDivEvents(); -+ this.props.onSizeChanged({ height: this._mainDivRef.clientHeight, width: this._mainDivRef.clientWidth }); -+ } -+ } -+ }; -+ ScrollViewer.prototype.componentWillUnmount = function () { -+ window.removeEventListener("scroll", this._windowOnScroll); -+ if (this._mainDivRef) { -+ this._mainDivRef.removeEventListener("scroll", this._onScroll); -+ } -+ window.removeEventListener("resize", this._onWindowResize); -+ }; -+ ScrollViewer.prototype.scrollTo = function (scrollInput) { -+ if (scrollInput.animated) { -+ this._doAnimatedScroll(this.props.horizontal ? scrollInput.x : scrollInput.y); -+ } -+ else { -+ this._setRelevantOffset(this.props.horizontal ? scrollInput.x : scrollInput.y); -+ } -+ }; -+ ScrollViewer.prototype.render = function () { -+ return !this.props.useWindowScroll -+ ? React.createElement("div", { ref: this._setDivRef, style: __assign({ WebkitOverflowScrolling: "touch", height: "100%", overflowX: this.props.horizontal ? "scroll" : "hidden", overflowY: !this.props.horizontal ? "scroll" : "hidden", width: "100%" }, this.props.style) }, -+ React.createElement("div", { style: { position: "relative" } }, this.props.children)) -+ : React.createElement("div", { ref: this._setDivRef, style: __assign({ position: "relative" }, this.props.style) }, this.props.children); -+ }; -+ ScrollViewer.prototype._doAnimatedScroll = function (offset) { -+ var _this = this; -+ var start = this._getRelevantOffset(); -+ if (offset > start) { -+ start = Math.max(offset - 800, start); -+ } -+ else { -+ start = Math.min(offset + 800, start); -+ } -+ var change = offset - start; -+ var increment = 20; -+ var duration = 200; -+ var animateScroll = function (elapsedTime) { -+ elapsedTime += increment; -+ var position = _this._easeInOut(elapsedTime, start, change, duration); -+ _this._setRelevantOffset(position); -+ if (elapsedTime < duration) { -+ window.setTimeout(function () { return animateScroll(elapsedTime); }, increment); -+ } -+ }; -+ animateScroll(0); -+ }; -+ ScrollViewer.prototype._startListeningToDivEvents = function () { -+ if (this._mainDivRef) { -+ this._mainDivRef.addEventListener("scroll", this._onScroll); -+ } -+ }; -+ ScrollViewer.prototype._startListeningToWindowEvents = function () { -+ window.addEventListener("scroll", this._windowOnScroll); -+ if (this.props.canChangeSize) { -+ window.addEventListener("resize", this._onWindowResize); -+ } -+ }; -+ ScrollViewer.prototype._easeInOut = function (currentTime, start, change, duration) { -+ currentTime /= duration / 2; -+ if (currentTime < 1) { -+ return change / 2 * currentTime * currentTime + start; -+ } -+ currentTime -= 1; -+ return (-change) / 2 * (currentTime * (currentTime - 2) - 1) + start; -+ }; -+ ScrollViewer.defaultProps = { -+ canChangeSize: false, -+ horizontal: false, -+ style: null, -+ useWindowScroll: false, -+ }; -+ return ScrollViewer; -+}(BaseScrollView_1.default)); -+exports.default = ScrollViewer; -+//# sourceMappingURL=ScrollViewer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js.map b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js.map -new file mode 100644 -index 0000000..ea465a9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/scrollcomponent/ScrollViewer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ScrollViewer.js","sourceRoot":"","sources":["../../../../../src/platform/web/scrollcomponent/ScrollViewer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.d.ts b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.d.ts -new file mode 100644 -index 0000000..76283f9 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.d.ts -@@ -0,0 +1,19 @@ -+/// -+import BaseViewRenderer from "../../../core/viewrenderer/BaseViewRenderer"; -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+export default class ViewRenderer extends BaseViewRenderer { -+ private _dim; -+ private _mainDiv; -+ componentDidMount(): void; -+ componentDidUpdate(): void; -+ render(): JSX.Element; -+ protected getRef(): object | null; -+ private _setRef; -+ private _getTransform; -+ private _checkSizeChange; -+} -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js -new file mode 100644 -index 0000000..81d8dc1 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js -@@ -0,0 +1,98 @@ -+"use strict"; -+var __extends = (this && this.__extends) || (function () { -+ var extendStatics = function (d, b) { -+ extendStatics = Object.setPrototypeOf || -+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || -+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; -+ return extendStatics(d, b); -+ }; -+ return function (d, b) { -+ extendStatics(d, b); -+ function __() { this.constructor = d; } -+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -+ }; -+})(); -+var __assign = (this && this.__assign) || function () { -+ __assign = Object.assign || function(t) { -+ for (var s, i = 1, n = arguments.length; i < n; i++) { -+ s = arguments[i]; -+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) -+ t[p] = s[p]; -+ } -+ return t; -+ }; -+ return __assign.apply(this, arguments); -+}; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var React = require("react"); -+var BaseViewRenderer_1 = require("../../../core/viewrenderer/BaseViewRenderer"); -+/*** -+ * View renderer is responsible for creating a container of size provided by LayoutProvider and render content inside it. -+ * Also enforces a logic to prevent re renders. RecyclerListView keeps moving these ViewRendereres around using transforms to enable recycling. -+ * View renderer will only update if its position, dimensions or given data changes. Make sure to have a relevant shouldComponentUpdate as well. -+ * This is second of the two things recycler works on. Implemented both for web and react native. -+ */ -+var ViewRenderer = /** @class */ (function (_super) { -+ __extends(ViewRenderer, _super); -+ function ViewRenderer() { -+ var _this = _super !== null && _super.apply(this, arguments) || this; -+ _this._dim = { width: 0, height: 0 }; -+ _this._mainDiv = null; -+ _this._setRef = function (div) { -+ _this._mainDiv = div; -+ }; -+ return _this; -+ } -+ ViewRenderer.prototype.componentDidMount = function () { -+ if (_super.prototype.componentDidMount) { -+ _super.prototype.componentDidMount.call(this); -+ } -+ this._checkSizeChange(); -+ }; -+ ViewRenderer.prototype.componentDidUpdate = function () { -+ this._checkSizeChange(); -+ }; -+ ViewRenderer.prototype.render = function () { -+ var style = this.props.forceNonDeterministicRendering -+ ? __assign({ transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides) : __assign({ height: this.props.height, overflow: "hidden", width: this.props.width, transform: this._getTransform(), WebkitTransform: this._getTransform() }, styles.baseViewStyle, this.props.styleOverrides, this.animatorStyleOverrides); -+ return (React.createElement("div", { ref: this._setRef, style: style }, this.renderChild())); -+ }; -+ ViewRenderer.prototype.getRef = function () { -+ return this._mainDiv; -+ }; -+ ViewRenderer.prototype._getTransform = function () { -+ return "translate(" + this.props.x + "px," + this.props.y + "px)"; -+ }; -+ ViewRenderer.prototype._checkSizeChange = function () { -+ if (this.props.forceNonDeterministicRendering && this.props.onSizeChanged) { -+ var mainDiv = this._mainDiv; -+ if (mainDiv) { -+ this._dim.width = mainDiv.clientWidth; -+ this._dim.height = mainDiv.clientHeight; -+ if (this.props.width !== this._dim.width || this.props.height !== this._dim.height) { -+ this.props.onSizeChanged(this._dim, this.props.index); -+ } -+ } -+ } -+ }; -+ return ViewRenderer; -+}(BaseViewRenderer_1.default)); -+exports.default = ViewRenderer; -+var styles = { -+ baseViewStyle: { -+ alignItems: "stretch", -+ borderWidth: 0, -+ borderStyle: "solid", -+ boxSizing: "border-box", -+ display: "flex", -+ flexDirection: "column", -+ margin: 0, -+ padding: 0, -+ position: "absolute", -+ minHeight: 0, -+ minWidth: 0, -+ left: 0, -+ top: 0, -+ }, -+}; -+//# sourceMappingURL=ViewRenderer.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js.map b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js.map -new file mode 100644 -index 0000000..7810112 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/platform/web/viewrenderer/ViewRenderer.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"ViewRenderer.js","sourceRoot":"","sources":["../../../../../src/platform/web/viewrenderer/ViewRenderer.tsx"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/AutoScroll.d.ts b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.d.ts -new file mode 100644 -index 0000000..0bd1380 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.d.ts -@@ -0,0 +1,6 @@ -+export interface Scrollable { -+ scrollToOffset(x: number, y: number, animate: boolean): void; -+} -+export declare class AutoScroll { -+ static scrollNow(scrollable: Scrollable, fromX: number, fromY: number, toX: number, toY: number, speedMultiplier?: number): Promise; -+} -diff --git a/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js -new file mode 100644 -index 0000000..ab91ef0 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js -@@ -0,0 +1,36 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var AutoScroll = /** @class */ (function () { -+ function AutoScroll() { -+ } -+ AutoScroll.scrollNow = function (scrollable, fromX, fromY, toX, toY, speedMultiplier) { -+ if (speedMultiplier === void 0) { speedMultiplier = 1; } -+ return new Promise(function (resolve) { -+ scrollable.scrollToOffset(fromX, fromY, false); -+ var incrementPerMs = 0.1 * speedMultiplier; -+ var startTime = Date.now(); -+ var startX = fromX; -+ var startY = fromY; -+ var animationLoop = function () { -+ requestAnimationFrame(function () { -+ var currentTime = Date.now(); -+ var timeElapsed = currentTime - startTime; -+ var distanceToCover = incrementPerMs * timeElapsed; -+ startX += distanceToCover; -+ startY += distanceToCover; -+ scrollable.scrollToOffset(Math.min(toX, startX), Math.min(toY, startY), false); -+ startTime = currentTime; -+ if (Math.min(toX, startX) !== toX || Math.min(toY, startY) !== toY) { -+ animationLoop(); -+ return; -+ } -+ resolve(); -+ }); -+ }; -+ animationLoop(); -+ }); -+ }; -+ return AutoScroll; -+}()); -+exports.AutoScroll = AutoScroll; -+//# sourceMappingURL=AutoScroll.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js.map b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js.map -new file mode 100644 -index 0000000..86f9d26 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/AutoScroll.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"AutoScroll.js","sourceRoot":"","sources":["../../../src/utils/AutoScroll.ts"],"names":[],"mappings":";;AAGA;IAAA;IA2BA,CAAC;IA1BiB,oBAAS,GAAvB,UAAwB,UAAsB,EAAE,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,eAA2B;QAA3B,gCAAA,EAAA,mBAA2B;QAC/H,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO;YACvB,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAM,cAAc,GAAG,GAAG,GAAG,eAAe,CAAC;YAC7C,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,IAAM,aAAa,GAAG;gBAClB,qBAAqB,CAAC;oBAClB,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC/B,IAAM,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;oBAC5C,IAAM,eAAe,GAAG,cAAc,GAAG,WAAW,CAAC;oBACrD,MAAM,IAAI,eAAe,CAAC;oBAC1B,MAAM,IAAI,eAAe,CAAC;oBAC1B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;oBAC/E,SAAS,GAAG,WAAW,CAAC;oBACxB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE;wBAChE,aAAa,EAAE,CAAC;wBAChB,OAAO;qBACV;oBACD,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,aAAa,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IACL,iBAAC;AAAD,CAAC,AA3BD,IA2BC;AA3BY,gCAAU"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/BinarySearch.d.ts b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.d.ts -new file mode 100644 -index 0000000..9365580 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.d.ts -@@ -0,0 +1,17 @@ -+export interface ValueAndIndex { -+ value: number; -+ index: number; -+} -+export default class BinarySearch { -+ static findClosestHigherValueIndex(size: number, targetValue: number, valueExtractor: (index: number) => number): number; -+ static findClosestValueToTarget(values: number[], target: number): ValueAndIndex; -+ /** -+ * Largest value from given values that is smaller or equal to the target number. -+ */ -+ static findValueSmallerThanTarget(values: number[], target: number): ValueAndIndex | undefined; -+ /** -+ * Smallest value from given values that is larger or equal to the target number. -+ */ -+ static findValueLargerThanTarget(values: number[], target: number): ValueAndIndex | undefined; -+ static findIndexOf(array: number[], value: number): number; -+} -diff --git a/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js -new file mode 100644 -index 0000000..74f37c5 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js -@@ -0,0 +1,154 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var CustomError_1 = require("../core/exceptions/CustomError"); -+var BinarySearch = /** @class */ (function () { -+ function BinarySearch() { -+ } -+ BinarySearch.findClosestHigherValueIndex = function (size, targetValue, valueExtractor) { -+ var low = 0; -+ var high = size - 1; -+ var mid = Math.floor((low + high) / 2); -+ var lastValue = 0; -+ var absoluteLastDiff = Math.abs(valueExtractor(mid) - targetValue); -+ var result = mid; -+ var diff = 0; -+ var absoluteDiff = 0; -+ if (absoluteLastDiff === 0) { -+ return result; -+ } -+ if (high < 0) { -+ throw new CustomError_1.default({ -+ message: "The collection cannot be empty", -+ type: "InvalidStateException", -+ }); -+ } -+ while (low <= high) { -+ mid = Math.floor((low + high) / 2); -+ lastValue = valueExtractor(mid); -+ diff = lastValue - targetValue; -+ absoluteDiff = Math.abs(diff); -+ if (diff >= 0 && absoluteDiff < absoluteLastDiff) { -+ absoluteLastDiff = absoluteDiff; -+ result = mid; -+ } -+ if (targetValue < lastValue) { -+ high = mid - 1; -+ } -+ else if (targetValue > lastValue) { -+ low = mid + 1; -+ } -+ else { -+ return mid; -+ } -+ } -+ return result; -+ }; -+ BinarySearch.findClosestValueToTarget = function (values, target) { -+ var low = 0; -+ var high = values.length - 1; -+ var mid = Math.floor((low + high) / 2); -+ var midValue = values[mid]; -+ var lastMidValue = midValue + 1; -+ while (low <= high && midValue !== lastMidValue) { -+ if (midValue === target) { -+ break; -+ } -+ else if (midValue < target) { -+ low = mid; -+ } -+ else if (midValue > target) { -+ high = mid; -+ } -+ mid = Math.floor((low + high) / 2); -+ lastMidValue = midValue; -+ midValue = values[mid]; -+ } -+ return { -+ value: midValue, -+ index: mid, -+ }; -+ }; -+ /** -+ * Largest value from given values that is smaller or equal to the target number. -+ */ -+ BinarySearch.findValueSmallerThanTarget = function (values, target) { -+ var low = 0; -+ var high = values.length - 1; -+ if (target >= values[high]) { -+ return { -+ value: values[high], -+ index: high, -+ }; -+ } -+ else if (target < values[low]) { -+ return undefined; -+ } -+ var midValueAndIndex = this.findClosestValueToTarget(values, target); -+ var midValue = midValueAndIndex.value; -+ var mid = midValueAndIndex.index; -+ if (midValue <= target) { -+ return { -+ value: midValue, -+ index: mid, -+ }; -+ } -+ else { -+ return { -+ value: values[mid - 1], -+ index: mid - 1, -+ }; -+ } -+ }; -+ /** -+ * Smallest value from given values that is larger or equal to the target number. -+ */ -+ BinarySearch.findValueLargerThanTarget = function (values, target) { -+ var low = 0; -+ var high = values.length - 1; -+ if (target < values[low]) { -+ return { -+ value: values[low], -+ index: low, -+ }; -+ } -+ else if (target > values[high]) { -+ return undefined; -+ } -+ var midValueAndIndex = this.findClosestValueToTarget(values, target); -+ var midValue = midValueAndIndex.value; -+ var mid = midValueAndIndex.index; -+ if (midValue >= target) { -+ return { -+ value: midValue, -+ index: mid, -+ }; -+ } -+ else { -+ return { -+ value: values[mid + 1], -+ index: mid + 1, -+ }; -+ } -+ }; -+ BinarySearch.findIndexOf = function (array, value) { -+ var j = 0; -+ var length = array.length; -+ var i = 0; -+ while (j < length) { -+ i = length + j - 1 >> 1; -+ if (value > array[i]) { -+ j = i + 1; -+ } -+ else if (value < array[i]) { -+ length = i; -+ } -+ else { -+ return i; -+ } -+ } -+ return -1; -+ }; -+ return BinarySearch; -+}()); -+exports.default = BinarySearch; -+//# sourceMappingURL=BinarySearch.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js.map b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js.map -new file mode 100644 -index 0000000..8684678 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/BinarySearch.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"BinarySearch.js","sourceRoot":"","sources":["../../../src/utils/BinarySearch.ts"],"names":[],"mappings":";;AAAA,8DAAyD;AAMzD;IAAA;IA2IA,CAAC;IA1IiB,wCAA2B,GAAzC,UAA0C,IAAY,EAAE,WAAmB,EAAE,cAAyC;QAClH,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QACpB,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;QACnE,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,IAAI,gBAAgB,KAAK,CAAC,EAAE;YACxB,OAAO,MAAM,CAAC;SACjB;QAED,IAAI,IAAI,GAAG,CAAC,EAAE;YACV,MAAM,IAAI,qBAAW,CAAC;gBAClB,OAAO,EAAE,gCAAgC;gBACzC,IAAI,EAAE,uBAAuB;aAChC,CAAC,CAAC;SACN;QAED,OAAO,GAAG,IAAI,IAAI,EAAE;YAChB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,GAAG,SAAS,GAAG,WAAW,CAAC;YAC/B,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,IAAI,IAAI,CAAC,IAAI,YAAY,GAAG,gBAAgB,EAAE;gBAC9C,gBAAgB,GAAG,YAAY,CAAC;gBAChC,MAAM,GAAG,GAAG,CAAC;aAChB;YACD,IAAI,WAAW,GAAG,SAAS,EAAE;gBACzB,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;aAClB;iBAAM,IAAI,WAAW,GAAG,SAAS,EAAE;gBAChC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;aACjB;iBAAM;gBACH,OAAO,GAAG,CAAC;aACd;SACJ;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IACa,qCAAwB,GAAtC,UAAuC,MAAgB,EAAE,MAAc;QACnE,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,YAAY,GAAG,QAAQ,GAAG,CAAC,CAAC;QAEhC,OAAO,GAAG,IAAI,IAAI,IAAI,QAAQ,KAAK,YAAY,EAAE;YAC7C,IAAI,QAAQ,KAAK,MAAM,EAAE;gBACrB,MAAM;aACT;iBAAM,IAAI,QAAQ,GAAG,MAAM,EAAE;gBAC1B,GAAG,GAAG,GAAG,CAAC;aACb;iBAAM,IAAI,QAAQ,GAAG,MAAM,EAAE;gBAC1B,IAAI,GAAG,GAAG,CAAC;aACd;YACD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC,YAAY,GAAG,QAAQ,CAAC;YACxB,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;SAC1B;QACD,OAAO;YACH,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,GAAG;SACb,CAAC;IACN,CAAC;IACD;;OAEG;IACW,uCAA0B,GAAxC,UAAyC,MAAgB,EAAE,MAAc;QACrE,IAAM,GAAG,GAAG,CAAC,CAAC;QACd,IAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;YACxB,OAAO;gBACH,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,IAAI;aACd,CAAC;SACL;aAAM,IAAI,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE;YAC7B,OAAO,SAAS,CAAC;SACpB;QACD,IAAM,gBAAgB,GAAkB,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtF,IAAM,QAAQ,GAAW,gBAAgB,CAAC,KAAK,CAAC;QAChD,IAAM,GAAG,GAAW,gBAAgB,CAAC,KAAK,CAAC;QAC3C,IAAI,QAAQ,IAAI,MAAM,EAAE;YACpB,OAAO;gBACH,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,GAAG;aACb,CAAC;SACL;aAAM;YACH,OAAO;gBACH,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;gBACtB,KAAK,EAAE,GAAG,GAAG,CAAC;aACjB,CAAC;SACL;IACL,CAAC;IACD;;OAEG;IACW,sCAAyB,GAAvC,UAAwC,MAAgB,EAAE,MAAc;QACpE,IAAM,GAAG,GAAG,CAAC,CAAC;QACd,IAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE;YACtB,OAAO;gBACH,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;gBAClB,KAAK,EAAE,GAAG;aACb,CAAC;SACL;aAAM,IAAI,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE;YAC9B,OAAO,SAAS,CAAC;SACpB;QACD,IAAM,gBAAgB,GAAkB,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtF,IAAM,QAAQ,GAAW,gBAAgB,CAAC,KAAK,CAAC;QAChD,IAAM,GAAG,GAAW,gBAAgB,CAAC,KAAK,CAAC;QAC3C,IAAI,QAAQ,IAAI,MAAM,EAAE;YACpB,OAAO;gBACH,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,GAAG;aACb,CAAC;SACL;aAAM;YACH,OAAO;gBACH,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;gBACtB,KAAK,EAAE,GAAG,GAAG,CAAC;aACjB,CAAC;SACL;IACL,CAAC;IACa,wBAAW,GAAzB,UAA0B,KAAe,EAAE,KAAa;QACpD,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,MAAM,EAAE;YACf,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;gBAClB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aACb;iBAAM,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;gBACzB,MAAM,GAAG,CAAC,CAAC;aACd;iBAAM;gBACH,OAAO,CAAC,CAAC;aACZ;SACJ;QACD,OAAO,CAAC,CAAC,CAAC;IACd,CAAC;IACL,mBAAC;AAAD,CAAC,AA3ID,IA2IC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.d.ts b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.d.ts -new file mode 100644 -index 0000000..113cffc ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.d.ts -@@ -0,0 +1,15 @@ -+/*** -+ * Recycle pool for maintaining recyclable items, supports segregation by type as well. -+ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation -+ */ -+export default class RecycleItemPool { -+ private _recyclableObjectMap; -+ private _availabilitySet; -+ constructor(); -+ putRecycledObject(objectType: string | number, object: string): void; -+ getRecycledObject(objectType: string | number): string | undefined; -+ removeFromPool(object: string): boolean; -+ clearAll(): void; -+ private _getRelevantSet; -+ private _stringify; -+} -diff --git a/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js -new file mode 100644 -index 0000000..d1173ad ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js -@@ -0,0 +1,65 @@ -+"use strict"; -+/*** -+ * Recycle pool for maintaining recyclable items, supports segregation by type as well. -+ * Availability check, add/remove etc are all O(1), uses two maps to achieve constant time operation -+ */ -+Object.defineProperty(exports, "__esModule", { value: true }); -+var RecycleItemPool = /** @class */ (function () { -+ function RecycleItemPool() { -+ this._recyclableObjectMap = {}; -+ this._availabilitySet = {}; -+ } -+ RecycleItemPool.prototype.putRecycledObject = function (objectType, object) { -+ objectType = this._stringify(objectType); -+ var objectSet = this._getRelevantSet(objectType); -+ if (!this._availabilitySet[object]) { -+ objectSet[object] = null; -+ this._availabilitySet[object] = objectType; -+ } -+ }; -+ RecycleItemPool.prototype.getRecycledObject = function (objectType) { -+ objectType = this._stringify(objectType); -+ var objectSet = this._getRelevantSet(objectType); -+ var recycledObject; -+ for (var property in objectSet) { -+ if (objectSet.hasOwnProperty(property)) { -+ recycledObject = property; -+ break; -+ } -+ } -+ if (recycledObject) { -+ delete objectSet[recycledObject]; -+ delete this._availabilitySet[recycledObject]; -+ } -+ return recycledObject; -+ }; -+ RecycleItemPool.prototype.removeFromPool = function (object) { -+ if (this._availabilitySet[object]) { -+ delete this._getRelevantSet(this._availabilitySet[object])[object]; -+ delete this._availabilitySet[object]; -+ return true; -+ } -+ return false; -+ }; -+ RecycleItemPool.prototype.clearAll = function () { -+ this._recyclableObjectMap = {}; -+ this._availabilitySet = {}; -+ }; -+ RecycleItemPool.prototype._getRelevantSet = function (objectType) { -+ var objectSet = this._recyclableObjectMap[objectType]; -+ if (!objectSet) { -+ objectSet = {}; -+ this._recyclableObjectMap[objectType] = objectSet; -+ } -+ return objectSet; -+ }; -+ RecycleItemPool.prototype._stringify = function (objectType) { -+ if (typeof objectType === "number") { -+ objectType = objectType.toString(); -+ } -+ return objectType; -+ }; -+ return RecycleItemPool; -+}()); -+exports.default = RecycleItemPool; -+//# sourceMappingURL=RecycleItemPool.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js.map b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js.map -new file mode 100644 -index 0000000..2dde95b ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/RecycleItemPool.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"RecycleItemPool.js","sourceRoot":"","sources":["../../../src/utils/RecycleItemPool.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH;IAII;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B,EAAE,MAAc;QAChE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAChC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;SAC9C;IACL,CAAC;IAEM,2CAAiB,GAAxB,UAAyB,UAA2B;QAChD,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC;QACnB,KAAK,IAAM,QAAQ,IAAI,SAAS,EAAE;YAC9B,IAAI,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;gBACpC,cAAc,GAAG,QAAQ,CAAC;gBAC1B,MAAM;aACT;SACJ;QAED,IAAI,cAAc,EAAE;YAChB,OAAO,SAAS,CAAC,cAAc,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;SAChD;QACD,OAAO,cAAc,CAAC;IAC1B,CAAC;IAEM,wCAAc,GAArB,UAAsB,MAAc;QAChC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;SACf;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,kCAAQ,GAAf;QACI,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAEO,yCAAe,GAAvB,UAAwB,UAAkB;QACtC,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE;YACZ,SAAS,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;SACrD;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,oCAAU,GAAlB,UAAmB,UAA2B;QAC1C,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;YAChC,UAAU,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC;SACtC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;IACL,sBAAC;AAAD,CAAC,AAjED,IAiEC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/TSCast.d.ts b/node_modules/recyclerlistview/dist/web/utils/TSCast.d.ts -new file mode 100644 -index 0000000..d867c7e ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/TSCast.d.ts -@@ -0,0 +1,3 @@ -+export default class TSCast { -+ static cast(object: any): T; -+} -diff --git a/node_modules/recyclerlistview/dist/web/utils/TSCast.js b/node_modules/recyclerlistview/dist/web/utils/TSCast.js -new file mode 100644 -index 0000000..526f93a ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/TSCast.js -@@ -0,0 +1,12 @@ -+"use strict"; -+Object.defineProperty(exports, "__esModule", { value: true }); -+var TSCast = /** @class */ (function () { -+ function TSCast() { -+ } -+ TSCast.cast = function (object) { -+ return object; -+ }; -+ return TSCast; -+}()); -+exports.default = TSCast; -+//# sourceMappingURL=TSCast.js.map -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/dist/web/utils/TSCast.js.map b/node_modules/recyclerlistview/dist/web/utils/TSCast.js.map -new file mode 100644 -index 0000000..3384c98 ---- /dev/null -+++ b/node_modules/recyclerlistview/dist/web/utils/TSCast.js.map -@@ -0,0 +1 @@ -+{"version":3,"file":"TSCast.js","sourceRoot":"","sources":["../../../src/utils/TSCast.ts"],"names":[],"mappings":";;AAAA;IAAA;IAIA,CAAC;IAHiB,WAAI,GAAlB,UAAsB,MAAW;QAC7B,OAAO,MAAW,CAAC;IACvB,CAAC;IACL,aAAC;AAAD,CAAC,AAJD,IAIC"} -\ No newline at end of file -diff --git a/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts b/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts -index bdfa5fb..34e2a71 100644 ---- a/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts -+++ b/node_modules/recyclerlistview/src/core/ViewabilityTracker.ts -@@ -66,9 +66,8 @@ export default class ViewabilityTracker { - } - - public forceRefresh(): boolean { -- const shouldForceScroll = this._currentOffset >= (this._maxOffset - this._windowBound); - this.forceRefreshWithOffset(this._currentOffset); -- return shouldForceScroll; -+ return false; - } - - public forceRefreshWithOffset(offset: number): void { -diff --git a/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts b/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts -index e9454a4..3ecd8ac 100644 ---- a/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts -+++ b/node_modules/recyclerlistview/src/core/layoutmanager/LayoutManager.ts -@@ -189,6 +189,10 @@ export class WrapGridLayoutManager extends LayoutManager { - } - let i = startIndex - 1; - for (; i >= 0; i--) { -+ if (!this._layouts[i]) { -+ console.warn("WrapGridLayoutManager layout at index", i, "does not exist"); //tslint:disable-line -+ continue; -+ } - if (this._isHorizontal) { - if (this._layouts[i].y === 0) { - break; -diff --git a/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx b/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx -index 22db8a2..6d91cc6 100644 ---- a/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx -+++ b/node_modules/recyclerlistview/src/core/sticky/StickyHeader.tsx -@@ -53,6 +53,6 @@ export default class StickyHeader

JSX.Element | JSX.Element[] | null; - } - export interface StickyObjectState { -- visible: boolean; -+ visibility: boolean; - } - export default abstract class StickyObject

extends React.Component { - protected stickyType: StickyType = StickyType.HEADER; - protected stickyTypeMultiplier: number = 1; - protected stickyVisiblity: boolean = false; -+ protected visibility: boolean = false; - protected containerPosition: StyleProp; - protected currentIndex: number = 0; - protected currentStickyIndex: number = 0; -@@ -64,7 +65,7 @@ export default abstract class StickyObject

-- {this.state.visible ? -+ {this.visibility ? - this._renderSticky() - : null} - -@@ -103,6 +104,15 @@ export default abstract class StickyObject

= 0 && prevVisibility === false) { -+ this.visibility = true; -+ } -+ if (prevVisibility !== this.visibility) { -+ this.render(); -+ } - this._initParams(); - this._offsetY = offsetY; - this.boundaryProcessing(offsetY, this.props.getDistanceFromWindow(), this._windowBound); -@@ -156,7 +166,7 @@ export default abstract class StickyObject

= 2.1.2 < 3" -+ -+inflight@^1.0.4: -+ version "1.0.6" -+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" -+ integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= -+ dependencies: -+ once "^1.3.0" -+ wrappy "1" -+ -+inherits@2: -+ version "2.0.4" -+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" -+ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -+ -+is-stream@^1.0.1: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -+ integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -+ -+isomorphic-fetch@^2.1.1: -+ version "2.2.1" -+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" -+ integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= -+ dependencies: -+ node-fetch "^1.0.1" -+ whatwg-fetch ">=0.10.0" -+ -+istextorbinary@^2.1.0: -+ version "2.5.1" -+ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.5.1.tgz#14a33824cf6b9d5d7743eac1be2bd2c310d0ccbd" -+ integrity sha512-pv/JNPWnfpwGjPx7JrtWTwsWsxkrK3fNzcEVnt92YKEIErps4Fsk49+qzCe9iQF2hjqK8Naqf8P9kzoeCuQI1g== -+ dependencies: -+ binaryextensions "^2.1.2" -+ editions "^2.1.3" -+ textextensions "^2.4.0" -+ -+"js-tokens@^3.0.0 || ^4.0.0": -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" -+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -+ -+js-tokens@^3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -+ integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -+ -+js-yaml@^3.7.0: -+ version "3.13.1" -+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" -+ integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== -+ dependencies: -+ argparse "^1.0.7" -+ esprima "^4.0.0" -+ -+lodash.debounce@4.0.8: -+ version "4.0.8" -+ resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" -+ integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -+ -+loose-envify@^1.0.0: -+ version "1.4.0" -+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" -+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== -+ dependencies: -+ js-tokens "^3.0.0 || ^4.0.0" -+ -+minimatch@^3.0.4: -+ version "3.0.4" -+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" -+ integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== -+ dependencies: -+ brace-expansion "^1.1.7" -+ -+ncp@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" -+ integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= -+ -+node-fetch@^1.0.1: -+ version "1.7.3" -+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" -+ integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== -+ dependencies: -+ encoding "^0.1.11" -+ is-stream "^1.0.1" -+ -+object-assign@^4.1.0: -+ version "4.1.1" -+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -+ integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -+ -+once@^1.3.0: -+ version "1.4.0" -+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" -+ integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= -+ dependencies: -+ wrappy "1" -+ -+path-is-absolute@^1.0.0: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -+ integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -+ -+path-parse@^1.0.6: -+ version "1.0.6" -+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" -+ integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -+ -+promise@^7.1.1: -+ version "7.3.1" -+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" -+ integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== -+ dependencies: -+ asap "~2.0.3" -+ -+prop-types@15.5.8: -+ version "15.5.8" -+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394" -+ integrity sha1-a3suFBCDvjjIWVqlH8VXdccZk5Q= -+ dependencies: -+ fbjs "^0.8.9" -+ -+resolve@^1.3.2: -+ version "1.12.0" -+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" -+ integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== -+ dependencies: -+ path-parse "^1.0.6" -+ -+"safer-buffer@>= 2.1.2 < 3": -+ version "2.1.2" -+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -+ -+semver@^5.3.0, semver@^5.6.0: -+ version "5.7.1" -+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" -+ integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -+ -+setimmediate@^1.0.5: -+ version "1.0.5" -+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" -+ integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= -+ -+sprintf-js@~1.0.2: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -+ integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -+ -+strip-ansi@^3.0.0: -+ version "3.0.1" -+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" -+ integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= -+ dependencies: -+ ansi-regex "^2.0.0" -+ -+supports-color@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -+ integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -+ -+supports-color@^5.3.0: -+ version "5.5.0" -+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" -+ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== -+ dependencies: -+ has-flag "^3.0.0" -+ -+textextensions@^2.4.0: -+ version "2.5.0" -+ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.5.0.tgz#e21d3831dafa37513dd80666dff541414e314293" -+ integrity sha512-1IkVr355eHcomgK7fgj1Xsokturx6L5S2JRT5WcRdA6v5shk9sxWuO/w/VbpQexwkXJMQIa/j1dBi3oo7+HhcA== -+ -+ts-object-utils@0.0.5: -+ version "0.0.5" -+ resolved "https://registry.yarnpkg.com/ts-object-utils/-/ts-object-utils-0.0.5.tgz#95361cdecd7e52167cfc5e634c76345e90a26077" -+ integrity sha1-lTYc3s1+UhZ8/F5jTHY0XpCiYHc= -+ -+tslib@^1.8.0, tslib@^1.8.1: -+ version "1.10.0" -+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" -+ integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== -+ -+tslint@5.11.0: -+ version "5.11.0" -+ resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed" -+ integrity sha1-mPMMAurjzecAYgHkwzywi0hYHu0= -+ dependencies: -+ babel-code-frame "^6.22.0" -+ builtin-modules "^1.1.1" -+ chalk "^2.3.0" -+ commander "^2.12.1" -+ diff "^3.2.0" -+ glob "^7.1.1" -+ js-yaml "^3.7.0" -+ minimatch "^3.0.4" -+ resolve "^1.3.2" -+ semver "^5.3.0" -+ tslib "^1.8.0" -+ tsutils "^2.27.2" -+ -+tsutils@^2.27.2: -+ version "2.29.0" -+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" -+ integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== -+ dependencies: -+ tslib "^1.8.1" -+ -+typescript@3.3.1: -+ version "3.3.1" -+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b" -+ integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA== -+ -+ua-parser-js@^0.7.18: -+ version "0.7.20" -+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" -+ integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== -+ -+whatwg-fetch@>=0.10.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" -+ integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== -+ -+wrappy@1: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -+ integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= diff --git a/src/components/shadow-stack/ShadowStack.js b/src/components/shadow-stack/ShadowStack.js index 8667a4e9509..dadb21f6d3b 100644 --- a/src/components/shadow-stack/ShadowStack.js +++ b/src/components/shadow-stack/ShadowStack.js @@ -6,13 +6,11 @@ import styled from 'styled-components/primitives'; import { colors, position } from '../../styles'; import ShadowItem from './ShadowItem'; - // flex-shrink: 0; const ChildrenWrapper = styled.View` ${position.cover}; background-color: ${({ backgroundColor }) => backgroundColor || colors.transparent}; border-radius: ${({ borderRadius }) => borderRadius}; overflow: hidden; - z-index: ${({ zIndex }) => zIndex}; `; const ShadowStackContainer = styled.View` @@ -30,8 +28,6 @@ const ShadowStackContainer = styled.View` border-radius: ${({ borderRadius }) => borderRadius}; z-index: 1; `; - // width: ${({ width }) => width}; - // height: ${({ height }) => height}; const ShadowItemPropBlacklist = ['children', 'shadowProps', 'shadows', 'style']; diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index e1d2054f8f3..b4eba1c28d7 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -2,7 +2,7 @@ import { StatusBar } from 'react-native'; import Animated from 'react-native-reanimated'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; import store from '../../redux/store'; -import { updateTransitionProps } from '../../redux/navigation'; +import { updateStackTransitionProps } from '../../redux/navigation'; import { deviceUtils } from '../../utils'; import { colors } from '../../styles'; @@ -47,7 +47,7 @@ const expandStyleInterpolator = ({ const onStart = or(and(eq(closing, 0), eq(current, 0)), and(eq(closing, 1), eq(current, 1))); const setShowingModal = call([], () => { - store.dispatch(updateTransitionProps({ showingModal: true })); + store.dispatch(updateStackTransitionProps({ showingModal: true })); }); return { @@ -97,7 +97,7 @@ const sheetStyleInterpolator = ({ const backgroundInterpolator = ({ progress: { next } }) => { const dispatch = cond(call([], () => { - store.dispatch(updateTransitionProps({ position: next })); + store.dispatch(updateStackTransitionProps({ position: next })); })); return { cardStyle: { opacity: block([dispatch, 1]) } }; }; diff --git a/src/navigation/transitions/expanded.js b/src/navigation/transitions/expanded.js deleted file mode 100644 index 550ff3f6cc8..00000000000 --- a/src/navigation/transitions/expanded.js +++ /dev/null @@ -1,116 +0,0 @@ -import { get } from 'lodash'; -import { Animated, Easing } from 'react-native'; -import { updateStackTransitionProps } from '../../redux/navigation'; -import store from '../../redux/store'; -import { colors } from '../../styles'; -import { deviceUtils, statusBar } from '../../utils'; - -export const transitionName = 'expanded'; - -export default function expanded(navigation, transitionProps, prevTransitionProps) { - const nextEffect = get(transitionProps, 'scene.descriptor.options.effect'); - const prevEffect = get(prevTransitionProps, 'scene.descriptor.options.effect'); - const nextIndex = get(transitionProps, 'index'); - const prevIndex = get(prevTransitionProps, 'index', nextIndex - 1); - - if (nextEffect === transitionName) { - statusBar.setBarStyle('light-content', true); - } - - if (prevEffect === transitionName) { - statusBar.setBarStyle('dark-content', true); - } - - return { - containerStyle: { - backgroundColor: colors.alpha(colors.blueGreyDarker, 0.72), - opacity: 1, - }, - screenInterpolator: (sceneProps = {}) => { - const { - layout, - position, - scene, - } = sceneProps; - - store.dispatch(updateStackTransitionProps({ - effect: transitionName, - nextIndex, - position, - prevIndex, - })); - - const opacityEnd = 1; - const translateYStart = deviceUtils.dimensions.height; - - if (nextEffect === transitionName && scene.index === prevIndex && nextIndex > prevIndex) { - const opacity = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [1, opacityEnd], - }); - - return { - backgroundColor: 'transparent', - opacity, - }; - } - - if (nextEffect === transitionName && scene.index === nextIndex && nextIndex > prevIndex) { - const translateY = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [translateYStart, 0], - }); - - return { - backgroundColor: 'transparent', - transform: [{ - translateY, - }], - }; - } - - if (prevEffect === transitionName && scene.index === nextIndex && nextIndex < prevIndex) { - const opacity = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [1, opacityEnd], - }); - - return { - opacity, - }; - } - - if (prevEffect === transitionName && scene.index === prevIndex && nextIndex < prevIndex) { - const translateY = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [translateYStart, 0], - }); - - return { - transform: [{ - translateY, - }], - }; - } - - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [scene.index - 1, scene.index], - outputRange: [width, 0], - }); - - return { - overflow: 'hidden', - transform: [{ - translateX, - }], - }; - }, - transitionSpec: { - duration: 315, - easing: Easing.bezier(0.19, 1, 0.22, 1), - timing: Animated.timing, - useNativeDriver: true, - }, - }; -} diff --git a/src/navigation/transitions/sheet.js b/src/navigation/transitions/sheet.js deleted file mode 100644 index 17dbed569aa..00000000000 --- a/src/navigation/transitions/sheet.js +++ /dev/null @@ -1,241 +0,0 @@ -import { get } from 'lodash'; -import { Animated, Easing } from 'react-native'; -import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; -import { updateStackTransitionProps } from '../../redux/navigation'; -import store from '../../redux/store'; -import { colors } from '../../styles'; -import { deviceUtils, statusBar } from '../../utils'; - -const distanceFromTop = 14; -const statusBarHeight = getStatusBarHeight(true); - -export const sheetVerticalOffset = distanceFromTop + statusBarHeight; -export const transitionName = 'sheet'; - -export default function sheet(navigation, transitionProps, prevTransitionProps) { - const nextEffect = get(transitionProps, 'scene.descriptor.options.effect'); - const prevEffect = get(prevTransitionProps, 'scene.descriptor.options.effect'); - const nextIndex = get(transitionProps, 'index'); - const prevIndex = get(prevTransitionProps, 'index', nextIndex - 1); - - if (nextEffect === transitionName) { - statusBar.setBarStyle('light-content', true); - } - - if (prevEffect === transitionName) { - statusBar.setBarStyle('dark-content', true); - } - - return { - containerStyle: { - backgroundColor: colors.black, - opacity: 1, - }, - screenInterpolator: (sceneProps = {}) => { - const { - layout, - position, - scene, - } = sceneProps; - - store.dispatch(updateStackTransitionProps({ - effect: transitionName, - nextIndex, - position, - prevIndex, - })); - - const scaleEnd = 1 - ((statusBarHeight + (isIphoneX() ? distanceFromTop : 0)) / deviceUtils.dimensions.height); - const heightEnd = statusBarHeight + distanceFromTop; - const borderRadiusEnd = 12; - const borderRadiusScaledEnd = borderRadiusEnd / scaleEnd; - const opacityEnd = 0.5; - - if (nextEffect === transitionName && scene.index === prevIndex && nextIndex > prevIndex) { - const translateY = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [0, distanceFromTop], - }); - - const opacity = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [1, opacityEnd], - }); - - const scale = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [1, scaleEnd], - }); - - const borderRadius = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [isIphoneX() ? 38.5 : 0, borderRadiusScaledEnd], - }); - - return { - borderTopLeftRadius: borderRadius, - borderTopRightRadius: borderRadius, - opacity, - overflow: 'hidden', - transform: [{ - translateY, - }, { - scale, - }], - zIndex: 1, - }; - } - - if (nextEffect === transitionName && scene.index === nextIndex && nextIndex > prevIndex) { - const height = layout.initHeight; - const translateY = position.interpolate({ - inputRange: [prevIndex, nextIndex], - outputRange: [height, heightEnd], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - overflow: 'hidden', - transform: [{ - translateY, - }], - zIndex: 2, - }; - } - - if (prevEffect === transitionName && scene.index === nextIndex && nextIndex < prevIndex) { - const opacity = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [1, opacityEnd], - }); - - const scale = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [1, scaleEnd], - }); - - const borderRadius = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [0, borderRadiusEnd], - }); - - return { - borderTopLeftRadius: borderRadius, - borderTopRightRadius: borderRadius, - opacity, - overflow: 'hidden', - transform: [{ - scale, - }], - zIndex: 1, - }; - } - - if (prevEffect === transitionName && scene.index === prevIndex && nextIndex < prevIndex) { - const height = layout.initHeight; - const translateY = position.interpolate({ - inputRange: [nextIndex, prevIndex], - outputRange: [height, heightEnd], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - overflow: 'hidden', - transform: [{ - translateY, - }], - zIndex: 2, - }; - } - - if ((prevEffect === transitionName && scene.index === prevIndex) || (nextEffect === transitionName && scene.index === nextIndex)) { - const height = layout.initHeight; - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [scene.index - 1, scene.index], - outputRange: [width, 0], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - height: height - heightEnd, - overflow: 'hidden', - transform: [{ - translateX, - }, { - translateY: heightEnd, - }], - zIndex: 2, - }; - } - - if (nextEffect === transitionName && prevIndex > nextIndex && scene.index === nextIndex - 1) { - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [nextIndex - 1, nextIndex], - outputRange: [width, 0], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - opacity: opacityEnd, - overflow: 'hidden', - transform: [{ - translateX, - }, { - translateY: distanceFromTop, - }, { - scale: scaleEnd, - }], - }; - } - - if (prevEffect === transitionName && prevIndex < nextIndex && scene.index === prevIndex - 1) { - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [prevIndex - 1, prevIndex], - outputRange: [width, 0], - }); - - return { - borderTopLeftRadius: borderRadiusEnd, - borderTopRightRadius: borderRadiusEnd, - opacity: opacityEnd, - overflow: 'hidden', - transform: [{ - translateX, - }, { - translateY: distanceFromTop, - }, { - scale: scaleEnd, - }], - }; - } - - const width = layout.initWidth; - const translateX = position.interpolate({ - inputRange: [scene.index - 1, scene.index], - outputRange: [width, 0], - }); - - return { - overflow: 'hidden', - transform: [{ - translateX, - }], - }; - }, - transitionSpec: { - duration: 375, - easing: Easing.bezier(0.19, 1, 0.22, 1), - timing: Animated.timing, - useNativeDriver: true, - }, - }; -} diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 1b37557aa8f..dd48f54abef 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -1,7 +1,6 @@ import analytics from '@segment/analytics-react-native'; import { get } from 'lodash'; import React from 'react'; -import Animated from 'react-native-reanimated'; import { createAppContainer, createMaterialTopTabNavigator, @@ -76,7 +75,7 @@ const MainNavigator = createStackNavigator({ ExampleScreen, ExchangeModal: { navigationOptions: { - effect: 'expanded', + ...expandedPreset, gestureResponseDistance: { vertical: deviceUtils.dimensions.height, }, @@ -123,18 +122,6 @@ const MainNavigator = createStackNavigator({ transparentCard: true, }, - ExchangeModal2: { - navigationOptions: { - effect: 'sheet', - gestureResponseDistance: { - vertical: deviceUtils.dimensions.height, - }, - mode: 'card', - gesturesEnabled: true, - }, - mode: 'card', - screen: ExchangeModal, - }, SwipeLayout: { navigationOptions: { ...backgroundPreset, diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index f3c14dca244..52a9419a889 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -113,11 +113,6 @@ class WalletScreen extends Component { sections, } = this.props; - const blurTranslateY = blurOpacity.interpolate({ - inputRange: [0, 0.001, 1], - outputRange: [deviceUtils.dimensions.height, 0, 0], - }); - return ( {/* Line below appears to be needed for having scrollViewTracker persistent while diff --git a/yarn.lock b/yarn.lock index 943d6ed373f..4f12a685fe5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,40 +9,10 @@ dependencies: "@babel/highlight" "^7.0.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== -======= -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": -======= -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": ->>>>>>> 96db5a28... begin mike -======= -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": -======= -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": ->>>>>>> dca19a02... very work in progress - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" - integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== ->>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/code-frame" "^7.5.5" "@babel/generator" "^7.6.0" @@ -51,50 +21,6 @@ "@babel/template" "^7.6.0" "@babel/traverse" "^7.6.0" "@babel/types" "^7.6.0" -======= -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a" - integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.4.4" - "@babel/helpers" "^7.4.4" - "@babel/parser" "^7.4.5" - "@babel/template" "^7.4.4" -<<<<<<< HEAD - "@babel/traverse" "^7.4.5" - "@babel/types" "^7.4.4" ->>>>>>> 751dba29... Replace navigation animations with new effects -======= - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd" - integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/helpers" "^7.5.4" - "@babel/parser" "^7.5.0" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -103,76 +29,12 @@ semver "^5.4.1" source-map "^0.5.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= -======= ->>>>>>> 2216260a... Create Exchange related Input components -"@babel/generator@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" - integrity sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ== - dependencies: - "@babel/types" "7.0.0-beta.44" - jsesc "^2.5.1" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA== dependencies: "@babel/types" "^7.6.0" -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> 034f7aa3... Create Exchange related Input components ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 034f7aa3... Create Exchange related Input components -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> dca19a02... very work in progress -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" - integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== - dependencies: - "@babel/types" "^7.5.5" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.0.tgz#f20e4b7a91750ee8b63656073d843d2a736dca4a" - integrity sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA== - dependencies: - "@babel/types" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -210,45 +72,10 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -"@babel/helper-create-class-features-plugin@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" - integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= -"@babel/helper-create-class-features-plugin@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz#02edb97f512d44ba23b3227f1bf2ed43454edac5" - integrity sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.5.5" @@ -388,10 +215,6 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/helpers@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e" @@ -400,45 +223,6 @@ "@babel/template" "^7.6.0" "@babel/traverse" "^7.6.0" "@babel/types" "^7.6.0" -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -"@babel/helpers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" - integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== - dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= -"@babel/helpers@^7.5.4": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.4.tgz#2f00608aa10d460bde0ccf665d6dcf8477357cf0" - integrity sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow== - dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.0" - "@babel/types" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/highlight@^7.0.0": version "7.5.0" @@ -449,45 +233,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" - integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.0.tgz#3e0713dff89ad6ae37faec3b29dcfc5c979770b7" - integrity sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -791,39 +540,9 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" integrity sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg== -======= -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" - integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== -======= - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.0.tgz#45242c2c9281158c5f06d25beebac63e498a284e" - integrity sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" - integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" - integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -861,48 +580,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz#48d78405f1aa856ebeea7288a48a19ed8da377a6" integrity sha512-yzw7EopOOr6saONZ3KA3lpizKnWRTe+rfBqg4AmQbSow7ik7fqmzrfIqt053osLwLE2AaTqGinLM2tl6+M/uog== dependencies: "@babel/helper-create-class-features-plugin" "^7.6.0" -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" - integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.5" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "7.5.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz#ea7da440d29b8ccdb1bd02e18f6cfdc7ce6c16f5" - integrity sha512-r4zJOMbKY5puETm8+cIpaa0RQZG/sSASW1u0pj8qYklcERgVIbxVbP2wyJA7zI1//h7lEagQmXi9IL9iI5rfsA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" @@ -926,239 +608,41 @@ pirates "^4.0.0" source-map-support "^0.5.9" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== -======= -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" - integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5": -======= -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": ->>>>>>> 96db5a28... begin mike - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== -<<<<<<< HEAD -======= -======= ->>>>>>> dca19a02... very work in progress -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "7.5.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.4.tgz#cb7d1ad7c6d65676e66b47186577930465b5271b" - integrity sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: regenerator-runtime "^0.13.2" -<<<<<<< HEAD -"@babel/template@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" - integrity sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng== - dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" - lodash "^4.2.0" - "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== -======= -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" - integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== ->>>>>>> 96db5a28... begin mike dependencies: "@babel/code-frame" "^7.0.0" -<<<<<<< HEAD "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" -<<<<<<< HEAD -======= - "@babel/parser" "^7.4.4" - "@babel/types" "^7.4.4" - -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -"@babel/traverse@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" - integrity sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA== - dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/generator" "7.0.0-beta.44" - "@babel/helper-function-name" "7.0.0-beta.44" - "@babel/helper-split-export-declaration" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" - debug "^3.1.0" - globals "^11.1.0" - invariant "^2.2.0" - lodash "^4.2.0" - -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> 034f7aa3... Create Exchange related Input components ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 034f7aa3... Create Exchange related Input components -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> dca19a02... very work in progress -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" - integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== ->>>>>>> f7a61a13... Create Exchange related Input components dependencies: "@babel/code-frame" "^7.5.5" "@babel/generator" "^7.6.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" -<<<<<<< HEAD "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" -======= - "@babel/parser" "^7.5.5" - "@babel/types" "^7.5.5" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.0.tgz#4216d6586854ef5c3c4592dab56ec7eb78485485" - integrity sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.5.0" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.0" - "@babel/types" "^7.5.0" ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= -======= ->>>>>>> 2216260a... Create Exchange related Input components -"@babel/types@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" - integrity sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ== - dependencies: - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^2.0.0" - -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": version "7.6.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> 034f7aa3... Create Exchange related Input components ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 034f7aa3... Create Exchange related Input components -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> dca19a02... very work in progress -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" - integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.0.tgz#e47d43840c2e7f9105bc4d3a2c371b4d0c7832ab" - integrity sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1214,7 +698,6 @@ integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": -<<<<<<< HEAD version "5.0.0-beta.129" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.129.tgz#bc93d04d3f0e8b7d33dbe7b47a81081f02af5a0e" integrity sha512-ob+olQe+i7Gvq10nZyDa3XFGCdVc7ojG1VsfwwFdxt8/li2cv74fFueR4rjTpgKBhJuPM2bwTeHq6sGLsVxetw== @@ -1250,63 +733,14 @@ dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" -<<<<<<< HEAD "@ethersproject/keccak256@>=5.0.0-beta.127": version "5.0.0-beta.128" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.128.tgz#5635a9f386de3692e17b2fa550807a30f9da78b0" integrity sha512-dWp669s9B1+DyUSDSjxtU29+g270qQzBVAfJ0O6GbAnyuWFoyLfU4eeD/4GDGHI6g94iHXNt8yAQNE9wocB+MQ== -======= -"@ethersproject/keccak256@>5.0.0-beta.0": - version "5.0.0-beta.125" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.125.tgz#ac2bd7d20a411ebcddddcfc686ebd426960eb112" - integrity sha512-Vzood4ptHvWk64yqE5DMef7qLivEm3qH3S/60l66kWSAMmf5ISuSxeO+8Ss3o+p86zEGIhyipjpenb2LD6+/xA== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.127.tgz#2110938680d703f341bde765d6f9088f1d2e1b1b" - integrity sha512-xHENyIzB56DO98Bs8EM4x09ssSS5Iy/7ZCDDwPuXnYefMrLOCrlZYFw1+hKNz27gUVJSQMxIDK/g8J6Gs3pE6g== - dependencies: - "@ethersproject/bignumber" ">5.0.0-beta.0" - "@ethersproject/bytes" ">5.0.0-beta.0" - "@ethersproject/keccak256" ">5.0.0-beta.0" - "@ethersproject/logger" ">5.0.0-beta.0" - "@ethersproject/rlp" ">5.0.0-beta.0" - bn.js "^4.4.0" - -"@ethersproject/bignumber@>5.0.0-beta.0": - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.129.tgz#86260a2221b178e60cb082e68cb23b5a824e6515" - integrity sha512-uT8tnOWB9OwHq+17YrI/jppVOnqSNfj3WfTBXljb38Vq/oLKMlma7z8KFB4Ua3w0gtK2hawgpI+5M3uE+qxs5w== - dependencies: - "@ethersproject/bytes" ">5.0.0-beta.0" - "@ethersproject/logger" ">5.0.0-beta.0" - "@ethersproject/properties" ">5.0.0-beta.0" - bn.js "^4.4.0" - -"@ethersproject/bytes@>5.0.0-beta.0", "@ethersproject/bytes@^5.0.0-beta.126": - version "5.0.0-beta.128" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.128.tgz#86300abd80d512be7dfa286eca5953206796d594" - integrity sha512-LvH0nZ7gR7pJAiAGWa3PxmSZcBtqhU70e9mTWFJirfOpXb8QqomGDdmU3I3cz9PsPnwkv3TD/NYwFRXzlpiiNw== - dependencies: - "@ethersproject/logger" ">5.0.0-beta.0" - -"@ethersproject/constants@>5.0.0-beta.0": - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.127.tgz#2b9c0acdbf6bf2f3284632d16a6dd3ce591caca4" - integrity sha512-JNsDHD4w50Rg3kB08FStN1f7vCZ2e428MsDckF7YOQK96l2poC14wrek/GEbaUV96MxubSXmLeV7uDffp8NFew== - dependencies: - "@ethersproject/bignumber" ">5.0.0-beta.0" - -"@ethersproject/keccak256@>5.0.0-beta.0": - version "5.0.0-beta.126" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.126.tgz#19695119e16f95e6ff205dd90b35e7ac46194686" - integrity sha512-po/Yh+VakW1etttj7Ll8it9fZdoQBN2GD/6ZyHIIv5Oxh2bdNMruxKGfgsafxbuIvWZmBsQ+6FNJKO1ICdARzQ== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" js-sha3 "0.5.7" -<<<<<<< HEAD "@ethersproject/logger@>=5.0.0-beta.129": version "5.0.0-beta.130" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.130.tgz#65fb67819ef59d16fe3a45ca04d50a4f7bc3953e" @@ -1323,33 +757,10 @@ version "5.0.0-beta.127" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.127.tgz#b9b9ab962f7392ced7c5c220d3d617f5e9df5953" integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== -======= -"@ethersproject/logger@>5.0.0-beta.0": - version "5.0.0-beta.128" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.128.tgz#1cfb0447b5aa98ce177d11df3b6a76a0e8783bbf" - integrity sha512-9sPvKQRtuBmGCH+vnidQg0BvWXccB8HU2G8oOQAkbg9lAzaRwmFe9V4YwkR4raCZQtpQNdcuxYXF0O6o23XjwA== - -"@ethersproject/properties@>5.0.0-beta.0": - version "5.0.0-beta.130" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.130.tgz#597c2537396943bcd57d68a28a0127c09356cbbf" - integrity sha512-8gdIFHZR7iBEFNpHw9PK9EXhbH/f2rPrgLCULMjKrmltcbkHgalHMws/L0XcEXiR0aQdwh2/oq1GpF1qq2hPEA== - dependencies: - "@ethersproject/logger" ">5.0.0-beta.0" - -"@ethersproject/rlp@>5.0.0-beta.0": - version "5.0.0-beta.125" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.125.tgz#e203233cf1bdd7d4f1cc7aba37808be5faa831e2" - integrity sha512-Tn1HZ9+D2sV/6ekyhpYzfGXufulRuWXHrIJnOsm0TkP1cmEH73MvDWyspByN/onrXkkUM9jtBIHY8FmrwnQoOw== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "5.0.0-beta.131" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" integrity sha512-TEUr1U1XWTPGEehAitqkG7SMgVspsAtB1+ESXdniznaYaMoP/D3W3lsDuFdvIIPWlAb97ra1w2pnCKxVcMmc4A== @@ -1357,32 +768,6 @@ "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/constants" ">=5.0.0-beta.128" "@ethersproject/logger" ">=5.0.0-beta.129" -======= -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" - integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== -======= - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.127.tgz#e07848b92cb1b615a11d7289449312c069a234e9" - integrity sha512-FKQDBKgcX7Bc0J45TIwwT4PTnE1TvtDRka3dAkH1VX4odnj6DzpZ99QdkhX4mBL2J+6/XK+trA7m/HTDx+5YqA== ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -======= -======= ->>>>>>> dca19a02... very work in progress - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.129.tgz#065fe106e3c2b9460e14ea6b401861070e91c7bc" - integrity sha512-jhdHMML3mwjRfYjFqC61VvAzHCCsJwNcehho8MQoa2b5GaCYzFPA5aT+bxjjnDqTYl9ojeNHXweiGvqnCvvunQ== - dependencies: - "@ethersproject/bytes" ">5.0.0-beta.0" - "@ethersproject/constants" ">5.0.0-beta.0" - "@ethersproject/logger" ">5.0.0-beta.0" ->>>>>>> e1a27438... Cleanup ButtonPressAnimation "@hapi/address@2.x.x": version "2.1.1" @@ -1395,21 +780,9 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x": -<<<<<<< HEAD -<<<<<<< HEAD version "8.2.4" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020" integrity sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow== -======= - version "8.2.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.0.tgz#079a133be240ff866ad8532eaa46a691bdd91117" - integrity sha512-pR2ZgiP562aiaQvQ98WgfqfTrm+xG+7hwHRPEiYZ+7U1OHAAb4OVZJIalCP03bMqYSioQzflzVTVrybSwDBn1Q== ->>>>>>> 1d794746... Minor cleanup Header component -======= - version "8.2.1" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.1.tgz#924af04cbb22e17359c620d2a9c946e63f58eb77" - integrity sha512-JPiBy+oSmsq3St7XlipfN5pNA6bDJ1kpa73PrK/zR29CVClDVqy04AanM/M/qx5bSF+I61DdCfAvRrujau+zRg== ->>>>>>> dca19a02... very work in progress "@hapi/joi@^15.0.3": version "15.1.1" @@ -1616,110 +989,22 @@ resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.6.1.tgz#19be07fc1d65c77bdeb20f46108ba12076aad1c5" integrity sha512-1WA28xfdhG+unkTEk/lXnqI2izv6belo0CYw7UdvaeHm8TIYT6eTmIIdGR7oiCa2xSKEnaPQqRMH6h7gyLNbww== -"@react-native-community/blur@@react-native-community/blur": +"@react-native-community/blur@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.3.1.tgz#bc9ecd6d85d89739d8180138716535ac7cfa4680" integrity sha512-UfH2ut/l4GpZHeq/TGx3BrmyXSCSBBwBCVx1DhPodP3k959zJ2ajgXa3PiU/qjutftTUw6KH9Frsh2U0ax9dMQ== dependencies: prop-types "^15.5.10" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== -======= -"@react-native-community/cli-platform-android@^2.0.0-rc.2": -======= -======= ->>>>>>> 2216260a... Create Exchange related Input components -"@react-native-community/cli-platform-android@^2.7.0": -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 96db5a28... begin mike - version "2.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" - integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== ->>>>>>> f7a61a13... Create Exchange related Input components -======= -======= -"@react-native-community/cli-platform-android@^2.7.0": -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> a7347f4b... podfile lock for text input mask -======= -<<<<<<< HEAD ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" - integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== -<<<<<<< HEAD ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= -"@react-native-community/cli-platform-android@^2.0.0-rc.2": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.7.0.tgz#511d1db12c52d29cb87b6e4e84d63030ffa2c38d" - integrity sha512-hO/gYqzLCeCFnLIgYiGlZhiQMAnMuTxNS6rCbC8leMnlGARzrarnWsepHhvottOKeSctVh0wzchLCLCBcw4zVA== -<<<<<<< HEAD ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= -======= -"@react-native-community/cli-platform-android@^2.0.1", "@react-native-community/cli-platform-android@^2.7.0", "@react-native-community/cli-platform-android@^2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" - integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= -======= -"@react-native-community/cli-platform-android@^2.8.3": -<<<<<<< HEAD ->>>>>>> 9bae1b8d... bump deps - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" - integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== ->>>>>>> bdd78363... podfile lock for text input mask -<<<<<<< HEAD ->>>>>>> a7347f4b... podfile lock for text input mask -======= -======= - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" - integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.8.3.tgz#097237769d69400ceaf254a780d645bb8284acd6" - integrity sha512-I0/knJYmyMgp1IkrgvgirifArnarFvm+EvrRKVQjEO0aEXhOjVU2DA7TshdjocZhjq1leKm/bSxz8D3WHpRJ9g== ->>>>>>> dca19a02... very work in progress -======= - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" - integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" execa "^1.0.0" jetifier "^1.6.2" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD logkitty "^0.6.0" slash "^3.0.0" xmldoc "^1.1.2" @@ -1737,198 +1022,12 @@ version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== -======= -"@react-native-community/cli-platform-android@^2.0.0-alpha.15": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.0.2.tgz#e2e9a93d37d6dab3a8086b14e191210359cb2e45" - integrity sha512-vJ/9ev+1oL5hkgV+o8ssrDtztZc3zugUTj8JVUe8SgHp87FAcSkKYf7XsD/GyZvUzTc+UjKiQ95QQaacs3l+Mw== - dependencies: - "@react-native-community/cli-tools" "^2.0.2" - logkitty "^0.4.0" - slash "^2.0.0" - xmldoc "^0.4.0" - -"@react-native-community/cli-platform-ios@^2.0.0-alpha.15": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.0.2.tgz#ce21fa9771152a71d2b05fba434d849e32e0376a" - integrity sha512-Pwp1EOCfbpNpTXwSLQg7mGmTsCD981nkizu3S7D3QVoIwhQGpuTGXM1xyIFu9IZI2AIHNtUT9W5Nqw97/UDmdw== -======= -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.4.1.tgz#27d4c5c7be2a6a28b07cd37f10e661a5eef70b0f" - integrity sha512-M482L65Kst1LYQWDkXNTFgBDcBmUAmiF8f6SLkhsps8zmimluMUrJ/yTcBnHSK8QGuxfpW/B+QT2sT1louShmw== - dependencies: - "@react-native-community/cli-tools" "^2.4.1" - chalk "^2.4.2" ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - logkitty "^0.5.0" -======= - logkitty "^0.6.0" ->>>>>>> fabd9f7f... Update yarn.lock - slash "^3.0.0" - xmldoc "^1.1.2" - -<<<<<<< HEAD -"@react-native-community/cli-platform-ios@^2.8.0": -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "2.8.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" - integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== ->>>>>>> f7a61a13... Create Exchange related Input components - dependencies: - "@react-native-community/cli-tools" "^2.0.2" - chalk "^1.1.1" - xcode "^2.0.0" - -<<<<<<< HEAD -<<<<<<< HEAD -"@react-native-community/cli-tools@^2.0.0-alpha.14", "@react-native-community/cli-tools@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.0.2.tgz#1dc4055f27f1b2fe3d0493959a6fc20467e93fe0" - integrity sha512-6OOKrE1Sdq1Lmcdp2K68J5PsG5G80a9USa9I1Kv92wvPHUup6IRt+Dy7E8IZqxmskzC/mlOR62Oh1CB3sFm84g== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": -======= -"@react-native-community/cli-tools@^2.7.0": ->>>>>>> 96db5a28... begin mike - version "2.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" - integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== -<<<<<<< HEAD -======= - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" - integrity sha512-EKfnN+ubIcCHbCCo2a1SlYcd4jLZDT12HfoLHhFg8WXG3/zFWc/vMNpBi+omrvT7Hoktr8cTtROXPg9cIS7FCQ== - dependencies: - "@react-native-community/cli-tools" "^2.4.1" - chalk "^2.4.2" - xcode "^2.0.0" - -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.4.1.tgz#5a23b92d0b486753add00a27d77d0ea9e8c331e1" - integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= ->>>>>>> a7347f4b... podfile lock for text input mask -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" - integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== -======= -"@react-native-community/cli-platform-ios@^2.0.0-rc.2": - version "2.8.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.0.tgz#95cea3e8feab4d9525a96a9dcf56bd0d62633158" - integrity sha512-a6DD4fnfJij8FicQ/5+4zgsqxRO92o6unt2XKZexIM8bqH3i8U5pvUsccOhRnsaIjXUFMbLU5knozRrFSaJBoQ== -<<<<<<< HEAD ->>>>>>> 034f7aa3... Create Exchange related Input components -======= -======= -"@react-native-community/cli-platform-ios@^2.0.1", "@react-native-community/cli-platform-ios@^2.8.0", "@react-native-community/cli-platform-ios@^2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" - integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> a3543960... rebase cleanup -======= -======= ->>>>>>> dca19a02... very work in progress -======= -"@react-native-community/cli-platform-ios@^2.8.3": -<<<<<<< HEAD ->>>>>>> 9bae1b8d... bump deps - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.8.3.tgz#2d77bf5c6fde753d7c675fd94f656f78c0d5f741" - integrity sha512-r2+xa4trWubLRqXvotYtDIFzQpepSwo9Zsjt0JT96BUJLdXNzsUSwTFZW2EmLPmnJiZJRNdWvoXaBYVqDthdTQ== -======= - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" - integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== ->>>>>>> fabd9f7f... Update yarn.lock - dependencies: - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - xcode "^2.0.0" - -"@react-native-community/cli-tools@^2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" - integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.7.0.tgz#b468ce74cb5ebf5789731d4d330740801679cf81" - integrity sha512-9rNoGiokyMkbQ97gAvQde4mpAw2M/GhPBtrQJb4WglgVoJhfj4kpe+qMCWNsOepCrID5JY2Y1nTDEq/v+ETyNA== -<<<<<<< HEAD -======= - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.4.1.tgz#99b38c6b3feecf061ecf1243fe41013f4112a51c" - integrity sha512-EKfnN+ubIcCHbCCo2a1SlYcd4jLZDT12HfoLHhFg8WXG3/zFWc/vMNpBi+omrvT7Hoktr8cTtROXPg9cIS7FCQ== - dependencies: - "@react-native-community/cli-tools" "^2.4.1" - chalk "^2.4.2" - xcode "^2.0.0" - -"@react-native-community/cli-tools@^2.0.0-rc.2", "@react-native-community/cli-tools@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.4.1.tgz#5a23b92d0b486753add00a27d77d0ea9e8c331e1" - integrity sha512-3V5Atno3q5uBGseHcW8gM3d7Gpcr87LJvC3YbB6SwCCM7g93+94u+U1vm9j4KmHt2tnf3Q4urL4rUCrdxzvSfw== ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress dependencies: chalk "^2.4.2" lodash "^4.17.5" mime "^2.4.1" node-fetch "^2.5.0" -<<<<<<< HEAD -<<<<<<< HEAD "@react-native-community/cli@2.9.0", "@react-native-community/cli@^2.6.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" @@ -1938,28 +1037,6 @@ "@react-native-community/cli-platform-android" "^2.9.0" "@react-native-community/cli-platform-ios" "^2.9.0" "@react-native-community/cli-tools" "^2.8.3" -======= -"@react-native-community/cli@2.8.0": - version "2.8.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.0.tgz#346ff73ace6b2265d99ec217a8624b8735d19930" - integrity sha512-sN43IyvBtFtC1iOjx3pfKeo7DK4wkJxWiggR3QkkNQdyjuGT3RGXiYZVPu+zda6BPKdeGYpS+7UJrkGT+1tuFg== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.7.0" - "@react-native-community/cli-platform-ios" "^2.8.0" - "@react-native-community/cli-tools" "^2.7.0" ->>>>>>> 96db5a28... begin mike -======= -"@react-native-community/cli@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.8.3.tgz#b59c4e44946a1ce6c464ae246328cf3a2ab47bd2" - integrity sha512-khlS6slD6fsIv8R6L0bbQvK2PQ/UJytmh8/XEZ835bDwgbn6U90Yqrf299r6JxKk2/tyckRu6QimQNAkEQxEHg== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.8.3" - "@react-native-community/cli-platform-ios" "^2.8.3" - "@react-native-community/cli-tools" "^2.8.3" ->>>>>>> 9bae1b8d... bump deps chalk "^2.4.2" commander "^2.19.0" compression "^1.7.1" @@ -1990,63 +1067,10 @@ shell-quote "1.6.1" ws "^1.1.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@react-native-community/eslint-config@^0.0.5": version "0.0.5" resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795" integrity sha512-jwO2tnKaTPTLX5XYXMHGEnFdf543SU7jz98/OF5mDH3b7lP+BOaCD+jVfqqHoDRkcqyPlYiR1CgwVGWpi0vMWg== -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> a7347f4b... podfile lock for text input mask -"@react-native-community/cli@^1.2.1": - version "1.9.11" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.9.11.tgz#b868b17201057b9cd16a3a20c30561176071f21a" - integrity sha512-VVu/tmTTzODfW2xlqIz0pZgeELG2ppPAIgbBEKLgHCO9DMxNZIKSqmei/JqkAi0gEipqQoP6YPAemHPd43lyrA== - dependencies: - chalk "^1.1.1" - commander "^2.19.0" - compression "^1.7.1" - connect "^3.6.5" - denodeify "^1.2.1" - envinfo "^5.7.0" - errorhandler "^1.5.0" - escape-string-regexp "^1.0.5" - execa "^1.0.0" - fs-extra "^7.0.1" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.51.0" - metro-config "^0.51.0" - metro-core "^0.51.0" - metro-memory-fs "^0.51.0" - metro-react-native-babel-transformer "^0.51.0" - mime "^1.3.4" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-fetch "^2.2.0" - node-notifier "^5.2.1" - opn "^3.0.2" - plist "^3.0.0" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" - slash "^2.0.0" - ws "^1.1.0" - xcode "^2.0.0" - xmldoc "^0.4.0" - -"@react-native-community/eslint-config@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.3.tgz#bf9be8434caa18f85b570cf4e28366f2a7f1ea91" - integrity sha512-YmCiqoiqgSW8YpWYWLwG4WYwVIwvkhfH97COxbin71CuCr5muZPlmhHOFwo2gIQzUvt1ewFb1shtUi1X8TAVhA== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: "@typescript-eslint/eslint-plugin" "^1.5.0" "@typescript-eslint/parser" "^1.5.0" @@ -2066,31 +1090,24 @@ integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== "@react-native-community/netinfo@^4.1.4": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.5.tgz#4bb44842db6a1a18f00a0f061b0e3dcc638f67dd" - integrity sha512-lagdZr9UiVAccNXYfTEj+aUcPCx9ykbMe9puffeIyF3JsRuMmlu3BjHYx1klUHX7wNRmFNC8qVP0puxUt1sZ0A== + version "4.2.1" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" + integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== "@react-navigation/core@~3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.0.tgz#73d1a12448e2bd71855e0080b95a7f51ede0cd9e" - integrity sha512-NLm24lA51R8o8c+iFnwtN9elqRzm4OJ8f1qPBCUNIYW1sb8M5yCD53vRP0fRcPFpr/6Xzs2TJMsWnnebwFp0Rw== + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.1.tgz#7a2339fca3496979305fb3a8ab88c2ca8d8c214d" + integrity sha512-q7NyhWVYOhVIWqL2GZKa6G78YarXaVTTtOlSDkvy4ZIggo40wZzamlnrJRvsaQX46gsgw45FAWb5SriHh8o7eA== dependencies: hoist-non-react-statics "^3.3.0" path-to-regexp "^1.7.0" query-string "^6.4.2" react-is "^16.8.6" -<<<<<<< HEAD "@react-navigation/native@~3.6.1": version "3.6.2" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== -======= -"@react-navigation/native@~3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.0.tgz#dabf93382f75037c01dfdd2a03807e40b48a4d61" - integrity sha512-MmsEF4Gf3DD7rtZlbOLULQOBCxE2nGz6FdPYxtlEI+N/E2I5OrdxrTNAA7EGWsIiaJEapU4bp0a+tLjh/9PQpA== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -2169,7 +1186,6 @@ "@svgr/babel-plugin-transform-svg-component" "^4.2.0" "@svgr/cli@^4.3.0": -<<<<<<< HEAD version "4.3.2" resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.2.tgz#fb20fd33429f0d0dfc6c7178e8bfc1e86006e9de" integrity sha512-QdYzVgsowOWpOwkX+3+EK6zxlttADc2v6t0Baj2xETAdhBcpFAf/nZ0xw6b5zxdbGk8fm3nxJyPUddYuBkgzpg== @@ -2177,15 +1193,6 @@ "@svgr/core" "^4.3.2" "@svgr/plugin-jsx" "^4.3.2" "@svgr/plugin-prettier" "^4.3.2" -======= - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.1.tgz#ee4da73b866c81d3fca4ea642df1279924d0cf77" - integrity sha512-et42q/arMztdgzwqVm3IEu1b/sDDOvqYgu3DHZ8wOBkn34XwPbIYfhHfWSYxyqAOBa3zarOPmJJsfv7+gIugAw== - dependencies: - "@svgr/core" "^4.3.1" - "@svgr/plugin-jsx" "^4.3.1" - "@svgr/plugin-prettier" "^4.3.1" ->>>>>>> 751dba29... Replace navigation animations with new effects "@svgr/plugin-svgo" "^4.3.1" camelcase "^5.3.1" chalk "^2.4.2" @@ -2195,7 +1202,6 @@ output-file-sync "^2.0.1" recursive-readdir "^2.2.2" -<<<<<<< HEAD "@svgr/core@^4.3.2": version "4.3.2" resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.2.tgz#939c89be670ad79b762f4c063f213f0e02535f2e" @@ -2226,40 +1232,6 @@ version "4.3.2" resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-4.3.2.tgz#41a95cf0c52a58e2d9841434d227e120d7d533f7" integrity sha512-GErOZQ0n/OinFDjyXg9svfVRNWP+18qqIxsc/9xRoRY7R/cPlnXkadLF7NdgDgSP2BYtt7XGcZ9TU+Skr1B3tw== -======= -"@svgr/core@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.1.tgz#58c44d0ccc3fe41718c50433758b549dabd4d197" - integrity sha512-TXFcvzp6QjxKP5Oy7qoQY08w/nAix9TMOc4jSi3wjIJBBMUqypVwQJFMxtHrViGMQGmFdaN1y2diQrhvA+xNNQ== - dependencies: - "@svgr/plugin-jsx" "^4.3.1" - camelcase "^5.3.1" - cosmiconfig "^5.2.1" - -"@svgr/hast-util-to-babel-ast@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.1.tgz#b3ea5b2228b50ff335a5d3cf3855f4b1f9fbc70e" - integrity sha512-MZbRccEpsro70mE6mhiv5QUXjBwHGDQZ7XrVcrDs44inaNvYUtIcheX0d9eColcnNgJmsfU3tEFfoGRnJ9E5pA== - dependencies: - "@babel/types" "^7.4.4" - -"@svgr/plugin-jsx@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.1.tgz#5b7f849213d1411886e1cec9b6c287faec69143e" - integrity sha512-v9sgsn/VpDM9G1U0ZDCair7ZmYqNrVC5LiSyIQli03DAm34bYLM12xVOOrl3dg8NGNY1k4C3A6YgBL3VKjA6Og== - dependencies: - "@babel/core" "^7.4.5" - "@svgr/babel-preset" "^4.3.1" - "@svgr/hast-util-to-babel-ast" "^4.3.1" - rehype-parse "^6.0.0" - unified "^7.1.0" - vfile "^4.0.1" - -"@svgr/plugin-prettier@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-4.3.1.tgz#b50347ec95a0163091ecbbc305991e727076c7d8" - integrity sha512-RTTZniRGtUQw+BufJk1sLKbeglZlHXCoJeE/op+hhrVLI3UZSbtliaQbyV6Rm5tZOed+08miuSWTLa6x3Tf10w== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: merge-deep "^3.0.2" prettier "^1.17.1" @@ -2364,151 +1336,19 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch - version "12.6.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" - integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== ->>>>>>> f7a61a13... Create Exchange related Input components "@types/node@^10.3.2": version "10.14.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== -======= - version "12.6.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" - integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== -======= - version "12.7.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.0.tgz#545dde2a1a5c27d281cfb8308d6736e0708f5d6c" - integrity sha512-vqcj1MVm2Sla4PpMfYKh1MyDN4D2f/mPIZD7RdAGqEsbE+JxfeqQHHVbRDQ0Nqn8i73gJa1HQ1Pu3+nH4Q0Yiw== ->>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views - -"@types/node@^10.3.2": - version "10.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" - integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress - version "12.7.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.1.tgz#3b5c3a26393c19b400844ac422bd0f631a94d69d" - integrity sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw== -======= - version "12.7.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" - integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== ->>>>>>> 9bae1b8d... bump deps - -"@types/node@^10.3.2": -<<<<<<< HEAD - version "10.14.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" - integrity sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g== -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= - version "12.6.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" - integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== - -"@types/node@^10.3.2": - version "10.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" - integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - version "12.6.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" - integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== - -"@types/node@^10.3.2": - version "10.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" - integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress "@types/node@^8.0.7": -<<<<<<< HEAD version "8.10.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== -======= - version "8.10.51" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.51.tgz#80600857c0a47a8e8bafc2dae6daed6db58e3627" - integrity sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "12.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" - integrity sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ== - -"@types/node@^10.3.2": - version "10.14.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f" - integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg== - -"@types/node@^8.0.7": - version "8.10.50" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.50.tgz#f3d68482b1f54b5f4fba8daaac385db12bb6a706" - integrity sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= - version "10.14.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.16.tgz#4d690c96cbb7b2728afea0e260d680501b3da5cf" - integrity sha512-/opXIbfn0P+VLt+N8DE4l8Mn8rbhiJgabU96ZJ0p9mxOkIks5gh6RUnpHak7Yh0SFkyjO/ODbxsQQPV2bpMmyA== - -"@types/node@^8.0.7": - version "8.10.52" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.52.tgz#ef0ca1809994e20186090408b8cb7f2a6877d5f9" - integrity sha512-2RbW7WXeLex6RI+kQSxq6Ym0GiVcODeQ4Km7MnnTX5BHdOGQnqVa+s6AUmAW+OFYAJ8wv9QxvNZXm7/kBdGTVw== ->>>>>>> fabd9f7f... Update yarn.lock "@types/q@^1.5.1": version "1.5.2" @@ -2543,15 +1383,9 @@ "@types/vfile-message" "*" "@types/yargs-parser@*": -<<<<<<< HEAD version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== -======= - version "13.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" - integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== ->>>>>>> fabd9f7f... Update yarn.lock "@types/yargs@^13.0.0": version "13.0.2" @@ -2598,54 +1432,6 @@ lodash.unescape "4.0.1" semver "5.5.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -"@walletconnect/core@^1.0.0-beta.35": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" - integrity sha512-VnS4exaqaNJQy6xc+HX+1psjmIjKimCir9xypbx4kMz1F8Tm8/m1bMv3h4c1Q7wyiZHsSTlMZmb64UuVhM2pqw== - dependencies: - "@walletconnect/types" "^1.0.0-beta.35" - "@walletconnect/utils" "^1.0.0-beta.35" - -"@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.35.tgz#318d1d067cae5261755b502a3a5b27dd23c6a815" - integrity sha512-npRV1XicayiSMk84+he5JEASC5oFHkYsL2S9yuHfCVzctIGE6kIX0gpuBKUbzCxkve1yezIeaQOYfwVKlLRp5w== - dependencies: - "@walletconnect/core" "^1.0.0-beta.35" - "@walletconnect/types" "^1.0.0-beta.35" - "@walletconnect/utils" "^1.0.0-beta.35" - -"@walletconnect/types@^1.0.0-beta.35": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.35.tgz#02577da82a85361c68518350fe6139dee4a43445" - integrity sha512-xlcSt0ZdEkiYmCpuO6cleLk1MmjyMPCCT5o1/z0zcRV15uDxfb+N9J/S2uVZBoLtnBtUK1m+11sRF3KrIo9FgQ== - -"@walletconnect/utils@^1.0.0-beta.35": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" - integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== -======= -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= -<<<<<<< HEAD -"@walletconnect/core@^1.0.0-beta.31": - version "1.0.0-beta.31" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.31.tgz#ce9257c13a0da7a52a61829b66c45a9686cedca9" - integrity sha512-EggZFGdQ0EMjWZrtqAn6PJslLDlc5suyPBWfp4PP0247tYorcXXz/7OSiek0XWBVQ7dakCqeJAOteuc/FaQ+hw== -======= -======= ->>>>>>> a3543960... rebase cleanup -======= ->>>>>>> dca19a02... very work in progress "@uniswap/sdk@^1.0.0-beta.3": version "1.0.0-beta.4" resolved "https://registry.yarnpkg.com/@uniswap/sdk/-/sdk-1.0.0-beta.4.tgz#d14a0ddc15e8de9173f3d97075e7ebbaa2570f1a" @@ -2655,70 +1441,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> a1921ad8... further sdk hookup -<<<<<<< HEAD ->>>>>>> 9a1e3741... further sdk hookup -======= -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress -"@walletconnect/core@^1.0.0-beta.32": - version "1.0.0-beta.32" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.32.tgz#e8125a877ab809bd2d74c7c03a07ad70401f9c34" - integrity sha512-CvDQ+vupPbEvrGFwZOwTANeT1bz+c6TSkkOxo5lXz+DotxbZpQqL3tsFuaenTuVL7AqvNH2RARgA5Ez2HSjNaA== -======= -"@walletconnect/core@^1.0.0-beta.33": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.33.tgz#ba8c4d1682c00630124cfacd8c3ac28a37737ffc" - integrity sha512-VnipTAEiVJx0fKR7kVKQ/KIaEDCFjIEF4wGSl73uuhp+YPBZSN0fXQ0/joF00dGUxVY6RiwmCQlmz5ZKpcGWYw== ->>>>>>> fabd9f7f... Update yarn.lock - dependencies: - "@walletconnect/types" "^1.0.0-beta.33" - "@walletconnect/utils" "^1.0.0-beta.33" +"@walletconnect/core@^1.0.0-beta.36": + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.36.tgz#671f70f739d1d9857456e45060727548317fe86a" + integrity sha512-/Xp4d2kEIcf4mglIypbZGq5qCLIshIkIUmyI7BT0n/OWq3Hw4GFlH2brycN3OUlbDiqjar0HqfoqO60wAbtUJw== + dependencies: + "@walletconnect/types" "^1.0.0-beta.36" + "@walletconnect/utils" "^1.0.0-beta.36" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.33.tgz#21542022f8204648e924a40c6f79c93bde109f5a" - integrity sha512-AFGiXFZXQ1HINGiQESRciMlu7R6s0e2s7LeC5g+EdQrtDDqSsEx9W6Lb8VMPQPnPREmcmcaz4B9L/wyUjNXXew== - dependencies: - "@walletconnect/core" "^1.0.0-beta.33" - "@walletconnect/types" "^1.0.0-beta.33" - "@walletconnect/utils" "^1.0.0-beta.33" - -"@walletconnect/types@^1.0.0-beta.33": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.33.tgz#2c95191e0a2986b24e4f66baeeeaa79f87dc52f4" - integrity sha512-RGC5F4Qb9IApPaOIZwiQVzT4b6K+vmgh0mi/7qHICzSylMJ9BZmvdDOn61+jgSBCjzQ/lmJROsQeXAABCU08rw== - -<<<<<<< HEAD -"@walletconnect/utils@^1.0.0-beta.32": - version "1.0.0-beta.32" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.32.tgz#f87841eaf60d62441b26e78603aafbd9b7bc7f2e" - integrity sha512-ShnWCVPFv2fZcIKInNDhROCu/gEUD2+vjbBUCPTRB1M+ERTK8fyrMgl2vId8NOSTR/Sd3Ie4+hCbUluLZYvrGQ== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -"@walletconnect/utils@^1.0.0-beta.33": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.33.tgz#59ff7edc74608398a341264bad781f24b4cf599f" - integrity sha512-BAKV+tVoN5QGoMDzF/JleO0s80wLoeJFAsw8/IG9QCSnHi4swZsin0Zk2TRYVb+gC/ZuDmMvwMHVkmVUqz7fOg== ->>>>>>> fabd9f7f... Update yarn.lock + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.36.tgz#64e34c4bd64446de224e39ea7b4a3029c0562466" + integrity sha512-Xj6OGj09HYYfx6N4EN8AssyfXSCGowb4pEo+iSLf8P3ylGVNH10HDkKBa3czGjhHWQc0nfeapmN4bM6V+GCdng== + dependencies: + "@walletconnect/core" "^1.0.0-beta.36" + "@walletconnect/types" "^1.0.0-beta.36" + "@walletconnect/utils" "^1.0.0-beta.36" + +"@walletconnect/types@^1.0.0-beta.36": + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.36.tgz#43985f3e1d5c994f1f264eb5ef5eb9661a285975" + integrity sha512-QcKGR68KlcN78HYF98RaQnTOgeqB2Vo//0ye9dyJCCmB4ziaxQyvXI7zkrtAl/FNjYPggo+7MGYszel1ggPQxQ== + +"@walletconnect/utils@^1.0.0-beta.36": + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.36.tgz#34c9def70f9db1ffcdd8e5fc94d9ce30dc716b8a" + integrity sha512-SlAqiWJLs/EG+eqxqWO/zOZRz06GYBKGlfK5OX203UjOl6Ps8WLN/D7l8llX97TdGzcGw5+b9Wq+kKuWR2HFQA== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" -<<<<<<< HEAD -<<<<<<< HEAD - "@walletconnect/types" "^1.0.0-beta.35" -======= - "@walletconnect/types" "^1.0.0-beta.32" ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - "@walletconnect/types" "^1.0.0-beta.33" ->>>>>>> fabd9f7f... Update yarn.lock + "@walletconnect/types" "^1.0.0-beta.36" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -2781,24 +1534,14 @@ accepts@~1.3.5, accepts@~1.3.7: negotiator "0.6.2" acorn-globals@^4.1.0: -<<<<<<< HEAD version "4.3.4" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== -======= - version "4.3.3" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.3.tgz#a86f75b69680b8780d30edd21eee4e0ea170c05e" - integrity sha512-vkR40VwS2SYO98AIeFvzWWh+xyc2qi9s7OoXSFEGIP/rOJKzjnhykaZJNnHdoq4BL2gGxI5EZOU16z896EYnOQ== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" -<<<<<<< HEAD -acorn-jsx@^5.0.0: -======= acorn-jsx@^5.0.2: ->>>>>>> fabd9f7f... Update yarn.lock version "5.0.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== @@ -2813,50 +1556,10 @@ acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -<<<<<<< HEAD -acorn@^6.0.1, acorn@^6.0.7: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "6.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" - integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== -======= -<<<<<<< HEAD -======= ->>>>>>> 2216260a... Create Exchange related Input components - version "6.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" - integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== -======= - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" - integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= - version "6.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" - integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= - version "6.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" - integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= acorn@^6.0.1: ->>>>>>> fabd9f7f... Update yarn.lock version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== ->>>>>>> dca19a02... very work in progress acorn@^7.0.0: version "7.0.0" @@ -3336,53 +2039,7 @@ babel-plugin-rewire@^1.2.0: resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89" integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: -======= -<<<<<<< HEAD -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.0: ->>>>>>> 751dba29... Replace navigation animations with new effects -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.2: -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> d743296d... BREAK UP -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ->>>>>>> 96db5a28... begin mike -======= -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.2: -======= "babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> d743296d... BREAK UP -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -"babel-plugin-styled-components@>= 1", babel-plugin-styled-components@^1.10.6: ->>>>>>> dca19a02... very work in progress version "1.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz#f8782953751115faf09a9f92431436912c34006b" integrity sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA== @@ -3721,10 +2378,6 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.6.3: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "4.7.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA== @@ -3732,22 +2385,6 @@ browserslist@^4.6.3: caniuse-lite "^1.0.30000989" electron-to-chromium "^1.3.247" node-releases "^1.1.29" -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== - dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" ->>>>>>> f7a61a13... Create Exchange related Input components bser@^2.0.0: version "2.1.0" @@ -3786,21 +2423,9 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: -<<<<<<< HEAD -<<<<<<< HEAD version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== -======= - version "5.3.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.3.0.tgz#5f9fa5fefe3939888d0fdbf7d964e2a8531fd69c" - integrity sha512-XykNc84nIOC32vZ9euOKbmGAP69JUkXDtBQfLq88c8/6J/gZi/t14A+l/p/9EM2TcT5xNC1MKPCrvO3LVUpVPw== ->>>>>>> dca19a02... very work in progress -======= - version "5.4.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.0.tgz#33294f5c1f26e08461e528b69fa06de3c45cbd8c" - integrity sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g== ->>>>>>> 9bae1b8d... bump deps dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -3906,125 +2531,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== -======= -can-promise@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/can-promise/-/can-promise-0.0.1.tgz#7a7597ad801fb14c8b22341dfec314b6bd6ad8d3" - integrity sha512-gzVrHyyrvgt0YpDm7pn04MQt8gjh0ZAhN4ZDyCRtGl6YnuuK6b4aiUTD7G52r9l4YNmxfTtEscb92vxtAlL6XQ== - dependencies: - window-or-global "^1.0.1" - -caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: - version "1.0.30000979" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz#92f16d00186a6cf20d6c5711bb6e042a3d667029" - integrity sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw== -======= -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "1.0.30000987" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" - integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== -======= - version "1.0.30000985" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f" - integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w== -======= -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: - version "1.0.30000983" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" - integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= -======= - version "1.0.30000987" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" - integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== -<<<<<<< HEAD -======= - version "1.0.30000985" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f" - integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w== -======= -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: - version "1.0.30000983" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" - integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= - version "1.0.30000987" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" - integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "1.0.30000988" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000988.tgz#742f35ec1b8b75b9628d705d7652eea1fef983db" - integrity sha512-lPj3T8poYrRc/bniW5SQPND3GRtSrQdUM/R4mCYTbZxyi3jQiggLvZH4+BYUuX0t4TXjU+vMM7KFDQg+rSzZUQ== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress - -capture-exit@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" - integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= - dependencies: - rsvp "^3.3.3" ->>>>>>> 751dba29... Replace navigation animations with new effects capture-exit@^2.0.0: version "2.0.0" @@ -4048,7 +2558,7 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1: +chalk@1.1.3, chalk@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -4324,22 +2834,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: -======= -commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: ->>>>>>> 96db5a28... begin mike -======= -commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: -======= -commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> 64f1594b... rebase cleanup -======= -commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0: ->>>>>>> a7347f4b... podfile lock for text input mask version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -4409,7 +2904,6 @@ concat-stream@^1.4.4, concat-stream@^1.4.7, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -<<<<<<< HEAD configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" @@ -4426,15 +2920,6 @@ confusing-browser-globals@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz#93ffec1f82a6e2bf2bc36769cc3a92fa20e502f3" integrity sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg== -<<<<<<< HEAD -======= -confusing-browser-globals@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.7.tgz#5ae852bd541a910e7ffb2dbb864a2d21a36ad29b" - integrity sha512-cgHI1azax5ATrZ8rJ+ODDML9Fvu67PimB6aNxBrc/QwSaDaM9eTfIEUHx3bBLJJ82ioSb+/5zfsMCCEJax3ByQ== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= ->>>>>>> 1d794746... Minor cleanup Header component connect@^3.6.5: version "3.7.0" @@ -4495,24 +2980,12 @@ core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -<<<<<<< HEAD -======= -core-js@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09" - integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw== - ->>>>>>> 1d794746... Minor cleanup Header component core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -<<<<<<< HEAD cosmiconfig@^5.0.5, cosmiconfig@^5.1.0, cosmiconfig@^5.2.0, cosmiconfig@^5.2.1: -======= -cosmiconfig@^5.0.0, cosmiconfig@^5.0.5, cosmiconfig@^5.1.0, cosmiconfig@^5.2.1: ->>>>>>> 751dba29... Replace navigation animations with new effects version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== @@ -4668,19 +3141,8 @@ cssstyle@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== -======= -"cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" - integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== - -cssstyle@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.3.0.tgz#c36c466f7037fd30f03baa271b65f0f17b50585c" - integrity sha512-wXsoRfsRfsLVNaVzoKdqvEmK/5PFaEXNspVT22Ots6K/cnJdpoDKuQFw+qlMiXnmaif1OgeC466X1zISgAOcGg== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: - cssom "~0.3.6" + cssom "0.3.x" currently-unhandled@^0.4.1: version "0.4.1" @@ -4733,15 +3195,9 @@ date-now@^0.1.4: integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= dayjs@^1.8.15: -<<<<<<< HEAD version "1.8.16" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== -======= - version "1.8.15" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.15.tgz#7121bc04e6a7f2621ed6db566be4a8aaf8c3913e" - integrity sha512-HYHCI1nohG52B45vCQg8Re3hNDZbMroWPkhz50yaX7Lu0ATyjGsTdoYZBpjED9ar6chqTx2dmSmM8A51mojnAg== ->>>>>>> fabd9f7f... Update yarn.lock debounce@^1.2.0: version "1.2.0" @@ -5092,214 +3548,15 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -electron-to-chromium@^1.3.247: - version "1.3.258" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.258.tgz#829b03be37424099b91aefb6815e8801bf30b509" - integrity sha512-rkPYrgFU7k/8ngjHYvzOZ44OQQ1GeIRIQnhGv00RkSlQXEnJKsGonQppbEEWHuuxZegpMao+WZmYraWQJQJMMg== -======= -electron-to-chromium@^1.3.164: - version "1.3.182" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.182.tgz#1711122c0c035f1568aea0d1b6b93c04b5f9fdf2" - integrity sha512-uqKh3J1/s4LkmtbrVi2cPpd5g2u7efYJdnRXApQLVhZlLjzaJZakafp+JFSUZNYrBDJNIqQChcJTCDZXqQOBYg== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress ejs@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.2.tgz#3a32c63d1cd16d11266cd4703b14fec4e74ab4f6" - integrity sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q== - -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -electron-to-chromium@^1.3.191: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "1.3.205" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" - integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== -======= -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD - version "1.3.200" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" - integrity sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg== -======= - version "1.3.199" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.199.tgz#f9a62a74cda77854310a2abffde8b75591ea09a1" - integrity sha512-gachlDdHSK47s0N2e58GH9HMC6Z4ip0SfmYUa5iEbE50AKaOUXysaJnXMfKj0xB245jWbYcyFSH+th3rqsF8hA== -======= -electron-to-chromium@^1.3.188: -<<<<<<< HEAD - version "1.3.188" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.188.tgz#e28e1afe4bb229989e280bfd3b395c7ec03c8b7a" - integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ== ->>>>>>> 8d2e8d2f... BREAK UP -<<<<<<< HEAD ->>>>>>> d743296d... BREAK UP -<<<<<<< HEAD ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= -======= -======= -======= - version "1.3.190" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz#5bf599519983bfffd9d4387817039a3ed7ca085f" - integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== ->>>>>>> 9a56f78d... WIP swap ui polish ->>>>>>> 2db58de2... WIP swap ui polish -<<<<<<< HEAD ->>>>>>> 30cb3e0d... WIP swap ui polish -<<<<<<< HEAD ->>>>>>> 397368cb... WIP swap ui polish -======= -======= -======= - version "1.3.205" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" - integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "1.3.205" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" - integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== ->>>>>>> dc42f3f4... begin mike -<<<<<<< HEAD ->>>>>>> 96db5a28... begin mike -======= -======= - version "1.3.215" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.215.tgz#c833cb31110c2e0a7dade1110648c2174f75233b" - integrity sha512-ZV3OnwF0FlIygwxAG2H92yt7WGjWBpawyFAFu8e9k7xJatY+BPowID0D0Bs3PMACYAJATEejw/I9cawO27ZvTg== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation -<<<<<<< HEAD ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= - version "1.3.218" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.218.tgz#8a873456e6640da1bed18a8718da1b1a3c4f604c" - integrity sha512-+ABuwQH2bEUbJTMPUMfP9mjBFtbLgDjlrkg3QGQZwr/RJB7aJZBm8g3SK/lR/J76P6l/4a6RgW2yQjZQDdjtFw== ->>>>>>> 55f47d2b... Begin orchestrating keyboard focus between swap modal views ->>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views -======= -======= -<<<<<<< HEAD -electron-to-chromium@^1.3.191: ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - version "1.3.221" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.221.tgz#421a58ac8d1931c8df400d55c7f6fd621710da10" - integrity sha512-YbNA7KgCvLq9ZaEa7wpYP7IP4LrJ4+b36oeF1lYBSJ0zVGVN7uo3Ct9qDUm/M3VDOWj03RVgsMFF8PdL8UjhzA== -<<<<<<< HEAD ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= -<<<<<<< HEAD -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -electron-to-chromium@^1.3.191: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "1.3.200" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f" - integrity sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg== -======= - version "1.3.199" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.199.tgz#f9a62a74cda77854310a2abffde8b75591ea09a1" - integrity sha512-gachlDdHSK47s0N2e58GH9HMC6Z4ip0SfmYUa5iEbE50AKaOUXysaJnXMfKj0xB245jWbYcyFSH+th3rqsF8hA== -======= -electron-to-chromium@^1.3.188: - version "1.3.188" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.188.tgz#e28e1afe4bb229989e280bfd3b395c7ec03c8b7a" - integrity sha512-tEQcughYIMj8WDMc59EGEtNxdGgwal/oLLTDw+NEqJRJwGflQvH3aiyiexrWeZOETP4/ko78PVr6gwNhdozvuQ== ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> d743296d... BREAK UP -<<<<<<< HEAD ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= -======= -======= - version "1.3.190" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz#5bf599519983bfffd9d4387817039a3ed7ca085f" - integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== ->>>>>>> 9a56f78d... WIP swap ui polish ->>>>>>> 2db58de2... WIP swap ui polish -======= - version "1.3.205" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" - integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "1.3.214" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.214.tgz#8b5b9a0415fd41b69c61f694007597cb8c8eb7e8" - integrity sha512-SU9yyql6uA0Fc8bWR7sCYNGBtxkC+tQb6UaC7ReaadN42Kx7Ka+dzx3lAIm9Ock+ULEawJuTFcVB2x34uOCg0Q== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= -electron-to-chromium@^1.3.191: - version "1.3.215" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.215.tgz#c833cb31110c2e0a7dade1110648c2174f75233b" - integrity sha512-ZV3OnwF0FlIygwxAG2H92yt7WGjWBpawyFAFu8e9k7xJatY+BPowID0D0Bs3PMACYAJATEejw/I9cawO27ZvTg== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= -electron-to-chromium@^1.3.191: -<<<<<<< HEAD - version "1.3.225" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.225.tgz#c6786475b5eb5f491ade01a78b82ba2c5bfdf72b" - integrity sha512-7W/L3jw7HYE+tUPbcVOGBmnSrlUmyZ/Uyg24QS7Vx0a9KodtNrN0r0Q/LyGHrcYMtw2rv7E49F/vTXwlV/fuaA== ->>>>>>> dca19a02... very work in progress -======= - version "1.3.228" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.228.tgz#8b1804bae329e2029ad6b25fbb15d9200fb12894" - integrity sha512-m3k/OYd9sCLFOAtvl6vqgXfzbG8iY1mLYg0fQjQGB46LpPudYDUFUmiSmj2meJsHEUABWXH1ZRSCeWj265v2RQ== ->>>>>>> 9bae1b8d... bump deps -======= - version "1.3.241" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.241.tgz#859dc49ab7f90773ed698767372d384190f60cb1" - integrity sha512-Gb9E6nWZlbgjDDNe5cAvMJixtn79krNJ70EDpq/M10lkGo7PGtBUe7Y0CYVHsBScRwi6ybCS+YetXAN9ysAHDg== ->>>>>>> fabd9f7f... Update yarn.lock + version "2.7.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" + integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== + +electron-to-chromium@^1.3.247: + version "1.3.259" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.259.tgz#d0b14836df3c89e86fa47be67315daa642fe9d5c" + integrity sha512-NMHS8iQzAYwiFZ1jL/rNOfrZJhvoowKN5uHrbbHOeNgBT5W762wpe/SRLo9kJoTiJ4d2R8i01/NQHwndo9N5PQ== elliptic@6.3.3: version "6.3.3" @@ -5312,15 +3569,9 @@ elliptic@6.3.3: inherits "^2.0.1" elliptic@^6.0.0: -<<<<<<< HEAD version "6.5.1" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b" integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg== -======= - version "6.5.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca" - integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -5392,48 +3643,10 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== -<<<<<<< HEAD -======= - -======= -<<<<<<< HEAD ->>>>>>> a3543960... rebase cleanup -envinfo@^5.7.0: - version "5.12.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" - integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== -<<<<<<< HEAD ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= -======= ->>>>>>> bdd78363... podfile lock for text input mask -======= ->>>>>>> b1697d93... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress -entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== -<<<<<<< HEAD ->>>>>>> 3291cb84... rebase cleanup ->>>>>>> 64f1594b... rebase cleanup -======= - -envinfo@^5.7.0: - version "5.12.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" - integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== ->>>>>>> a7347f4b... podfile lock for text input mask envinfo@^7.1.0: version "7.3.1" @@ -5577,20 +3790,10 @@ eslint-plugin-import@2.14.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -<<<<<<< HEAD -eslint-plugin-import@^2.14.0: -<<<<<<< HEAD -======= eslint-plugin-import@^2.18.2: ->>>>>>> 96db5a28... begin mike version "2.18.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== -======= - version "2.18.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz#7a5ba8d32622fb35eb9c8db195c2090bd18a3678" - integrity sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: array-includes "^3.0.3" contains-path "^0.1.0" @@ -5618,21 +3821,9 @@ eslint-plugin-prettier@2.6.2: jest-docblock "^21.0.0" eslint-plugin-react-hooks@^1.5.1: -<<<<<<< HEAD -<<<<<<< HEAD - version "1.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" - integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== -======= - version "1.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz#3c66a5515ea3e0a221ffc5d4e75c971c217b1a4c" - integrity sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= version "1.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== ->>>>>>> 1d794746... Minor cleanup Header component eslint-plugin-react-native-animation-linter@^0.1.2: version "0.1.2" @@ -5671,21 +3862,10 @@ eslint-plugin-react@7.12.4: prop-types "^15.6.2" resolve "^1.9.0" -<<<<<<< HEAD -<<<<<<< HEAD -eslint-plugin-react@^7.13.0: -======= eslint-plugin-react@^7.14.3: ->>>>>>> 96db5a28... begin mike version "7.14.3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== -======= -eslint-plugin-react@^7.12.1: - version "7.14.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz#94c193cc77a899ac0ecbb2766fbef88685b7ecc1" - integrity sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: array-includes "^3.0.3" doctrine "^2.1.0" @@ -5721,11 +3901,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -<<<<<<< HEAD -eslint-utils@^1.3.1: -======= eslint-utils@^1.3.1, eslint-utils@^1.4.2: ->>>>>>> fabd9f7f... Update yarn.lock version "1.4.2" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== @@ -5738,9 +3914,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.1.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" - integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== + version "6.4.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" + integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -5833,30 +4009,10 @@ eth-contract-metadata@^1.9.2: resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== -<<<<<<< HEAD -<<<<<<< HEAD -ethers@^4.0.33: +ethers@^4.0.28, ethers@^4.0.33: version "4.0.37" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== -======= -ethers@^4.0.27: - version "4.0.32" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.32.tgz#46378864cb3bf29b57c2effd17508b560743abf6" - integrity sha512-r0k2tBNF6MYEsvwmINeP3VPppD/7eAZyiOk/ifDDawXGCKqr3iEQkPq6OZSDVD+4Jie38WPteS9thXzpn2+A5Q== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= -ethers@^4.0.28, ethers@^4.0.33: -<<<<<<< HEAD - version "4.0.33" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" - integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== ->>>>>>> 9a1e3741... further sdk hookup -======= - version "4.0.36" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.36.tgz#96519fd3cc9317f938c8ee4d22050f34e3c2ef0e" - integrity sha512-rWdchEhUyXx01GiwexH6Sha97CQ9tJdQwe6FtYKxShC7VEZV41nuKt+lzCQ4OqvQwZK5PcAKaAZv2GDsCH33SA== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -5975,16 +4131,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -<<<<<<< HEAD -======= -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - ->>>>>>> fabd9f7f... Update yarn.lock expect@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" @@ -6326,30 +4472,9 @@ forever-agent@~0.6.1: integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= form-data@^2.3.3: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== -======= -======= -form-data@^2.3.1: ->>>>>>> 8d2e8d2f... BREAK UP -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= -form-data@^2.3.1: ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch - version "2.5.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" - integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== ->>>>>>> f7a61a13... Create Exchange related Input components dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" @@ -6692,27 +4817,9 @@ got@^6.7.1: url-parse-lax "^1.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== -======= - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= - version "4.2.1" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d" - integrity sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - version "4.2.2" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" - integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== ->>>>>>> 9bae1b8d... bump deps growl@1.10.5: version "1.10.5" @@ -6881,23 +4988,9 @@ hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.1.0, hoist-non-react- react-is "^16.7.0" hosted-git-info@^2.1.4: -<<<<<<< HEAD -<<<<<<< HEAD - version "2.8.4" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" - integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== -======= - version "2.8.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.2.tgz#a35c3f355ac1249f1093c0c2a542ace8818c171a" - integrity sha512-CyjlXII6LMsPMyUzxpTt8fzh5QwzGqPmQXgY/Jyf4Zfp27t/FvfhwoE/8laaMUcMy816CkWF20I7NeQhwwY88w== - dependencies: - lru-cache "^5.1.1" ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= version "2.8.4" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== ->>>>>>> dca19a02... very work in progress html-encoding-sniffer@^1.0.2: version "1.0.2" @@ -6970,72 +5063,9 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "17.0.14" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" - integrity sha512-yEGSWX9UTpWQskPsFy03t8uhZh5wyZ7v9p+MCo08Sd2edTaFdg1gFA633dg9OqTxJ/z1rtCiacgOlDSBpgssgw== -======= - version "17.0.6" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.6.tgz#01079cc2bcef408139ea8ce24d18ac0d512fbe85" - integrity sha512-bdNhzhcM6RG5m82RypVguCrAQNie/ycxW0Q5C6K9UDWD5hqApZfdJFbj4Ikz9jxIR+Ja1eg0yCQLhlCT+opwIg== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= - version "17.0.9" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.9.tgz#5f835e91a34fa5e7da1e5ae4c4586c81d7c4b17f" - integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - version "17.0.10" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" - integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - version "17.0.10" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.10.tgz#8f92ec815d84dc0a0752e8114dc22e1861522d71" - integrity sha512-EUsx6LGXA6m2bTKUtPHHBVhE1v48y0cHKCWP7c9cUfnAu3ZBpWYPy5QkrC3ppV+BByJP3Zww9c9hhtfgnOpGBg== -======= - version "17.0.7" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.7.tgz#aae8591634b109c0ecec755b46c6414b0d743e07" - integrity sha512-fQn+gcyDaHb3qXIeahjCnGMsCeHaKveSORclang55stBjOL13oK7ZYxXVz1AaFV6p3SzOSu/KW+tgZcUuDdf6Q== ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "17.0.8" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.8.tgz#0c7113a88ad156eb37b9025d83a7684e1bbc2e18" - integrity sha512-oojOrqEPQzKo1HDMDDOl19zTM/EaDwBRPobUSD4kEjNoTi2oERvUbngK2lkIm9nOGddh55jbMGbm6fusMBeoKQ== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - version "17.0.9" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.9.tgz#5f835e91a34fa5e7da1e5ae4c4586c81d7c4b17f" - integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - version "17.0.11" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.11.tgz#36424dc01f6de391fae87878d24f5ff713565c27" - integrity sha512-O+yzoNi0usYcd4oi85EFY4WuwZ8NNsYJLauZ629YSjwgIi2D7eYDSQxy6aAR67V++b//GNuZEk7hx/i3L9Rxag== ->>>>>>> dca19a02... very work in progress -======= - version "17.0.12" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.12.tgz#d732a6c1131fc3b02305a8241eac25ec0d1cf663" - integrity sha512-FoYYnORcAMNznVXSpwJ1zVGL8kXcv1JUmvTqoQyuPPRncBq9rd7Mi0I/oVXkGR3YIek5dDiunvA/NGG2o+mMuw== ->>>>>>> fabd9f7f... Update yarn.lock + version "17.0.15" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.15.tgz#a4a378910fa06ca1c34f9e481ff6642acdb16dba" + integrity sha512-d+DLqZY1G15jDhSLRtsCVd/+KAWKmcmX1bp/5RjamIhftEFDvSXVgWXXkzsBFIl41VHhBV1y5JORukgz1s3GCQ== dependencies: "@babel/runtime" "^7.3.1" @@ -7074,15 +5104,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^3.1.3: -<<<<<<< HEAD version "3.3.0" resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== -======= - version "3.2.0" - resolved "https://registry.yarnpkg.com/immer/-/immer-3.2.0.tgz#53686471e9dd2b070e0fb5500c6fdecd3a99375f" - integrity sha512-+a2R8z9eELHst6aht++nzVzJ8LJ+Hsg49qttfg9Kc/vmoxEdPXw5/rV6+4DYWGgnq+B36KbLr4OTaGtS9mDjtg== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation import-fresh@^2.0.0: version "2.0.0" @@ -7225,29 +5249,10 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -<<<<<<< HEAD -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== -======= inquirer@^6.4.1: -<<<<<<< HEAD -<<<<<<< HEAD - version "6.5.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" - integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== ->>>>>>> 96db5a28... begin mike -======= - version "6.5.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.1.tgz#8bfb7a5ac02dac6ff641ac4c5ff17da112fcdb42" - integrity sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw== ->>>>>>> dca19a02... very work in progress -======= version "6.5.2" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: ansi-escapes "^3.2.0" chalk "^2.4.2" @@ -7569,15 +5574,7 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -<<<<<<< HEAD -<<<<<<< HEAD -is-what@^3.3.1: -======= -is-what@^3.2.4: ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= is-what@^3.3.1: ->>>>>>> fabd9f7f... Update yarn.lock version "3.3.1" resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.3.1.tgz#79502181f40226e2d8c09226999db90ef7c1bcbe" integrity sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA== @@ -7813,22 +5810,6 @@ jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== -<<<<<<< HEAD -======= - -jest-haste-map@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" - integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.11" - invariant "^2.2.4" - jest-serializer "^24.0.0-alpha.6" - jest-worker "^24.0.0-alpha.6" - micromatch "^2.3.11" - sane "^3.0.0" ->>>>>>> fabd9f7f... Update yarn.lock jest-haste-map@^24.7.1, jest-haste-map@^24.9.0: version "24.9.0" @@ -7999,14 +5980,6 @@ jest-serializer@^24.4.0, jest-serializer@^24.9.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== -<<<<<<< HEAD -======= -jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0, jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== - ->>>>>>> fabd9f7f... Update yarn.lock jest-snapshot@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" @@ -8069,18 +6042,7 @@ jest-watcher@^24.9.0: jest-util "^24.9.0" string-length "^2.0.0" -<<<<<<< HEAD jest-worker@^24.6.0, jest-worker@^24.9.0: -======= -jest-worker@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" - integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== - dependencies: - merge-stream "^1.0.1" - -jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0, jest-worker@^24.9.0: ->>>>>>> fabd9f7f... Update yarn.lock version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== @@ -8726,14 +6688,6 @@ merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -<<<<<<< HEAD -======= - -merge2@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.4.tgz#c9269589e6885a60cf80605d9522d4b67ca646e3" - integrity sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation merge2@^1.2.3: version "1.3.0" @@ -8909,29 +6863,6 @@ metro-react-native-babel-preset@^0.56.0: "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" react-refresh "^0.4.0" -<<<<<<< HEAD -======= - -metro-react-native-babel-transformer@0.51.0: - version "0.51.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz#57a695e97a19d95de63c9633f9d0dc024ee8e99a" - integrity sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.0" - metro-react-native-babel-preset "0.51.0" - -metro-react-native-babel-transformer@^0.51.0: - version "0.51.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.1.tgz#bac34f988c150c725cd1875c13701cc2032615f9" - integrity sha512-D0KU+JPb/Z76nUWt3+bkjKggOlGvqAVI2BpIH2JFKprpUyBjWaCRqHnkBfZGixYwUfmu93MIlKJWr6iKzzFrlg== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.0.1" - metro-babel-transformer "0.51.1" - metro-react-native-babel-preset "0.51.1" ->>>>>>> 9bae1b8d... bump deps metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" @@ -9178,15 +7109,9 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: -<<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== -======= - version "2.4.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.4.0.tgz#38f0af94f42fb6f34d3d7d82a90e2c99cd3ff485" - integrity sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -9306,15 +7231,9 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.0.3: -<<<<<<< HEAD version "2.1.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== -======= - version "2.0.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.4.tgz#4889355c9ce8e24efad7c65945a4a2875ac3e8f4" - integrity sha512-sOJnBmY3TJQBVIBqKHoifuwygrocXg3NjS9rZSMnVl05XWSHK7Qxb177AIZQyMDjP86bz+yneozj/h9qsPLcCA== ->>>>>>> fabd9f7f... Update yarn.lock nanomatch@^1.2.9: version "1.2.13" @@ -9418,23 +7337,10 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> fabd9f7f... Update yarn.lock node-notifier@^5.2.1, node-notifier@^5.4.2: version "5.4.3" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== -<<<<<<< HEAD -======= -node-notifier@^5.2.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.1.tgz#7c0192cc63aedb25cd99619174daa27902b10903" - integrity sha512-p52B+onAEHKW1OF9MGO/S7k/ahGEHfhP5/tvwYzog/5XLYOd8ZuD6vdNZdUuWMONRnKPneXV43v3s6Snx1wsCQ== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= ->>>>>>> fabd9f7f... Update yarn.lock dependencies: growly "^1.3.0" is-wsl "^1.1.0" @@ -9458,30 +7364,10 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -<<<<<<< HEAD -<<<<<<< HEAD node-releases@^1.1.29: version "1.1.30" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== -======= -node-releases@^1.1.23: - version "1.1.24" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.24.tgz#2fb494562705c01bfb81a7af9f8584c4d56311b4" - integrity sha512-wym2jptfuKowMmkZsfCSTsn8qAVo8zm+UiQA6l5dNqUcpfChZSnS/vbbpOeXczf+VdPhutxh+99lWHhdd6xKzg== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= -node-releases@^1.1.25: -<<<<<<< HEAD - version "1.1.27" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.27.tgz#b19ec8add2afe9a826a99dceccc516104c1edaf4" - integrity sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA== ->>>>>>> dca19a02... very work in progress -======= - version "1.1.28" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.28.tgz#503c3c70d0e4732b84e7aaa2925fbdde10482d4a" - integrity sha512-AQw4emh6iSXnCpDiFe0phYcThiccmkNWMZnFZ+lDJjAP8J0m2fVd59duvUUyuTirQOhIAajTFkzG6FHCLBO59g== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: semver "^5.3.0" @@ -9557,8 +7443,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -<<<<<<< HEAD -======= npm-run-path@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" @@ -9566,16 +7450,6 @@ npm-run-path@^3.0.0: dependencies: path-key "^3.0.0" -npmlog@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" - integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= - dependencies: - ansi "~0.3.1" - are-we-there-yet "~1.1.2" - gauge "~1.2.5" - ->>>>>>> e1a27438... Cleanup ButtonPressAnimation npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -10388,38 +8262,9 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.0: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== -======= - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz#e3f6172cc91302912c89da55a42454025485250f" - integrity sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" - integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== ->>>>>>> 1d794746... Minor cleanup Header component -======= - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" - integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== -======= - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz#e3f6172cc91302912c89da55a42454025485250f" - integrity sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" - integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== ->>>>>>> dca19a02... very work in progress postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.7: version "7.0.18" @@ -10460,17 +8305,6 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== -<<<<<<< HEAD -======= -pretty-format@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" - integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - ->>>>>>> fabd9f7f... Update yarn.lock pretty-format@^24.7.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" @@ -10581,21 +8415,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: -<<<<<<< HEAD -<<<<<<< HEAD version "1.4.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== -======= - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= - version "1.3.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" - integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation public-encrypt@^4.0.0: version "4.0.3" @@ -10681,18 +8503,6 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= -<<<<<<< HEAD -======= -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - ->>>>>>> 9bae1b8d... bump deps randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -10733,46 +8543,7 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -<<<<<<< HEAD -======= -react-clone-referenced-element@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" - integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== - -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= -react-coin-icon@^0.1.9: -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD -<<<<<<< HEAD -react-coin-icon@^0.1.9: -======= -<<<<<<< HEAD -react-coin-icon@^0.1.8: -======= -<<<<<<< HEAD ->>>>>>> 397368cb... WIP swap ui polish -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -react-coin-icon@^0.1.9: ->>>>>>> 9a56f78d... WIP swap ui polish ->>>>>>> 2db58de2... WIP swap ui polish -======= -<<<<<<< HEAD -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch react-coin-icon@^0.1.9: ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -======= -react-coin-icon@^0.1.9: ->>>>>>> dca19a02... very work in progress version "0.1.9" resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== @@ -10804,7 +8575,7 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw== -react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2: +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== @@ -10875,100 +8646,9 @@ react-native-crypto@^2.1.2: randomfill "^1.0.3" react-native-device-info@^2.1.3: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== -======= -======= ->>>>>>> 96db5a28... begin mike -======= ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -<<<<<<< HEAD - version "2.3.1" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" - integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== -======= -<<<<<<< HEAD - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.0.tgz#7b2a8baf8453324bd8d120ce46e5e2bb0181ccd4" - integrity sha512-ISEChH2zg4bRX8PL1cYoNWffJ7wmgYosKyJbkWyTxs8g+rpeGkmMf9Wo4COriAt1AJ2jC78IGhJYFzbIc+Przw== -======= - version "2.3.1" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" - integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "2.3.1" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" - integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== ->>>>>>> dc42f3f4... begin mike -<<<<<<< HEAD ->>>>>>> 96db5a28... begin mike -======= -======= - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation version "2.3.2" resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== -======= -<<<<<<< HEAD - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.0.tgz#7b2a8baf8453324bd8d120ce46e5e2bb0181ccd4" - integrity sha512-ISEChH2zg4bRX8PL1cYoNWffJ7wmgYosKyJbkWyTxs8g+rpeGkmMf9Wo4COriAt1AJ2jC78IGhJYFzbIc+Przw== -======= - version "2.3.1" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.1.tgz#363267c4574dbd779290cdc06bb423f9c16d68d8" - integrity sha512-4kIBeBdYB/IwNjbSTEvfnWgFB4cXL0drvdXKfcAgfI5vxmsLElR5HI6t9fqVkPyMCiRtI7mvS6PbG2kjGdbQMw== ->>>>>>> b45c1992... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch -<<<<<<< HEAD ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -======= - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== ->>>>>>> dca19a02... very work in progress react-native-dotenv@^0.2.0: version "0.2.0" @@ -10984,11 +8664,7 @@ react-native-emoji@1.5.0: dependencies: node-emoji "1.10.0" -<<<<<<< HEAD react-native-fast-image@^6.0.3: -======= -react-native-fast-image@^6.0.0: ->>>>>>> 751dba29... Replace navigation animations with new effects version "6.1.1" resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-6.1.1.tgz#502165beeafdd117e09dfb68ba322fe602534b8e" integrity sha512-9bYUY8GLKpuTF9WOC28VM/ceH0+GyV60g3bcwYeiq0A+oDBVyVlj/ovMaJqRxHII6GQYX0WbTkiT5kWtPCtWkA== @@ -11002,16 +8678,10 @@ react-native-firebase@^4.3.8: postinstall-build "^5.0.1" prop-types "^15.6.1" -<<<<<<< HEAD react-native-gesture-handler@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== -======= -react-native-gesture-handler@mikedemarais/react-native-gesture-handler#mike-hooks: - version "1.3.1" - resolved "https://codeload.github.com/mikedemarais/react-native-gesture-handler/tar.gz/beb63c2d8af5ae26cf264cb598376fb76d41c08c" ->>>>>>> e1a27438... Cleanup ButtonPressAnimation dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -11069,21 +8739,9 @@ react-native-mail@^3.0.6: integrity sha512-FHe4kKJKAGuCPPWcDwaRSjdUhEE4IWIsVtTZ05dgD/MgOm00isYmM20zuJHla7oiHVQ2HmzGji76g6IuhIrCjw== react-native-os@^1.2.2: -<<<<<<< HEAD -<<<<<<< HEAD version "1.2.5" resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== -======= - version "1.2.4" - resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.4.tgz#f9ea7423cc9a9e865bc9cad590941ce37b7a3aee" - integrity sha512-ohlP5BxJxvWp8JZ99g8+xdZ2s8Z4bEoP6g99VDeytz04m+VYdVrCP7Xovy6FoEqA4qxyUbv4xeGHR+pzNnkZeg== ->>>>>>> 751dba29... Replace navigation animations with new effects -======= - version "1.2.5" - resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" - integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== ->>>>>>> fabd9f7f... Update yarn.lock react-native-permissions@^1.1.1: version "1.2.0" @@ -11116,28 +8774,6 @@ react-native-randombytes@^3.5.3: buffer "^4.9.1" sjcl "^1.0.3" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views -react-native-reanimated@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.2.0.tgz#9219227a52a5dfa4d34c324596d6726ccd874293" - integrity sha512-vkWRHrPK5qfHP/ZawlRoo38oeYe9NZaaOH/lmFxRcsKzaSK6x3H5ZPXI8lK6MfTLveqwo1QhJje3zIKXO4nQQw== - -<<<<<<< HEAD -react-native-redash@^7.2.1: - version "7.5.1" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.1.tgz#79c52c9a629b8ddeeb17e73336216aba1cc2f689" - integrity sha512-NidcTKlK57BtjCMC9OKhXJnH50TDlfb+vel4oLUfaYHO2kGY56jGj+IS29V3joZgB5iO1X+U5K5FYWuQuDnepA== -======= -react-native-redash@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.0.tgz#fa72c7a23ad2f3f884a494ed76a0e79041ae70e1" - integrity sha512-y2J19HbBYWOYq4kq+3U86wfbsDusxv1/ak4a6KqvfTmt/E3i85mnnUDIF+nk1Shqz0aYcwNMB2KD7bEWsVK/sw== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= react-native-reanimated@1.3.0-alpha: version "1.3.0-alpha" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.3.0-alpha.tgz#d278128acef895cf72aa34c5c4bd1540632c2ac6" @@ -11147,59 +8783,16 @@ react-native-redash@^7.5.1: version "7.5.1" resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-7.5.1.tgz#79c52c9a629b8ddeeb17e73336216aba1cc2f689" integrity sha512-NidcTKlK57BtjCMC9OKhXJnH50TDlfb+vel4oLUfaYHO2kGY56jGj+IS29V3joZgB5iO1X+U5K5FYWuQuDnepA== ->>>>>>> 9bae1b8d... bump deps dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" parse-svg-path "^0.1.2" use-memo-one "^1.1.1" -<<<<<<< HEAD -<<<<<<< HEAD -react-native-safe-area-view@^0.14.1: +react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: version "0.14.8" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== -======= -react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.5: -======= -react-native-reanimated@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz#ba6864055ec3a206cdd5209a293fe653ce276206" - integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== - -<<<<<<< HEAD -react-native-safe-area-view@^0.14.1: -<<<<<<< HEAD ->>>>>>> 751dba29... Replace navigation animations with new effects - version "0.14.5" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.5.tgz#eeded66bbeb0807f0a7f5f449e7fb2871f7ecf76" - integrity sha512-1NxWK1G0gzwCOuyNV/zf4n18s6FWsiqgwkzU3P9C0Iu8AErjhstK1jUqpRwzLH8+/7hGLsrQedmn+ZbQTOrJPg== ->>>>>>> bc689cd3... Update react-navigation-stack to 2.0.0-alpha.2 - dependencies: - hoist-non-react-statics "^2.3.1" - -react-native-safe-area-view@^0.14.6: -======= -react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: ->>>>>>> 3984235a... Bump react-navigation stack to current master -======= -react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: -<<<<<<< HEAD ->>>>>>> e162a3d6... Fix merge mistakes - version "0.14.6" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz#9a9d37d9f8f3887d60c4076eae7b5d2319539446" - integrity sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA== -======= - version "0.14.7" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" - integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== ->>>>>>> dca19a02... very work in progress -======= - version "0.14.7" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" - integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: hoist-non-react-statics "^2.3.1" @@ -11234,54 +8827,10 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -<<<<<<< HEAD -<<<<<<< HEAD -react-native-svg@^9.5.1: +react-native-svg@^9.6.2: version "9.9.3" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.9.3.tgz#5dab1a44b20b13a3f35245a286f30882b9611d66" integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== -======= -react-native-svg@^9.5.3: -======= -react-native-svg@^9.6.2: -<<<<<<< HEAD ->>>>>>> 9bae1b8d... bump deps - version "9.6.2" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" - integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= -======= - version "9.5.3" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.5.3.tgz#2389f3ffd700c6441166496a1aeade31ead89c59" - integrity sha512-VUOe4TLz7RFdmm/XT9EH87VSwlRykx49qbwJMA+dh9eFM7KPY1qH3kEyN7uRCqJD2eE8toxt9NpjR6ByvtPNlA== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - version "9.6.1" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.1.tgz#4d2ba1e7ecd78d06603e8bf2fbc5072fc5852506" - integrity sha512-X8WvZ5uNHyE+17Q4SSbdQZ1NsRyRxdvAFqipqDldL6D0oUB0pBI2tekx03N4taVtVN+p8Pg3T3SSmIxwXZmMYA== ->>>>>>> bdd78363... podfile lock for text input mask -<<<<<<< HEAD ->>>>>>> a7347f4b... podfile lock for text input mask -======= -======= - version "9.6.2" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.2.tgz#e29b626f115230e0f0f3693887f36e60b5b01408" - integrity sha512-TwTEkGTe2aRh1VBemFIuc6bCvPmlVUAd2kk4HmZLuxyBDAzEAbWYFsvDSkGd9mZ06ghx1gDg+c0hrH3y0q/eDA== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= ->>>>>>> dca19a02... very work in progress -======= - version "9.7.0" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.7.0.tgz#2d0bf1d31d5f1dd061587215b50deb29e626df18" - integrity sha512-8E1snfe2YYbfu6SP5DOoQgRhCdv7D0F4VewUAV+IgAn+IScrA/uuLB8LCodRdO+9U4Rm5dJ4yIwsVhPHRtuBkw== ->>>>>>> fabd9f7f... Update yarn.lock react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -11290,19 +8839,12 @@ react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: dependencies: prop-types "^15.6.1" -<<<<<<< HEAD -<<<<<<< HEAD -======= react-native-tab-view@^2.9.0: version "2.10.0" resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.0.tgz#5e249e5650502010013449ffd4e5edc18a95364b" integrity sha512-qgexVz5eO4yaFjdkmn/sURXgVvaBo6pZD/q1eoca96SbPVbaH3WzVhF3bRUfeTHwZkXwznFTpS3JURqIFU8vQA== ->>>>>>> 8fda6af4... Begin orchestrating keyboard focus between swap modal views react-native-tcp@^3.3.0: -======= -react-native-tcp@^3.2.1: ->>>>>>> 751dba29... Replace navigation animations with new effects version "3.3.1" resolved "https://registry.yarnpkg.com/react-native-tcp/-/react-native-tcp-3.3.1.tgz#dfb35ac48356fa8b707dafe69a971feb0845d88b" integrity sha512-kySTh7oUixfoNHCNAuxjSMjGPYXkg06sgCQOzj1bVInrTNMOSQpYvlKVSSqIorHvus2yvMmYOguTgLffMe65TA== @@ -11314,9 +8856,9 @@ react-native-tcp@^3.2.1: process "^0.11.9" util "^0.10.3" -react-native-text-input-mask@quixley/react-native-text-input-mask#development: +react-native-text-input-mask@react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9: version "1.0.6" - resolved "https://codeload.github.com/quixley/react-native-text-input-mask/tar.gz/76f7ce5cf57768aebc843051e98f8946a91ffd3e" + resolved "https://codeload.github.com/react-native-community/react-native-text-input-mask/tar.gz/abf0e7f538036bbc5719024fbd67a1efd756c4b9" react-native-tooltip@^5.2.0: version "5.2.0" @@ -11385,121 +8927,38 @@ react-navigation-drawer@~1.4.0: dependencies: react-native-tab-view "^1.2.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -react-navigation-stack@~1.5.0: - version "1.5.5" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.5.5.tgz#0b3cd98b7845a51d9ce9d7d678e9e3b9ed010bc3" - integrity sha512-qMhOhmUmyPNfFGWMbwv5flrNVsFU4JZSBWnONSgVGK4KWGW8DbobXBi4i4sBAC9Kg8EqJK0qyWcxnkMJJtfMWA== - dependencies: - prop-types "^15.7.2" -======= -"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.2", react-navigation-stack@~1.4.0: -======= -"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.2": ->>>>>>> 85ffae7a... Convert parts of the API to the new version - version "2.0.0-alpha.2" - resolved "https://github.com/react-navigation/stack#34e12dae8d9fbd9aff455ea82478639dc579df86" - dependencies: - react-native-safe-area-view "^0.14.5" ->>>>>>> bc689cd3... Update react-navigation-stack to 2.0.0-alpha.2 - -<<<<<<< HEAD -react-navigation-tabs@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" - integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== -======= -react-navigation-stack@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.4.0.tgz#69cdb029ea4ee5877d7e933b3117dc90bc841eb2" - integrity sha512-zEe9wCA0Ot8agarYb//0nSWYW1GM+1R0tY/nydUV0EizeJ27At0EklYVWvYEuYU6C48va6cu8OPL7QD/CcJACw== -======= -"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.5", react-navigation-stack@~1.4.0: - version "2.0.0-alpha.5" - resolved "https://github.com/react-navigation/stack#67a942dd5e880574f72ce214b02730ddf286109a" -======= -"react-navigation-stack@https://github.com/react-navigation/stack#2.0.0-alpha.6", react-navigation-stack@~1.4.0: - version "2.0.0-alpha.6" - resolved "https://github.com/react-navigation/stack#28359b3853ce234586302e98377c91638d75c585" ->>>>>>> 3a2e4076... Bump version of react-navigation-stack to alpha.6 -======= -======= -react-navigation-stack@^2.0.0-alpha.7: - version "2.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.7.tgz#1534e31e0f9cfc9c3340f0d752e5c992a1961a89" - integrity sha512-9ltkEY+ayNRBnOMRRC7UCTAS6wqdH15Tg8hE004sYLvsZw3HwwTj2il0C5BWzDq+IwItj+LI+S9tDdHUxF1a1Q== - dependencies: - react-native-safe-area-view "^0.14.6" - ->>>>>>> 996fc4e7... Update react-navigation-stack to alpha.7 -"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: - version "2.0.0-alpha.6" - resolved "https://github.com/react-navigation/stack#2ddf3a4a3985047811c3c90f1d8263ea71994966" ->>>>>>> 3984235a... Bump react-navigation stack to current master -======= -react-navigation-stack@^2.0.0-alpha.9: - version "2.0.0-alpha.9" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.9.tgz#6e0382f3f4e37235c94badf6712c7095415d4a6d" - integrity sha512-Lze5CuCDr9FtGIJyxG8e1YXbpyd77XjOgLnQN5PRG9qx7YNmAbkbybPrhsmlRVWiyosC8IEVFbnot0EDcR+O/w== - dependencies: - react-native-safe-area-view "^0.14.6" - -"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: +"react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.5.0: version "2.0.0-alpha.7" resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" ->>>>>>> fabd9f7f... Update yarn.lock dependencies: react-native-safe-area-view "^0.14.6" ->>>>>>> 751dba29... Replace navigation animations with new effects react-navigation-tabs@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.3.0.tgz#0288830e6ac5157f203ee3947bc29b0d6eda66b1" - integrity sha512-0LiTwXEVt7XdzVT02fvg14NMz90zfPUyw1g2mIrWA70+M56br5k6tXKrZg8NjH1MgWVz5TWBx90SI0MhD2OssA== + version "2.5.2" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.2.tgz#80812254e32c5720722fed9a26b6e109ed0f4ac1" + integrity sha512-f5OlXROO6VtnvgmSBzvS+2X8+KEMjJ4JM3S3IsmHa2J1dc/ssZE9QNEjttmsNxDi79vHVNaC+oiXI9GUtb3+YA== dependencies: hoist-non-react-statics "^3.3.0" react-lifecycles-compat "^3.0.4" + react-native-safe-area-view "^0.14.6" react-native-tab-view "^2.9.0" -<<<<<<< HEAD -react-navigation-tabs@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" - integrity sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ== ->>>>>>> 85ffae7a... Convert parts of the API to the new version -======= react-navigation-tabs@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: hoist-non-react-statics "^2.5.0" prop-types "^15.6.1" react-native-tab-view "^1.4.1" react-navigation@^3.11.1: -<<<<<<< HEAD version "3.12.1" resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== dependencies: "@react-navigation/core" "~3.5.0" "@react-navigation/native" "~3.6.1" -======= - version "3.12.0" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.0.tgz#31cc6c7d778c968965e86a820f12f1e1a66e20b9" - integrity sha512-Lr0l0lbZsFsajUx040I1HYm0yIfa+F9SCEeaNkS1eiey6k2G04eY5hYGZfo4i3kaMj99Yi8tuRcSN7DS0QZu8w== - dependencies: - "@react-navigation/core" "~3.5.0" - "@react-navigation/native" "~3.6.0" ->>>>>>> fabd9f7f... Update yarn.lock react-navigation-drawer "~1.4.0" react-navigation-stack "~1.5.0" react-navigation-tabs "~1.2.0" @@ -11536,15 +8995,9 @@ react-redux@^5.0.7: react-lifecycles-compat "^3.0.0" react-refresh@^0.4.0: -<<<<<<< HEAD version "0.4.2" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.2.tgz#54a277a6caaac2803d88f1d6f13c1dcfbd81e334" integrity sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ== -======= - version "0.4.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.0.tgz#d421f9bd65e0e4b9822a399f14ac56bda9c92292" - integrity sha512-bacjSio8GOtzNZKZZM6EWqbhlbb6pr28JWJWFTLwEBKvPIBRo6/Ob68D2EWZA2VyTdQxAh+TRnCYOPNKsQiXTA== ->>>>>>> 9bae1b8d... bump deps react-spring@^5.7.2: version "5.9.2" @@ -11719,21 +9172,10 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" -<<<<<<< HEAD recyclerlistview@2.0.1-alpha.1: version "2.0.1-alpha.1" resolved "https://registry.yarnpkg.com/recyclerlistview/-/recyclerlistview-2.0.1-alpha.1.tgz#881955e6917911fb54a9b272004e39e5c0d64f4a" integrity sha512-UaeJyxG9LL8lcfiAqkp0kPLxvjbYg95Dcq1U/QUvzwXU4+H2khg/LAws/FssxPX6CXNMw7BLcT2YHAhkFElqRQ== -======= -recyclerlistview@Flipkart/recyclerlistview#master: -<<<<<<< HEAD - version "2.0.10" - resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/1d310dffc80d63e4303bf1213d2f6b0ce498c33a" ->>>>>>> 9bae1b8d... bump deps -======= - version "2.0.13" - resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/6c191661214a53f6ba24567528f0de7902ffda6c" ->>>>>>> fabd9f7f... Update yarn.lock dependencies: lodash.debounce "4.0.8" prop-types "15.5.8" @@ -11820,15 +9262,9 @@ regexpp@^2.0.1: integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^4.5.4: -<<<<<<< HEAD version "4.6.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== -======= - version "4.5.5" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.5.tgz#aaffe61c2af58269b3e516b61a73790376326411" - integrity sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ== ->>>>>>> dca19a02... very work in progress dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^8.1.0" @@ -11864,18 +9300,6 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" -<<<<<<< HEAD -======= -rehype-parse@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.1.tgz#a5401d7f4144d5e17cbb69be11f05a2a7ba87e27" - integrity sha512-FrGSbOzcGxIvWty1qHjKTvHT4WBTt7C6JLs65EkvFPa7ZKraSmsoDDj6al1eBxaXS1t/kiGdPYazUe58Mgflgw== - dependencies: - hast-util-from-parse5 "^5.0.0" - parse5 "^5.0.0" - xtend "^4.0.1" - ->>>>>>> 751dba29... Replace navigation animations with new effects remark-parse@^6.0.0: version "6.0.3" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" @@ -12073,15 +9497,7 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -<<<<<<< HEAD -<<<<<<< HEAD -rimraf@2.6.3: -======= -rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@~2.6.2: ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= rimraf@2.6.3, rimraf@~2.6.2: ->>>>>>> 9bae1b8d... bump deps version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -12120,7 +9536,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rn-nodeify@^10.0.1: +rn-nodeify@10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.1.0.tgz#e36c4aa25d6bf1dbde7d9f733ab30168772d50c6" integrity sha512-EW9I7OWt1aTShdJEnnS/qoEvfb2myLee6uWcAMxJWcisn3z3DxWTTLfm5bqwn/2eYjcs6j677JLY6nL02uMaaQ== @@ -12237,31 +9653,10 @@ sax@^1.2.1, sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -schedule@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.4.0.tgz#fa20cfd0bfbf91c47d02272fd7096780d3170bbb" - integrity sha512-hYjmoaEMojiMkWCxKr6ue+LYcZ29u29+AamWYmzwT2VOO9ws5UJp/wNhsVUPiUeNh+EdRfZm7nDeB40ffTfMhA== -======= -======= ->>>>>>> a7347f4b... podfile lock for text input mask -sax@~1.1.1: - version "1.1.6" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" - integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= - -<<<<<<< HEAD -======= ->>>>>>> 64f1594b... rebase cleanup -======= ->>>>>>> a7347f4b... podfile lock for text input mask schedule@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" integrity sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw== ->>>>>>> 96db5a28... begin mike dependencies: object-assign "^4.1.1" @@ -12298,30 +9693,15 @@ semver-diff@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -<<<<<<< HEAD semver@5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== -<<<<<<< HEAD -<<<<<<< HEAD -semver@^6.0.0, semver@^6.1.1, semver@^6.2.0: -======= -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2: ->>>>>>> 96db5a28... begin mike -======= semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0: ->>>>>>> fabd9f7f... Update yarn.lock version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -======= -semver@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" - integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== ->>>>>>> 751dba29... Replace navigation animations with new effects semver@~2.3.1: version "2.3.2" @@ -12438,15 +9818,9 @@ shell-quote@1.6.1: jsonify "~0.0.0" shell-quote@^1.6.1: -<<<<<<< HEAD version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== -======= - version "1.7.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.1.tgz#3161d969886fb14f9140c65245a5dd19b6f0b06b" - integrity sha512-2kUqeAGnMAu6YrTPX4E3LfxacH9gKljzVjlkUeSqY0soGwK4KLl7TURXCem712tkhBCeeaFP9QK4dKn88s3Icg== ->>>>>>> 9bae1b8d... bump deps shell-utils@^1.0.9: version "1.0.10" @@ -12949,67 +10323,10 @@ styled-components@4.3.1: stylis-rule-sheet "^0.0.10" supports-color "^5.5.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -styled-components@^5.0.0-beta.8: -<<<<<<< HEAD - version "5.0.0-beta.8-groupsizefix" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8-groupsizefix.tgz#0497f11c0d60e9e51faa4b802afab7cc22136e42" - integrity sha512-5FDDRE4QhH8g6zsvHGPZ2NrJRi12AH1GxpZMy+y0lRYGrfNL6W5xni5Sz8kOKXS4PGf1VeyfVXaEG10mbrQYsA== -======= -======= -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= -<<<<<<< HEAD -styled-components@^5.0.0-beta.8: ->>>>>>> 2216260a... Create Exchange related Input components - version "5.0.0-beta.6-ej4" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.6-ej4.tgz#7570ebbf9c9356a8cca03ea37dd94233f2e40e84" - integrity sha512-WaytinYy4+Zc1TKXdTlPmkAOIj58QWvjn1rdgxCSAMAR4GFLlu2m7rQXwZ6WYWYk6GJd141rnZnE2Ig3XERc5A== -======= -<<<<<<< HEAD -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 034f7aa3... Create Exchange related Input components -<<<<<<< HEAD ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> dca19a02... very work in progress styled-components@5.0.0-beta.8: version "5.0.0-beta.8" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0-beta.8.tgz#ad1e672589a891987f5492cbe3ca6f480fcd99dc" integrity sha512-g4MrDmfaoR2jJnA56+JSTFf1ZsDpJYdvTyQSw3HWOHoV/KlCgaSFmU8TrHfTy7DwWQskxyX//IQInNZdn4mGcA== -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= -======= ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> 034f7aa3... Create Exchange related Input components ->>>>>>> 2216260a... Create Exchange related Input components -======= -======= ->>>>>>> 8d2e8d2f... BREAK UP ->>>>>>> 034f7aa3... Create Exchange related Input components -======= ->>>>>>> 25875d99... fix conflicts after rebasing over latest wallet-zero branch ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> dca19a02... very work in progress dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5" @@ -13161,15 +10478,9 @@ svg-tags@^1.0.0: integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= svgo@^1.2.2: -<<<<<<< HEAD version "1.3.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== -======= - version "1.2.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316" - integrity sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA== ->>>>>>> 751dba29... Replace navigation animations with new effects dependencies: chalk "^2.4.1" coa "^2.0.2" @@ -13209,21 +10520,9 @@ symbol-tree@^3.2.2: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^5.2.3: -<<<<<<< HEAD -<<<<<<< HEAD - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== -======= - version "5.4.5" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.5.tgz#c8f4ea2d8fee08c0027fac27b0ec0a4fe01dfa42" - integrity sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== ->>>>>>> fabd9f7f... Update yarn.lock dependencies: ajv "^6.10.2" lodash "^4.17.14" @@ -13482,49 +10781,9 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== tsutils@^3.7.0: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== -======= - version "3.17.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.0.tgz#c3ccab927a475aa2beef6a3695c2ff76da13cdf8" - integrity sha512-fyveWOtAXfumAxIqkcMHuPaaVyLBKjB8Y00ANZkqh+HITBAQscCbQIHwwBTJdvQq7RykLEbOPcUUnJ16X4NA0g== ->>>>>>> e1a27438... Cleanup ButtonPressAnimation -======= - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== ->>>>>>> 1d794746... Minor cleanup Header component -======= -======= ->>>>>>> 908925bc... Cleanup ButtonPressAnimation - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== -======= - version "3.15.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.15.0.tgz#3efabbf2c18a5d7c7496a878be0609eb90897ed6" - integrity sha512-or184xKZ6fLE1SrDcvsOs3Wkfb1JgizdKs5Fiag3cp/m9k7C7GWd4E7gs3K5LHAePaIP7K62C20ZZI3JQx8iBQ== ->>>>>>> a3543960... rebase cleanup -<<<<<<< HEAD ->>>>>>> 64f1594b... rebase cleanup -======= -======= - version "3.17.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.0.tgz#c3ccab927a475aa2beef6a3695c2ff76da13cdf8" - integrity sha512-fyveWOtAXfumAxIqkcMHuPaaVyLBKjB8Y00ANZkqh+HITBAQscCbQIHwwBTJdvQq7RykLEbOPcUUnJ16X4NA0g== ->>>>>>> b1697d93... Cleanup ButtonPressAnimation ->>>>>>> 908925bc... Cleanup ButtonPressAnimation -======= - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== ->>>>>>> dca19a02... very work in progress dependencies: tslib "^1.8.1" @@ -13880,23 +11139,10 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" -<<<<<<< HEAD vlq@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== -======= -vfile@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.1.tgz#fc3d43a1c71916034216bf65926d5ee3c64ed60c" - integrity sha512-lRHFCuC4SQBFr7Uq91oJDJxlnftoTLQ7eKIpMdubhYcVMho4781a8MWXLy3qZrZ0/STD1kRiKc0cQOHm4OkPeA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" ->>>>>>> 751dba29... Replace navigation animations with new effects vm-browserify@0.0.4: version "0.0.4" @@ -14138,13 +11384,6 @@ xmlbuilder@^9.0.7: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xmldoc@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" - integrity sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg= - dependencies: - sax "~1.1.1" - xmldoc@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" @@ -14302,25 +11541,7 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -<<<<<<< HEAD -<<<<<<< HEAD -yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: -======= -yargs@^13.0.0, yargs@^13.2.4: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> f7a61a13... Create Exchange related Input components -======= ->>>>>>> c2296ac1... fix conflicts after rebasing over latest wallet-zero branch -======= ->>>>>>> 2216260a... Create Exchange related Input components -======= ->>>>>>> 317ce799... fix conflicts after rebasing over latest wallet-zero branch -======= yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: ->>>>>>> fabd9f7f... Update yarn.lock version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== From 9097bad7a129f509239cd8424334d8ea5ea06951 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Fri, 16 Aug 2019 02:27:55 -0700 Subject: [PATCH 214/636] Clean up swap token list --- src/references/uniswap-pairs.json | 116 +++++++++--------------------- 1 file changed, 33 insertions(+), 83 deletions(-) diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index 6bd9cdaa81a..12b52ff991b 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -6,7 +6,7 @@ "exchange_address": null }, "0x960b236A07cf122663c4303350609A66A7B288C0": { - "name": "Aragon Network Token", + "name": "Aragon", "symbol": "ANT", "decimals": 18, "exchange_address": "0x077d52B047735976dfdA76feF74d4d988AC25196" @@ -18,23 +18,17 @@ "exchange_address": "0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914" }, "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { - "name": "Bloom Token", + "name": "Bloom", "symbol": "BLT", "decimals": 18, "exchange_address": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" }, "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { - "name": "Bancor Network Token", + "name": "Bancor", "symbol": "BNT", "decimals": 18, "exchange_address": "0x87d80DBD37E551F58680B4217b23aF6a752DA83F" }, - "0x26E75307Fc0C021472fEb8F727839531F112f317": { - "name": "Crypto20", - "symbol": "C20", - "decimals": 18, - "exchange_address": "0xF7B5A4b934658025390ff69dB302BC7F2AC4a542" - }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { "name": "Compound Dai", "symbol": "cDAI", @@ -48,7 +42,7 @@ "exchange_address": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" }, "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { - "name": "Dai Stablecoin v1.0", + "name": "Dai", "symbol": "DAI", "decimals": 18, "exchange_address": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" @@ -65,16 +59,8 @@ "decimals": 9, "exchange_address": "0xb92dE8B30584392Af27726D5ce04Ef3c4e5c9924" }, - - "0xc719d010B63E5bbF2C0551872CD5316ED26AcD83": { - "name": "Decentralized Insurance Protocol", - "symbol": "DIP", - "decimals": 18, - "exchange_address": "0x61792F290e5100FBBcBb2309F03A1Bab869fb850" - }, - "0x4946Fcea7C692606e8908002e55A582af44AC121": { - "name": "FOAM Token", + "name": "FOAM", "symbol": "FOAM", "decimals": 18, "exchange_address": "0xf79cb3BEA83BD502737586A6E8B133c378FD1fF2" @@ -92,13 +78,13 @@ "exchange_address": "0x26Cc0EAb6Cb650B0Db4D0d0dA8cB5BF69F4ad692" }, "0x6810e776880C02933D47DB1b9fc05908e5386b96": { - "name": "Gnosis Token", + "name": "Gnosis", "symbol": "GNO", "decimals": 18, "exchange_address": "0xe8e45431b93215566BA923a7E611B7342Ea954DF" }, "0x12B19D3e2ccc14Da04FAe33e63652ce469b3F2FD": { - "name": "GRID Token", + "name": "Grid+", "symbol": "GRID", "decimals": 12, "exchange_address": "0x4B17685b330307C751B47f33890c8398dF4Fe407" @@ -110,35 +96,29 @@ "exchange_address": "0xb7520a5F8c832c573d6BD0Df955fC5c9b72400F7" }, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { - "name": "Kyber Network Crystal", + "name": "Kyber Network", "symbol": "KNC", "decimals": 18, "exchange_address": "0x49c4f9bc14884f6210F28342ceD592A633801a8b" }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { - "name": "ChainLink Token", + "name": "Chainlink", "symbol": "LINK", "decimals": 18, "exchange_address": "0xF173214C720f58E03e194085B1DB28B50aCDeeaD" }, "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { - "name": "LoopringCoin V2", + "name": "Loopring", "symbol": "LRC", "decimals": 18, "exchange_address": "0xA539BAaa3aCA455c986bB1E25301CEF936CE1B65" }, "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { - "name": "HoloToken", + "name": "Holo", "symbol": "HOT", "decimals": 18, "exchange_address": "0xd4777E164c6C683E10593E08760B803D58529a8E" }, - "0xD29F0b5b3F50b07Fe9a9511F7d86F4f4bAc3f8c4": { - "name": "Liquidity.Network Token", - "symbol": "LQD", - "decimals": 18, - "exchange_address": "0xe3406e7D0155E0a83236eC25D34Cd3D903036669" - }, "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { "name": "LoomToken", "symbol": "LOOM", @@ -146,29 +126,23 @@ "exchange_address": "0x417CB32bc991fBbDCaE230C7c4771CC0D69daA6b" }, "0x58b6A8A3302369DAEc383334672404Ee733aB239": { - "name": "Livepeer Token", + "name": "Livepeer", "symbol": "LPT", "decimals": 18, "exchange_address": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" }, "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { - "name": "Decentraland MANA", + "name": "Decentraland", "symbol": "MANA", "decimals": 18, "exchange_address": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" }, "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { - "name": "Matic Token", + "name": "Matic Network", "symbol": "MATIC", "decimals": 18, "exchange_address": "0x9a7A75E66B325a3BD46973B2b57c9b8d9D26a621" }, - "0x80f222a749a2e18Eb7f676D371F19ad7EFEEe3b7": { - "name": "Magnolia Token", - "symbol": "MGN", - "decimals": 18, - "exchange_address": "0xdd80Ca8062c7Ef90FcA2547E6a2A126C596e611F" - }, "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { "name": "Maker", "symbol": "MKR", @@ -176,17 +150,11 @@ "exchange_address": "0x2C4Bd064b998838076fa341A83d007FC2FA50957" }, "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { - "name": "Melon Token", + "name": "Melon", "symbol": "MLN", "decimals": 18, "exchange_address": "0xA931F4eB165AC307fD7431b5EC6eADde53E14b0C" }, - "0x957c30aB0426e0C93CD8241E2c60392d08c6aC8e": { - "name": "Modum Token", - "symbol": "MOD", - "decimals": 0, - "exchange_address": "0xCCB98654CD486216fFF273dd025246588E77cFC1" - }, "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206": { "name": "Nexo", "symbol": "NEXO", @@ -200,55 +168,43 @@ "exchange_address": "0x2Bf5A5bA29E60682fC56B2Fcf9cE07Bef4F6196f" }, "0x8E870D67F660D95d5be530380D0eC0bd388289E1": { - "name": "PAX", + "name": "Paxos Standard", "symbol": "PAX", "decimals": 18, "exchange_address": "0xC040d51b07Aea5d94a89Bc21E8078B77366Fc6C7" }, "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { - "name": "Pinakion", + "name": "Kleros", "symbol": "PNK", "decimals": 18, "exchange_address": "0xF506828B166de88cA2EDb2A98D960aBba0D2402A" }, "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { - "name": "POA ERC20 on Foundation", + "name": "POA Network", "symbol": "POA20", "decimals": 18, "exchange_address": "0xA2E6B3EF205FeAEe475937c4883b24E6eB717eeF" }, - "0x687BfC3E73f6af55F0CccA8450114D107E781a0e": { - "name": "QChi", - "symbol": "QCH", - "decimals": 18, - "exchange_address": "0x755899F0540c3548b99E68C59AdB0f15d2695188" - }, "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6": { - "name": "Raiden Token", + "name": "Raiden", "symbol": "RDN", "decimals": 18, "exchange_address": "0x7D03CeCb36820b4666F45E1b4cA2538724Db271C" }, "0x408e41876cCCDC0F92210600ef50372656052a38": { - "name": "Republic Token", + "name": "Republic", "symbol": "REN", "decimals": 18, "exchange_address": "0x43892992B0b102459E895B88601Bb2C76736942c" }, "0x1985365e9f78359a9B6AD760e32412f4a445E862": { - "name": "Reputation", + "name": "Augur", "symbol": "REP", "decimals": 18, "exchange_address": "0x48B04d2A05B6B604d8d5223Fd1984f191DED51af" }, - "0x168296bb09e24A88805CB9c33356536B980D3fC5": { - "name": "RHOC", - "symbol": "RHOC", - "decimals": 8, - "exchange_address": "0x394e524b47A3AB3D3327f7fF6629dC378c1494a3" - }, "0x607F4C5BB672230e8672085532f7e901544a7375": { - "name": "iEx.ec Network Token", + "name": "iExec", "symbol": "RLC", "decimals": 9, "exchange_address": "0xA825CAE02B310E9901b4776806CE25db520c8642" @@ -260,49 +216,49 @@ "exchange_address": "0x3Fb2F18065926DdB33E7571475c509541d15dA0e" }, "0x4156D3342D5c385a87D264F90653733592000581": { - "name": "Salt", + "name": "SALT", "symbol": "SALT", "decimals": 8, "exchange_address": "0xC0C59cDe851bfcbdddD3377EC10ea54A18Efb937" }, "0x42456D7084eacF4083f1140d3229471bbA2949A8": { - "name": "Synth sETH", + "name": "Synthetix ETH", "symbol": "sETH", "decimals": 18, "exchange_address": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" }, "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E": { - "name": "Status Network Token", + "name": "Status", "symbol": "SNT", "decimals": 18, "exchange_address": "0x1aEC8F11A7E78dC22477e91Ed924Fab46e3A88Fd" }, "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { - "name": "Synthetix Network Token", + "name": "Synthetix", "symbol": "SNX", "decimals": 18, "exchange_address": "0x9fAA0Cb10912DE7Ad1D86705C65de291a9088A61" }, "0x42d6622deCe394b54999Fbd73D108123806f6a18": { - "name": "SPANK", + "name": "SpankChain", "symbol": "SPANK", "decimals": 18, "exchange_address": "0x4e395304655F0796bc3bc63709DB72173b9DdF98" }, "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { - "name": "StorjToken", + "name": "Storj", "symbol": "STORJ", "decimals": 8, "exchange_address": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" }, "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { - "name": "Synth sUSD", + "name": "Synthetix USD", "symbol": "sUSD", "decimals": 18, "exchange_address": "0xA1ECDcca26150cF69090280eE2EE32347C238c7b" }, "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { - "name": "Monolith TKN", + "name": "Monolith", "symbol": "TKN", "decimals": 8, "exchange_address": "0xb6cFBf322db47D39331E306005DC7E5e6549942B" @@ -320,19 +276,13 @@ "exchange_address": "0x601c32E0580D3aef9437dB52D09f5a5D7E60eC22" }, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": { - "name": "USD//C", + "name": "USD Coin", "symbol": "USDC", "decimals": 6, "exchange_address": "0x97deC872013f6B5fB443861090ad931542878126" }, - "0x8f3470A7388c05eE4e7AF3d01D8C722b0FF52374": { - "name": "Veritaseum", - "symbol": "VERI", - "decimals": 18, - "exchange_address": "0x17e5BF07D696eaf0d14caA4B44ff8A1E17B34de3" - }, "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": { - "name": "Wrapped BTC", + "name": "Wrapped Bitcoin", "symbol": "WBTC", "decimals": 8, "exchange_address": "0x4d2f5cFbA55AE412221182D8475bC85799A5644b" @@ -356,7 +306,7 @@ "exchange_address": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" }, "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { - "name": "0x Protocol Token", + "name": "0x", "symbol": "ZRX", "decimals": 18, "exchange_address": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" From 37323a81b0ba62844985eca4a7c6722154d69cc8 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 13 Aug 2019 18:12:02 -0700 Subject: [PATCH 215/636] renaming localstorage function names for uniswap liquidity --- src/handlers/commonStorage.js | 20 ++++++++++---------- src/handlers/uniswap.js | 2 +- src/redux/uniswap.js | 16 ++++++++-------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index b5002ec3bfe..985966c9b4c 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -73,7 +73,7 @@ const getIsWalletEmptyKey = (accountAddress, network) => `iswalletempty-${accoun const getRequestsKey = (accountAddress, network) => `requests-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getTransactionsKey = (accountAddress, network) => `transactions-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniqueTokensKey = (accountAddress, network) => `uniquetokens-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; -const getUniswapKey = (accountAddress, network) => `uniswap-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; +const getUniswapLiquidityInfoKey = (accountAddress, network) => `uniswap-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniswapLiquidityKey = (accountAddress, network) => `uniswapliquidity-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; /** @@ -111,36 +111,36 @@ export const removeUniswapLiquidityTokens = (accountAddress, network) => { }; /** - * @desc get Uniswap + * @desc get Uniswap liquidity info * @param {String} [address] * @param {String} [network] * @return {Object} */ -export const getUniswap = async (accountAddress, network) => { - const uniswap = await getLocal(getUniswapKey(accountAddress, network)); +export const getUniswapLiquidityInfo = async (accountAddress, network) => { + const uniswap = await getLocal(getUniswapLiquidityInfoKey(accountAddress, network)); return uniswap ? uniswap.data : {}; }; /** - * @desc save Uniswap + * @desc save Uniswap liquidity info * @param {String} [address] * @param {String} [network] */ -export const saveUniswap = async (accountAddress, uniswap, network) => { +export const saveUniswapLiquidityInfo = async (accountAddress, uniswap, network) => { await saveLocal( - getUniswapKey(accountAddress, network), + getUniswapLiquidityInfoKey(accountAddress, network), { data: uniswap }, ); }; /** - * @desc remove Uniswap + * @desc remove Uniswap liquidity info * @param {String} [address] * @param {String} [network] * @return {Object} */ -export const removeUniswap = (accountAddress, network) => { - const key = getUniswapKey(accountAddress, network); +export const removeUniswapLiquidityInfo = (accountAddress, network) => { + const key = getUniswapLiquidityInfoKey(accountAddress, network); removeLocal(key); }; diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index dd88a61b08c..1e273901f4d 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -72,7 +72,7 @@ export const executeSwap = async (tradeDetails) => { } }; -export const getUniswapLiquidityInfo = async (accountAddress, exchangeContracts) => { +export const getLiquidityInfo = async (accountAddress, exchangeContracts) => { const promises = map(exchangeContracts, async (exchangeAddress) => { try { const ethReserveCall = web3Provider.getBalance(exchangeAddress); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index ebda6299a0f..c55dfca23c7 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -6,14 +6,14 @@ import { map, } from 'lodash'; import { - getUniswap, + getUniswapLiquidityInfo, getUniswapLiquidityTokens, - removeUniswap, + removeUniswapLiquidityInfo, removeUniswapLiquidityTokens, - saveUniswap, + saveUniswapLiquidityInfo, saveUniswapLiquidityTokens, } from '../handlers/commonStorage'; -import { getUniswapLiquidityInfo } from '../handlers/uniswap'; +import { getLiquidityInfo } from '../handlers/uniswap'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -32,7 +32,7 @@ export const uniswapLoadState = () => async (dispatch, getState) => { const { accountAddress, network } = getState().settings; dispatch({ type: UNISWAP_LOAD_REQUEST }); try { - const uniswap = await getUniswap(accountAddress, network); + const uniswap = await getUniswapLiquidityInfo(accountAddress, network); const liquidityTokens = await getUniswapLiquidityTokens(accountAddress, network); dispatch({ payload: { liquidityTokens, uniswap }, @@ -45,7 +45,7 @@ export const uniswapLoadState = () => async (dispatch, getState) => { export const uniswapClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - removeUniswap(accountAddress, network); + removeUniswapLiquidityInfo(accountAddress, network); removeUniswapLiquidityTokens(accountAddress, network); dispatch({ type: UNISWAP_CLEAR_STATE }); }; @@ -87,9 +87,9 @@ export const uniswapUpdateState = () => (dispatch, getState) => ( dispatch({ type: UNISWAP_UPDATE_REQUEST }); const exchangeContracts = map(liquidityTokens, x => get(x, 'asset.asset_code')); - return getUniswapLiquidityInfo(accountAddress, exchangeContracts) + return getLiquidityInfo(accountAddress, exchangeContracts) .then(uniswap => { - saveUniswap(accountAddress, uniswap, network); + saveUniswapLiquidityInfo(accountAddress, uniswap, network); dispatch({ payload: uniswap, type: UNISWAP_UPDATE_SUCCESS, From aa240b2c232250a25230ac3d80e4a1069519e17e Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 13 Aug 2019 18:36:31 -0700 Subject: [PATCH 216/636] get allowance to return value in units of token --- src/utils/__tests__/contract.test.js | 6 +++--- src/utils/contract.js | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/utils/__tests__/contract.test.js b/src/utils/__tests__/contract.test.js index d321f091518..a5869727120 100644 --- a/src/utils/__tests__/contract.test.js +++ b/src/utils/__tests__/contract.test.js @@ -6,7 +6,7 @@ const accountAddress = '0x1492004547FF0eFd778CC2c14E794B26B4701105'; test('getAllowanceZrx', async () => { const exchangeAddress = '0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF'; const tokenAddress = '0xe41d2489571d322189246dafa5ebde1f4699f498'; - const allowance = await getAllowance(accountAddress, tokenAddress, exchangeAddress); + const allowance = await getAllowance(accountAddress, { address: tokenAddress, decimals: 18 }, exchangeAddress); const result = greaterThan(allowance, 0); expect(result).toBeTruthy(); }); @@ -14,7 +14,7 @@ test('getAllowanceZrx', async () => { test('getAllowanceMkr', async () => { const exchangeAddress = '0x2C4Bd064b998838076fa341A83d007FC2FA50957'; const tokenAddress = '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2'; - const allowance = await getAllowance(accountAddress, tokenAddress, exchangeAddress); + const allowance = await getAllowance(accountAddress, { address: tokenAddress, decimals: 18 }, exchangeAddress); const result = greaterThan(allowance, 0); expect(result).toBeTruthy(); }); @@ -22,7 +22,7 @@ test('getAllowanceMkr', async () => { test('getAllowanceBatNotApproved', async () => { const exchangeAddress = '0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914'; const tokenAddress = '0x0d8775f648430679a709e98d2b0cb6250d2887ef'; - const allowance = await getAllowance(accountAddress, tokenAddress, exchangeAddress); + const allowance = await getAllowance(accountAddress, { address: tokenAddress, decimals: 18 }, exchangeAddress); const result = greaterThan(allowance, 0); expect(result).toBeFalsy(); }); diff --git a/src/utils/contract.js b/src/utils/contract.js index 4cbfeab3cc2..c4b780affa7 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -1,12 +1,15 @@ import { ethers } from 'ethers'; import { web3Provider } from '../handlers/web3'; +import { convertRawAmountToDecimalFormat } from '../helpers/utilities'; import { loadWallet } from '../model/wallet'; import erc20ABI from '../references/erc20-abi.json'; -export const getAllowance = async (owner, tokenAddress, spender) => { +export const getAllowance = async (owner, token, spender) => { + const { address: tokenAddress, decimals } = token; const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); const allowance = await tokenContract.allowance(owner, spender); - return ethers.utils.bigNumberify(allowance.toString()); + const rawAllowance = ethers.utils.bigNumberify(allowance.toString()); + return convertRawAmountToDecimalFormat(rawAllowance, decimals); }; export const approve = async (tokenAddress, spender) => { From 031535bfb2dc420b7fcbac99a3f9b5241d95ee87 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 15 Aug 2019 09:36:23 -0700 Subject: [PATCH 217/636] common storage and redux and hoc for uniswap allowances --- src/handlers/commonStorage.js | 35 ++++++++++++++++++++++++++++++++ src/hoc/index.js | 1 + src/hoc/withUniswapAllowances.js | 9 ++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/hoc/withUniswapAllowances.js diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 985966c9b4c..a8e69836a2b 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -73,9 +73,44 @@ const getIsWalletEmptyKey = (accountAddress, network) => `iswalletempty-${accoun const getRequestsKey = (accountAddress, network) => `requests-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getTransactionsKey = (accountAddress, network) => `transactions-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniqueTokensKey = (accountAddress, network) => `uniquetokens-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; +const getUniswapAllowancesKey = (accountAddress, network) => `uniswapallowances-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniswapLiquidityInfoKey = (accountAddress, network) => `uniswap-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniswapLiquidityKey = (accountAddress, network) => `uniswapliquidity-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; +/** + * @desc get Uniswap allowances + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const getUniswapAllowances = async (accountAddress, network) => { + const allowances = await getLocal(getUniswapAllowancesKey(accountAddress, network)); + return allowances ? allowances.data : {}; +}; + +/** + * @desc save Uniswap allowances + * @param {String} [address] + * @param {String} [network] + */ +export const saveUniswapAllowances = async (accountAddress, allowances, network) => { + await saveLocal( + getUniswapAllowancesKey(accountAddress, network), + { data: allowances }, + ); +}; + +/** + * @desc remove Uniswap allowances + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeUniswapAllowances = (accountAddress, network) => { + const key = getUniswapAllowancesKey(accountAddress, network); + removeLocal(key); +}; + /** * @desc get Uniswap liquidity tokens * @param {String} [address] diff --git a/src/hoc/index.js b/src/hoc/index.js index 91c706e595d..3693e605ee4 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -30,6 +30,7 @@ export { default as withStatusBarStyle } from './withStatusBarStyle'; export { default as withTransactionConfirmationScreen } from './withTransactionConfirmationScreen'; export { default as withTransitionProps } from './withTransitionProps'; export { default as withUniqueTokens } from './withUniqueTokens'; +export { default as withUniswapAllowances } from './withUniswapAllowances'; export { default as withUniswapAssets } from './withUniswapAssets'; export { default as withUniswapLiquidity, readableUniswapSelector } from './withUniswapLiquidity'; export { default as withWalletConnectConfirmationModal } from './withWalletConnectConfirmationModal'; diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js new file mode 100644 index 00000000000..8c36e527547 --- /dev/null +++ b/src/hoc/withUniswapAllowances.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import { compose } from 'recompose'; +import { uniswapUpdateAllowances } from '../redux/uniswap'; + +const mapStateToProps = ({ uniswap: { allowances } }) => ({ allowances }); + +export default Component => compose( + connect(mapStateToProps, { uniswapUpdateAllowances }), +)(Component); From 3e7735a01e3fcf90ea1ff77a26ec6dba4ae7a9b9 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 15 Aug 2019 09:55:15 -0700 Subject: [PATCH 218/636] catching up with latest mike-swap-ui changes --- ios/Podfile.lock | 83 ++++++++++++++++++++------- ios/Rainbow.xcodeproj/project.pbxproj | 19 ++++++ src/hoc/withUniswapAllowances.js | 26 ++++++++- src/redux/uniswap.js | 24 +++++++- src/screens/ExchangeModal.js | 13 ++++- yarn.lock | 21 +++++++ 6 files changed, 162 insertions(+), 24 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1fc9cb9db4c..8f19c65d440 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Analytics (3.7.0) + - Analytics (3.6.10) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React @@ -40,25 +40,41 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - GoogleToolboxForMac/Defines (2.2.1) - - GoogleToolboxForMac/Logger (2.2.1): - - GoogleToolboxForMac/Defines (= 2.2.1) - - "GoogleToolboxForMac/NSData+zlib (2.2.1)": - - GoogleToolboxForMac/Defines (= 2.2.1) - - libwebp (1.0.3): - - libwebp/demux (= 1.0.3) - - libwebp/mux (= 1.0.3) - - libwebp/webp (= 1.0.3) - - libwebp/demux (1.0.3): + - GoogleToolboxForMac/Defines (2.2.0) + - GoogleToolboxForMac/Logger (2.2.0): + - GoogleToolboxForMac/Defines (= 2.2.0) + - "GoogleToolboxForMac/NSData+zlib (2.2.0)": + - GoogleToolboxForMac/Defines (= 2.2.0) + - libwebp (1.0.2): + - libwebp/core (= 1.0.2) + - libwebp/dec (= 1.0.2) + - libwebp/demux (= 1.0.2) + - libwebp/dsp (= 1.0.2) + - libwebp/enc (= 1.0.2) + - libwebp/mux (= 1.0.2) + - libwebp/utils (= 1.0.2) + - libwebp/webp (= 1.0.2) + - libwebp/core (1.0.2): - libwebp/webp - - libwebp/mux (1.0.3): - - libwebp/demux - - libwebp/webp (1.0.3) + - libwebp/dec (1.0.2): + - libwebp/core + - libwebp/demux (1.0.2): + - libwebp/core + - libwebp/dsp (1.0.2): + - libwebp/core + - libwebp/enc (1.0.2): + - libwebp/core + - libwebp/mux (1.0.2): + - libwebp/core + - libwebp/utils (1.0.2): + - libwebp/core + - libwebp/webp (1.0.2) - nanopb (0.3.901): - nanopb/decode (= 0.3.901) - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) +<<<<<<< HEAD - Protobuf (3.9.0) - React (0.60.5): - React-Core (= 0.60.5) @@ -105,6 +121,11 @@ PODS: - React-cxxreact (= 0.60.5) - React-jsi (= 0.60.5) - React-jsinspector (0.60.5) +======= + - Protobuf (3.7.0) + - React (0.59.9): + - React/Core (= 0.59.9) +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -164,10 +185,17 @@ PODS: - React - RNStoreReview (0.1.5): - React +<<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) - SDWebImage/Core (5.1.1) - yoga (0.60.5.React) +======= + - SDWebImage (5.0.2): + - SDWebImage/Core (= 5.0.2) + - SDWebImage/Core (5.0.2) + - yoga (0.59.9.React) +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -306,18 +334,19 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 + Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa - FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 - FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 - FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 - FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb + Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 + FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d + FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 + FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 + FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 +<<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 @@ -331,6 +360,15 @@ SPEC CHECKSUMS: React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 +======= + Folly: de497beb10f102453a1afa9edbf8cf8a251890de + glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d + GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d + libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a + React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 @@ -355,8 +393,13 @@ SPEC CHECKSUMS: RNReanimated: da57ffa32f04cebe2107da0b281999a01c0d1ecc RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 +<<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 +======= + SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 + yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index f66651a3861..395b09d997d 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -745,6 +745,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2440303322D6D5F70045D406 /* InputMask.framework in Frameworks */, + 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, + 387F40C9BD694ED8854578EC /* libRNTextInputMask.a in Frameworks */, ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */, 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */, @@ -2294,6 +2297,10 @@ ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -2349,6 +2356,10 @@ ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -2439,6 +2450,10 @@ ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -2575,6 +2590,10 @@ ); INFOPLIST_FILE = Rainbow/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 8c36e527547..8f9f8facbb0 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -1,9 +1,31 @@ +import { isNil } from 'lodash'; import { connect } from 'react-redux'; -import { compose } from 'recompose'; +import { compose, withHandlers } from 'recompact'; import { uniswapUpdateAllowances } from '../redux/uniswap'; +import { getAllowance } from '../utils/contract'; -const mapStateToProps = ({ uniswap: { allowances } }) => ({ allowances }); +const mapStateToProps = ({ + settings: { accountAddress }, + uniswap: { allowances }, +}) => ({ accountAddress, allowances }); export default Component => compose( connect(mapStateToProps, { uniswapUpdateAllowances }), + withHandlers({ + getCurrencyAllowance: (ownProps) => async (token, exchangeAddress, inputAmount) => { + /* + // if input amount + const result = ownProps.allowances[token.address]; + if (!isNil(result)) { + if (greaterThan(result, 0)) { + // TODO + } else { + } + } else { + const allowance = await getAllowance(ownProps.accountAddress, token, exchangeAddress); + ownProps.uniswapUpdateAllowances(token.address, allowance); + } + */ + }, + }), )(Component); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index c55dfca23c7..bb1f99283e6 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -6,10 +6,13 @@ import { map, } from 'lodash'; import { + getUniswapAllowances, getUniswapLiquidityInfo, getUniswapLiquidityTokens, + removeUniswapAllowances, removeUniswapLiquidityInfo, removeUniswapLiquidityTokens, + saveUniswapAllowances, saveUniswapLiquidityInfo, saveUniswapLiquidityTokens, } from '../handlers/commonStorage'; @@ -24,6 +27,7 @@ const UNISWAP_UPDATE_REQUEST = 'uniswap/UNISWAP_UPDATE_REQUEST'; const UNISWAP_UPDATE_SUCCESS = 'uniswap/UNISWAP_UPDATE_SUCCESS'; const UNISWAP_UPDATE_FAILURE = 'uniswap/UNISWAP_UPDATE_FAILURE'; +const UNISWAP_UPDATE_ALLOWANCES = 'uniswap/UNISWAP_UPDATE_ALLOWANCES'; const UNISWAP_UPDATE_LIQUIDITY_TOKENS = 'uniswap/UNISWAP_UPDATE_LIQUIDITY_TOKENS'; const UNISWAP_CLEAR_STATE = 'uniswap/UNISWAP_CLEAR_STATE'; @@ -34,8 +38,9 @@ export const uniswapLoadState = () => async (dispatch, getState) => { try { const uniswap = await getUniswapLiquidityInfo(accountAddress, network); const liquidityTokens = await getUniswapLiquidityTokens(accountAddress, network); + const allowances = await getUniswapAllowances(accountAddress, network); dispatch({ - payload: { liquidityTokens, uniswap }, + payload: { allowances, liquidityTokens, uniswap }, type: UNISWAP_LOAD_SUCCESS, }); } catch (error) { @@ -45,11 +50,23 @@ export const uniswapLoadState = () => async (dispatch, getState) => { export const uniswapClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; + removeUniswapAllowances(accountAddress, network); removeUniswapLiquidityInfo(accountAddress, network); removeUniswapLiquidityTokens(accountAddress, network); dispatch({ type: UNISWAP_CLEAR_STATE }); }; +export const uniswapUpdateAllowances = (tokenAddress, allowance) => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + const { allowances } = getState().uniswap; + const updatedAllowances = { ...allowances, [tokenAddress]: allowance }; + dispatch({ + payload: updatedAllowances, + type: UNISWAP_UPDATE_ALLOWANCES, + }); + saveUniswapAllowances(accountAddress, updatedAllowances, network); +}; + export const uniswapUpdateLiquidityTokens = (liquidityTokens) => (dispatch, getState) => { if (isEmpty(liquidityTokens)) return; const { accountAddress, network } = getState().settings; @@ -105,6 +122,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => ( // -- Reducer --------------------------------------------------------------- // export const INITIAL_UNISWAP_STATE = { + allowances: {}, fetchingUniswap: false, liquidityTokens: [], loadingUniswap: false, @@ -118,6 +136,7 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = break; case UNISWAP_LOAD_SUCCESS: draft.loadingUniswap = false; + draft.allowances = action.payload.allowances; draft.uniswap = action.payload.uniswap; draft.liquidityTokens = action.payload.liquidityTokens; break; @@ -137,6 +156,9 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = case UNISWAP_UPDATE_LIQUIDITY_TOKENS: draft.liquidityTokens = action.payload; break; + case UNISWAP_UPDATE_ALLOWANCES: + draft.allowances = action.payload; + break; case UNISWAP_CLEAR_STATE: return INITIAL_UNISWAP_STATE; default: diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 1a60f7bbdef..aa2f4a8048b 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -36,6 +36,8 @@ import { withKeyboardFocusHistory, withTransactionConfirmationScreen, withTransitionProps, + withUniswapAllowances, + withUniswapAssets, } from '../hoc'; import { colors, padding, position } from '../styles'; import { deviceUtils, ethereumUtils, safeAreaInsetValues } from '../utils'; @@ -74,9 +76,11 @@ const isSameAsset = (firstAsset, secondAsset) => { class ExchangeModal extends PureComponent { static propTypes = { allAssets: PropTypes.array, + allowances: PropTypes.object, chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, + getCurrencyAllowance: PropTypes.func, keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, navigation: PropTypes.object, @@ -85,6 +89,7 @@ class ExchangeModal extends PureComponent { } state = { + inputAllowance: null, inputAmount: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), @@ -100,6 +105,10 @@ class ExchangeModal extends PureComponent { const { isFocused, isTransitioning, keyboardFocusHistory} = this.props; const { inputAmount, outputAmount, outputCurrency } = this.state; + // TODO if inputCurrency has changed + // TODO include input amount + // this.props.getCurrencyAllowance(inputCurrency); + if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; @@ -429,13 +438,15 @@ export default compose( withNavigationFocus, withTransactionConfirmationScreen, withTransitionProps, + withUniswapAllowances, + withUniswapAssets, mapProps(({ navigation, tabsTransitionProps: { isTransitioning: isTabsTransitioning, }, stackTransitionProps: { - isTransitioning: isStacksTransitioning, + isTransitioning: isStacksTransitioning, }, ...props, }) => ({ diff --git a/yarn.lock b/yarn.lock index 4f12a685fe5..dac32e80537 100644 --- a/yarn.lock +++ b/yarn.lock @@ -996,7 +996,11 @@ dependencies: prop-types "^15.5.10" +<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": +======= +"@react-native-community/cli-platform-android@^2.8.3": +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== @@ -1009,7 +1013,11 @@ slash "^3.0.0" xmldoc "^1.1.2" +<<<<<<< HEAD "@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": +======= +"@react-native-community/cli-platform-ios@^2.8.3": +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== @@ -3195,9 +3203,15 @@ date-now@^0.1.4: integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= dayjs@^1.8.15: +<<<<<<< HEAD version "1.8.16" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== +======= + version "1.8.15" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.15.tgz#7121bc04e6a7f2621ed6db566be4a8aaf8c3913e" + integrity sha512-HYHCI1nohG52B45vCQg8Re3hNDZbMroWPkhz50yaX7Lu0ATyjGsTdoYZBpjED9ar6chqTx2dmSmM8A51mojnAg== +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes debounce@^1.2.0: version "1.2.0" @@ -3553,10 +3567,17 @@ ejs@^2.6.2: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== +<<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.259" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.259.tgz#d0b14836df3c89e86fa47be67315daa642fe9d5c" integrity sha512-NMHS8iQzAYwiFZ1jL/rNOfrZJhvoowKN5uHrbbHOeNgBT5W762wpe/SRLo9kJoTiJ4d2R8i01/NQHwndo9N5PQ== +======= +electron-to-chromium@^1.3.191: + version "1.3.229" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.229.tgz#accc9a08dd07d0a4d6c76937821bc94eb2e49eae" + integrity sha512-N6pUbSuKFBeUifxBZp9hODS1N9jFobJYW47QT2VvZIr+G5AWnHK/iG3ON9RPRGH7lHDQ6KUDVhzpNkj4ZiznoA== +>>>>>>> 730537c6... catching up with latest mike-swap-ui changes elliptic@6.3.3: version "6.3.3" From b151eb351759afe39f55e6a0ef43a3dc9636a362 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 15 Aug 2019 12:08:26 -0700 Subject: [PATCH 219/636] approvals for uniswap --- src/components/exchange/ExchangeInputField.js | 45 ++++---- src/hoc/withUniswapAllowances.js | 26 +---- src/hoc/withUniswapAssets.js | 23 ++-- src/references/uniswap-pairs.json | 104 +++++++++--------- src/screens/ExchangeModal.js | 42 +++++-- src/utils/contract.js | 4 + 6 files changed, 134 insertions(+), 110 deletions(-) diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index d9b6f09c966..8a9d2d37de3 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -26,6 +26,7 @@ export default class ExchangeInputField extends Component { nativeAmount: PropTypes.string, nativeCurrency: PropTypes.string, nativeFieldRef: PropTypes.func, + needsApproval: PropTypes.bool, onPressMaxBalance: PropTypes.func, onPressSelectInputCurrency: PropTypes.func, setInputAmount: PropTypes.func, @@ -80,6 +81,7 @@ export default class ExchangeInputField extends Component { nativeAmount, nativeCurrency, nativeFieldRef, + needsApproval, onFocus, setNativeAmount, } = this.props; @@ -172,26 +174,29 @@ export default class ExchangeInputField extends Component { {inputCurrency || 'Choose a Coin'} - - {this.renderNativeField()} - {isAssetApproved ? ( - - - - Max - - - ) : ( - - )} + + + + + {!needsApproval && } + + {needsApproval ? 'Approve' : 'Max'} + + + ); diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 8f9f8facbb0..766955bfc51 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -1,31 +1,9 @@ -import { isNil } from 'lodash'; import { connect } from 'react-redux'; -import { compose, withHandlers } from 'recompact'; +import { compose } from 'recompact'; import { uniswapUpdateAllowances } from '../redux/uniswap'; -import { getAllowance } from '../utils/contract'; -const mapStateToProps = ({ - settings: { accountAddress }, - uniswap: { allowances }, -}) => ({ accountAddress, allowances }); +const mapStateToProps = ({ uniswap: { allowances } }) => ({ allowances }); export default Component => compose( connect(mapStateToProps, { uniswapUpdateAllowances }), - withHandlers({ - getCurrencyAllowance: (ownProps) => async (token, exchangeAddress, inputAmount) => { - /* - // if input amount - const result = ownProps.allowances[token.address]; - if (!isNil(result)) { - if (greaterThan(result, 0)) { - // TODO - } else { - } - } else { - const allowance = await getAllowance(ownProps.accountAddress, token, exchangeAddress); - ownProps.uniswapUpdateAllowances(token.address, allowance); - } - */ - }, - }), )(Component); diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index c810c34e41d..60a01b721b9 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -1,7 +1,9 @@ import { filter, + get, keys, map, + mapKeys, mapValues, property, sortBy, @@ -16,17 +18,24 @@ import withAccountData from './withAccountData'; const allAssetsSelector = state => state.allAssets; const unsortedUniswapAssetsSelector = state => state.unsortedUniswapAssets; -const uniswapAssetAddresses = map(keys(uniswapAssetsRaw), toLower); +const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => toLower(key)); +const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); -const withAssetsAvailableOnUniswap = (allAssets) => ({ - assetsAvailableOnUniswap: filter(allAssets, filterUniswapAssetsByAvailability), -}); -const mapUniswapAssetItem = ({ exchange_address, ...asset }, address) => ({ +const withAssetsAvailableOnUniswap = (allAssets) => { + const availableAssets = filter(allAssets, filterUniswapAssetsByAvailability); + const assetsAvailableOnUniswap = map(availableAssets, (asset) => ({ + ...asset, + exchangeAddress: get(uniswapAssetsRawLoweredKeys, `${asset.address}.exchangeAddress`), + })); + return { assetsAvailableOnUniswap }; +}; + +const mapUniswapAssetItem = ({ exchangeAddress, ...asset }, address) => ({ ...asset, address, - exchange_address, - uniqueId: exchange_address, + exchangeAddress, + uniqueId: exchangeAddress, }); const unsortedUniswapAssets = values(mapValues(uniswapAssetsRaw, mapUniswapAssetItem)); diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index 12b52ff991b..702b1bc7eab 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -3,312 +3,312 @@ "name": "Ethereum", "symbol": "ETH", "decimals": 18, - "exchange_address": null + "exchangeAddress": null }, "0x960b236A07cf122663c4303350609A66A7B288C0": { "name": "Aragon", "symbol": "ANT", "decimals": 18, - "exchange_address": "0x077d52B047735976dfdA76feF74d4d988AC25196" + "exchangeAddress": "0x077d52B047735976dfdA76feF74d4d988AC25196" }, "0x0D8775F648430679A709E98d2b0Cb6250d2887EF": { "name": "Basic Attention Token", "symbol": "BAT", "decimals": 18, - "exchange_address": "0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914" + "exchangeAddress": "0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914" }, "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { "name": "Bloom", "symbol": "BLT", "decimals": 18, - "exchange_address": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" + "exchangeAddress": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" }, "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { "name": "Bancor", "symbol": "BNT", "decimals": 18, - "exchange_address": "0x87d80DBD37E551F58680B4217b23aF6a752DA83F" + "exchangeAddress": "0x87d80DBD37E551F58680B4217b23aF6a752DA83F" }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { "name": "Compound Dai", "symbol": "cDAI", "decimals": 8, - "exchange_address": "0x45A2FDfED7F7a2c791fb1bdF6075b83faD821ddE" + "exchangeAddress": "0x45A2FDfED7F7a2c791fb1bdF6075b83faD821ddE" }, "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { "name": "Civic", "symbol": "CVC", "decimals": 8, - "exchange_address": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" + "exchangeAddress": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" }, "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { "name": "Dai", "symbol": "DAI", "decimals": 18, - "exchange_address": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" + "exchangeAddress": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" }, "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A": { "name": "DigixDAO", "symbol": "DGD", "decimals": 9, - "exchange_address": "0xD55C1cA9F5992A2e5E379DCe49Abf24294ABe055" + "exchangeAddress": "0xD55C1cA9F5992A2e5E379DCe49Abf24294ABe055" }, "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { "name": "Digix Gold Token", "symbol": "DGX", "decimals": 9, - "exchange_address": "0xb92dE8B30584392Af27726D5ce04Ef3c4e5c9924" + "exchangeAddress": "0xb92dE8B30584392Af27726D5ce04Ef3c4e5c9924" }, "0x4946Fcea7C692606e8908002e55A582af44AC121": { "name": "FOAM", "symbol": "FOAM", "decimals": 18, - "exchange_address": "0xf79cb3BEA83BD502737586A6E8B133c378FD1fF2" + "exchangeAddress": "0xf79cb3BEA83BD502737586A6E8B133c378FD1fF2" }, "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b": { "name": "FunFair", "symbol": "FUN", "decimals": 8, - "exchange_address": "0x60a87cC7Fca7E53867facB79DA73181B1bB4238B" + "exchangeAddress": "0x60a87cC7Fca7E53867facB79DA73181B1bB4238B" }, "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { "name": "DAOstack", "symbol": "GEN", "decimals": 18, - "exchange_address": "0x26Cc0EAb6Cb650B0Db4D0d0dA8cB5BF69F4ad692" + "exchangeAddress": "0x26Cc0EAb6Cb650B0Db4D0d0dA8cB5BF69F4ad692" }, "0x6810e776880C02933D47DB1b9fc05908e5386b96": { "name": "Gnosis", "symbol": "GNO", "decimals": 18, - "exchange_address": "0xe8e45431b93215566BA923a7E611B7342Ea954DF" + "exchangeAddress": "0xe8e45431b93215566BA923a7E611B7342Ea954DF" }, "0x12B19D3e2ccc14Da04FAe33e63652ce469b3F2FD": { "name": "Grid+", "symbol": "GRID", "decimals": 12, - "exchange_address": "0x4B17685b330307C751B47f33890c8398dF4Fe407" + "exchangeAddress": "0x4B17685b330307C751B47f33890c8398dF4Fe407" }, "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { "name": "Kin", "symbol": "KIN", "decimals": 18, - "exchange_address": "0xb7520a5F8c832c573d6BD0Df955fC5c9b72400F7" + "exchangeAddress": "0xb7520a5F8c832c573d6BD0Df955fC5c9b72400F7" }, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { "name": "Kyber Network", "symbol": "KNC", "decimals": 18, - "exchange_address": "0x49c4f9bc14884f6210F28342ceD592A633801a8b" + "exchangeAddress": "0x49c4f9bc14884f6210F28342ceD592A633801a8b" }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { "name": "Chainlink", "symbol": "LINK", "decimals": 18, - "exchange_address": "0xF173214C720f58E03e194085B1DB28B50aCDeeaD" + "exchangeAddress": "0xF173214C720f58E03e194085B1DB28B50aCDeeaD" }, "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { "name": "Loopring", "symbol": "LRC", "decimals": 18, - "exchange_address": "0xA539BAaa3aCA455c986bB1E25301CEF936CE1B65" + "exchangeAddress": "0xA539BAaa3aCA455c986bB1E25301CEF936CE1B65" }, "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { "name": "Holo", "symbol": "HOT", "decimals": 18, - "exchange_address": "0xd4777E164c6C683E10593E08760B803D58529a8E" + "exchangeAddress": "0xd4777E164c6C683E10593E08760B803D58529a8E" }, "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { "name": "LoomToken", "symbol": "LOOM", "decimals": 18, - "exchange_address": "0x417CB32bc991fBbDCaE230C7c4771CC0D69daA6b" + "exchangeAddress": "0x417CB32bc991fBbDCaE230C7c4771CC0D69daA6b" }, "0x58b6A8A3302369DAEc383334672404Ee733aB239": { "name": "Livepeer", "symbol": "LPT", "decimals": 18, - "exchange_address": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" + "exchangeAddress": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" }, "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { "name": "Decentraland", "symbol": "MANA", "decimals": 18, - "exchange_address": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" + "exchangeAddress": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" }, "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { "name": "Matic Network", "symbol": "MATIC", "decimals": 18, - "exchange_address": "0x9a7A75E66B325a3BD46973B2b57c9b8d9D26a621" + "exchangeAddress": "0x9a7A75E66B325a3BD46973B2b57c9b8d9D26a621" }, "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { "name": "Maker", "symbol": "MKR", "decimals": 18, - "exchange_address": "0x2C4Bd064b998838076fa341A83d007FC2FA50957" + "exchangeAddress": "0x2C4Bd064b998838076fa341A83d007FC2FA50957" }, "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { "name": "Melon", "symbol": "MLN", "decimals": 18, - "exchange_address": "0xA931F4eB165AC307fD7431b5EC6eADde53E14b0C" + "exchangeAddress": "0xA931F4eB165AC307fD7431b5EC6eADde53E14b0C" }, "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206": { "name": "Nexo", "symbol": "NEXO", "decimals": 18, - "exchange_address": "0x069C97DBA948175D10af4b2414969e0B88d44669" + "exchangeAddress": "0x069C97DBA948175D10af4b2414969e0B88d44669" }, "0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671": { "name": "Numeraire", "symbol": "NMR", "decimals": 18, - "exchange_address": "0x2Bf5A5bA29E60682fC56B2Fcf9cE07Bef4F6196f" + "exchangeAddress": "0x2Bf5A5bA29E60682fC56B2Fcf9cE07Bef4F6196f" }, "0x8E870D67F660D95d5be530380D0eC0bd388289E1": { "name": "Paxos Standard", "symbol": "PAX", "decimals": 18, - "exchange_address": "0xC040d51b07Aea5d94a89Bc21E8078B77366Fc6C7" + "exchangeAddress": "0xC040d51b07Aea5d94a89Bc21E8078B77366Fc6C7" }, "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { "name": "Kleros", "symbol": "PNK", "decimals": 18, - "exchange_address": "0xF506828B166de88cA2EDb2A98D960aBba0D2402A" + "exchangeAddress": "0xF506828B166de88cA2EDb2A98D960aBba0D2402A" }, "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { "name": "POA Network", "symbol": "POA20", "decimals": 18, - "exchange_address": "0xA2E6B3EF205FeAEe475937c4883b24E6eB717eeF" + "exchangeAddress": "0xA2E6B3EF205FeAEe475937c4883b24E6eB717eeF" }, "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6": { "name": "Raiden", "symbol": "RDN", "decimals": 18, - "exchange_address": "0x7D03CeCb36820b4666F45E1b4cA2538724Db271C" + "exchangeAddress": "0x7D03CeCb36820b4666F45E1b4cA2538724Db271C" }, "0x408e41876cCCDC0F92210600ef50372656052a38": { "name": "Republic", "symbol": "REN", "decimals": 18, - "exchange_address": "0x43892992B0b102459E895B88601Bb2C76736942c" + "exchangeAddress": "0x43892992B0b102459E895B88601Bb2C76736942c" }, "0x1985365e9f78359a9B6AD760e32412f4a445E862": { "name": "Augur", "symbol": "REP", "decimals": 18, - "exchange_address": "0x48B04d2A05B6B604d8d5223Fd1984f191DED51af" + "exchangeAddress": "0x48B04d2A05B6B604d8d5223Fd1984f191DED51af" }, "0x607F4C5BB672230e8672085532f7e901544a7375": { "name": "iExec", "symbol": "RLC", "decimals": 9, - "exchange_address": "0xA825CAE02B310E9901b4776806CE25db520c8642" + "exchangeAddress": "0xA825CAE02B310E9901b4776806CE25db520c8642" }, "0xB4EFd85c19999D84251304bDA99E90B92300Bd93": { "name": "Rocket Pool", "symbol": "RPL", "decimals": 18, - "exchange_address": "0x3Fb2F18065926DdB33E7571475c509541d15dA0e" + "exchangeAddress": "0x3Fb2F18065926DdB33E7571475c509541d15dA0e" }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT", "symbol": "SALT", "decimals": 8, - "exchange_address": "0xC0C59cDe851bfcbdddD3377EC10ea54A18Efb937" + "exchangeAddress": "0xC0C59cDe851bfcbdddD3377EC10ea54A18Efb937" }, "0x42456D7084eacF4083f1140d3229471bbA2949A8": { "name": "Synthetix ETH", "symbol": "sETH", "decimals": 18, - "exchange_address": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" + "exchangeAddress": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" }, "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E": { "name": "Status", "symbol": "SNT", "decimals": 18, - "exchange_address": "0x1aEC8F11A7E78dC22477e91Ed924Fab46e3A88Fd" + "exchangeAddress": "0x1aEC8F11A7E78dC22477e91Ed924Fab46e3A88Fd" }, "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { "name": "Synthetix", "symbol": "SNX", "decimals": 18, - "exchange_address": "0x9fAA0Cb10912DE7Ad1D86705C65de291a9088A61" + "exchangeAddress": "0x9fAA0Cb10912DE7Ad1D86705C65de291a9088A61" }, "0x42d6622deCe394b54999Fbd73D108123806f6a18": { "name": "SpankChain", "symbol": "SPANK", "decimals": 18, - "exchange_address": "0x4e395304655F0796bc3bc63709DB72173b9DdF98" + "exchangeAddress": "0x4e395304655F0796bc3bc63709DB72173b9DdF98" }, "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { "name": "Storj", "symbol": "STORJ", "decimals": 8, - "exchange_address": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" + "exchangeAddress": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" }, "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { "name": "Synthetix USD", "symbol": "sUSD", "decimals": 18, - "exchange_address": "0xA1ECDcca26150cF69090280eE2EE32347C238c7b" + "exchangeAddress": "0xA1ECDcca26150cF69090280eE2EE32347C238c7b" }, "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { "name": "Monolith", "symbol": "TKN", "decimals": 8, - "exchange_address": "0xb6cFBf322db47D39331E306005DC7E5e6549942B" + "exchangeAddress": "0xb6cFBf322db47D39331E306005DC7E5e6549942B" }, "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E": { "name": "TrueUSD", "symbol": "TUSD", "decimals": 18, - "exchange_address": "0x4F30E682D0541eAC91748bd38A648d759261b8f3" + "exchangeAddress": "0x4F30E682D0541eAC91748bd38A648d759261b8f3" }, "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { "name": "Uniswap V1", "symbol": "UNI-V1:DAI", "decimals": 18, - "exchange_address": "0x601c32E0580D3aef9437dB52D09f5a5D7E60eC22" + "exchangeAddress": "0x601c32E0580D3aef9437dB52D09f5a5D7E60eC22" }, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": { "name": "USD Coin", "symbol": "USDC", "decimals": 6, - "exchange_address": "0x97deC872013f6B5fB443861090ad931542878126" + "exchangeAddress": "0x97deC872013f6B5fB443861090ad931542878126" }, "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": { "name": "Wrapped Bitcoin", "symbol": "WBTC", "decimals": 8, - "exchange_address": "0x4d2f5cFbA55AE412221182D8475bC85799A5644b" + "exchangeAddress": "0x4d2f5cFbA55AE412221182D8475bC85799A5644b" }, "0x09fE5f0236F0Ea5D930197DCE254d77B04128075": { "name": "Wrapped CryptoKitties", "symbol": "WCK", "decimals": 18, - "exchange_address": "0x4FF7Fa493559c40aBd6D157a0bfC35Df68d8D0aC" + "exchangeAddress": "0x4FF7Fa493559c40aBd6D157a0bfC35Df68d8D0aC" }, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": { "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, - "exchange_address": "0xA2881A90Bf33F03E7a3f803765Cd2ED5c8928dFb" + "exchangeAddress": "0xA2881A90Bf33F03E7a3f803765Cd2ED5c8928dFb" }, "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { "name": "CryptoFranc", "symbol": "XCHF", "decimals": 18, - "exchange_address": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" + "exchangeAddress": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" }, "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { "name": "0x", "symbol": "ZRX", "decimals": 18, - "exchange_address": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" + "exchangeAddress": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" } } diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index aa2f4a8048b..76be97e5408 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -26,6 +26,7 @@ import { convertAmountToNativeAmount, convertAmountToRawAmount, convertRawAmountToDecimalFormat, + greaterThan, subtract, } from '../helpers/utilities'; import { @@ -40,7 +41,12 @@ import { withUniswapAssets, } from '../hoc'; import { colors, padding, position } from '../styles'; -import { deviceUtils, ethereumUtils, safeAreaInsetValues } from '../utils'; +import { + contractUtils, + deviceUtils, + ethereumUtils, + safeAreaInsetValues, +} from '../utils'; import { ConfirmExchangeButton, ExchangeGasFeeButton, @@ -75,17 +81,18 @@ const isSameAsset = (firstAsset, secondAsset) => { class ExchangeModal extends PureComponent { static propTypes = { + accountAddress: PropTypes.string, allAssets: PropTypes.array, allowances: PropTypes.object, chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, - getCurrencyAllowance: PropTypes.func, keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, tradeDetails: PropTypes.object, + uniswapUpdateAllowances: PropTypes.func, } state = { @@ -94,6 +101,7 @@ class ExchangeModal extends PureComponent { inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), nativeAmount: null, + needsApproval: false, outputAmount: null, outputCurrency: null, showConfirmButton: false, @@ -101,14 +109,10 @@ class ExchangeModal extends PureComponent { tradeDetails: null, } - componentDidUpdate = (prevProps) => { + componentDidUpdate = (prevProps, prevState) => { const { isFocused, isTransitioning, keyboardFocusHistory} = this.props; const { inputAmount, outputAmount, outputCurrency } = this.state; - // TODO if inputCurrency has changed - // TODO include input amount - // this.props.getCurrencyAllowance(inputCurrency); - if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; @@ -130,6 +134,10 @@ class ExchangeModal extends PureComponent { console.log('should showConfirmButton'); this.setState({ showConfirmButton: true }); } + + if (this.state.inputCurrency.address !== prevState.inputCurrency.address) { + this.getCurrencyAllowance(); + } } componentWillUnmount = () => { @@ -149,6 +157,24 @@ class ExchangeModal extends PureComponent { return { rawUpdatedValue, slippage: slippage.toFixed() }; }; + getCurrencyAllowance = async () => { + const { accountAddress, allowances, uniswapUpdateAllowances } = this.props; + const { inputCurrency } = this.state; + if (inputCurrency.address === 'eth') { + this.setState({ needsApproval: false }); + return; + } + const allowance = allowances[inputCurrency.address]; + if (isNil(allowance)) { + this.setState({ needsApproval: true }); + } else { + this.setState({ needsApproval: !greaterThan(allowance, 0) }); + } + const newAllowance = await contractUtils.getAllowance(accountAddress, inputCurrency, inputCurrency.exchangeAddress); + uniswapUpdateAllowances(inputCurrency.address, newAllowance); + this.setState({ needsApproval: !greaterThan(newAllowance, 0) }); + }; + getMarketDetails = async () => { try { let tradeDetails = null; @@ -345,6 +371,7 @@ class ExchangeModal extends PureComponent { inputAmount, inputCurrency, nativeAmount, + needsApproval, outputAmount, outputCurrency, showConfirmButton, @@ -382,6 +409,7 @@ class ExchangeModal extends PureComponent { nativeAmount={nativeAmount} nativeCurrency={nativeCurrency} nativeFieldRef={this.handleNativeFieldRef} + needsApproval={needsApproval} onFocus={this.handleFocusField} onPressMaxBalance={this.onPressMaxBalance} onPressSelectInputCurrency={this.handleSelectInputCurrency} diff --git a/src/utils/contract.js b/src/utils/contract.js index c4b780affa7..0fc123e6fff 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -20,3 +20,7 @@ export const approve = async (tokenAddress, spender) => { return exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); }; +export default { + approve, + getAllowance, +}; From aed8da9574bf0cd09500d6ab121f8c284a97cffb Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 19 Aug 2019 14:03:34 -0700 Subject: [PATCH 220/636] setup for token reserves --- src/handlers/commonStorage.js | 35 +++++++++++++++++++ src/handlers/uniswap.js | 22 ++++++++++-- src/hoc/withDataInit.js | 15 ++++---- src/hoc/withUniswapAssets.js | 3 +- src/redux/uniswap.js | 58 +++++++++++++++++++++++++++++-- src/references/uniswap-pairs.json | 6 ---- src/utils/index.js | 1 + src/utils/promise.js | 11 ++++++ 8 files changed, 130 insertions(+), 21 deletions(-) create mode 100644 src/utils/promise.js diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index a8e69836a2b..681fdf05ad5 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -76,6 +76,7 @@ const getUniqueTokensKey = (accountAddress, network) => `uniquetokens-${accountA const getUniswapAllowancesKey = (accountAddress, network) => `uniswapallowances-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniswapLiquidityInfoKey = (accountAddress, network) => `uniswap-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; const getUniswapLiquidityKey = (accountAddress, network) => `uniswapliquidity-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; +const getUniswapTokenReservesKey = (accountAddress, network) => `uniswapreserves-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; /** * @desc get Uniswap allowances @@ -111,6 +112,40 @@ export const removeUniswapAllowances = (accountAddress, network) => { removeLocal(key); }; +/** + * @desc get Uniswap token reserves + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const getUniswapTokenReserves = async (accountAddress, network) => { + const reserves = await getLocal(getUniswapTokenReservesKey(accountAddress, network)); + return reserves ? reserves.data : {}; +}; + +/** + * @desc save Uniswap token reserves + * @param {String} [address] + * @param {String} [network] + */ +export const saveUniswapTokenReserves = async (accountAddress, reserves, network) => { + await saveLocal( + getUniswapTokenReservesKey(accountAddress, network), + { data: reserves }, + ); +}; + +/** + * @desc remove Uniswap token reserves + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeUniswapTokenReserves = (accountAddress, network) => { + const key = getUniswapTokenReservesKey(accountAddress, network); + removeLocal(key); +}; + /** * @desc get Uniswap liquidity tokens * @param {String} [address] diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 1e273901f4d..5fe4864feec 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -1,16 +1,25 @@ -import { getExecutionDetails } from '@uniswap/sdk'; +import { getExecutionDetails, getTokenReserves } from '@uniswap/sdk'; import contractMap from 'eth-contract-metadata'; import { ethers } from 'ethers'; -import { get, map, zipObject } from 'lodash'; +import { + compact, + get, + keyBy, + map, + slice, + zipObject, +} from 'lodash'; import { convertRawAmountToDecimalFormat, divide, fromWei, multiply, } from '../helpers/utilities'; +import { uniswapAssetAddresses } from '../hoc/withUniswapAssets'; import { loadWallet } from '../model/wallet'; import exchangeABI from '../references/uniswap-exchange-abi.json'; import erc20ABI from '../references/erc20-abi.json'; +import { promiseUtils } from '../utils'; import { web3Provider } from './web3'; const convertArgsForEthers = (methodArguments) => methodArguments.map(arg => (typeof arg === 'object') ? ethers.utils.bigNumberify(arg.toFixed()) : arg); @@ -20,6 +29,15 @@ const convertValueForEthers = (value) => { return ethers.utils.hexlify(valueBigNumber); }; +export const getReserves = async () => { + const uniswapTokens = slice(uniswapAssetAddresses, 1); + const reserves = await promiseUtils.PromiseAllWithFails(map(uniswapTokens, (token) => getTokenReserves(token))); + return keyBy(compact(reserves), reserve => { + const address = get(reserve, 'token.address') || ''; + return address.toLowerCase(); + }); +}; + export const executeSwap = async (tradeDetails) => { const executionDetails = getExecutionDetails(tradeDetails); const wallet = await loadWallet(); diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 353db8c723d..c570154de80 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -25,6 +25,7 @@ import { import { uniswapLoadState, uniswapClearState, + uniswapTokenReservesRefreshState, uniswapUpdateState, } from '../redux/uniswap'; import { @@ -37,15 +38,9 @@ import { walletConnectLoadState, walletConnectClearState, } from '../redux/walletconnect'; +import { promiseUtils } from '../utils'; import withHideSplashScreen from './withHideSplashScreen'; -const PromiseAllWithFails = async (promises) => ( - Promise.all(promises.map(promise => ( - (promise && promise.catch) - ? promise.catch(error => error) - : promise - )))); - export default Component => compose( connect(null, { clearIsWalletEmpty, @@ -64,6 +59,7 @@ export default Component => compose( uniqueTokensRefreshState, uniswapClearState, uniswapLoadState, + uniswapTokenReservesRefreshState, uniswapUpdateState, walletConnectClearState, walletConnectLoadState, @@ -87,11 +83,12 @@ export default Component => compose( const p6 = ownProps.nonceClearState(); const p7 = ownProps.requestsClearState(); const p8 = ownProps.uniswapClearState(); - return PromiseAllWithFails([p1, p2, p3, p4, p5, p6, p7, p8]); + return promiseUtils.PromiseAllWithFails([p1, p2, p3, p4, p5, p6, p7, p8]); }, initializeAccountData: (ownProps) => async () => { try { ownProps.dataInit(); + ownProps.uniswapTokenReservesRefreshState(); await ownProps.uniqueTokensRefreshState(); } catch (error) { // TODO @@ -104,7 +101,7 @@ export default Component => compose( const p4 = ownProps.walletConnectLoadState(); const p5 = ownProps.uniswapLoadState(); const p6 = ownProps.requestsLoadState(); - return PromiseAllWithFails([p1, p2, p3, p4, p5, p6]); + return promiseUtils.PromiseAllWithFails([p1, p2, p3, p4, p5, p6]); }, refreshAccountData: (ownProps) => async () => { try { diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 60a01b721b9..97d3fd94d3d 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -19,7 +19,8 @@ const allAssetsSelector = state => state.allAssets; const unsortedUniswapAssetsSelector = state => state.unsortedUniswapAssets; const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => toLower(key)); -const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); + +export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); const withAssetsAvailableOnUniswap = (allAssets) => { diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index bb1f99283e6..4a37282734c 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -9,14 +9,17 @@ import { getUniswapAllowances, getUniswapLiquidityInfo, getUniswapLiquidityTokens, + getUniswapTokenReserves, removeUniswapAllowances, removeUniswapLiquidityInfo, removeUniswapLiquidityTokens, + removeUniswapTokenReserves, saveUniswapAllowances, saveUniswapLiquidityInfo, saveUniswapLiquidityTokens, + saveUniswapTokenReserves, } from '../handlers/commonStorage'; -import { getLiquidityInfo } from '../handlers/uniswap'; +import { getLiquidityInfo, getReserves } from '../handlers/uniswap'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -27,11 +30,17 @@ const UNISWAP_UPDATE_REQUEST = 'uniswap/UNISWAP_UPDATE_REQUEST'; const UNISWAP_UPDATE_SUCCESS = 'uniswap/UNISWAP_UPDATE_SUCCESS'; const UNISWAP_UPDATE_FAILURE = 'uniswap/UNISWAP_UPDATE_FAILURE'; +const UNISWAP_GET_TOKEN_RESERVES_REQUEST = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_REQUEST'; +const UNISWAP_GET_TOKEN_RESERVES_SUCCESS = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_SUCCESS'; +const UNISWAP_GET_TOKEN_RESERVES_FAILURE = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_FAILURE'; + const UNISWAP_UPDATE_ALLOWANCES = 'uniswap/UNISWAP_UPDATE_ALLOWANCES'; const UNISWAP_UPDATE_LIQUIDITY_TOKENS = 'uniswap/UNISWAP_UPDATE_LIQUIDITY_TOKENS'; const UNISWAP_CLEAR_STATE = 'uniswap/UNISWAP_CLEAR_STATE'; // -- Actions --------------------------------------------------------------- // +let getTokenReservesInterval = null; + export const uniswapLoadState = () => async (dispatch, getState) => { const { accountAddress, network } = getState().settings; dispatch({ type: UNISWAP_LOAD_REQUEST }); @@ -39,8 +48,14 @@ export const uniswapLoadState = () => async (dispatch, getState) => { const uniswap = await getUniswapLiquidityInfo(accountAddress, network); const liquidityTokens = await getUniswapLiquidityTokens(accountAddress, network); const allowances = await getUniswapAllowances(accountAddress, network); + const tokenReserves = await getUniswapTokenReserves(accountAddress, network); dispatch({ - payload: { allowances, liquidityTokens, uniswap }, + payload: { + allowances, + liquidityTokens, + tokenReserves, + uniswap, + }, type: UNISWAP_LOAD_SUCCESS, }); } catch (error) { @@ -48,11 +63,44 @@ export const uniswapLoadState = () => async (dispatch, getState) => { } }; +export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => ( + new Promise((resolve, reject) => { + const fetchTokenReserves = () => new Promise((fetchResolve, fetchReject) => { + dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_REQUEST }); + const { accountAddress, network } = getState().settings; + getReserves() + .then(tokenReserves => { + dispatch({ + payload: tokenReserves, + type: UNISWAP_GET_TOKEN_RESERVES_SUCCESS, + }); + saveUniswapTokenReserves(accountAddress, tokenReserves, network); + fetchResolve(true); + }).catch(error => { + dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_FAILURE }); + fetchReject(error); + }); + }); + + return fetchTokenReserves().then(() => { + clearInterval(getTokenReservesInterval); + getTokenReservesInterval = setInterval(fetchTokenReserves, 15000); // 15 secs + resolve(true); + }).catch(error => { + clearInterval(getTokenReservesInterval); + getTokenReservesInterval = setInterval(fetchTokenReserves, 15000); // 15 secs + reject(error); + }); + }) +); + export const uniswapClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; removeUniswapAllowances(accountAddress, network); removeUniswapLiquidityInfo(accountAddress, network); removeUniswapLiquidityTokens(accountAddress, network); + removeUniswapTokenReserves(accountAddress, network); + clearInterval(getTokenReservesInterval); dispatch({ type: UNISWAP_CLEAR_STATE }); }; @@ -78,7 +126,6 @@ export const uniswapUpdateLiquidityTokens = (liquidityTokens) => (dispatch, getS dispatch(uniswapUpdateState()); }; - export const uniswapAddLiquidityTokens = (newLiquidityTokens) => (dispatch, getState) => { if (isEmpty(newLiquidityTokens)) return; const { accountAddress, network } = getState().settings; @@ -126,6 +173,7 @@ export const INITIAL_UNISWAP_STATE = { fetchingUniswap: false, liquidityTokens: [], loadingUniswap: false, + tokenReserves: {}, uniswap: {}, }; @@ -139,6 +187,7 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = draft.allowances = action.payload.allowances; draft.uniswap = action.payload.uniswap; draft.liquidityTokens = action.payload.liquidityTokens; + draft.tokenReserves = action.payload.tokenReserves; break; case UNISWAP_LOAD_FAILURE: draft.loadingUniswap = false; @@ -159,6 +208,9 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = case UNISWAP_UPDATE_ALLOWANCES: draft.allowances = action.payload; break; + case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: + draft.tokenResercves = action.payload; + break; case UNISWAP_CLEAR_STATE: return INITIAL_UNISWAP_STATE; default: diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index 702b1bc7eab..ba3997b2222 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -47,12 +47,6 @@ "decimals": 18, "exchangeAddress": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" }, - "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A": { - "name": "DigixDAO", - "symbol": "DGD", - "decimals": 9, - "exchangeAddress": "0xD55C1cA9F5992A2e5E379DCe49Abf24294ABe055" - }, "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { "name": "Digix Gold Token", "symbol": "DGX", diff --git a/src/utils/index.js b/src/utils/index.js index 5f6d3558274..0e83014f660 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -9,6 +9,7 @@ export { initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForPath } from './isNewValueForPath'; export { default as parseQueryParams } from './parseQueryParams'; +export { default as promiseUtils } from './promise'; export { default as reduceArrayToObject } from './reduceArrayToObject'; export { default as safeAreaInsetValues } from './safeAreaInsetValues'; export { default as statusBar } from './statusBar'; diff --git a/src/utils/promise.js b/src/utils/promise.js new file mode 100644 index 00000000000..42f1ce4f153 --- /dev/null +++ b/src/utils/promise.js @@ -0,0 +1,11 @@ +const PromiseAllWithFails = async (promises) => ( +Promise.all(promises.map(promise => ( + (promise && promise.catch) + ? promise.catch(error => error) + : promise +)))); + +export default { + PromiseAllWithFails, +}; + From 5d91d172e9c33d9d10ae6e1ee40317bf449833aa Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 20 Aug 2019 16:37:38 -0700 Subject: [PATCH 221/636] using sync calls for uniswap market details calculations --- src/handlers/uniswap.js | 2 ++ src/hoc/withUniswapAllowances.js | 6 +++--- src/redux/uniswap.js | 33 ++++++++++++++++++++++++++-- src/screens/ExchangeModal.js | 37 +++++++++++++++++++++----------- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 5fe4864feec..abbadb914be 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -29,6 +29,8 @@ const convertValueForEthers = (value) => { return ethers.utils.hexlify(valueBigNumber); }; +export const getReserve = tokenAddress => getTokenReserves(tokenAddress); + export const getReserves = async () => { const uniswapTokens = slice(uniswapAssetAddresses, 1); const reserves = await promiseUtils.PromiseAllWithFails(map(uniswapTokens, (token) => getTokenReserves(token))); diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 766955bfc51..85ee1d3618d 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -1,9 +1,9 @@ import { connect } from 'react-redux'; import { compose } from 'recompact'; -import { uniswapUpdateAllowances } from '../redux/uniswap'; +import { uniswapGetTokenReserve, uniswapUpdateAllowances } from '../redux/uniswap'; -const mapStateToProps = ({ uniswap: { allowances } }) => ({ allowances }); +const mapStateToProps = ({ uniswap: { allowances, tokenReserves } }) => ({ allowances, tokenReserves }); export default Component => compose( - connect(mapStateToProps, { uniswapUpdateAllowances }), + connect(mapStateToProps, { uniswapGetTokenReserve, uniswapUpdateAllowances }), )(Component); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 4a37282734c..a206beabc1b 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -19,7 +19,11 @@ import { saveUniswapLiquidityTokens, saveUniswapTokenReserves, } from '../handlers/commonStorage'; -import { getLiquidityInfo, getReserves } from '../handlers/uniswap'; +import { + getLiquidityInfo, + getReserve, + getReserves, +} from '../handlers/uniswap'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -63,6 +67,31 @@ export const uniswapLoadState = () => async (dispatch, getState) => { } }; +export const uniswapGetTokenReserve = (tokenAddress) => (dispatch, getState) => ( + new Promise((resolve, reject) => { + tokenAddress = tokenAddress.toLowerCase(); + dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_REQUEST }); + const { accountAddress, network } = getState().settings; + const { tokenReserves } = getState().uniswap; + getReserve(tokenAddress) + .then(tokenReserve => { + const updatedTokenReserves = { + ...tokenReserves, + [tokenAddress]: tokenReserve, + }; + dispatch({ + payload: updatedTokenReserves, + type: UNISWAP_GET_TOKEN_RESERVES_SUCCESS, + }); + saveUniswapTokenReserves(accountAddress, updatedTokenReserves, network); + resolve(tokenReserve); + }).catch(error => { + dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_FAILURE }); + reject(null); + }); + }) +); + export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => ( new Promise((resolve, reject) => { const fetchTokenReserves = () => new Promise((fetchResolve, fetchReject) => { @@ -209,7 +238,7 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = draft.allowances = action.payload; break; case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: - draft.tokenResercves = action.payload; + draft.tokenReserves = action.payload; break; case UNISWAP_CLEAR_STATE: return INITIAL_UNISWAP_STATE; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 76be97e5408..f5ce2d0a23f 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,10 +1,10 @@ import { - tradeEthForExactTokens, - tradeExactEthForTokens, - tradeExactTokensForEth, - tradeExactTokensForTokens, - tradeTokensForExactEth, - tradeTokensForExactTokens, + tradeEthForExactTokensWithData, + tradeExactEthForTokensWithData, + tradeExactTokensForEthWithData, + tradeExactTokensForTokensWithData, + tradeTokensForExactEthWithData, + tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; import { filter, @@ -92,6 +92,7 @@ class ExchangeModal extends PureComponent { navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, tradeDetails: PropTypes.object, + uniswapGetTokenReserve: PropTypes.func, uniswapUpdateAllowances: PropTypes.func, } @@ -175,6 +176,14 @@ class ExchangeModal extends PureComponent { this.setState({ needsApproval: !greaterThan(newAllowance, 0) }); }; + getReserveData = async tokenAddress => { + let reserve = this.props.tokenReserves[tokenAddress.toLowerCase()]; + if (isNil(reserve)) { + reserve = await this.props.uniswapGetTokenReserve(tokenAddress); + } + return reserve; + }; + getMarketDetails = async () => { try { let tradeDetails = null; @@ -200,17 +209,21 @@ class ExchangeModal extends PureComponent { const rawOutputAmount = convertAmountToRawAmount(outputAmount || 0, outputDecimals); if (inputCurrencyAddress === 'eth' && outputCurrencyAddress !== 'eth') { + const outputCurrencyReserve = await this.getReserveData(outputCurrencyAddress); tradeDetails = inputAsExactAmount - ? await tradeExactEthForTokens(outputCurrencyAddress, rawInputAmount, chainId) - : await tradeEthForExactTokens(outputCurrencyAddress, rawOutputAmount, chainId); + ? tradeExactEthForTokensWithData(outputCurrencyReserve, rawInputAmount, chainId) + : tradeEthForExactTokensWithData(outputCurrencyReserve, rawOutputAmount, chainId); } else if (inputCurrencyAddress !== 'eth' && outputCurrencyAddress === 'eth') { + const inputCurrencyReserve = await this.getReserveData(inputCurrencyAddress); tradeDetails = inputAsExactAmount - ? await tradeExactTokensForEth(inputCurrencyAddress, rawInputAmount, chainId) - : await tradeTokensForExactEth(inputCurrencyAddress, rawOutputAmount, chainId); + ? tradeExactTokensForEthWthData(inputCurrencyReserve, rawInputAmount, chainId) + : tradeTokensForExactEthWithData(inputCurrencyReserve, rawOutputAmount, chainId); } else if (inputCurrencyAddress !== 'eth' && outputCurrencyAddress !== 'eth') { + const inputCurrencyReserve = await this.getReserveData(inputCurrencyAddress); + const outputCurrencyReserve = await this.getReserveData(outputCurrencyAddress); tradeDetails = inputAsExactAmount - ? await tradeExactTokensForTokens(inputCurrencyAddress, outputCurrencyAddress, rawInputAmount, chainId) - : await tradeTokensForExactTokens(inputCurrencyAddress, outputCurrencyAddress, rawOutputAmount, chainId); + ? tradeExactTokensForTokensWithData(inputCurrencyReserve, outputCurrencyReserve, rawInputAmount, chainId) + : tradeTokensForExactTokensWithData(inputCurrencyReserve, outputCurrencyReserve, rawOutputAmount, chainId); } const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; const path = inputAsExactAmount ? 'outputAmount.amount' : 'inputAmount.amount'; From b305be8e7d2a2a39ab930488937b4964955f5900 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 20 Aug 2019 17:40:58 -0700 Subject: [PATCH 222/636] set up precision logic --- src/helpers/__tests__/utilities.test.js | 22 ++++++++++++++++++++++ src/helpers/utilities.js | 8 ++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/helpers/__tests__/utilities.test.js diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js new file mode 100644 index 00000000000..f0bb53928fe --- /dev/null +++ b/src/helpers/__tests__/utilities.test.js @@ -0,0 +1,22 @@ +import { determinePrecisionToDisplay } from '../utilities'; + +test('determinePrecisionToDisplay', () => { + const result = determinePrecisionToDisplay('0.123456789', '3.00'); + expect(result).toBe('0.123'); +}); + +test('determinePrecisionToDisplay', () => { + const result = determinePrecisionToDisplay('0.123456789', '32.04'); + expect(result).toBe('0.1235'); +}); + +test('determinePrecisionToDisplay', () => { + const result = determinePrecisionToDisplay('0.123456789', '132.00'); + expect(result).toBe('0.12346'); +}); + +test('determinePrecisionToDisplay', () => { + const result = determinePrecisionToDisplay('0.123456789', '1320.00'); + expect(result).toBe('0.123457'); +}); + diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 8682f4b50f5..bb1047cd11f 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -86,6 +86,14 @@ export const floorDivide = (numberOne, numberTwo) => BigNumber(`${numberOne}`) */ export const countDecimalPlaces = value => BigNumber(`${value}`).dp(); +export const determinePrecisionToDisplay = (amount, nativePrice) => { + const totalDigits = BigNumber(`${nativePrice}`) + .shiftedBy(2) + .sd(true); + return BigNumber(`${amount}`) + .decimalPlaces(totalDigits, BigNumber.ROUND_HALF_UP) + .toFixed(); +}; /** * @desc format inputOne value to signficant decimals given inputTwo From 86eb71c4a7a93ac77330ce0bed19a5e2bb0b312b Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 20 Aug 2019 22:31:47 -0700 Subject: [PATCH 223/636] setup for hooking in precision estimation calcuation --- src/helpers/__tests__/utilities.test.js | 18 +++++++++--------- src/helpers/utilities.js | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js index f0bb53928fe..de2dfe9c828 100644 --- a/src/helpers/__tests__/utilities.test.js +++ b/src/helpers/__tests__/utilities.test.js @@ -1,22 +1,22 @@ -import { determinePrecisionToDisplay } from '../utilities'; +import { updatePrecisionToDisplay } from '../utilities'; -test('determinePrecisionToDisplay', () => { - const result = determinePrecisionToDisplay('0.123456789', '3.00'); +test('updatePrecisionToDisplay', () => { + const result = updatePrecisionToDisplay('0.123456789', '3.00'); expect(result).toBe('0.123'); }); -test('determinePrecisionToDisplay', () => { - const result = determinePrecisionToDisplay('0.123456789', '32.04'); +test('updatePrecisionToDisplay', () => { + const result = updatePrecisionToDisplay('0.123456789', '32.04'); expect(result).toBe('0.1235'); }); -test('determinePrecisionToDisplay', () => { - const result = determinePrecisionToDisplay('0.123456789', '132.00'); +test('updatePrecisionToDisplay', () => { + const result = updatePrecisionToDisplay('0.123456789', '132.00'); expect(result).toBe('0.12346'); }); -test('determinePrecisionToDisplay', () => { - const result = determinePrecisionToDisplay('0.123456789', '1320.00'); +test('updatePrecisionToDisplay', () => { + const result = updatePrecisionToDisplay('0.123456789', '1320.00'); expect(result).toBe('0.123457'); }); diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index bb1047cd11f..18fb497cf46 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -86,7 +86,7 @@ export const floorDivide = (numberOne, numberTwo) => BigNumber(`${numberOne}`) */ export const countDecimalPlaces = value => BigNumber(`${value}`).dp(); -export const determinePrecisionToDisplay = (amount, nativePrice) => { +export const updatePrecisionToDisplay = (amount, nativePrice) => { const totalDigits = BigNumber(`${nativePrice}`) .shiftedBy(2) .sd(true); From 08b42f5ef7a3b23c0c5921c164725f713add34d5 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 21 Aug 2019 16:25:48 -0700 Subject: [PATCH 224/636] updated common storage --- .../settings-menu/SettingsSection.js | 2 +- src/handlers/localstorage/common.js | 100 +++++++++++++ src/handlers/localstorage/globalSettings.js | 76 ++++++++++ src/handlers/localstorage/storage.js | 136 ++++++++++++++++++ src/handlers/localstorage/walletconnect.js | 123 ++++++++++++++++ src/hoc/withDataInit.js | 2 +- src/model/firebase.js | 2 +- src/redux/isWalletEmpty.js | 2 +- src/redux/requests.js | 2 +- src/redux/settings.js | 2 +- src/redux/uniqueTokens.js | 2 +- src/redux/uniswap.js | 50 +++---- src/redux/walletconnect.js | 2 +- 13 files changed, 466 insertions(+), 35 deletions(-) create mode 100644 src/handlers/localstorage/common.js create mode 100644 src/handlers/localstorage/globalSettings.js create mode 100644 src/handlers/localstorage/storage.js create mode 100644 src/handlers/localstorage/walletconnect.js diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index 23fda7a9b1f..ee66492933a 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -14,7 +14,7 @@ import NetworkIcon from '../../assets/network-icon.png'; import { getAppStoreReviewRequestCount, setAppStoreReviewRequestCount, -} from '../../handlers/commonStorage'; +} from '../../handlers/localstorage/globalSettings'; import { withAccountSettings, withSendFeedback } from '../../hoc'; import { supportedLanguages } from '../../languages'; import { colors, position } from '../../styles'; diff --git a/src/handlers/localstorage/common.js b/src/handlers/localstorage/common.js new file mode 100644 index 00000000000..021d3639675 --- /dev/null +++ b/src/handlers/localstorage/common.js @@ -0,0 +1,100 @@ +const defaultVersion = '0.1.0'; + +export const getKey = (prefix, accountAddress, network) => `${prefix}-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; + +/** + * @desc save to storage + * @param {String} [key=''] + * @param {Object} [data={}] + * @param {String} [version=defaultVersion] + */ +export const saveLocal = async ( + key = '', + data = {}, + version = defaultVersion, +) => { + try { + data.storageVersion = version; + await storage.save({ + data, + expires: null, + key, + }); + } catch (error) { + console.log('Storage: error saving to local for key', key); + } +}; + +/** + * @desc get from storage + * @param {String} [key=''] + * @return {Object} + */ +export const getLocal = async (key = '', version = defaultVersion) => { + try { + const result = await storage.load({ + autoSync: false, + key, + syncInBackground: false, + }); + if (result && result.storageVersion === version) { + return result; + } + if (result) { + removeLocal(key); + return null; + } + return null; + } catch (error) { + console.log('Storage: error getting from local for key', key); + return null; + } +}; + +/** + * @desc get from storage + * @param {String} [key=''] + * @return {Object} + */ +export const removeLocal = (key = '') => { + try { + storage.remove({ key }); + } catch (error) { + console.log('Storage: error removing local with key', key); + } +}; + + +export const getAccountLocal = async ( + prefix, + accountAddress, + network, + emptyState = [] + version = defaultVersion, +) => { + const key = getKey(prefix, accountAddress, network); + const result = await getLocal(key, version); + return result ? result.data : emptyState; +}; + +export const saveAccountLocal = ( + prefix, + data, + accountAddress, + network, + version = defaultVersion, +) => saveLocal( + getKey(prefix, accountAddress, network), + { data }, + version, +); + +export const removeAccountLocal = ( + prefix, + accountAddress, + network, + version = defaultVersion, +) => { + const key = getKey(prefix, accountAddress, network); + removeLocal(key, version); +}; diff --git a/src/handlers/localstorage/globalSettings.js b/src/handlers/localstorage/globalSettings.js new file mode 100644 index 00000000000..393375b1b4d --- /dev/null +++ b/src/handlers/localstorage/globalSettings.js @@ -0,0 +1,76 @@ +import { + getLocal, + saveLocal, +} from './common'; + +/** + * @desc get native currency + * @return {Object} + */ +export const getNativeCurrency = async () => { + const nativeCurrency = await getLocal('nativeCurrency'); + const currency = nativeCurrency ? nativeCurrency.data : 'USD'; + if (currency === 'GBP') { + await saveNativeCurrency('USD'); + return 'USD'; + } + return currency; +}; + +/** + * @desc save native currency + * @param {String} [currency] + */ +export const saveNativeCurrency = async nativeCurrency => { + await saveLocal( + 'nativeCurrency', + { data: nativeCurrency }, + ); +}; + +/** + * @desc get language + * @return {Object} + */ +export const getLanguage = async () => { + const language = await getLocal('language'); + return language ? language.data : 'en'; +}; + +/** + * @desc save language + * @param {String} [language] + */ +export const saveLanguage = async language => { + await saveLocal('language', { data: language }); +}; + +/** + * @desc get show shitcoins setting + * @return {True|False} + */ +export const getShowShitcoinsSetting = async () => { + const showShitcoins = await getLocal('showShitcoins'); + return showShitcoins ? showShitcoins.data : null; +}; + +/** + * @desc update show shitcoins setting + * @param {Boolean} [updatedSetting] + * @return {Void} + */ +export const updateShowShitcoinsSetting = async (updatedSetting) => { + await saveLocal('showShitcoins', { data: updatedSetting }); +}; + +// apple restricts number of times developers are allowed to throw +// the in-app AppStore Review interface. +// see here for more: https://github.com/oblador/react-native-store-review +export const getAppStoreReviewRequestCount = async () => { + const count = await getLocal('appStoreReviewRequestCount'); + return count ? count.data : 0; +}; + +export const setAppStoreReviewRequestCount = async (newCount) => { + await saveLocal('appStoreReviewRequestCount', { data: newCount }); +}; diff --git a/src/handlers/localstorage/storage.js b/src/handlers/localstorage/storage.js new file mode 100644 index 00000000000..e594c1218fa --- /dev/null +++ b/src/handlers/localstorage/storage.js @@ -0,0 +1,136 @@ +import { + getAccountLocal, + getKey, + getLocal, + removeAccountLocal, + saveAccountLocal, + saveLocal, +} from './common'; + +const transactionsVersion = '0.2.0'; +const uniqueTokensVersion = '0.2.0'; +const assetsVersion = '0.2.0'; + +const ASSETS = 'assets'; +const WALLET_EMPTY = 'iswalletempty'; +const TRANSACTIONS = 'transactions'; +const UNIQUE_TOKENS = 'uniquetokens'; + +/** + * @desc get assets + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const getAssets = (accountAddress, network) => getAccountLocal(ASSETS, accountAddress, network, [], assetsVersion); + +/** + * @desc save assets + * @param {String} [address] + * @param {Array} [assets] + * @param {String} [network] + */ +export const saveAssets = (accountAddress, assets, network) => saveAccountLocal( + ASSETS, + assets, + accountAddress, + network, + assetsVersion, +); + +/** + * @desc remove assets + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeAssets = (accountAddress, network) => removeAccountLocal(ASSETS, accountAddress, network, assetsVersion); + +/** + * @desc get transactions + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const getLocalTransactions = (accountAddress, network) => getAccountLocal(TRANSACTIONS, accountAddress, network, [], transactionsVersion); + +/** + * @desc save transactions + * @param {String} [address] + * @param {Array} [transactions] + * @param {String} [network] + */ +export const saveLocalTransactions = (accountAddress, transactions, network) => saveAccountLocal( + TRANSACTIONS, + transactions, + accountAddress, + network, + transactionsVersion, +); + +/** + * @desc remove transactions + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeLocalTransactions = (accountAddress, network) => removeAccountLocal(TRANSACTIONS, accountAddress, network, transactionsVersion); + +/** + * @desc get is wallet empty + * @param {String} [address] + * @param {String} [network] + * @return {Boolean} + */ +export const getIsWalletEmpty = async (accountAddress, network) => await getLocal(getKey(WALLET_EMPTY, accountAddress, network)); + +/** + * @desc save is wallet empty + * @param {String} [address] + * @param {Boolean} [isWalletEmpty] + * @param {String} [network] + */ +export const saveIsWalletEmpty = async (accountAddress, isWalletEmpty, network) => { + await saveLocal( + getKey(WALLET_EMPTY, accountAddress, network), + isWalletEmpty, + ); +}; + +/** + * @desc remove is wallet empty + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeIsWalletEmpty = (accountAddress, network) => removeAccountLocal(WALLET_EMPTY, accountAddress, network); + +/** + * @desc get unique tokens + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const getUniqueTokens = (accountAddress, network) => getAccountLocal(UNIQUE_TOKENS, accountAddress, network, [], uniqueTokensVersion); + +/** + * @desc save unique tokens + * @param {String} [address] + * @param {Array} [uniqueTokens] + * @param {String} [network] + */ +export const saveUniqueTokens = (accountAddress, uniqueTokens, network) => saveAccountLocal( + UNIQUE_TOKENS, + uniqueTokens, + accountAddress, + network, + uniqueTokensVersion, +); + +/** + * @desc remove unique tokens + * @param {String} [address] + * @param {String} [network] + * @return {Object} + */ +export const removeUniqueTokens = (accountAddress, network) => removeAccountLocal(UNIQUE_TOKENS, accountAddress, network, uniqueTokensVersion); diff --git a/src/handlers/localstorage/walletconnect.js b/src/handlers/localstorage/walletconnect.js new file mode 100644 index 00000000000..b60159523cf --- /dev/null +++ b/src/handlers/localstorage/walletconnect.js @@ -0,0 +1,123 @@ +import { differenceInMinutes } from 'date-fns'; +import { omit, pickBy } from 'lodash'; +import { + getAccountLocal, + getKey, + getLocal, + removeAccountLocal, + removeLocal, + saveAccountLocal, + saveLocal, +} from './common'; + +const REQUESTS = 'requests'; + +/** + * @desc get all wallet connect sessions + * @return {Object} + */ +export const getAllValidWalletConnectSessions = async () => { + const allSessions = await getAllWalletConnectSessions(); + return pickBy(allSessions, value => value.connected); +}; + +/** + * @desc get all wallet connect sessions + * @return {Object} + */ +export const getAllWalletConnectSessions = async () => { + const allSessions = await getLocal('walletconnect'); + return allSessions || {}; +}; + +/** + * @desc save wallet connect session + * @param {String} [peerId] + * @param {Object} [session] + */ +export const saveWalletConnectSession = async (peerId, session) => { + const allSessions = await getAllValidWalletConnectSessions(); + allSessions[peerId] = session; + await saveLocal('walletconnect', allSessions); +}; + +/** + * @desc remove wallet connect session + * @param {String} [peerId] + */ +export const removeWalletConnectSession = async (peerId) => { + const allSessions = await getAllWalletConnectSessions(); + const session = allSessions ? allSessions[peerId] : null; + const resultingSessions = omit(allSessions, [peerId]); + await saveLocal('walletconnect', resultingSessions); + return session; +}; + +/** + * @desc remove wallet connect sessions + * @param {String} [sessionId] + */ +export const removeWalletConnectSessions = async (sessionIds) => { + const allSessions = await getAllWalletConnectSessions(); + const resultingSessions = omit(allSessions, sessionIds); + await saveLocal('walletconnect', resultingSessions); +}; + +/** + * @desc remove all wallet connect sessions + * @param {String} [sessionId] + */ +export const removeWalletConnect = () => removeLocal('walletconnect'); + +const isRequestStillValid = (request) => { + const createdAt = request.displayDetails.timestampInMs; + return (differenceInMinutes(Date.now(), createdAt) < 60); +}; + +/** + * @desc get account local requests + * @param {String} [address] + * @return {Object} + */ +export const getLocalRequests = async (accountAddress, network) => { + const requests = getAccountLocal(REQUESTS, accountAddress, network, {}); + const openRequests = pickBy(requests, isRequestStillValid); + await saveLocalRequests(accountAddress, network, openRequests); + return openRequests; +}; + +/** + * @desc save local incoming requests + * @param {String} [address] + * @param {String} [network] + * @return {Void} + */ +export const saveLocalRequests = async (accountAddress, network, requests) => saveAccountLocal( + REQUESTS, + requests, + accountAddress, + network, +); + +/** + * @desc remove request + * @param {String} [address] + * @param {String} [network] + * @param {String} [requestId] + * @return {Void} + */ +export const removeLocalRequest = async (address, network, requestId) => { + const requests = await getLocalRequests(address, network); + const updatedRequests = { ...requests }; + delete updatedRequests[requestId]; + await saveLocalRequests(address, network, updatedRequests); +}; + +/** + * @desc remove all requests + * @param {String} [address] + * @param {String} [network] + * @param {String} [requestId] + * @return {Void} + */ +export const removeLocalRequests = async (accountAddress, network) => removeAccountLocal(REQUESTS, accountAddress, network); diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index c570154de80..104292aad2f 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -3,7 +3,7 @@ import { isNil } from 'lodash'; import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { compose, withHandlers } from 'recompact'; -import { getIsWalletEmpty } from '../handlers/commonStorage'; +import { getIsWalletEmpty } from '../handlers/localstorage/storage'; import { hasEthBalance } from '../handlers/web3'; import { dataClearState, diff --git a/src/model/firebase.js b/src/model/firebase.js index 53bef4f6493..e548d4f0e07 100644 --- a/src/model/firebase.js +++ b/src/model/firebase.js @@ -2,7 +2,7 @@ import lang from 'i18n-js'; import { get } from 'lodash'; import firebase from 'react-native-firebase'; import { Alert } from '../components/alerts'; -import { getLocal, saveLocal } from '../handlers/commonStorage'; +import { getLocal, saveLocal } from '../handlers/localstorage/common'; export const getFCMToken = async () => { const fcmTokenLocal = await getLocal('rainbowFcmToken'); diff --git a/src/redux/isWalletEmpty.js b/src/redux/isWalletEmpty.js index aea6a231bf3..aeb1c5e4137 100644 --- a/src/redux/isWalletEmpty.js +++ b/src/redux/isWalletEmpty.js @@ -4,7 +4,7 @@ import { getIsWalletEmpty, removeIsWalletEmpty, saveIsWalletEmpty, -} from '../handlers/commonStorage'; +} from '../handlers/localstorage/storage'; // -- Constants --------------------------------------- // const SET_IS_WALLET_EMPTY = 'isWalletEmpty/SET_IS_WALLET_EMPTY'; diff --git a/src/redux/requests.js b/src/redux/requests.js index aa64ccae383..db3d77feb4c 100644 --- a/src/redux/requests.js +++ b/src/redux/requests.js @@ -11,7 +11,7 @@ import { removeLocalRequest, removeLocalRequests, saveLocalRequests, -} from '../handlers/commonStorage'; +} from '../handlers/localstorage/walletconnect'; import { convertAmountAndPriceToNativeDisplay, convertHexToString, diff --git a/src/redux/settings.js b/src/redux/settings.js index 4e23a125985..0ebd0293e51 100644 --- a/src/redux/settings.js +++ b/src/redux/settings.js @@ -4,7 +4,7 @@ import { getNativeCurrency, saveLanguage, saveNativeCurrency, -} from '../handlers/commonStorage'; +} from '../handlers/localstorage/globalSettings'; import { dataClearState, dataInit } from './data'; import { ethereumUtils } from '../utils'; import { web3SetHttpProvider } from '../handlers/web3'; diff --git a/src/redux/uniqueTokens.js b/src/redux/uniqueTokens.js index f50ec77b42b..8f4ef6b73de 100644 --- a/src/redux/uniqueTokens.js +++ b/src/redux/uniqueTokens.js @@ -4,7 +4,7 @@ import { getUniqueTokens, saveUniqueTokens, removeUniqueTokens, -} from '../handlers/commonStorage'; +} from '../handlers/localstorage/storage'; import { dedupeAssetsWithFamilies } from './data'; import { getFamilies } from '../parsers/uniqueTokens'; diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index a206beabc1b..5b35a767a2d 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -1,24 +1,16 @@ import produce from 'immer'; import { concat, + forEach, get, isEmpty, map, } from 'lodash'; import { - getUniswapAllowances, - getUniswapLiquidityInfo, - getUniswapLiquidityTokens, - getUniswapTokenReserves, - removeUniswapAllowances, - removeUniswapLiquidityInfo, - removeUniswapLiquidityTokens, - removeUniswapTokenReserves, - saveUniswapAllowances, - saveUniswapLiquidityInfo, - saveUniswapLiquidityTokens, - saveUniswapTokenReserves, -} from '../handlers/commonStorage'; + getAccountLocal, + removeAccountLocal, + saveAccountLocal, +} from '../handlers/localstorage/common'; import { getLiquidityInfo, getReserve, @@ -42,6 +34,12 @@ const UNISWAP_UPDATE_ALLOWANCES = 'uniswap/UNISWAP_UPDATE_ALLOWANCES'; const UNISWAP_UPDATE_LIQUIDITY_TOKENS = 'uniswap/UNISWAP_UPDATE_LIQUIDITY_TOKENS'; const UNISWAP_CLEAR_STATE = 'uniswap/UNISWAP_CLEAR_STATE'; +// Localstorage keys +export const ALLOWANCES = 'uniswapallowances'; +export const LIQUIDITY = 'uniswapliquidity'; +export const LIQUIDITY_INFO = 'uniswap'; +export const RESERVES = 'uniswapreserves'; + // -- Actions --------------------------------------------------------------- // let getTokenReservesInterval = null; @@ -49,10 +47,10 @@ export const uniswapLoadState = () => async (dispatch, getState) => { const { accountAddress, network } = getState().settings; dispatch({ type: UNISWAP_LOAD_REQUEST }); try { - const uniswap = await getUniswapLiquidityInfo(accountAddress, network); - const liquidityTokens = await getUniswapLiquidityTokens(accountAddress, network); - const allowances = await getUniswapAllowances(accountAddress, network); - const tokenReserves = await getUniswapTokenReserves(accountAddress, network); + const uniswap = await getAccountLocal(LIQUIDITY_INFO, accountAddress, network, {}); + const liquidityTokens = await getAccountLocal(LIQUIDITY, accountAddress, network); + const allowances = await getAccountLocal(ALLOWANCES, accountAddress, network, {}); + const tokenReserves = await getAccountLocal(RESERVES, accountAddress, network, {}); dispatch({ payload: { allowances, @@ -83,7 +81,7 @@ export const uniswapGetTokenReserve = (tokenAddress) => (dispatch, getState) => payload: updatedTokenReserves, type: UNISWAP_GET_TOKEN_RESERVES_SUCCESS, }); - saveUniswapTokenReserves(accountAddress, updatedTokenReserves, network); + saveAccountLocal(RESERVES, updatedTokenReserves, accountAddress, network); resolve(tokenReserve); }).catch(error => { dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_FAILURE }); @@ -103,7 +101,7 @@ export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => ( payload: tokenReserves, type: UNISWAP_GET_TOKEN_RESERVES_SUCCESS, }); - saveUniswapTokenReserves(accountAddress, tokenReserves, network); + saveAccountLocal(RESERVES, tokenReserves, accountAddress, network); fetchResolve(true); }).catch(error => { dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_FAILURE }); @@ -125,10 +123,8 @@ export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => ( export const uniswapClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - removeUniswapAllowances(accountAddress, network); - removeUniswapLiquidityInfo(accountAddress, network); - removeUniswapLiquidityTokens(accountAddress, network); - removeUniswapTokenReserves(accountAddress, network); + const storageKeys = [ALLOWANCES, LIQUIDITY_INFO, LIQUIDITY, RESERVES]; + forEach(storageKeys, key => removeAccountLocal(key, accountAddress, network)); clearInterval(getTokenReservesInterval); dispatch({ type: UNISWAP_CLEAR_STATE }); }; @@ -141,7 +137,7 @@ export const uniswapUpdateAllowances = (tokenAddress, allowance) => (dispatch, g payload: updatedAllowances, type: UNISWAP_UPDATE_ALLOWANCES, }); - saveUniswapAllowances(accountAddress, updatedAllowances, network); + saveAccountLocal(ALLOWANCES, updatedAllowances, accountAddress, network); }; export const uniswapUpdateLiquidityTokens = (liquidityTokens) => (dispatch, getState) => { @@ -151,7 +147,7 @@ export const uniswapUpdateLiquidityTokens = (liquidityTokens) => (dispatch, getS payload: liquidityTokens, type: UNISWAP_UPDATE_LIQUIDITY_TOKENS, }); - saveUniswapLiquidityTokens(accountAddress, liquidityTokens, network); + saveAccountLocal(LIQUIDITY, liquidityTokens, accountAddress, network); dispatch(uniswapUpdateState()); }; @@ -164,7 +160,7 @@ export const uniswapAddLiquidityTokens = (newLiquidityTokens) => (dispatch, getS payload: updatedLiquidityTokens, type: UNISWAP_UPDATE_LIQUIDITY_TOKENS, }); - saveUniswapLiquidityTokens(accountAddress, updatedLiquidityTokens, network); + saveAccountLocal(LIQUIDITY, updatedLiquidityTokens, accountAddress, network); dispatch(uniswapUpdateState()); }; @@ -182,7 +178,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => ( const exchangeContracts = map(liquidityTokens, x => get(x, 'asset.asset_code')); return getLiquidityInfo(accountAddress, exchangeContracts) .then(uniswap => { - saveUniswapLiquidityInfo(accountAddress, uniswap, network); + saveAccountLocal(LIQUIDITY_INFO, uniswap, accountAddress, network); dispatch({ payload: uniswap, type: UNISWAP_UPDATE_SUCCESS, diff --git a/src/redux/walletconnect.js b/src/redux/walletconnect.js index 06e82e5092b..860682310f6 100644 --- a/src/redux/walletconnect.js +++ b/src/redux/walletconnect.js @@ -14,7 +14,7 @@ import { saveWalletConnectSession, removeWalletConnect, removeWalletConnectSessions, -} from '../handlers/commonStorage'; +} from '../handlers/localstorage/walletconnect'; import { sendRpcCall } from '../handlers/web3'; import { getFCMToken, checkPushNotificationPermissions } from '../model/firebase'; import { addRequestToApprove } from './requests'; From 82a0aae2d69d0e01d4916f09f7cf02728386932b Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 22 Aug 2019 18:37:30 -0700 Subject: [PATCH 225/636] separate out explorer api from asset/txns data --- src/handlers/localstorage/common.js | 2 +- src/hoc/withDataInit.js | 17 ++- src/parsers/accounts.js | 30 +++-- src/redux/data.js | 126 +++++--------------- src/redux/explorer.js | 179 ++++++++++++++++++++++++++++ src/redux/reducers.js | 2 + src/redux/uniswap.js | 38 +++++- 7 files changed, 279 insertions(+), 115 deletions(-) create mode 100644 src/redux/explorer.js diff --git a/src/handlers/localstorage/common.js b/src/handlers/localstorage/common.js index 021d3639675..8a931e3baba 100644 --- a/src/handlers/localstorage/common.js +++ b/src/handlers/localstorage/common.js @@ -69,7 +69,7 @@ export const getAccountLocal = async ( prefix, accountAddress, network, - emptyState = [] + emptyState = [], version = defaultVersion, ) => { const key = getKey(prefix, accountAddress, network); diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 104292aad2f..d404d5cb2dc 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -8,9 +8,16 @@ import { hasEthBalance } from '../handlers/web3'; import { dataClearState, dataLoadState, - dataInit, } from '../redux/data'; +<<<<<<< HEAD import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; +======= +import { + explorerClearState, + explorerInit, +} from '../redux/explorer'; +import { clearIsWalletEmpty, loadIsWalletEmpty } from '../redux/isWalletEmpty'; +>>>>>>> 6d69f680... separate out explorer api from asset/txns data import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; @@ -46,8 +53,9 @@ export default Component => compose( clearIsWalletEmpty, clearOpenFamilyTab, dataClearState, - dataInit, dataLoadState, + explorerClearState, + explorerInit, nonceClearState, requestsClearState, requestsLoadState, @@ -75,6 +83,7 @@ export default Component => compose( } }, clearAccountData: (ownProps) => async () => { + const p0 = ownProps.explorerClearState(); const p1 = ownProps.dataClearState(); const p2 = ownProps.clearIsWalletEmpty(); const p3 = ownProps.uniqueTokensClearState(); @@ -83,11 +92,11 @@ export default Component => compose( const p6 = ownProps.nonceClearState(); const p7 = ownProps.requestsClearState(); const p8 = ownProps.uniswapClearState(); - return promiseUtils.PromiseAllWithFails([p1, p2, p3, p4, p5, p6, p7, p8]); + return promiseUtils.PromiseAllWithFails([p0, p1, p2, p3, p4, p5, p6, p7, p8]); }, initializeAccountData: (ownProps) => async () => { try { - ownProps.dataInit(); + ownProps.explorerInit(); ownProps.uniswapTokenReservesRefreshState(); await ownProps.uniqueTokensRefreshState(); } catch (error) { diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index 29ec6217f02..ed2bd8a7a3c 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -10,16 +10,7 @@ export const parseAccountAssets = data => { try { let assets = [...data]; assets = assets.map(assetData => { - const name = get(assetData, 'asset.name') || 'Unknown Token'; - const symbol = get(assetData, 'asset.symbol') || '———'; - const asset = { - address: get(assetData, 'asset.asset_code', null), - decimals: get(assetData, 'asset.decimals'), - name, - price: get(assetData, 'asset.price'), - symbol: symbol.toUpperCase(), - uniqueId: get(assetData, 'asset.asset_code') || name, - }; + const asset = parseAsset(assetData.asset); return { ...asset, balance: convertRawAmountToBalance(assetData.quantity, asset), @@ -35,3 +26,22 @@ export const parseAccountAssets = data => { throw error; } }; + +/** + * @desc parse asset + * @param {Object} assetData + * @return {Object} + */ +export const parseAsset = assetData => { + const name = get(assetData, 'name') || 'Unknown Token'; + const symbol = get(assetData, 'symbol') || '———'; + const asset = { + address: get(assetData, 'asset_code', null), + decimals: get(assetData, 'decimals'), + name, + price: get(assetData, 'price'), + symbol: symbol.toUpperCase(), + uniqueId: get(assetData, 'asset_code') || name, + }; + return asset; +}; diff --git a/src/redux/data.js b/src/redux/data.js index 124bd9f0177..680f60fa5b9 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -21,13 +21,20 @@ import { removeLocalTransactions, saveAssets, saveLocalTransactions, -} from '../handlers/commonStorage'; -import io from 'socket.io-client'; import { parseAccountAssets } from '../parsers/accounts'; +} from '../handlers/localstorage/storage'; +import { uniswapAssetAddresses } from '../hoc/withUniswapAssets'; +import io from 'socket.io-client'; +import { parseAccountAssets, parseAsset } from '../parsers/accounts'; import { parseNewTransaction } from '../parsers/newTransaction'; import { parseTransactions } from '../parsers/transactions'; import { getFamilies } from '../parsers/uniqueTokens'; import { isLowerCaseMatch } from '../utils'; -import { uniswapAddLiquidityTokens, uniswapUpdateLiquidityTokens } from './uniswap'; +import { + uniswapAddLiquidityTokens, + uniswapUpdateAssetPrice, + uniswapUpdateAssets, + uniswapUpdateLiquidityTokens, +} from './uniswap'; // -- Constants --------------------------------------- // @@ -48,47 +55,7 @@ const DATA_ADD_NEW_TRANSACTION_SUCCESS = 'data/DATA_ADD_NEW_TRANSACTION_SUCCESS' const DATA_CLEAR_STATE = 'data/DATA_CLEAR_STATE'; -const messages = { - ASSETS: { - APPENDED: 'appended address assets', - CHANGED: 'changed address assets', - RECEIVED: 'received address assets', - }, - CONNECT: 'connect', - DISCONNECT: 'disconnect', - ERROR: 'error', - RECONNECT_ATTEMPT: 'reconnect_attempt', - TRANSACTIONS: { - APPENDED: 'appended address transactions', - RECEIVED: 'received address transactions', - REMOVED: 'removed address transactions', - }, -}; - // -- Actions ---------------------------------------- // - -const createSocket = endpoint => io( - `wss://api.zerion.io/${endpoint}?api_token=${DATA_API_KEY}`, - { - extraHeaders: { Origin: DATA_ORIGIN }, - transports: ['websocket'], - }, -); - -/* eslint-disable camelcase */ -const addressSubscription = (address, currency, action = 'subscribe') => [ - action, - { - payload: { - address, - currency, - transactions_limit: 1000, - }, - scope: ['assets', 'transactions'], - }, -]; -/* eslint-disable camelcase */ - export const dataLoadState = () => async (dispatch, getState) => { const { accountAddress, network } = getState().settings; try { @@ -113,40 +80,13 @@ export const dataLoadState = () => async (dispatch, getState) => { } }; -const dataUnsubscribe = () => (dispatch, getState) => { - const { addressSocket } = getState().data; - const { accountAddress, nativeCurrency } = getState().settings; - if (!isNil(addressSocket)) { - addressSocket.emit(...addressSubscription( - accountAddress, - nativeCurrency.toLowerCase(), - 'unsubscribe', - )); - addressSocket.close(); - } -}; - export const dataClearState = () => (dispatch, getState) => { - dispatch(dataUnsubscribe()); const { accountAddress, network } = getState().settings; removeAssets(accountAddress, network); removeLocalTransactions(accountAddress, network); dispatch({ type: DATA_CLEAR_STATE }); }; -export const dataInit = () => (dispatch, getState) => { - const { accountAddress, nativeCurrency } = getState().settings; - const addressSocket = createSocket('address'); - dispatch({ - payload: addressSocket, - type: DATA_UPDATE_ADDRESS_SOCKET, - }); - addressSocket.on(messages.CONNECT, () => { - addressSocket.emit(...addressSubscription(accountAddress, nativeCurrency.toLowerCase())); - dispatch(listenOnNewMessages(addressSocket)); - }); -}; - const dedupePendingTransactions = (pendingTransactions, parsedTransactions) => { let updatedPendingTransactions = pendingTransactions; if (pendingTransactions.length) { @@ -196,7 +136,7 @@ const checkMeta = message => (dispatch, getState) => { return isLowerCaseMatch(address, accountAddress) && isLowerCaseMatch(currency, nativeCurrency); }; -const transactionsReceived = message => (dispatch, getState) => { +export const transactionsReceived = message => (dispatch, getState) => { const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; @@ -232,7 +172,7 @@ const transactionsReceived = message => (dispatch, getState) => { }); }; -const transactionsAppended = message => (dispatch, getState) => { +export const transactionsAppended = message => (dispatch, getState) => { const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; @@ -256,7 +196,7 @@ const transactionsAppended = message => (dispatch, getState) => { }); }; -const transactionsRemoved = message => (dispatch, getState) => { +export const transactionsRemoved = message => (dispatch, getState) => { const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; @@ -274,7 +214,7 @@ const transactionsRemoved = message => (dispatch, getState) => { }); }; -const assetsReceived = (message, append = false, change = false) => (dispatch, getState) => { +export const addressAssetsReceived = (message, append = false, change = false) => (dispatch, getState) => { const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; @@ -306,30 +246,21 @@ const assetsReceived = (message, append = false, change = false) => (dispatch, g }); }; -const listenOnNewMessages = socket => (dispatch, getState) => { - socket.on(messages.TRANSACTIONS.RECEIVED, (message) => { - dispatch(transactionsReceived(message)); - }); - - socket.on(messages.TRANSACTIONS.APPENDED, (message) => { - dispatch(transactionsAppended(message)); - }); - - socket.on(messages.TRANSACTIONS.REMOVED, (message) => { - dispatch(transactionsRemoved(message)); - }); - - socket.on(messages.ASSETS.RECEIVED, (message) => { - dispatch(assetsReceived(message)); - }); +export const assetsReceived = (message) => (dispatch, getState) => { + const assets = get(message, 'payload.assets', []); + if (!assets.length) return; + let parsedAssets = map(assets, asset => parseAsset(asset)); + dispatch(uniswapUpdateAssets(parsedAssets)); +}; - socket.on(messages.ASSETS.APPENDED, (message) => { - dispatch(assetsReceived(message, true)); - }); +export const priceChanged = (message) => (dispatch, getState) => { + const isValidMeta = dispatch(checkMeta(message)); + // TODO is it asset_code in meta? + const address = get(message, 'meta.asset_code'); - socket.on(messages.ASSETS.CHANGED, (message) => { - dispatch(assetsReceived(message, false, true)); - }); + const price = get(message, 'payload.price'); + if (isNil(price)) return; + dispatch(uniswapUpdateAssetPrice(address, price)); }; export const dataAddNewTransaction = txDetails => (dispatch, getState) => new Promise((resolve, reject) => { @@ -352,7 +283,6 @@ export const dataAddNewTransaction = txDetails => (dispatch, getState) => new Pr // -- Reducer ----------------------------------------- // const INITIAL_STATE = { - addressSocket: null, assets: [], loadingAssets: false, loadingTransactions: false, @@ -361,8 +291,6 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => { switch (action.type) { - case DATA_UPDATE_ADDRESS_SOCKET: - return { ...state, addressSocket: action.payload }; case DATA_UPDATE_ASSETS: return { ...state, assets: action.payload }; case DATA_UPDATE_TRANSACTIONS: diff --git a/src/redux/explorer.js b/src/redux/explorer.js new file mode 100644 index 00000000000..bebd4a65fe1 --- /dev/null +++ b/src/redux/explorer.js @@ -0,0 +1,179 @@ +import { get, isNil } from 'lodash'; +import { DATA_API_KEY, DATA_ORIGIN } from 'react-native-dotenv'; +import { uniswapAssetAddresses } from '../hoc/withUniswapAssets'; +import io from 'socket.io-client'; +import { parseAccountAssets } from '../parsers/accounts'; +import { isLowerCaseMatch } from '../utils'; +import { + addressAssetsReceived, + assetsReceived, + priceChanged, + transactionsAppended, + transactionsReceived, + transactionsRemoved, +} from './data'; + +// -- Constants --------------------------------------- // + +const EXPLORER_UPDATE_SOCKETS = 'explorer/EXPLORER_UPDATE_SOCKETS'; +const EXPLORER_CLEAR_STATE = 'explorer/EXPLORER_CLEAR_STATE'; + +const messages = { + ADDRESS_ASSETS: { + APPENDED: 'appended address assets', + CHANGED: 'changed address assets', + RECEIVED: 'received address assets', + }, + ASSETS: { + CHANGED: 'changed price', + RECEIVED: 'received assets', + }, + CONNECT: 'connect', + DISCONNECT: 'disconnect', + ERROR: 'error', + RECONNECT_ATTEMPT: 'reconnect_attempt', + ADDRESS_TRANSACTIONS: { + APPENDED: 'appended address transactions', + RECEIVED: 'received address transactions', + REMOVED: 'removed address transactions', + }, +}; + +// -- Actions ---------------------------------------- // + +const createSocket = endpoint => io( + `wss://api.zerion.io/${endpoint}?api_token=${DATA_API_KEY}`, + { + extraHeaders: { Origin: DATA_ORIGIN }, + transports: ['websocket'], + }, +); + +/* eslint-disable camelcase */ +const addressSubscription = (address, currency, action = 'subscribe') => [ + action, + { + payload: { + address, + currency: currency.toLowerCase(), + transactions_limit: 1000, + }, + scope: ['assets', 'transactions'], + }, +]; + +const assetsSubscription = (assetCodes, currency, action = 'subscribe') => [ + action, + { + payload: { + asset_codes: assetCodes, + currency: currency.toLowerCase(), + }, + }, +]; +/* eslint-disable camelcase */ + +const explorerUnsubscribe = () => (dispatch, getState) => { + const { addressSocket, assetsSocket } = getState().explorer; + const { accountAddress, nativeCurrency } = getState().settings; + if (!isNil(addressSocket)) { + addressSocket.emit(...addressSubscription( + accountAddress, + nativeCurrency, + 'unsubscribe', + )); + addressSocket.close(); + } + if (!isNil(assetsSocket)) { + assetsSocket.emit(...assetsSubscription( + uniswapAssetAddresses, + nativeCurrency, + 'unsubscribe', + )); + assetsSocket.close(); + } +}; + +export const explorerClearState = () => (dispatch, getState) => { + dispatch(explorerUnsubscribe()); + dispatch({ type: EXPLORER_CLEAR_STATE }); +}; + +export const explorerInit = () => (dispatch, getState) => { + const { accountAddress, nativeCurrency } = getState().settings; + const addressSocket = createSocket('address'); + const assetsSocket = createSocket('assets'); + dispatch({ + payload: { addressSocket, assetsSocket }, + type: EXPLORER_UPDATE_SOCKETS, + }); + assetsSocket.on(messages.CONNECT, () => { + assetsSocket.emit(...assetsSubscription(uniswapAssetAddresses, nativeCurrency)); + dispatch(listenOnAssetMessages(assetsSocket)); + }); + addressSocket.on(messages.CONNECT, () => { + addressSocket.emit(...addressSubscription(accountAddress, nativeCurrency)); + dispatch(listenOnAddressMessages(addressSocket)); + }); +}; + +const listenOnAssetMessages = socket => (dispatch, getState) => { + socket.on(messages.ASSETS.RECEIVED, (message) => { + dispatch(assetsReceived(message)); + }); + + socket.on(messages.ASSETS.CHANGED, (message) => { + // dispatch(priceChanged(message)); + }); +}; + +const listenOnAddressMessages = socket => (dispatch, getState) => { + socket.on(messages.ADDRESS_TRANSACTIONS.RECEIVED, (message) => { + dispatch(transactionsReceived(message)); + }); + + socket.on(messages.ADDRESS_TRANSACTIONS.APPENDED, (message) => { + dispatch(transactionsAppended(message)); + }); + + socket.on(messages.ADDRESS_TRANSACTIONS.REMOVED, (message) => { + dispatch(transactionsRemoved(message)); + }); + + socket.on(messages.ADDRESS_ASSETS.RECEIVED, (message) => { + console.log('ADDRESS received', message); + dispatch(addressAssetsReceived(message)); + }); + + socket.on(messages.ADDRESS_ASSETS.APPENDED, (message) => { + dispatch(addressAssetsReceived(message, true)); + }); + + socket.on(messages.ADDRESS_ASSETS.CHANGED, (message) => { + dispatch(addressAssetsReceived(message, false, true)); + }); +}; + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + addressSocket: null, + assetsSocket: null, +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case EXPLORER_UPDATE_SOCKETS: + return { + ...state, + addressSocket: action.payload.addressSocket, + assetsSocket: action.payload.assetsSocket, + }; + case EXPLORER_CLEAR_STATE: + return { + ...state, + ...INITIAL_STATE, + }; + default: + return state; + } +}; diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 61365ccb9b8..218afe74a81 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -2,6 +2,7 @@ import { combineReducers } from 'redux'; import actionSheetManager from './actionSheetManager'; import data from './data'; +import explorer from './explorer'; import imageDimensionsCache from './imageDimensionsCache'; import isWalletEmpty from './isWalletEmpty'; import isWalletEthZero from './isWalletEthZero'; @@ -24,6 +25,7 @@ import walletconnect from './walletconnect'; export default combineReducers({ actionSheetManager, data, + explorer, imageDimensionsCache, isWalletEmpty, isWalletEthZero, diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 5b35a767a2d..abf70845aa6 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -4,6 +4,7 @@ import { forEach, get, isEmpty, + keyBy, map, } from 'lodash'; import { @@ -30,6 +31,7 @@ const UNISWAP_GET_TOKEN_RESERVES_REQUEST = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_R const UNISWAP_GET_TOKEN_RESERVES_SUCCESS = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_SUCCESS'; const UNISWAP_GET_TOKEN_RESERVES_FAILURE = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_FAILURE'; +const UNISWAP_UPDATE_ASSETS = 'uniswap/UNISWAP_UPDATE_ASSETS'; const UNISWAP_UPDATE_ALLOWANCES = 'uniswap/UNISWAP_UPDATE_ALLOWANCES'; const UNISWAP_UPDATE_LIQUIDITY_TOKENS = 'uniswap/UNISWAP_UPDATE_LIQUIDITY_TOKENS'; const UNISWAP_CLEAR_STATE = 'uniswap/UNISWAP_CLEAR_STATE'; @@ -39,6 +41,7 @@ export const ALLOWANCES = 'uniswapallowances'; export const LIQUIDITY = 'uniswapliquidity'; export const LIQUIDITY_INFO = 'uniswap'; export const RESERVES = 'uniswapreserves'; +export const ASSETS = 'uniswapassets'; // -- Actions --------------------------------------------------------------- // let getTokenReservesInterval = null; @@ -51,12 +54,14 @@ export const uniswapLoadState = () => async (dispatch, getState) => { const liquidityTokens = await getAccountLocal(LIQUIDITY, accountAddress, network); const allowances = await getAccountLocal(ALLOWANCES, accountAddress, network, {}); const tokenReserves = await getAccountLocal(RESERVES, accountAddress, network, {}); + const uniswapAssets = await getAccountLocal(ASSETS, accountAddress, network, {}); dispatch({ payload: { allowances, liquidityTokens, tokenReserves, uniswap, + uniswapAssets, }, type: UNISWAP_LOAD_SUCCESS, }); @@ -123,7 +128,7 @@ export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => ( export const uniswapClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - const storageKeys = [ALLOWANCES, LIQUIDITY_INFO, LIQUIDITY, RESERVES]; + const storageKeys = [ASSETS, ALLOWANCES, LIQUIDITY_INFO, LIQUIDITY, RESERVES]; forEach(storageKeys, key => removeAccountLocal(key, accountAddress, network)); clearInterval(getTokenReservesInterval); dispatch({ type: UNISWAP_CLEAR_STATE }); @@ -140,6 +145,32 @@ export const uniswapUpdateAllowances = (tokenAddress, allowance) => (dispatch, g saveAccountLocal(ALLOWANCES, updatedAllowances, accountAddress, network); }; +export const uniswapUpdateAssets = (assets) => { + const { accountAddress, network } = getState().settings; + const mappedAssets = keyBy(assets, (asset) => asset.address.toLowerCase()); + dispatch({ + payload: mappedAssets, + type: UNISWAP_UPDATE_ASSETS, + }); + saveAccountLocal(ASSETS, mappedAssets, accountAddress, network); +}; + +export const uniswapUpdateAssetPrice = (address, price) => { + const addressKey = address.toLowerCase(); + const { accountAddress, network } = getState().settings; + const { uniswapAssets } = getState().uniswap; + const updatedAsset = { ...uniswapAssets[addressKey], price }; + const updatedAssets = { + ...uniswapAssets, + [addressKey]: updatedAsset, + }; + dispatch({ + payload: updatedAssets, + type: UNISWAP_UPDATE_ASSETS, + }); + saveAccountLocal(ASSETS, updatedAssets, accountAddress, network); +}; + export const uniswapUpdateLiquidityTokens = (liquidityTokens) => (dispatch, getState) => { if (isEmpty(liquidityTokens)) return; const { accountAddress, network } = getState().settings; @@ -200,6 +231,7 @@ export const INITIAL_UNISWAP_STATE = { loadingUniswap: false, tokenReserves: {}, uniswap: {}, + uniswapAssets: {}, }; export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft => { @@ -211,6 +243,7 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = draft.loadingUniswap = false; draft.allowances = action.payload.allowances; draft.uniswap = action.payload.uniswap; + draft.uniswapAssets = action.payload.uniswapAssets; draft.liquidityTokens = action.payload.liquidityTokens; draft.tokenReserves = action.payload.tokenReserves; break; @@ -233,6 +266,9 @@ export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft = case UNISWAP_UPDATE_ALLOWANCES: draft.allowances = action.payload; break; + case UNISWAP_UPDATE_ASSETS: + draft.uniswapAssets = action.payload; + break; case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: draft.tokenReserves = action.payload; break; From 95cbe7f498ae62b6dbd692f74285b52176c20f12 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 22 Aug 2019 20:07:54 -0700 Subject: [PATCH 226/636] read asset prices from redux --- src/hoc/withUniswapAssets.js | 29 +++++++-------- src/redux/uniswap.js | 10 +++++- src/screens/ExchangeModal.js | 69 ++++++++++++++++++++---------------- 3 files changed, 60 insertions(+), 48 deletions(-) diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 97d3fd94d3d..6177ab808b2 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -16,11 +16,10 @@ import uniswapAssetsRaw from '../references/uniswap-pairs.json'; import withAccountData from './withAccountData'; const allAssetsSelector = state => state.allAssets; -const unsortedUniswapAssetsSelector = state => state.unsortedUniswapAssets; - -const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => toLower(key)); - +const uniswapAssetsSelector = state => state.uniswapAssets; +export const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => toLower(key)); export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); + const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); const withAssetsAvailableOnUniswap = (allAssets) => { @@ -32,16 +31,8 @@ const withAssetsAvailableOnUniswap = (allAssets) => { return { assetsAvailableOnUniswap }; }; -const mapUniswapAssetItem = ({ exchangeAddress, ...asset }, address) => ({ - ...asset, - address, - exchangeAddress, - uniqueId: exchangeAddress, -}); - -const unsortedUniswapAssets = values(mapValues(uniswapAssetsRaw, mapUniswapAssetItem)); const withSortedUniswapAssets = (unsortedUniswapAssets) => ({ - sortedUniswapAssets: sortBy(unsortedUniswapAssets, property('name')), + sortedUniswapAssets: sortBy(values(unsortedUniswapAssets), property('name')), }); const withAssetsAvailableOnUniswapSelector = createSelector( @@ -50,15 +41,21 @@ const withAssetsAvailableOnUniswapSelector = createSelector( ); const withSortedUniswapAssetsSelector = createSelector( - [unsortedUniswapAssetsSelector], + [uniswapAssetsSelector], withSortedUniswapAssets, ); +const mapStateToProps = ({ + uniswap: { uniswapAssets }, +}) => ({ + uniswapAssets, +}); + + export default compose( + connect(mapStateToProps), withAccountData, - withProps({ unsortedUniswapAssets }), withProps(withSortedUniswapAssetsSelector), withProps(withAssetsAvailableOnUniswapSelector), - omitProps('unsortedUniswapAssets'), ); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index abf70845aa6..67b1f57bab9 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -17,6 +17,7 @@ import { getReserve, getReserves, } from '../handlers/uniswap'; +import { uniswapAssetsRawLoweredKeys } from '../hoc/withUniswapAssets'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -147,7 +148,14 @@ export const uniswapUpdateAllowances = (tokenAddress, allowance) => (dispatch, g export const uniswapUpdateAssets = (assets) => { const { accountAddress, network } = getState().settings; - const mappedAssets = keyBy(assets, (asset) => asset.address.toLowerCase()); + const uniswapAssetPrices = map(assets, asset => { + const loweredAddress = asset.address.toLowerCase(); + return { + ...asset, + exchangeAddress: get(uniswapAssetsRawLoweredKeys, `[${loweredAddress}].exchangeAddress`), + }; + }); + const mappedAssets = keyBy(uniswapAssetPrices, (asset) => asset.address.toLowerCase()); dispatch({ payload: mappedAssets, type: UNISWAP_UPDATE_ASSETS, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index f5ce2d0a23f..ebd2b7c7f4e 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -99,11 +99,13 @@ class ExchangeModal extends PureComponent { state = { inputAllowance: null, inputAmount: null, + inputAmountDisplay: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), nativeAmount: null, needsApproval: false, outputAmount: null, + outputAmountDisplay: null, outputCurrency: null, showConfirmButton: false, slippage: null, @@ -230,9 +232,11 @@ class ExchangeModal extends PureComponent { this.setState({ tradeDetails }); const { rawUpdatedValue, slippage } = this.parseTradeDetails(path, tradeDetails, decimals); if (inputAsExactAmount) { - this.setState({ outputAmount: rawUpdatedValue, slippage }); + const outputAmountDisplay = updatePrecisionToDisplay(rawUpdatedValue, get(outputCurrency, 'price.value')); + this.setState({ outputAmount: rawUpdatedValue, outputAmountDisplay, slippage }); } else { - this.setState({ inputAmount: rawUpdatedValue, slippage }); + const inputAmountDisplay = updatePrecisionToDisplay(rawUpdatedValue, get(inputCurrency, 'price.value')); + this.setState({ inputAmount: rawUpdatedValue, inputAmountDisplay, slippage }); } } catch (error) { console.log('error getting market details', error); @@ -240,34 +244,37 @@ class ExchangeModal extends PureComponent { } } - setInputAsExactAmount = (inputAsExactAmount) => this.setState({ inputAsExactAmount }) - - setNativeAmount = async (nativeAmount) => { - this.setState({ nativeAmount }); - const nativePrice = get(this.state.inputCurrency, 'native.price.amount', 0); - this.setState({ inputAmount: convertAmountFromNativeValue(nativeAmount, nativePrice) }); - this.setInputAsExactAmount(true); - await this.getMarketDetails(); + setNativeAmount = async nativeAmountDisplay => { + const nativeAmount = convertAmountFromNativeDisplay(nativeAmountDisplay, this.props.nativeCurrency); + const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); + const inputAmountDisplay = updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')); + this.setState({ + inputAmount, + inputAmountDisplay, + inputAsExactAmount: true, + nativeAmount: nativeAmountDisplay, + }); } - setInputAmount = async (inputAmount) => { - this.setState({ inputAmount }); - - let newNativeAmount = null; - if (inputAmount) { - const nativePrice = get(this.state.inputCurrency, 'native.price.amount', 0); - newNativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); - } - - this.setState({ nativeAmount: newNativeAmount }); - this.setInputAsExactAmount(true); - await this.getMarketDetails(); + setInputAmount = async inputAmount => { + const nativeAmount = convertAmountToNativeAmount( + inputAmount, + get(this.state.inputCurrency, 'native.price.amount', 0) + ); + this.setState({ + inputAmount, + inputAmountDisplay: inputAmount, + inputAsExactAmount: true, + nativeAmount, + }); } - setOutputAmount = async (outputAmount) => { - this.setState({ outputAmount }); - this.setInputAsExactAmount(false); - await this.getMarketDetails(); + setOutputAmount = async outputAmount => { + this.setState({ + inputAsExactAmount: false, + outputAmount, + outputAmountDisplay: outputAmount, + }); } setInputCurrency = (inputCurrencySelection, force) => { @@ -381,11 +388,11 @@ class ExchangeModal extends PureComponent { } = this.props; const { - inputAmount, + inputAmountDisplay, inputCurrency, nativeAmount, needsApproval, - outputAmount, + outputAmountDisplay, outputCurrency, showConfirmButton, slippage, @@ -416,7 +423,7 @@ class ExchangeModal extends PureComponent { From d164254a349783b4b9aea13008d32c89dc8a269b Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 26 Aug 2019 15:17:53 -0400 Subject: [PATCH 227/636] bugfixes + tweak decimal logic --- src/helpers/__tests__/utilities.test.js | 13 +++++++++---- src/helpers/utilities.js | 5 ++--- src/hoc/withUniswapAssets.js | 7 ++++++- src/redux/data.js | 3 --- src/redux/explorer.js | 2 +- src/redux/uniswap.js | 4 ++-- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js index de2dfe9c828..9c78f102927 100644 --- a/src/helpers/__tests__/utilities.test.js +++ b/src/helpers/__tests__/utilities.test.js @@ -1,22 +1,27 @@ import { updatePrecisionToDisplay } from '../utilities'; test('updatePrecisionToDisplay', () => { - const result = updatePrecisionToDisplay('0.123456789', '3.00'); + const result = updatePrecisionToDisplay('0.17987196800000002', '0.17987196800000002'); + expect(result).toBe('0.18'); +}); + +test('updatePrecisionToDisplay', () => { + const result = updatePrecisionToDisplay('0.123456789', '3.001'); expect(result).toBe('0.123'); }); test('updatePrecisionToDisplay', () => { - const result = updatePrecisionToDisplay('0.123456789', '32.04'); + const result = updatePrecisionToDisplay('0.123456789', '32.0412'); expect(result).toBe('0.1235'); }); test('updatePrecisionToDisplay', () => { - const result = updatePrecisionToDisplay('0.123456789', '132.00'); + const result = updatePrecisionToDisplay('0.123456789', '132.0051'); expect(result).toBe('0.12346'); }); test('updatePrecisionToDisplay', () => { - const result = updatePrecisionToDisplay('0.123456789', '1320.00'); + const result = updatePrecisionToDisplay('0.123456789', '1320.0112'); expect(result).toBe('0.123457'); }); diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 18fb497cf46..07ddfd929df 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -87,9 +87,8 @@ export const floorDivide = (numberOne, numberTwo) => BigNumber(`${numberOne}`) export const countDecimalPlaces = value => BigNumber(`${value}`).dp(); export const updatePrecisionToDisplay = (amount, nativePrice) => { - const totalDigits = BigNumber(`${nativePrice}`) - .shiftedBy(2) - .sd(true); + const significantDigits = BigNumber(`${nativePrice}`).decimalPlaces(0, BigNumber.ROUND_DOWN).sd(true); + const totalDigits = BigNumber(significantDigits).plus(2, 10).toNumber(); return BigNumber(`${amount}`) .decimalPlaces(totalDigits, BigNumber.ROUND_HALF_UP) .toFixed(); diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 6177ab808b2..90daa82757d 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -10,7 +10,12 @@ import { toLower, values, } from 'lodash'; -import { compose, omitProps, withProps } from 'recompact'; +import { connect } from 'react-redux'; +import { + compose, + omitProps, + withProps, +} from 'recompact'; import { createSelector } from 'reselect'; import uniswapAssetsRaw from '../references/uniswap-pairs.json'; import withAccountData from './withAccountData'; diff --git a/src/redux/data.js b/src/redux/data.js index 680f60fa5b9..878d5c9213f 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -254,10 +254,7 @@ export const assetsReceived = (message) => (dispatch, getState) => { }; export const priceChanged = (message) => (dispatch, getState) => { - const isValidMeta = dispatch(checkMeta(message)); - // TODO is it asset_code in meta? const address = get(message, 'meta.asset_code'); - const price = get(message, 'payload.price'); if (isNil(price)) return; dispatch(uniswapUpdateAssetPrice(address, price)); diff --git a/src/redux/explorer.js b/src/redux/explorer.js index bebd4a65fe1..f581c9f55b6 100644 --- a/src/redux/explorer.js +++ b/src/redux/explorer.js @@ -123,7 +123,7 @@ const listenOnAssetMessages = socket => (dispatch, getState) => { }); socket.on(messages.ASSETS.CHANGED, (message) => { - // dispatch(priceChanged(message)); + dispatch(priceChanged(message)); }); }; diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 67b1f57bab9..3ab3e4d66cd 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -146,7 +146,7 @@ export const uniswapUpdateAllowances = (tokenAddress, allowance) => (dispatch, g saveAccountLocal(ALLOWANCES, updatedAllowances, accountAddress, network); }; -export const uniswapUpdateAssets = (assets) => { +export const uniswapUpdateAssets = (assets) => (dispatch, getState) => { const { accountAddress, network } = getState().settings; const uniswapAssetPrices = map(assets, asset => { const loweredAddress = asset.address.toLowerCase(); @@ -163,7 +163,7 @@ export const uniswapUpdateAssets = (assets) => { saveAccountLocal(ASSETS, mappedAssets, accountAddress, network); }; -export const uniswapUpdateAssetPrice = (address, price) => { +export const uniswapUpdateAssetPrice = (address, price) => (dispatch, getState) => { const addressKey = address.toLowerCase(); const { accountAddress, network } = getState().settings; const { uniswapAssets } = getState().uniswap; From 1f5eaad6dc78f41718d806b96071c7a7d38762fa Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 19 Aug 2019 02:49:56 -0700 Subject: [PATCH 228/636] Move ExchangeModalNavigator to the /navigation directory --- src/navigation/ExchangeModalNavigator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navigation/ExchangeModalNavigator.js b/src/navigation/ExchangeModalNavigator.js index 963da9d9968..a2d23887639 100644 --- a/src/navigation/ExchangeModalNavigator.js +++ b/src/navigation/ExchangeModalNavigator.js @@ -54,8 +54,8 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen -const EnhancedExchangeModalNavigator = props => ;//React.memo(); +const EnhancedExchangeModalNavigator = React.memo(props => ); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ ...navigation.state.params, From 510b6a6d574b98efee72d606472bb8fcd03b6bb3 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 24 Aug 2019 21:04:27 -0700 Subject: [PATCH 229/636] begin fixing up the ExchangeModal input logic --- ios/Podfile.lock | 83 +++---- src/components/exchange/ExchangeInputField.js | 19 +- .../layout/KeyboardFixedOpenLayout.js | 4 +- src/hoc/withUniswapAssets.js | 1 - src/navigation/ExchangeModalNavigator.js | 13 +- src/redux/uniswap.js | 2 +- src/screens/CurrencySelectModal.js | 4 +- src/screens/ExchangeModal.js | 21 +- src/utils/contract.js | 16 +- src/utils/ethereumUtils.js | 10 +- yarn.lock | 212 ++++++++++++++++++ 11 files changed, 312 insertions(+), 73 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8f19c65d440..7bf6b36e9b4 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Analytics (3.6.10) + - Analytics (3.7.0) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React @@ -40,40 +40,26 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - GoogleToolboxForMac/Defines (2.2.0) - - GoogleToolboxForMac/Logger (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSData+zlib (2.2.0)": - - GoogleToolboxForMac/Defines (= 2.2.0) - - libwebp (1.0.2): - - libwebp/core (= 1.0.2) - - libwebp/dec (= 1.0.2) - - libwebp/demux (= 1.0.2) - - libwebp/dsp (= 1.0.2) - - libwebp/enc (= 1.0.2) - - libwebp/mux (= 1.0.2) - - libwebp/utils (= 1.0.2) - - libwebp/webp (= 1.0.2) - - libwebp/core (1.0.2): + - GoogleToolboxForMac/Defines (2.2.1) + - GoogleToolboxForMac/Logger (2.2.1): + - GoogleToolboxForMac/Defines (= 2.2.1) + - "GoogleToolboxForMac/NSData+zlib (2.2.1)": + - GoogleToolboxForMac/Defines (= 2.2.1) + - libwebp (1.0.3): + - libwebp/demux (= 1.0.3) + - libwebp/mux (= 1.0.3) + - libwebp/webp (= 1.0.3) + - libwebp/demux (1.0.3): - libwebp/webp - - libwebp/dec (1.0.2): - - libwebp/core - - libwebp/demux (1.0.2): - - libwebp/core - - libwebp/dsp (1.0.2): - - libwebp/core - - libwebp/enc (1.0.2): - - libwebp/core - - libwebp/mux (1.0.2): - - libwebp/core - - libwebp/utils (1.0.2): - - libwebp/core - - libwebp/webp (1.0.2) + - libwebp/mux (1.0.3): + - libwebp/demux + - libwebp/webp (1.0.3) - nanopb (0.3.901): - nanopb/decode (= 0.3.901) - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) +<<<<<<< HEAD <<<<<<< HEAD - Protobuf (3.9.0) - React (0.60.5): @@ -123,6 +109,9 @@ PODS: - React-jsinspector (0.60.5) ======= - Protobuf (3.7.0) +======= + - Protobuf (3.9.0) +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic - React (0.59.9): - React/Core (= 0.59.9) >>>>>>> 730537c6... catching up with latest mike-swap-ui changes @@ -139,7 +128,11 @@ PODS: - react-native-fast-image (6.1.1): - React - SDWebImage (~> 5.0) +<<<<<<< HEAD - react-native-netinfo (4.2.1): +======= + - react-native-netinfo (4.1.5): +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic - React - react-native-version-number (0.3.6): - React @@ -185,6 +178,7 @@ PODS: - React - RNStoreReview (0.1.5): - React +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -194,6 +188,11 @@ PODS: - SDWebImage (5.0.2): - SDWebImage/Core (= 5.0.2) - SDWebImage/Core (5.0.2) +======= + - SDWebImage (5.1.0): + - SDWebImage/Core (= 5.1.0) + - SDWebImage/Core (5.1.0) +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic - yoga (0.59.9.React) >>>>>>> 730537c6... catching up with latest mike-swap-ui changes @@ -334,17 +333,17 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 + Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 - FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d - FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 - FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 - FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 + Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa + FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 + FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 + FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 + FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 <<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 @@ -363,16 +362,20 @@ SPEC CHECKSUMS: ======= Folly: de497beb10f102453a1afa9edbf8cf8a251890de glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d - GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d - libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 + GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 + libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a + Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f >>>>>>> 730537c6... catching up with latest mike-swap-ui changes react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 +<<<<<<< HEAD react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 +======= + react-native-netinfo: 0e563248a4b9a99c33ec29bd03c2d50767db22a6 +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e @@ -393,11 +396,15 @@ SPEC CHECKSUMS: RNReanimated: da57ffa32f04cebe2107da0b281999a01c0d1ecc RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 ======= SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 +======= + SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> 730537c6... catching up with latest mike-swap-ui changes diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 8a9d2d37de3..a6f821c4ba6 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -26,14 +26,16 @@ export default class ExchangeInputField extends Component { nativeAmount: PropTypes.string, nativeCurrency: PropTypes.string, nativeFieldRef: PropTypes.func, - needsApproval: PropTypes.bool, + onFocus: PropTypes.func, onPressMaxBalance: PropTypes.func, onPressSelectInputCurrency: PropTypes.func, + onPressUnlockAsset: PropTypes.func, setInputAmount: PropTypes.func, setNativeAmount: PropTypes.func, } inputFieldRef = undefined + nativeFieldRef = undefined padding = 15 @@ -51,7 +53,7 @@ export default class ExchangeInputField extends Component { || isNewAssetApproved || isNewNativeAmount || isNewNativeCurrency - ) + ); } handleFocusInputField = () => { @@ -80,29 +82,22 @@ export default class ExchangeInputField extends Component { const { nativeAmount, nativeCurrency, - nativeFieldRef, - needsApproval, onFocus, setNativeAmount, } = this.props; const { mask, placeholder, symbol } = supportedNativeCurrencies[nativeCurrency]; - const symbolColor = ( - !!nativeAmount - ? colors.dark - : ExchangeInput.defaultProps.placeholderTextColor - ); - return ( - + ); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; -EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => ({ - ...navigation.state.params, - gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), -}); +EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => { + // console.log('navigation', navigation); + + + return ({ + ...navigation.state.params, + gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), + }); +} export default EnhancedExchangeModalNavigator; diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 3ab3e4d66cd..761b7a9d7e3 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -242,7 +242,7 @@ export const INITIAL_UNISWAP_STATE = { uniswapAssets: {}, }; -export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft => { +export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, (draft) => { switch (action.type) { case UNISWAP_LOAD_REQUEST: draft.loadingUniswap = true; diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 6ec262e9fc0..65c3b642d74 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -191,6 +191,8 @@ class CurrencySelectModal extends PureComponent { isTransitioning || listItems.length === 0 ); + console.log('listItems', listItems); + // console.log('isFocused', isFocused ? '👍️' : '👎️', ' ', isFocused); return ( @@ -202,7 +204,7 @@ class CurrencySelectModal extends PureComponent { extrapolate: 'clamp', inputRange: [0, 1], outputRange: [0, 1], - }) + }), }} > { } const firstAddress = get(firstAsset, 'address', '').toLowerCase(); - const secondAddress = get(firstAsset, 'address', '').toLowerCase(); + const secondAddress = get(secondAsset, 'address', '').toLowerCase(); return firstAddress === secondAddress; -} +}; class ExchangeModal extends PureComponent { static propTypes = { @@ -134,7 +134,7 @@ class ExchangeModal extends PureComponent { } if (outputCurrency) { - console.log('should showConfirmButton'); + // console.log('should showConfirmButton'); this.setState({ showConfirmButton: true }); } @@ -278,8 +278,11 @@ class ExchangeModal extends PureComponent { } setInputCurrency = (inputCurrencySelection, force) => { + const { accountAddress } = this.props; const { inputCurrency, outputCurrency } = this.state; + console.log('inputCurrencySelection', inputCurrencySelection); + const allowance = contractUtils.getAllowance(accountAddress); this.setState({ inputCurrency: inputCurrencySelection }); if (!force && isSameAsset(inputCurrency, outputCurrency)) { @@ -298,10 +301,11 @@ class ExchangeModal extends PureComponent { this.setState({ outputCurrency }); if (!force && isSameAsset(inputCurrency, outputCurrency)) { + console.log('outputCurrency', outputCurrency); const asset = ethereumUtils.getAsset(allAssets, outputCurrency.address.toLowerCase()); console.log('asset', asset); - // + if (inputCurrency !== null && outputCurrency !== null && !isNil(asset)) { this.setInputCurrency(null, true); } else { @@ -356,7 +360,7 @@ class ExchangeModal extends PureComponent { handleWillFocus = ({ lastState }) => { if (!lastState && this.inputFieldRef) { - return this.inputFieldRef.focus(); + this.inputFieldRef.focus(); } } @@ -398,6 +402,12 @@ class ExchangeModal extends PureComponent { slippage, } = this.state; + console.log(' ') + console.log('ExchangeModal -- this.props', this.props); + console.log('ExchangeModal -- this.state', this.state); + console.log(' ') + + return ( { - const { address: tokenAddress, decimals } = token; - const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); - const allowance = await tokenContract.allowance(owner, spender); - const rawAllowance = ethers.utils.bigNumberify(allowance.toString()); - return convertRawAmountToDecimalFormat(rawAllowance, decimals); -}; - export const approve = async (tokenAddress, spender) => { const wallet = await loadWallet(); if (!wallet) return null; @@ -20,6 +12,14 @@ export const approve = async (tokenAddress, spender) => { return exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); }; +export const getAllowance = async (owner, token, spender) => { + const { address: tokenAddress, decimals } = token; + const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); + const allowance = await tokenContract.allowance(owner, spender); + const rawAllowance = ethers.utils.bigNumberify(allowance.toString()); + return convertRawAmountToDecimalFormat(rawAllowance, decimals); +}; + export default { approve, getAllowance, diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index 297193d7fbc..ea5d4e61ccc 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -22,7 +22,15 @@ export const getBalanceAmount = (gasPrice, selected) => { return amount; }; -export const getAsset = (assets, address = 'eth') => find(assets, asset => asset.address === address); +export const getAsset = (assets, address = 'eth') => { + return find(assets, asset => { + // console.log('asset', asset); + // console.log('asset.address', asset.address); + // console.log('address', address) + + return asset.address === address + }); +} /** * @desc remove hex prefix diff --git a/yarn.lock b/yarn.lock index dac32e80537..53242d5cf4d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1098,6 +1098,7 @@ integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== "@react-native-community/netinfo@^4.1.4": +<<<<<<< HEAD version "4.2.1" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== @@ -1106,16 +1107,33 @@ version "3.5.1" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.1.tgz#7a2339fca3496979305fb3a8ab88c2ca8d8c214d" integrity sha512-q7NyhWVYOhVIWqL2GZKa6G78YarXaVTTtOlSDkvy4ZIggo40wZzamlnrJRvsaQX46gsgw45FAWb5SriHh8o7eA== +======= + version "4.1.5" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.5.tgz#4bb44842db6a1a18f00a0f061b0e3dcc638f67dd" + integrity sha512-lagdZr9UiVAccNXYfTEj+aUcPCx9ykbMe9puffeIyF3JsRuMmlu3BjHYx1klUHX7wNRmFNC8qVP0puxUt1sZ0A== + +"@react-navigation/core@~3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.0.tgz#73d1a12448e2bd71855e0080b95a7f51ede0cd9e" + integrity sha512-NLm24lA51R8o8c+iFnwtN9elqRzm4OJ8f1qPBCUNIYW1sb8M5yCD53vRP0fRcPFpr/6Xzs2TJMsWnnebwFp0Rw== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: hoist-non-react-statics "^3.3.0" path-to-regexp "^1.7.0" query-string "^6.4.2" react-is "^16.8.6" +<<<<<<< HEAD "@react-navigation/native@~3.6.1": version "3.6.2" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== +======= +"@react-navigation/native@~3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.0.tgz#dabf93382f75037c01dfdd2a03807e40b48a4d61" + integrity sha512-MmsEF4Gf3DD7rtZlbOLULQOBCxE2nGz6FdPYxtlEI+N/E2I5OrdxrTNAA7EGWsIiaJEapU4bp0a+tLjh/9PQpA== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -1349,6 +1367,7 @@ integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== "@types/node@^10.3.2": +<<<<<<< HEAD version "10.14.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== @@ -1357,6 +1376,16 @@ version "8.10.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== +======= + version "10.14.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.16.tgz#4d690c96cbb7b2728afea0e260d680501b3da5cf" + integrity sha512-/opXIbfn0P+VLt+N8DE4l8Mn8rbhiJgabU96ZJ0p9mxOkIks5gh6RUnpHak7Yh0SFkyjO/ODbxsQQPV2bpMmyA== + +"@types/node@^8.0.7": + version "8.10.52" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.52.tgz#ef0ca1809994e20186090408b8cb7f2a6877d5f9" + integrity sha512-2RbW7WXeLex6RI+kQSxq6Ym0GiVcODeQ4Km7MnnTX5BHdOGQnqVa+s6AUmAW+OFYAJ8wv9QxvNZXm7/kBdGTVw== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic "@types/q@^1.5.1": version "1.5.2" @@ -1391,9 +1420,15 @@ "@types/vfile-message" "*" "@types/yargs-parser@*": +<<<<<<< HEAD version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== +======= + version "13.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" + integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic "@types/yargs@^13.0.0": version "13.0.2" @@ -1449,6 +1484,7 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" +<<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.36": version "1.0.0-beta.36" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.36.tgz#671f70f739d1d9857456e45060727548317fe86a" @@ -1475,11 +1511,43 @@ version "1.0.0-beta.36" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.36.tgz#34c9def70f9db1ffcdd8e5fc94d9ce30dc716b8a" integrity sha512-SlAqiWJLs/EG+eqxqWO/zOZRz06GYBKGlfK5OX203UjOl6Ps8WLN/D7l8llX97TdGzcGw5+b9Wq+kKuWR2HFQA== +======= +"@walletconnect/core@^1.0.0-beta.33": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.33.tgz#ba8c4d1682c00630124cfacd8c3ac28a37737ffc" + integrity sha512-VnipTAEiVJx0fKR7kVKQ/KIaEDCFjIEF4wGSl73uuhp+YPBZSN0fXQ0/joF00dGUxVY6RiwmCQlmz5ZKpcGWYw== + dependencies: + "@walletconnect/types" "^1.0.0-beta.33" + "@walletconnect/utils" "^1.0.0-beta.33" + +"@walletconnect/react-native@^1.0.0-beta.29": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.33.tgz#21542022f8204648e924a40c6f79c93bde109f5a" + integrity sha512-AFGiXFZXQ1HINGiQESRciMlu7R6s0e2s7LeC5g+EdQrtDDqSsEx9W6Lb8VMPQPnPREmcmcaz4B9L/wyUjNXXew== + dependencies: + "@walletconnect/core" "^1.0.0-beta.33" + "@walletconnect/types" "^1.0.0-beta.33" + "@walletconnect/utils" "^1.0.0-beta.33" + +"@walletconnect/types@^1.0.0-beta.33": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.33.tgz#2c95191e0a2986b24e4f66baeeeaa79f87dc52f4" + integrity sha512-RGC5F4Qb9IApPaOIZwiQVzT4b6K+vmgh0mi/7qHICzSylMJ9BZmvdDOn61+jgSBCjzQ/lmJROsQeXAABCU08rw== + +"@walletconnect/utils@^1.0.0-beta.33": + version "1.0.0-beta.33" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.33.tgz#59ff7edc74608398a341264bad781f24b4cf599f" + integrity sha512-BAKV+tVoN5QGoMDzF/JleO0s80wLoeJFAsw8/IG9QCSnHi4swZsin0Zk2TRYVb+gC/ZuDmMvwMHVkmVUqz7fOg== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" +<<<<<<< HEAD "@walletconnect/types" "^1.0.0-beta.36" +======= + "@walletconnect/types" "^1.0.0-beta.33" +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -3574,10 +3642,16 @@ electron-to-chromium@^1.3.247: integrity sha512-NMHS8iQzAYwiFZ1jL/rNOfrZJhvoowKN5uHrbbHOeNgBT5W762wpe/SRLo9kJoTiJ4d2R8i01/NQHwndo9N5PQ== ======= electron-to-chromium@^1.3.191: +<<<<<<< HEAD version "1.3.229" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.229.tgz#accc9a08dd07d0a4d6c76937821bc94eb2e49eae" integrity sha512-N6pUbSuKFBeUifxBZp9hODS1N9jFobJYW47QT2VvZIr+G5AWnHK/iG3ON9RPRGH7lHDQ6KUDVhzpNkj4ZiznoA== >>>>>>> 730537c6... catching up with latest mike-swap-ui changes +======= + version "1.3.238" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.238.tgz#6d6496e393a709b7b186823281d49b1a5d96a6cf" + integrity sha512-k+s6EIiSTgfOm7WiMlGBMMMtBQXSui8OfLN1sXU3RohJOuLGVq0lVm7hXyDIDBcbPM0MeZabAdIPQOSEZT3ZLg== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic elliptic@6.3.3: version "6.3.3" @@ -3935,9 +4009,15 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.1.0: +<<<<<<< HEAD version "6.4.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== +======= + version "6.2.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" + integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4031,9 +4111,15 @@ eth-contract-metadata@^1.9.2: integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== ethers@^4.0.28, ethers@^4.0.33: +<<<<<<< HEAD version "4.0.37" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== +======= + version "4.0.36" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.36.tgz#96519fd3cc9317f938c8ee4d22050f34e3c2ef0e" + integrity sha512-rWdchEhUyXx01GiwexH6Sha97CQ9tJdQwe6FtYKxShC7VEZV41nuKt+lzCQ4OqvQwZK5PcAKaAZv2GDsCH33SA== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -4152,6 +4238,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +<<<<<<< HEAD +======= +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic expect@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" @@ -5084,9 +5180,15 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: +<<<<<<< HEAD version "17.0.15" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.15.tgz#a4a378910fa06ca1c34f9e481ff6642acdb16dba" integrity sha512-d+DLqZY1G15jDhSLRtsCVd/+KAWKmcmX1bp/5RjamIhftEFDvSXVgWXXkzsBFIl41VHhBV1y5JORukgz1s3GCQ== +======= + version "17.0.12" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.12.tgz#d732a6c1131fc3b02305a8241eac25ec0d1cf663" + integrity sha512-FoYYnORcAMNznVXSpwJ1zVGL8kXcv1JUmvTqoQyuPPRncBq9rd7Mi0I/oVXkGR3YIek5dDiunvA/NGG2o+mMuw== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: "@babel/runtime" "^7.3.1" @@ -5831,6 +5933,22 @@ jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== +<<<<<<< HEAD +======= + +jest-haste-map@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" + integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-serializer "^24.0.0-alpha.6" + jest-worker "^24.0.0-alpha.6" + micromatch "^2.3.11" + sane "^3.0.0" +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic jest-haste-map@^24.7.1, jest-haste-map@^24.9.0: version "24.9.0" @@ -5995,8 +6113,18 @@ jest-runtime@^24.9.0: slash "^2.0.0" strip-bom "^3.0.0" yargs "^13.3.0" +<<<<<<< HEAD jest-serializer@^24.4.0, jest-serializer@^24.9.0: +======= + +jest-serializer@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" + integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== + +jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0, jest-serializer@^24.9.0: +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== @@ -6071,6 +6199,17 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" +<<<<<<< HEAD +======= +jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic jest@^24.8.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" @@ -7130,9 +7269,15 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: +<<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== +======= + version "2.4.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.4.0.tgz#38f0af94f42fb6f34d3d7d82a90e2c99cd3ff485" + integrity sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -7385,10 +7530,17 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" +<<<<<<< HEAD node-releases@^1.1.29: version "1.1.30" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== +======= +node-releases@^1.1.25: + version "1.1.28" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.28.tgz#503c3c70d0e4732b84e7aaa2925fbdde10482d4a" + integrity sha512-AQw4emh6iSXnCpDiFe0phYcThiccmkNWMZnFZ+lDJjAP8J0m2fVd59duvUUyuTirQOhIAajTFkzG6FHCLBO59g== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: semver "^5.3.0" @@ -8326,6 +8478,17 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +<<<<<<< HEAD +======= +pretty-format@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" + integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== + dependencies: + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic pretty-format@^24.7.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" @@ -8811,9 +8974,15 @@ react-native-redash@^7.5.1: use-memo-one "^1.1.1" react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: +<<<<<<< HEAD version "0.14.8" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== +======= + version "0.14.7" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" + integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: hoist-non-react-statics "^2.3.1" @@ -8849,9 +9018,15 @@ react-native-store-review@^0.1.5: integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== react-native-svg@^9.6.2: +<<<<<<< HEAD version "9.9.3" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.9.3.tgz#5dab1a44b20b13a3f35245a286f30882b9611d66" integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== +======= + version "9.6.4" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.4.tgz#f9ceb228efd07317a5f9c378c6b9c5e13ff50cd0" + integrity sha512-6SlbGx0vlXHyDPQXSpX+8o6bNjxKFNJsISoboAkR7YWW6hdnkMg/HJXCgT6oJC0/ClKtSO7ZPrQcK4HR65kDNg== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -8948,7 +9123,18 @@ react-navigation-drawer@~1.4.0: dependencies: react-native-tab-view "^1.2.0" +<<<<<<< HEAD "react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.5.0: +======= +react-navigation-stack@^2.0.0-alpha.9: + version "2.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.9.tgz#6e0382f3f4e37235c94badf6712c7095415d4a6d" + integrity sha512-Lze5CuCDr9FtGIJyxG8e1YXbpyd77XjOgLnQN5PRG9qx7YNmAbkbybPrhsmlRVWiyosC8IEVFbnot0EDcR+O/w== + dependencies: + react-native-safe-area-view "^0.14.6" + +"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "2.0.0-alpha.7" resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" dependencies: @@ -8974,12 +9160,21 @@ react-navigation-tabs@~1.2.0: react-native-tab-view "^1.4.1" react-navigation@^3.11.1: +<<<<<<< HEAD version "3.12.1" resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== dependencies: "@react-navigation/core" "~3.5.0" "@react-navigation/native" "~3.6.1" +======= + version "3.12.0" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.0.tgz#31cc6c7d778c968965e86a820f12f1e1a66e20b9" + integrity sha512-Lr0l0lbZsFsajUx040I1HYm0yIfa+F9SCEeaNkS1eiey6k2G04eY5hYGZfo4i3kaMj99Yi8tuRcSN7DS0QZu8w== + dependencies: + "@react-navigation/core" "~3.5.0" + "@react-navigation/native" "~3.6.0" +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic react-navigation-drawer "~1.4.0" react-navigation-stack "~1.5.0" react-navigation-tabs "~1.2.0" @@ -9193,10 +9388,16 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" +<<<<<<< HEAD recyclerlistview@2.0.1-alpha.1: version "2.0.1-alpha.1" resolved "https://registry.yarnpkg.com/recyclerlistview/-/recyclerlistview-2.0.1-alpha.1.tgz#881955e6917911fb54a9b272004e39e5c0d64f4a" integrity sha512-UaeJyxG9LL8lcfiAqkp0kPLxvjbYg95Dcq1U/QUvzwXU4+H2khg/LAws/FssxPX6CXNMw7BLcT2YHAhkFElqRQ== +======= +recyclerlistview@Flipkart/recyclerlistview#master: + version "2.0.13" + resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/6c191661214a53f6ba24567528f0de7902ffda6c" +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic dependencies: lodash.debounce "4.0.8" prop-types "15.5.8" @@ -9557,7 +9758,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +<<<<<<< HEAD rn-nodeify@10.1.0: +======= +rn-nodeify@^10.0.1: +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "10.1.0" resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.1.0.tgz#e36c4aa25d6bf1dbde7d9f733ab30168772d50c6" integrity sha512-EW9I7OWt1aTShdJEnnS/qoEvfb2myLee6uWcAMxJWcisn3z3DxWTTLfm5bqwn/2eYjcs6j677JLY6nL02uMaaQ== @@ -10832,10 +11037,17 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +<<<<<<< HEAD type-fest@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +======= +type-fest@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" + integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== +>>>>>>> b318d04e... begin fixing up the ExchangeModal input logic typedarray@^0.0.6: version "0.0.6" From 4fe9757fdd4cd81f1f11dfd5ae699b409aff7849 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sun, 25 Aug 2019 05:12:55 -0700 Subject: [PATCH 230/636] delete some unused utility functions --- src/helpers/time.js | 35 ------------------------------ src/helpers/utilities.js | 46 +--------------------------------------- 2 files changed, 1 insertion(+), 80 deletions(-) diff --git a/src/helpers/time.js b/src/helpers/time.js index 7e0df496306..80725891ed3 100644 --- a/src/helpers/time.js +++ b/src/helpers/time.js @@ -2,25 +2,11 @@ import { convertStringToNumber, divide, formatFixedDecimals, - floorDivide, - greaterThanOrEqual, - mod, multiply, } from './utilities'; import timeUnits from '../references/time-units.json'; import lang from '../languages'; -/** - * @desc get local time & date string - * @param {Number} [timestamp=null] - * @return {String} - */ -export const getLocalTimeDate = (timestamp = null) => { - timestamp = Number(timestamp) || Date.now(); - const date = new Date(timestamp); - return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`; -}; - /** * @desc get time string for minimal unit * @param {String} [value=''] @@ -170,24 +156,3 @@ export const getTimeString = (value = '', unit = 'ms', short = false) => { } return `${_value} ${_unit}`; }; - -/** - * @desc get countdown (hrs:mins:secs) - * @param {Number} [miliseconds] - * @return {String} - */ -export const getCountdown = miliseconds => { - let remaining = miliseconds; - let slots = [timeUnits.ms.hour, timeUnits.ms.minute, timeUnits.ms.second]; - slots = slots.map(pack => { - const result = floorDivide(remaining, pack); - remaining = mod(remaining, pack); - if (greaterThanOrEqual(result, 1)) { - return result.length < 2 ? `0${result}` : result; - } - return null; - }); - return `${slots[0] ? `${slots[0]}:` : ''}${ - slots[1] ? `${slots[1]}:` : '00:' - }${slots[1] ? slots[2] || '00' : slots[2]}`; -}; diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 07ddfd929df..b5dd2967776 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -1,4 +1,4 @@ -import { get, split } from 'lodash'; +import { get } from 'lodash'; import BigNumber from 'bignumber.js'; import supportedNativeCurrencies from '../references/native-currencies.json'; @@ -359,47 +359,3 @@ export const convertRawAmountToDecimalFormat = (value, decimals = 18) => BigNumb .toFixed(); export const fromWei = (number) => convertRawAmountToDecimalFormat(number, 18); - -/** - * @desc ellipse text to max maxLength - * @param {String} [text = ''] - * @param {Number} [maxLength = 9999] - * @return {Intercom} - */ -export const ellipseText = (text = '', maxLength = 9999) => { - if (text.length <= maxLength) return text; - const _maxLength = maxLength - 3; - let ellipse = false; - let currentLength = 0; - const result = `${text - .split(' ') - .filter(word => { - currentLength += word.length; - if (ellipse || currentLength >= _maxLength) { - ellipse = true; - return false; - } - return true; - }) - .join(' ')}...`; - return result; -}; - -/** - * @desc ellipse text to max maxLength - * @param {String} [text = ''] - * @param {Number} [maxLength = 9999] - * @return {Intercom} - */ -export const ellipseAddress = (text = '') => { - const addressArr = text.split(''); - const firstFour = text.split('', 4).join(''); - const lastFour = addressArr - .reverse() - .join('') - .split('', 4) - .reverse() - .join(''); - const result = `${firstFour}...${lastFour}`; - return result; -}; From 5fda560227b7b2ec9d5a86b64be67a00d9d94ea9 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sun, 25 Aug 2019 05:16:05 -0700 Subject: [PATCH 231/636] Break out ExchangeNativeField into its own component --- src/components/exchange/ExchangeInput.js | 9 +- src/components/exchange/ExchangeInputField.js | 115 ++++++----------- .../exchange/ExchangeNativeField.js | 119 ++++++++++++++++++ .../exchange/ExchangeOutputField.js | 1 + src/components/exchange/index.js | 1 + 5 files changed, 163 insertions(+), 82 deletions(-) create mode 100644 src/components/exchange/ExchangeNativeField.js diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 3845faeff92..1006cc61a25 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -6,6 +6,7 @@ import { colors, fonts } from '../../styles'; export default class ExchangeInput extends PureComponent { static propTypes = { + color: PropTypes.string, disableTabularNums: PropTypes.bool, fontFamily: PropTypes.string, fontSize: PropTypes.string, @@ -14,11 +15,13 @@ export default class ExchangeInput extends PureComponent { onChangeText: PropTypes.func, placeholder: PropTypes.string, placeholderTextColor: PropTypes.string, + refInput: PropTypes.func, style: stylePropType, value: PropTypes.string, } static defaultProps = { + color: colors.dark, fontFamily: fonts.family.SFProDisplay, fontSize: fonts.size.h2, fontWeight: fonts.weight.medium, @@ -29,17 +32,17 @@ export default class ExchangeInput extends PureComponent { onChangeText = (formatted, extracted) => { // XXX TODO: some funky stuff is going on here related to the '$' symbol in the input mask - this.props.onChangeText(!!extracted ? formatted : ''); + this.props.onChangeText(extracted ? formatted : ''); } render = () => { const { + color, disableTabularNums, fontFamily, fontSize, fontWeight, mask, - onChangeText, placeholder, placeholderTextColor, refInput, @@ -61,7 +64,7 @@ export default class ExchangeInput extends PureComponent { refInput={refInput} selectionColor={colors.appleBlue} style={[{ - color: colors.dark, + color, fontFamily, fontSize: parseFloat(fontSize), fontVariant: disableTabularNums ? undefined : ['tabular-nums'], diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index a6f821c4ba6..6628caa02bd 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -1,8 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; -import supportedNativeCurrencies from '../../references/native-currencies.json'; -import { colors, fonts } from '../../styles'; +import { colors } from '../../styles'; import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; import { CoolButton } from '../buttons'; @@ -15,6 +14,7 @@ import { } from '../layout'; import { Emoji, Text } from '../text'; import ExchangeInput from './ExchangeInput'; +import ExchangeNativeField from './ExchangeNativeField'; import UnlockAssetButton from './UnlockAssetButton'; export default class ExchangeInputField extends Component { @@ -36,8 +36,6 @@ export default class ExchangeInputField extends Component { inputFieldRef = undefined - nativeFieldRef = undefined - padding = 15 shouldComponentUpdate = (nextProps, nextState) => { @@ -62,81 +60,31 @@ export default class ExchangeInputField extends Component { } } - handleFocusNativeField = () => { - if (this.nativeFieldRef) { - this.nativeFieldRef.focus(); - } - } - handleInputFieldRef = (ref) => { this.inputFieldRef = ref; this.props.inputFieldRef(ref); } - handleNativeFieldRef = (ref) => { - this.nativeFieldRef = ref; - this.props.nativeFieldRef(ref); - } - - renderNativeField = () => { - const { - nativeAmount, - nativeCurrency, - onFocus, - setNativeAmount, - } = this.props; - - const { mask, placeholder, symbol } = supportedNativeCurrencies[nativeCurrency]; - - return ( - - - - {symbol} - - - - - ); - } - render = () => { const { inputAmount, inputCurrency, isAssetApproved, + nativeAmount, + nativeCurrency, + nativeFieldRef, onFocus, onPressMaxBalance, onPressSelectInputCurrency, onPressUnlockAsset, setInputAmount, + setNativeAmount, } = this.props; const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); return ( - + - - + - - - {!needsApproval && } - - {needsApproval ? 'Approve' : 'Max'} - - - + + + Max + + + ) : ( + + )} ); diff --git a/src/components/exchange/ExchangeNativeField.js b/src/components/exchange/ExchangeNativeField.js new file mode 100644 index 00000000000..487f3e6f4bb --- /dev/null +++ b/src/components/exchange/ExchangeNativeField.js @@ -0,0 +1,119 @@ +import { pick } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { TouchableWithoutFeedback } from 'react-native'; +import { withProps } from 'recompact'; +import supportedNativeCurrencies from '../../references/native-currencies.json'; +import { colors, fonts } from '../../styles'; +import { isNewValueForPath } from '../../utils'; +import { Row } from '../layout'; +import { Text } from '../text'; +import ExchangeInput from './ExchangeInput'; + +class ExchangeNativeField extends Component { + static propTypes = { + height: PropTypes.number, + mask: PropTypes.string, + nativeAmount: PropTypes.string, + nativeFieldRef: PropTypes.func, + onBlur: PropTypes.func, + onFocus: PropTypes.func, + placeholder: PropTypes.string, + setNativeAmount: PropTypes.func, + symbol: PropTypes.string, + } + + state = { isFocused: false } + + nativeFieldRef = undefined + + shouldComponentUpdate = (nextProps, nextState) => { + const isNewAmount = isNewValueForPath(this.props, nextProps, 'nativeAmount'); + const isNewFocus = isNewValueForPath(this.state, nextState, 'isFocused'); + const isNewSymbol = isNewValueForPath(this.props, nextProps, 'symbol'); + + return ( + isNewAmount + || isNewFocus + || isNewSymbol + ); + } + + focusNativeField = () => { + if (this.nativeFieldRef) { + this.nativeFieldRef.focus(); + } + } + + handleBlur = (event) => { + this.setState({ isFocused: false }); + + if (this.props.onBlur) { + this.props.onBlur(event); + } + } + + handleFocus = (event) => { + this.setState({ isFocused: true }); + + if (this.props.onFocus) { + this.props.onFocus(event); + } + } + + handleNativeFieldRef = (ref) => { + this.nativeFieldRef = ref; + this.props.nativeFieldRef(ref); + } + + render = () => { + const { + height, + mask, + nativeAmount, + placeholder, + setNativeAmount, + symbol, + } = this.props; + + const opacity = this.state.isFocused ? 1 : 0.5; + + return ( + + + + {symbol} + + + + + ); + } +} + +export default withProps(({ nativeCurrency }) => ( + pick(supportedNativeCurrencies[nativeCurrency], [ + 'mask', + 'placeholder', + 'symbol', + ]) +))(ExchangeNativeField); diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index 1e50fdde601..e2482ab5bd8 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -33,6 +33,7 @@ const FakeNotchThing = withNeverRerender(() => ( export default class ExchangeOutputField extends PureComponent { static propTypes = { + onFocus: PropTypes.func, onPressSelectOutputCurrency: PropTypes.func, outputAmount: PropTypes.string, outputCurrency: PropTypes.string, diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js index cfa2adb013f..35f4e3b2217 100644 --- a/src/components/exchange/index.js +++ b/src/components/exchange/index.js @@ -4,6 +4,7 @@ export { default as ExchangeGasFeeButton } from './ExchangeGasFeeButton'; export { default as ExchangeInput } from './ExchangeInput'; export { default as ExchangeInputField } from './ExchangeInputField'; export { default as ExchangeModalHeader } from './ExchangeModalHeader'; +export { default as ExchangeNativeField } from './ExchangeNativeField'; export { default as ExchangeOutputField } from './ExchangeOutputField'; export { default as ExchangeSearch } from './ExchangeSearch'; export { default as SlippageWarning } from './SlippageWarning'; From 1f6a88b3632ba4cdce502c81bc50c396b18c1cbc Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sun, 25 Aug 2019 05:16:42 -0700 Subject: [PATCH 232/636] =?UTF-8?q?minor=20improvements=20to=20?= =?UTF-8?q?=F0=9F=A6=84=EF=B8=8F=20redux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hoc/withUniswapAllowances.js | 10 ++++++---- src/redux/uniswap.js | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 85ee1d3618d..3af39fe2618 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -1,9 +1,11 @@ import { connect } from 'react-redux'; -import { compose } from 'recompact'; import { uniswapGetTokenReserve, uniswapUpdateAllowances } from '../redux/uniswap'; const mapStateToProps = ({ uniswap: { allowances, tokenReserves } }) => ({ allowances, tokenReserves }); -export default Component => compose( - connect(mapStateToProps, { uniswapGetTokenReserve, uniswapUpdateAllowances }), -)(Component); +export default Component => ( + connect(mapStateToProps, { + uniswapGetTokenReserve, + uniswapUpdateAllowances, + })(Component) +); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 761b7a9d7e3..639afc6e499 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -89,9 +89,9 @@ export const uniswapGetTokenReserve = (tokenAddress) => (dispatch, getState) => }); saveAccountLocal(RESERVES, updatedTokenReserves, accountAddress, network); resolve(tokenReserve); - }).catch(error => { + }).catch((error) => { dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_FAILURE }); - reject(null); + reject(error); }); }) ); From 71823a29769aef6ac3f345e7c24a2f93d7e6265a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sun, 25 Aug 2019 06:02:07 -0700 Subject: [PATCH 233/636] Improve input/output logic --- .../layout/KeyboardFixedOpenLayout.js | 2 +- src/screens/CurrencySelectModal.js | 6 +- src/screens/ExchangeModal.js | 341 +++++++++--------- 3 files changed, 169 insertions(+), 180 deletions(-) diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index 6fc894746fe..516ddcceb3d 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -42,7 +42,7 @@ class KeyboardFixedOpenLayout extends PureComponent { clearKeyboardListeners = () => { if (this.willShowListener) { - console.log('this.willShowListener', this.willShowListener); + // console.log('this.willShowListener', this.willShowListener); this.willShowListener.remove(); } diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 65c3b642d74..6a92e979cd7 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,6 +1,6 @@ import { get, map, property } from 'lodash'; import PropTypes from 'prop-types'; -import React, { Component, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import { InteractionManager, View } from 'react-native'; import { compose, mapProps, withProps } from 'recompact'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; @@ -12,7 +12,7 @@ import { withUniswapAssets, } from '../hoc'; import { borders, colors, position } from '../styles'; -import { isNewValueForPath, safeAreaInsetValues } from '../utils'; +import { isNewValueForPath } from '../utils'; import { filterList } from '../utils/search'; import { EmptyAssetList } from '../components/asset-list'; import { ExchangeCoinRow } from '../components/coin-row'; @@ -191,7 +191,7 @@ class CurrencySelectModal extends PureComponent { isTransitioning || listItems.length === 0 ); - console.log('listItems', listItems); + // console.log('listItems', listItems); // console.log('isFocused', isFocused ? '👍️' : '👎️', ' ', isFocused); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index fb4c51d30a1..d09d5cd175a 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -6,20 +6,18 @@ import { tradeTokensForExactEthWithData, tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; -import { - filter, - findIndex, - get, - isNil, - keys, - map, -} from 'lodash'; +import { get, isNil } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { InteractionManager, LayoutAnimation, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; -import { NavigationActions, NavigationEvents, withNavigationFocus } from 'react-navigation'; -import { compose, mapProps, toClass, withProps } from 'recompact'; +import { NavigationEvents, withNavigationFocus } from 'react-navigation'; +import { + compose, + mapProps, + toClass, + withProps, +} from 'recompact'; import { executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeValue, @@ -41,12 +39,7 @@ import { withUniswapAssets, } from '../hoc'; import { colors, padding, position } from '../styles'; -import { - contractUtils, - deviceUtils, - ethereumUtils, - safeAreaInsetValues, -} from '../utils'; +import { contractUtils, ethereumUtils, isNewValueForPath } from '../utils'; import { ConfirmExchangeButton, ExchangeGasFeeButton, @@ -62,7 +55,6 @@ import { Column, KeyboardFixedOpenLayout, } from '../components/layout'; -import { Text } from '../components/text'; import { CurrencySelectionTypes } from './CurrencySelectModal'; export const exchangeModalBorderRadius = 30; @@ -87,11 +79,15 @@ class ExchangeModal extends PureComponent { chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, + isFocused: PropTypes.bool, + isTransitioning: PropTypes.bool, keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, + tokenReserves: PropTypes.array, tradeDetails: PropTypes.object, + transitionPosition: PropTypes.object, // animated value uniswapGetTokenReserve: PropTypes.func, uniswapUpdateAllowances: PropTypes.func, } @@ -99,13 +95,11 @@ class ExchangeModal extends PureComponent { state = { inputAllowance: null, inputAmount: null, - inputAmountDisplay: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), + isAssetApproved: true, nativeAmount: null, - needsApproval: false, outputAmount: null, - outputAmountDisplay: null, outputCurrency: null, showConfirmButton: false, slippage: null, @@ -113,8 +107,11 @@ class ExchangeModal extends PureComponent { } componentDidUpdate = (prevProps, prevState) => { - const { isFocused, isTransitioning, keyboardFocusHistory} = this.props; - const { inputAmount, outputAmount, outputCurrency } = this.state; + const { + isFocused, + isTransitioning, + keyboardFocusHistory, + } = this.props; if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; @@ -129,16 +126,20 @@ class ExchangeModal extends PureComponent { } } - if (inputAmount || outputAmount) { - LayoutAnimation.easeInEaseOut(); + if (this.state.outputCurrency) { + this.setState({ showConfirmButton: true }); } - if (outputCurrency) { - // console.log('should showConfirmButton'); - this.setState({ showConfirmButton: true }); + const isNewNativeAmount = isNewValueForPath(this.state, prevState, 'nativeAmount'); + const isNewInputAmount = isNewValueForPath(this.state, prevState, 'inputAmount'); + const isNewOutputAmount = isNewValueForPath(this.state, prevState, 'outputAmount'); + + if (isNewNativeAmount || isNewInputAmount || isNewOutputAmount) { + this.getMarketDetails(); + LayoutAnimation.easeInEaseOut(); } - if (this.state.inputCurrency.address !== prevState.inputCurrency.address) { + if (isNewValueForPath(this.state, prevState, 'inputCurrency.address')) { this.getCurrencyAllowance(); } } @@ -147,150 +148,157 @@ class ExchangeModal extends PureComponent { this.props.clearKeyboardFocusHistory(); } + /* eslint-disable lines-between-class-members */ inputFieldRef = null - nativeFieldRef = null - outputFieldRef = null - parseTradeDetails = (path, tradeDetails, decimals) => { - const updatedValue = get(tradeDetails, path); - const slippage = get(tradeDetails, 'marketRateSlippage'); - const rawUpdatedValue = convertRawAmountToDecimalFormat(updatedValue, decimals); - return { rawUpdatedValue, slippage: slippage.toFixed() }; - }; + assignInputFieldRef = (ref) => { this.inputFieldRef = ref; } + assignNativeFieldRef = (ref) => { this.nativeFieldRef = ref; } + assignOutputFieldRef = (ref) => { this.outputFieldRef = ref; } + /* eslint-enable lines-between-class-members */ getCurrencyAllowance = async () => { const { accountAddress, allowances, uniswapUpdateAllowances } = this.props; const { inputCurrency } = this.state; - if (inputCurrency.address === 'eth') { - this.setState({ needsApproval: false }); - return; + const { address: inputAddress, exchangeAddress } = inputCurrency; + + if (inputAddress === 'eth') { + return this.setState({ isAssetApproved: true }); } - const allowance = allowances[inputCurrency.address]; - if (isNil(allowance)) { - this.setState({ needsApproval: true }); - } else { - this.setState({ needsApproval: !greaterThan(allowance, 0) }); + + let allowance = allowances[inputAddress]; + if (!allowance) { + allowance = await contractUtils.getAllowance(accountAddress, inputCurrency, exchangeAddress); + uniswapUpdateAllowances(inputAddress, allowance); } - const newAllowance = await contractUtils.getAllowance(accountAddress, inputCurrency, inputCurrency.exchangeAddress); - uniswapUpdateAllowances(inputCurrency.address, newAllowance); - this.setState({ needsApproval: !greaterThan(newAllowance, 0) }); - }; - - getReserveData = async tokenAddress => { - let reserve = this.props.tokenReserves[tokenAddress.toLowerCase()]; - if (isNil(reserve)) { - reserve = await this.props.uniswapGetTokenReserve(tokenAddress); + + return this.setState({ isAssetApproved: greaterThan(allowance, 0) }); + } + + getReserveData = async (tokenAddress) => { + const { tokenReserves, uniswapGetTokenReserve } = this.props; + + if (tokenAddress === 'eth') { + return null; + } + + let reserve = tokenReserves[tokenAddress.toLowerCase()]; + if (!reserve) { + reserve = await uniswapGetTokenReserve(tokenAddress); } + return reserve; - }; + } getMarketDetails = async () => { + const { chainId } = this.props; + const { + inputAmount, + inputAsExactAmount, + inputCurrency, + nativeAmount, + outputAmount, + outputCurrency, + } = this.state; + + const isMissingAmounts = !inputAmount && !outputAmount; + const isMissingCurrency = !inputCurrency || !outputCurrency; + if (isMissingAmounts || isMissingCurrency) { + return; + } + try { - let tradeDetails = null; - const { chainId } = this.props; - const { - inputAmount, - inputAsExactAmount, - inputCurrency, - outputAmount, - outputCurrency, - } = this.state; - if (inputCurrency === null || outputCurrency === null) return; - if (isNil(inputAmount) && isNil(outputAmount)) return; - const { - address: inputCurrencyAddress, - decimals: inputDecimals, - } = inputCurrency; - const { - address: outputCurrencyAddress, - decimals: outputDecimals, - } = outputCurrency; + const { address: inputAddress, decimals: inputDecimals } = inputCurrency; + const { address: outputAddress, decimals: outputDecimals } = outputCurrency; + + const isInputEth = inputAddress === 'eth'; + const isOutputEth = outputAddress === 'eth'; + + const inputReserve = await this.getReserveData(inputAddress); + const outputReserve = await this.getReserveData(outputAddress); + const rawInputAmount = convertAmountToRawAmount(inputAmount || 0, inputDecimals); const rawOutputAmount = convertAmountToRawAmount(outputAmount || 0, outputDecimals); - if (inputCurrencyAddress === 'eth' && outputCurrencyAddress !== 'eth') { - const outputCurrencyReserve = await this.getReserveData(outputCurrencyAddress); + let tradeDetails = null; + + if (isInputEth && !isOutputEth) { tradeDetails = inputAsExactAmount - ? tradeExactEthForTokensWithData(outputCurrencyReserve, rawInputAmount, chainId) - : tradeEthForExactTokensWithData(outputCurrencyReserve, rawOutputAmount, chainId); - } else if (inputCurrencyAddress !== 'eth' && outputCurrencyAddress === 'eth') { - const inputCurrencyReserve = await this.getReserveData(inputCurrencyAddress); + ? tradeExactEthForTokensWithData(outputReserve, rawInputAmount, chainId) + : tradeEthForExactTokensWithData(outputReserve, rawOutputAmount, chainId); + } else if (!isInputEth && isOutputEth) { tradeDetails = inputAsExactAmount - ? tradeExactTokensForEthWthData(inputCurrencyReserve, rawInputAmount, chainId) - : tradeTokensForExactEthWithData(inputCurrencyReserve, rawOutputAmount, chainId); - } else if (inputCurrencyAddress !== 'eth' && outputCurrencyAddress !== 'eth') { - const inputCurrencyReserve = await this.getReserveData(inputCurrencyAddress); - const outputCurrencyReserve = await this.getReserveData(outputCurrencyAddress); + ? tradeExactTokensForEthWithData(inputReserve, rawInputAmount, chainId) + : tradeTokensForExactEthWithData(inputReserve, rawOutputAmount, chainId); + } else if (!isInputEth && !isOutputEth) { tradeDetails = inputAsExactAmount - ? tradeExactTokensForTokensWithData(inputCurrencyReserve, outputCurrencyReserve, rawInputAmount, chainId) - : tradeTokensForExactTokensWithData(inputCurrencyReserve, outputCurrencyReserve, rawOutputAmount, chainId); + ? tradeExactTokensForTokensWithData(inputReserve, outputReserve, rawInputAmount, chainId) + : tradeTokensForExactTokensWithData(inputReserve, outputReserve, rawOutputAmount, chainId); } + + const updatedAmountKey = inputAsExactAmount ? 'outputAmount' : 'inputAmount'; + const amountToUpdate = get(tradeDetails, `${updatedAmountKey}.amount`); const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; - const path = inputAsExactAmount ? 'outputAmount.amount' : 'inputAmount.amount'; - this.setState({ tradeDetails }); - const { rawUpdatedValue, slippage } = this.parseTradeDetails(path, tradeDetails, decimals); - if (inputAsExactAmount) { - const outputAmountDisplay = updatePrecisionToDisplay(rawUpdatedValue, get(outputCurrency, 'price.value')); - this.setState({ outputAmount: rawUpdatedValue, outputAmountDisplay, slippage }); - } else { - const inputAmountDisplay = updatePrecisionToDisplay(rawUpdatedValue, get(inputCurrency, 'price.value')); - this.setState({ inputAmount: rawUpdatedValue, inputAmountDisplay, slippage }); - } + + this.setState({ + slippage: get(tradeDetails, 'marketRateSlippage', 0).toFixed(), + tradeDetails, + [updatedAmountKey]: convertRawAmountToDecimalFormat(amountToUpdate, decimals), + }); } catch (error) { console.log('error getting market details', error); // TODO } } - setNativeAmount = async nativeAmountDisplay => { - const nativeAmount = convertAmountFromNativeDisplay(nativeAmountDisplay, this.props.nativeCurrency); - const inputAmount = convertAmountFromNativeValue(nativeAmount, get(this.state.inputCurrency, 'native.price.amount', 0)); - const inputAmountDisplay = updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')); - this.setState({ - inputAmount, - inputAmountDisplay, - inputAsExactAmount: true, - nativeAmount: nativeAmountDisplay, + setInputAmount = (inputAmount) => { + this.setState(({ inputCurrency }) => { + const nativePrice = get(inputCurrency, 'native.price.amount', 0); + + let nativeAmount = null; + if (inputAmount) { + nativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); + } + + return { + inputAmount, + inputAsExactAmount: true, + nativeAmount, + }; }); } - setInputAmount = async inputAmount => { - const nativeAmount = convertAmountToNativeAmount( - inputAmount, - get(this.state.inputCurrency, 'native.price.amount', 0) - ); - this.setState({ - inputAmount, - inputAmountDisplay: inputAmount, - inputAsExactAmount: true, - nativeAmount, + setNativeAmount = (nativeAmount) => { + this.setState(({ inputCurrency }) => { + const nativePrice = get(inputCurrency, 'native.price.amount', 0); + + return { + inputAmount: convertAmountFromNativeValue(nativeAmount, nativePrice), + inputAsExactAmount: true, + nativeAmount, + }; }); } - setOutputAmount = async outputAmount => { + setOutputAmount = (outputAmount) => { this.setState({ inputAsExactAmount: false, outputAmount, - outputAmountDisplay: outputAmount, }); } - setInputCurrency = (inputCurrencySelection, force) => { - const { accountAddress } = this.props; - const { inputCurrency, outputCurrency } = this.state; + setInputCurrency = (inputCurrency, force) => { + const { outputCurrency } = this.state; - console.log('inputCurrencySelection', inputCurrencySelection); - const allowance = contractUtils.getAllowance(accountAddress); - this.setState({ inputCurrency: inputCurrencySelection }); + this.setState({ inputCurrency }); if (!force && isSameAsset(inputCurrency, outputCurrency)) { - if (outputCurrency !== null && inputCurrency !== null) { - return this.setOutputCurrency(null, true); + if (!isNil(inputCurrency) && !isNil(outputCurrency)) { + this.setOutputCurrency(null, true); + } else { + this.setOutputCurrency(inputCurrency, true); } - - return this.setOutputCurrency(inputCurrency, true); } } @@ -301,12 +309,10 @@ class ExchangeModal extends PureComponent { this.setState({ outputCurrency }); if (!force && isSameAsset(inputCurrency, outputCurrency)) { - console.log('outputCurrency', outputCurrency); - const asset = ethereumUtils.getAsset(allAssets, outputCurrency.address.toLowerCase()); - - console.log('asset', asset); + const outputAddress = outputCurrency.address.toLowerCase(); + const asset = ethereumUtils.getAsset(allAssets, outputAddress); - if (inputCurrency !== null && outputCurrency !== null && !isNil(asset)) { + if (!isNil(asset) && !isNil(inputCurrency) && !isNil(outputCurrency)) { this.setInputCurrency(null, true); } else { this.setInputCurrency(outputCurrency, true); @@ -316,22 +322,26 @@ class ExchangeModal extends PureComponent { onPressMaxBalance = () => { const { inputCurrency } = this.state; - const balance = get(inputCurrency, 'balance.amount', 0); - const inputAmount = (inputCurrency.address === 'eth') ? subtract(balance, 0.01) : balance; - this.setState({ inputAmount }); + + let maxBalance = get(inputCurrency, 'balance.amount', 0); + if (inputCurrency.address === 'eth') { + maxBalance = subtract(maxBalance, 0.01); + } + + return this.setInputAmount(maxBalance); } handleSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { - type: CurrencySelectionTypes.input, onSelectCurrency: this.setInputCurrency, + type: CurrencySelectionTypes.input, }); } handleSelectOutputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { - type: CurrencySelectionTypes.output, onSelectCurrency: this.setOutputCurrency, + type: CurrencySelectionTypes.output, }); } @@ -364,18 +374,8 @@ class ExchangeModal extends PureComponent { } } - handleInputFieldRef = (ref) => { this.inputFieldRef = ref; } - - handleNativeFieldRef = (ref) => { this.nativeFieldRef = ref; } - - handleOutputFieldRef = (ref) => { this.outputFieldRef = ref; } - handleDidFocus = () => { // console.log('DID FOCUS', this.props.navigation) - - // if (this.inputFieldRef) { - // setTimeout(() => this.inputFieldRef.focus(), 250); - // } } handleFocusField = ({ currentTarget }) => { @@ -383,31 +383,19 @@ class ExchangeModal extends PureComponent { } render = () => { - const { - keyboardFocusHistory, - nativeCurrency, - navigation, - onPressConfirmExchange, - transitionPosition, - } = this.props; + const { nativeCurrency, transitionPosition } = this.props; const { - inputAmountDisplay, + inputAmount, inputCurrency, + isAssetApproved, nativeAmount, - needsApproval, - outputAmountDisplay, + outputAmount, outputCurrency, showConfirmButton, slippage, } = this.state; - console.log(' ') - console.log('ExchangeModal -- this.props', this.props); - console.log('ExchangeModal -- this.state', this.state); - console.log(' ') - - return ( + @@ -466,7 +454,7 @@ class ExchangeModal extends PureComponent { width="100%" > @@ -475,6 +463,7 @@ class ExchangeModal extends PureComponent { /> )} + @@ -501,13 +490,13 @@ export default compose( withUniswapAssets, mapProps(({ navigation, - tabsTransitionProps: { - isTransitioning: isTabsTransitioning, - }, stackTransitionProps: { isTransitioning: isStacksTransitioning, }, - ...props, + tabsTransitionProps: { + isTransitioning: isTabsTransitioning, + }, + ...props }) => ({ ...props, isTransitioning: isStacksTransitioning || isTabsTransitioning, From d46f479c7922e0f192e2a4aa4866d7763c58b77e Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 27 Aug 2019 00:47:07 -0400 Subject: [PATCH 234/636] update for when truncation is too short --- src/helpers/__tests__/utilities.test.js | 16 ++++++++++------ src/helpers/utilities.js | 16 +++++++++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js index 9c78f102927..18aeb71392e 100644 --- a/src/helpers/__tests__/utilities.test.js +++ b/src/helpers/__tests__/utilities.test.js @@ -1,8 +1,13 @@ import { updatePrecisionToDisplay } from '../utilities'; test('updatePrecisionToDisplay', () => { - const result = updatePrecisionToDisplay('0.17987196800000002', '0.17987196800000002'); - expect(result).toBe('0.18'); + const result = updatePrecisionToDisplay('0.00000000123', '0.1234987234'); + expect(result).toBe('0.000000001'); +}); + +test('updatePrecisionToDisplay', () => { + const result = updatePrecisionToDisplay('0.17987196800000002', '0.1234987234'); + expect(result).toBe('0.179'); }); test('updatePrecisionToDisplay', () => { @@ -12,16 +17,15 @@ test('updatePrecisionToDisplay', () => { test('updatePrecisionToDisplay', () => { const result = updatePrecisionToDisplay('0.123456789', '32.0412'); - expect(result).toBe('0.1235'); + expect(result).toBe('0.1234'); }); test('updatePrecisionToDisplay', () => { const result = updatePrecisionToDisplay('0.123456789', '132.0051'); - expect(result).toBe('0.12346'); + expect(result).toBe('0.12345'); }); test('updatePrecisionToDisplay', () => { const result = updatePrecisionToDisplay('0.123456789', '1320.0112'); - expect(result).toBe('0.123457'); + expect(result).toBe('0.123456'); }); - diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index b5dd2967776..0855a0bcfc4 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -87,11 +87,17 @@ export const floorDivide = (numberOne, numberTwo) => BigNumber(`${numberOne}`) export const countDecimalPlaces = value => BigNumber(`${value}`).dp(); export const updatePrecisionToDisplay = (amount, nativePrice) => { - const significantDigits = BigNumber(`${nativePrice}`).decimalPlaces(0, BigNumber.ROUND_DOWN).sd(true); - const totalDigits = BigNumber(significantDigits).plus(2, 10).toNumber(); - return BigNumber(`${amount}`) - .decimalPlaces(totalDigits, BigNumber.ROUND_HALF_UP) - .toFixed(); + const bnAmount = BigNumber(`${amount}`); + const significantDigits = BigNumber(`${nativePrice}`) + .decimalPlaces(0, BigNumber.ROUND_DOWN) + .sd(true); + const truncatedPrecision = BigNumber(significantDigits) + .plus(2, 10) + .toNumber(); + const result = bnAmount.decimalPlaces(truncatedPrecision, BigNumber.ROUND_DOWN); + return result.isZero() + ? BigNumber(bnAmount.toPrecision(1, BigNumber.ROUND_DOWN)).toFixed() + : result.toFixed(); }; /** From 1672a76d8fede7864edc59d6fb716e65ceda91e8 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 26 Aug 2019 17:47:37 -0400 Subject: [PATCH 235/636] added state for trade details --- src/screens/ExchangeModal.js | 48 +++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index d09d5cd175a..7659a9c5d82 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -6,6 +6,7 @@ import { tradeTokensForExactEthWithData, tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; +import BigNumber from 'bignumber.js'; import { get, isNil } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; @@ -18,10 +19,12 @@ import { toClass, withProps, } from 'recompact'; +import { Text } from '../components/text'; import { executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeValue, convertAmountToNativeAmount, + convertAmountToNativeDisplay, convertAmountToRawAmount, convertRawAmountToDecimalFormat, greaterThan, @@ -97,10 +100,14 @@ class ExchangeModal extends PureComponent { inputAmount: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), + inputExecutionRate: null, + inputNativePrice: null, isAssetApproved: true, nativeAmount: null, outputAmount: null, outputCurrency: null, + outputExecutionRate: null, + outputNativePrice: null, showConfirmButton: false, slippage: null, tradeDetails: null, @@ -192,7 +199,7 @@ class ExchangeModal extends PureComponent { } getMarketDetails = async () => { - const { chainId } = this.props; + const { chainId, nativeCurrency } = this.props; const { inputAmount, inputAsExactAmount, @@ -241,7 +248,40 @@ class ExchangeModal extends PureComponent { const amountToUpdate = get(tradeDetails, `${updatedAmountKey}.amount`); const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; + const rawUpdatedValue = convertRawAmountToDecimalFormat(amountToUpdate, decimals); + + let inputExecutionRate = ''; + let outputExecutionRate = ''; + let inputNativePrice = ''; + let outputNativePrice = ''; + + if (inputCurrency) { + inputExecutionRate = updatePrecisionToDisplay( + get(tradeDetails, 'executionRate.rate', BigNumber(0)), + get(inputCurrency, 'price.value'), + ); + inputNativePrice = convertAmountToNativeDisplay( + get(inputCurrency, 'price.value', 0), + nativeCurrency, + ); + } + if (outputCurrency) { + outputExecutionRate = updatePrecisionToDisplay( + get(tradeDetails, 'executionRate.rateInverted', BigNumber(0)), + get(outputCurrency, 'price.value'), + ); + + outputNativePrice = convertAmountToNativeDisplay( + get(outputCurrency, 'price.value', 0), + nativeCurrency, + ); + } + this.setState({ + inputExecutionRate, + inputNativePrice, + outputExecutionRate, + outputNativePrice, slippage: get(tradeDetails, 'marketRateSlippage', 0).toFixed(), tradeDetails, [updatedAmountKey]: convertRawAmountToDecimalFormat(amountToUpdate, decimals), @@ -388,14 +428,19 @@ class ExchangeModal extends PureComponent { const { inputAmount, inputCurrency, + inputExecutionRate, + inputNativePrice, isAssetApproved, nativeAmount, outputAmount, outputCurrency, + outputExecutionRate, + outputNativePrice, showConfirmButton, slippage, } = this.state; + return ( + ${inputExecutionRate} ${outputExecutionRate} ${inputNativePrice} ${outputNativePrice} {showConfirmButton && ( Date: Wed, 28 Aug 2019 19:47:40 -0700 Subject: [PATCH 236/636] cleanup after merging decimal-logic --- ios/Podfile.lock | 14 ++++++ package.json | 2 +- yarn.lock | 108 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 111 insertions(+), 13 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 7bf6b36e9b4..9b40424e242 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -60,6 +60,7 @@ PODS: - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - Protobuf (3.9.0) - React (0.60.5): @@ -112,6 +113,9 @@ PODS: ======= - Protobuf (3.9.0) >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + - Protobuf (3.9.0) +>>>>>>> 011e4f4a... cleanup after merging decimal-logic - React (0.59.9): - React/Core (= 0.59.9) >>>>>>> 730537c6... catching up with latest mike-swap-ui changes @@ -179,6 +183,7 @@ PODS: - RNStoreReview (0.1.5): - React <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -193,6 +198,11 @@ PODS: - SDWebImage/Core (= 5.1.0) - SDWebImage/Core (5.1.0) >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + - SDWebImage (5.1.0): + - SDWebImage/Core (= 5.1.0) + - SDWebImage/Core (5.1.0) +>>>>>>> 011e4f4a... cleanup after merging decimal-logic - yoga (0.59.9.React) >>>>>>> 730537c6... catching up with latest mike-swap-ui changes @@ -397,6 +407,7 @@ SPEC CHECKSUMS: RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -405,6 +416,9 @@ SPEC CHECKSUMS: ======= SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f +>>>>>>> 011e4f4a... cleanup after merging decimal-logic yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> 730537c6... catching up with latest mike-swap-ui changes diff --git a/package.json b/package.json index 2ad1be3f20f..e4b615e2594 100644 --- a/package.json +++ b/package.json @@ -243,4 +243,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 53242d5cf4d..d5ba778c203 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1124,16 +1124,22 @@ react-is "^16.8.6" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 011e4f4a... cleanup after merging decimal-logic "@react-navigation/native@~3.6.1": version "3.6.2" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== +<<<<<<< HEAD ======= "@react-navigation/native@~3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.0.tgz#dabf93382f75037c01dfdd2a03807e40b48a4d61" integrity sha512-MmsEF4Gf3DD7rtZlbOLULQOBCxE2nGz6FdPYxtlEI+N/E2I5OrdxrTNAA7EGWsIiaJEapU4bp0a+tLjh/9PQpA== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -1484,6 +1490,7 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" +<<<<<<< HEAD <<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.36": version "1.0.0-beta.36" @@ -1516,38 +1523,55 @@ version "1.0.0-beta.33" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.33.tgz#ba8c4d1682c00630124cfacd8c3ac28a37737ffc" integrity sha512-VnipTAEiVJx0fKR7kVKQ/KIaEDCFjIEF4wGSl73uuhp+YPBZSN0fXQ0/joF00dGUxVY6RiwmCQlmz5ZKpcGWYw== +======= +"@walletconnect/core@^1.0.0-beta.34": + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.34.tgz#76ad24610ba288a0a5f2ec146d15214fa9683261" + integrity sha512-Uu1biiWl/t/FzmHxqSK7Ij2s0tXjOF/0qV4IG4qzmfx4k2h1WR4luvF5oLTBMRsoFVSGF1M/FgYYllPEj1nfjQ== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: - "@walletconnect/types" "^1.0.0-beta.33" - "@walletconnect/utils" "^1.0.0-beta.33" + "@walletconnect/types" "^1.0.0-beta.34" + "@walletconnect/utils" "^1.0.0-beta.34" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.33.tgz#21542022f8204648e924a40c6f79c93bde109f5a" - integrity sha512-AFGiXFZXQ1HINGiQESRciMlu7R6s0e2s7LeC5g+EdQrtDDqSsEx9W6Lb8VMPQPnPREmcmcaz4B9L/wyUjNXXew== + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.34.tgz#b2ba8c7c04fc05c48efb468d167bdf7a1b9c6157" + integrity sha512-zKiMxm6QmK+t9NWvWn1XhZ+hS7TEVuk3HnitzbMUVEsIydFUJmowoCD+a5HUqhNIpqestz7efH/2p+zpI2vtRg== dependencies: - "@walletconnect/core" "^1.0.0-beta.33" - "@walletconnect/types" "^1.0.0-beta.33" - "@walletconnect/utils" "^1.0.0-beta.33" + "@walletconnect/core" "^1.0.0-beta.34" + "@walletconnect/types" "^1.0.0-beta.34" + "@walletconnect/utils" "^1.0.0-beta.34" -"@walletconnect/types@^1.0.0-beta.33": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.33.tgz#2c95191e0a2986b24e4f66baeeeaa79f87dc52f4" - integrity sha512-RGC5F4Qb9IApPaOIZwiQVzT4b6K+vmgh0mi/7qHICzSylMJ9BZmvdDOn61+jgSBCjzQ/lmJROsQeXAABCU08rw== +"@walletconnect/types@^1.0.0-beta.34": + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.34.tgz#b8b6a7a6ae2f628e116e89c735bf650e4287fd47" + integrity sha512-+p2qgzRaZprh+TnIwuKePh9Bua6dQZgfEcDfpK8EOAymFkU+aOvbFD6tCv3q494UUG8qoe1qQSxOjaXFip66SA== +<<<<<<< HEAD "@walletconnect/utils@^1.0.0-beta.33": version "1.0.0-beta.33" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.33.tgz#59ff7edc74608398a341264bad781f24b4cf599f" integrity sha512-BAKV+tVoN5QGoMDzF/JleO0s80wLoeJFAsw8/IG9QCSnHi4swZsin0Zk2TRYVb+gC/ZuDmMvwMHVkmVUqz7fOg== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= +"@walletconnect/utils@^1.0.0-beta.34": + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.34.tgz#af74d522826ecaff5d6cea85b960ba16b71a23d0" + integrity sha512-nGdcCaoL4UpSQptlxAdox5WdgGyvZms6kCu9m7TH4qxnL+nCkitQg13Y7m05o1RjzRPmf/4ukfqBrEWTz3heUQ== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" +<<<<<<< HEAD <<<<<<< HEAD "@walletconnect/types" "^1.0.0-beta.36" ======= "@walletconnect/types" "^1.0.0-beta.33" >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + "@walletconnect/types" "^1.0.0-beta.34" +>>>>>>> 011e4f4a... cleanup after merging decimal-logic bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -2499,9 +2523,15 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: +<<<<<<< HEAD version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== +======= + version "5.4.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.2.tgz#2012872776206182480eccb2c0fba5f672a2efef" + integrity sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -3271,6 +3301,7 @@ date-now@^0.1.4: integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= dayjs@^1.8.15: +<<<<<<< HEAD <<<<<<< HEAD version "1.8.16" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" @@ -3280,6 +3311,11 @@ dayjs@^1.8.15: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.15.tgz#7121bc04e6a7f2621ed6db566be4a8aaf8c3913e" integrity sha512-HYHCI1nohG52B45vCQg8Re3hNDZbMroWPkhz50yaX7Lu0ATyjGsTdoYZBpjED9ar6chqTx2dmSmM8A51mojnAg== >>>>>>> 730537c6... catching up with latest mike-swap-ui changes +======= + version "1.8.16" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" + integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic debounce@^1.2.0: version "1.2.0" @@ -3642,6 +3678,7 @@ electron-to-chromium@^1.3.247: integrity sha512-NMHS8iQzAYwiFZ1jL/rNOfrZJhvoowKN5uHrbbHOeNgBT5W762wpe/SRLo9kJoTiJ4d2R8i01/NQHwndo9N5PQ== ======= electron-to-chromium@^1.3.191: +<<<<<<< HEAD <<<<<<< HEAD version "1.3.229" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.229.tgz#accc9a08dd07d0a4d6c76937821bc94eb2e49eae" @@ -3652,6 +3689,11 @@ electron-to-chromium@^1.3.191: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.238.tgz#6d6496e393a709b7b186823281d49b1a5d96a6cf" integrity sha512-k+s6EIiSTgfOm7WiMlGBMMMtBQXSui8OfLN1sXU3RohJOuLGVq0lVm7hXyDIDBcbPM0MeZabAdIPQOSEZT3ZLg== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "1.3.243" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.243.tgz#32f64f00fa121532d1d49f5c0a15fd77f52ae889" + integrity sha512-+edFdHGxLSmAKftXa5xZIg19rHkkJLiW+tRu0VMVG3RKztyeKX7d3pXf707lS6+BxB9uBun3RShbxCI1PtBAgQ== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic elliptic@6.3.3: version "6.3.3" @@ -7269,6 +7311,7 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: +<<<<<<< HEAD <<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" @@ -7278,6 +7321,11 @@ minipass@^2.2.1, minipass@^2.3.5: resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.4.0.tgz#38f0af94f42fb6f34d3d7d82a90e2c99cd3ff485" integrity sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "2.5.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.0.tgz#dddb1d001976978158a05badfcbef4a771612857" + integrity sha512-9FwMVYhn6ERvMR8XFdOavRz4QK/VJV8elU1x50vYexf9lslDcWe/f4HBRxCPd185ekRSjU6CfYyJCECa/CQy7Q== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -7397,9 +7445,15 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.0.3: +<<<<<<< HEAD version "2.1.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== +======= + version "2.0.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.4.tgz#4889355c9ce8e24efad7c65945a4a2875ac3e8f4" + integrity sha512-sOJnBmY3TJQBVIBqKHoifuwygrocXg3NjS9rZSMnVl05XWSHK7Qxb177AIZQyMDjP86bz+yneozj/h9qsPLcCA== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic nanomatch@^1.2.9: version "1.2.13" @@ -7689,11 +7743,14 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +<<<<<<< HEAD object-inspect@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== +======= +>>>>>>> 011e4f4a... cleanup after merging decimal-logic object-is@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" @@ -9018,6 +9075,7 @@ react-native-store-review@^0.1.5: integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== react-native-svg@^9.6.2: +<<<<<<< HEAD <<<<<<< HEAD version "9.9.3" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.9.3.tgz#5dab1a44b20b13a3f35245a286f30882b9611d66" @@ -9027,6 +9085,11 @@ react-native-svg@^9.6.2: resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.4.tgz#f9ceb228efd07317a5f9c378c6b9c5e13ff50cd0" integrity sha512-6SlbGx0vlXHyDPQXSpX+8o6bNjxKFNJsISoboAkR7YWW6hdnkMg/HJXCgT6oJC0/ClKtSO7ZPrQcK4HR65kDNg== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "9.7.1" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.7.1.tgz#a6d270cd51f8f238de7623338211debf4ff9cf5c" + integrity sha512-Yr54SyLPCdovLCJ08V7syJUe1iKrTYG9V5wB08z6lh/9FdC2R9CtBnMyz83GDLKfzUONqqH9nN1l+o61CgD3tg== +>>>>>>> 011e4f4a... cleanup after merging decimal-logic react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -9123,6 +9186,7 @@ react-navigation-drawer@~1.4.0: dependencies: react-native-tab-view "^1.2.0" +<<<<<<< HEAD <<<<<<< HEAD "react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.5.0: ======= @@ -9137,6 +9201,11 @@ react-navigation-stack@^2.0.0-alpha.9: >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "2.0.0-alpha.7" resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" +======= +react-navigation-stack@^2.0.0-alpha.9, "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: + version "2.0.0-alpha.10" + resolved "https://github.com/react-navigation/stack#95c9fcad62fdf9f5fe3861bbf182d83d9e6b0edd" +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: react-native-safe-area-view "^0.14.6" @@ -9160,6 +9229,7 @@ react-navigation-tabs@~1.2.0: react-native-tab-view "^1.4.1" react-navigation@^3.11.1: +<<<<<<< HEAD <<<<<<< HEAD version "3.12.1" resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" @@ -9175,6 +9245,14 @@ react-navigation@^3.11.1: "@react-navigation/core" "~3.5.0" "@react-navigation/native" "~3.6.0" >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "3.12.1" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" + integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== + dependencies: + "@react-navigation/core" "~3.5.0" + "@react-navigation/native" "~3.6.1" +>>>>>>> 011e4f4a... cleanup after merging decimal-logic react-navigation-drawer "~1.4.0" react-navigation-stack "~1.5.0" react-navigation-tabs "~1.2.0" @@ -9388,6 +9466,7 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" +<<<<<<< HEAD <<<<<<< HEAD recyclerlistview@2.0.1-alpha.1: version "2.0.1-alpha.1" @@ -9398,6 +9477,11 @@ recyclerlistview@Flipkart/recyclerlistview#master: version "2.0.13" resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/6c191661214a53f6ba24567528f0de7902ffda6c" >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= +recyclerlistview@Flipkart/recyclerlistview#1d310dffc80d63e4303bf1213d2f6b0ce498c33a: + version "2.0.10" + resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/1d310dffc80d63e4303bf1213d2f6b0ce498c33a" +>>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: lodash.debounce "4.0.8" prop-types "15.5.8" From 8637e156d6b7d45f4f2cba21c414208937c9650f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 28 Aug 2019 21:18:38 -0700 Subject: [PATCH 237/636] delete dead code --- src/helpers/utilities.js | 1 - src/hoc/withUniswapAssets.js | 7 ++----- src/screens/ExchangeModal.js | 15 +-------------- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 0855a0bcfc4..d9677a7207d 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -59,7 +59,6 @@ export const mod = (numberOne, numberTwo) => BigNumber(`${numberOne}`) .mod(BigNumber(`${numberTwo}`)) .toFixed(); - /** * @desc compares if numberOne is greater than or equal to numberTwo * @param {Number} numberOne diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 4f6e1e48081..2a3363d9796 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -11,17 +11,14 @@ import { values, } from 'lodash'; import { connect } from 'react-redux'; -import { - compose, - omitProps, - withProps, -} from 'recompact'; +import { compose, withProps } from 'recompact'; import { createSelector } from 'reselect'; import uniswapAssetsRaw from '../references/uniswap-pairs.json'; import withAccountData from './withAccountData'; const allAssetsSelector = state => state.allAssets; const uniswapAssetsSelector = state => state.uniswapAssets; + export const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => toLower(key)); export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 7659a9c5d82..2e0edcab72d 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -13,12 +13,7 @@ import React, { Fragment, PureComponent } from 'react'; import { InteractionManager, LayoutAnimation, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; -import { - compose, - mapProps, - toClass, - withProps, -} from 'recompact'; +import { compose, mapProps, toClass } from 'recompact'; import { Text } from '../components/text'; import { executeSwap } from '../handlers/uniswap'; import { @@ -204,7 +199,6 @@ class ExchangeModal extends PureComponent { inputAmount, inputAsExactAmount, inputCurrency, - nativeAmount, outputAmount, outputCurrency, } = this.state; @@ -440,7 +434,6 @@ class ExchangeModal extends PureComponent { slippage, } = this.state; - return ( Date: Wed, 28 Aug 2019 21:21:34 -0700 Subject: [PATCH 238/636] Add more label states to ConfirmExchangeButton --- .../buttons/HoldToAuthorizeButton.js | 4 +- .../exchange/ConfirmExchangeButton.js | 66 +++++++++++++------ src/components/exchange/SlippageWarning.js | 5 +- src/screens/ExchangeModal.js | 21 +++++- 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/components/buttons/HoldToAuthorizeButton.js b/src/components/buttons/HoldToAuthorizeButton.js index b5adc823a6f..5a1e521c283 100644 --- a/src/components/buttons/HoldToAuthorizeButton.js +++ b/src/components/buttons/HoldToAuthorizeButton.js @@ -120,6 +120,7 @@ export default class HoldToAuthorizeButton extends PureComponent { backgroundColor: PropTypes.string, children: PropTypes.any, disabled: PropTypes.bool, + hideBiometricIcon: PropTypes.bool, isAuthorizing: PropTypes.bool, onLongPress: PropTypes.func.isRequired, shadows: PropTypes.arrayOf(PropTypes.array), @@ -201,6 +202,7 @@ export default class HoldToAuthorizeButton extends PureComponent { backgroundColor, children, disabled, + hideBiometricIcon, shadows, style, theme, @@ -225,7 +227,7 @@ export default class HoldToAuthorizeButton extends PureComponent { width="100%" > - {!disabled && ( + {(!disabled && !hideBiometricIcon) && ( ( - - {disabled - ? 'Enter an amount' - : 'Hold to swap' - } - -); +const ConfirmExchangeButton = ({ + disabled, + inputCurrencyName, + isAssetApproved, + isSufficientBalance, + isUnlockingAsset, + onPress, + slippage, + ...props +}) => { + let label = 'Hold to Swap'; + if (!isAssetApproved) { + label = `Tap to Unlock ${inputCurrencyName}`; + } else if (!isSufficientBalance) { + label = 'Insufficient Funds'; + } else if (slippage > SlippageWarningTheshold) { + label = 'Swap Anyway'; + } else if (disabled) { + label = 'Enter an Amount'; + } + + return ( + + {label} + + ); +}; ConfirmExchangeButton.propTypes = { disabled: PropTypes.bool, + inputCurrencyName: PropTypes.string, + isAssetApproved: PropTypes.bool, + isSufficientBalance: PropTypes.bool, + isUnlockingAsset: PropTypes.bool, onPress: PropTypes.func, + slippage: PropTypes.number, }; -export default onlyUpdateForPropTypes(ConfirmExchangeButton); +export default ConfirmExchangeButton;//onlyUpdateForPropTypes(); diff --git a/src/components/exchange/SlippageWarning.js b/src/components/exchange/SlippageWarning.js index 0491fb342c3..690f59cf6dc 100644 --- a/src/components/exchange/SlippageWarning.js +++ b/src/components/exchange/SlippageWarning.js @@ -12,7 +12,8 @@ import { Icon } from '../icons'; import { Row, RowWithMargins } from '../layout'; import { Text } from '../text'; -const SevereSlippageThreshold = 10; +export const SlippageWarningTheshold = 5; +const SevereSlippageThreshold = SlippageWarningTheshold * 2; const Container = styled(Row).attrs({ align: 'center', @@ -54,7 +55,7 @@ const SlippageWarning = enhance(({ severityColor, slippage, }) => ( - (slippage < (SevereSlippageThreshold / 2)) + (slippage < SlippageWarningTheshold) ? null : ( diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 2e0edcab72d..f97a7d06d16 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -98,6 +98,7 @@ class ExchangeModal extends PureComponent { inputExecutionRate: null, inputNativePrice: null, isAssetApproved: true, + isSufficientBalance: true, nativeAmount: null, outputAmount: null, outputCurrency: null, @@ -210,8 +211,15 @@ class ExchangeModal extends PureComponent { } try { - const { address: inputAddress, decimals: inputDecimals } = inputCurrency; - const { address: outputAddress, decimals: outputDecimals } = outputCurrency; + const { + address: inputAddress, + balance: { amount: inputBalance }, + decimals: inputDecimals, + } = inputCurrency; + const { + address: outputAddress, + decimals: outputDecimals, + } = outputCurrency; const isInputEth = inputAddress === 'eth'; const isOutputEth = outputAddress === 'eth'; @@ -274,6 +282,7 @@ class ExchangeModal extends PureComponent { this.setState({ inputExecutionRate, inputNativePrice, + isSufficientBalance: Number(inputBalance) >= Number(inputAmount), outputExecutionRate, outputNativePrice, slippage: get(tradeDetails, 'marketRateSlippage', 0).toFixed(), @@ -425,6 +434,7 @@ class ExchangeModal extends PureComponent { inputExecutionRate, inputNativePrice, isAssetApproved, + isSufficientBalance, nativeAmount, outputAmount, outputCurrency, @@ -493,8 +503,13 @@ class ExchangeModal extends PureComponent { width="100%" > Date: Wed, 28 Aug 2019 21:22:11 -0700 Subject: [PATCH 239/636] fix the react-navigation-stacks version to previous release for now --- yarn.lock | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index d5ba778c203..6aef7f1435d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1112,17 +1112,25 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.5.tgz#4bb44842db6a1a18f00a0f061b0e3dcc638f67dd" integrity sha512-lagdZr9UiVAccNXYfTEj+aUcPCx9ykbMe9puffeIyF3JsRuMmlu3BjHYx1klUHX7wNRmFNC8qVP0puxUt1sZ0A== +<<<<<<< HEAD "@react-navigation/core@~3.5.0": version "3.5.0" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.0.tgz#73d1a12448e2bd71855e0080b95a7f51ede0cd9e" integrity sha512-NLm24lA51R8o8c+iFnwtN9elqRzm4OJ8f1qPBCUNIYW1sb8M5yCD53vRP0fRcPFpr/6Xzs2TJMsWnnebwFp0Rw== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= +"@react-navigation/core@~3.4.1": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.4.2.tgz#bec563e94fde40fbab3730cdc97f22afbb2a1498" + integrity sha512-7G+iDzLSTeOUU4vVZeRZKJ+Bd7ds7ZxYNqZcB8i0KlBeQEQfR74Ounfu/p0KIEq2RiNnaE3QT7WVP3C87sebzw== +>>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now dependencies: hoist-non-react-statics "^3.3.0" path-to-regexp "^1.7.0" query-string "^6.4.2" react-is "^16.8.6" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD ======= @@ -1140,6 +1148,12 @@ >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic ======= >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= +"@react-navigation/native@~3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.5.0.tgz#f5d16e0845ac26d1147d1caa481f18a00740e7ae" + integrity sha512-TmGOis++ejEXG3sqNJhCSKqB0/qLu3FQgDtO959qpqif36R/diR8SQwJqeSdofoEiK3CepdhFlTCeHdS1/+MsQ== +>>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -9179,30 +9193,38 @@ react-native@0.60.5: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-drawer@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.4.0.tgz#70f3dd83e3da9cd4ea6e2739526502c823d466b9" - integrity sha512-ZyWBozcjB2aZ7vwCALv90cYA2NpDjM+WALaiYRshvPvue8l7cqynePbHK8GhlMGyJDwZqp4MxQmu8u1XAKp3Bw== +react-navigation-drawer@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.2.1.tgz#7bd5efeee7d2f611d3ebb0933e0c8e8eb7cafe52" + integrity sha512-T2kaBjY2c4/3I6noWFnaf/c18ntNH5DsST38i+pdc2NPxn5Yi5lkK+ZZTeKuHSFD4a7G0jWY9OGf1iRkHWLMAQ== dependencies: react-native-tab-view "^1.2.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.5.0: ======= react-navigation-stack@^2.0.0-alpha.9: +======= +react-navigation-stack@2.0.0-alpha.9: +>>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now version "2.0.0-alpha.9" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.9.tgz#6e0382f3f4e37235c94badf6712c7095415d4a6d" integrity sha512-Lze5CuCDr9FtGIJyxG8e1YXbpyd77XjOgLnQN5PRG9qx7YNmAbkbybPrhsmlRVWiyosC8IEVFbnot0EDcR+O/w== dependencies: react-native-safe-area-view "^0.14.6" +<<<<<<< HEAD "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "2.0.0-alpha.7" resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" ======= react-navigation-stack@^2.0.0-alpha.9, "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: +======= +"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: +>>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now version "2.0.0-alpha.10" resolved "https://github.com/react-navigation/stack#95c9fcad62fdf9f5fe3861bbf182d83d9e6b0edd" >>>>>>> 011e4f4a... cleanup after merging decimal-logic @@ -9219,15 +9241,17 @@ react-navigation-tabs@^2.3.0: react-native-safe-area-view "^0.14.6" react-native-tab-view "^2.9.0" -react-navigation-tabs@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.2.0.tgz#602c147029bb4f1c569b26479ddba534fe3ebb19" - integrity sha512-I6vq3XX4ub9KhWQzcrggznls+2Z2C6w2ro46vokDGGvJ02CBpQRar7J0ETV29Ot5AJY67HucNUmZdH3yDFckmQ== +react-navigation-tabs@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" + integrity sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ== dependencies: hoist-non-react-statics "^2.5.0" prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" react-native-tab-view "^1.4.1" +<<<<<<< HEAD react-navigation@^3.11.1: <<<<<<< HEAD <<<<<<< HEAD @@ -9256,6 +9280,18 @@ react-navigation@^3.11.1: react-navigation-drawer "~1.4.0" react-navigation-stack "~1.5.0" react-navigation-tabs "~1.2.0" +======= +react-navigation@3.11.1: + version "3.11.1" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.1.tgz#ba696ad6b512088a97a20cc7e6a250c53dbddd26" + integrity sha512-n64HxLG5s5ucVFo1Gs+D9ujChhHDd98lpQ1p27wL7gq8V1PaRJMvsBEIsguhtc2rTIL/TWDynOesXQDG+Eg6FQ== + dependencies: + "@react-navigation/core" "~3.4.1" + "@react-navigation/native" "~3.5.0" + react-navigation-drawer "~1.2.1" + react-navigation-stack "~1.4.0" + react-navigation-tabs "~1.1.4" +>>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now react-primitives@^0.8.0: version "0.8.0" From 12bc64fc4988f0e2d219f43b648ee48c4ff53c1f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 28 Aug 2019 21:22:54 -0700 Subject: [PATCH 240/636] Attempt at fixing the syncronicity of Exchange Inputs --- src/screens/ExchangeModal.js | 68 ++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index f97a7d06d16..456d22ef007 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -24,6 +24,7 @@ import { convertRawAmountToDecimalFormat, greaterThan, subtract, + updatePrecisionToDisplay, } from '../helpers/utilities'; import { withAccountAddress, @@ -93,6 +94,7 @@ class ExchangeModal extends PureComponent { state = { inputAllowance: null, inputAmount: null, + inputAmountDisplay: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), inputExecutionRate: null, @@ -101,6 +103,7 @@ class ExchangeModal extends PureComponent { isSufficientBalance: true, nativeAmount: null, outputAmount: null, + outputAmountDisplay: null, outputCurrency: null, outputExecutionRate: null, outputNativePrice: null, @@ -137,7 +140,13 @@ class ExchangeModal extends PureComponent { const isNewInputAmount = isNewValueForPath(this.state, prevState, 'inputAmount'); const isNewOutputAmount = isNewValueForPath(this.state, prevState, 'outputAmount'); - if (isNewNativeAmount || isNewInputAmount || isNewOutputAmount) { + const isNewInputCurrency = isNewValueForPath(this.state, prevState, 'inputCurrency'); + const isNewOutputCurrency = isNewValueForPath(this.state, prevState, 'outputCurrency'); + + const isNewAmount = isNewNativeAmount || isNewInputAmount || isNewOutputAmount; + const isNewCurrency = isNewInputCurrency || isNewOutputCurrency; + + if (isNewAmount || isNewCurrency) { this.getMarketDetails(); LayoutAnimation.easeInEaseOut(); } @@ -246,12 +255,6 @@ class ExchangeModal extends PureComponent { : tradeTokensForExactTokensWithData(inputReserve, outputReserve, rawOutputAmount, chainId); } - const updatedAmountKey = inputAsExactAmount ? 'outputAmount' : 'inputAmount'; - const amountToUpdate = get(tradeDetails, `${updatedAmountKey}.amount`); - const decimals = inputAsExactAmount ? outputDecimals : inputDecimals; - - const rawUpdatedValue = convertRawAmountToDecimalFormat(amountToUpdate, decimals); - let inputExecutionRate = ''; let outputExecutionRate = ''; let inputNativePrice = ''; @@ -267,6 +270,7 @@ class ExchangeModal extends PureComponent { nativeCurrency, ); } + if (outputCurrency) { outputExecutionRate = updatePrecisionToDisplay( get(tradeDetails, 'executionRate.rateInverted', BigNumber(0)), @@ -287,15 +291,24 @@ class ExchangeModal extends PureComponent { outputNativePrice, slippage: get(tradeDetails, 'marketRateSlippage', 0).toFixed(), tradeDetails, - [updatedAmountKey]: convertRawAmountToDecimalFormat(amountToUpdate, decimals), }); + + if (inputAsExactAmount) { + const updatedAmount = get(tradeDetails, 'outputAmount.amount'); + const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, outputDecimals); + this.setOutputAmount(rawUpdatedAmount, false); // should this be true? + } else { + const updatedAmount = get(tradeDetails, 'inputAmount.amount'); + const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, inputDecimals); + this.setInputAmount(rawUpdatedAmount, false); // should this be true? + } } catch (error) { console.log('error getting market details', error); // TODO } } - setInputAmount = (inputAmount) => { + setInputAmount = (inputAmount, isExact = true) => { this.setState(({ inputCurrency }) => { const nativePrice = get(inputCurrency, 'native.price.amount', 0); @@ -306,29 +319,33 @@ class ExchangeModal extends PureComponent { return { inputAmount, - inputAsExactAmount: true, + inputAmountDisplay: updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')), + inputAsExactAmount: isExact, nativeAmount, }; }); } - setNativeAmount = (nativeAmount) => { + setNativeAmount = (nativeAmount, isExact = true) => { this.setState(({ inputCurrency }) => { const nativePrice = get(inputCurrency, 'native.price.amount', 0); + const inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); return { - inputAmount: convertAmountFromNativeValue(nativeAmount, nativePrice), - inputAsExactAmount: true, + inputAmount, + inputAmountDisplay: updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')), + inputAsExactAmount: isExact, nativeAmount, }; }); } - setOutputAmount = (outputAmount) => { - this.setState({ - inputAsExactAmount: false, + setOutputAmount = (outputAmount, isExact = false) => { + this.setState(({ outputCurrency }) => ({ + inputAsExactAmount: isExact, outputAmount, - }); + outputAmountDisplay: updatePrecisionToDisplay(outputAmount, get(outputCurrency, 'price.value')), + })); } setInputCurrency = (inputCurrency, force) => { @@ -365,7 +382,6 @@ class ExchangeModal extends PureComponent { onPressMaxBalance = () => { const { inputCurrency } = this.state; - let maxBalance = get(inputCurrency, 'balance.amount', 0); if (inputCurrency.address === 'eth') { maxBalance = subtract(maxBalance, 0.01); @@ -429,14 +445,14 @@ class ExchangeModal extends PureComponent { const { nativeCurrency, transitionPosition } = this.props; const { - inputAmount, + inputAmountDisplay, inputCurrency, inputExecutionRate, inputNativePrice, isAssetApproved, isSufficientBalance, nativeAmount, - outputAmount, + outputAmountDisplay, outputCurrency, outputExecutionRate, outputNativePrice, @@ -470,7 +486,7 @@ class ExchangeModal extends PureComponent { - ${inputExecutionRate} ${outputExecutionRate} ${inputNativePrice} ${outputNativePrice} + + {inputExecutionRate} {outputExecutionRate} {inputNativePrice} {outputNativePrice} + {showConfirmButton && ( Date: Wed, 28 Aug 2019 21:23:15 -0700 Subject: [PATCH 241/636] minor cleanup / optimization to withUniswapAssets hoc --- src/hoc/withUniswapAssets.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 2a3363d9796..7a8ae62bc89 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -4,7 +4,6 @@ import { keys, map, mapKeys, - mapValues, property, sortBy, toLower, @@ -24,13 +23,19 @@ export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); +const mapUniswapAssetItem = (asset) => { + const exchangeAddress = get(uniswapAssetsRawLoweredKeys, `${asset.address}.exchangeAddress`); + + return { + ...asset, + exchangeAddress, + uniqueId: exchangeAddress, + }; +}; + const withAssetsAvailableOnUniswap = (allAssets) => { const availableAssets = filter(allAssets, filterUniswapAssetsByAvailability); - const assetsAvailableOnUniswap = map(availableAssets, (asset) => ({ - ...asset, - exchangeAddress: get(uniswapAssetsRawLoweredKeys, `${asset.address}.exchangeAddress`), - })); - return { assetsAvailableOnUniswap }; + return { assetsAvailableOnUniswap: map(availableAssets, mapUniswapAssetItem) }; }; const withSortedUniswapAssets = (unsortedUniswapAssets) => ({ @@ -47,12 +52,7 @@ const withSortedUniswapAssetsSelector = createSelector( withSortedUniswapAssets, ); -const mapStateToProps = ({ - uniswap: { uniswapAssets }, -}) => ({ - uniswapAssets, -}); - +const mapStateToProps = ({ uniswap: { uniswapAssets } }) => ({ uniswapAssets }); export default compose( connect(mapStateToProps), From 1ed93e56ccc2eb093248c582e4bc46d1afa93168 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 29 Aug 2019 00:03:58 -0700 Subject: [PATCH 242/636] make ButtonPressAnimation fire onPress when ACTIVE --- .../animations/ButtonPressAnimation.js | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index c0e9d272ec1..c8d6595a89c 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -135,15 +135,17 @@ export default class ButtonPressAnimation extends PureComponent { } } - createInteraction = () => { + handleActive = () => { if (this.props.isInteraction) { this.handle = InteractionManager.createInteractionHandle(); + } else { + this.handlePress(); } } - handleHaptic = () => { - if (this.props.enableHapticFeedback) { - ReactNativeHapticFeedback.trigger('selection'); + handleEnd = () => { + if (this.props.isInteraction) { + InteractionManager.runAfterInteractions(this.handlePress); } } @@ -155,17 +157,15 @@ export default class ButtonPressAnimation extends PureComponent { } handlePress = () => { + if (this.props.enableHapticFeedback) { + ReactNativeHapticFeedback.trigger('selection'); + } + if (this.props.onPress) { this.props.onPress(); } } - handleRunInteraction = () => ( - this.props.isInteraction - ? InteractionManager.runAfterInteractions(this.handlePress) - : this.handlePress() - ) - render = () => { const { activeOpacity, @@ -238,14 +238,11 @@ export default class ButtonPressAnimation extends PureComponent { this.gestureState, cond( eq(this.gestureState, ACTIVE), - call([], this.createInteraction), + call([], this.handleActive), // else if cond( eq(this.gestureState, END), - [ - call([], this.handleHaptic), - call([], this.handleRunInteraction), - ], + call([], this.handleEnd), ), ), ), From d62f36f327715ce16605d87ea30602d6144971d0 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 29 Aug 2019 00:07:44 -0700 Subject: [PATCH 243/636] =?UTF-8?q?Begin=20=E2=80=9Cunlock=E2=80=9D=20asse?= =?UTF-8?q?t=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../buttons/HoldToAuthorizeButton.js | 69 +++++++++++++------ .../exchange/ConfirmExchangeButton.js | 52 +++++++++++--- src/components/exchange/ExchangeInputField.js | 38 +++++----- src/components/exchange/UnlockAssetButton.js | 12 +++- src/components/send/SendButton.js | 5 +- src/helpers/utilities.js | 2 +- src/screens/ExchangeModal.js | 37 ++++++---- src/screens/TransactionConfirmationScreen.js | 20 +++--- src/styles/colors.js | 1 + 9 files changed, 163 insertions(+), 73 deletions(-) diff --git a/src/components/buttons/HoldToAuthorizeButton.js b/src/components/buttons/HoldToAuthorizeButton.js index 5a1e521c283..c5e98a6c052 100644 --- a/src/components/buttons/HoldToAuthorizeButton.js +++ b/src/components/buttons/HoldToAuthorizeButton.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; +import React, { Fragment, PureComponent } from 'react'; import { LongPressGestureHandler, State, TapGestureHandler } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; @@ -28,7 +28,7 @@ const ButtonBorderRadius = 30; const ButtonHeight = 59; const ButtonDisabledBgColor = { - dark: colors.darkGrey,// blueGreyLighter, + dark: colors.darkGrey, // blueGreyLighter, light: colors.lighterGrey, }; @@ -120,9 +120,12 @@ export default class HoldToAuthorizeButton extends PureComponent { backgroundColor: PropTypes.string, children: PropTypes.any, disabled: PropTypes.bool, + disabledBackgroundColor: PropTypes.string, hideBiometricIcon: PropTypes.bool, isAuthorizing: PropTypes.bool, + label: PropTypes.string, onLongPress: PropTypes.func.isRequired, + onPress: PropTypes.func, shadows: PropTypes.arrayOf(PropTypes.array), style: PropTypes.object, theme: PropTypes.oneOf(['light', 'dark']), @@ -152,12 +155,12 @@ export default class HoldToAuthorizeButton extends PureComponent { } } - onTapChange = ({ nativeEvent }) => { - const { disabled } = this.props; + onTapChange = ({ nativeEvent: { state } }) => { + const { disabled, onPress } = this.props; - this.tapHandlerState = nativeEvent.state; + this.tapHandlerState = state; - if (nativeEvent.state === State.BEGAN) { + if (state === State.BEGAN) { if (disabled) { ReactNativeHapticFeedback.trigger('notificationWarning'); buildAnimation(this.scale, { toValue: 0.99 }).start(() => { @@ -170,7 +173,11 @@ export default class HoldToAuthorizeButton extends PureComponent { toValue: 100, }).start(); } - } else if (!disabled && nativeEvent.state === State.END) { + } else if (!disabled && state === State.ACTIVE) { + if (onPress) { + onPress(); + } + } else if (!disabled && state === State.END) { buildAnimation(this.scale, { toValue: 1 }).start(); buildAnimation(this.animation, { duration: calculateReverseDuration(this.animation), @@ -197,20 +204,50 @@ export default class HoldToAuthorizeButton extends PureComponent { } } - render() { + renderContent = () => { const { - backgroundColor, children, disabled, hideBiometricIcon, + label, + } = this.props; + + const { isAuthorizing } = this.state; + + if (children) { + return children; + } + + return ( + + {(!disabled && !hideBiometricIcon) && ( + + )} + + {isAuthorizing ? 'Authorizing' : label} + + + ); + } + + render() { + const { + backgroundColor, + disabled, + disabledBackgroundColor, shadows, style, theme, ...props } = this.props; - const { isAuthorizing } = this.state; - const bgColor = disabled ? ButtonDisabledBgColor[theme] : backgroundColor; + let bgColor = backgroundColor; + if (disabled) { + bgColor = disabledBackgroundColor || ButtonDisabledBgColor[theme]; + } return ( @@ -227,15 +264,7 @@ export default class HoldToAuthorizeButton extends PureComponent { width="100%" > - {(!disabled && !hideBiometricIcon) && ( - - )} - - {isAuthorizing ? 'Authorizing' : children} - + {this.renderContent()} diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 7a16e4c1baf..0c55ed3b54e 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -1,17 +1,46 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { onlyUpdateForPropTypes } from 'recompact'; import { colors } from '../../styles'; import { HoldToAuthorizeButton } from '../buttons'; +import { Icon } from '../icons'; +import { Centered, RowWithMargins } from '../layout'; +import { Text } from '../text'; import { SlippageWarningTheshold } from './SlippageWarning'; +const UnlockingSpinner = ({ ...props }) => { + // lol this isnt done + return ( + + + + + Unlocking + + + + {`~ 12s Remaining`} + + + ); +}; + const ConfirmExchangeButton = ({ disabled, inputCurrencyName, isAssetApproved, isSufficientBalance, isUnlockingAsset, - onPress, + onSubmit, + onUnlockAsset, slippage, ...props }) => { @@ -28,10 +57,13 @@ const ConfirmExchangeButton = ({ return ( - {label} + {isUnlockingAsset + ? + : undefined + } ); }; @@ -51,8 +86,9 @@ ConfirmExchangeButton.propTypes = { isAssetApproved: PropTypes.bool, isSufficientBalance: PropTypes.bool, isUnlockingAsset: PropTypes.bool, - onPress: PropTypes.func, + onSubmit: PropTypes.func, + onUnlockAsset: PropTypes.func, slippage: PropTypes.number, }; -export default ConfirmExchangeButton;//onlyUpdateForPropTypes(); +export default ConfirmExchangeButton; diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 6628caa02bd..57450d930f8 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -20,16 +20,17 @@ import UnlockAssetButton from './UnlockAssetButton'; export default class ExchangeInputField extends Component { static propTypes = { inputAmount: PropTypes.string, - inputCurrency: PropTypes.string, + inputCurrencySymbol: PropTypes.string, inputFieldRef: PropTypes.func, isAssetApproved: PropTypes.bool, + isUnlockingAsset: PropTypes.bool, nativeAmount: PropTypes.string, nativeCurrency: PropTypes.string, nativeFieldRef: PropTypes.func, onFocus: PropTypes.func, onPressMaxBalance: PropTypes.func, onPressSelectInputCurrency: PropTypes.func, - onPressUnlockAsset: PropTypes.func, + onUnlockAsset: PropTypes.func, setInputAmount: PropTypes.func, setNativeAmount: PropTypes.func, } @@ -39,18 +40,20 @@ export default class ExchangeInputField extends Component { padding = 15 shouldComponentUpdate = (nextProps, nextState) => { - const isNewInputAmount = isNewValueForPath(this.props, nextProps, 'inputAmount'); - const isNewInputCurrency = isNewValueForPath(this.props, nextProps, 'inputCurrency'); const isNewAssetApproved = isNewValueForPath(this.props, nextProps, 'isAssetApproved'); + const isNewInputAmount = isNewValueForPath(this.props, nextProps, 'inputAmount'); + const isNewInputCurrency = isNewValueForPath(this.props, nextProps, 'inputCurrencySymbol'); const isNewNativeAmount = isNewValueForPath(this.props, nextProps, 'nativeAmount'); const isNewNativeCurrency = isNewValueForPath(this.props, nextProps, 'nativeCurrency'); + const isNewUnlockingAsset = isNewValueForPath(this.props, nextProps, 'isUnlockingAsset'); return ( - isNewInputAmount + isNewAssetApproved + || isNewInputAmount || isNewInputCurrency - || isNewAssetApproved || isNewNativeAmount || isNewNativeCurrency + || isNewUnlockingAsset ); } @@ -68,15 +71,16 @@ export default class ExchangeInputField extends Component { render = () => { const { inputAmount, - inputCurrency, + inputCurrencySymbol, isAssetApproved, + isUnlockingAsset, nativeAmount, nativeCurrency, nativeFieldRef, onFocus, onPressMaxBalance, onPressSelectInputCurrency, - onPressUnlockAsset, + onUnlockAsset, setInputAmount, setNativeAmount, } = this.props; @@ -94,27 +98,27 @@ export default class ExchangeInputField extends Component { paddingLeft={this.padding} > - {inputCurrency || 'Choose a Coin'} + {inputCurrencySymbol || 'Choose a Coin'} - {isAssetApproved ? ( + {(isAssetApproved || isUnlockingAsset) ? ( ) : ( - + )} diff --git a/src/components/exchange/UnlockAssetButton.js b/src/components/exchange/UnlockAssetButton.js index a2bb8f7407a..d677162b402 100644 --- a/src/components/exchange/UnlockAssetButton.js +++ b/src/components/exchange/UnlockAssetButton.js @@ -22,7 +22,7 @@ const UnlockAssetButton = ({ onPress, shadows, }) => ( - + ); -UnlockAssetButton.propTypes = CoolButton.propTypes; +UnlockAssetButton.propTypes = { + // see CoolButton's proptypes + ...CoolButton.propTypes, +}; -UnlockAssetButton.defaultProps = CoolButton.defaultProps; +UnlockAssetButton.defaultProps = { + // see CoolButton's default props + ...CoolButton.defaultProps, +}; export default withNeverRerender(UnlockAssetButton); diff --git a/src/components/send/SendButton.js b/src/components/send/SendButton.js index 322eec389fa..f35a6318167 100644 --- a/src/components/send/SendButton.js +++ b/src/components/send/SendButton.js @@ -32,10 +32,9 @@ const SendButton = ({ {...props} disabled={disabled} isAuthorizing={isAuthorizing} + label={label} onLongPress={onLongPress} - > - {label} - + /> ); }; diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index d9677a7207d..7de52741de5 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -95,7 +95,7 @@ export const updatePrecisionToDisplay = (amount, nativePrice) => { .toNumber(); const result = bnAmount.decimalPlaces(truncatedPrecision, BigNumber.ROUND_DOWN); return result.isZero() - ? BigNumber(bnAmount.toPrecision(1, BigNumber.ROUND_DOWN)).toFixed() + ? BigNumber(bnAmount.toPrecision(1, BigNumber.ROUND_DOWN)).toFixed() : result.toFixed(); }; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 456d22ef007..33f57ad8577 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -101,6 +101,7 @@ class ExchangeModal extends PureComponent { inputNativePrice: null, isAssetApproved: true, isSufficientBalance: true, + isUnlockingAsset: false, nativeAmount: null, outputAmount: null, outputAmountDisplay: null, @@ -441,6 +442,19 @@ class ExchangeModal extends PureComponent { this.props.pushKeyboardFocusHistory(currentTarget); } + handleUnlockAsset = async () => { + const { + inputCurrency: { + address: tokenAddress, + exchangeAddress: spender, + }, + } = this.state; + + // const approval = await contractUtils.approve(tokenAddress, spender); + + this.setState({ isUnlockingAsset: true }); + } + render = () => { const { nativeCurrency, transitionPosition } = this.props; @@ -451,6 +465,7 @@ class ExchangeModal extends PureComponent { inputNativePrice, isAssetApproved, isSufficientBalance, + isUnlockingAsset, nativeAmount, outputAmountDisplay, outputCurrency, @@ -487,15 +502,17 @@ class ExchangeModal extends PureComponent { @@ -509,14 +526,7 @@ class ExchangeModal extends PureComponent { /> - - - {inputExecutionRate} {outputExecutionRate} {inputNativePrice} {outputNativePrice} - + {isSufficientBalance && } {showConfirmButton && ( diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 946e762da7a..72538bdf236 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -97,14 +97,18 @@ export default class TransactionConfirmationScreen extends PureComponent { await onConfirm(requestType); } - renderSendButton = () => ( - - {`Hold to ${(this.props.requestType === 'message' || this.props.requestType === 'messagePersonal') ? 'Sign' : 'Send'}`} - - ) + renderSendButton = () => { + const { requestType } = this.props; + const isMessage = requestType === 'message' || requestType === 'messagePersonal'; + + return ( + + ); + } renderTransactionSection = () => { const { request, requestType } = this.props; diff --git a/src/styles/colors.js b/src/styles/colors.js index 77cc9adc86a..84815538a57 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -17,6 +17,7 @@ const base = { darkGrey: '#71778a', // '113, 119, 138' dodgerBlue: '#575CFF', // '87, 92, 255' green: '#00994d', // '0, 153, 77' + grey20: '#333333', // '51, 51, 51' grey: '#a9adb9', // '169, 173, 185' headerTitle: '#aaafbd', // '170, 175, 189' highlightBackground: '#F0F7FF', // '240, 247, 255' From d848680ff45fe1b5b3ee0a81cb6778e00bed0b0d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 29 Aug 2019 00:07:57 -0700 Subject: [PATCH 244/636] minor cleanup to ExchangeModal --- src/screens/ExchangeModal.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 33f57ad8577..05c77875fbb 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -262,24 +262,27 @@ class ExchangeModal extends PureComponent { let outputNativePrice = ''; if (inputCurrency) { + const inputPriceValue = get(inputCurrency, 'price.value', 0); inputExecutionRate = updatePrecisionToDisplay( get(tradeDetails, 'executionRate.rate', BigNumber(0)), - get(inputCurrency, 'price.value'), + inputPriceValue, ); + inputNativePrice = convertAmountToNativeDisplay( - get(inputCurrency, 'price.value', 0), + inputPriceValue, nativeCurrency, ); } if (outputCurrency) { + const outputPriceValue = get(outputCurrency, 'price.value', 0); outputExecutionRate = updatePrecisionToDisplay( get(tradeDetails, 'executionRate.rateInverted', BigNumber(0)), - get(outputCurrency, 'price.value'), + outputPriceValue, ); outputNativePrice = convertAmountToNativeDisplay( - get(outputCurrency, 'price.value', 0), + outputPriceValue, nativeCurrency, ); } @@ -301,7 +304,7 @@ class ExchangeModal extends PureComponent { } else { const updatedAmount = get(tradeDetails, 'inputAmount.amount'); const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, inputDecimals); - this.setInputAmount(rawUpdatedAmount, false); // should this be true? + this.setInputAmount(rawUpdatedAmount, true); // should this be true? } } catch (error) { console.log('error getting market details', error); @@ -461,16 +464,16 @@ class ExchangeModal extends PureComponent { const { inputAmountDisplay, inputCurrency, - inputExecutionRate, - inputNativePrice, + // inputExecutionRate, + // inputNativePrice, isAssetApproved, isSufficientBalance, isUnlockingAsset, nativeAmount, outputAmountDisplay, outputCurrency, - outputExecutionRate, - outputNativePrice, + // outputExecutionRate, + // outputNativePrice, showConfirmButton, slippage, } = this.state; From 8430177e7ad24a378aaea24b731508632a156ec2 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 29 Aug 2019 03:54:19 -0700 Subject: [PATCH 245/636] wow inputs are all in sync now!!!! --- src/screens/ExchangeModal.js | 83 ++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 05c77875fbb..a857db8f621 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -14,7 +14,6 @@ import { InteractionManager, LayoutAnimation, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, mapProps, toClass } from 'recompact'; -import { Text } from '../components/text'; import { executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeValue, @@ -137,12 +136,18 @@ class ExchangeModal extends PureComponent { this.setState({ showConfirmButton: true }); } - const isNewNativeAmount = isNewValueForPath(this.state, prevState, 'nativeAmount'); const isNewInputAmount = isNewValueForPath(this.state, prevState, 'inputAmount'); const isNewOutputAmount = isNewValueForPath(this.state, prevState, 'outputAmount'); - const isNewInputCurrency = isNewValueForPath(this.state, prevState, 'inputCurrency'); - const isNewOutputCurrency = isNewValueForPath(this.state, prevState, 'outputCurrency'); + const isNewNativeAmount = ( + // Only consider 'new' if the native input isnt focused, + // otherwise itll fight with the user's keystrokes + isNewValueForPath(this.state, prevState, 'nativeAmount') + && this.nativeFieldRef.isFocused() + ); + + const isNewInputCurrency = isNewValueForPath(this.state, prevState, 'inputCurrency.uniqueId'); + const isNewOutputCurrency = isNewValueForPath(this.state, prevState, 'outputCurrency.uniqueId'); const isNewAmount = isNewNativeAmount || isNewInputAmount || isNewOutputAmount; const isNewCurrency = isNewInputCurrency || isNewOutputCurrency; @@ -171,6 +176,8 @@ class ExchangeModal extends PureComponent { assignOutputFieldRef = (ref) => { this.outputFieldRef = ref; } /* eslint-enable lines-between-class-members */ + clearInputField = () => this.inputFieldRef.clear() + getCurrencyAllowance = async () => { const { accountAddress, allowances, uniswapUpdateAllowances } = this.props; const { inputCurrency } = this.state; @@ -287,24 +294,45 @@ class ExchangeModal extends PureComponent { ); } + const slippage = get(tradeDetails, 'marketRateSlippage', 0).toFixed(); + this.setState({ inputExecutionRate, inputNativePrice, isSufficientBalance: Number(inputBalance) >= Number(inputAmount), outputExecutionRate, outputNativePrice, - slippage: get(tradeDetails, 'marketRateSlippage', 0).toFixed(), + slippage, tradeDetails, }); - if (inputAsExactAmount) { + if (inputAsExactAmount && !this.outputFieldRef.isFocused()) { const updatedAmount = get(tradeDetails, 'outputAmount.amount'); const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, outputDecimals); - this.setOutputAmount(rawUpdatedAmount, false); // should this be true? - } else { - const updatedAmount = get(tradeDetails, 'inputAmount.amount'); - const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, inputDecimals); - this.setInputAmount(rawUpdatedAmount, true); // should this be true? + + const updatedAmountDisplay = updatePrecisionToDisplay( + rawUpdatedAmount, + get(outputCurrency, 'price.value'), + ); + + this.setOutputAmount(rawUpdatedAmount, updatedAmountDisplay); + } + + if (!inputAsExactAmount && !this.inputFieldRef.isFocused()) { + if (Number(slippage) === 0) { + // this isnt working + this.setInputAmount(0, undefined, this.clearInputField); + } else { + const updatedAmount = get(tradeDetails, 'inputAmount.amount'); + const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, inputDecimals); + + const updatedAmountDisplay = updatePrecisionToDisplay( + rawUpdatedAmount, + get(inputCurrency, 'price.value'), + ); + + this.setInputAmount(rawUpdatedAmount, updatedAmountDisplay); + } } } catch (error) { console.log('error getting market details', error); @@ -312,25 +340,24 @@ class ExchangeModal extends PureComponent { } } - setInputAmount = (inputAmount, isExact = true) => { + setInputAmount = (inputAmount, amountDisplay, callback) => { this.setState(({ inputCurrency }) => { - const nativePrice = get(inputCurrency, 'native.price.amount', 0); + const newState = { + inputAmount, + inputAmountDisplay: amountDisplay !== undefined ? amountDisplay : inputAmount, + inputAsExactAmount: true, + }; - let nativeAmount = null; - if (inputAmount) { - nativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); + if (!this.nativeFieldRef.isFocused()) { + const nativePrice = get(inputCurrency, 'native.price.amount', 0); + newState.nativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); } - return { - inputAmount, - inputAmountDisplay: updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')), - inputAsExactAmount: isExact, - nativeAmount, - }; - }); + return newState; + }, callback); } - setNativeAmount = (nativeAmount, isExact = true) => { + setNativeAmount = (nativeAmount) => { this.setState(({ inputCurrency }) => { const nativePrice = get(inputCurrency, 'native.price.amount', 0); const inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); @@ -338,17 +365,17 @@ class ExchangeModal extends PureComponent { return { inputAmount, inputAmountDisplay: updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')), - inputAsExactAmount: isExact, + inputAsExactAmount: true, nativeAmount, }; }); } - setOutputAmount = (outputAmount, isExact = false) => { + setOutputAmount = (outputAmount, amountDisplay) => { this.setState(({ outputCurrency }) => ({ - inputAsExactAmount: isExact, + inputAsExactAmount: false, outputAmount, - outputAmountDisplay: updatePrecisionToDisplay(outputAmount, get(outputCurrency, 'price.value')), + outputAmountDisplay: amountDisplay !== undefined ? amountDisplay : outputAmount, })); } From 9a1fa61e255d4e5115d77ec82d2dd877010f6708 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 29 Aug 2019 04:01:47 -0700 Subject: [PATCH 246/636] undo my dumb idea for improving ButtonPressAnimation --- .../animations/ButtonPressAnimation.js | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index c8d6595a89c..c0e9d272ec1 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -135,17 +135,15 @@ export default class ButtonPressAnimation extends PureComponent { } } - handleActive = () => { + createInteraction = () => { if (this.props.isInteraction) { this.handle = InteractionManager.createInteractionHandle(); - } else { - this.handlePress(); } } - handleEnd = () => { - if (this.props.isInteraction) { - InteractionManager.runAfterInteractions(this.handlePress); + handleHaptic = () => { + if (this.props.enableHapticFeedback) { + ReactNativeHapticFeedback.trigger('selection'); } } @@ -157,15 +155,17 @@ export default class ButtonPressAnimation extends PureComponent { } handlePress = () => { - if (this.props.enableHapticFeedback) { - ReactNativeHapticFeedback.trigger('selection'); - } - if (this.props.onPress) { this.props.onPress(); } } + handleRunInteraction = () => ( + this.props.isInteraction + ? InteractionManager.runAfterInteractions(this.handlePress) + : this.handlePress() + ) + render = () => { const { activeOpacity, @@ -238,11 +238,14 @@ export default class ButtonPressAnimation extends PureComponent { this.gestureState, cond( eq(this.gestureState, ACTIVE), - call([], this.handleActive), + call([], this.createInteraction), // else if cond( eq(this.gestureState, END), - call([], this.handleEnd), + [ + call([], this.handleHaptic), + call([], this.handleRunInteraction), + ], ), ), ), From 5c316be98b82e73ff5f0ce6ba29785c17508f3af Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Fri, 30 Aug 2019 18:08:55 -0700 Subject: [PATCH 247/636] Downgrade react-native-svg due to breaking changes https://github.com/react-native-community/react-native-svg/issues/1083 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4b615e2594..bf2d1d60e90 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "^9.6.2", + "react-native-svg": "9.7.1", "react-native-tcp": "^3.3.0", "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", "react-native-tooltip": "^5.2.0", From 9c52ebb84422455dadf1856f3eab60dee5c6c8d3 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 29 Aug 2019 00:33:57 -0400 Subject: [PATCH 248/636] use token detail overrides in assets as well as exchange --- src/hoc/withUniswapAssets.js | 39 ++++++------ src/parsers/accounts.js | 11 ++-- src/redux/data.js | 13 +--- src/redux/uniswap.js | 4 +- src/references/index.js | 28 +++++++++ src/references/token-overrides.json | 98 +++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 37 deletions(-) create mode 100644 src/references/index.js create mode 100644 src/references/token-overrides.json diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 7a8ae62bc89..73b4fea11ed 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -1,41 +1,35 @@ import { filter, get, - keys, map, - mapKeys, property, sortBy, - toLower, values, } from 'lodash'; import { connect } from 'react-redux'; -import { compose, withProps } from 'recompact'; +import { + compose, + withProps, +} from 'recompact'; import { createSelector } from 'reselect'; -import uniswapAssetsRaw from '../references/uniswap-pairs.json'; +import { + uniswapAssetAddresses, + uniswapAssetsClean, +} from '../references'; import withAccountData from './withAccountData'; const allAssetsSelector = state => state.allAssets; const uniswapAssetsSelector = state => state.uniswapAssets; -export const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => toLower(key)); -export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); - const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); -const mapUniswapAssetItem = (asset) => { - const exchangeAddress = get(uniswapAssetsRawLoweredKeys, `${asset.address}.exchangeAddress`); - - return { - ...asset, - exchangeAddress, - uniqueId: exchangeAddress, - }; -}; - const withAssetsAvailableOnUniswap = (allAssets) => { const availableAssets = filter(allAssets, filterUniswapAssetsByAvailability); - return { assetsAvailableOnUniswap: map(availableAssets, mapUniswapAssetItem) }; + const assetsAvailableOnUniswap = map(availableAssets, (asset) => ({ + ...asset, + exchangeAddress: get(uniswapAssetsClean, `${asset.address}.exchangeAddress`), + })); + return { assetsAvailableOnUniswap }; }; const withSortedUniswapAssets = (unsortedUniswapAssets) => ({ @@ -52,7 +46,12 @@ const withSortedUniswapAssetsSelector = createSelector( withSortedUniswapAssets, ); -const mapStateToProps = ({ uniswap: { uniswapAssets } }) => ({ uniswapAssets }); +const mapStateToProps = ({ + uniswap: { uniswapAssets }, +}) => ({ + uniswapAssets, +}); + export default compose( connect(mapStateToProps), diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index ed2bd8a7a3c..f058b3fba1a 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -1,5 +1,6 @@ import { get } from 'lodash'; import { convertRawAmountToBalance } from '../helpers/utilities'; +import { loweredTokenOverrides } from '../references'; /** * @desc parse account assets @@ -17,11 +18,9 @@ export const parseAccountAssets = data => { }; }); - assets = assets.filter( + return assets.filter( asset => !!Number(get(asset, 'balance.amount')), ); - - return assets; } catch (error) { throw error; } @@ -33,15 +32,17 @@ export const parseAccountAssets = data => { * @return {Object} */ export const parseAsset = assetData => { + const address = get(assetData, 'asset_code', null); const name = get(assetData, 'name') || 'Unknown Token'; const symbol = get(assetData, 'symbol') || '———'; const asset = { - address: get(assetData, 'asset_code', null), + address, decimals: get(assetData, 'decimals'), name, price: get(assetData, 'price'), symbol: symbol.toUpperCase(), - uniqueId: get(assetData, 'asset_code') || name, + uniqueId: address || name, + ...loweredTokenOverrides[address], }; return asset; }; diff --git a/src/redux/data.js b/src/redux/data.js index 878d5c9213f..ecbbf73eaab 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -5,7 +5,6 @@ import { findIndex, get, includes, - isEmpty, isNil, map, partition, @@ -13,7 +12,6 @@ import { slice, uniqBy, } from 'lodash'; -import { DATA_API_KEY, DATA_ORIGIN } from 'react-native-dotenv'; import { getAssets, getLocalTransactions, @@ -22,8 +20,6 @@ import { saveAssets, saveLocalTransactions, } from '../handlers/localstorage/storage'; -import { uniswapAssetAddresses } from '../hoc/withUniswapAssets'; -import io from 'socket.io-client'; import { parseAccountAssets, parseAsset } from '../parsers/accounts'; import { parseNewTransaction } from '../parsers/newTransaction'; import { parseTransactions } from '../parsers/transactions'; @@ -41,8 +37,6 @@ import { const DATA_UPDATE_ASSETS = 'data/DATA_UPDATE_ASSETS'; const DATA_UPDATE_TRANSACTIONS = 'data/DATA_UPDATE_TRANSACTIONS'; -const DATA_UPDATE_ADDRESS_SOCKET = 'data/DATA_UPDATE_ADDRESS_SOCKET'; - const DATA_LOAD_ASSETS_REQUEST = 'data/DATA_LOAD_ASSETS_REQUEST'; const DATA_LOAD_ASSETS_SUCCESS = 'data/DATA_LOAD_ASSETS_SUCCESS'; const DATA_LOAD_ASSETS_FAILURE = 'data/DATA_LOAD_ASSETS_FAILURE'; @@ -220,8 +214,6 @@ export const addressAssetsReceived = (message, append = false, change = false) = const { accountAddress, network } = getState().settings; const assets = get(message, 'payload.assets', []); - if (!assets.length) return; - const liquidityTokens = remove(assets, (asset) => { const symbol = get(asset, 'asset.symbol', ''); return symbol === 'uni-v1'; @@ -233,8 +225,9 @@ export const addressAssetsReceived = (message, append = false, change = false) = dispatch(uniswapUpdateLiquidityTokens(liquidityTokens)); } const updatedAssets = dispatch(dedupeUniqueTokens(assets)); - if (!updatedAssets.length) return; + let parsedAssets = parseAccountAssets(updatedAssets); + if (append || change) { const { assets: existingAssets } = getState().data; parsedAssets = uniqBy(concat(parsedAssets, existingAssets), (item) => item.uniqueId); @@ -249,7 +242,7 @@ export const addressAssetsReceived = (message, append = false, change = false) = export const assetsReceived = (message) => (dispatch, getState) => { const assets = get(message, 'payload.assets', []); if (!assets.length) return; - let parsedAssets = map(assets, asset => parseAsset(asset)); + const parsedAssets = map(assets, asset => parseAsset(asset)); dispatch(uniswapUpdateAssets(parsedAssets)); }; diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 639afc6e499..f5f7bf0ce7f 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -17,7 +17,7 @@ import { getReserve, getReserves, } from '../handlers/uniswap'; -import { uniswapAssetsRawLoweredKeys } from '../hoc/withUniswapAssets'; +import { uniswapAssetsClean } from '../references'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -152,7 +152,7 @@ export const uniswapUpdateAssets = (assets) => (dispatch, getState) => { const loweredAddress = asset.address.toLowerCase(); return { ...asset, - exchangeAddress: get(uniswapAssetsRawLoweredKeys, `[${loweredAddress}].exchangeAddress`), + exchangeAddress: get(uniswapAssetsClean, `[${loweredAddress}].exchangeAddress`), }; }); const mappedAssets = keyBy(uniswapAssetPrices, (asset) => asset.address.toLowerCase()); diff --git a/src/references/index.js b/src/references/index.js new file mode 100644 index 00000000000..54c12800ab1 --- /dev/null +++ b/src/references/index.js @@ -0,0 +1,28 @@ +import { + keys, + mapKeys, + mapValues, + toLower, +} from 'lodash'; +import tokenOverrides from './token-overrides.json'; +import uniswapAssetsRaw from './uniswap-pairs.json'; + +export const loweredTokenOverrides = mapKeys( + tokenOverrides, + (value, address) => toLower(address), +); + +const uniswapAssetsRawLoweredKeys = mapKeys( + uniswapAssetsRaw, + (value, key) => toLower(key), +); + +export const uniswapAssetsClean = mapValues( + uniswapAssetsRawLoweredKeys, + (value, key) => ({ + ...value, + ...loweredTokenOverrides[key], + }), +); + +export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json new file mode 100644 index 00000000000..385235d3ac5 --- /dev/null +++ b/src/references/token-overrides.json @@ -0,0 +1,98 @@ +{ + "0x960b236A07cf122663c4303350609A66A7B288C0": { + "name": "Aragon" + }, + "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { + "name": "Bloom" + }, + "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { + "name": "Bancor" + }, + "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { + "name": "Dai" + }, + "0x4946Fcea7C692606e8908002e55A582af44AC121": { + "name": "FOAM" + }, + "0x6810e776880C02933D47DB1b9fc05908e5386b96": { + "name": "Gnosis" + }, + "0x12B19D3e2ccc14Da04FAe33e63652ce469b3F2FD": { + "name": "Grid+" + }, + "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { + "name": "Kyber Network" + }, + "0x514910771AF9Ca656af840dff83E8264EcF986CA": { + "name": "Chainlink" + }, + "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { + "name": "Loopring" + }, + "0x58b6A8A3302369DAEc383334672404Ee733aB239": { + "name": "Livepeer" + }, + "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { + "name": "Decentraland" + }, + "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { + "name": "Matic Network" + }, + "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { + "name": "Melon" + }, + "0x8E870D67F660D95d5be530380D0eC0bd388289E1": { + "name": "Paxos Standard" + }, + "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { + "name": "Kleros" + }, + "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { + "name": "POA Network" + }, + "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6": { + "name": "Raiden" + }, + "0x408e41876cCCDC0F92210600ef50372656052a38": { + "name": "Republic" + }, + "0x1985365e9f78359a9B6AD760e32412f4a445E862": { + "name": "Augur" + }, + "0x607F4C5BB672230e8672085532f7e901544a7375": { + "name": "iExec" + }, + "0x4156D3342D5c385a87D264F90653733592000581": { + "name": "SALT" + }, + "0x42456D7084eacF4083f1140d3229471bbA2949A8": { + "name": "Synthetix ETH" + }, + "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E": { + "name": "Status" + }, + "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { + "name": "Synthetix" + }, + "0x42d6622deCe394b54999Fbd73D108123806f6a18": { + "name": "SpankChain" + }, + "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { + "name": "Storj" + }, + "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { + "name": "Synthetix USD" + }, + "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { + "name": "Monolith" + }, + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": { + "name": "USD Coin" + }, + "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": { + "name": "Wrapped Bitcoin" + }, + "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { + "name": "0x" + } +} From a19199dff4fa65b9531f3d98333982ba58d01b5a Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 29 Aug 2019 00:50:23 -0400 Subject: [PATCH 249/636] removing spaces --- src/redux/data.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/redux/data.js b/src/redux/data.js index ecbbf73eaab..4753ff83d07 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -225,9 +225,7 @@ export const addressAssetsReceived = (message, append = false, change = false) = dispatch(uniswapUpdateLiquidityTokens(liquidityTokens)); } const updatedAssets = dispatch(dedupeUniqueTokens(assets)); - let parsedAssets = parseAccountAssets(updatedAssets); - if (append || change) { const { assets: existingAssets } = getState().data; parsedAssets = uniqBy(concat(parsedAssets, existingAssets), (item) => item.uniqueId); From 847fe8fd334b7c16e441b8bae58bcc349b4a1e65 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 29 Aug 2019 12:55:34 -0400 Subject: [PATCH 250/636] finish hookup of using token overrides for exchange --- src/components/exchange/ExchangeOutputField.js | 2 +- src/handlers/uniswap.js | 2 +- src/hoc/withAccountAddress.js | 3 ++- src/redux/explorer.js | 17 +++++++---------- src/redux/uniswap.js | 9 +++++---- src/utils/ethereumUtils.js | 4 ++-- 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index e2482ab5bd8..0d42c682c5d 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { withNeverRerender } from '../../hoc'; -import { colors, padding, position, shadow } from '../../styles'; +import { colors, padding } from '../../styles'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; import { EnDash } from '../html-entities'; diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index abbadb914be..de7429d9706 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -15,7 +15,7 @@ import { fromWei, multiply, } from '../helpers/utilities'; -import { uniswapAssetAddresses } from '../hoc/withUniswapAssets'; +import { uniswapAssetAddresses } from '../references'; import { loadWallet } from '../model/wallet'; import exchangeABI from '../references/uniswap-exchange-abi.json'; import erc20ABI from '../references/erc20-abi.json'; diff --git a/src/hoc/withAccountAddress.js b/src/hoc/withAccountAddress.js index f430622c1f1..5cd0b7e9211 100644 --- a/src/hoc/withAccountAddress.js +++ b/src/hoc/withAccountAddress.js @@ -1,3 +1,4 @@ +import { toLower } from 'lodash'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; import { createSelector } from 'reselect'; @@ -9,7 +10,7 @@ const accountAddressSelector = state => state.accountAddress; const lowerAccountAddressSelector = createSelector( [accountAddressSelector], - (accountAddress) => ({ accountAddress: accountAddress.toLowerCase() }), + (accountAddress) => ({ accountAddress: toLower(accountAddress) }), ); export default Component => compose( diff --git a/src/redux/explorer.js b/src/redux/explorer.js index f581c9f55b6..76d21cb1a90 100644 --- a/src/redux/explorer.js +++ b/src/redux/explorer.js @@ -1,9 +1,7 @@ -import { get, isNil } from 'lodash'; +import { isNil } from 'lodash'; import { DATA_API_KEY, DATA_ORIGIN } from 'react-native-dotenv'; -import { uniswapAssetAddresses } from '../hoc/withUniswapAssets'; import io from 'socket.io-client'; -import { parseAccountAssets } from '../parsers/accounts'; -import { isLowerCaseMatch } from '../utils'; +import { uniswapAssetAddresses } from '../references'; import { addressAssetsReceived, assetsReceived, @@ -24,6 +22,11 @@ const messages = { CHANGED: 'changed address assets', RECEIVED: 'received address assets', }, + ADDRESS_TRANSACTIONS: { + APPENDED: 'appended address transactions', + RECEIVED: 'received address transactions', + REMOVED: 'removed address transactions', + }, ASSETS: { CHANGED: 'changed price', RECEIVED: 'received assets', @@ -32,11 +35,6 @@ const messages = { DISCONNECT: 'disconnect', ERROR: 'error', RECONNECT_ATTEMPT: 'reconnect_attempt', - ADDRESS_TRANSACTIONS: { - APPENDED: 'appended address transactions', - RECEIVED: 'received address transactions', - REMOVED: 'removed address transactions', - }, }; // -- Actions ---------------------------------------- // @@ -141,7 +139,6 @@ const listenOnAddressMessages = socket => (dispatch, getState) => { }); socket.on(messages.ADDRESS_ASSETS.RECEIVED, (message) => { - console.log('ADDRESS received', message); dispatch(addressAssetsReceived(message)); }); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index f5f7bf0ce7f..6ce29b0d38e 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -6,6 +6,7 @@ import { isEmpty, keyBy, map, + toLower, } from 'lodash'; import { getAccountLocal, @@ -73,7 +74,7 @@ export const uniswapLoadState = () => async (dispatch, getState) => { export const uniswapGetTokenReserve = (tokenAddress) => (dispatch, getState) => ( new Promise((resolve, reject) => { - tokenAddress = tokenAddress.toLowerCase(); + tokenAddress = toLower(tokenAddress); dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_REQUEST }); const { accountAddress, network } = getState().settings; const { tokenReserves } = getState().uniswap; @@ -149,13 +150,13 @@ export const uniswapUpdateAllowances = (tokenAddress, allowance) => (dispatch, g export const uniswapUpdateAssets = (assets) => (dispatch, getState) => { const { accountAddress, network } = getState().settings; const uniswapAssetPrices = map(assets, asset => { - const loweredAddress = asset.address.toLowerCase(); + const loweredAddress = toLower(asset.address); return { ...asset, exchangeAddress: get(uniswapAssetsClean, `[${loweredAddress}].exchangeAddress`), }; }); - const mappedAssets = keyBy(uniswapAssetPrices, (asset) => asset.address.toLowerCase()); + const mappedAssets = keyBy(uniswapAssetPrices, asset => toLower(asset.address)); dispatch({ payload: mappedAssets, type: UNISWAP_UPDATE_ASSETS, @@ -164,7 +165,7 @@ export const uniswapUpdateAssets = (assets) => (dispatch, getState) => { }; export const uniswapUpdateAssetPrice = (address, price) => (dispatch, getState) => { - const addressKey = address.toLowerCase(); + const addressKey = toLower(address); const { accountAddress, network } = getState().settings; const { uniswapAssets } = getState().uniswap; const updatedAsset = { ...uniswapAssets[addressKey], price }; diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index ea5d4e61ccc..284a4e12797 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -28,9 +28,9 @@ export const getAsset = (assets, address = 'eth') => { // console.log('asset.address', asset.address); // console.log('address', address) - return asset.address === address + return asset.address === address; }); -} +}; /** * @desc remove hex prefix From ed0f23f89210d0fda0479c85f4ff64f62ea97774 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Mon, 2 Sep 2019 17:04:20 -0600 Subject: [PATCH 251/636] Add more overrides --- src/references/token-overrides.json | 63 +++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 385235d3ac5..3618a1901ac 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -1,25 +1,52 @@ { + "ETH": { + "name": "Ethereum" + }, "0x960b236A07cf122663c4303350609A66A7B288C0": { "name": "Aragon" }, + "0x0D8775F648430679A709E98d2b0Cb6250d2887EF": { + "name": "Basic Attention Token" + }, "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { "name": "Bloom" }, "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { "name": "Bancor" }, + "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { + "name": "Compound Dai" + }, + "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { + "name": "Civic" + }, "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { "name": "Dai" }, + "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { + "name": "Digix Gold Token" + }, "0x4946Fcea7C692606e8908002e55A582af44AC121": { "name": "FOAM" }, + "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b": { + "name": "FunFair" + }, + "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { + "name": "DAOstack" + }, "0x6810e776880C02933D47DB1b9fc05908e5386b96": { "name": "Gnosis" }, + "0xa74476443119A942dE498590Fe1f2454d7D4aC0d": { + "name": "Golem" + }, "0x12B19D3e2ccc14Da04FAe33e63652ce469b3F2FD": { "name": "Grid+" }, + "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { + "name": "Kin" + }, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { "name": "Kyber Network" }, @@ -29,6 +56,12 @@ "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { "name": "Loopring" }, + "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { + "name": "Holo" + }, + "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { + "name": "LoomToken" + }, "0x58b6A8A3302369DAEc383334672404Ee733aB239": { "name": "Livepeer" }, @@ -38,9 +71,18 @@ "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { "name": "Matic Network" }, + "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { + "name": "Maker" + }, "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { "name": "Melon" }, + "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206": { + "name": "Nexo" + }, + "0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671": { + "name": "Numeraire" + }, "0x8E870D67F660D95d5be530380D0eC0bd388289E1": { "name": "Paxos Standard" }, @@ -62,6 +104,9 @@ "0x607F4C5BB672230e8672085532f7e901544a7375": { "name": "iExec" }, + "0xB4EFd85c19999D84251304bDA99E90B92300Bd93": { + "name": "Rocket Pool" + }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT" }, @@ -86,12 +131,30 @@ "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { "name": "Monolith" }, + "0xdac17f958d2ee523a2206206994597c13d831ec7": { + "name": "Tether" + }, + "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E": { + "name": "TrueUSD" + }, + "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { + "name": "Uniswap V1" + }, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": { "name": "USD Coin" }, "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": { "name": "Wrapped Bitcoin" }, + "0x09fE5f0236F0Ea5D930197DCE254d77B04128075": { + "name": "Wrapped CryptoKitties" + }, + "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": { + "name": "Wrapped Ether" + }, + "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { + "name": "CryptoFranc" + }, "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { "name": "0x" } From c60b5f4365910e294c139da5b3c88594859ce6bb Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 10 Sep 2019 19:14:51 -0400 Subject: [PATCH 252/636] syncronize the clearing of ExchangeModal TextInputs when user clears a single field --- src/components/exchange/ExchangeInput.js | 8 +- src/helpers/utilities.js | 2 - src/screens/ExchangeModal.js | 244 +++++++++++++---------- 3 files changed, 137 insertions(+), 117 deletions(-) diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 1006cc61a25..3af9094ee74 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -30,11 +30,6 @@ export default class ExchangeInput extends PureComponent { placeholderTextColor: colors.alpha(colors.blueGreyDark, 0.5), } - onChangeText = (formatted, extracted) => { - // XXX TODO: some funky stuff is going on here related to the '$' symbol in the input mask - this.props.onChangeText(extracted ? formatted : ''); - } - render = () => { const { color, @@ -43,6 +38,7 @@ export default class ExchangeInput extends PureComponent { fontSize, fontWeight, mask, + onChangeText, placeholder, placeholderTextColor, refInput, @@ -58,7 +54,7 @@ export default class ExchangeInput extends PureComponent { keyboardAppearance="dark" keyboardType="decimal-pad" mask={mask} - onChangeText={this.onChangeText} + onChangeText={onChangeText} placeholder={placeholder} placeholderTextColor={placeholderTextColor} refInput={refInput} diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 7de52741de5..e23d0fb4179 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -27,7 +27,6 @@ export const convertAmountToRawAmount = (value, decimals) => BigNumber(value).ti */ export const convertNumberToString = value => BigNumber(`${value}`).toFixed(); - /** * @desc compares if numberOne is greater than numberTwo * @param {Number} numberOne @@ -67,7 +66,6 @@ export const mod = (numberOne, numberTwo) => BigNumber(`${numberOne}`) */ export const greaterThanOrEqual = (numberOne, numberTwo) => BigNumber(`${numberOne}`).comparedTo(BigNumber(`${numberTwo}`)) >= 0; - /** * @desc real floor divides two numbers * @param {Number} numberOne diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a857db8f621..34a9a5a2097 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -176,7 +176,11 @@ class ExchangeModal extends PureComponent { assignOutputFieldRef = (ref) => { this.outputFieldRef = ref; } /* eslint-enable lines-between-class-members */ - clearInputField = () => this.inputFieldRef.clear() + clearForm = () => { + if (this.inputFieldRef) this.inputFieldRef.clear(); + if (this.nativeFieldRef) this.nativeFieldRef.clear(); + if (this.outputFieldRef) this.outputFieldRef.clear(); + } getCurrencyAllowance = async () => { const { accountAddress, allowances, uniswapUpdateAllowances } = this.props; @@ -196,27 +200,13 @@ class ExchangeModal extends PureComponent { return this.setState({ isAssetApproved: greaterThan(allowance, 0) }); } - getReserveData = async (tokenAddress) => { - const { tokenReserves, uniswapGetTokenReserve } = this.props; - - if (tokenAddress === 'eth') { - return null; - } - - let reserve = tokenReserves[tokenAddress.toLowerCase()]; - if (!reserve) { - reserve = await uniswapGetTokenReserve(tokenAddress); - } - - return reserve; - } - getMarketDetails = async () => { const { chainId, nativeCurrency } = this.props; const { inputAmount, inputAsExactAmount, inputCurrency, + nativeAmount, outputAmount, outputCurrency, } = this.state; @@ -306,22 +296,33 @@ class ExchangeModal extends PureComponent { tradeDetails, }); + const isInputZero = Number(rawInputAmount) === 0; + const isNativeZero = Number(nativeAmount || 0) === 0; + const isOutputZero = Number(rawOutputAmount) === 0; + + if (this.nativeFieldRef.isFocused() && isNativeZero) { + this.clearForm(); + } + if (inputAsExactAmount && !this.outputFieldRef.isFocused()) { - const updatedAmount = get(tradeDetails, 'outputAmount.amount'); - const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, outputDecimals); + if (isInputZero) { + this.clearForm(); + } else { + const updatedAmount = get(tradeDetails, 'outputAmount.amount'); + const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, outputDecimals); - const updatedAmountDisplay = updatePrecisionToDisplay( - rawUpdatedAmount, - get(outputCurrency, 'price.value'), - ); + const updatedAmountDisplay = updatePrecisionToDisplay( + rawUpdatedAmount, + get(outputCurrency, 'price.value'), + ); - this.setOutputAmount(rawUpdatedAmount, updatedAmountDisplay); + this.setOutputAmount(rawUpdatedAmount, updatedAmountDisplay); + } } if (!inputAsExactAmount && !this.inputFieldRef.isFocused()) { - if (Number(slippage) === 0) { - // this isnt working - this.setInputAmount(0, undefined, this.clearInputField); + if (isOutputZero) { + this.clearForm(); } else { const updatedAmount = get(tradeDetails, 'inputAmount.amount'); const rawUpdatedAmount = convertRawAmountToDecimalFormat(updatedAmount, inputDecimals); @@ -340,78 +341,20 @@ class ExchangeModal extends PureComponent { } } - setInputAmount = (inputAmount, amountDisplay, callback) => { - this.setState(({ inputCurrency }) => { - const newState = { - inputAmount, - inputAmountDisplay: amountDisplay !== undefined ? amountDisplay : inputAmount, - inputAsExactAmount: true, - }; - - if (!this.nativeFieldRef.isFocused()) { - const nativePrice = get(inputCurrency, 'native.price.amount', 0); - newState.nativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); - } - - return newState; - }, callback); - } - - setNativeAmount = (nativeAmount) => { - this.setState(({ inputCurrency }) => { - const nativePrice = get(inputCurrency, 'native.price.amount', 0); - const inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); - - return { - inputAmount, - inputAmountDisplay: updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')), - inputAsExactAmount: true, - nativeAmount, - }; - }); - } - - setOutputAmount = (outputAmount, amountDisplay) => { - this.setState(({ outputCurrency }) => ({ - inputAsExactAmount: false, - outputAmount, - outputAmountDisplay: amountDisplay !== undefined ? amountDisplay : outputAmount, - })); - } - - setInputCurrency = (inputCurrency, force) => { - const { outputCurrency } = this.state; + getReserveData = async (tokenAddress) => { + if (tokenAddress === 'eth') return null; - this.setState({ inputCurrency }); + const { tokenReserves, uniswapGetTokenReserve } = this.props; - if (!force && isSameAsset(inputCurrency, outputCurrency)) { - if (!isNil(inputCurrency) && !isNil(outputCurrency)) { - this.setOutputCurrency(null, true); - } else { - this.setOutputCurrency(inputCurrency, true); - } + let reserve = tokenReserves[tokenAddress.toLowerCase()]; + if (!reserve) { + reserve = await uniswapGetTokenReserve(tokenAddress); } - } - - setOutputCurrency = (outputCurrency, force) => { - const { allAssets } = this.props; - const { inputCurrency } = this.state; - - this.setState({ outputCurrency }); - if (!force && isSameAsset(inputCurrency, outputCurrency)) { - const outputAddress = outputCurrency.address.toLowerCase(); - const asset = ethereumUtils.getAsset(allAssets, outputAddress); - - if (!isNil(asset) && !isNil(inputCurrency) && !isNil(outputCurrency)) { - this.setInputCurrency(null, true); - } else { - this.setInputCurrency(outputCurrency, true); - } - } + return reserve; } - onPressMaxBalance = () => { + handlePressMaxBalance = () => { const { inputCurrency } = this.state; let maxBalance = get(inputCurrency, 'balance.amount', 0); if (inputCurrency.address === 'eth') { @@ -421,20 +364,6 @@ class ExchangeModal extends PureComponent { return this.setInputAmount(maxBalance); } - handleSelectInputCurrency = () => { - this.props.navigation.navigate('CurrencySelectScreen', { - onSelectCurrency: this.setInputCurrency, - type: CurrencySelectionTypes.input, - }); - } - - handleSelectOutputCurrency = () => { - this.props.navigation.navigate('CurrencySelectScreen', { - onSelectCurrency: this.setOutputCurrency, - type: CurrencySelectionTypes.output, - }); - } - handleSubmit = async () => { const { accountAddress, dataAddNewTransaction, navigation } = this.props; const { inputAmount, inputCurrency, tradeDetails } = this.state; @@ -485,6 +414,103 @@ class ExchangeModal extends PureComponent { this.setState({ isUnlockingAsset: true }); } + navigateToSelectInputCurrency = () => { + this.props.navigation.navigate('CurrencySelectScreen', { + onSelectCurrency: this.setInputCurrency, + type: CurrencySelectionTypes.input, + }); + } + + navigateToSelectOutputCurrency = () => { + this.props.navigation.navigate('CurrencySelectScreen', { + onSelectCurrency: this.setOutputCurrency, + type: CurrencySelectionTypes.output, + }); + } + + setInputAmount = (inputAmount, amountDisplay) => { + this.setState(({ inputCurrency }) => { + const newState = { + inputAmount, + inputAmountDisplay: amountDisplay !== undefined ? amountDisplay : inputAmount, + inputAsExactAmount: true, + }; + + if (!this.nativeFieldRef.isFocused()) { + let nativeAmount = null; + + if (inputAmount) { + const nativePrice = get(inputCurrency, 'native.price.amount', 0); + nativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); + } + + newState.nativeAmount = nativeAmount; + } + + return newState; + }); + } + + setInputCurrency = (inputCurrency, force) => { + const { outputCurrency } = this.state; + + this.setState({ inputCurrency }); + + if (!force && isSameAsset(inputCurrency, outputCurrency)) { + if (!isNil(inputCurrency) && !isNil(outputCurrency)) { + this.setOutputCurrency(null, true); + } else { + this.setOutputCurrency(inputCurrency, true); + } + } + } + + setNativeAmount = (nativeAmount) => { + this.setState(({ inputCurrency }) => { + let inputAmount = null; + let inputAmountDisplay = null; + + if (nativeAmount) { + const nativePrice = get(inputCurrency, 'native.price.amount', 0); + inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); + inputAmountDisplay = updatePrecisionToDisplay(inputAmount, get(inputCurrency, 'price.value')); + } + + return { + inputAmount, + inputAmountDisplay, + inputAsExactAmount: true, + nativeAmount, + }; + }); + } + + setOutputAmount = (outputAmount, amountDisplay) => { + this.setState(({ outputCurrency }) => ({ + inputAsExactAmount: false, + outputAmount, + outputAmountDisplay: amountDisplay !== undefined ? amountDisplay : outputAmount, + })); + } + + setOutputCurrency = (outputCurrency, force) => { + const { allAssets } = this.props; + const { inputCurrency } = this.state; + + this.setState({ outputCurrency }); + + if (!force && isSameAsset(inputCurrency, outputCurrency)) { + const outputAddress = outputCurrency.address.toLowerCase(); + const asset = ethereumUtils.getAsset(allAssets, outputAddress); + + if (!isNil(asset) && !isNil(inputCurrency) && !isNil(outputCurrency)) { + this.setInputCurrency(null, true); + } else { + this.setInputCurrency(outputCurrency, true); + } + } + } + render = () => { const { nativeCurrency, transitionPosition } = this.props; @@ -540,15 +566,15 @@ class ExchangeModal extends PureComponent { nativeCurrency={nativeCurrency} nativeFieldRef={this.assignNativeFieldRef} onFocus={this.handleFocusField} - onPressMaxBalance={this.onPressMaxBalance} - onPressSelectInputCurrency={this.handleSelectInputCurrency} + onPressMaxBalance={this.handlePressMaxBalance} + onPressSelectInputCurrency={this.navigateToSelectInputCurrency} onUnlockAsset={this.handleUnlockAsset} setInputAmount={this.setInputAmount} setNativeAmount={this.setNativeAmount} /> Date: Tue, 10 Sep 2019 20:01:34 -0400 Subject: [PATCH 253/636] =?UTF-8?q?fix=20=E2=80=98react-navigation-tabs?= =?UTF-8?q?=E2=80=99=20at=20version=202.3.0=20due=20to=20breaking=20change?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 8 +++ package.json | 2 +- yarn.lock | 165 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 162 insertions(+), 13 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9b40424e242..d8bde0534b8 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -132,11 +132,15 @@ PODS: - react-native-fast-image (6.1.1): - React - SDWebImage (~> 5.0) +<<<<<<< HEAD <<<<<<< HEAD - react-native-netinfo (4.2.1): ======= - react-native-netinfo (4.1.5): >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + - react-native-netinfo (4.2.1): +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes - React - react-native-version-number (0.3.6): - React @@ -381,11 +385,15 @@ SPEC CHECKSUMS: react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 +<<<<<<< HEAD <<<<<<< HEAD react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 ======= react-native-netinfo: 0e563248a4b9a99c33ec29bd03c2d50767db22a6 >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e diff --git a/package.json b/package.json index bf2d1d60e90..35b97ae9554 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "react-native-version-number": "^0.3.6", "react-navigation": "^3.11.1", "react-navigation-stack": "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", - "react-navigation-tabs": "^2.3.0", + "react-navigation-tabs": "2.3.0", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", diff --git a/yarn.lock b/yarn.lock index 6aef7f1435d..4cadc1dac3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -233,10 +233,22 @@ esutils "^2.0.2" js-tokens "^4.0.0" +<<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== +======= +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" + integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes + +"@babel/parser@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" + integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -1098,6 +1110,7 @@ integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== "@react-native-community/netinfo@^4.1.4": +<<<<<<< HEAD <<<<<<< HEAD version "4.2.1" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" @@ -1111,6 +1124,11 @@ version "4.1.5" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.5.tgz#4bb44842db6a1a18f00a0f061b0e3dcc638f67dd" integrity sha512-lagdZr9UiVAccNXYfTEj+aUcPCx9ykbMe9puffeIyF3JsRuMmlu3BjHYx1klUHX7wNRmFNC8qVP0puxUt1sZ0A== +======= + version "4.2.1" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" + integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes <<<<<<< HEAD "@react-navigation/core@~3.5.0": @@ -1382,6 +1400,7 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": +<<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== @@ -1406,6 +1425,21 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.52.tgz#ef0ca1809994e20186090408b8cb7f2a6877d5f9" integrity sha512-2RbW7WXeLex6RI+kQSxq6Ym0GiVcODeQ4Km7MnnTX5BHdOGQnqVa+s6AUmAW+OFYAJ8wv9QxvNZXm7/kBdGTVw== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "12.7.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04" + integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== + +"@types/node@^10.3.2": + version "10.14.17" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.17.tgz#b96d4dd3e427382482848948041d3754d40fd5ce" + integrity sha512-p/sGgiPaathCfOtqu2fx5Mu1bcjuP8ALFg4xpGgNkcin7LwRyzUKniEHBKdcE1RPsenq5JVPIpMTJSygLboygQ== + +"@types/node@^8.0.7": + version "8.10.53" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.53.tgz#5fa08eef810b08b2c03073e360b54f7bad899db1" + integrity sha512-aOmXdv1a1/vYUn1OT1CED8ftbkmmYbKhKGSyMDeJiidLvKRKvZUQOdXwG/wcNY7T1Qb0XTlVdiYjIq00U7pLrQ== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes "@types/q@^1.5.1": version "1.5.2" @@ -1440,6 +1474,7 @@ "@types/vfile-message" "*" "@types/yargs-parser@*": +<<<<<<< HEAD <<<<<<< HEAD version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -1449,6 +1484,11 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "13.1.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" + integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes "@types/yargs@^13.0.0": version "13.0.2" @@ -1504,6 +1544,7 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.36": @@ -1543,24 +1584,31 @@ resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.34.tgz#76ad24610ba288a0a5f2ec146d15214fa9683261" integrity sha512-Uu1biiWl/t/FzmHxqSK7Ij2s0tXjOF/0qV4IG4qzmfx4k2h1WR4luvF5oLTBMRsoFVSGF1M/FgYYllPEj1nfjQ== >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= +"@walletconnect/core@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" + integrity sha512-VnS4exaqaNJQy6xc+HX+1psjmIjKimCir9xypbx4kMz1F8Tm8/m1bMv3h4c1Q7wyiZHsSTlMZmb64UuVhM2pqw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: - "@walletconnect/types" "^1.0.0-beta.34" - "@walletconnect/utils" "^1.0.0-beta.34" + "@walletconnect/types" "^1.0.0-beta.35" + "@walletconnect/utils" "^1.0.0-beta.35" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.34.tgz#b2ba8c7c04fc05c48efb468d167bdf7a1b9c6157" - integrity sha512-zKiMxm6QmK+t9NWvWn1XhZ+hS7TEVuk3HnitzbMUVEsIydFUJmowoCD+a5HUqhNIpqestz7efH/2p+zpI2vtRg== + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.35.tgz#318d1d067cae5261755b502a3a5b27dd23c6a815" + integrity sha512-npRV1XicayiSMk84+he5JEASC5oFHkYsL2S9yuHfCVzctIGE6kIX0gpuBKUbzCxkve1yezIeaQOYfwVKlLRp5w== dependencies: - "@walletconnect/core" "^1.0.0-beta.34" - "@walletconnect/types" "^1.0.0-beta.34" - "@walletconnect/utils" "^1.0.0-beta.34" + "@walletconnect/core" "^1.0.0-beta.35" + "@walletconnect/types" "^1.0.0-beta.35" + "@walletconnect/utils" "^1.0.0-beta.35" -"@walletconnect/types@^1.0.0-beta.34": - version "1.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.34.tgz#b8b6a7a6ae2f628e116e89c735bf650e4287fd47" - integrity sha512-+p2qgzRaZprh+TnIwuKePh9Bua6dQZgfEcDfpK8EOAymFkU+aOvbFD6tCv3q494UUG8qoe1qQSxOjaXFip66SA== +"@walletconnect/types@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.35.tgz#02577da82a85361c68518350fe6139dee4a43445" + integrity sha512-xlcSt0ZdEkiYmCpuO6cleLk1MmjyMPCCT5o1/z0zcRV15uDxfb+N9J/S2uVZBoLtnBtUK1m+11sRF3KrIo9FgQ== +<<<<<<< HEAD <<<<<<< HEAD "@walletconnect/utils@^1.0.0-beta.33": version "1.0.0-beta.33" @@ -1573,11 +1621,18 @@ resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.34.tgz#af74d522826ecaff5d6cea85b960ba16b71a23d0" integrity sha512-nGdcCaoL4UpSQptlxAdox5WdgGyvZms6kCu9m7TH4qxnL+nCkitQg13Y7m05o1RjzRPmf/4ukfqBrEWTz3heUQ== >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= +"@walletconnect/utils@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" + integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD "@walletconnect/types" "^1.0.0-beta.36" ======= @@ -1586,6 +1641,9 @@ ======= "@walletconnect/types" "^1.0.0-beta.34" >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= + "@walletconnect/types" "^1.0.0-beta.35" +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -3685,6 +3743,7 @@ ejs@^2.6.2: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== +<<<<<<< HEAD <<<<<<< HEAD electron-to-chromium@^1.3.247: version "1.3.259" @@ -3708,6 +3767,12 @@ electron-to-chromium@^1.3.191: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.243.tgz#32f64f00fa121532d1d49f5c0a15fd77f52ae889" integrity sha512-+edFdHGxLSmAKftXa5xZIg19rHkkJLiW+tRu0VMVG3RKztyeKX7d3pXf707lS6+BxB9uBun3RShbxCI1PtBAgQ== >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= +electron-to-chromium@^1.3.247: + version "1.3.254" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.254.tgz#af9795b9b2af0729997331a033ddc767af758224" + integrity sha512-7I5/OkgR6JKy6RFLJeru0kc0RMmmMu1UnkHBKInFKRrg1/4EQKIqOaUqITSww/SZ1LqWwp1qc/LLoIGy449eYw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes elliptic@6.3.3: version "6.3.3" @@ -4065,6 +4130,7 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.1.0: +<<<<<<< HEAD <<<<<<< HEAD version "6.4.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" @@ -4074,6 +4140,11 @@ eslint@^6.1.0: resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "6.3.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.3.0.tgz#1f1a902f67bfd4c354e7288b81e40654d927eb6a" + integrity sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4167,6 +4238,7 @@ eth-contract-metadata@^1.9.2: integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== ethers@^4.0.28, ethers@^4.0.33: +<<<<<<< HEAD <<<<<<< HEAD version "4.0.37" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" @@ -4176,6 +4248,11 @@ ethers@^4.0.28, ethers@^4.0.33: resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.36.tgz#96519fd3cc9317f938c8ee4d22050f34e3c2ef0e" integrity sha512-rWdchEhUyXx01GiwexH6Sha97CQ9tJdQwe6FtYKxShC7VEZV41nuKt+lzCQ4OqvQwZK5PcAKaAZv2GDsCH33SA== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "4.0.37" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" + integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -5236,6 +5313,7 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: +<<<<<<< HEAD <<<<<<< HEAD version "17.0.15" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.15.tgz#a4a378910fa06ca1c34f9e481ff6642acdb16dba" @@ -5245,6 +5323,11 @@ i18next@^17.0.3: resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.12.tgz#d732a6c1131fc3b02305a8241eac25ec0d1cf663" integrity sha512-FoYYnORcAMNznVXSpwJ1zVGL8kXcv1JUmvTqoQyuPPRncBq9rd7Mi0I/oVXkGR3YIek5dDiunvA/NGG2o+mMuw== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "17.0.14" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" + integrity sha512-yEGSWX9UTpWQskPsFy03t8uhZh5wyZ7v9p+MCo08Sd2edTaFdg1gFA633dg9OqTxJ/z1rtCiacgOlDSBpgssgw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@babel/runtime" "^7.3.1" @@ -5283,9 +5366,15 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^3.1.3: +<<<<<<< HEAD version "3.3.0" resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== +======= + version "3.2.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-3.2.1.tgz#e3070a96508ffdb7331f8bf681f2a55f8729d0cd" + integrity sha512-tRu/ipavNRwxKcRSUW2jOJ6cZCitHAHdI5WdH9fYfFt35PvZXJ7GmNVR0s1ATt6DGhgQJMnu3tVtZ2C/UzTUQw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes import-fresh@^2.0.0: version "2.0.0" @@ -7326,6 +7415,7 @@ minimist@~0.0.1: minipass@^2.2.1, minipass@^2.3.5: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.5.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" @@ -7340,6 +7430,11 @@ minipass@^2.2.1, minipass@^2.3.5: resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.0.tgz#dddb1d001976978158a05badfcbef4a771612857" integrity sha512-9FwMVYhn6ERvMR8XFdOavRz4QK/VJV8elU1x50vYexf9lslDcWe/f4HBRxCPd185ekRSjU6CfYyJCECa/CQy7Q== >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= + version "2.5.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" + integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -7459,6 +7554,7 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.0.3: +<<<<<<< HEAD <<<<<<< HEAD version "2.1.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" @@ -7468,6 +7564,11 @@ nanoid@^2.0.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.4.tgz#4889355c9ce8e24efad7c65945a4a2875ac3e8f4" integrity sha512-sOJnBmY3TJQBVIBqKHoifuwygrocXg3NjS9rZSMnVl05XWSHK7Qxb177AIZQyMDjP86bz+yneozj/h9qsPLcCA== >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= + version "2.1.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.0.tgz#3de3dbd68cfb2f3bd52550e2bfd439cf75040eb2" + integrity sha512-g5WwS+p6Cm+zQhO2YOpRbQThZVnNb7DDq74h8YDCLfAGynrEOrbx2E16dc8ciENiP1va5sqaAruqn2sN+xpkWg== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes nanomatch@^1.2.9: version "1.2.13" @@ -7599,16 +7700,22 @@ node-pre-gyp@^0.12.0: tar "^4" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes node-releases@^1.1.29: version "1.1.30" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== +<<<<<<< HEAD ======= node-releases@^1.1.25: version "1.1.28" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.28.tgz#503c3c70d0e4732b84e7aaa2925fbdde10482d4a" integrity sha512-AQw4emh6iSXnCpDiFe0phYcThiccmkNWMZnFZ+lDJjAP8J0m2fVd59duvUUyuTirQOhIAajTFkzG6FHCLBO59g== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: semver "^5.3.0" @@ -7758,13 +7865,19 @@ object-copy@^0.1.0: kind-of "^3.0.3" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes object-inspect@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== +<<<<<<< HEAD ======= >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes object-is@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" @@ -8211,9 +8324,15 @@ pascalcase@^0.1.1: integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= patch-package@^6.1.2: +<<<<<<< HEAD version "6.2.0" resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.0.tgz#677de858e352b6ca4e6cb48a6efde2cec9fde566" integrity sha512-HWlQflaBBMjLBfOWomfolF8aqsFDeNbSNro1JDUgYqnVvPM5OILJ9DQdwIRiKmGaOsmHvhkl1FYkvv1I9r2ZJw== +======= + version "6.1.4" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.1.4.tgz#3a3201e9f62d2fc119a0fd115e1e5e6dbd5f0036" + integrity sha512-4lKS4wKT7OEUdzyACeGJtMvz36PdzjQ3o6pRc9DFDLpA8jPlq1IWeh7yleOXv/+fJDv+bNPpnAhid35pUVHaSA== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@yarnpkg/lockfile" "^1.1.0" chalk "^2.4.2" @@ -9045,6 +9164,7 @@ react-native-redash@^7.5.1: use-memo-one "^1.1.1" react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: +<<<<<<< HEAD <<<<<<< HEAD version "0.14.8" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" @@ -9054,6 +9174,11 @@ react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= + version "0.14.8" + resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" + integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: hoist-non-react-statics "^2.3.1" @@ -9088,6 +9213,7 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== +<<<<<<< HEAD react-native-svg@^9.6.2: <<<<<<< HEAD <<<<<<< HEAD @@ -9100,6 +9226,9 @@ react-native-svg@^9.6.2: integrity sha512-6SlbGx0vlXHyDPQXSpX+8o6bNjxKFNJsISoboAkR7YWW6hdnkMg/HJXCgT6oJC0/ClKtSO7ZPrQcK4HR65kDNg== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic ======= +======= +react-native-svg@9.7.1: +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes version "9.7.1" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.7.1.tgz#a6d270cd51f8f238de7623338211debf4ff9cf5c" integrity sha512-Yr54SyLPCdovLCJ08V7syJUe1iKrTYG9V5wB08z6lh/9FdC2R9CtBnMyz83GDLKfzUONqqH9nN1l+o61CgD3tg== @@ -9224,6 +9353,7 @@ react-navigation-stack@2.0.0-alpha.9: react-navigation-stack@^2.0.0-alpha.9, "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: ======= "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: +<<<<<<< HEAD >>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now version "2.0.0-alpha.10" resolved "https://github.com/react-navigation/stack#95c9fcad62fdf9f5fe3861bbf182d83d9e6b0edd" @@ -9235,6 +9365,17 @@ react-navigation-tabs@^2.3.0: version "2.5.2" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.2.tgz#80812254e32c5720722fed9a26b6e109ed0f4ac1" integrity sha512-f5OlXROO6VtnvgmSBzvS+2X8+KEMjJ4JM3S3IsmHa2J1dc/ssZE9QNEjttmsNxDi79vHVNaC+oiXI9GUtb3+YA== +======= + version "2.0.0-alpha.12" + resolved "https://github.com/react-navigation/stack#143701d50532e37f54f0e027d899164fd8ede32a" + dependencies: + react-native-safe-area-view "^0.14.6" + +react-navigation-tabs@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.3.0.tgz#0288830e6ac5157f203ee3947bc29b0d6eda66b1" + integrity sha512-0LiTwXEVt7XdzVT02fvg14NMz90zfPUyw1g2mIrWA70+M56br5k6tXKrZg8NjH1MgWVz5TWBx90SI0MhD2OssA== +>>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: hoist-non-react-statics "^3.3.0" react-lifecycles-compat "^3.0.4" From b48b618b538c7694c98cfc680fec1a69ab797339 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 10 Sep 2019 20:36:28 -0400 Subject: [PATCH 254/636] =?UTF-8?q?Fix=20missing=20background=20color=20in?= =?UTF-8?q?=20Send=20flow=E2=80=99s=20HoldToAuthorizeButton?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Avatar.js | 2 +- src/components/Divider.js | 2 +- src/components/buttons/HoldToAuthorizeButton.js | 2 +- src/components/send/SendAssetForm.js | 2 +- src/components/send/SendAssetList.js | 2 +- src/styles/borders.js | 2 +- src/styles/colors.js | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 9c38e561241..32d3c790ce5 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -9,7 +9,7 @@ import { ShadowStack } from './shadow-stack'; const Container = styled(Centered)` ${position.cover} - background-color: ${colors.lightGrey}; + background-color: ${colors.lighterGrey}; border-radius: ${({ size }) => size}; `; diff --git a/src/components/Divider.js b/src/components/Divider.js index ffa5b1b68bb..042cd27fa82 100644 --- a/src/components/Divider.js +++ b/src/components/Divider.js @@ -86,7 +86,7 @@ Divider.propTypes = { }; Divider.defaultProps = { - color: colors.lightGrey, + color: colors.lighterGrey, horizontal: true, inset: [0, 0, 0, 19], size: DefaultDividerSize, diff --git a/src/components/buttons/HoldToAuthorizeButton.js b/src/components/buttons/HoldToAuthorizeButton.js index c5e98a6c052..3f7de7e4831 100644 --- a/src/components/buttons/HoldToAuthorizeButton.js +++ b/src/components/buttons/HoldToAuthorizeButton.js @@ -29,7 +29,7 @@ const ButtonHeight = 59; const ButtonDisabledBgColor = { dark: colors.darkGrey, // blueGreyLighter, - light: colors.lighterGrey, + light: colors.lightGrey, }; const ButtonShadows = { diff --git a/src/components/send/SendAssetForm.js b/src/components/send/SendAssetForm.js index 718b777e665..a0e86d96dab 100644 --- a/src/components/send/SendAssetForm.js +++ b/src/components/send/SendAssetForm.js @@ -28,7 +28,7 @@ const TransactionContainer = styled(Column).attrs({ justify: 'space-between', })` ${({ isNft }) => padding(22, 15, isNft ? nftPaddingBottom : tokenPaddingBottom)}; - background-color: ${colors.lightGrey}; + background-color: ${colors.lighterGrey}; flex: 1; width: 100%; `; diff --git a/src/components/send/SendAssetList.js b/src/components/send/SendAssetList.js index b0c7f08a52d..0971d1f7164 100644 --- a/src/components/send/SendAssetList.js +++ b/src/components/send/SendAssetList.js @@ -27,7 +27,7 @@ const dividerHeight = 18; const Divider = styled.View` height: 2px; - background-color: ${colors.lightGrey}; + background-color: ${colors.lighterGrey}; margin: 10px 19px; width: 100%; `; diff --git a/src/styles/borders.js b/src/styles/borders.js index 11e451fc284..3cf431f30a0 100644 --- a/src/styles/borders.js +++ b/src/styles/borders.js @@ -5,7 +5,7 @@ import position from './position'; const border = {}; -border.color = colors.lightGrey; +border.color = colors.lighterGrey; border.radius = 6; border.width = 1; diff --git a/src/styles/colors.js b/src/styles/colors.js index 84815538a57..75dec0bc042 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -20,11 +20,11 @@ const base = { grey20: '#333333', // '51, 51, 51' grey: '#a9adb9', // '169, 173, 185' headerTitle: '#aaafbd', // '170, 175, 189' - highlightBackground: '#F0F7FF', // '240, 247, 255' lightBlue: '#c5f2ff', // '197, 242, 255' lightBlueGrey: '#F3F5F7', // '243, 245, 247' + lighterGrey: '#f7f7f8', // '247, 247, 248' lightestGrey: '#E9EBEF', // '238, 233, 232' - lightGrey: '#f7f7f8', // '247, 247, 248' + lightGrey: '#CDCFD4', // '205, 207, 212' limeGreen: '#3FCC18', // '58, 166, 134' mediumGrey: '#a1a5b3', // '161, 165, 179' orangeMedium: '#FCA247', // '252, 162, 71' From 85d49c245036a99b04d09d602f96299338ab273d Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 30 Aug 2019 21:44:35 -0400 Subject: [PATCH 255/636] separation of gas from send flow --- src/components/SendComponentWithData.js | 41 ++--- src/handlers/{api.js => gasPrices.js} | 0 src/hoc/withDataInit.js | 15 +- src/parsers/gas.js | 125 +++++++-------- src/redux/gas.js | 203 ++++++++++++++++++++++++ src/redux/reducers.js | 2 + src/redux/send.js | 187 +++------------------- src/screens/ExchangeModal.js | 2 +- src/screens/SendSheet.js | 44 ++--- src/screens/WalletScreen.js | 2 +- src/utils/ethereumUtils.js | 14 +- src/utils/gas.js | 28 ++++ src/utils/index.js | 1 + 13 files changed, 356 insertions(+), 308 deletions(-) rename src/handlers/{api.js => gasPrices.js} (100%) create mode 100644 src/redux/gas.js create mode 100644 src/utils/gas.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index d731c257bcf..2486fd6e8d6 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -5,6 +5,7 @@ import { compose } from 'recompact'; import { get } from 'lodash'; import lang from '../languages'; import { withAccountData, withUniqueTokens } from '../hoc'; +import { gasUpdateGasPrice } from '../redux/gas'; import { sendClearFields, sendMaxBalance, @@ -12,7 +13,6 @@ import { sendToggleConfirmationView, sendTransaction, sendUpdateAssetAmount, - sendUpdateGasPrice, sendUpdateNativeAmount, sendUpdateRecipient, sendUpdateSelected, @@ -21,23 +21,23 @@ import { isValidAddress } from '../helpers/validators'; import { greaterThan } from '../helpers/utilities'; import { ethereumUtils } from '../utils'; -const mapStateToProps = ({ send, settings }) => ({ +const mapStateToProps = ({ gas, send, settings }) => ({ accountType: settings.accountType, address: send.address, assetAmount: send.assetAmount, confirm: send.confirm, fetching: send.fetching, - gasLimit: send.gasLimit, - gasPrice: send.gasPrice, - gasPriceOption: send.gasPriceOption, - gasPrices: send.gasPrices, + gasLimit: gas.gasLimit, + gasPrices: gas.gasPrices, isSufficientBalance: send.isSufficientBalance, - isSufficientGas: send.isSufficientGas, + isSufficientGas: gas.isSufficientGas, nativeAmount: send.nativeAmount, nativeCurrency: settings.nativeCurrency, network: settings.network, recipient: send.recipient, selected: send.selected, + selectedGasPrice: gas.selectedGasPrice, + txFees: gas.txFees, txHash: send.txHash, }); @@ -59,9 +59,8 @@ export const withSendComponentWithData = (SendComponent, options) => { confirm: PropTypes.bool.isRequired, fetching: PropTypes.bool.isRequired, gasLimit: PropTypes.number.isRequired, - gasPrice: PropTypes.object.isRequired, - gasPriceOption: PropTypes.string.isRequired, gasPrices: PropTypes.object.isRequired, + gasUpdateGasPrice: PropTypes.func.isRequired, isSufficientBalance: PropTypes.bool.isRequired, isSufficientGas: PropTypes.bool.isRequired, nativeAmount: PropTypes.string.isRequired, @@ -69,16 +68,17 @@ export const withSendComponentWithData = (SendComponent, options) => { network: PropTypes.string.isRequired, recipient: PropTypes.string.isRequired, selected: PropTypes.object.isRequired, + selectedGasPrice: PropTypes.shape({ txFee: PropTypes.object }), sendClearFields: PropTypes.func.isRequired, sendMaxBalance: PropTypes.func.isRequired, sendModalInit: PropTypes.func.isRequired, sendToggleConfirmationView: PropTypes.func.isRequired, sendTransaction: PropTypes.func.isRequired, sendUpdateAssetAmount: PropTypes.func.isRequired, - sendUpdateGasPrice: PropTypes.func.isRequired, sendUpdateNativeAmount: PropTypes.func.isRequired, sendUpdateRecipient: PropTypes.func.isRequired, sendUpdateSelected: PropTypes.func.isRequired, + txFees: PropTypes.object.isRequired, txHash: PropTypes.string.isRequired, }; @@ -111,7 +111,7 @@ export const withSendComponentWithData = (SendComponent, options) => { if ((selected.symbol !== prevProps.selected.symbol) || (recipient !== prevProps.recipient) || (assetAmount !== prevProps.assetAmount)) { - this.props.sendUpdateGasPrice(); + this.props.gasUpdateGasPrice(); } } } @@ -145,7 +145,7 @@ export const withSendComponentWithData = (SendComponent, options) => { event.preventDefault(); } - if (!this.props.gasPrice.txFee) { + if (!this.props.selectedGasPrice.txFee) { return; } @@ -160,7 +160,7 @@ export const withSendComponentWithData = (SendComponent, options) => { const { requestedAmount, balance, amountWithFees } = ethereumUtils.transactionData( this.props.assets, this.props.assetAmount, - this.props.gasPrice, + this.props.selectedGasPrice, ); if (greaterThan(requestedAmount, balance)) { @@ -173,7 +173,7 @@ export const withSendComponentWithData = (SendComponent, options) => { const { requestedAmount, balance, txFee } = ethereumUtils.transactionData( this.props.assets, this.props.assetAmount, - this.props.gasPrice, + this.props.selectedGasPrice, ); const tokenBalance = get(this.props, 'selected.balance.amount'); @@ -193,24 +193,16 @@ export const withSendComponentWithData = (SendComponent, options) => { amount: this.props.assetAmount, asset: this.props.selected, gasLimit: this.props.gasLimit, - gasPrice: this.props.gasPrice, + gasPrice: this.props.selectedGasPrice, recipient: this.props.recipient, }, this.sendTransactionCallback); } }; - updateGasPrice = gasPrice => { - this.props.sendUpdateGasPrice(gasPrice); - }; - onClose = () => { this.props.sendClearFields(); }; - updateGasPrice = gasPrice => { - this.props.sendUpdateGasPrice(gasPrice); - }; - // QR Code Reader Handlers toggleQRCodeReader = () => this.setState({ showQRCodeReader: !this.state.showQRCodeReader }); @@ -249,7 +241,6 @@ export const withSendComponentWithData = (SendComponent, options) => { onSubmit={this.onSubmit} showQRCodeReader={this.state.showQRCodeReader} toggleQRCodeReader={this.toggleQRCodeReader} - updateGasPrice={this.updateGasPrice} {...this.props} /> ); @@ -258,13 +249,13 @@ export const withSendComponentWithData = (SendComponent, options) => { return compose( connect(mapStateToProps, { + gasUpdateGasPrice, sendClearFields, sendMaxBalance, sendModalInit, sendToggleConfirmationView, sendTransaction, sendUpdateAssetAmount, - sendUpdateGasPrice, sendUpdateNativeAmount, sendUpdateRecipient, sendUpdateSelected, diff --git a/src/handlers/api.js b/src/handlers/gasPrices.js similarity index 100% rename from src/handlers/api.js rename to src/handlers/gasPrices.js diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index d404d5cb2dc..48b9eb7d47d 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -9,15 +9,12 @@ import { dataClearState, dataLoadState, } from '../redux/data'; -<<<<<<< HEAD -import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; -======= import { explorerClearState, explorerInit, } from '../redux/explorer'; -import { clearIsWalletEmpty, loadIsWalletEmpty } from '../redux/isWalletEmpty'; ->>>>>>> 6d69f680... separate out explorer api from asset/txns data +import { gasClearFields, gasPricesInit } from '../redux/gas'; +import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; @@ -56,6 +53,8 @@ export default Component => compose( dataLoadState, explorerClearState, explorerInit, + gasClearFields, + gasPricesInit, nonceClearState, requestsClearState, requestsLoadState, @@ -92,15 +91,17 @@ export default Component => compose( const p6 = ownProps.nonceClearState(); const p7 = ownProps.requestsClearState(); const p8 = ownProps.uniswapClearState(); - return promiseUtils.PromiseAllWithFails([p0, p1, p2, p3, p4, p5, p6, p7, p8]); + const p9 = ownProps.gasClearState(); + return promiseUtils.PromiseAllWithFails([p0, p1, p2, p3, p4, p5, p6, p7, p8, p9]); }, initializeAccountData: (ownProps) => async () => { try { ownProps.explorerInit(); + ownProps.gasPricesInit(); ownProps.uniswapTokenReservesRefreshState(); await ownProps.uniqueTokensRefreshState(); } catch (error) { - // TODO + // TODO error state } }, loadAccountData: (ownProps) => async () => { diff --git a/src/parsers/gas.js b/src/parsers/gas.js index 357366deb9d..9422f449ba3 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -11,64 +11,53 @@ import { /** * @desc parse ether gas prices * @param {Object} data - * @param {Object} prices - * @param {Number} gasLimit + * @param {Boolean} short - use short format or not */ -export const parseGasPrices = (data, priceUnit, gasLimit, nativeCurrency, short) => { +export const getFallbackGasPrices = (short = true) => { const gasPrices = { average: null, fast: null, slow: null, }; - if (!data) { - gasPrices.fast = defaultGasPriceFormat('fast', '30000', '5000000000', '5 Gwei', short); - gasPrices.average = defaultGasPriceFormat('average', '360000', '2000000000', '2 Gwei', short); - gasPrices.slow = defaultGasPriceFormat('slow', '1800000', '1000000000', '1 Gwei', short); - } else { - const fastTimeAmount = multiply(data.fastWait, timeUnits.ms.minute); - const fastValueAmount = divide(data.fast, 10); - gasPrices.fast = defaultGasPriceFormat( - 'fast', - fastTimeAmount, - multiply(fastValueAmount, ethUnits.gwei), - `${fastValueAmount} Gwei`, - short, - ); - - const avgTimeAmount = multiply(data.avgWait, timeUnits.ms.minute); - const avgValueAmount = divide(data.average, 10); - gasPrices.average = defaultGasPriceFormat( - 'average', - avgTimeAmount, - multiply(avgValueAmount, ethUnits.gwei), - `${avgValueAmount} Gwei`, - short, - ); + gasPrices.fast = defaultGasPriceFormat('fast', '30000', '5000000000', '5 Gwei', short); + gasPrices.average = defaultGasPriceFormat('average', '360000', '2000000000', '2 Gwei', short); + gasPrices.slow = defaultGasPriceFormat('slow', '1800000', '1000000000', '1 Gwei', short); + return gasPrices; +}; - const slowTimeAmount = multiply(data.safeLowWait, timeUnits.ms.minute); - const slowValueAmount = divide(data.safeLow, 10); - gasPrices.slow = defaultGasPriceFormat( - 'slow', - slowTimeAmount, - multiply(slowValueAmount, ethUnits.gwei), - `${slowValueAmount} Gwei`, - short, - ); - } - return parseGasPricesTxFee(gasPrices, priceUnit, gasLimit, nativeCurrency); +/** + * @desc parse ether gas prices + * @param {Object} data + * @param {Boolean} short - use short format or not + */ +export const parseGasPrices = (data, short = true) => { + if (!data) return getFallbackGasPrices(); + const gasPrices = { + average: null, + fast: null, + slow: null, + }; + gasPrices.fast = defaultGasPriceFormat('fast', data.fastWait, data.fast, short); + gasPrices.average = defaultGasPriceFormat('average', data.avgWait, data.average, short); + gasPrices.slow = defaultGasPriceFormat('slow', data.safeLowWait, data.safeLow, short); + return gasPrices; }; -const defaultGasPriceFormat = (option, timeAmount, valueAmount, valueDisplay, short) => ({ - estimatedTime: { - amount: timeAmount, - display: getTimeString(timeAmount, 'ms', short), - }, - option, - value: { - amount: valueAmount, - display: valueDisplay, - }, -}); +const defaultGasPriceFormat = (option, timeWait, value, short) => { + const timeAmount = multiply(timeWait, timeUnits.ms.minute); + const valueAmount = multiply(divide(value, 10), ethUnits.gwei); + return { + estimatedTime: { + amount: timeAmount, + display: getTimeString(timeAmount, 'ms', short), + }, + option, + value: { + amount: valueAmount, + display: `${valueAmount} Gwei`, + }, + }; +}; /** * @desc parse ether gas prices with updated gas limit @@ -76,11 +65,16 @@ const defaultGasPriceFormat = (option, timeAmount, valueAmount, valueDisplay, sh * @param {Object} prices * @param {Number} gasLimit */ -export const parseGasPricesTxFee = (gasPrices, priceUnit, gasLimit, nativeCurrency) => { - gasPrices.fast.txFee = getTxFee(gasPrices.fast.value.amount, gasLimit); - gasPrices.average.txFee = getTxFee(gasPrices.average.value.amount, gasLimit); - gasPrices.slow.txFee = getTxFee(gasPrices.slow.value.amount, gasLimit); - return convertGasPricesToNative(priceUnit, gasPrices, nativeCurrency); +export const parseTxFees = (gasPrices, priceUnit, gasLimit, nativeCurrency) => { + const txFees = { + average: { txFee: null }, + fast: { txFee: null }, + slow: { txFee: null }, + }; + txFees.fast.txFee = getTxFee(gasPrices.fast.value.amount, gasLimit); + txFees.average.txFee = getTxFee(gasPrices.average.value.amount, gasLimit); + txFees.slow.txFee = getTxFee(gasPrices.slow.value.amount, gasLimit); + return convertTxFeesToNative(priceUnit, txFees, nativeCurrency); }; const getTxFee = (gasPrice, gasLimit) => { @@ -100,22 +94,19 @@ const getTxFee = (gasPrice, gasLimit) => { }; }; -const convertGasPricesToNative = (priceUnit, gasPrices, nativeCurrency) => { - const nativeGases = { ...gasPrices }; - nativeGases.fast.txFee.native = getNativeGasPrice(priceUnit, gasPrices.fast.txFee.value.amount, nativeCurrency); - nativeGases.average.txFee.native = getNativeGasPrice(priceUnit, gasPrices.average.txFee.value.amount, nativeCurrency); - nativeGases.slow.txFee.native = getNativeGasPrice(priceUnit, gasPrices.slow.txFee.value.amount, nativeCurrency); - return nativeGases; +const convertTxFeesToNative = (priceUnit, txFees, nativeCurrency) => { + const nativeTxFees = { ...txFees }; + nativeTxFees.fast.txFee.native = getNativeTxFee(priceUnit, txFees.fast.txFee.value.amount, nativeCurrency); + nativeTxFees.average.txFee.native = getNativeTxFee(priceUnit, txFees.average.txFee.value.amount, nativeCurrency); + nativeTxFees.slow.txFee.native = getNativeTxFee(priceUnit, txFees.slow.txFee.value.amount, nativeCurrency); + return nativeTxFees; }; -const getNativeGasPrice = (priceUnit, feeAmount, nativeCurrency) => { - const nativeDisplay = convertRawAmountToNativeDisplay( +const getNativeTxFee = (priceUnit, feeAmount, nativeCurrency) => ({ + value: convertRawAmountToNativeDisplay( feeAmount, 18, priceUnit, nativeCurrency, - ); - return { - value: nativeDisplay, - }; -}; + ), +}); diff --git a/src/redux/gas.js b/src/redux/gas.js new file mode 100644 index 00000000000..d5dfd65c698 --- /dev/null +++ b/src/redux/gas.js @@ -0,0 +1,203 @@ +import { get, isEmpty } from 'lodash'; +import { apiGetGasPrices } from '../handlers/gasPrices'; +import { estimateGasLimit } from '../handlers/web3'; +import { fromWei } from '../helpers/utilities'; +import { + getFallbackGasPrices, + parseGasPrices, + parseTxFees, +} from '../parsers/gas'; +import ethUnits from '../references/ethereum-units.json'; +import { ethereumUtils } from '../utils'; + +// -- Constants ------------------------------------------------------------- // + +const GAS_PRICES_REQUEST = 'gas/GAS_PRICES_REQUEST'; +const GAS_PRICES_SUCCESS = 'gas/GAS_PRICES_SUCCESS'; +const GAS_PRICES_FAILURE = 'gas/GAS_PRICES_FAILURE'; + +const GAS_UPDATE_TX_FEE_SUCCESS = 'send/GAS_UPDATE_TX_FEE_SUCCESS'; +const GAS_UPDATE_TX_FEE_FAILURE = 'send/GAS_UPDATE_TX_FEE_FAILURE'; + +const GAS_CLEAR_FIELDS = 'send/GAS_CLEAR_FIELDS'; +const GAS_CLEAR_TXN_SPECIFIC_FIELDS = 'send/GAS_CLEAR_TXN_SPECIFIC_FIELDS'; + +// -- Actions --------------------------------------------------------------- // +let getGasPricesInterval = null; + +const getEthPriceUnit = (assets) => { + const ethAsset = ethereumUtils.getAsset(assets); + return get(ethAsset, 'price.value', 0); +}; + +export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, reject) => { + const { assets } = getState().data; + const { gasLimit } = getState().gas; + const { nativeCurrency } = getState().settings; + const fallbackGasPrices = getFallbackGasPrices(); + const ethPriceUnit = getEthPriceUnit(assets); + const txFees = parseTxFees(fallbackGasPrices, ethPriceUnit, gasLimit, nativeCurrency); + const selectedGasPrice = { + ...txFees.average, + ...fallbackGasPrices.average, + }; + dispatch({ + payload: { + gasPrices: fallbackGasPrices, + selectedGasPrice, + }, + type: GAS_PRICES_REQUEST, + }); + + const getGasPrices = () => new Promise((fetchResolve, fetchReject) => { + const { useShortGasFormat } = getState().gas; + apiGetGasPrices() + .then(({ data }) => { + const gasPrices = parseGasPrices( + data, + useShortGasFormat, + ); + dispatch({ + payload: gasPrices, + type: GAS_PRICES_SUCCESS, + }); + fetchResolve(true); + }) + .catch(error => { + console.error(error); + dispatch({ + payload: fallbackGasPrices, + type: GAS_PRICES_FAILURE, + }); + fetchReject(error); + }); + }); + return getGasPrices().then(() => { + clearInterval(getGasPricesInterval); + getGasPricesInterval = setInterval(getGasPrices, 15000); // 15 secs + resolve(true); + }).catch(error => { + clearInterval(getGasPricesInterval); + getGasPricesInterval = setInterval(getGasPrices, 15000); // 15 secs + reject(error); + }); +}); + +export const gasUpdateGasPrice = newGasPriceOption => (dispatch, getState) => { + const { + address, + recipient, + assetAmount, + selected, + } = getState().send; + const { gasPrices, selectedGasPriceOption } = getState().gas; + const { assets } = getState().data; + const { nativeCurrency } = getState().settings; + const _gasPriceOption = newGasPriceOption || selectedGasPriceOption; + const ethAsset = ethereumUtils.getAsset(assets); + if (isEmpty(selected)) return; + if (isEmpty(gasPrices)) return; + estimateGasLimit({ + address, + amount: assetAmount, + asset: selected, + recipient, + }) + .then(gasLimit => { + const ethPriceUnit = getEthPriceUnit(assets); + const txFees = parseTxFees(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); + const txFee = txFees[_gasPriceOption]; + const balanceAmount = get(ethAsset, 'balance.amount', 0); + const txFeeAmount = fromWei(get(txFee, 'value.amount', 0)); + const selectedGasPrice = { + ...txFee, + ...gasPrices[_gasPriceOption], + }; + dispatch({ + payload: { + gasLimit, + isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), + selectedGasPrice, + selectedGasPriceOption: _gasPriceOption, + txFees, + }, + type: GAS_UPDATE_TX_FEE_SUCCESS, + }); + }) + .catch(error => { + dispatch({ + payload: _gasPriceOption, + type: GAS_UPDATE_TX_FEE_FAILURE, + }); + }); +}; + +export const resetGasTxFees = () => (dispatch) => { + dispatch({ type: GAS_CLEAR_TXN_SPECIFIC_FIELDS }); +}; + +export const gasClearFields = () => (dispatch) => { + clearInterval(getGasPricesInterval); + dispatch({ type: GAS_CLEAR_FIELDS }); +}; + +// -- Reducer --------------------------------------------------------------- // +const INITIAL_STATE = { + fetchingGasPrices: false, + gasLimit: ethUnits.basic_tx, + gasPrices: {}, + isSufficientGas: false, + selectedGasPrice: {}, + selectedGasPriceOption: 'average', + txFees: {}, + useShortGasFormat: true, +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case GAS_PRICES_REQUEST: + return { + ...state, + fetchingGasPrices: true, + gasPrices: action.payload.gasPrices, + selectedGasPrice: action.payload.selectedGasPrice, + }; + case GAS_PRICES_SUCCESS: + return { + ...state, + fetchingGasPrices: false, + gasPrices: action.payload, + }; + case GAS_PRICES_FAILURE: + return { + ...state, + fetchingGasPrices: false, + gasPrices: action.payload, + }; + case GAS_UPDATE_TX_FEE_SUCCESS: + return { + ...state, + gasLimit: action.payload.gasLimit, + isSufficientGas: action.payload.isSufficientGas, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: action.payload.selectedGasPriceOption, + txFees: action.payload.txFees, + }; + case GAS_UPDATE_TX_FEE_FAILURE: + return { + ...state, + selectedGasPriceOption: action.payload, + }; + case GAS_CLEAR_FIELDS: + return { ...state, ...INITIAL_STATE }; + case GAS_CLEAR_TXN_SPECIFIC_FIELDS: { + return { + ...INITIAL_STATE, + fetchingGasPrices: state.fetchingGasPrices, + gasPrices: state.gasPrices, + }; + } + default: + return state; + } +}; diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 218afe74a81..033b463931c 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -3,6 +3,7 @@ import { combineReducers } from 'redux'; import actionSheetManager from './actionSheetManager'; import data from './data'; import explorer from './explorer'; +import gas from './gas'; import imageDimensionsCache from './imageDimensionsCache'; import isWalletEmpty from './isWalletEmpty'; import isWalletEthZero from './isWalletEthZero'; @@ -26,6 +27,7 @@ export default combineReducers({ actionSheetManager, data, explorer, + gas, imageDimensionsCache, isWalletEmpty, isWalletEthZero, diff --git a/src/redux/send.js b/src/redux/send.js index 0b42a00f471..2ea5c5533ac 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -1,32 +1,17 @@ import { get, isEmpty } from 'lodash'; -import { apiGetGasPrices } from '../handlers/api'; -import ethUnits from '../references/ethereum-units.json'; -import { dataAddNewTransaction } from './data'; -import { ethereumUtils } from '../utils'; import { convertAmountAndPriceToNativeDisplay, convertAmountFromNativeValue, formatInputDecimals, - fromWei, } from '../helpers/utilities'; -import { - parseGasPrices, - parseGasPricesTxFee, -} from '../parsers/gas'; -import { - createSignableTransaction, - estimateGasLimit, -} from '../handlers/web3'; +import { createSignableTransaction } from '../handlers/web3'; +import { gasUpdateGasPrice, resetGasTxFees } from './gas'; +import { ethereumUtils } from '../utils'; +import { dataAddNewTransaction } from './data'; // -- Constants ------------------------------------------------------------- // -const SEND_GET_GAS_PRICES_REQUEST = 'send/SEND_GET_GAS_PRICES_REQUEST'; -const SEND_GET_GAS_PRICES_SUCCESS = 'send/SEND_GET_GAS_PRICES_SUCCESS'; -const SEND_GET_GAS_PRICES_FAILURE = 'send/SEND_GET_GAS_PRICES_FAILURE'; - -const SEND_UPDATE_GAS_PRICE_REQUEST = 'send/SEND_UPDATE_GAS_PRICE_REQUEST'; -const SEND_UPDATE_GAS_PRICE_SUCCESS = 'send/SEND_UPDATE_GAS_PRICE_SUCCESS'; -const SEND_UPDATE_GAS_PRICE_FAILURE = 'send/SEND_UPDATE_GAS_PRICE_FAILURE'; +const SEND_MODAL_INIT = 'send/SEND_MODAL_INIT'; const SEND_TRANSACTION_REQUEST = 'send/SEND_TRANSACTION_REQUEST'; const SEND_TRANSACTION_SUCCESS = 'send/SEND_TRANSACTION_SUCCESS'; @@ -44,103 +29,19 @@ const SEND_UPDATE_NFT_SELECTED = 'send/SEND_UPDATE_NFT_SELECTED'; const SEND_CLEAR_FIELDS = 'send/SEND_CLEAR_FIELDS'; // -- Actions --------------------------------------------------------------- // -const getEthPriceUnit = (assets) => { - const ethAsset = ethereumUtils.getAsset(assets); - return get(ethAsset, 'price.value', 0); -}; export const sendModalInit = (options = {}) => (dispatch, getState) => { - const { accountAddress, nativeCurrency } = getState().settings; + const { accountAddress } = getState().settings; const { assets } = getState().data; - const { gasLimit } = getState().send; - const ethPriceUnit = getEthPriceUnit(assets); - - const fallbackGasPrices = parseGasPrices(null, ethPriceUnit, gasLimit, nativeCurrency, options.gasFormat === 'short'); const selected = assets.filter(asset => asset.address === options.defaultAsset)[0] || {}; dispatch({ payload: { address: accountAddress, - gasPrices: fallbackGasPrices, selected, }, - type: SEND_GET_GAS_PRICES_REQUEST, + type: SEND_MODAL_INIT, }); - - apiGetGasPrices() - .then(({ data }) => { - const gasPrices = parseGasPrices(data, ethPriceUnit, gasLimit, nativeCurrency, options.gasFormat === 'short'); - dispatch({ - payload: gasPrices, - type: SEND_GET_GAS_PRICES_SUCCESS, - }); - }) - .catch(error => { - console.error(error); - - dispatch({ - payload: fallbackGasPrices, - type: SEND_GET_GAS_PRICES_FAILURE, - }); - }); -}; - -export const sendUpdateGasPrice = newGasPriceOption => (dispatch, getState) => { - const { - selected, - address, - recipient, - assetAmount, - gasPrice, - gasPrices: existingGasPrices, - gasPriceOption, - fetchingGasPrices, - } = getState().send; - if (isEmpty(selected)) return; - if (fetchingGasPrices) return; - let gasPrices = existingGasPrices; - if (!Object.keys(gasPrices).length) return; - const _gasPriceOption = newGasPriceOption || gasPriceOption; - let _gasPrice = _gasPriceOption ? gasPrices[_gasPriceOption] : gasPrice; - dispatch({ type: SEND_UPDATE_GAS_PRICE_REQUEST }); - estimateGasLimit({ - address, - amount: assetAmount, - asset: selected, - recipient, - }) - .then(gasLimit => { - const { assets } = getState().data; - const { nativeCurrency } = getState().settings; - const ethPriceUnit = getEthPriceUnit(assets); - gasPrices = parseGasPricesTxFee(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); - _gasPrice = gasPriceOption ? gasPrices[_gasPriceOption] : gasPrice; - - const ethereum = ethereumUtils.getAsset(assets); - const balanceAmount = get(ethereum, 'balance.amount', 0); - const txFeeAmount = fromWei(get(_gasPrice, 'txFee.value.amount', 0)); - - dispatch({ - payload: { - gasLimit, - gasPrice: _gasPrice, - gasPriceOption: _gasPriceOption, - gasPrices, - isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), - }, - type: SEND_UPDATE_GAS_PRICE_SUCCESS, - }); - }) - .catch(error => { - dispatch({ - payload: { - gasPrice: _gasPrice, - gasPriceOption: _gasPriceOption, - gasPrices, - }, - type: SEND_UPDATE_GAS_PRICE_FAILURE, - }); - }); }; export const sendTransaction = (transactionDetails, signAndSendTransactionCb) => (dispatch, getState) => new Promise((resolve, reject) => { @@ -178,8 +79,10 @@ export const sendTransaction = (transactionDetails, signAndSendTransactionCb) => payload: txHash, type: SEND_TRANSACTION_SUCCESS, }); + dispatch(resetGasTxFees()); resolve(txHash); }).catch(error => { + dispatch(resetGasTxFees()); reject(error); }); } else { @@ -218,7 +121,8 @@ export const sendUpdateRecipient = recipient => dispatch => { export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { const { nativeCurrency } = getState().settings; - const { gasPrice, selected } = getState().send; + const { selected } = getState().send; + const { selectedGasPrice } = getState().gas; const _assetAmount = assetAmount.replace(/[^0-9.]/g, ''); let _nativeAmount = ''; if (_assetAmount.length) { @@ -230,7 +134,7 @@ export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { ); _nativeAmount = formatInputDecimals(nativeAmount, _assetAmount); } - const balanceAmount = ethereumUtils.getBalanceAmount(gasPrice, selected); + const balanceAmount = ethereumUtils.getBalanceAmount(selectedGasPrice, selected); dispatch({ payload: { assetAmount: _assetAmount, @@ -242,7 +146,8 @@ export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { }; export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { - const { gasPrice, selected } = getState().send; + const { selected } = getState().send; + const { selectedGasPrice } = getState().gas; const _nativeAmount = nativeAmount.replace(/[^0-9.]/g, ''); let _assetAmount = ''; if (_nativeAmount.length) { @@ -254,7 +159,7 @@ export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); } - const balanceAmount = ethereumUtils.getBalanceAmount(gasPrice, selected); + const balanceAmount = ethereumUtils.getBalanceAmount(selectedGasPrice, selected); dispatch({ payload: { @@ -277,7 +182,7 @@ export const sendUpdateSelected = (asset) => (dispatch, getState) => { }, type: SEND_UPDATE_NFT_SELECTED, }); - dispatch(sendUpdateGasPrice()); + dispatch(gasUpdateGasPrice()); } else { const state = getState(); const assetAmount = get(state, 'send.assetAmount'); @@ -286,16 +191,16 @@ export const sendUpdateSelected = (asset) => (dispatch, getState) => { type: SEND_UPDATE_SELECTED, }); dispatch(sendUpdateAssetAmount(assetAmount)); - dispatch(sendUpdateGasPrice()); + dispatch(gasUpdateGasPrice()); } }; export const sendMaxBalance = () => (dispatch, getState) => { - const { gasPrice, selected } = getState().send; - const balanceAmount = ethereumUtils.getBalanceAmount(gasPrice, selected); - + const { selected } = getState().send; + const { selectedGasPrice } = getState().gas; + const balanceAmount = ethereumUtils.getBalanceAmount(selectedGasPrice, selected); dispatch(sendUpdateAssetAmount(balanceAmount)); - dispatch(sendUpdateGasPrice()); + dispatch(gasUpdateGasPrice()); }; export const sendClearFields = () => ({ type: SEND_CLEAR_FIELDS }); @@ -306,13 +211,7 @@ const INITIAL_STATE = { assetAmount: '', confirm: false, fetching: false, - fetchingGasPrices: false, - gasLimit: ethUnits.basic_tx, - gasPrice: {}, - gasPriceOption: 'average', - gasPrices: {}, isSufficientBalance: false, - isSufficientGas: false, nativeAmount: '', recipient: '', selected: {}, @@ -321,60 +220,18 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => { switch (action.type) { - case SEND_GET_GAS_PRICES_REQUEST: + case SEND_MODAL_INIT: return { ...state, address: action.payload.address, - fetchingGasPrices: true, - gasPrice: action.payload.gasPrices.average, - gasPriceOption: action.payload.gasPrices.average.option, - gasPrices: action.payload.gasPrices, selected: action.payload.selected, }; - case SEND_GET_GAS_PRICES_SUCCESS: - return { - ...state, - fetchingGasPrices: false, - gasPrice: action.payload.average, - gasPriceOption: action.payload.average.option, - gasPrices: action.payload, - }; - case SEND_GET_GAS_PRICES_FAILURE: - return { - ...state, - fetchingGasPrices: false, - gasPrice: action.payload.average, - gasPriceOption: action.payload.average.option, - gasPrices: action.payload, - }; - case SEND_UPDATE_GAS_PRICE_REQUEST: - return { ...state, fetchingGasPrices: true }; - case SEND_UPDATE_GAS_PRICE_SUCCESS: - return { - ...state, - fetchingGasPrices: false, - gasLimit: action.payload.gasLimit, - gasPrice: action.payload.gasPrice, - gasPriceOption: action.payload.gasPriceOption, - gasPrices: action.payload.gasPrices, - isSufficientGas: action.payload.isSufficientGas, - }; - - case SEND_UPDATE_GAS_PRICE_FAILURE: - return { - ...state, - fetchingGasPrices: false, - gasPrice: action.payload.gasPrice, - gasPriceOption: action.payload.gasPriceOption, - gasPrices: action.payload.gasPrices, - }; case SEND_TRANSACTION_REQUEST: return { ...state, fetching: true }; case SEND_TRANSACTION_SUCCESS: return { ...state, fetching: false, - gasPrices: {}, txHash: action.payload, }; case SEND_TRANSACTION_FAILURE: diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 34a9a5a2097..73c06644a86 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -337,7 +337,7 @@ class ExchangeModal extends PureComponent { } } catch (error) { console.log('error getting market details', error); - // TODO + // TODO error state } } diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 44e9175d9b5..eae7c9c6e3b 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -1,14 +1,10 @@ import analytics from '@segment/analytics-react-native'; import { get, - indexOf, isEmpty, isFunction, isString, - map, property, - sortBy, - upperFirst, } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -32,7 +28,7 @@ import { withUniqueTokens, } from '../hoc'; import { colors } from '../styles'; -import { deviceUtils, isNewValueForPath } from '../utils'; +import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; import { showActionSheetWithOptions } from '../utils/actionsheet'; const Container = styled(Column)` @@ -40,32 +36,13 @@ const Container = styled(Column)` height: 100%; `; -const formatGastSpeedItem = (value, key) => { - const cost = get(value, 'txFee.native.value.display'); - const gwei = get(value, 'value.display'); - const time = get(value, 'estimatedTime.display'); - - return { - gweiValue: gwei, - label: `${upperFirst(key)}: ${cost} ~${time.slice(0, -1)}`, - value: key, - }; -}; - -const labelOrder = ['slow', 'average', 'fast']; - -const formatGasSpeedItems = (gasPrices) => { - const gasItems = map(gasPrices, formatGastSpeedItem); - return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); -}; - class SendSheet extends Component { static propTypes = { allAssets: PropTypes.array, assetAmount: PropTypes.string, fetchData: PropTypes.func, - gasPrice: PropTypes.object, gasPrices: PropTypes.object, + gasUpdateGasPrice: PropTypes.func, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, @@ -74,14 +51,15 @@ class SendSheet extends Component { onSubmit: PropTypes.func, recipient: PropTypes.string, selected: PropTypes.object, + selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), sendClearFields: PropTypes.func, sendMaxBalance: PropTypes.func, sendUpdateAssetAmount: PropTypes.func, - sendUpdateGasPrice: PropTypes.func, sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, sendUpdateSelected: PropTypes.func, + txFees: PropTypes.object, } static defaultProps = { @@ -166,11 +144,15 @@ class SendSheet extends Component { } onPressTransactionSpeed = (onSuccess) => { - const { gasPrices, sendUpdateGasPrice } = this.props; + const { + gasPrices, + gasUpdateGasPrice, + txFees, + } = this.props; const options = [ { label: 'Cancel' }, - ...formatGasSpeedItems(gasPrices), + ...gasUtils.formatGasSpeedItems(gasPrices, txFees), ]; showActionSheetWithOptions({ @@ -180,7 +162,7 @@ class SendSheet extends Component { if (buttonIndex > 0) { const selectedGasPriceItem = options[buttonIndex]; - sendUpdateGasPrice(selectedGasPriceItem.value); + gasUpdateGasPrice(selectedGasPriceItem.value); analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); } @@ -227,11 +209,11 @@ class SendSheet extends Component { const { allAssets, fetchData, - gasPrice, isValidAddress, nativeCurrencySymbol, recipient, selected, + selectedGasPrice, sendableUniqueTokens, sendUpdateRecipient, ...props @@ -276,7 +258,7 @@ class SendSheet extends Component { txSpeedRenderer={( isIphoneX() && ( diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 52a9419a889..f469e380942 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -72,7 +72,7 @@ class WalletScreen extends Component { await this.setInitialStatesForOpenAssets(); await this.props.initializeWallet(); } catch (error) { - // TODO + // TODO error state } } diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index 284a4e12797..fcb14b8f780 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -8,11 +8,11 @@ import { subtract, } from '../helpers/utilities'; -export const getBalanceAmount = (gasPrice, selected) => { +export const getBalanceAmount = (selectedGasPrice, selected) => { let amount = ''; if (selected.address === 'eth') { const balanceAmount = get(selected, 'balance.amount', 0); - const txFeeRaw = get(gasPrice, 'txFee.value.amount'); + const txFeeRaw = get(selectedGasPrice, 'txFee.value.amount'); const txFeeAmount = fromWei(txFeeRaw); const remaining = subtract(balanceAmount, txFeeAmount); amount = convertNumberToString(greaterThan(remaining, 0) ? remaining : 0); @@ -22,15 +22,7 @@ export const getBalanceAmount = (gasPrice, selected) => { return amount; }; -export const getAsset = (assets, address = 'eth') => { - return find(assets, asset => { - // console.log('asset', asset); - // console.log('asset.address', asset.address); - // console.log('address', address) - - return asset.address === address; - }); -}; +export const getAsset = (assets, address = 'eth') => find(assets, asset => asset.address === address); /** * @desc remove hex prefix diff --git a/src/utils/gas.js b/src/utils/gas.js new file mode 100644 index 00000000000..699be9590ee --- /dev/null +++ b/src/utils/gas.js @@ -0,0 +1,28 @@ +import { + get, + indexOf, + map, + sortBy, + upperFirst, +} from 'lodash'; + +const labelOrder = ['slow', 'average', 'fast']; + +const formatGasSpeedItems = (gasPrices, txFees) => { + const gasItems = map(labelOrder, speed => { + const cost = get(txFees, `[${speed}].txFee.native.value.display`); + const gwei = get(gasPrices, `[${speed}].value.display`); + const time = get(gasPrices, `[${speed}].estimatedTime.display`); + + return { + gweiValue: gwei, + label: `${upperFirst(speed)}: ${cost} ~${time.slice(0, -1)}`, + value: speed, + }; + }); + return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); +}; + +export default { + formatGasSpeedItems, +}; diff --git a/src/utils/index.js b/src/utils/index.js index 0e83014f660..d1d4669fab3 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -5,6 +5,7 @@ export { default as deviceUtils } from './deviceUtils'; export { default as dimensionsPropType } from './dimensionsPropType'; export { default as directionPropType } from './directionPropType'; export { default as ethereumUtils } from './ethereumUtils'; +export { default as gasUtils } from './gas'; export { initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForPath } from './isNewValueForPath'; From fa47fd34cb36974ddd88d169bff9c969d19b07f2 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 31 Aug 2019 00:51:12 -0400 Subject: [PATCH 256/636] setup for hooking in gas prices into exchange --- src/components/SendComponentWithData.js | 28 +++++--- .../exchange/ExchangeGasFeeButton.js | 70 +++++++++++-------- src/components/send/SendTransactionSpeed.js | 6 +- src/hoc/index.js | 1 + src/hoc/withGas.js | 19 +++++ src/redux/gas.js | 43 +++++------- src/redux/send.js | 5 +- src/screens/ExchangeModal.js | 23 +++++- src/screens/SendSheet.js | 6 +- 9 files changed, 126 insertions(+), 75 deletions(-) create mode 100644 src/hoc/withGas.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index 2486fd6e8d6..1ee467d4a1d 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -4,8 +4,11 @@ import { connect } from 'react-redux'; import { compose } from 'recompact'; import { get } from 'lodash'; import lang from '../languages'; -import { withAccountData, withUniqueTokens } from '../hoc'; -import { gasUpdateGasPrice } from '../redux/gas'; +import { + withAccountData, + withGas, + withUniqueTokens, +} from '../hoc'; import { sendClearFields, sendMaxBalance, @@ -21,23 +24,18 @@ import { isValidAddress } from '../helpers/validators'; import { greaterThan } from '../helpers/utilities'; import { ethereumUtils } from '../utils'; -const mapStateToProps = ({ gas, send, settings }) => ({ +const mapStateToProps = ({ send, settings }) => ({ accountType: settings.accountType, address: send.address, assetAmount: send.assetAmount, confirm: send.confirm, fetching: send.fetching, - gasLimit: gas.gasLimit, - gasPrices: gas.gasPrices, isSufficientBalance: send.isSufficientBalance, - isSufficientGas: gas.isSufficientGas, nativeAmount: send.nativeAmount, nativeCurrency: settings.nativeCurrency, network: settings.network, recipient: send.recipient, selected: send.selected, - selectedGasPrice: gas.selectedGasPrice, - txFees: gas.txFees, txHash: send.txHash, }); @@ -69,6 +67,7 @@ export const withSendComponentWithData = (SendComponent, options) => { recipient: PropTypes.string.isRequired, selected: PropTypes.object.isRequired, selectedGasPrice: PropTypes.shape({ txFee: PropTypes.object }), + selectedGasPriceOption: PropTypes.string.isRequired, sendClearFields: PropTypes.func.isRequired, sendMaxBalance: PropTypes.func.isRequired, sendModalInit: PropTypes.func.isRequired, @@ -100,7 +99,13 @@ export const withSendComponentWithData = (SendComponent, options) => { } async componentDidUpdate(prevProps) { - const { assetAmount, recipient, selected } = this.props; + const { + address, + assetAmount, + recipient, + selected, + selectedGasPriceOption, + } = this.props; if (recipient !== prevProps.recipient) { const validAddress = await isValidAddress(recipient); @@ -109,9 +114,10 @@ export const withSendComponentWithData = (SendComponent, options) => { if (this.state.isValidAddress) { if ((selected.symbol !== prevProps.selected.symbol) + || (selectedGasPriceOption !== prevProps.selectedGasPriceOption) || (recipient !== prevProps.recipient) || (assetAmount !== prevProps.assetAmount)) { - this.props.gasUpdateGasPrice(); + this.props.gasUpdateGasPrice(address, assetAmount, selected, recipient); } } } @@ -249,7 +255,6 @@ export const withSendComponentWithData = (SendComponent, options) => { return compose( connect(mapStateToProps, { - gasUpdateGasPrice, sendClearFields, sendMaxBalance, sendModalInit, @@ -260,6 +265,7 @@ export const withSendComponentWithData = (SendComponent, options) => { sendUpdateRecipient, sendUpdateSelected, }), + withGas, withAccountData, withUniqueTokens, )(SendComponentWithData); diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js index 7c3e6dbe377..ebe39b461ff 100644 --- a/src/components/exchange/ExchangeGasFeeButton.js +++ b/src/components/exchange/ExchangeGasFeeButton.js @@ -1,8 +1,13 @@ +import { get } from 'lodash'; import React from 'react'; import PropTypes from 'prop-types'; -import { compose, pure, withHandlers, withProps } from 'recompact'; -import styled from 'styled-components/primitives'; -import { colors, padding, shadow } from '../../styles'; +import { + compose, + pure, + withHandlers, + withProps, +} from 'recompact'; +import { colors, padding } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { Nbsp } from '../html-entities'; import { Column, Row } from '../layout'; @@ -32,36 +37,45 @@ const enhance = compose( }), ); -const ExchangeGasFeeButton = enhance(({ gasPrice, onPress }) => ( - - - - {gasPrice} - - - - - Normal - +const ExchangeGasFeeButton = enhance(({ + gasPrice, + nativeCurrencySymbol, + onPress, +}) => { + const fee = get(gasPrice, 'txFee.native.value.display', `${nativeCurrencySymbol}0.00`); + const time = get(gasPrice, 'estimatedTime.display', ''); + return ( + + + + {fee} + + + + + Normal + + - - - - - - + + + + + + - - - -)); + + + ); +}); ExchangeGasFeeButton.propTypes = { gasPrice: PropTypes.string, + nativeCurrencySymbol: PropTypes.string, onPress: PropTypes.func, }; diff --git a/src/components/send/SendTransactionSpeed.js b/src/components/send/SendTransactionSpeed.js index a69d82c6cf6..9f91d1ea3a8 100644 --- a/src/components/send/SendTransactionSpeed.js +++ b/src/components/send/SendTransactionSpeed.js @@ -7,7 +7,11 @@ import { Icon } from '../icons'; import { Row } from '../layout'; import { Text } from '../text'; -const SendTransactionSpeed = ({ gasPrice, nativeCurrencySymbol, onPressTransactionSpeed }) => { +const SendTransactionSpeed = ({ + gasPrice, + nativeCurrencySymbol, + onPressTransactionSpeed, +}) => { const fee = get(gasPrice, 'txFee.native.value.display', `${nativeCurrencySymbol}0.00`); const time = get(gasPrice, 'estimatedTime.display', ''); diff --git a/src/hoc/index.js b/src/hoc/index.js index 3693e605ee4..6c7ab7025ce 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -9,6 +9,7 @@ export { default as withBlurTransitionProps } from './withBlurTransitionProps'; export { default as withDataInit } from './withDataInit'; export { default as withFabSelection } from './withFabSelection'; export { default as withFabSendAction } from './withFabSendAction'; +export { default as withGas } from './withGas'; export { default as withHideSplashScreen } from './withHideSplashScreen'; export { default as withImageDimensionsCache } from './withImageDimensionsCache'; export { default as withIsWalletEmpty } from './withIsWalletEmpty'; diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js new file mode 100644 index 00000000000..171b1c475dc --- /dev/null +++ b/src/hoc/withGas.js @@ -0,0 +1,19 @@ +import { connect } from 'react-redux'; +import { compose } from 'recompact'; +import { gasUpdateGasPrice, gasUpdateGasPriceOption } from '../redux/gas'; + +const mapStateToProps = ({ gas }) => ({ + gasLimit: gas.gasLimit, + gasPrices: gas.gasPrices, + isSufficientGas: gas.isSufficientGas, + selectedGasPrice: gas.selectedGasPrice, + selectedGasPriceOption: gas.selectedGasPriceOption, + txFees: gas.txFees, +}); + +export default Component => compose( + connect(mapStateToProps, { + gasUpdateGasPrice, + gasUpdateGasPriceOption, + }), +)(Component); diff --git a/src/redux/gas.js b/src/redux/gas.js index d5dfd65c698..71000d19792 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -16,11 +16,10 @@ const GAS_PRICES_REQUEST = 'gas/GAS_PRICES_REQUEST'; const GAS_PRICES_SUCCESS = 'gas/GAS_PRICES_SUCCESS'; const GAS_PRICES_FAILURE = 'gas/GAS_PRICES_FAILURE'; -const GAS_UPDATE_TX_FEE_SUCCESS = 'send/GAS_UPDATE_TX_FEE_SUCCESS'; -const GAS_UPDATE_TX_FEE_FAILURE = 'send/GAS_UPDATE_TX_FEE_FAILURE'; - -const GAS_CLEAR_FIELDS = 'send/GAS_CLEAR_FIELDS'; -const GAS_CLEAR_TXN_SPECIFIC_FIELDS = 'send/GAS_CLEAR_TXN_SPECIFIC_FIELDS'; +const GAS_UPDATE_TX_FEE_SUCCESS = 'gas/GAS_UPDATE_TX_FEE_SUCCESS'; +const GAS_UPDATE_GAS_PRICE_OPTION = 'gas/GAS_UPDATE_GAS_PRICE_OPTION'; +const GAS_CLEAR_FIELDS = 'gas/GAS_CLEAR_FIELDS'; +const GAS_CLEAR_TXN_SPECIFIC_FIELDS = 'gas/GAS_CLEAR_TXN_SPECIFIC_FIELDS'; // -- Actions --------------------------------------------------------------- // let getGasPricesInterval = null; @@ -83,52 +82,47 @@ export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, }); }); -export const gasUpdateGasPrice = newGasPriceOption => (dispatch, getState) => { - const { - address, - recipient, - assetAmount, - selected, - } = getState().send; +export const gasUpdateGasPriceOption = (newGasPriceOption) => (dispatch) => { + dispatch({ + payload: newGasPriceOption, + type: GAS_UPDATE_GAS_PRICE_OPTION, + }); +}; + +export const gasUpdateGasPrice = (address, amount, asset, recipient) => (dispatch, getState) => { const { gasPrices, selectedGasPriceOption } = getState().gas; const { assets } = getState().data; const { nativeCurrency } = getState().settings; - const _gasPriceOption = newGasPriceOption || selectedGasPriceOption; const ethAsset = ethereumUtils.getAsset(assets); - if (isEmpty(selected)) return; + if (isEmpty(asset)) return; if (isEmpty(gasPrices)) return; estimateGasLimit({ address, - amount: assetAmount, - asset: selected, + amount, + asset, recipient, }) .then(gasLimit => { const ethPriceUnit = getEthPriceUnit(assets); const txFees = parseTxFees(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); - const txFee = txFees[_gasPriceOption]; + const txFee = txFees[selectedGasPriceOption]; const balanceAmount = get(ethAsset, 'balance.amount', 0); const txFeeAmount = fromWei(get(txFee, 'value.amount', 0)); const selectedGasPrice = { ...txFee, - ...gasPrices[_gasPriceOption], + ...gasPrices[selectedGasPriceOption], }; dispatch({ payload: { gasLimit, isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), selectedGasPrice, - selectedGasPriceOption: _gasPriceOption, txFees, }, type: GAS_UPDATE_TX_FEE_SUCCESS, }); }) .catch(error => { - dispatch({ - payload: _gasPriceOption, - type: GAS_UPDATE_TX_FEE_FAILURE, - }); }); }; @@ -180,10 +174,9 @@ export default (state = INITIAL_STATE, action) => { gasLimit: action.payload.gasLimit, isSufficientGas: action.payload.isSufficientGas, selectedGasPrice: action.payload.selectedGasPrice, - selectedGasPriceOption: action.payload.selectedGasPriceOption, txFees: action.payload.txFees, }; - case GAS_UPDATE_TX_FEE_FAILURE: + case GAS_UPDATE_GAS_PRICE_OPTION: return { ...state, selectedGasPriceOption: action.payload, diff --git a/src/redux/send.js b/src/redux/send.js index 2ea5c5533ac..03cbe9cb7bc 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -5,7 +5,7 @@ import { formatInputDecimals, } from '../helpers/utilities'; import { createSignableTransaction } from '../handlers/web3'; -import { gasUpdateGasPrice, resetGasTxFees } from './gas'; +import { resetGasTxFees } from './gas'; import { ethereumUtils } from '../utils'; import { dataAddNewTransaction } from './data'; @@ -182,7 +182,6 @@ export const sendUpdateSelected = (asset) => (dispatch, getState) => { }, type: SEND_UPDATE_NFT_SELECTED, }); - dispatch(gasUpdateGasPrice()); } else { const state = getState(); const assetAmount = get(state, 'send.assetAmount'); @@ -191,7 +190,6 @@ export const sendUpdateSelected = (asset) => (dispatch, getState) => { type: SEND_UPDATE_SELECTED, }); dispatch(sendUpdateAssetAmount(assetAmount)); - dispatch(gasUpdateGasPrice()); } }; @@ -200,7 +198,6 @@ export const sendMaxBalance = () => (dispatch, getState) => { const { selectedGasPrice } = getState().gas; const balanceAmount = ethereumUtils.getBalanceAmount(selectedGasPrice, selected); dispatch(sendUpdateAssetAmount(balanceAmount)); - dispatch(gasUpdateGasPrice()); }; export const sendClearFields = () => ({ type: SEND_CLEAR_FIELDS }); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 73c06644a86..ba208e0052e 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -30,6 +30,7 @@ import { withAccountData, withAccountSettings, withBlockedHorizontalSwipe, + withGas, withKeyboardFocusHistory, withTransactionConfirmationScreen, withTransitionProps, @@ -37,7 +38,11 @@ import { withUniswapAssets, } from '../hoc'; import { colors, padding, position } from '../styles'; -import { contractUtils, ethereumUtils, isNewValueForPath } from '../utils'; +import { + contractUtils, + ethereumUtils, + isNewValueForPath, +} from '../utils'; import { ConfirmExchangeButton, ExchangeGasFeeButton, @@ -77,12 +82,15 @@ class ExchangeModal extends PureComponent { chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, + gasUpdateGasPrice: PropTypes.func, isFocused: PropTypes.bool, isTransitioning: PropTypes.bool, keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, + nativeCurrencySymbol: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, + selectedGasPrice: PropTypes.object, tokenReserves: PropTypes.array, tradeDetails: PropTypes.object, transitionPosition: PropTypes.object, // animated value @@ -339,6 +347,8 @@ class ExchangeModal extends PureComponent { console.log('error getting market details', error); // TODO error state } + // TODO JIN + // this.props.gasUpdateGasPrice(address, assetAmount, selected, recipient); } getReserveData = async (tokenAddress) => { @@ -512,7 +522,12 @@ class ExchangeModal extends PureComponent { } render = () => { - const { nativeCurrency, transitionPosition } = this.props; + const { + nativeCurrency, + nativeCurrencySymbol, + selectedGasPrice, + transitionPosition, + } = this.props; const { inputAmountDisplay, @@ -602,7 +617,8 @@ class ExchangeModal extends PureComponent { /> )} @@ -619,6 +635,7 @@ export default compose( withAccountData, withAccountSettings, withBlockedHorizontalSwipe, + withGas, withKeyboardFocusHistory, withNavigationFocus, withTransactionConfirmationScreen, diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index eae7c9c6e3b..9c755ef793d 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -42,7 +42,7 @@ class SendSheet extends Component { assetAmount: PropTypes.string, fetchData: PropTypes.func, gasPrices: PropTypes.object, - gasUpdateGasPrice: PropTypes.func, + gasUpdateGasPriceOption: PropTypes.func, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, @@ -146,7 +146,7 @@ class SendSheet extends Component { onPressTransactionSpeed = (onSuccess) => { const { gasPrices, - gasUpdateGasPrice, + gasUpdateGasPriceOption, txFees, } = this.props; @@ -162,7 +162,7 @@ class SendSheet extends Component { if (buttonIndex > 0) { const selectedGasPriceItem = options[buttonIndex]; - gasUpdateGasPrice(selectedGasPriceItem.value); + gasUpdateGasPriceOption(selectedGasPriceItem.value); analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); } From f100f099061ee304a553be32db2be990afe37a66 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 31 Aug 2019 01:27:04 -0400 Subject: [PATCH 257/636] decoupling gas estimation from tx fee calculation --- src/components/SendComponentWithData.js | 23 +++++--- src/hoc/withGas.js | 4 +- src/redux/gas.js | 70 ++++++++++--------------- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index 1ee467d4a1d..d59adc7210e 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -1,14 +1,17 @@ -import React, { Component } from 'react'; +import { get } from 'lodash'; import PropTypes from 'prop-types'; +import React, { Component } from 'react'; import { connect } from 'react-redux'; import { compose } from 'recompact'; -import { get } from 'lodash'; -import lang from '../languages'; +import { estimateGasLimit } from '../handlers/web3'; +import { greaterThan } from '../helpers/utilities'; +import { isValidAddress } from '../helpers/validators'; import { withAccountData, withGas, withUniqueTokens, } from '../hoc'; +import lang from '../languages'; import { sendClearFields, sendMaxBalance, @@ -20,8 +23,6 @@ import { sendUpdateRecipient, sendUpdateSelected, } from '../redux/send'; -import { isValidAddress } from '../helpers/validators'; -import { greaterThan } from '../helpers/utilities'; import { ethereumUtils } from '../utils'; const mapStateToProps = ({ send, settings }) => ({ @@ -58,7 +59,7 @@ export const withSendComponentWithData = (SendComponent, options) => { fetching: PropTypes.bool.isRequired, gasLimit: PropTypes.number.isRequired, gasPrices: PropTypes.object.isRequired, - gasUpdateGasPrice: PropTypes.func.isRequired, + gasUpdateTxFee: PropTypes.func.isRequired, isSufficientBalance: PropTypes.bool.isRequired, isSufficientGas: PropTypes.bool.isRequired, nativeAmount: PropTypes.string.isRequired, @@ -117,7 +118,15 @@ export const withSendComponentWithData = (SendComponent, options) => { || (selectedGasPriceOption !== prevProps.selectedGasPriceOption) || (recipient !== prevProps.recipient) || (assetAmount !== prevProps.assetAmount)) { - this.props.gasUpdateGasPrice(address, assetAmount, selected, recipient); + estimateGasLimit({ + address, + amount: assetAmount, + asset: selected, + recipient, + }).then(gasLimit => { + this.props.gasUpdateTxFee(gasLimit); + }).catch(error => { + }); } } } diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js index 171b1c475dc..69adf03d6c1 100644 --- a/src/hoc/withGas.js +++ b/src/hoc/withGas.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { compose } from 'recompact'; -import { gasUpdateGasPrice, gasUpdateGasPriceOption } from '../redux/gas'; +import { gasUpdateGasPriceOption, gasUpdateTxFee } from '../redux/gas'; const mapStateToProps = ({ gas }) => ({ gasLimit: gas.gasLimit, @@ -13,7 +13,7 @@ const mapStateToProps = ({ gas }) => ({ export default Component => compose( connect(mapStateToProps, { - gasUpdateGasPrice, gasUpdateGasPriceOption, + gasUpdateTxFee, }), )(Component); diff --git a/src/redux/gas.js b/src/redux/gas.js index 71000d19792..632dbc5f111 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -1,6 +1,5 @@ import { get, isEmpty } from 'lodash'; import { apiGetGasPrices } from '../handlers/gasPrices'; -import { estimateGasLimit } from '../handlers/web3'; import { fromWei } from '../helpers/utilities'; import { getFallbackGasPrices, @@ -12,11 +11,11 @@ import { ethereumUtils } from '../utils'; // -- Constants ------------------------------------------------------------- // -const GAS_PRICES_REQUEST = 'gas/GAS_PRICES_REQUEST'; +const GAS_PRICES_DEFAULT = 'gas/GAS_PRICES_DEFAULT'; const GAS_PRICES_SUCCESS = 'gas/GAS_PRICES_SUCCESS'; const GAS_PRICES_FAILURE = 'gas/GAS_PRICES_FAILURE'; -const GAS_UPDATE_TX_FEE_SUCCESS = 'gas/GAS_UPDATE_TX_FEE_SUCCESS'; +const GAS_UPDATE_TX_FEE = 'gas/GAS_UPDATE_TX_FEE'; const GAS_UPDATE_GAS_PRICE_OPTION = 'gas/GAS_UPDATE_GAS_PRICE_OPTION'; const GAS_CLEAR_FIELDS = 'gas/GAS_CLEAR_FIELDS'; const GAS_CLEAR_TXN_SPECIFIC_FIELDS = 'gas/GAS_CLEAR_TXN_SPECIFIC_FIELDS'; @@ -45,7 +44,7 @@ export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, gasPrices: fallbackGasPrices, selectedGasPrice, }, - type: GAS_PRICES_REQUEST, + type: GAS_PRICES_DEFAULT, }); const getGasPrices = () => new Promise((fetchResolve, fetchReject) => { @@ -82,48 +81,35 @@ export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, }); }); -export const gasUpdateGasPriceOption = (newGasPriceOption) => (dispatch) => { - dispatch({ - payload: newGasPriceOption, - type: GAS_UPDATE_GAS_PRICE_OPTION, - }); -}; +export const gasUpdateGasPriceOption = (newGasPriceOption) => (dispatch) => dispatch({ + payload: newGasPriceOption, + type: GAS_UPDATE_GAS_PRICE_OPTION, +}); -export const gasUpdateGasPrice = (address, amount, asset, recipient) => (dispatch, getState) => { +export const gasUpdateTxFee = (gasLimit) => (dispatch, getState) => { const { gasPrices, selectedGasPriceOption } = getState().gas; const { assets } = getState().data; const { nativeCurrency } = getState().settings; const ethAsset = ethereumUtils.getAsset(assets); - if (isEmpty(asset)) return; if (isEmpty(gasPrices)) return; - estimateGasLimit({ - address, - amount, - asset, - recipient, - }) - .then(gasLimit => { - const ethPriceUnit = getEthPriceUnit(assets); - const txFees = parseTxFees(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); - const txFee = txFees[selectedGasPriceOption]; - const balanceAmount = get(ethAsset, 'balance.amount', 0); - const txFeeAmount = fromWei(get(txFee, 'value.amount', 0)); - const selectedGasPrice = { - ...txFee, - ...gasPrices[selectedGasPriceOption], - }; - dispatch({ - payload: { - gasLimit, - isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), - selectedGasPrice, - txFees, - }, - type: GAS_UPDATE_TX_FEE_SUCCESS, - }); - }) - .catch(error => { - }); + const ethPriceUnit = getEthPriceUnit(assets); + const txFees = parseTxFees(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); + const txFee = txFees[selectedGasPriceOption]; + const balanceAmount = get(ethAsset, 'balance.amount', 0); + const txFeeAmount = fromWei(get(txFee, 'value.amount', 0)); + const selectedGasPrice = { + ...txFee, + ...gasPrices[selectedGasPriceOption], + }; + dispatch({ + payload: { + gasLimit, + isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), + selectedGasPrice, + txFees, + }, + type: GAS_UPDATE_TX_FEE, + }); }; export const resetGasTxFees = () => (dispatch) => { @@ -149,7 +135,7 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => { switch (action.type) { - case GAS_PRICES_REQUEST: + case GAS_PRICES_DEFAULT: return { ...state, fetchingGasPrices: true, @@ -168,7 +154,7 @@ export default (state = INITIAL_STATE, action) => { fetchingGasPrices: false, gasPrices: action.payload, }; - case GAS_UPDATE_TX_FEE_SUCCESS: + case GAS_UPDATE_TX_FEE: return { ...state, gasLimit: action.payload.gasLimit, From 4a11e7f63aa011f6742a39405342a0bcb792d2ca Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 31 Aug 2019 10:08:20 -0400 Subject: [PATCH 258/636] hook in exchange modal to getting gas prices --- src/handlers/uniswap.js | 109 ++++++++++++++++++++++------------- src/parsers/gas.js | 6 +- src/screens/ExchangeModal.js | 22 ++++--- 3 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index de7429d9706..9f5b84e736e 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -40,54 +40,85 @@ export const getReserves = async () => { }); }; -export const executeSwap = async (tradeDetails) => { +const getGasLimit = (exchange, methodName, updatedMethodArgs, value) => { + switch (methodName) { + case 'ethToTokenSwapInput': + return exchange.estimate.ethToTokenSwapInput(...updatedMethodArgs, { value }); + case 'ethToTokenSwapOutput': + return exchange.estimate.ethToTokenSwapOutput(...updatedMethodArgs, { value }); + case 'tokenToEthSwapInput': + return exchange.estimate.tokenToEthSwapInput(...updatedMethodArgs, { value }); + case 'tokenToEthSwapOutput': + return exchange.estimate.tokenToEthSwapOutput(...updatedMethodArgs, { value }); + case 'tokenToTokenSwapInput': + return exchange.estimate.tokenToTokenSwapInput(...updatedMethodArgs, { value }); + case 'tokenToTokenSwapOutput': + return exchange.estimate.tokenToTokenSwapOutput(...updatedMethodArgs, { value }); + default: + return null; + } +}; + +export const estimateSwapGasLimit = (tradeDetails) => { + const { + exchange, + methodName, + updatedMethodArgs, + value, + } = getContractExecutionDetails(tradeDetails, web3Provider); + return getGasLimit(exchange, methodName, updatedMethodArgs, value); +}; + +export const getContractExecutionDetails = (tradeDetails, providerOrSigner) => { const executionDetails = getExecutionDetails(tradeDetails); - const wallet = await loadWallet(); - if (!wallet) return null; const { exchangeAddress, methodArguments, methodName, value: rawValue, } = executionDetails; - const exchange = new ethers.Contract(exchangeAddress, exchangeABI, wallet); + const exchange = new ethers.Contract(exchangeAddress, exchangeABI, providerOrSigner); const updatedMethodArgs = convertArgsForEthers(methodArguments); const value = convertValueForEthers(rawValue); - try { - switch (methodName) { - case 'ethToTokenSwapInput': { - const gasLimit = await exchange.estimate.ethToTokenSwapInput(...updatedMethodArgs, { value }); - return exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); - } - case 'ethToTokenSwapOutput': { - const gasLimit = await exchange.estimate.ethToTokenSwapOutput(...updatedMethodArgs, { value }); - return exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); - } - case 'tokenToEthSwapInput': { - // TODO approval check - const gasLimit = await exchange.estimate.tokenToEthSwapInput(...updatedMethodArgs, { value }); - return exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); - } - case 'tokenToEthSwapOutput': { - // TODO approval check - const gasLimit = await exchange.estimate.tokenToEthSwapOutput(...updatedMethodArgs, { value }); - return exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); - } - case 'tokenToTokenSwapInput': { - // TODO approval check - const gasLimit = await exchange.estimate.tokenToTokenSwapInput(...updatedMethodArgs, { value }); - return exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); - } - case 'tokenToTokenSwapOutput': { - // TODO approval check - const gasLimit = await exchange.estimate.tokenToTokenSwapOutput(...updatedMethodArgs, { value }); - return exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); - } - default: - return null; - } - } catch (error) { - console.log('error exchanging', error); + return { + exchange, + methodName, + updatedMethodArgs, + value, + }; +}; + +export const executeSwap = async (tradeDetails, gasLimit) => { + const wallet = await loadWallet(); + if (!wallet) return null; + const { + exchange, + methodName, + updatedMethodArgs, + value, + } = getContractExecutionDetails(tradeDetails, wallet); + switch (methodName) { + case 'ethToTokenSwapInput': + return exchange.ethToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); + case 'ethToTokenSwapOutput': + return exchange.ethToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); + case 'tokenToEthSwapInput': { + // TODO approval check + return exchange.tokenToEthSwapInput(...updatedMethodArgs, { gasLimit, value }); + } + case 'tokenToEthSwapOutput': { + // TODO approval check + return exchange.tokenToEthSwapOutput(...updatedMethodArgs, { gasLimit, value }); + } + case 'tokenToTokenSwapInput': { + // TODO approval check + return exchange.tokenToTokenSwapInput(...updatedMethodArgs, { gasLimit, value }); + } + case 'tokenToTokenSwapOutput': { + // TODO approval check + return exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { gasLimit, value }); + } + default: return null; } }; diff --git a/src/parsers/gas.js b/src/parsers/gas.js index 9422f449ba3..ce7ec8fe580 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -19,9 +19,9 @@ export const getFallbackGasPrices = (short = true) => { fast: null, slow: null, }; - gasPrices.fast = defaultGasPriceFormat('fast', '30000', '5000000000', '5 Gwei', short); - gasPrices.average = defaultGasPriceFormat('average', '360000', '2000000000', '2 Gwei', short); - gasPrices.slow = defaultGasPriceFormat('slow', '1800000', '1000000000', '1 Gwei', short); + gasPrices.fast = defaultGasPriceFormat('fast', '0.5', '200', short); + gasPrices.average = defaultGasPriceFormat('average', '2.5', '100', short); + gasPrices.slow = defaultGasPriceFormat('slow', '2.5', '100', short); return gasPrices; }; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index ba208e0052e..6ad3a606400 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -14,7 +14,7 @@ import { InteractionManager, LayoutAnimation, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, mapProps, toClass } from 'recompact'; -import { executeSwap } from '../handlers/uniswap'; +import { estimateSwapGasLimit, executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeValue, convertAmountToNativeAmount, @@ -82,7 +82,8 @@ class ExchangeModal extends PureComponent { chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, - gasUpdateGasPrice: PropTypes.func, + gasLimit: PropTypes.number, + gasUpdateTxFee: PropTypes.func, isFocused: PropTypes.bool, isTransitioning: PropTypes.bool, keyboardFocusHistory: PropTypes.array, @@ -343,12 +344,14 @@ class ExchangeModal extends PureComponent { this.setInputAmount(rawUpdatedAmount, updatedAmountDisplay); } } + const gasLimit = await estimateSwapGasLimit(tradeDetails); + if (gasLimit) { + this.props.gasUpdateTxFee(gasLimit.toNumber()); + } } catch (error) { console.log('error getting market details', error); // TODO error state } - // TODO JIN - // this.props.gasUpdateGasPrice(address, assetAmount, selected, recipient); } getReserveData = async (tokenAddress) => { @@ -375,11 +378,16 @@ class ExchangeModal extends PureComponent { } handleSubmit = async () => { - const { accountAddress, dataAddNewTransaction, navigation } = this.props; + const { + accountAddress, + dataAddNewTransaction, + gasLimit, + navigation, + } = this.props; const { inputAmount, inputCurrency, tradeDetails } = this.state; try { - const txn = await executeSwap(tradeDetails); + const txn = await executeSwap(tradeDetails, gasLimit); if (txn) { dataAddNewTransaction({ amount: inputAmount, @@ -523,12 +531,12 @@ class ExchangeModal extends PureComponent { render = () => { const { + gasLimit, nativeCurrency, nativeCurrencySymbol, selectedGasPrice, transitionPosition, } = this.props; - const { inputAmountDisplay, inputCurrency, From b3ef50a0a0a91c48fc9cee35779b0a83528949eb Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 31 Aug 2019 13:46:21 -0400 Subject: [PATCH 259/636] transaction speed selection for exchange --- src/components/SendComponentWithData.js | 2 - .../exchange/ExchangeGasFeeButton.js | 54 +++++++++---------- src/redux/gas.js | 49 +++++++++++------ src/screens/ExchangeModal.js | 20 +++++-- src/screens/SendSheet.js | 24 +-------- src/utils/gas.js | 34 +++++++++++- 6 files changed, 108 insertions(+), 75 deletions(-) diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index d59adc7210e..d8c3fd582d6 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -105,7 +105,6 @@ export const withSendComponentWithData = (SendComponent, options) => { assetAmount, recipient, selected, - selectedGasPriceOption, } = this.props; if (recipient !== prevProps.recipient) { @@ -115,7 +114,6 @@ export const withSendComponentWithData = (SendComponent, options) => { if (this.state.isValidAddress) { if ((selected.symbol !== prevProps.selected.symbol) - || (selectedGasPriceOption !== prevProps.selectedGasPriceOption) || (recipient !== prevProps.recipient) || (assetAmount !== prevProps.assetAmount)) { estimateGasLimit({ diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js index ebe39b461ff..c56fa8a49d1 100644 --- a/src/components/exchange/ExchangeGasFeeButton.js +++ b/src/components/exchange/ExchangeGasFeeButton.js @@ -1,4 +1,4 @@ -import { get } from 'lodash'; +import { get, upperFirst } from 'lodash'; import React from 'react'; import PropTypes from 'prop-types'; import { @@ -41,37 +41,31 @@ const ExchangeGasFeeButton = enhance(({ gasPrice, nativeCurrencySymbol, onPress, -}) => { - const fee = get(gasPrice, 'txFee.native.value.display', `${nativeCurrencySymbol}0.00`); - const time = get(gasPrice, 'estimatedTime.display', ''); - return ( - - - - {fee} - - - - - Normal - - +}) => ( + + + + {get(gasPrice, 'txFee.native.value.display', `${nativeCurrencySymbol}0.00`)} + + + + {upperFirst(get(gasPrice, 'option', 'average'))} - - - - - - + + + + + + - - - ); -}); + + + +)); ExchangeGasFeeButton.propTypes = { gasPrice: PropTypes.string, diff --git a/src/redux/gas.js b/src/redux/gas.js index 632dbc5f111..8b81d476892 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -81,37 +81,52 @@ export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, }); }); -export const gasUpdateGasPriceOption = (newGasPriceOption) => (dispatch) => dispatch({ - payload: newGasPriceOption, - type: GAS_UPDATE_GAS_PRICE_OPTION, -}); +export const gasUpdateGasPriceOption = (newGasPriceOption) => (dispatch, getState) => { + const { gasPrices, txFees } = getState().gas; + if (isEmpty(gasPrices)) return; + const { assets } = getState().data; + const results = getSelectedGasPrice(assets, gasPrices, txFees, newGasPriceOption); + dispatch({ + payload: { + ...results, + selectedGasPriceOption: newGasPriceOption, + }, + type: GAS_UPDATE_GAS_PRICE_OPTION, + }); +}; export const gasUpdateTxFee = (gasLimit) => (dispatch, getState) => { const { gasPrices, selectedGasPriceOption } = getState().gas; + if (isEmpty(gasPrices)) return; const { assets } = getState().data; const { nativeCurrency } = getState().settings; - const ethAsset = ethereumUtils.getAsset(assets); - if (isEmpty(gasPrices)) return; const ethPriceUnit = getEthPriceUnit(assets); const txFees = parseTxFees(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); - const txFee = txFees[selectedGasPriceOption]; - const balanceAmount = get(ethAsset, 'balance.amount', 0); - const txFeeAmount = fromWei(get(txFee, 'value.amount', 0)); - const selectedGasPrice = { - ...txFee, - ...gasPrices[selectedGasPriceOption], - }; + const results = getSelectedGasPrice(assets, gasPrices, txFees, selectedGasPriceOption); dispatch({ payload: { + ...results, gasLimit, - isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), - selectedGasPrice, txFees, }, type: GAS_UPDATE_TX_FEE, }); }; +const getSelectedGasPrice = (assets, gasPrices, txFees, selectedGasPriceOption) => { + const txFee = txFees[selectedGasPriceOption]; + const ethAsset = ethereumUtils.getAsset(assets); + const balanceAmount = get(ethAsset, 'balance.amount', 0); + const txFeeAmount = fromWei(get(txFee, 'value.amount', 0)); + return ({ + isSufficientGas: Number(balanceAmount) > Number(txFeeAmount), + selectedGasPrice: { + ...txFee, + ...gasPrices[selectedGasPriceOption], + }, + }); +}; + export const resetGasTxFees = () => (dispatch) => { dispatch({ type: GAS_CLEAR_TXN_SPECIFIC_FIELDS }); }; @@ -165,7 +180,9 @@ export default (state = INITIAL_STATE, action) => { case GAS_UPDATE_GAS_PRICE_OPTION: return { ...state, - selectedGasPriceOption: action.payload, + isSufficientGas: action.payload.isSufficientGas, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: action.payload.selectedGasPriceOption, }; case GAS_CLEAR_FIELDS: return { ...state, ...INITIAL_STATE }; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 6ad3a606400..3445b9778e0 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -41,6 +41,7 @@ import { colors, padding, position } from '../styles'; import { contractUtils, ethereumUtils, + gasUtils, isNewValueForPath, } from '../utils'; import { @@ -83,6 +84,8 @@ class ExchangeModal extends PureComponent { clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, gasLimit: PropTypes.number, + gasPrices: PropTypes.object, + gasUpdateGasPriceOption: PropTypes.string, gasUpdateTxFee: PropTypes.func, isFocused: PropTypes.bool, isTransitioning: PropTypes.bool, @@ -95,6 +98,7 @@ class ExchangeModal extends PureComponent { tokenReserves: PropTypes.array, tradeDetails: PropTypes.object, transitionPosition: PropTypes.object, // animated value + txFees: PropTypes.object, uniswapGetTokenReserve: PropTypes.func, uniswapUpdateAllowances: PropTypes.func, } @@ -210,7 +214,7 @@ class ExchangeModal extends PureComponent { } getMarketDetails = async () => { - const { chainId, nativeCurrency } = this.props; + const { chainId, gasUpdateTxFee, nativeCurrency } = this.props; const { inputAmount, inputAsExactAmount, @@ -346,7 +350,7 @@ class ExchangeModal extends PureComponent { } const gasLimit = await estimateSwapGasLimit(tradeDetails); if (gasLimit) { - this.props.gasUpdateTxFee(gasLimit.toNumber()); + gasUpdateTxFee(gasLimit.toNumber()); } } catch (error) { console.log('error getting market details', error); @@ -377,6 +381,16 @@ class ExchangeModal extends PureComponent { return this.setInputAmount(maxBalance); } + handlePressTransactionSpeed = () => { + const { + gasPrices, + gasUpdateGasPriceOption, + txFees, + } = this.props; + + gasUtils.showTransactionSpeedOptions(gasPrices, txFees, gasUpdateGasPriceOption); + } + handleSubmit = async () => { const { accountAddress, @@ -531,7 +545,6 @@ class ExchangeModal extends PureComponent { render = () => { const { - gasLimit, nativeCurrency, nativeCurrencySymbol, selectedGasPrice, @@ -627,6 +640,7 @@ class ExchangeModal extends PureComponent { )} diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 9c755ef793d..7a524490a38 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -2,9 +2,7 @@ import analytics from '@segment/analytics-react-native'; import { get, isEmpty, - isFunction, isString, - property, } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -29,7 +27,6 @@ import { } from '../hoc'; import { colors } from '../styles'; import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; -import { showActionSheetWithOptions } from '../utils/actionsheet'; const Container = styled(Column)` background-color: ${colors.white}; @@ -150,26 +147,7 @@ class SendSheet extends Component { txFees, } = this.props; - const options = [ - { label: 'Cancel' }, - ...gasUtils.formatGasSpeedItems(gasPrices, txFees), - ]; - - showActionSheetWithOptions({ - cancelButtonIndex: 0, - options: options.map(property('label')), - }, (buttonIndex) => { - if (buttonIndex > 0) { - const selectedGasPriceItem = options[buttonIndex]; - - gasUpdateGasPriceOption(selectedGasPriceItem.value); - analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); - } - - if (isFunction(onSuccess)) { - onSuccess(); - } - }); + gasUtils.showTransactionSpeedOptions(gasPrices, txFees, gasUpdateGasPriceOption, onSuccess); } onResetAssetSelection = () => { diff --git a/src/utils/gas.js b/src/utils/gas.js index 699be9590ee..0cd970fe005 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -1,13 +1,45 @@ +import analytics from '@segment/analytics-react-native'; import { get, indexOf, + isFunction, map, + property, sortBy, upperFirst, } from 'lodash'; +import { showActionSheetWithOptions } from './actionsheet'; const labelOrder = ['slow', 'average', 'fast']; +const showTransactionSpeedOptions = ( + gasPrices, + txFees, + updateGasOption, + onSuccess, +) => { + const options = [ + { label: 'Cancel' }, + ...formatGasSpeedItems(gasPrices, txFees), + ]; + + showActionSheetWithOptions({ + cancelButtonIndex: 0, + options: options.map(property('label')), + }, (buttonIndex) => { + if (buttonIndex > 0) { + const selectedGasPriceItem = options[buttonIndex]; + + updateGasOption(selectedGasPriceItem.value); + analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); + } + + if (isFunction(onSuccess)) { + onSuccess(); + } + }); +}; + const formatGasSpeedItems = (gasPrices, txFees) => { const gasItems = map(labelOrder, speed => { const cost = get(txFees, `[${speed}].txFee.native.value.display`); @@ -24,5 +56,5 @@ const formatGasSpeedItems = (gasPrices, txFees) => { }; export default { - formatGasSpeedItems, + showTransactionSpeedOptions, }; From d451ad7e2d2884832074bbfb14a46d137dee4da6 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 31 Aug 2019 16:40:22 -0400 Subject: [PATCH 260/636] setting up txfees value in default gas prices --- src/redux/gas.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/redux/gas.js b/src/redux/gas.js index 8b81d476892..794b682a2ef 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -43,6 +43,7 @@ export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, payload: { gasPrices: fallbackGasPrices, selectedGasPrice, + txFees, }, type: GAS_PRICES_DEFAULT, }); @@ -156,6 +157,7 @@ export default (state = INITIAL_STATE, action) => { fetchingGasPrices: true, gasPrices: action.payload.gasPrices, selectedGasPrice: action.payload.selectedGasPrice, + txFees: action.payload.txFees, }; case GAS_PRICES_SUCCESS: return { From 0f4037ac2fc3f0293665a2ac44d6bd1ccc2f3660 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 31 Aug 2019 17:14:44 -0400 Subject: [PATCH 261/636] reset tx fees when open/closing modals while keeping speed option remembered --- src/hoc/withGas.js | 7 ++++++- src/redux/gas.js | 29 +++++++++++++++++++++++------ src/redux/send.js | 4 +--- src/screens/ExchangeModal.js | 2 ++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js index 69adf03d6c1..ce809702457 100644 --- a/src/hoc/withGas.js +++ b/src/hoc/withGas.js @@ -1,6 +1,10 @@ import { connect } from 'react-redux'; import { compose } from 'recompact'; -import { gasUpdateGasPriceOption, gasUpdateTxFee } from '../redux/gas'; +import { + gasUpdateGasPriceOption, + gasUpdateTxFee, + resetGasTxFees, +} from '../redux/gas'; const mapStateToProps = ({ gas }) => ({ gasLimit: gas.gasLimit, @@ -15,5 +19,6 @@ export default Component => compose( connect(mapStateToProps, { gasUpdateGasPriceOption, gasUpdateTxFee, + resetGasTxFees, }), )(Component); diff --git a/src/redux/gas.js b/src/redux/gas.js index 794b682a2ef..ec3a98f0a49 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -18,7 +18,7 @@ const GAS_PRICES_FAILURE = 'gas/GAS_PRICES_FAILURE'; const GAS_UPDATE_TX_FEE = 'gas/GAS_UPDATE_TX_FEE'; const GAS_UPDATE_GAS_PRICE_OPTION = 'gas/GAS_UPDATE_GAS_PRICE_OPTION'; const GAS_CLEAR_FIELDS = 'gas/GAS_CLEAR_FIELDS'; -const GAS_CLEAR_TXN_SPECIFIC_FIELDS = 'gas/GAS_CLEAR_TXN_SPECIFIC_FIELDS'; +const GAS_RESET_FIELDS = 'gas/GAS_RESET_FIELDS'; // -- Actions --------------------------------------------------------------- // let getGasPricesInterval = null; @@ -28,7 +28,7 @@ const getEthPriceUnit = (assets) => { return get(ethAsset, 'price.value', 0); }; -export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, reject) => { +const getDefaultTxFees = () => (dispatch, getState) => { const { assets } = getState().data; const { gasLimit } = getState().gas; const { nativeCurrency } = getState().settings; @@ -39,6 +39,15 @@ export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, ...txFees.average, ...fallbackGasPrices.average, }; + return { + fallbackGasPrices, + selectedGasPrice, + txFees, + }; +}; + +export const gasPricesInit = () => (dispatch, getState) => new Promise((resolve, reject) => { + const { fallbackGasPrices, selectedGasPrice, txFees } = dispatch(getDefaultTxFees()); dispatch({ payload: { gasPrices: fallbackGasPrices, @@ -129,7 +138,14 @@ const getSelectedGasPrice = (assets, gasPrices, txFees, selectedGasPriceOption) }; export const resetGasTxFees = () => (dispatch) => { - dispatch({ type: GAS_CLEAR_TXN_SPECIFIC_FIELDS }); + const { selectedGasPrice, txFees } = dispatch(getDefaultTxFees()); + dispatch({ + payload: { + selectedGasPrice, + txFees, + }, + type: GAS_RESET_FIELDS, + }); }; export const gasClearFields = () => (dispatch) => { @@ -186,13 +202,14 @@ export default (state = INITIAL_STATE, action) => { selectedGasPrice: action.payload.selectedGasPrice, selectedGasPriceOption: action.payload.selectedGasPriceOption, }; - case GAS_CLEAR_FIELDS: - return { ...state, ...INITIAL_STATE }; - case GAS_CLEAR_TXN_SPECIFIC_FIELDS: { + case GAS_RESET_FIELDS: { return { ...INITIAL_STATE, fetchingGasPrices: state.fetchingGasPrices, gasPrices: state.gasPrices, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: state.selectedGasPriceOption, + txFees: action.payload.txFees, }; } default: diff --git a/src/redux/send.js b/src/redux/send.js index 03cbe9cb7bc..d88d5cb72d2 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -34,7 +34,6 @@ export const sendModalInit = (options = {}) => (dispatch, getState) => { const { accountAddress } = getState().settings; const { assets } = getState().data; const selected = assets.filter(asset => asset.address === options.defaultAsset)[0] || {}; - dispatch({ payload: { address: accountAddress, @@ -42,6 +41,7 @@ export const sendModalInit = (options = {}) => (dispatch, getState) => { }, type: SEND_MODAL_INIT, }); + dispatch(resetGasTxFees()); }; export const sendTransaction = (transactionDetails, signAndSendTransactionCb) => (dispatch, getState) => new Promise((resolve, reject) => { @@ -79,10 +79,8 @@ export const sendTransaction = (transactionDetails, signAndSendTransactionCb) => payload: txHash, type: SEND_TRANSACTION_SUCCESS, }); - dispatch(resetGasTxFees()); resolve(txHash); }).catch(error => { - dispatch(resetGasTxFees()); reject(error); }); } else { diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 3445b9778e0..e7e0d2ef17a 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -94,6 +94,7 @@ class ExchangeModal extends PureComponent { nativeCurrencySymbol: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, + resetGasTxFees: PropTypes.func, selectedGasPrice: PropTypes.object, tokenReserves: PropTypes.array, tradeDetails: PropTypes.object, @@ -176,6 +177,7 @@ class ExchangeModal extends PureComponent { } componentWillUnmount = () => { + this.props.resetGasTxFees(); this.props.clearKeyboardFocusHistory(); } From ea671e599121d5dcd4d8e8335c7cf257a5b96727 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 1 Sep 2019 14:38:13 -0400 Subject: [PATCH 262/636] gas estimation for approval --- .../exchange/ExchangeGasFeeButton.js | 2 +- src/screens/ExchangeModal.js | 26 ++++++++++++++----- src/utils/contract.js | 14 +++++++--- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js index c56fa8a49d1..5f7950a2155 100644 --- a/src/components/exchange/ExchangeGasFeeButton.js +++ b/src/components/exchange/ExchangeGasFeeButton.js @@ -68,7 +68,7 @@ const ExchangeGasFeeButton = enhance(({ )); ExchangeGasFeeButton.propTypes = { - gasPrice: PropTypes.string, + gasPrice: PropTypes.object, nativeCurrencySymbol: PropTypes.string, onPress: PropTypes.func, }; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index e7e0d2ef17a..7872b8a39dc 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -83,7 +83,7 @@ class ExchangeModal extends PureComponent { chainId: PropTypes.number, clearKeyboardFocusHistory: PropTypes.func, dataAddNewTransaction: PropTypes.func, - gasLimit: PropTypes.number, + gasLimit: PropTypes.string, gasPrices: PropTypes.object, gasUpdateGasPriceOption: PropTypes.string, gasUpdateTxFee: PropTypes.func, @@ -211,8 +211,16 @@ class ExchangeModal extends PureComponent { allowance = await contractUtils.getAllowance(accountAddress, inputCurrency, exchangeAddress); uniswapUpdateAllowances(inputAddress, allowance); } - - return this.setState({ isAssetApproved: greaterThan(allowance, 0) }); + const isAssetApproved = greaterThan(allowance, 0); + if (isAssetApproved) { + return this.setState({ isAssetApproved }); + } + try { + const gasLimit = await contractUtils.estimateApprove(inputCurrency.address, exchangeAddress); + return this.setState({ gasLimit: gasLimit.toFixed(), isAssetApproved }); + } catch (error) { + return this.setState({ isAssetApproved }); + } } getMarketDetails = async () => { @@ -221,6 +229,7 @@ class ExchangeModal extends PureComponent { inputAmount, inputAsExactAmount, inputCurrency, + isAssetApproved, nativeAmount, outputAmount, outputCurrency, @@ -350,9 +359,11 @@ class ExchangeModal extends PureComponent { this.setInputAmount(rawUpdatedAmount, updatedAmountDisplay); } } - const gasLimit = await estimateSwapGasLimit(tradeDetails); - if (gasLimit) { - gasUpdateTxFee(gasLimit.toNumber()); + if (isAssetApproved) { + const gasLimit = await estimateSwapGasLimit(tradeDetails); + if (gasLimit) { + gasUpdateTxFee(gasLimit.toFixed()); + } } } catch (error) { console.log('error getting market details', error); @@ -436,12 +447,14 @@ class ExchangeModal extends PureComponent { } handleUnlockAsset = async () => { + /* const { inputCurrency: { address: tokenAddress, exchangeAddress: spender, }, } = this.state; + */ // const approval = await contractUtils.approve(tokenAddress, spender); @@ -552,6 +565,7 @@ class ExchangeModal extends PureComponent { selectedGasPrice, transitionPosition, } = this.props; + const { inputAmountDisplay, inputCurrency, diff --git a/src/utils/contract.js b/src/utils/contract.js index e81d5b294eb..c107b8fb7e9 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -4,15 +4,22 @@ import { convertRawAmountToDecimalFormat } from '../helpers/utilities'; import { loadWallet } from '../model/wallet'; import erc20ABI from '../references/erc20-abi.json'; -export const approve = async (tokenAddress, spender) => { +const estimateApproveWithExchange = (spender, exchange) => exchange.estimate.approve(spender, ethers.constants.MaxUint256); + +const estimateApprove = (tokenAddress, spender) => { + const exchange = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); + return estimateApproveWithExchange(spender, exchange); +}; + +const approve = async (tokenAddress, spender) => { const wallet = await loadWallet(); if (!wallet) return null; const exchange = new ethers.Contract(tokenAddress, erc20ABI, wallet); - const gasLimit = await exchange.estimate.approve(spender, ethers.constants.MaxUint256); + const gasLimit = await estimateApproveWithExchange(spender, exchange); return exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); }; -export const getAllowance = async (owner, token, spender) => { +const getAllowance = async (owner, token, spender) => { const { address: tokenAddress, decimals } = token; const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); const allowance = await tokenContract.allowance(owner, spender); @@ -22,5 +29,6 @@ export const getAllowance = async (owner, token, spender) => { export default { approve, + estimateApprove, getAllowance, }; From 87d0eb056393b56521fd81374d91e46ea6aaba41 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 1 Sep 2019 16:03:16 -0400 Subject: [PATCH 263/636] fix for gaslimit update --- src/screens/ExchangeModal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 7872b8a39dc..716acd51662 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -362,7 +362,7 @@ class ExchangeModal extends PureComponent { if (isAssetApproved) { const gasLimit = await estimateSwapGasLimit(tradeDetails); if (gasLimit) { - gasUpdateTxFee(gasLimit.toFixed()); + gasUpdateTxFee(gasLimit.toString()); } } } catch (error) { From b8cd3cc913aaeb0770804b571bb112bdb7e39684 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 11 Sep 2019 19:12:52 -0400 Subject: [PATCH 264/636] revert change to onChangeText of ExchangeInput --- src/components/exchange/ExchangeInput.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 3af9094ee74..4655b5d00b8 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -30,6 +30,10 @@ export default class ExchangeInput extends PureComponent { placeholderTextColor: colors.alpha(colors.blueGreyDark, 0.5), } + handleChangeText = (formatted, extracted) => { + this.props.onChangeText(extracted ? formatted : ''); + } + render = () => { const { color, @@ -38,7 +42,6 @@ export default class ExchangeInput extends PureComponent { fontSize, fontWeight, mask, - onChangeText, placeholder, placeholderTextColor, refInput, @@ -54,7 +57,7 @@ export default class ExchangeInput extends PureComponent { keyboardAppearance="dark" keyboardType="decimal-pad" mask={mask} - onChangeText={onChangeText} + onChangeText={this.handleChangeText} placeholder={placeholder} placeholderTextColor={placeholderTextColor} refInput={refInput} From a2c454c8d12441aed17bd6d4aaa245c9f7732548 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 11 Sep 2019 19:15:32 -0400 Subject: [PATCH 265/636] Begin animating ExchangeGasButton - refactor wildly overcomplicated time.js code - refactor how `time` related translation json files are structured --- package.json | 3 +- .../exchange/ExchangeGasFeeButton.js | 135 ++++++++---- src/helpers/time.js | 205 +++++------------- src/hoc/withGas.js | 7 +- src/languages/_english.json | 75 +++++-- src/languages/_french.json | 75 +++++-- src/parsers/gas.js | 69 +++--- src/utils/gas.js | 11 +- yarn.lock | 5 + 9 files changed, 300 insertions(+), 285 deletions(-) diff --git a/package.json b/package.json index 35b97ae9554..e32e0ef6704 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "inherits": "^2.0.3", "lodash": "^4.17.15", "nanoid": "^2.0.3", + "parse-ms": "^2.1.0", "patch-package": "^6.1.2", "path-browserify": "0.0.0", "postcss": "^7.0.13", @@ -102,7 +103,7 @@ "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", - "react-navigation": "^3.11.1", + "react-navigation": "3.11.1", "react-navigation-stack": "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", "react-navigation-tabs": "2.3.0", "react-primitives": "^0.8.0", diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js index 5f7950a2155..1880ee07a2c 100644 --- a/src/components/exchange/ExchangeGasFeeButton.js +++ b/src/components/exchange/ExchangeGasFeeButton.js @@ -1,10 +1,10 @@ +import AnimateNumber from '@bankify/react-native-animate-number'; import { get, upperFirst } from 'lodash'; -import React from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { compose, - pure, - withHandlers, + mapProps, withProps, } from 'recompact'; import { colors, padding } from '../../styles'; @@ -13,6 +13,12 @@ import { Nbsp } from '../html-entities'; import { Column, Row } from '../layout'; import { Emoji, Text } from '../text'; +const EmojiForGasSpeedType = { + fast: 'rocket', // 🚀️ + normal: 'stopwatch', // ⏱️ + slow: 'snail', // 🐌️ +}; + const Label = withProps({ color: colors.alpha(colors.white, 0.4), size: 'smedium', @@ -26,51 +32,86 @@ const Title = withProps({ weight: 'semibold', })(Text); -const enhance = compose( - pure, - withHandlers({ - onPress: ({ onPress }) => (event) => { - if (onPress) { - onPress(event); - } - }, - }), +const renderGasPriceText = (displayValue) => ( + + {displayValue} + ); -const ExchangeGasFeeButton = enhance(({ - gasPrice, - nativeCurrencySymbol, - onPress, -}) => ( - - - - {get(gasPrice, 'txFee.native.value.display', `${nativeCurrencySymbol}0.00`)} - - - - {upperFirst(get(gasPrice, 'option', 'average'))} - - - - - - - - - - - -)); +class ExchangeGasFeeButton extends PureComponent { + static propTypes = { + estimatedTime: PropTypes.string, + label: PropTypes.string, + nativeCurrencySymbol: PropTypes.string, + onPress: PropTypes.func, + price: PropTypes.string, + } -ExchangeGasFeeButton.propTypes = { - gasPrice: PropTypes.object, - nativeCurrencySymbol: PropTypes.string, - onPress: PropTypes.func, -}; + handlePress = (event) => { + if (this.props.onPress) { + this.props.onPress(event); + } + } + + formatAnimatedGasPrice = (gasPrice) => { + const price = parseFloat(gasPrice || '0.00').toFixed(3); + return `${this.props.nativeCurrencySymbol}${price}`; + } -export default ExchangeGasFeeButton; + render = () => { + const { + estimatedTime, + label, + price, + } = this.props; + + return ( + + + + + + + + {upperFirst(label)} + + + + + + + + + + + + ); + } +} + +export default compose( + mapProps(({ gasPrice, ...props }) => { + let label = get(gasPrice, 'option', 'normal'); + if (label === 'average') { + label = 'normal'; + } + + return { + estimatedTime: get(gasPrice, 'estimatedTime.display', ''), + label, + price: get(gasPrice, 'txFee.native.value.amount', '0.00'), + ...props, + }; + }), +)(ExchangeGasFeeButton); diff --git a/src/helpers/time.js b/src/helpers/time.js index 80725891ed3..712afe8bd47 100644 --- a/src/helpers/time.js +++ b/src/helpers/time.js @@ -1,158 +1,65 @@ import { - convertStringToNumber, - divide, - formatFixedDecimals, - multiply, -} from './utilities'; -import timeUnits from '../references/time-units.json'; + findKey, + isObjectLike, + isString, + omitBy, + pick, +} from 'lodash'; +import parseMilliseconds from 'parse-ms'; import lang from '../languages'; +import { convertStringToNumber } from './utilities'; + +const MinimalTimeUnitWhitelist = [ + 'days', + 'hours', + 'minutes', + 'seconds', +]; + +const buildLocalizedTimeUnitString = ({ plural, short, unit }) => { + const length = short ? 'short' : 'long'; + const plurality = plural ? 'plural' : 'singular'; + + return lang.t(`time.${unit}.${length}.${plurality}`); +}; + +const getHighestResolutionUnit = (timeUnitValues) => { + const highestResolutionUnit = findKey(timeUnitValues); + return { + unit: highestResolutionUnit, + value: timeUnitValues[highestResolutionUnit], + }; +}; + +const isZero = number => (number === 0); /** * @desc get time string for minimal unit * @param {String} [value=''] - * @param {String} [unit='ms'] - * @param {Boolean} [short=false] + * @param {Boolean} [short=true] + * @param {Boolean} [plural=false] * @return {String} */ -export const getTimeString = (value = '', unit = 'ms', short = false) => { - if (!value) return null; - let _value = convertStringToNumber(value); - let _unit = ''; - let _unitShort = ''; - if (_value) { - if (unit === 'miliseconds' || unit === 'ms') { - if (_value === 1) { - _unit = lang.t('time.milisecond'); - _unitShort = lang.t('time.ms'); - } else if ( - _value >= timeUnits.ms.second - && _value < timeUnits.ms.minute - ) { - _value = formatFixedDecimals(divide(_value, timeUnits.ms.second), 2); - if (_value === 1) { - _unit = lang.t('time.second'); - _unitShort = lang.t('time.sec'); - } else { - _unit = lang.t('time.seconds'); - _unitShort = lang.t('time.secs'); - } - } else if (_value >= timeUnits.ms.minute && _value < timeUnits.ms.hour) { - _value = formatFixedDecimals(divide(_value, timeUnits.ms.minute), 2); - if (_value === 1) { - _unit = lang.t('time.minute'); - _unitShort = lang.t('time.min'); - } else { - _unit = lang.t('time.minutes'); - _unitShort = lang.t('time.mins'); - } - } else if (_value >= timeUnits.ms.hour && _value < timeUnits.ms.day) { - _value = formatFixedDecimals(divide(_value, timeUnits.ms.hour), 2); - if (_value === 1) { - _unit = lang.t('time.hour'); - _unitShort = lang.t('time.hr'); - } else { - _unit = lang.t('time.hours'); - _unitShort = lang.t('time.hrs'); - } - } else if (_value >= timeUnits.ms.day) { - _value = formatFixedDecimals(divide(_value, timeUnits.ms.day), 2); - if (_value === 1) { - _unit = lang.t('time.day'); - _unitShort = lang.t('time.day'); - } else { - _unit = lang.t('time.days'); - _unitShort = lang.t('time.days'); - } - } else { - _unit = lang.t('time.miliseconds'); - _unitShort = lang.t('time.ms'); - } - } else if (unit === 'seconds' || unit === 'secs') { - if (_value === 1) { - _unit = lang.t('time.second'); - _unitShort = lang.t('time.sec'); - } else if (_value < 1) { - _value = formatFixedDecimals(multiply(_value, timeUnits.ms.second)); - if (_value === 1) { - _unit = lang.t('time.milisecond'); - _unitShort = lang.t('time.ms'); - } else { - _unit = lang.t('time.miliseconds'); - _unitShort = lang.t('time.ms'); - } - } else if ( - _value >= timeUnits.secs.minute - && _value < timeUnits.secs.hour - ) { - _value = formatFixedDecimals(divide(_value, timeUnits.secs.minute), 2); - if (_value === 1) { - _unit = lang.t('time.minute'); - _unitShort = lang.t('time.min'); - } else { - _unit = lang.t('time.minutes'); - _unitShort = lang.t('time.mins'); - } - } else if (_value >= timeUnits.secs.hour && _value < timeUnits.secs.day) { - _value = formatFixedDecimals(divide(_value, timeUnits.secs.hour), 2); - if (_value === 1) { - _unit = lang.t('time.hour'); - _unitShort = lang.t('time.hr'); - } else { - _unit = lang.t('time.hours'); - _unitShort = lang.t('time.hrs'); - } - } else if (_value >= timeUnits.secs.day) { - _value = formatFixedDecimals(divide(_value, timeUnits.secs.day), 2); - if (_value === 1) { - _unit = lang.t('time.day'); - _unitShort = lang.t('time.day'); - } else { - _unit = lang.t('time.days'); - _unitShort = lang.t('time.days'); - } - } else { - _unit = lang.t('time.seconds'); - _unitShort = lang.t('time.secs'); - } - } else if (unit === 'minutes' || unit === 'mins') { - if (_value === 1) { - _unit = lang.t('time.minute'); - _unitShort = lang.t('time.min'); - } else if (_value < 1) { - _value = formatFixedDecimals(multiply(_value, timeUnits.secs.minute)); - if (_value === 1) { - _unit = lang.t('time.second'); - _unitShort = lang.t('time.sec'); - } else { - _unit = lang.t('time.seconds'); - _unitShort = lang.t('time.secs'); - } - } else if (_value > timeUnits.mins.hour && _value < timeUnits.mins.day) { - _value = formatFixedDecimals(divide(_value, timeUnits.mins.hour), 2); - if (_value === 1) { - _unit = lang.t('time.hour'); - _unitShort = lang.t('time.hr'); - } else { - _unit = lang.t('time.hours'); - _unitShort = lang.t('time.hrs'); - } - } else if (_value >= timeUnits.mins.day) { - _value = formatFixedDecimals(divide(_value, timeUnits.mins.day), 2); - if (_value === 1) { - _unit = lang.t('time.day'); - _unitShort = lang.t('time.day'); - } else { - _unit = lang.t('time.days'); - _unitShort = lang.t('time.days'); - } - } else { - _unit = lang.t('time.minutes'); - _unitShort = lang.t('time.mins'); - } - } - } - if (short) { - return `${_value} ${_unitShort}`; - } - return `${_value} ${_unit}`; +export const getMinimalTimeUnitStringForMs = (value = 0, short = true, plural) => { + const ms = (isObjectLike(value) || isString(value)) + ? convertStringToNumber(value) + : value; + + const parsedMs = omitBy( + pick(parseMilliseconds(Number(ms)), MinimalTimeUnitWhitelist), + isZero, + ); + + const { + unit: highestResolutionUnit, + value: highestResolutionValue, + } = getHighestResolutionUnit(parsedMs); + + const label = buildLocalizedTimeUnitString({ + plural, + short, + unit: highestResolutionUnit, + }); + + return `${highestResolutionValue} ${label}`; }; diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js index ce809702457..d5688c0d017 100644 --- a/src/hoc/withGas.js +++ b/src/hoc/withGas.js @@ -1,5 +1,4 @@ import { connect } from 'react-redux'; -import { compose } from 'recompact'; import { gasUpdateGasPriceOption, gasUpdateTxFee, @@ -15,10 +14,10 @@ const mapStateToProps = ({ gas }) => ({ txFees: gas.txFees, }); -export default Component => compose( +export default Component => ( connect(mapStateToProps, { gasUpdateGasPriceOption, gasUpdateTxFee, resetGasTxFees, - }), -)(Component); + })(Component) +); diff --git a/src/languages/_english.json b/src/languages/_english.json index c35147a1cef..adcece09793 100644 --- a/src/languages/_english.json +++ b/src/languages/_english.json @@ -209,25 +209,62 @@ "generic_error": "Oops, something went wrong" }, "time": { - "ms": "ms", - "milisecond": "milisecond", - "miliseconds": "miliseconds", - "s": "s", - "sec": "sec", - "secs": "secs", - "second": "second", - "seconds": "seconds", - "min": "min", - "mins": "mins", - "minute": "minute", - "minutes": "minutes", - "hr": "hr", - "hrs": "hrs", - "hour": "hour", - "hours": "hours", - "day": "day", - "days": "days", - "now": "Now" + "days": { + "long": { + "singular": "day", + "plural": "days" + }, + "micro": "d", + "short": { + "singular": "day", + "plural": "days" + } + }, + "hours": { + "long": { + "singular": "hour", + "plural": "hours" + }, + "micro": "h", + "short": { + "singular": "hr", + "plural": "hrs" + } + }, + "milliseconds": { + "long": { + "singular": "millisecond", + "plural": "milliseconds" + }, + "micro": "ms", + "short": { + "singular": "ms", + "plural": "ms" + } + }, + "minutes": { + "long": { + "singular": "minute", + "plural": "minutes" + }, + "micro": "m", + "short": { + "singular": "min", + "plural": "mins" + } + }, + "now": "Now", + "seconds": { + "long": { + "singular": "second", + "plural": "seconds" + }, + "micro": "s", + "short": { + "singular": "sec", + "plural": "secs" + } + } }, "wallet": { "action": { diff --git a/src/languages/_french.json b/src/languages/_french.json index bfb97639a17..90f329033f5 100644 --- a/src/languages/_french.json +++ b/src/languages/_french.json @@ -180,26 +180,63 @@ "generic_error": "Oups, une erreur s’est produite" }, "time": { - "ms": "ms", - "milisecond": "milliseconde", - "miliseconds": "millisecondes", - "s": "s", - "sec": "sec", - "secs": "secs", - "second": "seconde", - "seconds": "secondes", - "min": "min", - "mins": "mins", - "minute": "minute", - "minutes": "minutes", - "hr": "h", - "hrs": "hres", - "hour": "heure", - "hours": "heures", - "day": "jour", - "days": "jours", - "now": "Maintenant" + "days": { + "long": { + "singular": "jour", + "plural": "jours" + }, + "micro": "j", + "short": { + "singular": "jour", + "plural": "jours" + } + }, + "hours": { + "long": { + "singular": "heure", + "plural": "heures" + }, + "micro": "h", + "short": { + "singular": "h", + "plural": "hres" + } + }, + "milliseconds": { + "long": { + "singular": "milliseconde", + "plural": "millisecondes" + }, + "micro": "ms", + "short": { + "singular": "ms", + "plural": "ms" + } }, + "minutes": { + "long": { + "singular": "minute", + "plural": "minutes" + }, + "micro": "m", + "short": { + "singular": "min", + "plural": "mins" + } + }, + "now": "Maintenant", + "seconds": { + "long": { + "singular": "seconde", + "plural": "secondes" + }, + "micro": "s", + "short": { + "singular": "sec", + "plural": "secs" + } + } + }, "wallet": { "action": { "cancel": "Annuler", diff --git a/src/parsers/gas.js b/src/parsers/gas.js index ce7ec8fe580..6f3ce3b3ea4 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -1,55 +1,47 @@ -import timeUnits from '../references/time-units.json'; -import ethUnits from '../references/ethereum-units.json'; -import { getTimeString } from '../helpers/time'; +import { getMinimalTimeUnitStringForMs } from '../helpers/time'; import { convertRawAmountToBalance, convertRawAmountToNativeDisplay, divide, multiply, } from '../helpers/utilities'; +import timeUnits from '../references/time-units.json'; +import ethUnits from '../references/ethereum-units.json'; /** * @desc parse ether gas prices * @param {Object} data * @param {Boolean} short - use short format or not */ -export const getFallbackGasPrices = (short = true) => { - const gasPrices = { - average: null, - fast: null, - slow: null, - }; - gasPrices.fast = defaultGasPriceFormat('fast', '0.5', '200', short); - gasPrices.average = defaultGasPriceFormat('average', '2.5', '100', short); - gasPrices.slow = defaultGasPriceFormat('slow', '2.5', '100', short); - return gasPrices; -}; +export const getFallbackGasPrices = (short = true) => ({ + average: defaultGasPriceFormat('average', '2.5', '100', short), + fast: defaultGasPriceFormat('fast', '0.5', '200', short), + slow: defaultGasPriceFormat('slow', '2.5', '100', short), +}); /** * @desc parse ether gas prices * @param {Object} data * @param {Boolean} short - use short format or not */ -export const parseGasPrices = (data, short = true) => { - if (!data) return getFallbackGasPrices(); - const gasPrices = { - average: null, - fast: null, - slow: null, - }; - gasPrices.fast = defaultGasPriceFormat('fast', data.fastWait, data.fast, short); - gasPrices.average = defaultGasPriceFormat('average', data.avgWait, data.average, short); - gasPrices.slow = defaultGasPriceFormat('slow', data.safeLowWait, data.safeLow, short); - return gasPrices; -}; +export const parseGasPrices = (data, short = true) => ( + !data + ? getFallbackGasPrices() + : ({ + average: defaultGasPriceFormat('average', data.avgWait, data.average, short), + fast: defaultGasPriceFormat('fast', data.fastWait, data.fast, short), + slow: defaultGasPriceFormat('slow', data.safeLowWait, data.safeLow, short), + }) +); const defaultGasPriceFormat = (option, timeWait, value, short) => { const timeAmount = multiply(timeWait, timeUnits.ms.minute); const valueAmount = multiply(divide(value, 10), ethUnits.gwei); + return { estimatedTime: { amount: timeAmount, - display: getTimeString(timeAmount, 'ms', short), + display: getMinimalTimeUnitStringForMs(timeAmount), }, option, value: { @@ -67,30 +59,21 @@ const defaultGasPriceFormat = (option, timeWait, value, short) => { */ export const parseTxFees = (gasPrices, priceUnit, gasLimit, nativeCurrency) => { const txFees = { - average: { txFee: null }, - fast: { txFee: null }, - slow: { txFee: null }, + average: { txFee: getTxFee(gasPrices.average.value.amount, gasLimit) }, + fast: { txFee: getTxFee(gasPrices.fast.value.amount, gasLimit) }, + slow: { txFee: getTxFee(gasPrices.slow.value.amount, gasLimit) }, }; - txFees.fast.txFee = getTxFee(gasPrices.fast.value.amount, gasLimit); - txFees.average.txFee = getTxFee(gasPrices.average.value.amount, gasLimit); - txFees.slow.txFee = getTxFee(gasPrices.slow.value.amount, gasLimit); + return convertTxFeesToNative(priceUnit, txFees, nativeCurrency); }; const getTxFee = (gasPrice, gasLimit) => { const amount = multiply(gasPrice, gasLimit); + const display = convertRawAmountToBalance(amount, { decimals: 18, symbol: 'ETH' }); + return { native: null, - value: { - amount, - display: convertRawAmountToBalance( - amount, - { - decimals: 18, - symbol: 'ETH', - }, - ), - }, + value: { amount, display }, }; }; diff --git a/src/utils/gas.js b/src/utils/gas.js index 0cd970fe005..bff51841363 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -10,7 +10,7 @@ import { } from 'lodash'; import { showActionSheetWithOptions } from './actionsheet'; -const labelOrder = ['slow', 'average', 'fast']; +const labelOrder = ['slow', 'normal', 'fast']; const showTransactionSpeedOptions = ( gasPrices, @@ -41,14 +41,19 @@ const showTransactionSpeedOptions = ( }; const formatGasSpeedItems = (gasPrices, txFees) => { - const gasItems = map(labelOrder, speed => { + const gasItems = map(labelOrder, (label) => { + let speed = label; + if (label === 'normal') { + speed = 'average'; + } + const cost = get(txFees, `[${speed}].txFee.native.value.display`); const gwei = get(gasPrices, `[${speed}].value.display`); const time = get(gasPrices, `[${speed}].estimatedTime.display`); return { gweiValue: gwei, - label: `${upperFirst(speed)}: ${cost} ~${time.slice(0, -1)}`, + label: `${upperFirst(label)}: ${cost} ~${time.slice(0, -1)}`, value: speed, }; }); diff --git a/yarn.lock b/yarn.lock index 4cadc1dac3e..aaa04f09b9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8284,6 +8284,11 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-ms@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" + integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== + parse-node-version@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" From e3bbe6cd61544564eaf3e892be85743e747bef8c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 13 Sep 2019 19:09:34 -0400 Subject: [PATCH 266/636] Create animated GasSpeedButton component --- .eslintrc | 18 ++- ios/Podfile.lock | 10 ++ package.json | 1 + .../animations/ButtonPressAnimation.js | 18 ++- .../exchange/ExchangeGasFeeButton.js | 117 -------------- src/components/exchange/index.js | 1 - src/components/gas/GasSpeedButton.js | 146 ++++++++++++++++++ src/components/gas/GasSpeedEmoji.js | 49 ++++++ src/components/gas/GasSpeedLabelPager.js | 29 ++++ src/components/gas/GasSpeedLabelPagerItem.js | 116 ++++++++++++++ src/components/gas/index.js | 4 + src/hoc/withDataInit.js | 1 + src/hoc/withGas.js | 23 ++- src/screens/ExampleScreen.js | 58 +++---- src/screens/ExchangeModal.js | 16 +- src/styles/fonts.js | 2 +- src/utils/gas.js | 7 +- yarn.lock | 81 +++++++++- 18 files changed, 506 insertions(+), 191 deletions(-) delete mode 100644 src/components/exchange/ExchangeGasFeeButton.js create mode 100644 src/components/gas/GasSpeedButton.js create mode 100644 src/components/gas/GasSpeedEmoji.js create mode 100644 src/components/gas/GasSpeedLabelPager.js create mode 100644 src/components/gas/GasSpeedLabelPagerItem.js create mode 100644 src/components/gas/index.js diff --git a/.eslintrc b/.eslintrc index f99c7e43b9f..69795e61401 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,7 @@ "parser": "babel-eslint", "plugins": [ "react", + "react-hooks", "react-native", "react-native-animation-linter" ], @@ -18,18 +19,21 @@ ], "rules" : { "arrow-body-style": "warn", + "arrow-parens": ["off"], "camelcase": ["error", {ignoreDestructuring: true}], "class-methods-use-this": "off", - "no-console": "off", - "max-len": ["error", {"code": 160, "comments": 500}], - "no-tabs": "error", "indent": ["error", 2], - "no-use-before-define": ["error", {"functions": false, "variables": false}], - "no-unused-vars": ["error", {"args": "none"}], + "max-len": ["error", {"code": 160, "comments": 500}], + "no-console": "off", + "no-nested-ternary": "error", + "no-param-reassign": ["off"], "no-plusplus": ["off"], + "no-tabs": "error", "no-underscore-dangle": ["off"], - "arrow-parens": ["off"], - "no-param-reassign": ["off"], + "no-unused-vars": ["error", {"args": "none"}], + "no-use-before-define": ["error", {"functions": false, "variables": false}], + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn", "react-native-animation-linter/must-tear-down-animations": 2, "sort-keys": ["error", "asc", {"caseSensitive": false, "natural": false}] }, diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d8bde0534b8..2e41fc9768a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -188,6 +188,7 @@ PODS: - React <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) @@ -207,6 +208,11 @@ PODS: - SDWebImage/Core (= 5.1.0) - SDWebImage/Core (5.1.0) >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= + - SDWebImage (5.1.1): + - SDWebImage/Core (= 5.1.1) + - SDWebImage/Core (5.1.1) +>>>>>>> 8f2ed039... Create animated GasSpeedButton component - yoga (0.59.9.React) >>>>>>> 730537c6... catching up with latest mike-swap-ui changes @@ -416,6 +422,7 @@ SPEC CHECKSUMS: RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 @@ -427,6 +434,9 @@ SPEC CHECKSUMS: ======= SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= + SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 +>>>>>>> 8f2ed039... Create animated GasSpeedButton component yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee >>>>>>> 730537c6... catching up with latest mike-swap-ui changes diff --git a/package.json b/package.json index e32e0ef6704..3de2e2ae0c0 100644 --- a/package.json +++ b/package.json @@ -149,6 +149,7 @@ "eslint-config-airbnb-base": "^13.2.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-react": "^7.14.3", + "eslint-plugin-react-hooks": "^2.0.1", "eslint-plugin-react-native": "^3.7.0", "eslint-plugin-react-native-animation-linter": "^0.1.2", "jest": "^24.8.0", diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index c0e9d272ec1..d1d51f74cd9 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -67,6 +67,16 @@ const AnimatedRawButton = createNativeWrapper( const NOOP = () => undefined; +const HapticFeedbackTypes = { + impactHeavy: 'impactHeavy', + impactLight: 'impactLight', + impactMedium: 'impactMedium', + notificationError: 'notificationError', + notificationSuccess: 'notificationSuccess', + notificationWarning: 'notificationWarning', + selection: 'selection', +}; + export default class ButtonPressAnimation extends PureComponent { static propTypes = { activeOpacity: PropTypes.number, @@ -77,6 +87,7 @@ export default class ButtonPressAnimation extends PureComponent { easing: PropTypes.object, enableHapticFeedback: PropTypes.bool, exclusive: PropTypes.bool, + hapticType: PropTypes.oneOf(Object.keys(HapticFeedbackTypes)), isInteraction: PropTypes.bool, onPress: PropTypes.func, scaleTo: PropTypes.number, @@ -92,6 +103,7 @@ export default class ButtonPressAnimation extends PureComponent { easing: Easing.bezier(0.25, 0.46, 0.45, 0.94), enableHapticFeedback: true, exclusive: true, + hapticType: HapticFeedbackTypes.selection, scaleTo: animations.keyframes.button.to.scale, } @@ -142,8 +154,10 @@ export default class ButtonPressAnimation extends PureComponent { } handleHaptic = () => { - if (this.props.enableHapticFeedback) { - ReactNativeHapticFeedback.trigger('selection'); + const { enableHapticFeedback, hapticType } = this.props; + + if (enableHapticFeedback) { + ReactNativeHapticFeedback.trigger(hapticType); } } diff --git a/src/components/exchange/ExchangeGasFeeButton.js b/src/components/exchange/ExchangeGasFeeButton.js deleted file mode 100644 index 1880ee07a2c..00000000000 --- a/src/components/exchange/ExchangeGasFeeButton.js +++ /dev/null @@ -1,117 +0,0 @@ -import AnimateNumber from '@bankify/react-native-animate-number'; -import { get, upperFirst } from 'lodash'; -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import { - compose, - mapProps, - withProps, -} from 'recompact'; -import { colors, padding } from '../../styles'; -import { ButtonPressAnimation } from '../animations'; -import { Nbsp } from '../html-entities'; -import { Column, Row } from '../layout'; -import { Emoji, Text } from '../text'; - -const EmojiForGasSpeedType = { - fast: 'rocket', // 🚀️ - normal: 'stopwatch', // ⏱️ - slow: 'snail', // 🐌️ -}; - -const Label = withProps({ - color: colors.alpha(colors.white, 0.4), - size: 'smedium', - weight: 'medium', -})(Text); - -const Title = withProps({ - color: colors.white, - letterSpacing: 'tight', - size: 'lmedium', - weight: 'semibold', -})(Text); - -const renderGasPriceText = (displayValue) => ( - - {displayValue} - -); - -class ExchangeGasFeeButton extends PureComponent { - static propTypes = { - estimatedTime: PropTypes.string, - label: PropTypes.string, - nativeCurrencySymbol: PropTypes.string, - onPress: PropTypes.func, - price: PropTypes.string, - } - - handlePress = (event) => { - if (this.props.onPress) { - this.props.onPress(event); - } - } - - formatAnimatedGasPrice = (gasPrice) => { - const price = parseFloat(gasPrice || '0.00').toFixed(3); - return `${this.props.nativeCurrencySymbol}${price}`; - } - - render = () => { - const { - estimatedTime, - label, - price, - } = this.props; - - return ( - - - - - - - - {upperFirst(label)} - - - - - - - - - - - - ); - } -} - -export default compose( - mapProps(({ gasPrice, ...props }) => { - let label = get(gasPrice, 'option', 'normal'); - if (label === 'average') { - label = 'normal'; - } - - return { - estimatedTime: get(gasPrice, 'estimatedTime.display', ''), - label, - price: get(gasPrice, 'txFee.native.value.amount', '0.00'), - ...props, - }; - }), -)(ExchangeGasFeeButton); diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js index 35f4e3b2217..4a6d2a08909 100644 --- a/src/components/exchange/index.js +++ b/src/components/exchange/index.js @@ -1,6 +1,5 @@ export { default as ConfirmExchangeButton } from './ConfirmExchangeButton'; export { default as ExchangeAssetList } from './ExchangeAssetList'; -export { default as ExchangeGasFeeButton } from './ExchangeGasFeeButton'; export { default as ExchangeInput } from './ExchangeInput'; export { default as ExchangeInputField } from './ExchangeInputField'; export { default as ExchangeModalHeader } from './ExchangeModalHeader'; diff --git a/src/components/gas/GasSpeedButton.js b/src/components/gas/GasSpeedButton.js new file mode 100644 index 00000000000..dd110188058 --- /dev/null +++ b/src/components/gas/GasSpeedButton.js @@ -0,0 +1,146 @@ +import AnimateNumber from '@bankify/react-native-animate-number'; +import analytics from '@segment/analytics-react-native'; +import { get } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { LayoutAnimation } from 'react-native'; +import { + compose, + mapProps, + onlyUpdateForKeys, + withProps, +} from 'recompact'; +import { withAccountSettings, withGas } from '../../hoc'; +import { colors, padding } from '../../styles'; +import { gasUtils } from '../../utils'; +import { ButtonPressAnimation } from '../animations'; +import { Column, Row } from '../layout'; +import { Text } from '../text'; +import GasSpeedLabelPager from './GasSpeedLabelPager'; + +const Label = withProps({ + color: colors.alpha(colors.white, 0.4), + size: 'smedium', + weight: 'medium', +})(Text); + +const renderEstimatedTimeText = (animatedNumber) => ( + +); + +const renderGasPriceText = (animatedNumber) => ( + + {animatedNumber} + +); + +class GasSpeedButton extends PureComponent { + static propTypes = { + estimatedTimeUnit: PropTypes.string, + estimatedTimeValue: PropTypes.string, + gasPrices: PropTypes.object, + gasUpdateGasPriceOption: PropTypes.func, + label: PropTypes.string, + nativeCurrencySymbol: PropTypes.string, + onPress: PropTypes.func, + price: PropTypes.string, + } + + getLabel = (nextLabel) => { + let label = nextLabel || this.props.label; + const shouldReverse = !!nextLabel; + + if (shouldReverse && label === 'normal') { + label = 'average'; + } else if (label === 'average') { + label = 'normal'; + } + + return label; + } + + handlePress = () => { + const { gasPrices, gasUpdateGasPriceOption } = this.props; + + LayoutAnimation.easeInEaseOut(); + + const currentSpeedIndex = gasUtils.GasSpeedTypes.indexOf(this.getLabel()); + + let nextSpeedIndex = currentSpeedIndex + 1; + if (nextSpeedIndex > (gasUtils.GasSpeedTypes.length - 1)) { + nextSpeedIndex = 0; + } + + const nextSpeed = this.getLabel(gasUtils.GasSpeedTypes[nextSpeedIndex]); + const nextSpeedGweiValue = get(gasPrices, `[${nextSpeed}].value.display`); + + gasUpdateGasPriceOption(nextSpeed); + analytics.track('Updated Gas Price', { gasPrice: nextSpeedGweiValue }); + } + + formatAnimatedGasPrice = (gasPrice) => { + const price = parseFloat(gasPrice || '0.00').toFixed(3); + return `${this.props.nativeCurrencySymbol}${price}`; + } + + formatAnimatedEstimatedTime = (estimatedTime) => { + const time = parseFloat(estimatedTime || 0).toFixed(0); + return `Swaps in ~ ${time} ${this.props.estimatedTimeUnit}`; + } + + render = () => ( + + + + + + + + + + + + + ) +} + +export default compose( + withAccountSettings, + withGas, + mapProps(({ selectedGasPrice, ...props }) => { + const estimatedTime = get(selectedGasPrice, 'estimatedTime.display', '').split(' '); + + return { + estimatedTimeUnit: estimatedTime[1] || 'min', + estimatedTimeValue: estimatedTime[0] || 0, + label: get(selectedGasPrice, 'option', 'normal'), + price: get(selectedGasPrice, 'txFee.native.value.amount', '0.00'), + ...props, + }; + }), + onlyUpdateForKeys(['estimatedTimeUnit', 'estimatedTimeValue', 'label', 'price']), +)(GasSpeedButton); diff --git a/src/components/gas/GasSpeedEmoji.js b/src/components/gas/GasSpeedEmoji.js new file mode 100644 index 00000000000..bf316116b59 --- /dev/null +++ b/src/components/gas/GasSpeedEmoji.js @@ -0,0 +1,49 @@ +import { has } from 'lodash'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { View } from 'react-primitives'; +import { onlyUpdateForKeys } from 'recompact'; +import { gasUtils } from '../../utils'; +import { Emoji } from '../text'; + +const EmojiForGasSpeedType = { + fast: { + emoji: 'rocket', // 🚀️ + position: [1, 2], // x: 1, y: 2 + }, + normal: { + emoji: 'stopwatch', // ⏱️ + position: [2, 1], // x: 2, y: 1 + }, + slow: { + emoji: 'snail', // 🐌️ + position: [1, 0], // x: 1, y: 0 + }, +}; + +const GasSpeedEmoji = ({ label }) => { + const gasSpeed = has(EmojiForGasSpeedType, label) + ? EmojiForGasSpeedType[label] + : EmojiForGasSpeedType.normal; + + return ( + + + + ); +}; + +GasSpeedEmoji.propTypes = { + label: PropTypes.oneOf(gasUtils.GasSpeedTypes), +}; + +export default onlyUpdateForKeys(['label'])(GasSpeedEmoji); diff --git a/src/components/gas/GasSpeedLabelPager.js b/src/components/gas/GasSpeedLabelPager.js new file mode 100644 index 00000000000..7806acfbd2f --- /dev/null +++ b/src/components/gas/GasSpeedLabelPager.js @@ -0,0 +1,29 @@ +import PropTypes from 'prop-types'; +import React, { useEffect, useState } from 'react'; +import { gasUtils } from '../../utils'; +import { Row } from '../layout'; +import GasSpeedLabelPagerItem from './GasSpeedLabelPagerItem'; + +const GasSpeedLabelPager = ({ label }) => { + const [touched, setTouched] = useState(false); + useEffect(() => setTouched(true), [label]); + + return ( + + {gasUtils.GasSpeedTypes.map((speed) => ( + + ))} + + ); +}; + +GasSpeedLabelPager.propTypes = { + label: PropTypes.oneOf(gasUtils.GasSpeedTypes), +}; + +export default React.memo(GasSpeedLabelPager); diff --git a/src/components/gas/GasSpeedLabelPagerItem.js b/src/components/gas/GasSpeedLabelPagerItem.js new file mode 100644 index 00000000000..14c6573588f --- /dev/null +++ b/src/components/gas/GasSpeedLabelPagerItem.js @@ -0,0 +1,116 @@ +import { upperFirst } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { useRef } from 'react'; +import Animated, { Easing, Transitioning, Transition } from 'react-native-reanimated'; +import { useTransition } from 'react-native-redash'; +import { withProps } from 'recompact'; +import { gasUtils } from '../../utils'; +import { Row } from '../layout'; +import { Text } from '../text'; +import GasSpeedEmoji from './GasSpeedEmoji'; + +const { + cond, + eq, + interpolate, + neq, +} = Animated; + +const containerStyle = { + bottom: 0, + position: 'absolute', + right: 0, + top: 0, +}; + +const GasSpeedLabel = withProps({ + color: 'white', + letterSpacing: 'tight', + size: 'lmedium', + weight: 'semibold', +})(Text); + +const distance = 20; +const duration = 150; +const height = 28; +const transition = ; + +const GasSpeedLabelPagerItem = ({ label, selected, shouldAnimate }) => { + const ref = useRef(); + if (shouldAnimate && ref.current) { + ref.current.animateNextTransition(); + } + + const index = gasUtils.GasSpeedTypes.indexOf(label); + const isFirst = index === 0; + const isLast = index === gasUtils.GasSpeedTypes.length - 1; + + const transitionVal = useTransition( + selected, + neq(selected, label), + eq(selected, label), + duration + (isFirst ? 50 : 0), + Easing.out(Easing.ease), + ); + + const defaultOpacity = cond(selected, 1, 0); + const opacity = cond( + shouldAnimate, + cond( + selected, + // animate in + interpolate(transitionVal, { + inputRange: [0, 1], + outputRange: [1, 0], + }), + // animate out + interpolate(transitionVal, { + inputRange: [0, 0.333, 1], + outputRange: [1, 0.666, 0], + }), + ), + defaultOpacity, + ); + + const defaultTranslateX = 0; + const translateX = cond( + shouldAnimate, + cond( + selected, + // animate in + interpolate(transitionVal, { + inputRange: [0, 1], + outputRange: [0, cond(isFirst, distance * -2, distance)], + }), + // animate out + interpolate(transitionVal, { + inputRange: [0, 1], + outputRange: [0, cond(isLast, distance * 2, distance * -2)], + }), + ), + defaultTranslateX, + ); + + return ( + + + + + + {upperFirst(label)} + + + + + ); +}; + +GasSpeedLabelPagerItem.propTypes = { + label: PropTypes.oneOf(gasUtils.GasSpeedTypes), + selected: PropTypes.bool, + shouldAnimate: PropTypes.bool, +}; + +GasSpeedLabelPagerItem.height = height; + +export default GasSpeedLabelPagerItem; diff --git a/src/components/gas/index.js b/src/components/gas/index.js new file mode 100644 index 00000000000..2bc10623e0e --- /dev/null +++ b/src/components/gas/index.js @@ -0,0 +1,4 @@ +export { default as GasSpeedButton } from './GasSpeedButton'; +export { default as GasSpeedEmoji } from './GasSpeedEmoji'; +export { default as GasSpeedLabelPager } from './GasSpeedLabelPager'; +export { default as GasSpeedLabelPagerItem } from './GasSpeedLabelPagerItem'; diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 48b9eb7d47d..dd30d9d1f51 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -102,6 +102,7 @@ export default Component => compose( await ownProps.uniqueTokensRefreshState(); } catch (error) { // TODO error state + console.log('Error initializing account data: ', error); } }, loadAccountData: (ownProps) => async () => { diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js index d5688c0d017..967c1cc9b9d 100644 --- a/src/hoc/withGas.js +++ b/src/hoc/withGas.js @@ -5,13 +5,22 @@ import { resetGasTxFees, } from '../redux/gas'; -const mapStateToProps = ({ gas }) => ({ - gasLimit: gas.gasLimit, - gasPrices: gas.gasPrices, - isSufficientGas: gas.isSufficientGas, - selectedGasPrice: gas.selectedGasPrice, - selectedGasPriceOption: gas.selectedGasPriceOption, - txFees: gas.txFees, +const mapStateToProps = ({ + gas: { + gasLimit, + gasPrices, + isSufficientGas, + selectedGasPrice, + selectedGasPriceOption, + txFees, + }, +}) => ({ + gasLimit, + gasPrices, + isSufficientGas, + selectedGasPrice, + selectedGasPriceOption, + txFees, }); export default Component => ( diff --git a/src/screens/ExampleScreen.js b/src/screens/ExampleScreen.js index b996b72bf7d..6f08d376b20 100644 --- a/src/screens/ExampleScreen.js +++ b/src/screens/ExampleScreen.js @@ -1,50 +1,29 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { View } from 'react-native'; -import { ExchangeCoinRow } from '../components/coin-row'; -import { Centered, Row, Page } from '../components/layout'; -import { withHideSplashScreen } from '../hoc'; -import { position } from '../styles'; - -const item = { - address: "eth", - balance: { - amount: "0.07429230016603229", - display: "0.0743 ETH", - }, - decimals: 18, - name: "Ethereum", - native: { - balance: { - amount: "17.1696934913717225419", - display: "$17.17", - }, - change: "5.28%", - price: { - amount: 231.11, - display: "$231.11", - }, - }, - price: { - changed_at: 1564999503, - relative_change_24h: 5.279701166180759, - value: 231.11, - }, - symbol: "ETH", - uniqueId: "eth", -}; +import { compose } from 'recompact'; +import { GasSpeedButton } from '../components/gas'; +import { Centered, Page } from '../components/layout'; +import { withDataInit, withAccountData } from '../hoc'; +import { colors, position } from '../styles'; class ExampleScreen extends PureComponent { static propTypes = { - onHideSplashScreen: PropTypes.func, + initializeWallet: PropTypes.func, } - componentDidMount = () => this.props.onHideSplashScreen() + componentDidMount = async () => { + try { + await this.props.initializeWallet(); + } catch (error) { + console.log('lol error on ExampleScreen like a n00b: ', error); + } + } render = () => ( {/* @@ -53,10 +32,15 @@ class ExampleScreen extends PureComponent { */} - + ) } -export default withHideSplashScreen(ExampleScreen); +export default compose( + withAccountData, + withDataInit, +)(ExampleScreen); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 716acd51662..24beb970972 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -46,13 +46,13 @@ import { } from '../utils'; import { ConfirmExchangeButton, - ExchangeGasFeeButton, ExchangeInputField, ExchangeModalHeader, ExchangeOutputField, SlippageWarning, } from '../components/exchange'; import { FloatingPanel, FloatingPanels } from '../components/expanded-state'; +import { GasSpeedButton } from '../components/gas'; import GestureBlocker from '../components/GestureBlocker'; import { Centered, @@ -91,7 +91,6 @@ class ExchangeModal extends PureComponent { isTransitioning: PropTypes.bool, keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, - nativeCurrencySymbol: PropTypes.string, navigation: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, resetGasTxFees: PropTypes.func, @@ -559,12 +558,7 @@ class ExchangeModal extends PureComponent { } render = () => { - const { - nativeCurrency, - nativeCurrencySymbol, - selectedGasPrice, - transitionPosition, - } = this.props; + const { nativeCurrency, transitionPosition } = this.props; const { inputAmountDisplay, @@ -653,11 +647,7 @@ class ExchangeModal extends PureComponent { slippage={slippage} /> - + )} diff --git a/src/styles/fonts.js b/src/styles/fonts.js index 8908805bc32..5a03de06da3 100644 --- a/src/styles/fonts.js +++ b/src/styles/fonts.js @@ -21,7 +21,7 @@ font.lineHeight = { tight: 16, normal: 20, loose: 21, - looser: 25, + looser: 26, loosest: 28, }; diff --git a/src/utils/gas.js b/src/utils/gas.js index bff51841363..f2328f0f609 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -10,7 +10,7 @@ import { } from 'lodash'; import { showActionSheetWithOptions } from './actionsheet'; -const labelOrder = ['slow', 'normal', 'fast']; +const GasSpeedTypes = ['slow', 'normal', 'fast']; const showTransactionSpeedOptions = ( gasPrices, @@ -41,7 +41,7 @@ const showTransactionSpeedOptions = ( }; const formatGasSpeedItems = (gasPrices, txFees) => { - const gasItems = map(labelOrder, (label) => { + const gasItems = map(GasSpeedTypes, (label) => { let speed = label; if (label === 'normal') { speed = 'average'; @@ -57,9 +57,10 @@ const formatGasSpeedItems = (gasPrices, txFees) => { value: speed, }; }); - return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); + return sortBy(gasItems, ({ value }) => indexOf(GasSpeedTypes, value)); }; export default { + GasSpeedTypes, showTransactionSpeedOptions, }; diff --git a/yarn.lock b/yarn.lock index aaa04f09b9d..1151409a928 100644 --- a/yarn.lock +++ b/yarn.lock @@ -233,6 +233,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" +<<<<<<< HEAD <<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" @@ -246,6 +247,9 @@ >>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes "@babel/parser@^7.6.0": +======= +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": +>>>>>>> 8f2ed039... Create animated GasSpeedButton component version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== @@ -1400,6 +1404,7 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": +<<<<<<< HEAD <<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" @@ -1429,17 +1434,28 @@ version "12.7.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04" integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== +======= + version "12.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" + integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component "@types/node@^10.3.2": - version "10.14.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.17.tgz#b96d4dd3e427382482848948041d3754d40fd5ce" - integrity sha512-p/sGgiPaathCfOtqu2fx5Mu1bcjuP8ALFg4xpGgNkcin7LwRyzUKniEHBKdcE1RPsenq5JVPIpMTJSygLboygQ== + version "10.14.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" + integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== "@types/node@^8.0.7": +<<<<<<< HEAD version "8.10.53" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.53.tgz#5fa08eef810b08b2c03073e360b54f7bad899db1" integrity sha512-aOmXdv1a1/vYUn1OT1CED8ftbkmmYbKhKGSyMDeJiidLvKRKvZUQOdXwG/wcNY7T1Qb0XTlVdiYjIq00U7pLrQ== >>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes +======= + version "8.10.54" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" + integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component "@types/q@^1.5.1": version "1.5.2" @@ -2595,6 +2611,7 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: +<<<<<<< HEAD <<<<<<< HEAD version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" @@ -2604,6 +2621,11 @@ buffer@^5.0.0: resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.2.tgz#2012872776206182480eccb2c0fba5f672a2efef" integrity sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag== >>>>>>> 011e4f4a... cleanup after merging decimal-logic +======= + version "5.4.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" + integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -3769,10 +3791,16 @@ electron-to-chromium@^1.3.191: >>>>>>> 011e4f4a... cleanup after merging decimal-logic ======= electron-to-chromium@^1.3.247: +<<<<<<< HEAD version "1.3.254" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.254.tgz#af9795b9b2af0729997331a033ddc767af758224" integrity sha512-7I5/OkgR6JKy6RFLJeru0kc0RMmmMu1UnkHBKInFKRrg1/4EQKIqOaUqITSww/SZ1LqWwp1qc/LLoIGy449eYw== >>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes +======= + version "1.3.257" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.257.tgz#35da0ad5833b27184c8298804c498a4d2f4ed27d" + integrity sha512-EcKVmUeHCZelPA0wnIaSmpAN8karKhKBwFb+xLUjSVZ8sGRE1l3fst1zQZ7KJUkyJ7H5edPd4RP94pzC9sG00A== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component elliptic@6.3.3: version "6.3.3" @@ -4041,6 +4069,11 @@ eslint-plugin-react-hooks@^1.5.1: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== +eslint-plugin-react-hooks@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.0.1.tgz#e898ec26a0a335af6f7b0ad1f0bedda7143ed756" + integrity sha512-xir+3KHKo86AasxlCV8AHRtIZPHljqCRRUYgASkbatmt0fad4+5GgC7zkT7o/06hdKM6MIwp8giHVXqBPaarHQ== + eslint-plugin-react-native-animation-linter@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react-native-animation-linter/-/eslint-plugin-react-native-animation-linter-0.1.2.tgz#07edd97544f5db7e04c640480d3683e99d264ff1" @@ -5366,6 +5399,7 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^3.1.3: +<<<<<<< HEAD <<<<<<< HEAD version "3.3.0" resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" @@ -5375,6 +5409,11 @@ immer@^3.1.3: resolved "https://registry.yarnpkg.com/immer/-/immer-3.2.1.tgz#e3070a96508ffdb7331f8bf681f2a55f8729d0cd" integrity sha512-tRu/ipavNRwxKcRSUW2jOJ6cZCitHAHdI5WdH9fYfFt35PvZXJ7GmNVR0s1ATt6DGhgQJMnu3tVtZ2C/UzTUQw== >>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes +======= + version "3.3.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" + integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component import-fresh@^2.0.0: version "2.0.0" @@ -6998,6 +7037,14 @@ merge2@^1.2.3: version "1.3.0" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +<<<<<<< HEAD +======= + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component methods@^1.1.2: version "1.1.2" @@ -7555,6 +7602,7 @@ nan@^2.12.1, nan@^2.14.0: nanoid@^2.0.3: <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD version "2.1.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" @@ -7569,6 +7617,11 @@ nanoid@^2.0.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.0.tgz#3de3dbd68cfb2f3bd52550e2bfd439cf75040eb2" integrity sha512-g5WwS+p6Cm+zQhO2YOpRbQThZVnNb7DDq74h8YDCLfAGynrEOrbx2E16dc8ciENiP1va5sqaAruqn2sN+xpkWg== >>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes +======= + version "2.1.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" + integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component nanomatch@^1.2.9: version "1.2.13" @@ -8329,6 +8382,7 @@ pascalcase@^0.1.1: integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= patch-package@^6.1.2: +<<<<<<< HEAD <<<<<<< HEAD version "6.2.0" resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.0.tgz#677de858e352b6ca4e6cb48a6efde2cec9fde566" @@ -8338,6 +8392,11 @@ patch-package@^6.1.2: resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.1.4.tgz#3a3201e9f62d2fc119a0fd115e1e5e6dbd5f0036" integrity sha512-4lKS4wKT7OEUdzyACeGJtMvz36PdzjQ3o6pRc9DFDLpA8jPlq1IWeh7yleOXv/+fJDv+bNPpnAhid35pUVHaSA== >>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes +======= + version "6.2.0" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.0.tgz#677de858e352b6ca4e6cb48a6efde2cec9fde566" + integrity sha512-HWlQflaBBMjLBfOWomfolF8aqsFDeNbSNro1JDUgYqnVvPM5OILJ9DQdwIRiKmGaOsmHvhkl1FYkvv1I9r2ZJw== +>>>>>>> 8f2ed039... Create animated GasSpeedButton component dependencies: "@yarnpkg/lockfile" "^1.1.0" chalk "^2.4.2" @@ -9072,6 +9131,11 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== +react-native-hooks@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/react-native-hooks/-/react-native-hooks-0.9.0.tgz#589fc2390296d9afe03327298dabcf0a1f350910" + integrity sha512-yqSAH0zxqjYHYPo6mPut3dEROoB5qMvsAbN3EK0MDQrWA5zdqmzgTEpS9/qwXaIyllk6hQbHxYnRTWq2uq4tJQ== + react-native-indicators@^0.13.0: version "0.13.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.13.0.tgz#001824bba194b1ca6e654d903beaf0168d4e6ac8" @@ -9359,6 +9423,7 @@ react-navigation-stack@^2.0.0-alpha.9, "react-navigation-stack@https://github.co ======= "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now version "2.0.0-alpha.10" resolved "https://github.com/react-navigation/stack#95c9fcad62fdf9f5fe3861bbf182d83d9e6b0edd" @@ -9373,6 +9438,10 @@ react-navigation-tabs@^2.3.0: ======= version "2.0.0-alpha.12" resolved "https://github.com/react-navigation/stack#143701d50532e37f54f0e027d899164fd8ede32a" +======= + version "2.0.0-alpha.13" + resolved "https://github.com/react-navigation/stack#3450a72ab624183fddaf80f54951db8ca9ccfdbd" +>>>>>>> 8f2ed039... Create animated GasSpeedButton component dependencies: react-native-safe-area-view "^0.14.6" @@ -11304,16 +11373,22 @@ type-check@~0.3.2: prelude-ls "~1.1.2" <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 8f2ed039... Create animated GasSpeedButton component type-fest@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +<<<<<<< HEAD ======= type-fest@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== >>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +======= +>>>>>>> 8f2ed039... Create animated GasSpeedButton component typedarray@^0.0.6: version "0.0.6" From 3a6353844296ffc56f8729bf67ddc75965452396 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 01:24:11 -0400 Subject: [PATCH 267/636] minor --- ios/Podfile.lock | 82 --- package.json | 2 +- src/components/exchange/ExchangeInputField.js | 8 +- src/navigation/ExchangeModalNavigator.js | 4 +- src/styles/colors.js | 2 +- yarn.lock | 572 +----------------- 6 files changed, 12 insertions(+), 658 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2e41fc9768a..1fc9cb9db4c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -59,9 +59,6 @@ PODS: - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - Protobuf (3.9.0) - React (0.60.5): - React-Core (= 0.60.5) @@ -108,17 +105,6 @@ PODS: - React-cxxreact (= 0.60.5) - React-jsi (= 0.60.5) - React-jsinspector (0.60.5) -======= - - Protobuf (3.7.0) -======= - - Protobuf (3.9.0) ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - - Protobuf (3.9.0) ->>>>>>> 011e4f4a... cleanup after merging decimal-logic - - React (0.59.9): - - React/Core (= 0.59.9) ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -132,15 +118,7 @@ PODS: - react-native-fast-image (6.1.1): - React - SDWebImage (~> 5.0) -<<<<<<< HEAD -<<<<<<< HEAD - - react-native-netinfo (4.2.1): -======= - - react-native-netinfo (4.1.5): ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - react-native-netinfo (4.2.1): ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes - React - react-native-version-number (0.3.6): - React @@ -186,35 +164,10 @@ PODS: - React - RNStoreReview (0.1.5): - React -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - SDWebImage (5.1.1): - SDWebImage/Core (= 5.1.1) - SDWebImage/Core (5.1.1) - yoga (0.60.5.React) -======= - - SDWebImage (5.0.2): - - SDWebImage/Core (= 5.0.2) - - SDWebImage/Core (5.0.2) -======= - - SDWebImage (5.1.0): - - SDWebImage/Core (= 5.1.0) - - SDWebImage/Core (5.1.0) ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - - SDWebImage (5.1.0): - - SDWebImage/Core (= 5.1.0) - - SDWebImage/Core (5.1.0) ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= - - SDWebImage (5.1.1): - - SDWebImage/Core (= 5.1.1) - - SDWebImage/Core (5.1.1) ->>>>>>> 8f2ed039... Create animated GasSpeedButton component - - yoga (0.59.9.React) ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) @@ -365,7 +318,6 @@ SPEC CHECKSUMS: FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 -<<<<<<< HEAD Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 @@ -379,27 +331,10 @@ SPEC CHECKSUMS: React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 -======= - Folly: de497beb10f102453a1afa9edbf8cf8a251890de - glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d - GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 - libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a - React: a86b92f00edbe1873a63e4a212c29b7a7ad5224f ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 -<<<<<<< HEAD -<<<<<<< HEAD - react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 -======= - react-native-netinfo: 0e563248a4b9a99c33ec29bd03c2d50767db22a6 ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e @@ -420,25 +355,8 @@ SPEC CHECKSUMS: RNReanimated: da57ffa32f04cebe2107da0b281999a01c0d1ecc RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 -======= - SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 -======= - SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - SDWebImage: fb387001955223213dde14bc08c8b73f371f8d8f ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= - SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 ->>>>>>> 8f2ed039... Create animated GasSpeedButton component - yoga: 03ff42a6f223fb88deeaed60249020d80c3091ee ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/package.json b/package.json index 3de2e2ae0c0..952fe19a008 100644 --- a/package.json +++ b/package.json @@ -245,4 +245,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 57450d930f8..9dcca8b425d 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -17,6 +17,8 @@ import ExchangeInput from './ExchangeInput'; import ExchangeNativeField from './ExchangeNativeField'; import UnlockAssetButton from './UnlockAssetButton'; +const BottomRowHeight = 32; + export default class ExchangeInputField extends Component { static propTypes = { inputAmount: PropTypes.string, @@ -123,12 +125,12 @@ export default class ExchangeInputField extends Component { diff --git a/src/navigation/ExchangeModalNavigator.js b/src/navigation/ExchangeModalNavigator.js index 1301e845ae7..0b78b523ce6 100644 --- a/src/navigation/ExchangeModalNavigator.js +++ b/src/navigation/ExchangeModalNavigator.js @@ -54,17 +54,15 @@ const ExchangeModalNavigator = createMaterialTopTabNavigator({ // I need it for changing navigationOptions dynamically // for preventing swipe down to close on CurrencySelectScreen - const EnhancedExchangeModalNavigator = React.memo(props => ); EnhancedExchangeModalNavigator.router = ExchangeModalNavigator.router; EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => { // console.log('navigation', navigation); - return ({ ...navigation.state.params, gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), }); -} +}; export default EnhancedExchangeModalNavigator; diff --git a/src/styles/colors.js b/src/styles/colors.js index 75dec0bc042..cf8cf88d9fa 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -17,8 +17,8 @@ const base = { darkGrey: '#71778a', // '113, 119, 138' dodgerBlue: '#575CFF', // '87, 92, 255' green: '#00994d', // '0, 153, 77' - grey20: '#333333', // '51, 51, 51' grey: '#a9adb9', // '169, 173, 185' + grey20: '#333333', // '51, 51, 51' headerTitle: '#aaafbd', // '170, 175, 189' lightBlue: '#c5f2ff', // '197, 242, 255' lightBlueGrey: '#F3F5F7', // '243, 245, 247' diff --git a/yarn.lock b/yarn.lock index 1151409a928..21fbe11b440 100644 --- a/yarn.lock +++ b/yarn.lock @@ -233,26 +233,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -<<<<<<< HEAD -<<<<<<< HEAD "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== -======= -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" - integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes - -"@babel/parser@^7.6.0": -======= -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": ->>>>>>> 8f2ed039... Create animated GasSpeedButton component - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" - integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -1012,11 +996,7 @@ dependencies: prop-types "^15.5.10" -<<<<<<< HEAD "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": -======= -"@react-native-community/cli-platform-android@^2.8.3": ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== @@ -1029,11 +1009,7 @@ slash "^3.0.0" xmldoc "^1.1.2" -<<<<<<< HEAD "@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": -======= -"@react-native-community/cli-platform-ios@^2.8.3": ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== @@ -1114,68 +1090,24 @@ integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== "@react-native-community/netinfo@^4.1.4": -<<<<<<< HEAD -<<<<<<< HEAD version "4.2.1" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== -"@react-navigation/core@~3.5.0": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.1.tgz#7a2339fca3496979305fb3a8ab88c2ca8d8c214d" - integrity sha512-q7NyhWVYOhVIWqL2GZKa6G78YarXaVTTtOlSDkvy4ZIggo40wZzamlnrJRvsaQX46gsgw45FAWb5SriHh8o7eA== -======= - version "4.1.5" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.1.5.tgz#4bb44842db6a1a18f00a0f061b0e3dcc638f67dd" - integrity sha512-lagdZr9UiVAccNXYfTEj+aUcPCx9ykbMe9puffeIyF3JsRuMmlu3BjHYx1klUHX7wNRmFNC8qVP0puxUt1sZ0A== -======= - version "4.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" - integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes - -<<<<<<< HEAD -"@react-navigation/core@~3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.0.tgz#73d1a12448e2bd71855e0080b95a7f51ede0cd9e" - integrity sha512-NLm24lA51R8o8c+iFnwtN9elqRzm4OJ8f1qPBCUNIYW1sb8M5yCD53vRP0fRcPFpr/6Xzs2TJMsWnnebwFp0Rw== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= "@react-navigation/core@~3.4.1": version "3.4.2" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.4.2.tgz#bec563e94fde40fbab3730cdc97f22afbb2a1498" integrity sha512-7G+iDzLSTeOUU4vVZeRZKJ+Bd7ds7ZxYNqZcB8i0KlBeQEQfR74Ounfu/p0KIEq2RiNnaE3QT7WVP3C87sebzw== ->>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now dependencies: hoist-non-react-statics "^3.3.0" path-to-regexp "^1.7.0" query-string "^6.4.2" react-is "^16.8.6" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -"@react-navigation/native@~3.6.1": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" - integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== -<<<<<<< HEAD -======= -"@react-navigation/native@~3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.0.tgz#dabf93382f75037c01dfdd2a03807e40b48a4d61" - integrity sha512-MmsEF4Gf3DD7rtZlbOLULQOBCxE2nGz6FdPYxtlEI+N/E2I5OrdxrTNAA7EGWsIiaJEapU4bp0a+tLjh/9PQpA== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= "@react-navigation/native@~3.5.0": version "3.5.0" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.5.0.tgz#f5d16e0845ac26d1147d1caa481f18a00740e7ae" integrity sha512-TmGOis++ejEXG3sqNJhCSKqB0/qLu3FQgDtO959qpqif36R/diR8SQwJqeSdofoEiK3CepdhFlTCeHdS1/+MsQ== ->>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -1404,14 +1336,11 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": -<<<<<<< HEAD -<<<<<<< HEAD version "12.7.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== "@types/node@^10.3.2": -<<<<<<< HEAD version "10.14.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== @@ -1420,42 +1349,6 @@ version "8.10.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== -======= - version "10.14.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.16.tgz#4d690c96cbb7b2728afea0e260d680501b3da5cf" - integrity sha512-/opXIbfn0P+VLt+N8DE4l8Mn8rbhiJgabU96ZJ0p9mxOkIks5gh6RUnpHak7Yh0SFkyjO/ODbxsQQPV2bpMmyA== - -"@types/node@^8.0.7": - version "8.10.52" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.52.tgz#ef0ca1809994e20186090408b8cb7f2a6877d5f9" - integrity sha512-2RbW7WXeLex6RI+kQSxq6Ym0GiVcODeQ4Km7MnnTX5BHdOGQnqVa+s6AUmAW+OFYAJ8wv9QxvNZXm7/kBdGTVw== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "12.7.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04" - integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== -======= - version "12.7.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" - integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component - -"@types/node@^10.3.2": - version "10.14.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" - integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== - -"@types/node@^8.0.7": -<<<<<<< HEAD - version "8.10.53" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.53.tgz#5fa08eef810b08b2c03073e360b54f7bad899db1" - integrity sha512-aOmXdv1a1/vYUn1OT1CED8ftbkmmYbKhKGSyMDeJiidLvKRKvZUQOdXwG/wcNY7T1Qb0XTlVdiYjIq00U7pLrQ== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes -======= - version "8.10.54" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" - integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component "@types/q@^1.5.1": version "1.5.2" @@ -1490,21 +1383,9 @@ "@types/vfile-message" "*" "@types/yargs-parser@*": -<<<<<<< HEAD -<<<<<<< HEAD - version "13.1.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" - integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== -======= - version "13.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" - integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes "@types/yargs@^13.0.0": version "13.0.2" @@ -1560,9 +1441,6 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@walletconnect/core@^1.0.0-beta.36": version "1.0.0-beta.36" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.36.tgz#671f70f739d1d9857456e45060727548317fe86a" @@ -1589,77 +1467,11 @@ version "1.0.0-beta.36" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.36.tgz#34c9def70f9db1ffcdd8e5fc94d9ce30dc716b8a" integrity sha512-SlAqiWJLs/EG+eqxqWO/zOZRz06GYBKGlfK5OX203UjOl6Ps8WLN/D7l8llX97TdGzcGw5+b9Wq+kKuWR2HFQA== -======= -"@walletconnect/core@^1.0.0-beta.33": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.33.tgz#ba8c4d1682c00630124cfacd8c3ac28a37737ffc" - integrity sha512-VnipTAEiVJx0fKR7kVKQ/KIaEDCFjIEF4wGSl73uuhp+YPBZSN0fXQ0/joF00dGUxVY6RiwmCQlmz5ZKpcGWYw== -======= -"@walletconnect/core@^1.0.0-beta.34": - version "1.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.34.tgz#76ad24610ba288a0a5f2ec146d15214fa9683261" - integrity sha512-Uu1biiWl/t/FzmHxqSK7Ij2s0tXjOF/0qV4IG4qzmfx4k2h1WR4luvF5oLTBMRsoFVSGF1M/FgYYllPEj1nfjQ== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= -"@walletconnect/core@^1.0.0-beta.35": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.35.tgz#47781b836966a1f7ef199c58e35482409a3cc3cf" - integrity sha512-VnS4exaqaNJQy6xc+HX+1psjmIjKimCir9xypbx4kMz1F8Tm8/m1bMv3h4c1Q7wyiZHsSTlMZmb64UuVhM2pqw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes - dependencies: - "@walletconnect/types" "^1.0.0-beta.35" - "@walletconnect/utils" "^1.0.0-beta.35" - -"@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.35.tgz#318d1d067cae5261755b502a3a5b27dd23c6a815" - integrity sha512-npRV1XicayiSMk84+he5JEASC5oFHkYsL2S9yuHfCVzctIGE6kIX0gpuBKUbzCxkve1yezIeaQOYfwVKlLRp5w== - dependencies: - "@walletconnect/core" "^1.0.0-beta.35" - "@walletconnect/types" "^1.0.0-beta.35" - "@walletconnect/utils" "^1.0.0-beta.35" - -"@walletconnect/types@^1.0.0-beta.35": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.35.tgz#02577da82a85361c68518350fe6139dee4a43445" - integrity sha512-xlcSt0ZdEkiYmCpuO6cleLk1MmjyMPCCT5o1/z0zcRV15uDxfb+N9J/S2uVZBoLtnBtUK1m+11sRF3KrIo9FgQ== - -<<<<<<< HEAD -<<<<<<< HEAD -"@walletconnect/utils@^1.0.0-beta.33": - version "1.0.0-beta.33" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.33.tgz#59ff7edc74608398a341264bad781f24b4cf599f" - integrity sha512-BAKV+tVoN5QGoMDzF/JleO0s80wLoeJFAsw8/IG9QCSnHi4swZsin0Zk2TRYVb+gC/ZuDmMvwMHVkmVUqz7fOg== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= -"@walletconnect/utils@^1.0.0-beta.34": - version "1.0.0-beta.34" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.34.tgz#af74d522826ecaff5d6cea85b960ba16b71a23d0" - integrity sha512-nGdcCaoL4UpSQptlxAdox5WdgGyvZms6kCu9m7TH4qxnL+nCkitQg13Y7m05o1RjzRPmf/4ukfqBrEWTz3heUQ== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= -"@walletconnect/utils@^1.0.0-beta.35": - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" - integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "@walletconnect/types" "^1.0.0-beta.36" -======= - "@walletconnect/types" "^1.0.0-beta.33" ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - "@walletconnect/types" "^1.0.0-beta.34" ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= - "@walletconnect/types" "^1.0.0-beta.35" ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -2611,21 +2423,9 @@ buffer@^4.9.1: isarray "^1.0.0" buffer@^5.0.0: -<<<<<<< HEAD -<<<<<<< HEAD - version "5.4.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" - integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== -======= - version "5.4.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.2.tgz#2012872776206182480eccb2c0fba5f672a2efef" - integrity sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -3395,21 +3195,9 @@ date-now@^0.1.4: integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= dayjs@^1.8.15: -<<<<<<< HEAD -<<<<<<< HEAD version "1.8.16" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== -======= - version "1.8.15" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.15.tgz#7121bc04e6a7f2621ed6db566be4a8aaf8c3913e" - integrity sha512-HYHCI1nohG52B45vCQg8Re3hNDZbMroWPkhz50yaX7Lu0ATyjGsTdoYZBpjED9ar6chqTx2dmSmM8A51mojnAg== ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes -======= - version "1.8.16" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" - integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic debounce@^1.2.0: version "1.2.0" @@ -3765,42 +3553,10 @@ ejs@^2.6.2: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== -<<<<<<< HEAD -<<<<<<< HEAD -electron-to-chromium@^1.3.247: - version "1.3.259" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.259.tgz#d0b14836df3c89e86fa47be67315daa642fe9d5c" - integrity sha512-NMHS8iQzAYwiFZ1jL/rNOfrZJhvoowKN5uHrbbHOeNgBT5W762wpe/SRLo9kJoTiJ4d2R8i01/NQHwndo9N5PQ== -======= -electron-to-chromium@^1.3.191: -<<<<<<< HEAD -<<<<<<< HEAD - version "1.3.229" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.229.tgz#accc9a08dd07d0a4d6c76937821bc94eb2e49eae" - integrity sha512-N6pUbSuKFBeUifxBZp9hODS1N9jFobJYW47QT2VvZIr+G5AWnHK/iG3ON9RPRGH7lHDQ6KUDVhzpNkj4ZiznoA== ->>>>>>> 730537c6... catching up with latest mike-swap-ui changes -======= - version "1.3.238" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.238.tgz#6d6496e393a709b7b186823281d49b1a5d96a6cf" - integrity sha512-k+s6EIiSTgfOm7WiMlGBMMMtBQXSui8OfLN1sXU3RohJOuLGVq0lVm7hXyDIDBcbPM0MeZabAdIPQOSEZT3ZLg== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "1.3.243" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.243.tgz#32f64f00fa121532d1d49f5c0a15fd77f52ae889" - integrity sha512-+edFdHGxLSmAKftXa5xZIg19rHkkJLiW+tRu0VMVG3RKztyeKX7d3pXf707lS6+BxB9uBun3RShbxCI1PtBAgQ== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= electron-to-chromium@^1.3.247: -<<<<<<< HEAD - version "1.3.254" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.254.tgz#af9795b9b2af0729997331a033ddc767af758224" - integrity sha512-7I5/OkgR6JKy6RFLJeru0kc0RMmmMu1UnkHBKInFKRrg1/4EQKIqOaUqITSww/SZ1LqWwp1qc/LLoIGy449eYw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes -======= - version "1.3.257" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.257.tgz#35da0ad5833b27184c8298804c498a4d2f4ed27d" - integrity sha512-EcKVmUeHCZelPA0wnIaSmpAN8karKhKBwFb+xLUjSVZ8sGRE1l3fst1zQZ7KJUkyJ7H5edPd4RP94pzC9sG00A== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component + version "1.3.260" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.260.tgz#ffd686b4810bab0e1a428e7af5f08c21fe7c1fa2" + integrity sha512-wGt+OivF1C1MPwaSv3LJ96ebNbLAWlx3HndivDDWqwIVSQxmhL17Y/YmwUdEMtS/bPyommELt47Dct0/VZNQBQ== elliptic@6.3.3: version "6.3.3" @@ -4163,21 +3919,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.1.0: -<<<<<<< HEAD -<<<<<<< HEAD version "6.4.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== -======= - version "6.2.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" - integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "6.3.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.3.0.tgz#1f1a902f67bfd4c354e7288b81e40654d927eb6a" - integrity sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4271,21 +4015,9 @@ eth-contract-metadata@^1.9.2: integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== ethers@^4.0.28, ethers@^4.0.33: -<<<<<<< HEAD -<<<<<<< HEAD - version "4.0.37" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" - integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== -======= - version "4.0.36" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.36.tgz#96519fd3cc9317f938c8ee4d22050f34e3c2ef0e" - integrity sha512-rWdchEhUyXx01GiwexH6Sha97CQ9tJdQwe6FtYKxShC7VEZV41nuKt+lzCQ4OqvQwZK5PcAKaAZv2GDsCH33SA== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= version "4.0.37" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -4404,16 +4136,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -<<<<<<< HEAD -======= -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic expect@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" @@ -5346,21 +5068,9 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: -<<<<<<< HEAD -<<<<<<< HEAD version "17.0.15" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.15.tgz#a4a378910fa06ca1c34f9e481ff6642acdb16dba" integrity sha512-d+DLqZY1G15jDhSLRtsCVd/+KAWKmcmX1bp/5RjamIhftEFDvSXVgWXXkzsBFIl41VHhBV1y5JORukgz1s3GCQ== -======= - version "17.0.12" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.12.tgz#d732a6c1131fc3b02305a8241eac25ec0d1cf663" - integrity sha512-FoYYnORcAMNznVXSpwJ1zVGL8kXcv1JUmvTqoQyuPPRncBq9rd7Mi0I/oVXkGR3YIek5dDiunvA/NGG2o+mMuw== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "17.0.14" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.14.tgz#b736fcb8c84aa84c57bfad3caac7f8b5f92d85a4" - integrity sha512-yEGSWX9UTpWQskPsFy03t8uhZh5wyZ7v9p+MCo08Sd2edTaFdg1gFA633dg9OqTxJ/z1rtCiacgOlDSBpgssgw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: "@babel/runtime" "^7.3.1" @@ -5399,21 +5109,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^3.1.3: -<<<<<<< HEAD -<<<<<<< HEAD version "3.3.0" resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== -======= - version "3.2.1" - resolved "https://registry.yarnpkg.com/immer/-/immer-3.2.1.tgz#e3070a96508ffdb7331f8bf681f2a55f8729d0cd" - integrity sha512-tRu/ipavNRwxKcRSUW2jOJ6cZCitHAHdI5WdH9fYfFt35PvZXJ7GmNVR0s1ATt6DGhgQJMnu3tVtZ2C/UzTUQw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes -======= - version "3.3.0" - resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" - integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component import-fresh@^2.0.0: version "2.0.0" @@ -6117,22 +5815,6 @@ jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== -<<<<<<< HEAD -======= - -jest-haste-map@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" - integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.11" - invariant "^2.2.4" - jest-serializer "^24.0.0-alpha.6" - jest-worker "^24.0.0-alpha.6" - micromatch "^2.3.11" - sane "^3.0.0" ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic jest-haste-map@^24.7.1, jest-haste-map@^24.9.0: version "24.9.0" @@ -6297,18 +5979,8 @@ jest-runtime@^24.9.0: slash "^2.0.0" strip-bom "^3.0.0" yargs "^13.3.0" -<<<<<<< HEAD jest-serializer@^24.4.0, jest-serializer@^24.9.0: -======= - -jest-serializer@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" - integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== - -jest-serializer@^24.0.0-alpha.6, jest-serializer@^24.4.0, jest-serializer@^24.9.0: ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== @@ -6383,17 +6055,6 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -<<<<<<< HEAD -======= -jest-worker@^24.0.0-alpha.6, jest-worker@^24.6.0, jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic jest@^24.8.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" @@ -7037,14 +6698,6 @@ merge2@^1.2.3: version "1.3.0" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== -<<<<<<< HEAD -======= - -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component methods@^1.1.2: version "1.1.2" @@ -7461,27 +7114,9 @@ minimist@~0.0.1: integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= minipass@^2.2.1, minipass@^2.3.5: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "2.5.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" - integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== -======= - version "2.4.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.4.0.tgz#38f0af94f42fb6f34d3d7d82a90e2c99cd3ff485" - integrity sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "2.5.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.0.tgz#dddb1d001976978158a05badfcbef4a771612857" - integrity sha512-9FwMVYhn6ERvMR8XFdOavRz4QK/VJV8elU1x50vYexf9lslDcWe/f4HBRxCPd185ekRSjU6CfYyJCECa/CQy7Q== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= version "2.5.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -7601,27 +7236,9 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.0.3: -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version "2.1.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" - integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== -======= - version "2.0.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.4.tgz#4889355c9ce8e24efad7c65945a4a2875ac3e8f4" - integrity sha512-sOJnBmY3TJQBVIBqKHoifuwygrocXg3NjS9rZSMnVl05XWSHK7Qxb177AIZQyMDjP86bz+yneozj/h9qsPLcCA== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= - version "2.1.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.0.tgz#3de3dbd68cfb2f3bd52550e2bfd439cf75040eb2" - integrity sha512-g5WwS+p6Cm+zQhO2YOpRbQThZVnNb7DDq74h8YDCLfAGynrEOrbx2E16dc8ciENiP1va5sqaAruqn2sN+xpkWg== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes -======= version "2.1.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.1.tgz#524fd4acd45c126e0c87cd43ab5ee8346e695df9" integrity sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component nanomatch@^1.2.9: version "1.2.13" @@ -7752,23 +7369,10 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes node-releases@^1.1.29: version "1.1.30" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== -<<<<<<< HEAD -======= -node-releases@^1.1.25: - version "1.1.28" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.28.tgz#503c3c70d0e4732b84e7aaa2925fbdde10482d4a" - integrity sha512-AQw4emh6iSXnCpDiFe0phYcThiccmkNWMZnFZ+lDJjAP8J0m2fVd59duvUUyuTirQOhIAajTFkzG6FHCLBO59g== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: semver "^5.3.0" @@ -7917,20 +7521,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes object-inspect@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== -<<<<<<< HEAD -======= ->>>>>>> 011e4f4a... cleanup after merging decimal-logic -======= ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes object-is@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" @@ -8382,21 +7977,9 @@ pascalcase@^0.1.1: integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= patch-package@^6.1.2: -<<<<<<< HEAD -<<<<<<< HEAD - version "6.2.0" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.0.tgz#677de858e352b6ca4e6cb48a6efde2cec9fde566" - integrity sha512-HWlQflaBBMjLBfOWomfolF8aqsFDeNbSNro1JDUgYqnVvPM5OILJ9DQdwIRiKmGaOsmHvhkl1FYkvv1I9r2ZJw== -======= - version "6.1.4" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.1.4.tgz#3a3201e9f62d2fc119a0fd115e1e5e6dbd5f0036" - integrity sha512-4lKS4wKT7OEUdzyACeGJtMvz36PdzjQ3o6pRc9DFDLpA8jPlq1IWeh7yleOXv/+fJDv+bNPpnAhid35pUVHaSA== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes -======= version "6.2.0" resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.0.tgz#677de858e352b6ca4e6cb48a6efde2cec9fde566" integrity sha512-HWlQflaBBMjLBfOWomfolF8aqsFDeNbSNro1JDUgYqnVvPM5OILJ9DQdwIRiKmGaOsmHvhkl1FYkvv1I9r2ZJw== ->>>>>>> 8f2ed039... Create animated GasSpeedButton component dependencies: "@yarnpkg/lockfile" "^1.1.0" chalk "^2.4.2" @@ -8732,17 +8315,6 @@ prettier@^1.17.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== -<<<<<<< HEAD -======= -pretty-format@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" - integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic pretty-format@^24.7.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" @@ -9131,11 +8703,6 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -react-native-hooks@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/react-native-hooks/-/react-native-hooks-0.9.0.tgz#589fc2390296d9afe03327298dabcf0a1f350910" - integrity sha512-yqSAH0zxqjYHYPo6mPut3dEROoB5qMvsAbN3EK0MDQrWA5zdqmzgTEpS9/qwXaIyllk6hQbHxYnRTWq2uq4tJQ== - react-native-indicators@^0.13.0: version "0.13.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.13.0.tgz#001824bba194b1ca6e654d903beaf0168d4e6ac8" @@ -9233,21 +8800,9 @@ react-native-redash@^7.5.1: use-memo-one "^1.1.1" react-native-safe-area-view@^0.14.1, react-native-safe-area-view@^0.14.6: -<<<<<<< HEAD -<<<<<<< HEAD version "0.14.8" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== -======= - version "0.14.7" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.7.tgz#e1dd1c4d25a90677df2c15347fdddb2306ba5971" - integrity sha512-fmuBYpvKDJK33bimo4JXrK2BN2CGw7nof1y1LDRgzqv+FZ3eADSDGshprN8WeQqSZjQ20hJx1CiWk28Edg/v4Q== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "0.14.8" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" - integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: hoist-non-react-statics "^2.3.1" @@ -9282,26 +8837,10 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -<<<<<<< HEAD -react-native-svg@^9.6.2: -<<<<<<< HEAD -<<<<<<< HEAD - version "9.9.3" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.9.3.tgz#5dab1a44b20b13a3f35245a286f30882b9611d66" - integrity sha512-oL4EWGEYhaXDwZw3ULxAtXXh3xao0BiUt2UdVANdGuP3jdpSWuXUmXCd2HpgppOVsHwbSuR67sFmnduXPGaxuA== -======= - version "9.6.4" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.6.4.tgz#f9ceb228efd07317a5f9c378c6b9c5e13ff50cd0" - integrity sha512-6SlbGx0vlXHyDPQXSpX+8o6bNjxKFNJsISoboAkR7YWW6hdnkMg/HJXCgT6oJC0/ClKtSO7ZPrQcK4HR65kDNg== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= -======= react-native-svg@9.7.1: ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes version "9.7.1" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.7.1.tgz#a6d270cd51f8f238de7623338211debf4ff9cf5c" integrity sha512-Yr54SyLPCdovLCJ08V7syJUe1iKrTYG9V5wB08z6lh/9FdC2R9CtBnMyz83GDLKfzUONqqH9nN1l+o61CgD3tg== ->>>>>>> 011e4f4a... cleanup after merging decimal-logic react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: version "1.4.1" @@ -9398,50 +8937,9 @@ react-navigation-drawer@~1.2.1: dependencies: react-native-tab-view "^1.2.0" -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -"react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.5.0: -======= -react-navigation-stack@^2.0.0-alpha.9: -======= -react-navigation-stack@2.0.0-alpha.9: ->>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now - version "2.0.0-alpha.9" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.9.tgz#6e0382f3f4e37235c94badf6712c7095415d4a6d" - integrity sha512-Lze5CuCDr9FtGIJyxG8e1YXbpyd77XjOgLnQN5PRG9qx7YNmAbkbybPrhsmlRVWiyosC8IEVFbnot0EDcR+O/w== - dependencies: - react-native-safe-area-view "^0.14.6" - -<<<<<<< HEAD -"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic +"react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.4.0: version "2.0.0-alpha.7" resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" -======= -react-navigation-stack@^2.0.0-alpha.9, "react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.5.0: -======= -"react-navigation-stack@https://github.com/react-navigation/stack#master", react-navigation-stack@~1.4.0: -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now - version "2.0.0-alpha.10" - resolved "https://github.com/react-navigation/stack#95c9fcad62fdf9f5fe3861bbf182d83d9e6b0edd" ->>>>>>> 011e4f4a... cleanup after merging decimal-logic - dependencies: - react-native-safe-area-view "^0.14.6" - -react-navigation-tabs@^2.3.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.2.tgz#80812254e32c5720722fed9a26b6e109ed0f4ac1" - integrity sha512-f5OlXROO6VtnvgmSBzvS+2X8+KEMjJ4JM3S3IsmHa2J1dc/ssZE9QNEjttmsNxDi79vHVNaC+oiXI9GUtb3+YA== -======= - version "2.0.0-alpha.12" - resolved "https://github.com/react-navigation/stack#143701d50532e37f54f0e027d899164fd8ede32a" -======= - version "2.0.0-alpha.13" - resolved "https://github.com/react-navigation/stack#3450a72ab624183fddaf80f54951db8ca9ccfdbd" ->>>>>>> 8f2ed039... Create animated GasSpeedButton component dependencies: react-native-safe-area-view "^0.14.6" @@ -9449,11 +8947,9 @@ react-navigation-tabs@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.3.0.tgz#0288830e6ac5157f203ee3947bc29b0d6eda66b1" integrity sha512-0LiTwXEVt7XdzVT02fvg14NMz90zfPUyw1g2mIrWA70+M56br5k6tXKrZg8NjH1MgWVz5TWBx90SI0MhD2OssA== ->>>>>>> 50ca8411... fix ‘react-navigation-tabs’ at version 2.3.0 due to breaking changes dependencies: hoist-non-react-statics "^3.3.0" react-lifecycles-compat "^3.0.4" - react-native-safe-area-view "^0.14.6" react-native-tab-view "^2.9.0" react-navigation-tabs@~1.1.4: @@ -9466,36 +8962,6 @@ react-navigation-tabs@~1.1.4: react-lifecycles-compat "^3.0.4" react-native-tab-view "^1.4.1" -<<<<<<< HEAD -react-navigation@^3.11.1: -<<<<<<< HEAD -<<<<<<< HEAD - version "3.12.1" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" - integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== - dependencies: - "@react-navigation/core" "~3.5.0" - "@react-navigation/native" "~3.6.1" -======= - version "3.12.0" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.0.tgz#31cc6c7d778c968965e86a820f12f1e1a66e20b9" - integrity sha512-Lr0l0lbZsFsajUx040I1HYm0yIfa+F9SCEeaNkS1eiey6k2G04eY5hYGZfo4i3kaMj99Yi8tuRcSN7DS0QZu8w== - dependencies: - "@react-navigation/core" "~3.5.0" - "@react-navigation/native" "~3.6.0" ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= - version "3.12.1" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.12.1.tgz#f86246e65030ab16160e9cbfa8585f3822450e38" - integrity sha512-WLjQis/A40cIMpFlw4o26nSLN+CvrZp8MGvJoL5K5H7DMZ/TdwgPa/Nm2sAQA27Hw7hOohQGj+diyxFRZi89Iw== - dependencies: - "@react-navigation/core" "~3.5.0" - "@react-navigation/native" "~3.6.1" ->>>>>>> 011e4f4a... cleanup after merging decimal-logic - react-navigation-drawer "~1.4.0" - react-navigation-stack "~1.5.0" - react-navigation-tabs "~1.2.0" -======= react-navigation@3.11.1: version "3.11.1" resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.1.tgz#ba696ad6b512088a97a20cc7e6a250c53dbddd26" @@ -9506,7 +8972,6 @@ react-navigation@3.11.1: react-navigation-drawer "~1.2.1" react-navigation-stack "~1.4.0" react-navigation-tabs "~1.1.4" ->>>>>>> 8e6e4f48... fix the react-navigation-stacks version to previous release for now react-primitives@^0.8.0: version "0.8.0" @@ -9717,22 +9182,10 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" -<<<<<<< HEAD -<<<<<<< HEAD recyclerlistview@2.0.1-alpha.1: version "2.0.1-alpha.1" resolved "https://registry.yarnpkg.com/recyclerlistview/-/recyclerlistview-2.0.1-alpha.1.tgz#881955e6917911fb54a9b272004e39e5c0d64f4a" integrity sha512-UaeJyxG9LL8lcfiAqkp0kPLxvjbYg95Dcq1U/QUvzwXU4+H2khg/LAws/FssxPX6CXNMw7BLcT2YHAhkFElqRQ== -======= -recyclerlistview@Flipkart/recyclerlistview#master: - version "2.0.13" - resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/6c191661214a53f6ba24567528f0de7902ffda6c" ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= -recyclerlistview@Flipkart/recyclerlistview#1d310dffc80d63e4303bf1213d2f6b0ce498c33a: - version "2.0.10" - resolved "https://codeload.github.com/Flipkart/recyclerlistview/tar.gz/1d310dffc80d63e4303bf1213d2f6b0ce498c33a" ->>>>>>> 011e4f4a... cleanup after merging decimal-logic dependencies: lodash.debounce "4.0.8" prop-types "15.5.8" @@ -10093,11 +9546,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -<<<<<<< HEAD rn-nodeify@10.1.0: -======= -rn-nodeify@^10.0.1: ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic version "10.1.0" resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.1.0.tgz#e36c4aa25d6bf1dbde7d9f733ab30168772d50c6" integrity sha512-EW9I7OWt1aTShdJEnnS/qoEvfb2myLee6uWcAMxJWcisn3z3DxWTTLfm5bqwn/2eYjcs6j677JLY6nL02uMaaQ== @@ -11372,23 +10821,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 8f2ed039... Create animated GasSpeedButton component type-fest@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== -<<<<<<< HEAD -======= -type-fest@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" - integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== ->>>>>>> b318d04e... begin fixing up the ExchangeModal input logic -======= ->>>>>>> 8f2ed039... Create animated GasSpeedButton component typedarray@^0.0.6: version "0.0.6" From 158431971876f1703b8ef671d7f7ddbebc55dbdb Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 27 Jun 2019 16:52:14 +0200 Subject: [PATCH 268/636] Changes to bottom ios menu --- src/components/coin-row/TransactionCoinRow.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 18291a7c571..3b03f06a58e 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -20,6 +20,7 @@ import CoinName from './CoinName'; import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; +// XXX after rebase, not sure if still needed const containerStyles = css` paddingLeft: 15; `; @@ -116,13 +117,16 @@ export default compose( ...props, })), withHandlers({ - onPressTransaction: ({ hash }) => () => { + onPressTransaction: ({ hash, item }) => () => { if (hash) { showActionSheetWithOptions({ - cancelButtonIndex: 1, - options: ['View on Etherscan', 'Cancel'], + title: `${item.status} ${item.status === "sent" ? `to ${item.to}` : `from ${item.from}`} `, + cancelButtonIndex: 2, + options: ['asdfadsf', 'View on Etherscan', 'Cancel'], }, (buttonIndex) => { if (buttonIndex === 0) { + console.log(item); + } else if (buttonIndex === 1) { const normalizedHash = hash.replace(/-.*/g, ''); Linking.openURL(`https://etherscan.io/tx/${normalizedHash}`); } From 006402075602100946467657409d6b3c04c8ba97 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 28 Jun 2019 14:48:59 +0200 Subject: [PATCH 269/636] add new modal and handle adding contact from transactions page --- src/components/coin-row/TransactionCoinRow.js | 11 +- .../expanded-state/AddContactState.js | 116 ++++++++++++++++++ .../expanded-state/TokenExpandedState.js | 4 +- .../UniqueTokenExpandedState.js | 4 +- src/components/expanded-state/index.js | 1 + src/helpers/buildWalletSections.js | 1 + src/screens/ExpandedAssetScreen.js | 5 +- src/styles/colors.js | 13 ++ 8 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 src/components/expanded-state/AddContactState.js diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 3b03f06a58e..6af095fd706 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -19,6 +19,7 @@ import BalanceText from './BalanceText'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; +import { withNavigation } from 'react-navigation'; // XXX after rebase, not sure if still needed const containerStyles = css` @@ -116,16 +117,20 @@ export default compose( pending, ...props, })), + withNavigation, withHandlers({ - onPressTransaction: ({ hash, item }) => () => { + onPressTransaction: ({ hash, item, navigation }) => () => { if (hash) { showActionSheetWithOptions({ title: `${item.status} ${item.status === "sent" ? `to ${item.to}` : `from ${item.from}`} `, cancelButtonIndex: 2, - options: ['asdfadsf', 'View on Etherscan', 'Cancel'], + options: ['Add to Contacts', 'View on Etherscan', 'Cancel'], }, (buttonIndex) => { if (buttonIndex === 0) { - console.log(item); + navigation.navigate('ExpandedAssetScreen', { + asset: item, + type: 'contact', + }); } else if (buttonIndex === 1) { const normalizedHash = hash.replace(/-.*/g, ''); Linking.openURL(`https://etherscan.io/tx/${normalizedHash}`); diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js new file mode 100644 index 00000000000..3180a6bb50a --- /dev/null +++ b/src/components/expanded-state/AddContactState.js @@ -0,0 +1,116 @@ +import { get } from 'lodash'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { InteractionManager, TextInput, KeyboardAvoidingView, View } from 'react-native'; +import { + compose, + onlyUpdateForKeys, + withHandlers, + withProps, +} from 'recompact'; +import { AssetPanel, AssetPanelAction, AssetPanelHeader } from './asset-panel'; +import FloatingPanels from './FloatingPanels'; +import { withAccountData, withAccountSettings } from '../../hoc'; +import { ethereumUtils } from '../../utils'; +import styled from 'styled-components/primitives'; +import { Input } from '../inputs'; +import { colors } from '../../styles'; + +const TopMenu = styled(View)` + justify-content: center; + align-items: center; +`; + +const Container = styled(View)` + justify-content: center; + align-items: center; + height: 100%; +`; + +const NameCircle = styled(View)` + justify-content: center; + align-items: center; + height: 60px; + width: 60px; + border-radius: 30px; + background-color: ${colors.avatar1} +`; + + +const AddContactState = ({ + onPressSend, + price, + subtitle, + title, +}) => ( + + + + + + + + + + + + + + ); + +AddContactState.propTypes = { + onPressSend: PropTypes.func, + price: PropTypes.string, + subtitle: PropTypes.string, + title: PropTypes.string, +}; + +export default compose( + withAccountData, + withAccountSettings, + withProps(({ + asset: { + address, + name, + symbol, + ...asset + }, + assets, + nativeCurrencySymbol, + }) => { + const selectedAsset = ethereumUtils.getAsset(assets, address); + return { + price: get(selectedAsset, 'native.price.display', null), + subtitle: get(selectedAsset, 'balance.display', symbol), + title: name, + }; + }), + withHandlers({ + onPressSend: ({ navigation, asset: { address } }) => () => { + navigation.goBack(); + + InteractionManager.runAfterInteractions(() => { + navigation.navigate('SendSheet', { asset: address }); + }); + }, + }), + onlyUpdateForKeys(['price', 'subtitle']), +)(AddContactState); diff --git a/src/components/expanded-state/TokenExpandedState.js b/src/components/expanded-state/TokenExpandedState.js index 54587c73014..3143c43c4df 100644 --- a/src/components/expanded-state/TokenExpandedState.js +++ b/src/components/expanded-state/TokenExpandedState.js @@ -19,7 +19,9 @@ const TokenExpandedState = ({ subtitle, title, }) => ( - + + {!!maxImageHeight && ( diff --git a/src/components/expanded-state/index.js b/src/components/expanded-state/index.js index 2582acc9818..c8cff3f975e 100644 --- a/src/components/expanded-state/index.js +++ b/src/components/expanded-state/index.js @@ -3,3 +3,4 @@ export { default as FloatingPanels } from './FloatingPanels'; export { default as InvestmentExpandedState } from './InvestmentExpandedState'; export { default as TokenExpandedState } from './TokenExpandedState'; export { default as UniqueTokenExpandedState } from './UniqueTokenExpandedState'; +export { default as AddContactState } from './AddContactState'; diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index 18dcf5cad11..c718df854e9 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -35,6 +35,7 @@ const enhanceRenderItem = compose( withNavigation, withHandlers({ onPress: ({ assetType, navigation }) => (item) => { + console.log(assetType); navigation.navigate('ExpandedAssetScreen', { asset: item, type: assetType, diff --git a/src/screens/ExpandedAssetScreen.js b/src/screens/ExpandedAssetScreen.js index b65d767a187..42e816709d2 100644 --- a/src/screens/ExpandedAssetScreen.js +++ b/src/screens/ExpandedAssetScreen.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React, { createElement } from 'react'; import { + AddContactState, InvestmentExpandedState, TokenExpandedState, UniqueTokenExpandedState, @@ -17,7 +18,9 @@ const { } = safeAreaInsetValues; const ScreenTypes = { + contact: AddContactState, token: TokenExpandedState, + // eslint-disable-next-line camelcase unique_token: UniqueTokenExpandedState, uniswap: InvestmentExpandedState, }; @@ -43,7 +46,7 @@ ExpandedAssetScreen.propTypes = { containerPadding: PropTypes.number.isRequired, onPressBackground: PropTypes.func, panelWidth: PropTypes.number, - type: PropTypes.oneOf(['token', 'unique_token', 'uniswap']), + type: PropTypes.oneOf(Object.keys(ScreenTypes)).isRequired, }; ExpandedAssetScreen.defaultProps = { diff --git a/src/styles/colors.js b/src/styles/colors.js index cf8cf88d9fa..2149186dd3c 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -41,6 +41,18 @@ const base = { white: '#ffffff', // '255, 255, 255' }; +const avatarColor = { + avatar1: '#ff494a', // '255, 73, 74' + avatar2: '#02d3ff', // '2, 211, 255' + avatar3: '#fb60c4', // '251, 96, 196' + avatar4: '#3f6aff', // '63, 106, 255' + avatar5: '#fada3d', // '250, 218, 61' + avatar6: '#b140ff', // '177, 64, 255' + avatar7: '#40ebc1', // '64, 235, 193' + avatar8: '#f46e38', // '244, 110, 56' + avatar9: '#6d7e8f', // '109, 126, 143' +} + const assetIcon = { blue: '#7dabf0', // '125, 171, 240' orange: '#f2bb3a', // '242, 187, 58' @@ -101,6 +113,7 @@ const colors = { isColorLight, sendScreen, ...base, + ...avatarColor, ...transparent, ...vendor, }; From 4e89b62f907975bea88ca4ca9b7a9ddf2866986a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 29 Jun 2019 10:20:26 +0200 Subject: [PATCH 270/636] changes to add contact modal --- .../expanded-state/AddContactState.js | 76 +++++++++++++------ 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 3180a6bb50a..f5d9179dc72 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -11,14 +11,18 @@ import { import { AssetPanel, AssetPanelAction, AssetPanelHeader } from './asset-panel'; import FloatingPanels from './FloatingPanels'; import { withAccountData, withAccountSettings } from '../../hoc'; -import { ethereumUtils } from '../../utils'; +import { ethereumUtils, deviceUtils } from '../../utils'; import styled from 'styled-components/primitives'; import { Input } from '../inputs'; import { colors } from '../../styles'; +import { Button } from '../buttons'; +import { Monospace } from '../text'; const TopMenu = styled(View)` justify-content: center; align-items: center; + width: ${deviceUtils.dimensions.width - 110}; + padding: 24px; `; const Container = styled(View)` @@ -37,44 +41,68 @@ const NameCircle = styled(View)` `; -const AddContactState = ({ - onPressSend, - price, - subtitle, - title, -}) => ( - - - +class AddContactState extends React.PureComponent { + + constructor(props) { + super(props); + + this.state = { + value: "", + }; + } + + format = (string) => ( + this.props.format + ? this.props.format(string) + : string + ) + + onChange = (event) => { + const { nativeEvent } = event; + + const value = this.format(nativeEvent.text); + console.log(value); + if (value !== this.value) { + this.setState({ value }); + } + } + + render() { + return + + + + {this.props.asset.to} + + - - - + + - ); + } +}; AddContactState.propTypes = { onPressSend: PropTypes.func, From d6ce15d58be1b804d2b53abdccf23170a676005a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 10 Jul 2019 15:32:31 +0200 Subject: [PATCH 271/636] create add contact modal --- src/components/buttons/CancelButton.js | 51 +++++++++++++ src/components/buttons/index.js | 1 + .../expanded-state/AddContactState.js | 72 +++++++++++++++---- 3 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 src/components/buttons/CancelButton.js diff --git a/src/components/buttons/CancelButton.js b/src/components/buttons/CancelButton.js new file mode 100644 index 00000000000..4c40212a25e --- /dev/null +++ b/src/components/buttons/CancelButton.js @@ -0,0 +1,51 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { pure } from 'recompact'; +import styled from 'styled-components/primitives'; +import { colors, padding } from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { Icon } from '../icons'; +import { RowWithMargins } from '../layout'; +import { Text } from '../text'; + +const Container = styled(RowWithMargins).attrs({ + align: 'center', + margin: 6, +})` + ${padding(8, 9)}; + background-color: ${colors.white}; + opacity: 0.4; +`; + +const CancelButton = ({ + icon, + iconSize, + onPress, + text, + ...props +}) => ( + + + + {text} + + + +); + +CancelButton.propTypes = { + icon: Icon.propTypes.name, + iconSize: PropTypes.number, + onPress: PropTypes.func, + text: PropTypes.string, +}; + +CancelButton.defaultProps = { + iconSize: 16, +}; + +export default pure(CancelButton); diff --git a/src/components/buttons/index.js b/src/components/buttons/index.js index 9ef6c2012f0..a2df17686c4 100644 --- a/src/components/buttons/index.js +++ b/src/components/buttons/index.js @@ -1,5 +1,6 @@ // export { default as BlockButton } from './BlockButton'; export { default as Button } from './Button'; +export { default as CancelButton } from './CancelButton'; export { default as PasteAddressButton } from './PasteAddressButton'; export { default as HoldToAuthorizeButton } from './HoldToAuthorizeButton'; // export { default as LongPressButton } from './LongPressButton'; diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index f5d9179dc72..6ec14e502dc 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -1,7 +1,7 @@ import { get } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; -import { InteractionManager, TextInput, KeyboardAvoidingView, View } from 'react-native'; +import { InteractionManager, KeyboardAvoidingView, View } from 'react-native'; import { compose, onlyUpdateForKeys, @@ -16,7 +16,10 @@ import styled from 'styled-components/primitives'; import { Input } from '../inputs'; import { colors } from '../../styles'; import { Button } from '../buttons'; -import { Monospace } from '../text'; +import { Monospace, TruncatedAddress } from '../text'; +import { Text } from 'react-primitives'; +import { abbreviations } from '../../utils'; +import { CancelButton } from '../buttons'; const TopMenu = styled(View)` justify-content: center; @@ -32,12 +35,43 @@ const Container = styled(View)` `; const NameCircle = styled(View)` - justify-content: center; - align-items: center; height: 60px; width: 60px; border-radius: 30px; background-color: ${colors.avatar1} + margin-bottom: 19px; +`; + +const FirstLetter = styled(Text)` + width: 100%; + text-align: center; + line-height: 58px; + font-size: 27px; + color: #fff; + padding-left: 2px; + font-weight: 600; +`; + +const AddressAbbreviation = styled(TruncatedAddress).attrs({ + align: 'center', + firstSectionLength: abbreviations.defaultNumCharsPerSection, + size: 'lmedium', + truncationLength: 4, + weight: 'regular', + color: colors.blueGreyDark, +})` + opacity: 0.6; + width: 100%; + margin-top: 9px; + margin-bottom: 5px; +`; + +const Divider = styled(View)` + width: 93px; + margin: 19px 0; + height: 2px; + opacity: 0.05; + background-color: ${colors.blueGreyLigter}; `; @@ -61,7 +95,6 @@ class AddContactState extends React.PureComponent { const { nativeEvent } = event; const value = this.format(nativeEvent.text); - console.log(value); if (value !== this.value) { this.setState({ value }); } @@ -75,8 +108,13 @@ class AddContactState extends React.PureComponent { - + + + {this.state.value.length > 0 && this.state.value[0].toUpperCase()} + + - - {this.props.asset.to} - - + + {this.props.navigation.goBack()}} + text="Cancel" + /> From 790226fcd0f2cf405c5c88c559cdf0b6cfd2734d Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 10 Jul 2019 16:34:33 +0200 Subject: [PATCH 272/636] sendable StickyHeader = (props) => { if(this.position) {} } --- src/components/coin-row/TransactionCoinRow.js | 3 ++- src/components/expanded-state/AddContactState.js | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 6af095fd706..8383c0ae78a 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -20,6 +20,7 @@ import CoinName from './CoinName'; import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; import { withNavigation } from 'react-navigation'; +import { abbreviations } from '../../utils'; // XXX after rebase, not sure if still needed const containerStyles = css` @@ -122,7 +123,7 @@ export default compose( onPressTransaction: ({ hash, item, navigation }) => () => { if (hash) { showActionSheetWithOptions({ - title: `${item.status} ${item.status === "sent" ? `to ${item.to}` : `from ${item.from}`} `, + title: `${item.status} ${item.status === "sent" ? `to ${abbreviations.address(item.to, 4, 10)}` : `from ${abbreviations.address(item.from, 4, 10)}`} `, cancelButtonIndex: 2, options: ['Add to Contacts', 'View on Etherscan', 'Cancel'], }, (buttonIndex) => { diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 6ec14e502dc..1e5b7873c53 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -118,11 +118,8 @@ class AddContactState extends React.PureComponent { autoFocus={true} color={colors.blueGreyDark} family={'SFProDisplay'} - - // maxLength={maxLength} - // onBlur={this.onBlur} + maxLength={20} onChange={this.onChange} - // onFocus={this.onFocus} placeholder={'Name'} size="big" textAlign={'center'} @@ -133,7 +130,7 @@ class AddContactState extends React.PureComponent { backgroundColor={this.state.value.length > 0 ? colors.appleBlue : undefined} width={215} showShadow - disabled = {!this.state.value.length > 0} + disabled={!this.state.value.length > 0} > Add Contact From ea4f737cf2190a1e2271244f9ff374f956c77383 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 11 Jul 2019 18:34:52 +0200 Subject: [PATCH 273/636] add basic logic to adding contacts --- .../expanded-state/AddContactState.js | 9 ++++++ src/handlers/commonStorage.js | 28 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 1e5b7873c53..851c41941d2 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -20,6 +20,9 @@ import { Monospace, TruncatedAddress } from '../text'; import { Text } from 'react-primitives'; import { abbreviations } from '../../utils'; import { CancelButton } from '../buttons'; +import { + addNewLocalContact, +} from '../../handlers/commonStorage'; const TopMenu = styled(View)` justify-content: center; @@ -100,6 +103,11 @@ class AddContactState extends React.PureComponent { } } + addContact = async () => { + await addNewLocalContact(this.props.asset.to, this.state.value, colors.avatar1); + this.props.navigation.goBack(); + } + render() { return 0} + onPress={this.addContact} > Add Contact diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 681fdf05ad5..8f5ebbd9940 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -584,3 +584,31 @@ export const getAppStoreReviewRequestCount = async () => { export const setAppStoreReviewRequestCount = async (newCount) => { await saveLocal('appStoreReviewRequestCount', { data: newCount }); }; + +/** + * @desc get local contacts + * @return {True|False} + */ +export const getLocalContacts = async () => { + const localContacts = await getLocal('localContacts'); + return localContacts ? localContacts.data : null; +}; + +/** + * @desc add new contact to the local contacts + * @param {String} [address] + * @param {String} [nickname] + * @param {String} [color] + * @return {Void} + */ +export const addNewLocalContact = async (address, nickname, color) => { + let contacts = await getLocalContacts(); + if (!contacts) contacts = []; + + contacts.push({ + address, + color, + nickname, + }); + await saveLocal('localContacts', { data: contacts }); +}; From 560338d4dad697efca97889c603a9d81d192d87f Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 15 Jul 2019 15:50:39 +0200 Subject: [PATCH 274/636] add finding address and showing header in bottom menu --- src/components/coin-row/TransactionCoinRow.js | 21 +++++++++++++++++-- src/handlers/commonStorage.js | 20 +++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 8383c0ae78a..25d4798b1ae 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -21,6 +21,7 @@ import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; import { withNavigation } from 'react-navigation'; import { abbreviations } from '../../utils'; +import { getSelectedLocalContact } from '../../handlers/commonStorage'; // XXX after rebase, not sure if still needed const containerStyles = css` @@ -120,10 +121,26 @@ export default compose( })), withNavigation, withHandlers({ - onPressTransaction: ({ hash, item, navigation }) => () => { + onPressTransaction: ({ hash, item, navigation }) => async () => { + let headerInfo = { + type: "", + divider: "", + address: "", + } + headerInfo.type = item.status.charAt(0).toUpperCase() + item.status.slice(1); + headerInfo.divider = item.status === "sent" ? "to" : "from"; + + const contactAddressNumber = item.status === "sent" ? item.to : item.from; + const contact = await getSelectedLocalContact(contactAddressNumber); + if (contact) { + headerInfo.address = contact.nickname; + } else { + headerInfo.address = abbreviations.address(contactAddressNumber, 4, 10); + } + if (hash) { showActionSheetWithOptions({ - title: `${item.status} ${item.status === "sent" ? `to ${abbreviations.address(item.to, 4, 10)}` : `from ${abbreviations.address(item.from, 4, 10)}`} `, + title: `${headerInfo.type} ${headerInfo.divider} ${headerInfo.address}`, cancelButtonIndex: 2, options: ['Add to Contacts', 'View on Etherscan', 'Cancel'], }, (buttonIndex) => { diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 8f5ebbd9940..c7180aa7cac 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -587,13 +587,31 @@ export const setAppStoreReviewRequestCount = async (newCount) => { /** * @desc get local contacts - * @return {True|False} + * @return {Table} */ export const getLocalContacts = async () => { const localContacts = await getLocal('localContacts'); return localContacts ? localContacts.data : null; }; +/** + * @desc get local contacts + * @param {String} [address] + * @return {True|False} + */ +export const getSelectedLocalContact = async (address) => { + const contacts = await getLocalContacts(); + contacts ? contacts : contacts = []; + console.log(contacts); + let localContact = false; + contacts.forEach(contact => { + if (contact.address == address) { + localContact = contact; + } + }); + return localContact; +}; + /** * @desc add new contact to the local contacts * @param {String} [address] From 0ede684e148707a4227f853477f7d1e2a01eebae Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 18:42:23 -0400 Subject: [PATCH 275/636] created contact affect the add contact state modal # Conflicts: # src/handlers/commonStorage.js --- src/components/coin-row/TransactionCoinRow.js | 3 ++- .../expanded-state/AddContactState.js | 23 +++++++++++++----- src/handlers/commonStorage.js | 24 ++++++++++--------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 25d4798b1ae..374f7eb5b11 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -142,11 +142,12 @@ export default compose( showActionSheetWithOptions({ title: `${headerInfo.type} ${headerInfo.divider} ${headerInfo.address}`, cancelButtonIndex: 2, - options: ['Add to Contacts', 'View on Etherscan', 'Cancel'], + options: [contact ? 'View Contact' : 'Add to Contacts', 'View on Etherscan', 'Cancel'], }, (buttonIndex) => { if (buttonIndex === 0) { navigation.navigate('ExpandedAssetScreen', { asset: item, + contact: contact, type: 'contact', }); } else if (buttonIndex === 1) { diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 851c41941d2..db15fff8262 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -88,6 +88,12 @@ class AddContactState extends React.PureComponent { }; } + componentDidMount = () => { + if (this.props.contact.nickname) { + this.setState({ value: this.props.contact.nickname}); + } + } + format = (string) => ( this.props.format ? this.props.format(string) @@ -131,21 +137,22 @@ class AddContactState extends React.PureComponent { placeholder={'Name'} size="big" textAlign={'center'} + value={this.state.value} /> - {this.props.navigation.goBack()}} + style={{ paddingTop: 11 }} + onPress={() => { this.props.navigation.goBack() }} text="Cancel" /> @@ -173,6 +180,10 @@ export default compose( symbol, ...asset }, + contact: { + nickname, + ...contact + }, assets, nativeCurrencySymbol, }) => { diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index c7180aa7cac..f4a62c5373e 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -1,5 +1,5 @@ import { differenceInMinutes } from 'date-fns'; -import { omit, pickBy } from 'lodash'; +import { find, omit, pickBy } from 'lodash'; const defaultVersion = '0.1.0'; const transactionsVersion = '0.2.0'; @@ -591,6 +591,7 @@ export const setAppStoreReviewRequestCount = async (newCount) => { */ export const getLocalContacts = async () => { const localContacts = await getLocal('localContacts'); + console.log(localContacts.data); return localContacts ? localContacts.data : null; }; @@ -600,16 +601,10 @@ export const getLocalContacts = async () => { * @return {True|False} */ export const getSelectedLocalContact = async (address) => { - const contacts = await getLocalContacts(); - contacts ? contacts : contacts = []; - console.log(contacts); - let localContact = false; - contacts.forEach(contact => { - if (contact.address == address) { - localContact = contact; - } - }); - return localContact; + let contacts = await getLocalContacts(); + if (!contacts) contacts = []; + const localContact = find(contacts, (contact) => (contact.address === address)); + return localContact || false; }; /** @@ -623,6 +618,13 @@ export const addNewLocalContact = async (address, nickname, color) => { let contacts = await getLocalContacts(); if (!contacts) contacts = []; + for (let i = 0; i < contacts.length; i++) { + if (contacts[i].address === address) { + contacts.splice(i, 1); + i--; + } + } + contacts.push({ address, color, From b9a065b25ea9cf18c2dc7f03cd9c98e92977f5ce Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 18:43:38 -0400 Subject: [PATCH 276/636] add color queue to contact book # Conflicts: # src/handlers/commonStorage.js --- src/components/coin-row/TransactionCoinRow.js | 9 ++++++- .../expanded-state/AddContactState.js | 10 ++++---- src/handlers/commonStorage.js | 13 ++++++++-- src/styles/colors.js | 24 +++++++++---------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 374f7eb5b11..9d2ad781c33 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -21,7 +21,7 @@ import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; import { withNavigation } from 'react-navigation'; import { abbreviations } from '../../utils'; -import { getSelectedLocalContact } from '../../handlers/commonStorage'; +import { getSelectedLocalContact, getNumberOfLocalContacts } from '../../handlers/commonStorage'; // XXX after rebase, not sure if still needed const containerStyles = css` @@ -132,10 +132,15 @@ export default compose( const contactAddressNumber = item.status === "sent" ? item.to : item.from; const contact = await getSelectedLocalContact(contactAddressNumber); + const contactsAmount = await getNumberOfLocalContacts(); + let contactColor = 0; + if (contact) { headerInfo.address = contact.nickname; + contactColor = contact.color; } else { headerInfo.address = abbreviations.address(contactAddressNumber, 4, 10); + contactColor = contactsAmount % 8; } if (hash) { @@ -146,6 +151,8 @@ export default compose( }, (buttonIndex) => { if (buttonIndex === 0) { navigation.navigate('ExpandedAssetScreen', { + address: contactAddressNumber, + color: contactColor, asset: item, contact: contact, type: 'contact', diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index db15fff8262..a896a2b855b 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -41,7 +41,6 @@ const NameCircle = styled(View)` height: 60px; width: 60px; border-radius: 30px; - background-color: ${colors.avatar1} margin-bottom: 19px; `; @@ -110,7 +109,7 @@ class AddContactState extends React.PureComponent { } addContact = async () => { - await addNewLocalContact(this.props.asset.to, this.state.value, colors.avatar1); + await addNewLocalContact(this.props.address, this.state.value, this.props.color); this.props.navigation.goBack(); } @@ -122,7 +121,7 @@ class AddContactState extends React.PureComponent { - + {this.state.value.length > 0 && this.state.value[0].toUpperCase()} @@ -139,7 +138,7 @@ class AddContactState extends React.PureComponent { textAlign={'center'} value={this.state.value} /> - + - { this.props.navigation.goBack() }} - text="Cancel" - /> + {!this.props.contact ? + { this.props.navigation.goBack() }} + text="Cancel" + /> : + { await deleteLocalContact(this.props.address); this.props.navigation.goBack() }} + text="Delete Contact" + /> + } diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 37edae0932a..a0e256fd1c9 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -131,6 +131,9 @@ class SendContactList extends React.Component { } render() { + let newAssets = Object.assign([], this.props.allAssets); + newAssets.reverse(); + return ( { return r1 !== r2; - }).cloneWithRows(this.props.allAssets) + }).cloneWithRows(newAssets) } layoutProvider={this._layoutProvider} /> diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 47a6429b0c7..cd15bed1099 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -592,7 +592,6 @@ export const setAppStoreReviewRequestCount = async (newCount) => { export const getLocalContacts = async () => { try { const localContacts = await getLocal('localContacts'); - console.log(localContacts.data); return localContacts ? localContacts.data : null; } catch { @@ -646,3 +645,19 @@ export const addNewLocalContact = async (address, nickname, color) => { }); await saveLocal('localContacts', { data: contacts }); }; + +/** + * @desc delete contact from the local contacts + * @param {String} [address] + * @return {Void} + */ +export const deleteLocalContact = async (address) => { + const contacts = await getLocalContacts(); + for (let i = 0; i < contacts.length; i++) { + if(contacts[i].address == address) { + contacts.splice(i, 1); + i--; + } + } + await saveLocal('localContacts', { data: contacts }); +}; \ No newline at end of file From dd162b12b9d826c6ea858438d22e0a29eae93d7e Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 16 Jul 2019 18:16:04 +0200 Subject: [PATCH 281/636] show nickname in header if recognize address --- src/components/buttons/AddContactButton.js | 58 ++++++++++++++++++ src/components/buttons/index.js | 1 + src/components/fields/AddressField.js | 43 ++++++++++++-- src/components/send/SendHeader.js | 69 ++++++++++++++-------- src/screens/SendSheet.js | 9 ++- 5 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 src/components/buttons/AddContactButton.js diff --git a/src/components/buttons/AddContactButton.js b/src/components/buttons/AddContactButton.js new file mode 100644 index 00000000000..49f55cd8e93 --- /dev/null +++ b/src/components/buttons/AddContactButton.js @@ -0,0 +1,58 @@ +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { Clipboard } from 'react-native'; +import Button from './Button'; +import { withAppState } from '../../hoc'; +import { colors } from '../../styles'; +import { isValidAddress } from '../../helpers/validators'; + +class AddContactButton extends PureComponent { + static propTypes = { + appState: PropTypes.string, + onPress: PropTypes.func.isRequired, + } + + state = { clipboardContents: null } + + componentDidMount() { + this.getClipboardContents(); + } + + componentDidUpdate(prevProps) { + if (prevProps.appState === 'background' && this.props.appState === 'active') { + this.getClipboardContents(); + } + } + + getClipboardContents = async () => Clipboard.getString().then(this.setClipboardContents) + + handlePress = () => { + if (this.state.clipboardContents) { + this.props.onPress(this.state.clipboardContents); + } + } + + setClipboardContents = async (clipboardContents) => { + if (await isValidAddress(clipboardContents)) { + this.setState({ clipboardContents }); + } + } + + render() { + const { clipboardContents } = this.state; + + return ( + + ); + } +} + +export default withAppState(AddContactButton); diff --git a/src/components/buttons/index.js b/src/components/buttons/index.js index a2df17686c4..e5ef08bd30d 100644 --- a/src/components/buttons/index.js +++ b/src/components/buttons/index.js @@ -2,6 +2,7 @@ export { default as Button } from './Button'; export { default as CancelButton } from './CancelButton'; export { default as PasteAddressButton } from './PasteAddressButton'; +export { default as AddContactButton } from './AddContactButton'; export { default as HoldToAuthorizeButton } from './HoldToAuthorizeButton'; // export { default as LongPressButton } from './LongPressButton'; export { default as CoolButton } from './CoolButton'; diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index aa86c6898fa..646558d3703 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -2,18 +2,22 @@ import { omit } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import styled from 'styled-components/primitives'; -import { Input } from '../inputs'; import { Row } from '../layout'; -import { colors } from '../../styles'; +import { colors, fonts } from '../../styles'; import { Label } from '../text'; import { isValidAddress } from '../../helpers/validators'; import { isHexString } from '../../handlers/web3'; import { abbreviations, addressUtils, isNewValueForPath } from '../../utils'; +import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; +import { TextInput } from 'react-native'; -const AddressInput = styled(Input).attrs({ family: 'SFMono' })` +const AddressInput = styled(TextInput)` flex-grow: 1; margin-top: 1; z-index: 1; + font-family: ${fonts.family.SFMono}; + font-weight: ${fonts.weight.semibold}; + font-size: ${fonts.size.bmedium}; `; const Placeholder = styled(Row)` @@ -26,12 +30,23 @@ const PlaceholderText = styled(Label)` opacity: 0.45; `; +const HeaderNameText = styled(Label)` + margin-top: 0.5px; + opacity: 1; + background-color: white; + z-index: 100; + width: 300px; + color: ${colors.appleBlue}; +`; + const formatValue = value => ( (isHexString(value) && (value.length === addressUtils.maxLength)) ? abbreviations.address(value) : value ); +let input; + export default class AddressField extends PureComponent { static propTypes = { address: PropTypes.string, @@ -42,6 +57,7 @@ export default class AddressField extends PureComponent { state = { address: '', isValid: false, + focused: true, } componentDidUpdate(prevProps, prevState) { @@ -69,13 +85,24 @@ export default class AddressField extends PureComponent { return this.setState({ isValid }); } + onBlur = () => { + this.setState({ focused: false }); + } + onPressNickName = () => { + this.setState({ focused: true }); + setTimeout(() => { + input.focus(); + }, 50); + } + render() { - const { autoFocus, ...props } = this.props; + const { autoFocus, headerName, ...props } = this.props; const { address, isValid } = this.state; return ( input = x} {...props} {...omit(Label.textProps, 'opacity')} autoCorrect={false} @@ -86,6 +113,7 @@ export default class AddressField extends PureComponent { onChangeText={this.onChangeText} selectTextOnFocus={true} value={formatValue(address)} + onBlur={this.onBlur} /> {!address && ( @@ -94,6 +122,13 @@ export default class AddressField extends PureComponent { ...) )} + {headerName.length > 0 && !this.state.focused && ( + + + {headerName} + + + )} ); } diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index fbfffb9fa83..2e3460c7864 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -8,7 +8,8 @@ import { Icon } from '../icons'; import { Row } from '../layout'; import { Label } from '../text'; import { colors, padding } from '../../styles'; -import { PasteAddressButton } from '../buttons'; +import { PasteAddressButton, AddContactButton } from '../buttons'; +import { Text } from 'react-native'; const AddressInputContainer = styled(Row).attrs({ align: 'center' })` ${padding(19, 15)} @@ -16,32 +17,50 @@ const AddressInputContainer = styled(Row).attrs({ align: 'center' })` overflow: hidden; width: 100%; `; +const Nickname = styled(Text)` + background-color: ${colors.white}; + overflow: hidden; + height: 45px; + width: 76.5%; + margin-right: -20px; + line-height: 45px; +`; -const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste }) => ( - - - - - { + let headerName = ""; + for ( let i = 0; i < contacts.length; i++ ) { + if(recipient == contacts[i].address){ + headerName = contacts[i].nickname; + } + } + + return ( + + + + + + {isValidAddress ? : } + + - - - - -); + + ) +}; SendHeader.propTypes = { onChangeAddressInput: PropTypes.func, diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index f7c4b3bdce2..a265a6f8038 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -216,8 +216,15 @@ class SendSheet extends Component { onChangeAddressInput={sendUpdateRecipient} recipient={recipient} onPressPaste={sendUpdateRecipient} + contacts={this.state.contacts} + isValidAddress={isValidAddress} /> - {showEmptyState && } + {showEmptyState && ( + + )} {showAssetList && ( Date: Tue, 16 Jul 2019 18:21:30 +0200 Subject: [PATCH 282/636] make button change depending if address appear in contacts --- src/components/buttons/AddContactButton.js | 2 +- src/components/send/SendHeader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/buttons/AddContactButton.js b/src/components/buttons/AddContactButton.js index 49f55cd8e93..b553d31e35e 100644 --- a/src/components/buttons/AddContactButton.js +++ b/src/components/buttons/AddContactButton.js @@ -49,7 +49,7 @@ class AddContactButton extends PureComponent { size="small" type="pill" > - Add + {this.props.edit ? `Edit` : `Add`} ); } diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 2e3460c7864..350e9d88ff3 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -51,7 +51,7 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr onChange={onChangeAddressInput} headerName={headerName} /> - {isValidAddress ? : } + {isValidAddress ? headerName.length > 0 ? : : } Date: Tue, 16 Jul 2019 19:18:40 +0200 Subject: [PATCH 283/636] add placeholder for contacts list if the list is empty --- src/components/send/SendContactList.js | 72 +++++++++++++++++--------- src/components/send/SendHeader.js | 12 +++-- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index a0e256fd1c9..55d57de81fa 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -22,6 +22,9 @@ import { colors } from '../../styles'; import { abbreviations } from '../../utils'; import { Monospace, TruncatedAddress } from '../text'; import { ButtonPressAnimation } from '../animations'; +import { Icon } from '../icons'; +import { Centered, Column, Row } from '../layout'; +import transitionConfig from '../../navigation/transitions'; const rowHeight = 62; @@ -45,7 +48,7 @@ const FirstLetter = styled(Text)` font-weight: 600; `; -const Column = styled(View)` +const ContactColumn = styled(View)` height: 40px; flex-direction: column; justify-content: space-between; @@ -77,19 +80,19 @@ class Avatar extends React.PureComponent { } render() { - const item = this.props; + const item = this.props; return - - - {item.nickname[0].toUpperCase()} - - - - {item.nickname} - - - - + + + {item.nickname[0].toUpperCase()} + + + + {item.nickname} + + + + } } @@ -122,8 +125,8 @@ class SendContactList extends React.Component { } } - shouldComponentUpdate (prev) { - if(this.props.allAssets !== prev.allAssets) { + shouldComponentUpdate(prev) { + if (this.props.allAssets !== prev.allAssets) { return true; } else { return false; @@ -133,18 +136,37 @@ class SendContactList extends React.Component { render() { let newAssets = Object.assign([], this.props.allAssets); newAssets.reverse(); - + return ( - { - return r1 !== r2; - }).cloneWithRows(newAssets) - } - layoutProvider={this._layoutProvider} - /> + {newAssets.length == 0 ? + + + + + + : + { + return r1 !== r2; + }).cloneWithRows(newAssets) + } + layoutProvider={this._layoutProvider} + /> + } ); }; diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 350e9d88ff3..f2dc4a20541 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React, { Fragment } from 'react'; -import { pure } from 'recompact'; +import { compose } from 'recompact'; import styled from 'styled-components/primitives'; import Divider from '../Divider'; import { AddressField } from '../fields'; @@ -10,6 +10,7 @@ import { Label } from '../text'; import { colors, padding } from '../../styles'; import { PasteAddressButton, AddContactButton } from '../buttons'; import { Text } from 'react-native'; +import { withNavigation } from 'react-navigation'; const AddressInputContainer = styled(Row).attrs({ align: 'center' })` ${padding(19, 15)} @@ -26,7 +27,7 @@ const Nickname = styled(Text)` line-height: 45px; `; -const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddress, contacts }) => { +const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddress, contacts, navigation }) => { let headerName = ""; for ( let i = 0; i < contacts.length; i++ ) { if(recipient == contacts[i].address){ @@ -51,7 +52,10 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr onChange={onChangeAddressInput} headerName={headerName} /> - {isValidAddress ? headerName.length > 0 ? : : } + {isValidAddress ? headerName.length > 0 ? + {}}/> : + {}}/> : + } Date: Wed, 17 Jul 2019 15:19:54 +0200 Subject: [PATCH 284/636] initial implementation of swipable contact list --- src/components/fields/AddressField.js | 4 +- src/components/send/SendContactList.js | 123 +++++++++++++++++-------- src/components/send/SendHeader.js | 12 ++- src/screens/SendSheet.js | 2 +- 4 files changed, 100 insertions(+), 41 deletions(-) diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 646558d3703..dc020e0cebe 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -117,7 +117,9 @@ export default class AddressField extends PureComponent { /> {!address && ( - ENS or Address ( + + ENS or Address ( + 0x ...) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 55d57de81fa..63d396e45c6 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -1,30 +1,24 @@ import lang from 'i18n-js'; import PropTypes from 'prop-types'; import React from 'react'; -import { - compose, - onlyUpdateForKeys, - shouldUpdate, - withHandlers, -} from 'recompact'; -import { buildAssetUniqueIdentifier } from '../../helpers/assets'; import { deviceUtils } from '../../utils'; import { FlyInAnimation } from '../animations'; -import { CoinRow, CollectiblesSendRow, SendCoinRow } from '../coin-row'; -import { ListFooter } from '../list'; import { View, Text } from 'react-primitives'; -import { TouchableHighlight } from 'react-native-gesture-handler'; import { RecyclerListView, LayoutProvider, DataProvider } from "recyclerlistview"; -import { LayoutAnimation } from 'react-native'; -import FastImage from 'react-native-fast-image'; import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; import { colors } from '../../styles'; import { abbreviations } from '../../utils'; -import { Monospace, TruncatedAddress } from '../text'; +import { TruncatedAddress } from '../text'; import { ButtonPressAnimation } from '../animations'; import { Icon } from '../icons'; import { Centered, Column, Row } from '../layout'; import transitionConfig from '../../navigation/transitions'; +import Swipeable from 'react-native-gesture-handler/Swipeable'; +import { RectButton } from 'react-native-gesture-handler'; +import { Animated, StyleSheet } from 'react-native'; +import { + deleteLocalContact, +} from '../../handlers/commonStorage'; const rowHeight = 62; @@ -79,21 +73,75 @@ class Avatar extends React.PureComponent { this.props.onPress(this.props.address); } + renderRightAction = (text, color, x, progress) => { + const trans = progress.interpolate({ + inputRange: [0, 1], + outputRange: [x, 0], + }); + + const pressHandler = async () => { + this.close(); + await deleteLocalContact(this.props.address); + }; + + return ( + + + {text} + + + ); + }; + + renderRightActions = progress => ( + + {this.renderRightAction('Edit', '#ffab00', 140, progress)} + {this.renderRightAction('Delete', '#dd2c00', 70, progress)} + + ); + + updateRef = ref => { + this._swipeableRow = ref; + }; + close = () => { + this._swipeableRow.close(); + }; + render() { const item = this.props; - return - - - {item.nickname[0].toUpperCase()} - - - - {item.nickname} - - - - - + return ( + + + + + {item.nickname[0].toUpperCase()} + + + + {item.nickname} + + + + + + + ) } } @@ -102,6 +150,10 @@ class SendContactList extends React.Component { constructor(args) { super(args); + + this.state = { + contacts: [], + } this._layoutProvider = new LayoutProvider((i) => { return 'COIN_ROW'; @@ -125,21 +177,18 @@ class SendContactList extends React.Component { } } - shouldComponentUpdate(prev) { - if (this.props.allAssets !== prev.allAssets) { - return true; - } else { - return false; + componentWillReceiveProps = (props) => { + let newAssets = Object.assign([], props.allAssets); + newAssets.reverse(); + if(newAssets !== this.state.contacts) { + this.setState({ contacts: newAssets }); } } render() { - let newAssets = Object.assign([], this.props.allAssets); - newAssets.reverse(); - return ( - {newAssets.length == 0 ? + {this.state.contacts.length == 0 ? - : + : { return r1 !== r2; - }).cloneWithRows(newAssets) + }).cloneWithRows(this.state.contacts) } layoutProvider={this._layoutProvider} /> diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index f2dc4a20541..6c08b34389f 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -53,8 +53,16 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr headerName={headerName} /> {isValidAddress ? headerName.length > 0 ? - {}}/> : - {}}/> : + null : + { + navigation.navigate('ExpandedAssetScreen', { + address: recipient, + color: 1, + asset: contacts[0], + contact: false, + type: 'contact', + }); + }}/> : } Date: Wed, 17 Jul 2019 15:56:04 +0200 Subject: [PATCH 285/636] initial implementation of delete button for contact list --- src/components/send/SendContactList.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 63d396e45c6..a57f173a6ca 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -15,8 +15,9 @@ import { Centered, Column, Row } from '../layout'; import transitionConfig from '../../navigation/transitions'; import Swipeable from 'react-native-gesture-handler/Swipeable'; import { RectButton } from 'react-native-gesture-handler'; -import { Animated, StyleSheet } from 'react-native'; +import { Animated, LayoutAnimation } from 'react-native'; import { + getLocalContacts, deleteLocalContact, } from '../../handlers/commonStorage'; @@ -66,6 +67,16 @@ const BottomRow = styled(TruncatedAddress).attrs({ width: 100%; `; +const NOOP = () => undefined; + +const layoutItemAnimator = { + animateDidMount: NOOP, + animateShift: NOOP, + animateWillMount: NOOP, + animateWillUnmount: NOOP, + animateWillUpdate: () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')), +}; + class Avatar extends React.PureComponent { @@ -82,6 +93,7 @@ class Avatar extends React.PureComponent { const pressHandler = async () => { this.close(); await deleteLocalContact(this.props.address); + this.props.onChange(); }; return ( @@ -146,7 +158,7 @@ class Avatar extends React.PureComponent { } class SendContactList extends React.Component { - balancesRenderItem = item => + balancesRenderItem = item => constructor(args) { super(args); @@ -177,6 +189,13 @@ class SendContactList extends React.Component { } } + onChangeContacts = async () => { + const contacts = await getLocalContacts(); + let newAssets = Object.assign([], contacts); + newAssets.reverse(); + this.setState({ contacts: newAssets }); + } + componentWillReceiveProps = (props) => { let newAssets = Object.assign([], props.allAssets); newAssets.reverse(); @@ -214,6 +233,7 @@ class SendContactList extends React.Component { }).cloneWithRows(this.state.contacts) } layoutProvider={this._layoutProvider} + // itemAnimator={layoutItemAnimator} /> } From 52b78125540d4af14df9302b1ed119e98290113f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 18:47:00 -0400 Subject: [PATCH 286/636] add small fixes to add state modal # Conflicts: # src/components/send/SendHeader.js --- .../expanded-state/AddContactState.js | 14 +------ src/components/send/SendHeader.js | 37 ++++++++++++++----- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 24226d11031..abc449b0b15 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -181,11 +181,6 @@ export default compose( withAccountData, withAccountSettings, withProps(({ - asset: { - name, - symbol, - ...asset - }, contact: { nickname, ...contact @@ -194,14 +189,7 @@ export default compose( color, assets, nativeCurrencySymbol, - }) => { - const selectedAsset = ethereumUtils.getAsset(assets, address); - return { - price: get(selectedAsset, 'native.price.display', null), - subtitle: get(selectedAsset, 'balance.display', symbol), - title: name, - }; - }), + }) => {}), withHandlers({ onPressSend: ({ navigation, asset: { address } }) => () => { navigation.goBack(); diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 6c08b34389f..a65c6949ee0 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -27,11 +27,19 @@ const Nickname = styled(Text)` line-height: 45px; `; -const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddress, contacts, navigation }) => { - let headerName = ""; - for ( let i = 0; i < contacts.length; i++ ) { - if(recipient == contacts[i].address){ - headerName = contacts[i].nickname; +const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddress, contacts, navigation, onUpdateContacts }) => { + let contactColor = 0; + let contact = { + nickname: "", + color: 0, + address: "", + } + + if( contacts ) { + for ( let i = 0; i < contacts.length; i++ ) { + if(recipient == contacts[i].address){ + contact = contacts[i]; + } } } @@ -50,10 +58,19 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr address={recipient} autoFocus onChange={onChangeAddressInput} - headerName={headerName} + headerName={contact.nickname} /> - {isValidAddress ? headerName.length > 0 ? - null : + {isValidAddress ? contact.nickname.length > 0 ? + { + navigation.navigate('ExpandedAssetScreen', { + address: recipient, + color: contact.color, + asset: [], + contact: contact, + type: 'contact', + onCloseModal: onUpdateContacts, + }); + }}/> : { navigation.navigate('ExpandedAssetScreen', { address: recipient, @@ -62,7 +79,7 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr contact: false, type: 'contact', }); - }}/> : + }}/> : } Date: Thu, 18 Jul 2019 15:47:02 +0200 Subject: [PATCH 287/636] make header list button independet of clipboard --- src/components/buttons/AddContactButton.js | 33 ++-------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/components/buttons/AddContactButton.js b/src/components/buttons/AddContactButton.js index b553d31e35e..6fc0dfcac78 100644 --- a/src/components/buttons/AddContactButton.js +++ b/src/components/buttons/AddContactButton.js @@ -12,40 +12,11 @@ class AddContactButton extends PureComponent { onPress: PropTypes.func.isRequired, } - state = { clipboardContents: null } - - componentDidMount() { - this.getClipboardContents(); - } - - componentDidUpdate(prevProps) { - if (prevProps.appState === 'background' && this.props.appState === 'active') { - this.getClipboardContents(); - } - } - - getClipboardContents = async () => Clipboard.getString().then(this.setClipboardContents) - - handlePress = () => { - if (this.state.clipboardContents) { - this.props.onPress(this.state.clipboardContents); - } - } - - setClipboardContents = async (clipboardContents) => { - if (await isValidAddress(clipboardContents)) { - this.setState({ clipboardContents }); - } - } - render() { - const { clipboardContents } = this.state; - return ( + + {!this.props.edit ? ( + + ) : ( + + + + + + )} + ); } } From ca83d249b028b0a5b7341f2377483e0d5df32eab Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 18:49:20 -0400 Subject: [PATCH 294/636] fix emoji, add toolkit, fix not responsible background, capitalize letters in AddContactState # Conflicts: # src/components/expanded-state/AddContactState.js # src/components/send/SendContactList.js --- src/components/CopyTooltip.js | 13 +- .../expanded-state/AddContactState.js | 153 ++++++++++-------- src/components/fields/AddressField.js | 5 +- src/components/send/SendContactList.js | 75 ++++++--- src/components/send/SendHeader.js | 2 - 5 files changed, 154 insertions(+), 94 deletions(-) diff --git a/src/components/CopyTooltip.js b/src/components/CopyTooltip.js index 028e84f5160..915feea2f11 100644 --- a/src/components/CopyTooltip.js +++ b/src/components/CopyTooltip.js @@ -12,6 +12,7 @@ class CopyTooltip extends PureComponent { navigation: PropTypes.object, textToCopy: PropTypes.string, tooltipText: PropTypes.string, + waitForKeyboard: PropTypes.boolean, } static defaultProps = { @@ -33,7 +34,15 @@ class CopyTooltip extends PureComponent { handleHideTooltip = () => this.tooltip.hideMenu() - handlePressIn = () => this.tooltip.showMenu() + handlePressIn = (isWaitingForKeyboard) => { + if (isWaitingForKeyboard) { + setTimeout(() => { + this.tooltip.showMenu(); + }, 300); + } else { + this.tooltip.showMenu(); + } + } handleRef = (ref) => { this.tooltip = ref; } @@ -42,7 +51,7 @@ class CopyTooltip extends PureComponent { {...this.props} actions={[{ onPress: this.handleCopy, text: this.props.tooltipText }]} activeOpacity={this.props.activeOpacity} - onPressIn={this.handlePressIn} + onPressIn={() => this.handlePressIn(this.props.waitForKeyboard)} ref={this.handleRef} underlayColor={colors.transparent} /> diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index dff2d217e5a..3d33e288120 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -1,7 +1,12 @@ import { get } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; -import { InteractionManager, KeyboardAvoidingView, View } from 'react-native'; +import { + InteractionManager, + KeyboardAvoidingView, + View, + Keyboard +} from 'react-native'; import { compose, onlyUpdateForKeys, @@ -14,7 +19,7 @@ import { withAccountData, withAccountSettings } from '../../hoc'; import { ethereumUtils, deviceUtils } from '../../utils'; import styled from 'styled-components/primitives'; import { Input } from '../inputs'; -import { colors } from '../../styles'; +import { colors, fonts } from '../../styles'; import { Button } from '../buttons'; import { Monospace, TruncatedAddress } from '../text'; import { Text } from 'react-primitives'; @@ -25,6 +30,9 @@ import { deleteLocalContact, } from '../../handlers/commonStorage'; import { ButtonPressAnimation } from '../animations'; +import CopyTooltip from '../CopyTooltip'; +import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; +import { Alert } from '../alerts'; const TopMenu = styled(View)` justify-content: center; @@ -36,7 +44,6 @@ const TopMenu = styled(View)` const Container = styled(View)` justify-content: center; align-items: center; - height: 100%; `; const NameCircle = styled(View)` @@ -52,7 +59,7 @@ const FirstLetter = styled(Text)` line-height: 58px; font-size: 27px; color: #fff; - padding-left: 2px; + padding-left: 1px; font-weight: 600; `; @@ -78,6 +85,14 @@ const Divider = styled(View)` background-color: ${colors.blueGreyLigter}; `; +const Placeholder = styled(Text)` + color: ${colors.blueGreyDark}; + font-size: ${fonts.size.big}; + font-weight: ${fonts.weight.semibold}; + opacity: 0.3; + margin-bottom: -27px; +`; + class AddContactState extends React.PureComponent { @@ -93,6 +108,7 @@ class AddContactState extends React.PureComponent { componentDidMount = () => { let newState = { color: this.props.color, + value: "", }; if (this.props.contact.nickname) { newState.value = this.props.contact.nickname; @@ -108,11 +124,8 @@ class AddContactState extends React.PureComponent { onChange = (event) => { const { nativeEvent } = event; - - const value = this.format(nativeEvent.text); - if (value !== this.value) { - this.setState({ value }); - } + let value = nativeEvent.text; + this.setState({ value }); } addContact = async () => { @@ -128,60 +141,72 @@ class AddContactState extends React.PureComponent { } render() { - return - - - - - - - - {this.state.value.length > 0 && this.state.value[0].toUpperCase()} - - - - - - - - {!this.props.contact ? - { this.props.navigation.goBack() }} - text="Cancel" - /> : - { await deleteLocalContact(this.props.address); this.props.navigation.goBack() }} - text="Delete Contact" - /> - } - - - - - + return this.props.navigation.goBack()}> + + + + + + + + + + {this.state.value.length > 0 && this.state.value.charCodeAt(0) < 55000 ? + this.state.value[0] : + this.state.value.length > 1 && this.state.value.charCodeAt(0) > 55000 && this.state.value[0] + "" + this.state.value[1]} + + + + + {this.state.value.length > 0 ? ' ' : 'Name'} + + + Keyboard.dismiss()}> + + + + + + + {!this.props.contact ? + { this.props.onCloseModal(); this.props.navigation.goBack() }} + text="Cancel" + /> : + { await deleteLocalContact(this.props.address); this.props.onCloseModal(); this.props.navigation.goBack(); Alert({title: `Success`, message: `Contact has been deleted from your address book`})}} + text="Delete Contact" + /> + } + + + + + + + } }; @@ -204,7 +229,7 @@ export default compose( color, assets, nativeCurrencySymbol, - }) => {}), + }) => { }), withHandlers({ onPressSend: ({ navigation, asset: { address } }) => () => { navigation.goBack(); diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 6c22fc43784..ad5889fd9fb 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -31,13 +31,14 @@ const PlaceholderText = styled(Label)` `; const HeaderNameText = styled(Label)` - margin-top: 0.5px; + margin-top: -0.5px; opacity: 1; background-color: white; z-index: 100; width: 300px; color: ${colors.appleBlue}; - height: 40px; + height: 22px; + line-height: 23px; `; const formatValue = value => ( diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 47a59082aff..7b163ed39ac 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -12,7 +12,7 @@ import { TruncatedAddress } from '../text'; import { ButtonPressAnimation } from '../animations'; import { Icon } from '../icons'; import { Centered, Column, Row } from '../layout'; -import transitionConfig from '../../navigation/transitions'; +import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import Swipeable from 'react-native-gesture-handler/Swipeable'; import { RectButton } from 'react-native-gesture-handler'; import { Animated, LayoutAnimation } from 'react-native'; @@ -20,6 +20,9 @@ import { getLocalContacts, deleteLocalContact, } from '../../handlers/commonStorage'; +import { withNavigation } from 'react-navigation'; +import { compose } from 'recompact'; +import { Alert } from '../alerts'; const rowHeight = 62; @@ -85,18 +88,12 @@ class Avatar extends React.PureComponent { this.props.onPress(this.props.address); } - renderRightAction = (text, color, x, progress) => { + renderRightAction = (text, color, x, progress, onPress) => { const trans = progress.interpolate({ inputRange: [0, 1], outputRange: [x, 0], }); - const pressHandler = async () => { - this.close(); - await deleteLocalContact(this.props.address); - this.props.onChange(); - }; - return ( + onPress={onPress}> {text} + }}> + {text} + ); }; + deleteHandler = async () => { + this.close(); + await deleteLocalContact(this.props.address); + Alert({title: `Success`, message: `Contact has been deleted from your address book`}) + this.props.onChange(); + }; + + editHandler = async () => { + console.log(this.props); + this.close(); + this.props.navigation.navigate('ExpandedAssetScreen', { + address: this.props.address, + color: this.props.color, + asset: [], + contact: { + address: this.props.address, + color: this.props.color, + nickname: this.props.nickname, + }, + type: 'contact', + onCloseModal: this.props.onChange, + }); + }; + renderRightActions = progress => ( - {this.renderRightAction('Edit', '#ffab00', 140, progress)} - {this.renderRightAction('Delete', '#dd2c00', 70, progress)} + {this.renderRightAction('Edit', '#ffab00', 140, progress, this.editHandler)} + {this.renderRightAction('Delete', '#dd2c00', 70, progress, this.deleteHandler)} ); @@ -143,7 +166,11 @@ class Avatar extends React.PureComponent { - {item.nickname[0].toUpperCase()} + + {item.nickname.charCodeAt(0) < 55000? + item.nickname[0] : + item.nickname.length > 1 && item.nickname.charCodeAt(0) > 55000 && item.nickname[0] + "" + item.nickname[1]} + @@ -159,7 +186,14 @@ class Avatar extends React.PureComponent { } class SendContactList extends React.Component { - balancesRenderItem = item => + balancesRenderItem = item => ( + + ); constructor(args) { super(args); @@ -190,13 +224,6 @@ class SendContactList extends React.Component { } } - onChangeContacts = async () => { - const contacts = await getLocalContacts(); - let newAssets = Object.assign([], contacts); - newAssets.reverse(); - this.setState({ contacts: newAssets }); - } - componentWillReceiveProps = (props) => { let newAssets = Object.assign([], props.allAssets); newAssets.reverse(); @@ -219,7 +246,7 @@ class SendContactList extends React.Component { { From f328afac9db4efd87468562d60306fee1aab0d90 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 23 Jul 2019 12:39:15 +0200 Subject: [PATCH 295/636] make add contact modal always avoid keyboard and add patch to tooltip --- patches/react-native-tooltip+5.2.0.patch | 13 +++++++++++++ src/components/send/SendHeader.js | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 patches/react-native-tooltip+5.2.0.patch diff --git a/patches/react-native-tooltip+5.2.0.patch b/patches/react-native-tooltip+5.2.0.patch new file mode 100644 index 00000000000..f97a6c35e86 --- /dev/null +++ b/patches/react-native-tooltip+5.2.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/react-native-tooltip/ToolTip.ios.js b/node_modules/react-native-tooltip/ToolTip.ios.js +index 83bfbfe..56bba0e 100644 +--- a/node_modules/react-native-tooltip/ToolTip.ios.js ++++ b/node_modules/react-native-tooltip/ToolTip.ios.js +@@ -65,7 +65,7 @@ export default class ToolTip extends PureComponent { + if (this.props.longPress) { + props.onLongPress = this.showMenu; + } else { +- props.onPress = this.showMenu; ++ // props.onPress = this.showMenu; + } + + return props; diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index c2977e003e3..6a55efb696f 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -9,7 +9,7 @@ import { Row } from '../layout'; import { Label } from '../text'; import { colors, padding } from '../../styles'; import { PasteAddressButton, AddContactButton } from '../buttons'; -import { Text } from 'react-native'; +import { Text, Keyboard } from 'react-native'; import { withNavigation } from 'react-navigation'; const AddressInputContainer = styled(Row).attrs({ align: 'center' })` @@ -58,6 +58,7 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr /> {isValidAddress ? contact.nickname.length > 0 ? { + Keyboard.dismiss(); navigation.navigate('ExpandedAssetScreen', { address: recipient, color: contact.color, @@ -69,7 +70,7 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr }} /> : { const contactColor = Math.floor(Math.random() * colors.avatarColor.length); - + Keyboard.dismiss(); navigation.navigate('ExpandedAssetScreen', { address: recipient, color: contactColor, From f442f2847047a37aab2ff84a2602d24ce488759b Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 23 Jul 2019 13:01:09 +0200 Subject: [PATCH 296/636] add confirmation sheet on delete --- .../expanded-state/AddContactState.js | 17 ++++++++++++++++- src/components/send/SendContactList.js | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 3d33e288120..50d4871ecd9 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -33,6 +33,7 @@ import { ButtonPressAnimation } from '../animations'; import CopyTooltip from '../CopyTooltip'; import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; import { Alert } from '../alerts'; +import { showActionSheetWithOptions } from '../../utils/actionsheet'; const TopMenu = styled(View)` justify-content: center; @@ -140,6 +141,20 @@ class AddContactState extends React.PureComponent { this.setState({ color: newColor }); } + onDeleteContact = () => { + showActionSheetWithOptions({ + cancelButtonIndex: 1, + destructiveButtonIndex: 0, + options: [`Delete ${this.state.value}`, 'Cancel'], + }, async (buttonIndex) => { + if (buttonIndex === 0) { + await deleteLocalContact(this.props.address); + this.props.onCloseModal(); + this.props.navigation.goBack(); + } + }); + } + render() { return this.props.navigation.goBack()}> @@ -196,7 +211,7 @@ class AddContactState extends React.PureComponent { /> : { await deleteLocalContact(this.props.address); this.props.onCloseModal(); this.props.navigation.goBack(); Alert({title: `Success`, message: `Contact has been deleted from your address book`})}} + onPress={this.onDeleteContact} text="Delete Contact" /> } diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 7b163ed39ac..730c5e48195 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -23,6 +23,7 @@ import { import { withNavigation } from 'react-navigation'; import { compose } from 'recompact'; import { Alert } from '../alerts'; +import { showActionSheetWithOptions } from '../../utils/actionsheet'; const rowHeight = 62; @@ -119,9 +120,17 @@ class Avatar extends React.PureComponent { deleteHandler = async () => { this.close(); - await deleteLocalContact(this.props.address); - Alert({title: `Success`, message: `Contact has been deleted from your address book`}) - this.props.onChange(); + showActionSheetWithOptions({ + cancelButtonIndex: 1, + destructiveButtonIndex: 0, + options: [`Delete ${this.props.nickname}`, 'Cancel'], + }, async (buttonIndex) => { + if (buttonIndex === 0) { + await deleteLocalContact(this.props.address); + // Alert({title: `Success`, message: `Contact has been deleted from your address book`}) + this.props.onChange(); + } + }); }; editHandler = async () => { From dc4ee558b7113cc07bfdf5dfe49e82c9bc904d71 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 23 Jul 2019 15:58:50 +0200 Subject: [PATCH 297/636] fix proptypes typo --- src/components/CopyTooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CopyTooltip.js b/src/components/CopyTooltip.js index 915feea2f11..b0ac46f989b 100644 --- a/src/components/CopyTooltip.js +++ b/src/components/CopyTooltip.js @@ -12,7 +12,7 @@ class CopyTooltip extends PureComponent { navigation: PropTypes.object, textToCopy: PropTypes.string, tooltipText: PropTypes.string, - waitForKeyboard: PropTypes.boolean, + waitForKeyboard: PropTypes.bool, } static defaultProps = { From 53fb19e54485d76474a7d83fbbaac50a07ab8190 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 23 Jul 2019 16:48:04 +0200 Subject: [PATCH 298/636] change send lins input to detect nicknames of the contacts --- src/components/fields/AddressField.js | 87 ++++++++++++--------------- src/components/send/SendHeader.js | 4 +- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index ad5889fd9fb..ca056a565be 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -30,84 +30,78 @@ const PlaceholderText = styled(Label)` opacity: 0.45; `; -const HeaderNameText = styled(Label)` - margin-top: -0.5px; - opacity: 1; - background-color: white; - z-index: 100; - width: 300px; - color: ${colors.appleBlue}; - height: 22px; - line-height: 23px; -`; - const formatValue = value => ( (isHexString(value) && (value.length === addressUtils.maxLength)) ? abbreviations.address(value) : value ); -let input; - export default class AddressField extends PureComponent { static propTypes = { address: PropTypes.string, autoFocus: PropTypes.bool, onChange: PropTypes.func.isRequired, + contacts: PropTypes.array, + currentContact: PropTypes.object, } state = { + currentContact: false, + inputValue: '', address: '', isValid: false, focused: true, forceShowNickname: false, } - componentDidUpdate(prevProps, prevState) { - // Validate 'address' whenever its value changes - if (isNewValueForPath(this.state, prevState, 'address')) { - this.validateAddress(this.state.address); - } - - // Allow component state to be overwritten by parent component through the - // use of the 'address' prop. Assume that 'address' is valid because redux handles that for us. - if (this.props.address && !this.state.address) { + componentDidUpdate(props) { + if (this.props.currentContact.nickname !== props.currentContact.nickname ) { + this.setState({ + currentContact: this.props.currentContact, + inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, + address: this.props.address, + isValid: true, + }); + } else if (this.props.address && !this.state.address) { this.setState({ + inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, address: this.props.address, isValid: true, }); } } - componentWillReceiveProps(props) { - if (props.headerName !== this.props.headerName) { - this.setState({forceShowNickname: true}); + onChange = ({ nativeEvent }) => { + const contact = this.findContactByNickname(nativeEvent.text); + if(contact) { + this.props.onChange(contact.address); + this.validateAddress(contact.address); + return true; } + this.props.onChange(nativeEvent.text); + this.validateAddress(nativeEvent.text); + return this.setState({ address: nativeEvent.text }); } - onChange = ({ nativeEvent }) => this.props.onChange(nativeEvent.text) - - onChangeText = address => this.setState({ address }) + onChangeText = inputValue => this.setState({ inputValue }); - validateAddress = async (inputValue) => { - const isValid = await isValidAddress(inputValue); + validateAddress = async (address) => { + const isValid = await isValidAddress(address); return this.setState({ isValid }); } - onBlur = () => { - this.setState({ focused: false }); - } - onPressNickName = () => { - this.setState({ focused: true, forceShowNickname: false }); - setTimeout(() => { - input.focus(); - }, 50); + findContactByNickname = (nickname) => { + for (let i = 0; i < this.props.contacts.length; i++) { + if (this.props.contacts[i].nickname == nickname) { + return this.props.contacts[i]; + } + } } render() { - const { autoFocus, headerName, ...props } = this.props; - const { address, isValid } = this.state; - + const { autoFocus, ...props } = this.props; + const { inputValue, isValid } = this.state; + return ( - {!address && ( + {!inputValue && ( ENS or Address ( @@ -133,13 +127,6 @@ export default class AddressField extends PureComponent { ...) )} - {headerName.length > 0 && (!this.state.focused || this.state.forceShowNickname) && ( - - - {headerName} - - - )} ); } diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 6a55efb696f..26de76f00a2 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -54,7 +54,9 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr address={recipient} autoFocus onChange={onChangeAddressInput} - headerName={contact.nickname} + currentContact={contact} + name={contact.nickname} + contacts={contacts} /> {isValidAddress ? contact.nickname.length > 0 ? { From 26cf3b18f8604e2ea6e1ef2d847636f7db436058 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 23 Jul 2019 18:37:18 +0200 Subject: [PATCH 299/636] add spliter to recognize emoji correctly --- package.json | 1 + src/components/expanded-state/AddContactState.js | 6 ++---- src/components/send/SendContactList.js | 5 ++--- yarn.lock | 5 +++++ 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 952fe19a008..b8bba7942cc 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "ethers": "^4.0.33", "events": "^1.1.1", "global": "^4.3.2", + "grapheme-splitter": "^1.0.4", "https-browserify": "0.0.1", "i18n-js": "^3.0.11", "i18next": "^17.0.3", diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 50d4871ecd9..ef1b1f47209 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -34,6 +34,7 @@ import CopyTooltip from '../CopyTooltip'; import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; import { Alert } from '../alerts'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; +import GraphemeSplitter from 'grapheme-splitter'; const TopMenu = styled(View)` justify-content: center; @@ -166,9 +167,7 @@ class AddContactState extends React.PureComponent { - {this.state.value.length > 0 && this.state.value.charCodeAt(0) < 55000 ? - this.state.value[0] : - this.state.value.length > 1 && this.state.value.charCodeAt(0) > 55000 && this.state.value[0] + "" + this.state.value[1]} + {new GraphemeSplitter().splitGraphemes(this.state.value)[0]} @@ -180,7 +179,6 @@ class AddContactState extends React.PureComponent { autoFocus={this.props.contact.nickname ? false : true} color={colors.blueGreyDark} family={'SFProDisplay'} - maxLength={20} onChange={this.onChange} size="big" textAlign={'center'} diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 730c5e48195..198f8745687 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -24,6 +24,7 @@ import { withNavigation } from 'react-navigation'; import { compose } from 'recompact'; import { Alert } from '../alerts'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; +import GraphemeSplitter from 'grapheme-splitter'; const rowHeight = 62; @@ -176,9 +177,7 @@ class Avatar extends React.PureComponent { - {item.nickname.charCodeAt(0) < 55000? - item.nickname[0] : - item.nickname.length > 1 && item.nickname.charCodeAt(0) > 55000 && item.nickname[0] + "" + item.nickname[1]} + {new GraphemeSplitter().splitGraphemes(item.nickname)[0]} diff --git a/yarn.lock b/yarn.lock index 21fbe11b440..26eddd7c31c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4826,6 +4826,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" From ab0ed8ba2e827f82ea807544069acc8173d64642 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 18:51:53 -0400 Subject: [PATCH 300/636] change font in header send, change styling for contacts swipable actions, add filtering for contact list, fix spacing issue # Conflicts: # src/handlers/commonStorage.js # src/screens/SendSheet.js --- src/assets/swipeToDelete.png | Bin 0 -> 1367 bytes src/assets/swipeToDelete@2x.png | Bin 0 -> 2813 bytes src/assets/swipeToDelete@3x.png | Bin 0 -> 4395 bytes src/assets/swipeToEdit.png | Bin 0 -> 1179 bytes src/assets/swipeToEdit@2x.png | Bin 0 -> 2432 bytes src/assets/swipeToEdit@3x.png | Bin 0 -> 3875 bytes .../expanded-state/AddContactState.js | 3 + src/components/fields/AddressField.js | 2 +- src/components/send/SendContactList.js | 101 +++++++++++++----- src/handlers/commonStorage.js | 26 ++++- src/helpers/emojiHandler.js | 25 +++++ src/screens/SendSheet.js | 95 ++++++++++++---- 12 files changed, 200 insertions(+), 52 deletions(-) create mode 100755 src/assets/swipeToDelete.png create mode 100755 src/assets/swipeToDelete@2x.png create mode 100755 src/assets/swipeToDelete@3x.png create mode 100755 src/assets/swipeToEdit.png create mode 100755 src/assets/swipeToEdit@2x.png create mode 100755 src/assets/swipeToEdit@3x.png create mode 100644 src/helpers/emojiHandler.js diff --git a/src/assets/swipeToDelete.png b/src/assets/swipeToDelete.png new file mode 100755 index 0000000000000000000000000000000000000000..974666e83bc12a03d2f3ea4590c970d7daac03a3 GIT binary patch literal 1367 zcmV-d1*rOoP)500001b5ch_0Itp) z=>Px)5lKWrR9FeMSWReLRTMtwy-6mWi7spf+dz%t54O595sN}aH%<~`z6 z;#NY`Mcqle6C?)eMrujgG+iiI1QnWKL8um#6cMVMCQ!(XB$;`~@0>U9XXd?^dBOBT za?d?~_j~7_d+)i!w8JJtLywb3V=#M?SPqa-A2IJme~Ui;LHH;-2#; z%fv*PR#)F6;ny+YLwRgWhv|2Ko1s$aG@m{DZzsEL!N~ZyOSRf0zWPHFxv!J6OgS?m zMpHB}Fw4`^UY1@a7y!AKsXAQMo*hD6OU0rh<{m=o2Jc7huqzX7oRK zE7aZf5}!Z+Tf3hG7z0A}9}$te+Ld>4e48A8x;?>Lz}V8PSC=qpe~yV)kOvo$pw&>< zqY~)hoJqbyz2(99l7(O_S*x|nxpIX0FDjP~!_j&Oq)FJ$yR~`^!~S+zV$6J*1_xdU zlDZHo*sjT)tlugSsf-*W@!m2Yj6KIR!)MNXDK8FvgXp{+`pzOmo}=aE;}FlNilhJR zYdo1&I$vupjWk|`^-=p%$0Enfo+({ zyRT5Ud!6U!R{|e-dwlf+s39bsvQAAS>0;cq7WDW$wZTnWIHQ1$t@j=G7 zcKjoO z#F|TPp z&OKa|7J*O_5u!DXzfABQL^6_RQQd`k$I3ru+)X)}>-x@7re{aSw!9yi0DLFcdN-jA z^>+vH7oGG?9y!;^is9~x8{2Mb=1jxM8yTD52jlW7?2gWf%odl6Pb()XJBNlQal3vVQ%jN#e~cn}Dk(_kpftfG z@=m(6$#r-VKCRM=uKrSKmey;p!T4yVvC#Wcsce$C*N7XEt>-e%ug6f5zLBY;0WQ3bSI{x?s6=(|1P+4ZNN%fj)ASNN z{e6a__oKT7wxxhr~%>?(nm+|Y>pp~pzDQbbHb&-`L_FK%d-g#Ne5%(9T Z{{!^kxZjCwOAr76002ovPDHLkV1k2Tk@Wxo literal 0 HcmV?d00001 diff --git a/src/assets/swipeToDelete@2x.png b/src/assets/swipeToDelete@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..2a3b0814630ba78042b5db266a5c25d575c61d4e GIT binary patch literal 2813 zcmVPxhhccEJ>H8G)~ z#OPlne#W#Bvx?CeV>De&Obks8)(V&i3oIIhQpDOWMyoLfgsrtS7SL+3<@?QCe|O&8 znL9K0&6}^c?mEfad*^)JbI(2J%)NK+EYmn%V$GVxWZTO~@FHTdn26_-5HnDA5mOiH zf|%ceN^hb5ChDgEKS{zmK~pL(^6uSZV^4sE0_ryHI<~uR_Kl zvaAuh<(9oXG<3C)yaeX97)JE<-3dc%!tWt;>d^P`yG1oIBE_(|TkZ#2IkGiRxW z5v$j%CUUmG7%R=qwF$~}7+$m$20Bt!3#AxF^!G0(+xae(T2_`~x#Tb(rD|m}4-fw_ z7r(|-$S??*Zsd@!A$fiRrKQRJUsmf#*iTTkItT;FM4s!)Z5Ywpdl#NA&lFCmxztX@ z^a{M^VcxsMkZQ1{qm1s zl%7_CCJ$cp(&*^6R{ACyhI;!SgOxF@FY#i&jCsZuOy!r-%6e3HVeuSB^QZ=vyqH*)cnR?yx^9035ZIVrzC1G`1htthxKXz@wACp^!6RZ z0NtBQe6_L?%LR9^f>5eEkLD64nFQbD&XRKrD3MW!n{rEYoK1??^%!?I-*(Qz(p?IX zxn$Z6o}Uv{Y^qt$^PW9_&MYGb1Lj=w=$Z`=u`v;4gpyd7LyTg%K<}LWE`I8%D~%ju z+YcZ%^BYBq6*Pdq_#wsAozJ5_E{36c{dN-052OlGiGtU3I)8pGWbE`p$-?e_iI)(a zCTVh(Db}wyE-~aP-t}AqBUZx}_@*0Bcq!qO`+7!juWZLNjOZ~oninWIrmUCT&(Yf# zPok4kbkSnnx;ZrV^6NX={#o2ax^2CWgLVEQHI-wEi8=UBE)6c z)Bm`#b>|+mGZh-nrz=;&bEV7IdVuQ&ZW=t`!+I~E-vZ#4;5P-4a-WWK>s+!0vSHHVGw*=&I)WIM`}?{_5?OV@)aWJl%sbxL5xH>j%FAN zWGFU4nnx*M!BPkqhG{`TF>!WND3R7F4s|xpuR}r}<6P8HZoT{*BNr44EF`rVvBru6 z;-knMbSjg_=-yR{dkk^Bt)lwFCI}@Q+9~^Lm1DAa4B0nm>ctHsD4fVO;`~+alA%<- zVc0N=dX6E|JDaS(9!f$BN5#c$Fbr&>KPFXE#Y^KT)`HO%dU&*GPN&twF<>h{lpq^9 z2It+%zS!UqTn}=L?gcH|))KYJW6WXOQfeXrYyyuF>@QrXbt;3$=-ySW2H}Xt#m0^Az;q+Lgh*5>C6f8H^q3PV$+MB!R>))AvnkBi zTp@aRw2~?`@2W)RF>kyPYNM5?^msmLA^o<;Fcp3A=d0B48rC}NqncKNM|)?d=5?U2 zRN7-0*aVBn+VQ3;6+xIbkbMh$49+ZO?*NbL;H3!m~PczmdcBqOgC&M__xQzLnXpEO2x zALxgjwmMfxfg>bkU)->TGR%Rps*Ec0wM(9I+EqkijMunN;)R1B9x<*s zAn>lx9L6OShH#BbNDr}ir%Lc%D1q0qo=h(x1*LH`y*-(rvnd4m>#n%RScaX#G!mQ9 z2(e9}e8V6U{|3P46ry-(+>2G6WA`*@nnqM8v0

H?CF=*P}{!?-$H{M9tNrlK+J z#bT=M^2+tu*|Wh}nMx%%5ad{|MCAX&y%!#@jx@Z#($U%K)>fT9WEh-Y`X!bK&+7!a z>n!4L4q1F3xlEqedm15xaF!S#N;5jvzfrC7B@N z8UGHuCo=I~&CafI2*zOmF(2|i;J(Y&P&ulJ2cVl8MmB`e{v1wZe=|p;6Q70YGk83I zyP2ZNhLImx^!3S)EI!suz@&t;wVg-yJ(8rmImdV$%q(cmoQ+7y?jhtPL6Zi@bbyvG z-PB6oM2}I-V#9_``scq6BDhv6*rY6(evMtfRi%8$B@Mvaw_l`LGjX72GJ6g_{Yz;S z+2_Pik_75hHF=%ZX0 z-Hy6^B!404>C>#y%!W~dym`(J+|O08302C;8;OtVE9NZvr4FU2Py6|`K+2DKg8bzv{+hg?pdJ9kaInM`m`1sfH`7m~RV33!Jwq1&0loFUJ z-;2rM78vL*1sk7|kKj47HM(_Br0r4-qZD!TkNjXk(8GXDQ}B|@3)n8$i9y&_BxIWD z)E2|2#&80BD!qLfr@6&y{5}Nu9EHnSo^KZb%V2Bgm`}I*I{8Lex?YjRj3kOOzYXXOO P00000NkvXXu0mjfk=kh! literal 0 HcmV?d00001 diff --git a/src/assets/swipeToDelete@3x.png b/src/assets/swipeToDelete@3x.png new file mode 100755 index 0000000000000000000000000000000000000000..b9b876e756b5d4235ae2b432accbe3be32c52ae2 GIT binary patch literal 4395 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 literal 0 HcmV?d00001 diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index ef1b1f47209..f0731a1826e 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -127,6 +127,9 @@ class AddContactState extends React.PureComponent { onChange = (event) => { const { nativeEvent } = event; let value = nativeEvent.text; + if (value.charCodeAt(0) === 32) { + value = value.substring(1); + } this.setState({ value }); } diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index ca056a565be..d2ab411c9bf 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -15,7 +15,7 @@ const AddressInput = styled(TextInput)` flex-grow: 1; margin-top: 1; z-index: 1; - font-family: ${fonts.family.SFMono}; + font-family: ${fonts.family.SFProText}; font-weight: ${fonts.weight.semibold}; font-size: ${fonts.size.bmedium}; `; diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 198f8745687..2af8f580ef8 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -6,7 +6,7 @@ import { FlyInAnimation } from '../animations'; import { View, Text } from 'react-primitives'; import { RecyclerListView, LayoutProvider, DataProvider } from "recyclerlistview"; import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; -import { colors } from '../../styles'; +import { colors, fonts } from '../../styles'; import { abbreviations } from '../../utils'; import { TruncatedAddress } from '../text'; import { ButtonPressAnimation } from '../animations'; @@ -25,6 +25,10 @@ import { compose } from 'recompact'; import { Alert } from '../alerts'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import GraphemeSplitter from 'grapheme-splitter'; +import FastImage from 'react-native-fast-image'; +import EditIcon from '../../assets/swipeToEdit.png'; +import DeleteIcon from '../../assets/swipeToDelete.png'; +import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; const rowHeight = 62; @@ -56,8 +60,8 @@ const ContactColumn = styled(View)` `; const TopRow = styled(Text)` - font-weight: 500, - font-size: 16 + font-weight: 500; + font-size: 16; `; const BottomRow = styled(TruncatedAddress).attrs({ @@ -72,6 +76,21 @@ const BottomRow = styled(TruncatedAddress).attrs({ width: 100%; `; +const RightActionText = styled(Text)` + font-weight: ${fonts.weight.medium}; + font-size: ${fonts.size.smaller}; + opacity: 0.4; + color: ${colors.blueGreyDark}; + letter-spacing: ${fonts.letterSpacing.tight}; + text-align: center; +`; + +const ActionIcon = styled(FastImage)` + width: 35px; + height: 35px; + margin: 0px 10px 5px 10px; +`; + const NOOP = () => undefined; const layoutItemAnimator = { @@ -90,31 +109,26 @@ class Avatar extends React.PureComponent { this.props.onPress(this.props.address); } - renderRightAction = (text, color, x, progress, onPress) => { + renderRightAction = (text, x, progress, onPress) => { const trans = progress.interpolate({ inputRange: [0, 1], outputRange: [x, 0], }); return ( - - - + + + + {text} - - + + ); }; @@ -152,21 +166,37 @@ class Avatar extends React.PureComponent { }; renderRightActions = progress => ( - - {this.renderRightAction('Edit', '#ffab00', 140, progress, this.editHandler)} - {this.renderRightAction('Delete', '#dd2c00', 70, progress, this.deleteHandler)} + + {this.renderRightAction('Edit', 120, progress, this.editHandler)} + {this.renderRightAction('Delete', 90, progress, this.deleteHandler)} ); updateRef = ref => { this._swipeableRow = ref; }; + close = () => { this._swipeableRow.close(); }; + isEmoji = (str) => { + var ranges = [ + '\ud83c[\udf00-\udfff]', // U+1F300 to U+1F3FF + '\ud83d[\udc00-\ude4f]', // U+1F400 to U+1F64F + '\ud83d[\ude80-\udeff]' // U+1F680 to U+1F6FF + ]; + if (str.match(ranges.join('|'))) { + return true; + } else { + return false; + } +} + render() { const item = this.props; + const displayName = removeFirstEmojiFromString(item.nickname) + return ( - {item.nickname} + {displayName} @@ -235,11 +265,32 @@ class SendContactList extends React.Component { componentWillReceiveProps = (props) => { let newAssets = Object.assign([], props.allAssets); newAssets.reverse(); + newAssets = this.filterContactList(newAssets, props.currentInput, 'nickname'); if(newAssets !== this.state.contacts) { this.setState({ contacts: newAssets }); } } + filterContactList = (list, searchPhrase, searchParameter = false, separator = ' ') => { + const filteredList = []; + if (list && searchPhrase.length > 0) { + for (let i = 0; i < list.length; i++) { + let searchedItem = searchParameter ? list[i][searchParameter] : list[i]; + const splitedWordList = searchedItem.split(separator); + splitedWordList.push(searchedItem); + for (let j = 0; j < splitedWordList.length; j++) { + if (splitedWordList[j].startsWith(searchPhrase)) { + filteredList.push(list[i]); + break; + } + } + } + } else { + return list; + } + return filteredList; + } + shouldComponentUpdate = () => { if(position < 0) { return false; diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index cd15bed1099..4814c0f4cba 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -1,5 +1,11 @@ import { differenceInMinutes } from 'date-fns'; -import { find, omit, pickBy } from 'lodash'; +import { + find, + omit, + orderBy, + pickBy, +} from 'lodash'; +import { removeFirstEmojiFromString, makeSpaceAfterFirstEmoji } from '../helpers/emojiHandler'; const defaultVersion = '0.1.0'; const transactionsVersion = '0.2.0'; @@ -641,9 +647,19 @@ export const addNewLocalContact = async (address, nickname, color) => { contacts.push({ address, color, - nickname, + nickname: makeSpaceAfterFirstEmoji(nickname), }); - await saveLocal('localContacts', { data: contacts }); + + const sortedContacts = orderBy( + contacts, + [contact => { + let newContact = contact.nickname.toLowerCase(); + newContact = removeFirstEmojiFromString(newContact); + return newContact; + }], + ['desc'] + ); + await saveLocal('localContacts', { data: sortedContacts }); }; /** @@ -654,10 +670,10 @@ export const addNewLocalContact = async (address, nickname, color) => { export const deleteLocalContact = async (address) => { const contacts = await getLocalContacts(); for (let i = 0; i < contacts.length; i++) { - if(contacts[i].address == address) { + if (contacts[i].address === address) { contacts.splice(i, 1); i--; } } await saveLocal('localContacts', { data: contacts }); -}; \ No newline at end of file +}; diff --git a/src/helpers/emojiHandler.js b/src/helpers/emojiHandler.js new file mode 100644 index 00000000000..0c1746272a2 --- /dev/null +++ b/src/helpers/emojiHandler.js @@ -0,0 +1,25 @@ +import GraphemeSplitter from 'grapheme-splitter'; + +const regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g; + +export const removeFirstEmojiFromString = (string) => { + const splitedString = new GraphemeSplitter().splitGraphemes(string); + const first = splitedString[0]; + + if (first.search(regex) > -1) { + splitedString.splice(0, 2); + } + return splitedString; +} + +export const makeSpaceAfterFirstEmoji = (string) => { + const splitedString = new GraphemeSplitter().splitGraphemes(string); + const first = splitedString[0]; + + if (first.search(regex) > -1) { + if(splitedString[1] !== ' ') { + return string.replace(first, `${first} `); + } + } + return string; +} \ No newline at end of file diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 0a4a3ae7297..187c6d4fd13 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -1,8 +1,14 @@ import analytics from '@segment/analytics-react-native'; import { get, + indexOf, isEmpty, + isFunction, isString, + map, + property, + sortBy, + upperFirst, } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -19,7 +25,6 @@ import { SendHeader, SendTransactionSpeed, } from '../components/send'; -import { getLocalContacts } from '../handlers/commonStorage'; import { withAccountData, withAccountSettings, @@ -27,20 +32,41 @@ import { withUniqueTokens, } from '../hoc'; import { colors } from '../styles'; -import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; +import { deviceUtils, isNewValueForPath } from '../utils'; +import { showActionSheetWithOptions } from '../utils/actionsheet'; +import { getLocalContacts } from '../handlers/commonStorage'; const Container = styled(Column)` background-color: ${colors.white}; height: 100%; `; +const formatGastSpeedItem = (value, key) => { + const cost = get(value, 'txFee.native.value.display'); + const gwei = get(value, 'value.display'); + const time = get(value, 'estimatedTime.display'); + + return { + gweiValue: gwei, + label: `${upperFirst(key)}: ${cost} ~${time.slice(0, -1)}`, + value: key, + }; +}; + +const labelOrder = ['slow', 'average', 'fast']; + +const formatGasSpeedItems = (gasPrices) => { + const gasItems = map(gasPrices, formatGastSpeedItem); + return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); +}; + class SendSheet extends Component { static propTypes = { allAssets: PropTypes.array, assetAmount: PropTypes.string, fetchData: PropTypes.func, + gasPrice: PropTypes.object, gasPrices: PropTypes.object, - gasUpdateGasPriceOption: PropTypes.func, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, @@ -49,15 +75,14 @@ class SendSheet extends Component { onSubmit: PropTypes.func, recipient: PropTypes.string, selected: PropTypes.object, - selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), sendClearFields: PropTypes.func, sendMaxBalance: PropTypes.func, sendUpdateAssetAmount: PropTypes.func, + sendUpdateGasPrice: PropTypes.func, sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, sendUpdateSelected: PropTypes.func, - txFees: PropTypes.object, } static defaultProps = { @@ -71,6 +96,7 @@ class SendSheet extends Component { this.state = { isAuthorizing: false, contacts: [], + currentInput: '', } } @@ -81,8 +107,7 @@ class SendSheet extends Component { if (address) { sendUpdateRecipient(address); } - const contacts = await getLocalContacts(); - this.setState({ contacts: contacts }); + this.onUpdateContacts() } componentDidUpdate(prevProps) { @@ -148,13 +173,28 @@ class SendSheet extends Component { } onPressTransactionSpeed = (onSuccess) => { - const { - gasPrices, - gasUpdateGasPriceOption, - txFees, - } = this.props; + const { gasPrices, sendUpdateGasPrice } = this.props; + + const options = [ + { label: 'Cancel' }, + ...formatGasSpeedItems(gasPrices), + ]; - gasUtils.showTransactionSpeedOptions(gasPrices, txFees, gasUpdateGasPriceOption, onSuccess); + showActionSheetWithOptions({ + cancelButtonIndex: 0, + options: options.map(property('label')), + }, (buttonIndex) => { + if (buttonIndex > 0) { + const selectedGasPriceItem = options[buttonIndex]; + + sendUpdateGasPrice(selectedGasPriceItem.value); + analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); + } + + if (isFunction(onSuccess)) { + onSuccess(); + } + }); } onResetAssetSelection = () => { @@ -190,15 +230,25 @@ class SendSheet extends Component { }); } + onUpdateContacts = async () => { + const contacts = await getLocalContacts(); + this.setState({ contacts: contacts }); + } + + onChangeInput = (event) => { + this.setState({ currentInput: event }); + this.props.sendUpdateRecipient(event); + } + render() { const { allAssets, fetchData, + gasPrice, isValidAddress, nativeCurrencySymbol, recipient, selected, - selectedGasPrice, sendableUniqueTokens, sendUpdateRecipient, ...props @@ -213,16 +263,19 @@ class SendSheet extends Component { {showEmptyState && ( - )} {showAssetList && ( @@ -251,7 +304,7 @@ class SendSheet extends Component { txSpeedRenderer={( isIphoneX() && ( From c825dbf17d70ab5f984a86fa293c72cda7755cb0 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 24 Jul 2019 15:29:30 +0200 Subject: [PATCH 301/636] fix return button on keyboard, and truncate text --- .../expanded-state/AddContactState.js | 9 ++++++--- src/components/send/SendContactList.js | 20 ++++--------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index f0731a1826e..8e21fec7280 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -134,9 +134,11 @@ class AddContactState extends React.PureComponent { } addContact = async () => { - await addNewLocalContact(this.props.address, this.state.value, this.state.color); - this.props.onCloseModal(); - this.props.navigation.goBack(); + if (this.state.value.length > 0) { + await addNewLocalContact(this.props.address, this.state.value, this.state.color); + this.props.onCloseModal(); + this.props.navigation.goBack(); + } } onChangeColor = () => { @@ -188,6 +190,7 @@ class AddContactState extends React.PureComponent { value={this.state.value} autoCapitalize onSubmitEditing={this.addContact} + returnKeyType={'done'} /> Keyboard.dismiss()}> diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 2af8f580ef8..46813510630 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -62,6 +62,7 @@ const ContactColumn = styled(View)` const TopRow = styled(Text)` font-weight: 500; font-size: 16; + width: ${deviceUtils.dimensions.width - 90}; `; const BottomRow = styled(TruncatedAddress).attrs({ @@ -180,23 +181,10 @@ class Avatar extends React.PureComponent { this._swipeableRow.close(); }; - isEmoji = (str) => { - var ranges = [ - '\ud83c[\udf00-\udfff]', // U+1F300 to U+1F3FF - '\ud83d[\udc00-\ude4f]', // U+1F400 to U+1F64F - '\ud83d[\ude80-\udeff]' // U+1F680 to U+1F6FF - ]; - if (str.match(ranges.join('|'))) { - return true; - } else { - return false; - } -} - render() { const item = this.props; const displayName = removeFirstEmojiFromString(item.nickname) - + return ( - + {displayName} @@ -279,7 +267,7 @@ class SendContactList extends React.Component { const splitedWordList = searchedItem.split(separator); splitedWordList.push(searchedItem); for (let j = 0; j < splitedWordList.length; j++) { - if (splitedWordList[j].startsWith(searchPhrase)) { + if (splitedWordList[j].toLowerCase().startsWith(searchPhrase.toLowerCase())) { filteredList.push(list[i]); break; } From 70c7d4aa9108b06690f3c252ec5162d5095d5b0d Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 25 Jul 2019 12:56:56 -0700 Subject: [PATCH 302/636] Design adjustments --- .../expanded-state/AddContactState.js | 19 ++++++----- src/components/send/SendContactList.js | 34 ++++++++++--------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 8e21fec7280..affc18aa2a5 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -1,11 +1,11 @@ import { get } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; -import { - InteractionManager, - KeyboardAvoidingView, - View, - Keyboard +import { + InteractionManager, + KeyboardAvoidingView, + View, + Keyboard } from 'react-native'; import { compose, @@ -149,14 +149,15 @@ class AddContactState extends React.PureComponent { onDeleteContact = () => { showActionSheetWithOptions({ + title: `Are you sure you want to delete this contact?`, cancelButtonIndex: 1, destructiveButtonIndex: 0, - options: [`Delete ${this.state.value}`, 'Cancel'], + options: [`Delete Contact`, 'Cancel'], }, async (buttonIndex) => { if (buttonIndex === 0) { - await deleteLocalContact(this.props.address); - this.props.onCloseModal(); - this.props.navigation.goBack(); + await deleteLocalContact(this.props.address); + this.props.onCloseModal(); + this.props.navigation.goBack(); } }); } diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 46813510630..7561acc2c0a 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -34,7 +34,7 @@ const rowHeight = 62; const AvatarWrapper = styled(View)` flex-direction: row; - margin: 11px 15px; + margin: 17px 15px 5px 15px; `; const AvatarCircle = styled(View)` @@ -46,7 +46,7 @@ const AvatarCircle = styled(View)` const FirstLetter = styled(Text)` width: 100%; text-align: center; - line-height: 40px; + line-height: 39px; font-size: 18px; color: #fff; font-weight: 600; @@ -56,7 +56,7 @@ const ContactColumn = styled(View)` height: 40px; flex-direction: column; justify-content: space-between; - margin-left: 11px; + margin-left: 10px; `; const TopRow = styled(Text)` @@ -117,12 +117,13 @@ class Avatar extends React.PureComponent { }); return ( - @@ -137,9 +138,10 @@ class Avatar extends React.PureComponent { deleteHandler = async () => { this.close(); showActionSheetWithOptions({ + title: `Are you sure you want to delete this contact?`, cancelButtonIndex: 1, destructiveButtonIndex: 0, - options: [`Delete ${this.props.nickname}`, 'Cancel'], + options: [`Delete Contact`, 'Cancel'], }, async (buttonIndex) => { if (buttonIndex === 0) { await deleteLocalContact(this.props.address); @@ -213,17 +215,17 @@ class Avatar extends React.PureComponent { class SendContactList extends React.Component { balancesRenderItem = item => ( - ); constructor(args) { super(args); - + this.state = { contacts: [], } @@ -288,7 +290,7 @@ class SendContactList extends React.Component { render() { return ( - + {this.state.contacts.length == 0 ? Date: Thu, 25 Jul 2019 22:50:25 -0700 Subject: [PATCH 303/636] Remove contact deletion action sheet title --- src/components/expanded-state/AddContactState.js | 1 - src/components/send/SendContactList.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index affc18aa2a5..db2bbe82207 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -149,7 +149,6 @@ class AddContactState extends React.PureComponent { onDeleteContact = () => { showActionSheetWithOptions({ - title: `Are you sure you want to delete this contact?`, cancelButtonIndex: 1, destructiveButtonIndex: 0, options: [`Delete Contact`, 'Cancel'], diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 7561acc2c0a..f3c77622221 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -138,7 +138,6 @@ class Avatar extends React.PureComponent { deleteHandler = async () => { this.close(); showActionSheetWithOptions({ - title: `Are you sure you want to delete this contact?`, cancelButtonIndex: 1, destructiveButtonIndex: 0, options: [`Delete Contact`, 'Cancel'], From 11f822eb9b4acbafe82cdab5157bf3139584b309 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 27 Jul 2019 01:33:49 +0200 Subject: [PATCH 304/636] fix autofocus on open modal --- src/components/expanded-state/AddContactState.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index db2bbe82207..5bdfcd74624 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -181,7 +181,7 @@ class AddContactState extends React.PureComponent { Date: Fri, 26 Jul 2019 16:48:38 -0700 Subject: [PATCH 305/636] Change SendContactList address font, tweak Swipeable config --- src/components/send/SendContactList.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index f3c77622221..71a7797eeb2 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -73,6 +73,7 @@ const BottomRow = styled(TruncatedAddress).attrs({ weight: 'regular', color: colors.blueGreyDark, })` + font-family: ${fonts.family.SFProText}; opacity: 0.4; width: 100%; `; @@ -190,7 +191,7 @@ class Avatar extends React.PureComponent { From 6830147339c1425c68aaf139de8b611e7295718f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Fri, 26 Jul 2019 17:43:47 -0700 Subject: [PATCH 306/636] Patch react-native-gesture-handler to improve Swipeable performance --- .../react-native-gesture-handler+1.3.0.patch | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 patches/react-native-gesture-handler+1.3.0.patch diff --git a/patches/react-native-gesture-handler+1.3.0.patch b/patches/react-native-gesture-handler+1.3.0.patch new file mode 100644 index 00000000000..6a7b36c12c5 --- /dev/null +++ b/patches/react-native-gesture-handler+1.3.0.patch @@ -0,0 +1,49 @@ +diff --git a/node_modules/react-native-gesture-handler/Swipeable.js b/node_modules/react-native-gesture-handler/Swipeable.js +index 22284a3..185e88b 100644 +--- a/node_modules/react-native-gesture-handler/Swipeable.js ++++ b/node_modules/react-native-gesture-handler/Swipeable.js +@@ -183,8 +183,8 @@ export default class Swipeable extends Component { + rightThreshold = rightWidth / 2, + } = this.props; + +- const startOffsetX = this._currentOffset() + dragX / friction; +- const translationX = (dragX + DRAG_TOSS * velocityX) / friction; ++ const startOffsetX = this._currentOffset() + dragX; ++ const translationX = dragX + DRAG_TOSS * velocityX; + + let toValue = 0; + if (rowState === 0) { +@@ -205,7 +205,7 @@ export default class Swipeable extends Component { + } + } + +- this._animateRow(startOffsetX, toValue, velocityX / friction); ++ this._animateRow(startOffsetX, toValue, velocityX); + }; + + _animateRow = (fromValue, toValue, velocityX) => { +diff --git a/node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj/xcuserdata/christian.xcuserdatad/xcschemes/xcschememanagement.plist b/node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj/xcuserdata/christian.xcuserdatad/xcschemes/xcschememanagement.plist +new file mode 100644 +index 0000000..cf96c26 +--- /dev/null ++++ b/node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj/xcuserdata/christian.xcuserdatad/xcschemes/xcschememanagement.plist +@@ -0,0 +1,19 @@ ++ ++ ++ ++ ++ SchemeUserState ++ ++ RNGestureHandler-tvOS.xcscheme_^#shared#^_ ++ ++ orderHint ++ 86 ++ ++ RNGestureHandler.xcscheme_^#shared#^_ ++ ++ orderHint ++ 85 ++ ++ ++ ++ From 2666e235d254f694908681b094aefb4e566d930c Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 27 Jul 2019 04:06:11 +0200 Subject: [PATCH 307/636] fix losing focus on send header, and copy full address instead short visible version --- src/components/fields/AddressField.js | 40 +++++++++++++++------------ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index d2ab411c9bf..4ddef674bf0 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -9,7 +9,7 @@ import { isValidAddress } from '../../helpers/validators'; import { isHexString } from '../../handlers/web3'; import { abbreviations, addressUtils, isNewValueForPath } from '../../utils'; import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; -import { TextInput } from 'react-native'; +import { TextInput, Clipboard } from 'react-native'; const AddressInput = styled(TextInput)` flex-grow: 1; @@ -32,7 +32,7 @@ const PlaceholderText = styled(Label)` const formatValue = value => ( (isHexString(value) && (value.length === addressUtils.maxLength)) - ? abbreviations.address(value) + ? abbreviations.address(value, 4, 10) : value ); @@ -50,12 +50,20 @@ export default class AddressField extends PureComponent { inputValue: '', address: '', isValid: false, - focused: true, - forceShowNickname: false, + } + + shouldComponentUpdate(props, state) { + if (state.inputValue == this.state.inputValue && + !(this.props.currentContact.nickname !== props.currentContact.nickname) && + !(this.props.address && !this.state.address) && + this.state.isValid == state.isValid) { + return false; + } + return true; } componentDidUpdate(props) { - if (this.props.currentContact.nickname !== props.currentContact.nickname ) { + if (this.props.currentContact.nickname !== props.currentContact.nickname) { this.setState({ currentContact: this.props.currentContact, inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, @@ -72,14 +80,9 @@ export default class AddressField extends PureComponent { } onChange = ({ nativeEvent }) => { - const contact = this.findContactByNickname(nativeEvent.text); - if(contact) { - this.props.onChange(contact.address); - this.validateAddress(contact.address); - return true; - } this.props.onChange(nativeEvent.text); this.validateAddress(nativeEvent.text); + this.checkClipboard(this.state.address); return this.setState({ address: nativeEvent.text }); } @@ -90,11 +93,14 @@ export default class AddressField extends PureComponent { return this.setState({ isValid }); } - findContactByNickname = (nickname) => { - for (let i = 0; i < this.props.contacts.length; i++) { - if (this.props.contacts[i].nickname == nickname) { - return this.props.contacts[i]; - } + onBlur = () => { + this.checkClipboard(this.state.address); + } + + checkClipboard = async (address) => { + const clipboard = await Clipboard.getString(); + if (abbreviations.address(address, 4, 10) == clipboard) { + Clipboard.setString(address); } } @@ -116,7 +122,7 @@ export default class AddressField extends PureComponent { onChangeText={this.onChangeText} selectTextOnFocus={true} value={formatValue(inputValue)} - onBlur={this.onBlur} + onBlur={this.onBlur} /> {!inputValue && ( From 05da69fb5e75f1521fd96fcd3ff5972e517fc4c4 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Sat, 27 Jul 2019 04:14:22 +0200 Subject: [PATCH 308/636] add one more searchable string in filter function for contact list --- src/components/send/SendContactList.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 71a7797eeb2..f70ad52e0c3 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -185,7 +185,7 @@ class Avatar extends React.PureComponent { render() { const item = this.props; - const displayName = removeFirstEmojiFromString(item.nickname) + const displayName = removeFirstEmojiFromString(item.nickname); return ( Date: Sat, 27 Jul 2019 09:31:51 +0200 Subject: [PATCH 309/636] add padding to the last element of the list --- src/components/send/SendContactList.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index f70ad52e0c3..212e34f8ef2 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -29,6 +29,7 @@ import FastImage from 'react-native-fast-image'; import EditIcon from '../../assets/swipeToEdit.png'; import DeleteIcon from '../../assets/swipeToDelete.png'; import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; +import { ListFooter } from '../list'; const rowHeight = 62; @@ -93,16 +94,6 @@ const ActionIcon = styled(FastImage)` margin: 0px 10px 5px 10px; `; -const NOOP = () => undefined; - -const layoutItemAnimator = { - animateDidMount: NOOP, - animateShift: NOOP, - animateWillMount: NOOP, - animateWillUnmount: NOOP, - animateWillUpdate: () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')), -}; - let position = 0; class Avatar extends React.PureComponent { @@ -231,11 +222,17 @@ class SendContactList extends React.Component { } this._layoutProvider = new LayoutProvider((i) => { + if (i == this.state.contacts.length - 1) { + return 'LAST_COIN_ROW'; + } return 'COIN_ROW'; }, (type, dim) => { if (type == "COIN_ROW") { dim.width = deviceUtils.dimensions.width; dim.height = rowHeight; + } else if (type == "LAST_COIN_ROW") { + dim.width = deviceUtils.dimensions.width; + dim.height = rowHeight + ListFooter.height; } else { dim.width = 0; dim.height = 0; @@ -245,7 +242,7 @@ class SendContactList extends React.Component { } _renderRow(type, data) { - if (type == "COIN_ROW") { + if (type == "COIN_ROW" || type == "LAST_COIN_ROW") { return this.balancesRenderItem(data); } else { return this.balancesRenderItem(data); @@ -256,7 +253,7 @@ class SendContactList extends React.Component { let newAssets = Object.assign([], props.allAssets); newAssets.reverse(); newAssets = this.filterContactList(newAssets, props.currentInput, 'nickname'); - if(newAssets !== this.state.contacts) { + if (newAssets !== this.state.contacts) { this.setState({ contacts: newAssets }); } } @@ -283,7 +280,7 @@ class SendContactList extends React.Component { } shouldComponentUpdate = () => { - if(position < 0) { + if (position < 0) { return false; } return true; @@ -318,7 +315,6 @@ class SendContactList extends React.Component { }).cloneWithRows(this.state.contacts) } layoutProvider={this._layoutProvider} - // itemAnimator={layoutItemAnimator} onScroll={(event, _offsetX, offsetY) => { position = offsetY; }} From 543381d14611228c57319814a0a1446f50108001 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Sat, 27 Jul 2019 21:45:27 -0700 Subject: [PATCH 310/636] Font and spacing adjustments --- src/components/expanded-state/AddContactState.js | 6 ++++-- src/components/send/SendContactList.js | 15 ++++++++++----- src/styles/fonts.js | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 5bdfcd74624..023b0bef126 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -182,10 +182,12 @@ class AddContactState extends React.PureComponent { Date: Mon, 16 Sep 2019 19:37:38 -0400 Subject: [PATCH 311/636] add mechanism closing all not used swiped contacts in send list # Conflicts: # src/components/animations/ButtonPressAnimation.js --- .../animations/ButtonPressAnimation.js | 57 ++++++++++++++----- src/components/send/SendContactList.js | 35 +++++++++++- 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index d1d51f74cd9..53bcfeaf673 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -1,4 +1,9 @@ -import { omit, pick, toUpper } from 'lodash'; +import { + isFunction, + omit, + pick, + toUpper, +} from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { InteractionManager } from 'react-native'; @@ -90,6 +95,7 @@ export default class ButtonPressAnimation extends PureComponent { hapticType: PropTypes.oneOf(Object.keys(HapticFeedbackTypes)), isInteraction: PropTypes.bool, onPress: PropTypes.func, + onPressStart: PropTypes.func, scaleTo: PropTypes.number, style: stylePropType, tapRef: PropTypes.object, @@ -139,16 +145,19 @@ export default class ButtonPressAnimation extends PureComponent { }]); } - componentWillUnmount = () => this.clearInteraction() + componentWillUnmount = () => { + this.clearInteraction(); + } clearInteraction = () => { if (this.props.isInteraction && this.handle) { InteractionManager.clearInteractionHandle(this.handle); + this.handle = undefined; } } createInteraction = () => { - if (this.props.isInteraction) { + if (this.props.isInteraction && !this.handle) { this.handle = InteractionManager.createInteractionHandle(); } } @@ -174,11 +183,21 @@ export default class ButtonPressAnimation extends PureComponent { } } - handleRunInteraction = () => ( - this.props.isInteraction - ? InteractionManager.runAfterInteractions(this.handlePress) - : this.handlePress() - ) + handlePressStart = () => { + const { onPressStart } = this.props; + + if (onPressStart) { + this.handleRunInteraction(onPressStart); + } + } + + handleRunInteraction = (functionToRun) => { + const action = isFunction(functionToRun) ? functionToRun : this.handlePress; + + return this.props.isInteraction + ? InteractionManager.runAfterInteractions(action) + : action(); + } render = () => { const { @@ -251,15 +270,23 @@ export default class ButtonPressAnimation extends PureComponent { onChange( this.gestureState, cond( - eq(this.gestureState, ACTIVE), - call([], this.createInteraction), + eq(this.gestureState, BEGAN), + call([], [ + this.createInteraction, + this.handlePressStart, + ]), // else if cond( - eq(this.gestureState, END), - [ - call([], this.handleHaptic), - call([], this.handleRunInteraction), - ], + eq(this.gestureState, ACTIVE), + call([], this.createInteraction), + // else if + cond( + eq(this.gestureState, END), + [ + call([], this.handleHaptic), + call([], this.handleRunInteraction), + ], + ), ), ), ), diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 5b7cbaedcf1..6504e9bbb32 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -103,6 +103,10 @@ let position = 0; class Avatar extends React.PureComponent { + componentWillReceiveProps = () => { + this.close(); + } + onPress = () => { this.props.onPress(this.props.address); } @@ -188,8 +192,9 @@ class Avatar extends React.PureComponent { ref={this.updateRef} friction={2} rightThreshold={0} - renderRightActions={this.renderRightActions}> - + renderRightActions={this.renderRightActions} + onSwipeableWillOpen={() => this.props.onTransitionEnd(item.address)} > + this.props.onTouch(item.address)} onPress={this.onPress} scaleTo={0.96}> @@ -210,11 +215,25 @@ class Avatar extends React.PureComponent { } class SendContactList extends React.Component { + + changeCurrentlyUsedContact = (address) => { + this.currentlyOpenContact = address; + } + + closeAllDifferentContacts = (address) => { + this.touchedContact = address; + this.recentlyRendered = false; + this.setState({ touchedContact: address }); + } + balancesRenderItem = item => ( ); @@ -244,6 +263,9 @@ class SendContactList extends React.Component { } }); this._renderRow = this._renderRow.bind(this); + this.currentlyOpenContact = undefined; + this.touchedContact = undefined; + this.recentlyRendered = false; } _renderRow(type, data) { @@ -316,7 +338,14 @@ class SendContactList extends React.Component { rowRenderer={this._renderRow} dataProvider={ new DataProvider((r1, r2) => { - return r1 !== r2; + if (this.touchedContact && this.currentlyOpenContact && this.touchedContact !== this.currentlyOpenContact && !this.recentlyRendered) { + if (r2 == this.state.contacts[this.state.contacts.length - 1]) { + this.recentlyRendered = true; + } + return true; + } else if (r1 !== r2) { + return true; + } }).cloneWithRows(this.state.contacts) } layoutProvider={this._layoutProvider} From 3c4b3d296df8afefdaedab6cd2073dbcac7d2edd Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 19:39:40 -0400 Subject: [PATCH 312/636] add saving changes on close modal by gesture or tap # Conflicts: # src/screens/ExpandedAssetScreen.js --- .../expanded-state/AddContactState.js | 11 +++- src/screens/ExpandedAssetScreen.js | 55 +++++++++++++++---- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 023b0bef126..c77d5d9ab9a 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -131,6 +131,7 @@ class AddContactState extends React.PureComponent { value = value.substring(1); } this.setState({ value }); + this.props.onUnmountModal(value, this.state.color, true); } addContact = async () => { @@ -141,10 +142,11 @@ class AddContactState extends React.PureComponent { } } - onChangeColor = () => { + onChangeColor = async () => { let newColor = this.state.color; newColor = ++newColor > colors.avatarColor.length - 1 ? 0 : newColor++; this.setState({ color: newColor }); + this.props.onUnmountModal(this.state.value, newColor, true); } onDeleteContact = () => { @@ -154,6 +156,7 @@ class AddContactState extends React.PureComponent { options: [`Delete Contact`, 'Cancel'], }, async (buttonIndex) => { if (buttonIndex === 0) { + this.props.onUnmountModal("", 0, false); await deleteLocalContact(this.props.address); this.props.onCloseModal(); this.props.navigation.goBack(); @@ -212,7 +215,11 @@ class AddContactState extends React.PureComponent { {!this.props.contact ? { this.props.onCloseModal(); this.props.navigation.goBack() }} + onPress={() => { + this.props.onUnmountModal("", 0, false); + this.props.onCloseModal(); + this.props.navigation.goBack() + }} text="Cancel" /> : ( +class ExpandedAssetScreen extends React.Component { + constructor(props) { + super(props); + + this.state = { + value: "", + color: 0, + shouldSave: false, + }; + } + + shouldComponentUpdate = () => { + return false; + } + + componentWillUnmount = async () => { + if (this.state.shouldSave && this.props.type == "contact") { + await addNewLocalContact(this.props.address, this.state.value, this.state.color); + this.props.onCloseModal(); + } + } + + setNewValuesToSave = (value, color, shouldSave = true) => { + this.setState({ + value: value, + color: color, + shouldSave: shouldSave, + }); + } + + render() { + let newProps = Object.assign({}, this.props); + newProps.onUnmountModal = this.setNewValuesToSave; + + return ( - - {createElement(ScreenTypes[type], props)} + + + {createElement(ScreenTypes[this.props.type], newProps)} -)); + ) + } +}; ExpandedAssetScreen.propTypes = { asset: PropTypes.object, From 25e66d84480c0ed152c291747235d6a3f3e8a4c4 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 29 Jul 2019 01:49:46 +0200 Subject: [PATCH 313/636] add handling for no value when close modal by gesture --- src/screens/ExpandedAssetScreen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/ExpandedAssetScreen.js b/src/screens/ExpandedAssetScreen.js index f53bbbf67cb..9ffa3c8875f 100644 --- a/src/screens/ExpandedAssetScreen.js +++ b/src/screens/ExpandedAssetScreen.js @@ -42,7 +42,7 @@ class ExpandedAssetScreen extends React.Component { } componentWillUnmount = async () => { - if (this.state.shouldSave && this.props.type == "contact") { + if (this.state.shouldSave && this.props.type == "contact" && this.state.value.length > 0) { await addNewLocalContact(this.props.address, this.state.value, this.state.color); this.props.onCloseModal(); } From 34fd5071ad7ebb41c46d2f12f01d4ea0ab006750 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 29 Jul 2019 02:11:23 +0200 Subject: [PATCH 314/636] add handling for tapping on placeholder in sendHeader --- src/components/fields/AddressField.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 4ddef674bf0..14d75273a48 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -104,6 +104,10 @@ export default class AddressField extends PureComponent { } } + onPressNickname = () => { + input.focus(); + } + render() { const { autoFocus, ...props } = this.props; const { inputValue, isValid } = this.state; @@ -126,7 +130,7 @@ export default class AddressField extends PureComponent { /> {!inputValue && ( - + ENS or Address ( 0x From 7ae19239be75037738ea49cbf38b75ea13e81526 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 19:40:04 -0400 Subject: [PATCH 315/636] fix syntax and initial add edit contact menu # Conflicts: # src/components/send/SendHeader.js --- .../expanded-state/AddContactState.js | 31 +++---- src/components/send/SendHeader.js | 86 ++++++++++++------- 2 files changed, 70 insertions(+), 47 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index c77d5d9ab9a..ac7560d3aea 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -1,11 +1,10 @@ -import { get } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { InteractionManager, KeyboardAvoidingView, View, - Keyboard + Keyboard, } from 'react-native'; import { compose, @@ -13,28 +12,26 @@ import { withHandlers, withProps, } from 'recompact'; -import { AssetPanel, AssetPanelAction, AssetPanelHeader } from './asset-panel'; +import GraphemeSplitter from 'grapheme-splitter'; +import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; +import { Text } from 'react-primitives'; +import styled from 'styled-components/primitives'; +import { AssetPanel } from './asset-panel'; import FloatingPanels from './FloatingPanels'; import { withAccountData, withAccountSettings } from '../../hoc'; -import { ethereumUtils, deviceUtils } from '../../utils'; -import styled from 'styled-components/primitives'; import { Input } from '../inputs'; import { colors, fonts } from '../../styles'; -import { Button } from '../buttons'; -import { Monospace, TruncatedAddress } from '../text'; -import { Text } from 'react-primitives'; -import { abbreviations } from '../../utils'; -import { CancelButton } from '../buttons'; +import { Button, CancelButton } from '../buttons'; +import { TruncatedAddress } from '../text'; +import { abbreviations, deviceUtils } from '../../utils'; + import { addNewLocalContact, deleteLocalContact, } from '../../handlers/commonStorage'; import { ButtonPressAnimation } from '../animations'; import CopyTooltip from '../CopyTooltip'; -import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; -import { Alert } from '../alerts'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; -import GraphemeSplitter from 'grapheme-splitter'; const TopMenu = styled(View)` justify-content: center; @@ -67,11 +64,11 @@ const FirstLetter = styled(Text)` const AddressAbbreviation = styled(TruncatedAddress).attrs({ align: 'center', + color: colors.blueGreyDark, firstSectionLength: abbreviations.defaultNumCharsPerSection, size: 'lmedium', truncationLength: 4, weight: 'regular', - color: colors.blueGreyDark, })` opacity: 0.6; width: 100%; @@ -102,15 +99,15 @@ class AddContactState extends React.PureComponent { super(props); this.state = { - value: "", color: 0, + value: '', }; } componentDidMount = () => { - let newState = { + const newState = { color: this.props.color, - value: "", + value: '', }; if (this.props.contact.nickname) { newState.value = this.props.contact.nickname; diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 26de76f00a2..6ddacd83ac2 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -2,6 +2,8 @@ import PropTypes from 'prop-types'; import React, { Fragment } from 'react'; import { compose } from 'recompact'; import styled from 'styled-components/primitives'; +import { Keyboard, Clipboard } from 'react-native'; +import { withNavigation } from 'react-navigation'; import Divider from '../Divider'; import { AddressField } from '../fields'; import { Icon } from '../icons'; @@ -9,8 +11,8 @@ import { Row } from '../layout'; import { Label } from '../text'; import { colors, padding } from '../../styles'; import { PasteAddressButton, AddContactButton } from '../buttons'; -import { Text, Keyboard } from 'react-native'; -import { withNavigation } from 'react-navigation'; +import { showActionSheetWithOptions } from '../../utils/actionsheet'; +import { deleteLocalContact } from '../../handlers/commonStorage'; const AddressInputContainer = styled(Row).attrs({ align: 'center' })` ${padding(19, 15)} @@ -18,22 +20,24 @@ const AddressInputContainer = styled(Row).attrs({ align: 'center' })` overflow: hidden; width: 100%; `; -const Nickname = styled(Text)` - background-color: ${colors.white}; - overflow: hidden; - width: 76.5%; - margin-right: -20px; -`; -const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddress, contacts, navigation, onUpdateContacts }) => { +const SendHeader = ({ + onChangeAddressInput, + recipient, + onPressPaste, + isValidAddress, + contacts, + navigation, + onUpdateContacts, +}) => { let contact = { - nickname: "", + address: '', color: 0, - address: "", - } + nickname: '', + }; if (contacts && contacts.length > 0) { for (let i = 0; i < contacts.length; i++) { - if (recipient == contacts[i].address) { + if (recipient === contacts[i].address) { contact = contacts[i]; } } @@ -58,31 +62,49 @@ const SendHeader = ({ onChangeAddressInput, recipient, onPressPaste, isValidAddr name={contact.nickname} contacts={contacts} /> - {isValidAddress ? contact.nickname.length > 0 ? - { - Keyboard.dismiss(); - navigation.navigate('ExpandedAssetScreen', { - address: recipient, - color: contact.color, - asset: [], - contact: contact, - type: 'contact', - onCloseModal: onUpdateContacts, + {isValidAddress && contact.nickname.length > 0 + && { + showActionSheetWithOptions({ + cancelButtonIndex: 3, + destructiveButtonIndex: 2, + options: ['Copy Address', 'Edit Contact', 'Delete Contact', 'Cancel'], + }, async (buttonIndex) => { + if (buttonIndex === 0) { + Clipboard.setString(recipient); + } + if (buttonIndex === 1) { + Keyboard.dismiss(); + navigation.navigate('ExpandedAssetScreen', { + address: recipient, + asset: [], + color: contact.color, + contact, + onCloseModal: onUpdateContacts, + type: 'contact', + }); + } + if (buttonIndex === 2) { + await deleteLocalContact(recipient); + onUpdateContacts(); + } }); - }} /> : - { + }} /> + } + {isValidAddress && contact.nickname.length === 0 + && { const contactColor = Math.floor(Math.random() * colors.avatarColor.length); Keyboard.dismiss(); navigation.navigate('ExpandedAssetScreen', { address: recipient, - color: contactColor, asset: [], + color: contactColor, contact: false, - type: 'contact', onCloseModal: onUpdateContacts, + type: 'contact', }); - }} /> : - } + }} /> + } + {!isValidAddress && } - ) + ); }; SendHeader.propTypes = { + contacts: PropTypes.array, + isValidAddress: PropTypes.bool, + navigation: PropTypes.any, onChangeAddressInput: PropTypes.func, onPressPaste: PropTypes.func, + onUpdateContacts: PropTypes.func, recipient: PropTypes.string, }; From 0cf9581b2cdd70625dedf808177666c6f1724217 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 19:46:16 -0400 Subject: [PATCH 316/636] add long press to contact send list # Conflicts: # src/components/animations/ButtonPressAnimation.js --- .../animations/ButtonPressAnimation.js | 48 +++++++++++++++++-- src/components/send/SendContactList.js | 37 +++++++------- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 53bcfeaf673..006d0ef7bea 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -7,7 +7,13 @@ import { import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { InteractionManager } from 'react-native'; -import { createNativeWrapper, PureNativeButton, State } from 'react-native-gesture-handler'; +import { + createNativeWrapper, + LongPressGestureHandler, + PureNativeButton, + State, + TapGestureHandler, +} from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { @@ -70,6 +76,12 @@ const AnimatedRawButton = createNativeWrapper( }, ); +const AnimatedRawButtonPropBlacklist = [ + 'onLongPress', + 'onPress', + 'onPressStart', +]; + const NOOP = () => undefined; const HapticFeedbackTypes = { @@ -94,6 +106,7 @@ export default class ButtonPressAnimation extends PureComponent { exclusive: PropTypes.bool, hapticType: PropTypes.oneOf(Object.keys(HapticFeedbackTypes)), isInteraction: PropTypes.bool, + onLongPress: PropTypes.func, onPress: PropTypes.func, onPressStart: PropTypes.func, scaleTo: PropTypes.number, @@ -199,7 +212,7 @@ export default class ButtonPressAnimation extends PureComponent { : action(); } - render = () => { + tapGesture = () => { const { activeOpacity, children, @@ -240,7 +253,7 @@ export default class ButtonPressAnimation extends PureComponent { return ( ); } + + longPressGesture = () => { + const { + onLongPress, + } = this.props; + + return ( + { + if (nativeEvent.state === State.ACTIVE) { + if (onLongPress) { + onLongPress(); + } + } + }} + minDurationMs={800}> + {this.tapGesture()} + + ); + } + + render = () => { + const { onLongPress } = this.props; + + if (onLongPress) { + return this.longPressGesture(); + } + return this.tapGesture(); + } } diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 6504e9bbb32..dfbe7611630 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -1,35 +1,28 @@ -import lang from 'i18n-js'; import PropTypes from 'prop-types'; import React from 'react'; -import { deviceUtils } from '../../utils'; -import { FlyInAnimation } from '../animations'; -import { View, Text } from 'react-primitives'; -import { RecyclerListView, LayoutProvider, DataProvider } from "recyclerlistview"; +import { RecyclerListView, LayoutProvider, DataProvider } from 'recyclerlistview'; import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; +import Swipeable from 'react-native-gesture-handler/Swipeable'; +import { Animated } from 'react-native'; +import { withNavigation } from 'react-navigation'; +import { compose } from 'recompact'; +import GraphemeSplitter from 'grapheme-splitter'; +import FastImage from 'react-native-fast-image'; +import { View, Text } from 'react-primitives'; +import { abbreviations, deviceUtils } from '../../utils'; import { colors, fonts } from '../../styles'; -import { abbreviations } from '../../utils'; import { TruncatedAddress } from '../text'; -import { ButtonPressAnimation } from '../animations'; +import { ButtonPressAnimation, FlyInAnimation } from '../animations'; import { Icon } from '../icons'; -import { Centered, Column, Row } from '../layout'; +import { Centered, Column } from '../layout'; import { sheetVerticalOffset } from '../../navigation/transitions/effects'; -import Swipeable from 'react-native-gesture-handler/Swipeable'; -import { RectButton } from 'react-native-gesture-handler'; -import { Animated, LayoutAnimation } from 'react-native'; import { - getLocalContacts, deleteLocalContact, } from '../../handlers/commonStorage'; -import { withNavigation } from 'react-navigation'; -import { compose } from 'recompact'; -import { Alert } from '../alerts'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; -import GraphemeSplitter from 'grapheme-splitter'; -import FastImage from 'react-native-fast-image'; import EditIcon from '../../assets/swipeToEdit.png'; import DeleteIcon from '../../assets/swipeToDelete.png'; import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; -import { ListFooter } from '../list'; const rowHeight = 62; @@ -72,11 +65,11 @@ const TopRow = styled(Text)` const BottomRow = styled(TruncatedAddress).attrs({ align: 'left', + color: colors.blueGreyDark, firstSectionLength: abbreviations.defaultNumCharsPerSection, size: 'smedium', truncationLength: 4, weight: 'regular', - color: colors.blueGreyDark, })` font-family: ${fonts.family.SFProText}; opacity: 0.4; @@ -111,6 +104,10 @@ class Avatar extends React.PureComponent { this.props.onPress(this.props.address); } + onLongPress = () => { + this._swipeableRow.openRight(); + } + renderRightAction = (text, x, progress, onPress) => { const trans = progress.interpolate({ inputRange: [0, 1], @@ -194,7 +191,7 @@ class Avatar extends React.PureComponent { rightThreshold={0} renderRightActions={this.renderRightActions} onSwipeableWillOpen={() => this.props.onTransitionEnd(item.address)} > - this.props.onTouch(item.address)} onPress={this.onPress} scaleTo={0.96}> + this.props.onTouch(item.address)} onLongPress={this.onLongPress} onPress={this.onPress} scaleTo={0.96}> From 4bc723d8f4375eb6f6a7af7f7c45fcd323acf6eb Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 31 Jul 2019 18:53:33 +0200 Subject: [PATCH 317/636] add quicker response to closing modal and add proptypes --- .../expanded-state/AddContactState.js | 157 ++++++++++-------- 1 file changed, 84 insertions(+), 73 deletions(-) diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index ac7560d3aea..2c2d16618ca 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -94,7 +94,6 @@ const Placeholder = styled(Text)` class AddContactState extends React.PureComponent { - constructor(props) { super(props); @@ -150,10 +149,10 @@ class AddContactState extends React.PureComponent { showActionSheetWithOptions({ cancelButtonIndex: 1, destructiveButtonIndex: 0, - options: [`Delete Contact`, 'Cancel'], + options: ['Delete Contact', 'Cancel'], }, async (buttonIndex) => { if (buttonIndex === 0) { - this.props.onUnmountModal("", 0, false); + this.props.onUnmountModal('', 0, false); await deleteLocalContact(this.props.address); this.props.onCloseModal(); this.props.navigation.goBack(); @@ -162,81 +161,93 @@ class AddContactState extends React.PureComponent { } render() { - return this.props.navigation.goBack()}> - - - - - - - - - - {new GraphemeSplitter().splitGraphemes(this.state.value)[0]} - - - - - {this.state.value.length > 0 ? ' ' : 'Name'} - - - Keyboard.dismiss()}> - - - - - - - {!this.props.contact ? - { - this.props.onUnmountModal("", 0, false); - this.props.onCloseModal(); - this.props.navigation.goBack() - }} - text="Cancel" - /> : - + + + + + + + + + + {new GraphemeSplitter().splitGraphemes(this.state.value)[0]} + + + + + {this.state.value.length > 0 ? ' ' : 'Name'} + + - } - - - - - - - + Keyboard.dismiss()}> + + + + + + + {!this.props.contact + ? { + this.props.onUnmountModal('', 0, false); + this.props.onCloseModal(); + this.props.navigation.goBack(); + }} + text="Cancel" + /> + : + } + + + + + + + + ); } -}; +} AddContactState.propTypes = { + address: PropTypes.string, + color: PropTypes.number, + contact: PropTypes.object, + format: PropTypes.func, + navigation: PropTypes.object, + onCloseModal: PropTypes.func, onPressSend: PropTypes.func, + onUnmountModal: PropTypes.func, price: PropTypes.string, subtitle: PropTypes.string, title: PropTypes.string, From 238ccbd4f93491fdc616ac037bea1cb4f1f18e2f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Wed, 31 Jul 2019 15:23:24 -0400 Subject: [PATCH 318/636] Reduce contact list long press duration --- src/components/animations/ButtonPressAnimation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 006d0ef7bea..010971de072 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -339,7 +339,7 @@ export default class ButtonPressAnimation extends PureComponent { } } }} - minDurationMs={800}> + minDurationMs={500}> {this.tapGesture()} ); From b11944310423b9276eb3ec757dc4bbaa6b2d1e17 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Wed, 31 Jul 2019 15:32:53 -0400 Subject: [PATCH 319/636] Rearrange edit contact menu --- src/components/send/SendHeader.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 6ddacd83ac2..f93142d73ff 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -66,10 +66,10 @@ const SendHeader = ({ && { showActionSheetWithOptions({ cancelButtonIndex: 3, - destructiveButtonIndex: 2, - options: ['Copy Address', 'Edit Contact', 'Delete Contact', 'Cancel'], + destructiveButtonIndex: 0, + options: ['Delete Contact', 'Edit Contact', 'Copy Address', 'Cancel'], }, async (buttonIndex) => { - if (buttonIndex === 0) { + if (buttonIndex === 2) { Clipboard.setString(recipient); } if (buttonIndex === 1) { @@ -83,7 +83,7 @@ const SendHeader = ({ type: 'contact', }); } - if (buttonIndex === 2) { + if (buttonIndex === 0) { await deleteLocalContact(recipient); onUpdateContacts(); } From 579418ef26297f36ba5661a2b112c3bca3a7394a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Thu, 1 Aug 2019 13:51:27 +0200 Subject: [PATCH 320/636] add delete menu in edit menu --- src/components/send/SendHeader.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index f93142d73ff..646c6b7d7e7 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -84,8 +84,16 @@ const SendHeader = ({ }); } if (buttonIndex === 0) { - await deleteLocalContact(recipient); - onUpdateContacts(); + showActionSheetWithOptions({ + cancelButtonIndex: 1, + destructiveButtonIndex: 0, + options: ['Delete Contact', 'Cancel'], + }, async (deleteButtonIndex) => { + if (deleteButtonIndex === 0) { + await deleteLocalContact(recipient); + onUpdateContacts(); + } + }); } }); }} /> From c804f8fe8d3d1c7336fca514b98986d9ec77c38e Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 30 Aug 2019 20:19:07 +0200 Subject: [PATCH 321/636] clean up in Send Contact List --- src/components/send/SendAvatar.js | 218 +++++++++++++++++++++ src/components/send/SendContactList.js | 251 ++++--------------------- 2 files changed, 250 insertions(+), 219 deletions(-) create mode 100644 src/components/send/SendAvatar.js diff --git a/src/components/send/SendAvatar.js b/src/components/send/SendAvatar.js new file mode 100644 index 00000000000..573c47fb799 --- /dev/null +++ b/src/components/send/SendAvatar.js @@ -0,0 +1,218 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; +import Swipeable from 'react-native-gesture-handler/Swipeable'; +import { Animated } from 'react-native'; +import GraphemeSplitter from 'grapheme-splitter'; +import FastImage from 'react-native-fast-image'; +import { View, Text } from 'react-primitives'; +import { abbreviations, deviceUtils } from '../../utils'; +import { colors, fonts } from '../../styles'; +import { TruncatedAddress } from '../text'; +import { ButtonPressAnimation } from '../animations'; +import { + deleteLocalContact, +} from '../../handlers/commonStorage'; +import { showActionSheetWithOptions } from '../../utils/actionsheet'; +import EditIcon from '../../assets/swipeToEdit.png'; +import DeleteIcon from '../../assets/swipeToDelete.png'; +import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; + + +const AvatarWrapper = styled(View)` + flex-direction: row; + margin: 17px 15px 5px 15px; +`; + +const AvatarCircle = styled(View)` + height: 40px; + width: 40px; + border-radius: 20px; +`; + +const FirstLetter = styled(Text)` + width: 100%; + text-align: center; + line-height: 39px; + font-size: 18px; + color: #fff; + font-weight: 600; +`; + +const ContactColumn = styled(View)` + height: 40px; + flex-direction: column; + justify-content: space-between; + margin-left: 10px; +`; + +const TopRow = styled(Text)` + font-family: ${fonts.family.SFProText}; + font-size: 16; + font-weight: 500; + letter-spacing: ${fonts.letterSpacing.tight}; + width: ${deviceUtils.dimensions.width - 90}; +`; + +const BottomRow = styled(TruncatedAddress).attrs({ + align: 'left', + color: colors.blueGreyDark, + firstSectionLength: abbreviations.defaultNumCharsPerSection, + size: 'smedium', + truncationLength: 4, + weight: 'regular', +})` + font-family: ${fonts.family.SFProText}; + opacity: 0.4; + width: 100%; +`; + +const RightActionText = styled(Text)` + color: ${colors.blueGreyDark}; + font-family: ${fonts.family.SFProText}; + font-size: ${fonts.size.smaller}; + font-weight: ${fonts.weight.medium}; + letter-spacing: ${fonts.letterSpacing.tight}; + opacity: 0.4; + text-align: center; +`; + +const ActionIcon = styled(FastImage)` + width: 35px; + height: 35px; + margin: 0px 10px 5px 10px; +`; + +class SendAvatar extends React.PureComponent { + componentWillReceiveProps = () => { + this.close(); + } + + onPress = () => { + this.props.onPress(this.props.address); + } + + onLongPress = () => { + this._swipeableRow.openRight(); + } + + renderRightAction = (text, x, progress, onPress) => { + const trans = progress.interpolate({ + inputRange: [0, 1], + outputRange: [x, 0], + }); + + return ( + + + + + {text} + + + + ); + }; + + deleteHandler = async () => { + this.close(); + showActionSheetWithOptions({ + cancelButtonIndex: 1, + destructiveButtonIndex: 0, + options: ['Delete Contact', 'Cancel'], + }, async (buttonIndex) => { + if (buttonIndex === 0) { + await deleteLocalContact(this.props.address); + // Alert({title: `Success`, message: `Contact has been deleted from your address book`}) + this.props.onChange(); + } + }); + }; + + editHandler = async () => { + console.log(this.props); + this.close(); + this.props.navigation.navigate('ExpandedAssetScreen', { + address: this.props.address, + asset: [], + color: this.props.color, + contact: { + address: this.props.address, + color: this.props.color, + nickname: this.props.nickname, + }, + onCloseModal: this.props.onChange, + type: 'contact', + }); + }; + + renderRightActions = progress => ( + + {this.renderRightAction('Edit', 120, progress, this.editHandler)} + {this.renderRightAction('Delete', 90, progress, this.deleteHandler)} + + ); + + updateRef = ref => { + this._swipeableRow = ref; + }; + + close = () => { + this._swipeableRow.close(); + }; + + render() { + const { + address, + color, + nickname, + onTouch, + } = this.props; + const displayName = removeFirstEmojiFromString(nickname); + + return ( + this.props.onTransitionEnd(address)} > + onTouch(address)} onLongPress={this.onLongPress} onPress={this.onPress} scaleTo={0.96}> + + + + {new GraphemeSplitter().splitGraphemes(nickname)[0]} + + + + + {displayName} + + + + + + + ); + } +} + +SendAvatar.propTypes = { + address: PropTypes.string, + color: PropTypes.number, + navigation: PropTypes.object, + nickname: PropTypes.string, + onChange: PropTypes.func, + onPress: PropTypes.func, + onTouch: PropTypes.func, + onTransitionEnd: PropTypes.func, +}; + +export default SendAvatar; diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index dfbe7611630..de7a5f8822f 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -1,218 +1,27 @@ import PropTypes from 'prop-types'; import React from 'react'; import { RecyclerListView, LayoutProvider, DataProvider } from 'recyclerlistview'; -import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; -import Swipeable from 'react-native-gesture-handler/Swipeable'; -import { Animated } from 'react-native'; import { withNavigation } from 'react-navigation'; import { compose } from 'recompact'; -import GraphemeSplitter from 'grapheme-splitter'; -import FastImage from 'react-native-fast-image'; -import { View, Text } from 'react-primitives'; -import { abbreviations, deviceUtils } from '../../utils'; -import { colors, fonts } from '../../styles'; -import { TruncatedAddress } from '../text'; -import { ButtonPressAnimation, FlyInAnimation } from '../animations'; +import { deviceUtils } from '../../utils'; +import { colors } from '../../styles'; +import { FlyInAnimation } from '../animations'; import { Icon } from '../icons'; import { Centered, Column } from '../layout'; import { sheetVerticalOffset } from '../../navigation/transitions/effects'; -import { - deleteLocalContact, -} from '../../handlers/commonStorage'; -import { showActionSheetWithOptions } from '../../utils/actionsheet'; -import EditIcon from '../../assets/swipeToEdit.png'; -import DeleteIcon from '../../assets/swipeToDelete.png'; import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; +import SendAvatar from './SendAvatar'; const rowHeight = 62; const LastRowPadding = 12; -const AvatarWrapper = styled(View)` - flex-direction: row; - margin: 17px 15px 5px 15px; -`; - -const AvatarCircle = styled(View)` - height: 40px; - width: 40px; - border-radius: 20px; -`; - -const FirstLetter = styled(Text)` - width: 100%; - text-align: center; - line-height: 39px; - font-size: 18px; - color: #fff; - font-weight: 600; -`; - -const ContactColumn = styled(View)` - height: 40px; - flex-direction: column; - justify-content: space-between; - margin-left: 10px; -`; - -const TopRow = styled(Text)` - font-family: ${fonts.family.SFProText}; - font-size: 16; - font-weight: 500; - letter-spacing: ${fonts.letterSpacing.tight}; - width: ${deviceUtils.dimensions.width - 90}; -`; - -const BottomRow = styled(TruncatedAddress).attrs({ - align: 'left', - color: colors.blueGreyDark, - firstSectionLength: abbreviations.defaultNumCharsPerSection, - size: 'smedium', - truncationLength: 4, - weight: 'regular', -})` - font-family: ${fonts.family.SFProText}; - opacity: 0.4; - width: 100%; -`; - -const RightActionText = styled(Text)` - color: ${colors.blueGreyDark}; - font-family: ${fonts.family.SFProText}; - font-size: ${fonts.size.smaller}; - font-weight: ${fonts.weight.medium}; - letter-spacing: ${fonts.letterSpacing.tight}; - opacity: 0.4; - text-align: center; -`; - -const ActionIcon = styled(FastImage)` - width: 35px; - height: 35px; - margin: 0px 10px 5px 10px; -`; - let position = 0; -class Avatar extends React.PureComponent { - - componentWillReceiveProps = () => { - this.close(); - } - - onPress = () => { - this.props.onPress(this.props.address); - } - - onLongPress = () => { - this._swipeableRow.openRight(); - } - - renderRightAction = (text, x, progress, onPress) => { - const trans = progress.interpolate({ - inputRange: [0, 1], - outputRange: [x, 0], - }); - - return ( - - - - - {text} - - - - ); - }; - - deleteHandler = async () => { - this.close(); - showActionSheetWithOptions({ - cancelButtonIndex: 1, - destructiveButtonIndex: 0, - options: [`Delete Contact`, 'Cancel'], - }, async (buttonIndex) => { - if (buttonIndex === 0) { - await deleteLocalContact(this.props.address); - // Alert({title: `Success`, message: `Contact has been deleted from your address book`}) - this.props.onChange(); - } - }); - }; - - editHandler = async () => { - console.log(this.props); - this.close(); - this.props.navigation.navigate('ExpandedAssetScreen', { - address: this.props.address, - color: this.props.color, - asset: [], - contact: { - address: this.props.address, - color: this.props.color, - nickname: this.props.nickname, - }, - type: 'contact', - onCloseModal: this.props.onChange, - }); - }; - - renderRightActions = progress => ( - - {this.renderRightAction('Edit', 120, progress, this.editHandler)} - {this.renderRightAction('Delete', 90, progress, this.deleteHandler)} - - ); - - updateRef = ref => { - this._swipeableRow = ref; - }; - - close = () => { - this._swipeableRow.close(); - }; - - render() { - const item = this.props; - const displayName = removeFirstEmojiFromString(item.nickname); - - return ( - this.props.onTransitionEnd(item.address)} > - this.props.onTouch(item.address)} onLongPress={this.onLongPress} onPress={this.onPress} scaleTo={0.96}> - - - - {new GraphemeSplitter().splitGraphemes(item.nickname)[0]} - - - - - {displayName} - - - - - - - ) - } -} +const COIN_ROW = 1; +const LAST_COIN_ROW = 1; class SendContactList extends React.Component { - changeCurrentlyUsedContact = (address) => { this.currentlyOpenContact = address; } @@ -224,7 +33,7 @@ class SendContactList extends React.Component { } balancesRenderItem = item => ( - { - if (i == this.state.contacts.length - 1) { - return 'LAST_COIN_ROW'; + if (i === this.state.contacts.length - 1) { + return LAST_COIN_ROW; } - return 'COIN_ROW'; + return COIN_ROW; }, (type, dim) => { - if (type == "COIN_ROW") { + if (type === COIN_ROW) { dim.width = deviceUtils.dimensions.width; dim.height = rowHeight; - } else if (type == "LAST_COIN_ROW") { + } else if (type === LAST_COIN_ROW) { dim.width = deviceUtils.dimensions.width; dim.height = rowHeight + LastRowPadding; } else { @@ -266,11 +75,7 @@ class SendContactList extends React.Component { } _renderRow(type, data) { - if (type == "COIN_ROW" || type == "LAST_COIN_ROW") { - return this.balancesRenderItem(data); - } else { - return this.balancesRenderItem(data); - } + return this.balancesRenderItem(data); } componentWillReceiveProps = (props) => { @@ -286,10 +91,10 @@ class SendContactList extends React.Component { const filteredList = []; if (list && searchPhrase.length > 0) { for (let i = 0; i < list.length; i++) { - let searchedItem = searchParameter ? list[i][searchParameter] : list[i]; + const searchedItem = searchParameter ? list[i][searchParameter] : list[i]; const splitedWordList = searchedItem.split(separator); splitedWordList.push(searchedItem); - splitedWordList.push(removeFirstEmojiFromString(searchedItem).join("")); + splitedWordList.push(removeFirstEmojiFromString(searchedItem).join('')); for (let j = 0; j < splitedWordList.length; j++) { if (splitedWordList[j].toLowerCase().startsWith(searchPhrase.toLowerCase())) { filteredList.push(list[i]); @@ -312,9 +117,9 @@ class SendContactList extends React.Component { render() { return ( - - {this.state.contacts.length == 0 ? - + {this.state.contacts.length === 0 + ? - : - { if (this.touchedContact && this.currentlyOpenContact && this.touchedContact !== this.currentlyOpenContact && !this.recentlyRendered) { - if (r2 == this.state.contacts[this.state.contacts.length - 1]) { + if (r2 === this.state.contacts[this.state.contacts.length - 1]) { this.recentlyRendered = true; } return true; - } else if (r1 !== r2) { + } if (r1 !== r2) { return true; } + return false; }).cloneWithRows(this.state.contacts) } layoutProvider={this._layoutProvider} @@ -354,7 +159,15 @@ class SendContactList extends React.Component { } ); - }; + } } +SendContactList.propTypes = { + allAssets: PropTypes.array, + currentInput: PropTypes.string, + navigation: PropTypes.object, + onPressContact: PropTypes.func, + onUpdateContacts: PropTypes.array, +}; + export default compose(withNavigation)(SendContactList); From ebc3244bc68db2c07975205761a0a2cbf0dce12c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 19:48:20 -0400 Subject: [PATCH 322/636] clean up in AddressField and commonStorage # Conflicts: # src/handlers/commonStorage.js --- src/components/fields/AddressField.js | 30 +++++++++++++-------------- src/handlers/commonStorage.js | 7 +++---- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 14d75273a48..41eaccbdd04 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -2,14 +2,14 @@ import { omit } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import styled from 'styled-components/primitives'; +import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; +import { TextInput, Clipboard } from 'react-native'; import { Row } from '../layout'; import { colors, fonts } from '../../styles'; import { Label } from '../text'; import { isValidAddress } from '../../helpers/validators'; import { isHexString } from '../../handlers/web3'; -import { abbreviations, addressUtils, isNewValueForPath } from '../../utils'; -import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; -import { TextInput, Clipboard } from 'react-native'; +import { abbreviations, addressUtils } from '../../utils'; const AddressInput = styled(TextInput)` flex-grow: 1; @@ -40,23 +40,23 @@ export default class AddressField extends PureComponent { static propTypes = { address: PropTypes.string, autoFocus: PropTypes.bool, - onChange: PropTypes.func.isRequired, contacts: PropTypes.array, currentContact: PropTypes.object, + onChange: PropTypes.func.isRequired, } state = { + address: '', currentContact: false, inputValue: '', - address: '', isValid: false, } shouldComponentUpdate(props, state) { - if (state.inputValue == this.state.inputValue && - !(this.props.currentContact.nickname !== props.currentContact.nickname) && - !(this.props.address && !this.state.address) && - this.state.isValid == state.isValid) { + if (state.inputValue === this.state.inputValue + && !(this.props.currentContact.nickname !== props.currentContact.nickname) + && !(this.props.address && !this.state.address) + && this.state.isValid === state.isValid) { return false; } return true; @@ -64,16 +64,16 @@ export default class AddressField extends PureComponent { componentDidUpdate(props) { if (this.props.currentContact.nickname !== props.currentContact.nickname) { - this.setState({ + this.setState({ + address: this.props.address, currentContact: this.props.currentContact, inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, - address: this.props.address, isValid: true, }); } else if (this.props.address && !this.state.address) { this.setState({ - inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, address: this.props.address, + inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, isValid: true, }); } @@ -99,7 +99,7 @@ export default class AddressField extends PureComponent { checkClipboard = async (address) => { const clipboard = await Clipboard.getString(); - if (abbreviations.address(address, 4, 10) == clipboard) { + if (abbreviations.address(address, 4, 10) === clipboard) { Clipboard.setString(address); } } @@ -111,7 +111,7 @@ export default class AddressField extends PureComponent { render() { const { autoFocus, ...props } = this.props; const { inputValue, isValid } = this.state; - + return ( {!inputValue && ( diff --git a/src/handlers/commonStorage.js b/src/handlers/commonStorage.js index 4814c0f4cba..bc06caef7c6 100644 --- a/src/handlers/commonStorage.js +++ b/src/handlers/commonStorage.js @@ -598,9 +598,8 @@ export const setAppStoreReviewRequestCount = async (newCount) => { export const getLocalContacts = async () => { try { const localContacts = await getLocal('localContacts'); - return localContacts ? localContacts.data : null; - } - catch { + return localContacts ? localContacts.data : []; + } catch { return []; } }; @@ -657,7 +656,7 @@ export const addNewLocalContact = async (address, nickname, color) => { newContact = removeFirstEmojiFromString(newContact); return newContact; }], - ['desc'] + ['desc'], ); await saveLocal('localContacts', { data: sortedContacts }); }; From 1809042051c051744e218b69b7bc03f3be271c3c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 16 Sep 2019 23:28:55 -0400 Subject: [PATCH 323/636] Cleanup ButtonPressAnimation --- .../animations/ButtonPressAnimation.js | 53 ++++++++----------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 010971de072..2c56db52556 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -12,7 +12,6 @@ import { LongPressGestureHandler, PureNativeButton, State, - TapGestureHandler, } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; @@ -190,6 +189,14 @@ export default class ButtonPressAnimation extends PureComponent { } } + handleLongPress = ({ nativeEvent: { state } }) => { + const { onLongPress } = this.props; + + if (state === State.ACTIVE && onLongPress) { + onLongPress(); + } + } + handlePress = () => { if (this.props.onPress) { this.props.onPress(); @@ -212,7 +219,7 @@ export default class ButtonPressAnimation extends PureComponent { : action(); } - tapGesture = () => { + renderButton = () => { const { activeOpacity, children, @@ -325,32 +332,18 @@ export default class ButtonPressAnimation extends PureComponent { ); } - longPressGesture = () => { - const { - onLongPress, - } = this.props; - - return ( - { - if (nativeEvent.state === State.ACTIVE) { - if (onLongPress) { - onLongPress(); - } - } - }} - minDurationMs={500}> - {this.tapGesture()} - - ); - } - - render = () => { - const { onLongPress } = this.props; - - if (onLongPress) { - return this.longPressGesture(); - } - return this.tapGesture(); - } + renderLongPressButton = () => ( + + {this.renderButton()} + + ) + + render = () => ( + this.props.onLongPress + ? this.renderLongPressButton() + : this.renderButton() + ) } From b5c21eccc5d1f35d594f30e9d2f328f0ec68df7d Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 18 Sep 2019 15:54:55 -0400 Subject: [PATCH 324/636] Add grapheme string helpers --- src/helpers/emojiHandler.js | 30 ++++++++++++++---------------- src/utils/formatters.js | 6 ++++++ src/utils/index.js | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/helpers/emojiHandler.js b/src/helpers/emojiHandler.js index 0c1746272a2..f3648bb1f30 100644 --- a/src/helpers/emojiHandler.js +++ b/src/helpers/emojiHandler.js @@ -1,25 +1,23 @@ import GraphemeSplitter from 'grapheme-splitter'; +// eslint-disable-next-line max-len const regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g; -export const removeFirstEmojiFromString = (string) => { - const splitedString = new GraphemeSplitter().splitGraphemes(string); - const first = splitedString[0]; +export const makeSpaceAfterFirstEmoji = (string) => { + const grapheme = new GraphemeSplitter().splitGraphemes(string); + const first = grapheme[0]; - if (first.search(regex) > -1) { - splitedString.splice(0, 2); - } - return splitedString; -} + return (grapheme[1] !== ' ' && first.search(regex) > -1) + ? string.replace(first, `${first} `) + : string; +}; -export const makeSpaceAfterFirstEmoji = (string) => { - const splitedString = new GraphemeSplitter().splitGraphemes(string); - const first = splitedString[0]; +export const removeFirstEmojiFromString = (string) => { + const grapheme = new GraphemeSplitter().splitGraphemes(string); + const first = grapheme[0]; if (first.search(regex) > -1) { - if(splitedString[1] !== ' ') { - return string.replace(first, `${first} `); - } + grapheme.splice(0, 2); } - return string; -} \ No newline at end of file + return grapheme; +}; diff --git a/src/utils/formatters.js b/src/utils/formatters.js index b1b2be1925c..297a16df8f4 100644 --- a/src/utils/formatters.js +++ b/src/utils/formatters.js @@ -1,7 +1,12 @@ import { isString } from 'lodash'; +import GraphemeSplitter from 'grapheme-splitter'; + +const grapheme = new GraphemeSplitter(); const firstCharacterOfString = n => n.charAt(0); +export const getFirstGrapheme = string => grapheme.splitGraphemes(string)[0]; + export const initials = (string) => ( (!string || !isString(string)) ? '?' @@ -25,6 +30,7 @@ export function removeLeadingZeros(value = '') { } export default { + getFirstGrapheme, initials, removeLeadingZeros, }; diff --git a/src/utils/index.js b/src/utils/index.js index d1d4669fab3..35f3aeda708 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -6,7 +6,7 @@ export { default as dimensionsPropType } from './dimensionsPropType'; export { default as directionPropType } from './directionPropType'; export { default as ethereumUtils } from './ethereumUtils'; export { default as gasUtils } from './gas'; -export { initials, removeLeadingZeros } from './formatters'; +export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForPath } from './isNewValueForPath'; export { default as parseQueryParams } from './parseQueryParams'; From bc4402644dc18bfdf9ca9280c4d53d176bab040b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 18 Sep 2019 15:55:49 -0400 Subject: [PATCH 325/636] Cleanup BlurOverlay --- src/components/BlurOverlay.js | 58 +++++++++++++---------------------- src/screens/ProfileScreen.js | 3 +- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index 7ad2defa94f..f1056ba6ef3 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -1,47 +1,33 @@ import PropTypes from 'prop-types'; import React from 'react'; import { StyleSheet, View } from 'react-native'; -import { pure } from 'recompact'; import Animated from 'react-native-reanimated'; import { BlurView } from '@react-native-community/blur'; -const { - Value, - multiply, - interpolate, - min, - add, -} = Animated; - const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); -const BlurOverlay = ({ blurType, intensity }) => { - const opacity = interpolate( - intensity, - { - inputRange: [0, 0.1, 1], - outputRange: [0, 0, 1], - }, - ); - - return ( - - - - ); +const interpolationConfig = { + inputRange: [0, 0.1, 1], + outputRange: [0, 0, 1], }; +const BlurOverlay = ({ blurType, intensity }) => ( + + + +); + BlurOverlay.propTypes = { blurType: PropTypes.oneOf(['default', 'light', 'dark']).isRequired, intensity: PropTypes.number, @@ -49,7 +35,7 @@ BlurOverlay.propTypes = { BlurOverlay.defaultProps = { blurType: 'dark', - intensity: new Value(0), + intensity: new Animated.Value(0), }; -export default pure(BlurOverlay); +export default React.memo(BlurOverlay); diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index 8f2331018ac..c180bce19a1 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -7,7 +7,7 @@ import { BackButton, Header, HeaderButton } from '../components/header'; import { FlexItem, Page } from '../components/layout'; import { Icon } from '../components/icons'; import { ProfileMasthead } from '../components/profile'; -import { colors, position } from '../styles'; +import { position } from '../styles'; const ProfileScreen = ({ accountAddress, @@ -48,7 +48,6 @@ const ProfileScreen = ({ /> {isEmpty && } From 3eb49901a24c7103d7c85cf296e08b2c9814adee Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 18 Sep 2019 20:03:29 -0400 Subject: [PATCH 326/636] Fix onLongPress and onPressStart support in ButtonPressAnimation --- .../animations/ButtonPressAnimation.js | 125 +++++++++--------- 1 file changed, 59 insertions(+), 66 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 2c56db52556..5f1a2233d45 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -1,18 +1,8 @@ -import { - isFunction, - omit, - pick, - toUpper, -} from 'lodash'; +import { omit, pick, toUpper } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { InteractionManager } from 'react-native'; -import { - createNativeWrapper, - LongPressGestureHandler, - PureNativeButton, - State, -} from 'react-native-gesture-handler'; +import { createNativeWrapper, PureNativeButton, State } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { @@ -71,7 +61,7 @@ const AnimatedRawButton = createNativeWrapper( createAnimatedComponent(PureNativeButton), { shouldActivateOnStart: true, - shouldCancelWhenOutside: false, + shouldCancelWhenOutside: true, }, ); @@ -105,6 +95,7 @@ export default class ButtonPressAnimation extends PureComponent { exclusive: PropTypes.bool, hapticType: PropTypes.oneOf(Object.keys(HapticFeedbackTypes)), isInteraction: PropTypes.bool, + minLongPressDuration: PropTypes.number, onLongPress: PropTypes.func, onPress: PropTypes.func, onPressStart: PropTypes.func, @@ -122,6 +113,7 @@ export default class ButtonPressAnimation extends PureComponent { enableHapticFeedback: true, exclusive: true, hapticType: HapticFeedbackTypes.selection, + minLongPressDuration: 500, scaleTo: animations.keyframes.button.to.scale, } @@ -131,6 +123,8 @@ export default class ButtonPressAnimation extends PureComponent { this.clock = new Clock(); this.gestureState = new Value(UNDETERMINED); this.handle = undefined; + this.longPressDetected = false; + this.longPressTimeout = undefined; this.scale = new Value(1); this.shouldSpring = new Value(-1); @@ -158,7 +152,7 @@ export default class ButtonPressAnimation extends PureComponent { } componentWillUnmount = () => { - this.clearInteraction(); + this.reset(); } clearInteraction = () => { @@ -168,12 +162,26 @@ export default class ButtonPressAnimation extends PureComponent { } } + clearLongPressListener = () => { + this.longPressDetected = false; + if (this.longPressTimeout) { + clearTimeout(this.longPressTimeout); + } + } + createInteraction = () => { if (this.props.isInteraction && !this.handle) { this.handle = InteractionManager.createInteractionHandle(); } } + createLongPressListener = () => { + const { minLongPressDuration, onLongPress } = this.props; + if (onLongPress) { + this.longPressTimeout = setTimeout(this.handleDetectedLongPress, minLongPressDuration); + } + } + handleHaptic = () => { const { enableHapticFeedback, hapticType } = this.props; @@ -189,37 +197,35 @@ export default class ButtonPressAnimation extends PureComponent { } } - handleLongPress = ({ nativeEvent: { state } }) => { - const { onLongPress } = this.props; - - if (state === State.ACTIVE && onLongPress) { - onLongPress(); - } + handleDetectedLongPress = () => { + this.longPressDetected = true; + this.props.onLongPress(); } handlePress = () => { - if (this.props.onPress) { + if (!this.longPressDetected && this.props.onPress) { this.props.onPress(); } } handlePressStart = () => { - const { onPressStart } = this.props; - - if (onPressStart) { - this.handleRunInteraction(onPressStart); + if (this.props.onPressStart) { + this.props.onPressStart(); } } - handleRunInteraction = (functionToRun) => { - const action = isFunction(functionToRun) ? functionToRun : this.handlePress; + handleRunInteraction = () => ( + this.props.isInteraction + ? InteractionManager.runAfterInteractions(this.handlePress) + : this.handlePress() + ) - return this.props.isInteraction - ? InteractionManager.runAfterInteractions(action) - : action(); + reset = () => { + this.clearInteraction(); + this.clearLongPressListener(); } - renderButton = () => { + render = () => { const { activeOpacity, children, @@ -285,37 +291,39 @@ export default class ButtonPressAnimation extends PureComponent { ), cond( contains([FAILED, CANCELLED], this.gestureState), - set(this.shouldSpring, 0), + [ + set(this.shouldSpring, 0), + this.reset(), + ], ), onChange( this.gestureState, cond( - eq(this.gestureState, BEGAN), - call([], [ - this.createInteraction, - this.handlePressStart, - ]), + eq(this.gestureState, ACTIVE), + [ + call([], this.createInteraction), + call([], this.createLongPressListener), + call([], this.handlePressStart), + ], // else if cond( - eq(this.gestureState, ACTIVE), - call([], this.createInteraction), - // else if - cond( - eq(this.gestureState, END), - [ - call([], this.handleHaptic), - call([], this.handleRunInteraction), - ], - ), + eq(this.gestureState, END), + [ + call([], this.handleHaptic), + call([], this.handleRunInteraction), + ], ), ), ), cond( eq(this.gestureState, END), - runDelay([ - set(this.shouldSpring, 0), - call([], this.clearInteraction), - ], duration), + runDelay( + [ + set(this.shouldSpring, 0), + call([], this.clearInteraction), + ], + duration, + ), ), set( this.scale, @@ -331,19 +339,4 @@ export default class ButtonPressAnimation extends PureComponent { ); } - - renderLongPressButton = () => ( - - {this.renderButton()} - - ) - - render = () => ( - this.props.onLongPress - ? this.renderLongPressButton() - : this.renderButton() - ) } From e3a325bbfc7f35bd6d115c6a681f977efa426532 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 18 Sep 2019 21:32:53 -0400 Subject: [PATCH 327/636] Cleanup new Contact-related components + SendHeader --- src/components/buttons/AddContactButton.js | 138 +++++---- src/components/contacts/ContactAvatar.js | 36 +++ src/components/contacts/ContactRow.js | 65 +++++ .../contacts/SwipeableContactRow.js | 155 ++++++++++ src/components/contacts/index.js | 4 + .../contacts/showDeleteContactActionSheet.js | 20 ++ src/components/fields/AddressField.js | 77 ++--- src/components/send/SendAssetList.js | 5 +- src/components/send/SendAvatar.js | 218 -------------- src/components/send/SendContactList.js | 168 +++++------ src/components/send/SendEmptyState.js | 67 +++-- src/components/send/SendHeader.js | 270 +++++++++++------- src/components/send/index.js | 4 +- src/components/text/TruncatedAddress.js | 42 ++- src/screens/SendSheet.js | 19 +- src/styles/colors.js | 4 +- src/styles/fonts.js | 1 + 17 files changed, 732 insertions(+), 561 deletions(-) create mode 100644 src/components/contacts/ContactAvatar.js create mode 100644 src/components/contacts/ContactRow.js create mode 100644 src/components/contacts/SwipeableContactRow.js create mode 100644 src/components/contacts/index.js create mode 100644 src/components/contacts/showDeleteContactActionSheet.js delete mode 100644 src/components/send/SendAvatar.js diff --git a/src/components/buttons/AddContactButton.js b/src/components/buttons/AddContactButton.js index 1923fc1cf1f..4d82fc73c5c 100644 --- a/src/components/buttons/AddContactButton.js +++ b/src/components/buttons/AddContactButton.js @@ -1,55 +1,95 @@ import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import { Clipboard, View } from 'react-native'; -import Button from './Button'; -import { withAppState } from '../../hoc'; -import { colors } from '../../styles'; +import React, { useEffect, useRef } from 'react'; import FastImage from 'react-native-fast-image'; +import { Transitioning, Transition } from 'react-native-reanimated'; +import { View } from 'react-primitives'; +import { compose, setPropTypes } from 'recompact'; import AddContactIcon from '../../assets/addContactIcon.png'; -import styled from 'styled-components/primitives'; +import { withNeverRerender } from '../../hoc'; +import { colors } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { Icon } from '../icons'; +import Button from './Button'; + +const duration = 200; +const transition = ( + + + + + + + + + + + +); + +const enhanceButton = compose( + setPropTypes({ onPress: PropTypes.func.isRequired }), + withNeverRerender, +); + +const AddButton = enhanceButton(({ onPress }) => ( + +)); + +const EditButton = enhanceButton(({ onPress }) => ( + + + +)); + +const AddContactButton = ({ edit, onPress }) => { + const addButtonRef = useRef(); + const editButtonRef = useRef(); + + useEffect(() => { + if (addButtonRef.current) addButtonRef.current.animateNextTransition(); + if (editButtonRef.current) editButtonRef.current.animateNextTransition(); + }, [edit]); + + return ( + + {edit ? ( + + + + ) : ( + + + + )} + + ); +}; + +AddContactButton.propTypes = { + edit: PropTypes.bool, + onPress: PropTypes.func.isRequired, +}; -const AddIcon = styled(FastImage)` - width: 19px; - height: 14.7px; - margin: 1.525px; -`; - -const EditIcon = styled(View)` - height: 30px; - padding-right: 4px; - justify-content: center; -`; - -class AddContactButton extends PureComponent { - static propTypes = { - appState: PropTypes.string, - onPress: PropTypes.func.isRequired, - } - - render() { - return ( - - {!this.props.edit ? ( - - ) : ( - - - - - - )} - - ); - } -} - -export default withAppState(AddContactButton); +export default React.memo(AddContactButton); diff --git a/src/components/contacts/ContactAvatar.js b/src/components/contacts/ContactAvatar.js new file mode 100644 index 00000000000..1b24e568d77 --- /dev/null +++ b/src/components/contacts/ContactAvatar.js @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { borders, colors } from '../../styles'; +import { getFirstGrapheme } from '../../utils'; +import { Centered } from '../layout'; +import { Text } from '../text'; + +const ContactAvatar = ({ + color, + large, + value, + ...props +}) => ( + + + {getFirstGrapheme(value)} + + +); + +ContactAvatar.propTypes = { + color: PropTypes.number, + large: PropTypes.bool, + value: PropTypes.string, +}; + +export default React.memo(ContactAvatar); diff --git a/src/components/contacts/ContactRow.js b/src/components/contacts/ContactRow.js new file mode 100644 index 00000000000..4b621dccdb7 --- /dev/null +++ b/src/components/contacts/ContactRow.js @@ -0,0 +1,65 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { onlyUpdateForPropTypes, withProps } from 'recompact'; +import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; +import { colors, margin } from '../../styles'; +import { abbreviations, deviceUtils } from '../../utils'; +import { ButtonPressAnimation } from '../animations'; +import { Column, RowWithMargins } from '../layout'; +import { Text, TruncatedAddress } from '../text'; +import ContactAvatar from './ContactAvatar'; + +const TruncatedContactAddress = withProps({ + align: 'left', + color: colors.alpha(colors.blueGreyDark, 0.4), + size: 'smedium', + weight: 'regular', + width: '100%', +})(TruncatedAddress); + +const ContactRow = ({ + address, + color, + nickname, + ...props +}) => ( + + + + + + {removeFirstEmojiFromString(nickname)} + + + + + +); + +ContactRow.propTypes = { + address: PropTypes.string, + color: PropTypes.number, + nickname: PropTypes.string, +}; + +export default onlyUpdateForPropTypes(ContactRow); diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js new file mode 100644 index 00000000000..718f1166cbb --- /dev/null +++ b/src/components/contacts/SwipeableContactRow.js @@ -0,0 +1,155 @@ +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { Animated } from 'react-native'; +import FastImage from 'react-native-fast-image'; +import Swipeable from 'react-native-gesture-handler/Swipeable'; +import { toClass } from 'recompact'; +import DeleteIcon from '../../assets/swipeToDelete.png'; +import EditIcon from '../../assets/swipeToEdit.png'; +import { colors, margin, position } from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { Centered, Row } from '../layout'; +import { Text } from '../text'; +import ContactRow from './ContactRow'; +import showDeleteContactActionSheet from './showDeleteContactActionSheet'; + +const AnimatedCentered = Animated.createAnimatedComponent(toClass(Centered)); + +const RightAction = ({ + onPress, + progress, + text, + x, +}) => { + const isEdit = text === 'Edit'; + const translateX = progress.interpolate({ + inputRange: [0, 1], + outputRange: [x, 0], + }); + + return ( + + + + + {text} + + + + ); +}; + +RightAction.propTypes = { + onPress: PropTypes.func, + progress: PropTypes.any, + text: PropTypes.string, + x: PropTypes.number, +}; + +export default class SwipeableContactRow extends PureComponent { + static propTypes = { + address: PropTypes.string, + color: PropTypes.number, + navigation: PropTypes.object, + nickname: PropTypes.string, + onChange: PropTypes.func, + onPress: PropTypes.func, + onTouch: PropTypes.func, + onTransitionEnd: PropTypes.func, + } + + componentWillReceiveProps = () => this.close() + + swipeableRef = undefined + + close = () => this.swipeableRef.close() + + handleDeleteContact = async () => { + const { address, nickname, onChange } = this.props; + this.close(); + showdeletecontactactionsheet({ + address, + nickname, + onDelete: onChange, + }); + } + + handleEditContact = () => { + const { + address, + color, + navigation, + nickname, + onChange, + } = this.props; + + this.close(); + navigation.navigate('ExpandedAssetScreen', { + address, + asset: [], + color, + contact: { address, color, nickname }, + onCloseModal: onChange, + type: 'contact', + }); + } + + handleLongPress = () => this.swipeableRef.openRight() + + handlePress = () => this.props.onPress(this.props.address) + + handlePressStart = () => this.props.onTouch(this.props.address) + + handleSwipeableWillOpen = () => this.props.onTransitionEnd(this.props.address) + + handleRef = (ref) => { this.swipeableRef = ref; } + + renderRightActions = (progress) => ( + + + + + ) + + render = () => ( + + + + ) +} diff --git a/src/components/contacts/index.js b/src/components/contacts/index.js new file mode 100644 index 00000000000..07180d5a091 --- /dev/null +++ b/src/components/contacts/index.js @@ -0,0 +1,4 @@ +export { default as ContactAvatar } from './ContactAvatar'; +export { default as ContactRow } from './ContactRow'; +export { default as showDeleteContactActionSheet } from './showDeleteContactActionSheet'; +export { default as SwipeableContactRow } from './SwipeableContactRow'; diff --git a/src/components/contacts/showDeleteContactActionSheet.js b/src/components/contacts/showDeleteContactActionSheet.js new file mode 100644 index 00000000000..559c20b0e71 --- /dev/null +++ b/src/components/contacts/showDeleteContactActionSheet.js @@ -0,0 +1,20 @@ +import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; +import { deleteLocalContact } from '../../handlers/commonStorage'; +import { showActionSheetWithOptions } from '../../utils/actionsheet'; + +const showDeleteContactActionSheet = ({ address, nickname, onDelete }) => ( + showActionSheetWithOptions({ + cancelButtonIndex: 1, + destructiveButtonIndex: 0, + message: `Are you sure that you want to delete "${nickname || address}" from your contacts?`, + options: ['Delete Contact', 'Cancel'], + }, async (buttonIndex) => { + if (buttonIndex === 0) { + await deleteLocalContact(address); + ReactNativeHapticFeedback.trigger('notificationSuccess'); + onDelete(); + } + }) +); + +export default showDeleteContactActionSheet; diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 41eaccbdd04..c0b38dad175 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -9,15 +9,15 @@ import { colors, fonts } from '../../styles'; import { Label } from '../text'; import { isValidAddress } from '../../helpers/validators'; import { isHexString } from '../../handlers/web3'; -import { abbreviations, addressUtils } from '../../utils'; +import { abbreviations, addressUtils, isNewValueForPath } from '../../utils'; const AddressInput = styled(TextInput)` flex-grow: 1; - margin-top: 1; - z-index: 1; font-family: ${fonts.family.SFProText}; - font-weight: ${fonts.weight.semibold}; font-size: ${fonts.size.bmedium}; + font-weight: ${fonts.weight.semibold}; + margin-top: 1; + z-index: 1; `; const Placeholder = styled(Row)` @@ -52,41 +52,52 @@ export default class AddressField extends PureComponent { isValid: false, } - shouldComponentUpdate(props, state) { - if (state.inputValue === this.state.inputValue - && !(this.props.currentContact.nickname !== props.currentContact.nickname) - && !(this.props.address && !this.state.address) - && this.state.isValid === state.isValid) { - return false; - } - return true; + inputRef = undefined + + shouldComponentUpdate(nextProps, nextState) { + const isNewAddress = isNewValueForPath(this.props, this.state, 'address'); + const isNewInputValue = isNewValueForPath(this.state, nextState, 'inputValue'); + const isNewNickname = isNewValueForPath(this.props, nextProps, 'currentContact.nickname'); + const isNewValid = isNewValueForPath(this.state, nextState, 'isValid'); + return ( + isNewAddress + || isNewInputValue + || isNewNickname + || isNewValid + ); } - componentDidUpdate(props) { - if (this.props.currentContact.nickname !== props.currentContact.nickname) { - this.setState({ - address: this.props.address, - currentContact: this.props.currentContact, - inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, - isValid: true, - }); - } else if (this.props.address && !this.state.address) { - this.setState({ - address: this.props.address, - inputValue: this.props.currentContact.nickname ? this.props.currentContact.nickname : this.props.address, + componentDidUpdate(prevProps) { + const { address, currentContact } = this.props; + + const isNewNickname = isNewValueForPath(this.props, prevProps, 'currentContact.nickname'); + const isNewAddress = address !== this.state.address; + + if (isNewAddress || isNewNickname) { + const newState = { + address, + inputValue: currentContact.nickname ? currentContact.nickname : address, isValid: true, - }); + }; + + if (isNewNickname) { + newState.currentContact = currentContact; + } + + this.setState(newState); } } - onChange = ({ nativeEvent }) => { - this.props.onChange(nativeEvent.text); - this.validateAddress(nativeEvent.text); + handleInputRef = (ref) => { this.inputRef = ref; } + + onChange = ({ nativeEvent: { text } }) => { + this.props.onChange(text); + this.validateAddress(text); this.checkClipboard(this.state.address); - return this.setState({ address: nativeEvent.text }); + return this.setState({ address: text }); } - onChangeText = inputValue => this.setState({ inputValue }); + onChangeText = inputValue => this.setState({ inputValue }) validateAddress = async (address) => { const isValid = await isValidAddress(address); @@ -105,7 +116,7 @@ export default class AddressField extends PureComponent { } onPressNickname = () => { - input.focus(); + this.inputRef.focus(); } render() { @@ -115,18 +126,18 @@ export default class AddressField extends PureComponent { return ( input = x} {...props} {...omit(Label.textProps, 'opacity')} autoCorrect={false} autoFocus={autoFocus} color={isValid ? colors.appleBlue : colors.blueGreyDark} maxLength={addressUtils.maxLength} + onBlur={this.onBlur} onChange={this.onChange} onChangeText={this.onChangeText} + ref={this.handleInputRef} selectTextOnFocus={true} value={formatValue(inputValue)} - onBlur={this.onBlur} /> {!inputValue && ( diff --git a/src/components/send/SendAssetList.js b/src/components/send/SendAssetList.js index 0971d1f7164..5179dbe347d 100644 --- a/src/components/send/SendAssetList.js +++ b/src/components/send/SendAssetList.js @@ -26,8 +26,8 @@ const familyHeaderHeight = 64; const dividerHeight = 18; const Divider = styled.View` - height: 2px; background-color: ${colors.lighterGrey}; + height: 2px; margin: 10px 19px; width: 100%; `; @@ -65,8 +65,7 @@ class SendAssetList extends React.Component { const renderSize = familyHeaderHeight + this.props.uniqueTokens[index].data.length * rowHeight; const screenHeight = this.position + this.componentHeight; if(heightBelow + renderSize + 64 > screenHeight) { - const diff = this.position + (heightBelow + renderSize - screenHeight + familyHeaderHeight); - if( renderSize < this.componentHeight) { + if(renderSize < this.componentHeight) { setTimeout(() => { this.rlv.scrollToOffset(0, this.position + (heightBelow + renderSize - screenHeight + familyHeaderHeight), true); }, 10); diff --git a/src/components/send/SendAvatar.js b/src/components/send/SendAvatar.js deleted file mode 100644 index 573c47fb799..00000000000 --- a/src/components/send/SendAvatar.js +++ /dev/null @@ -1,218 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; -import Swipeable from 'react-native-gesture-handler/Swipeable'; -import { Animated } from 'react-native'; -import GraphemeSplitter from 'grapheme-splitter'; -import FastImage from 'react-native-fast-image'; -import { View, Text } from 'react-primitives'; -import { abbreviations, deviceUtils } from '../../utils'; -import { colors, fonts } from '../../styles'; -import { TruncatedAddress } from '../text'; -import { ButtonPressAnimation } from '../animations'; -import { - deleteLocalContact, -} from '../../handlers/commonStorage'; -import { showActionSheetWithOptions } from '../../utils/actionsheet'; -import EditIcon from '../../assets/swipeToEdit.png'; -import DeleteIcon from '../../assets/swipeToDelete.png'; -import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; - - -const AvatarWrapper = styled(View)` - flex-direction: row; - margin: 17px 15px 5px 15px; -`; - -const AvatarCircle = styled(View)` - height: 40px; - width: 40px; - border-radius: 20px; -`; - -const FirstLetter = styled(Text)` - width: 100%; - text-align: center; - line-height: 39px; - font-size: 18px; - color: #fff; - font-weight: 600; -`; - -const ContactColumn = styled(View)` - height: 40px; - flex-direction: column; - justify-content: space-between; - margin-left: 10px; -`; - -const TopRow = styled(Text)` - font-family: ${fonts.family.SFProText}; - font-size: 16; - font-weight: 500; - letter-spacing: ${fonts.letterSpacing.tight}; - width: ${deviceUtils.dimensions.width - 90}; -`; - -const BottomRow = styled(TruncatedAddress).attrs({ - align: 'left', - color: colors.blueGreyDark, - firstSectionLength: abbreviations.defaultNumCharsPerSection, - size: 'smedium', - truncationLength: 4, - weight: 'regular', -})` - font-family: ${fonts.family.SFProText}; - opacity: 0.4; - width: 100%; -`; - -const RightActionText = styled(Text)` - color: ${colors.blueGreyDark}; - font-family: ${fonts.family.SFProText}; - font-size: ${fonts.size.smaller}; - font-weight: ${fonts.weight.medium}; - letter-spacing: ${fonts.letterSpacing.tight}; - opacity: 0.4; - text-align: center; -`; - -const ActionIcon = styled(FastImage)` - width: 35px; - height: 35px; - margin: 0px 10px 5px 10px; -`; - -class SendAvatar extends React.PureComponent { - componentWillReceiveProps = () => { - this.close(); - } - - onPress = () => { - this.props.onPress(this.props.address); - } - - onLongPress = () => { - this._swipeableRow.openRight(); - } - - renderRightAction = (text, x, progress, onPress) => { - const trans = progress.interpolate({ - inputRange: [0, 1], - outputRange: [x, 0], - }); - - return ( - - - - - {text} - - - - ); - }; - - deleteHandler = async () => { - this.close(); - showActionSheetWithOptions({ - cancelButtonIndex: 1, - destructiveButtonIndex: 0, - options: ['Delete Contact', 'Cancel'], - }, async (buttonIndex) => { - if (buttonIndex === 0) { - await deleteLocalContact(this.props.address); - // Alert({title: `Success`, message: `Contact has been deleted from your address book`}) - this.props.onChange(); - } - }); - }; - - editHandler = async () => { - console.log(this.props); - this.close(); - this.props.navigation.navigate('ExpandedAssetScreen', { - address: this.props.address, - asset: [], - color: this.props.color, - contact: { - address: this.props.address, - color: this.props.color, - nickname: this.props.nickname, - }, - onCloseModal: this.props.onChange, - type: 'contact', - }); - }; - - renderRightActions = progress => ( - - {this.renderRightAction('Edit', 120, progress, this.editHandler)} - {this.renderRightAction('Delete', 90, progress, this.deleteHandler)} - - ); - - updateRef = ref => { - this._swipeableRow = ref; - }; - - close = () => { - this._swipeableRow.close(); - }; - - render() { - const { - address, - color, - nickname, - onTouch, - } = this.props; - const displayName = removeFirstEmojiFromString(nickname); - - return ( - this.props.onTransitionEnd(address)} > - onTouch(address)} onLongPress={this.onLongPress} onPress={this.onPress} scaleTo={0.96}> - - - - {new GraphemeSplitter().splitGraphemes(nickname)[0]} - - - - - {displayName} - - - - - - - ); - } -} - -SendAvatar.propTypes = { - address: PropTypes.string, - color: PropTypes.number, - navigation: PropTypes.object, - nickname: PropTypes.string, - onChange: PropTypes.func, - onPress: PropTypes.func, - onTouch: PropTypes.func, - onTransitionEnd: PropTypes.func, -}; - -export default SendAvatar; diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index de7a5f8822f..3f09dafdaed 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -1,49 +1,31 @@ import PropTypes from 'prop-types'; -import React from 'react'; -import { RecyclerListView, LayoutProvider, DataProvider } from 'recyclerlistview'; +import React, { Component } from 'react'; +import { DataProvider, LayoutProvider, RecyclerListView } from 'recyclerlistview'; import { withNavigation } from 'react-navigation'; -import { compose } from 'recompact'; import { deviceUtils } from '../../utils'; -import { colors } from '../../styles'; import { FlyInAnimation } from '../animations'; -import { Icon } from '../icons'; -import { Centered, Column } from '../layout'; import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; -import SendAvatar from './SendAvatar'; - -const rowHeight = 62; +import { SwipeableContactRow } from '../contacts'; +import SendEmptyState from './SendEmptyState'; const LastRowPadding = 12; +const rowHeight = 62; let position = 0; const COIN_ROW = 1; const LAST_COIN_ROW = 1; -class SendContactList extends React.Component { - changeCurrentlyUsedContact = (address) => { - this.currentlyOpenContact = address; +class SendContactList extends Component { + static propTypes = { + allAssets: PropTypes.array, + currentInput: PropTypes.string, + navigation: PropTypes.object, + onPressContact: PropTypes.func, + onUpdateContacts: PropTypes.array, } - closeAllDifferentContacts = (address) => { - this.touchedContact = address; - this.recentlyRendered = false; - this.setState({ touchedContact: address }); - } - - balancesRenderItem = item => ( - - ); - constructor(args) { super(args); @@ -51,6 +33,10 @@ class SendContactList extends React.Component { contacts: [], }; + this.currentlyOpenContact = undefined; + this.recentlyRendered = false; + this.touchedContact = undefined; + this._layoutProvider = new LayoutProvider((i) => { if (i === this.state.contacts.length - 1) { return LAST_COIN_ROW; @@ -58,24 +44,23 @@ class SendContactList extends React.Component { return COIN_ROW; }, (type, dim) => { if (type === COIN_ROW) { - dim.width = deviceUtils.dimensions.width; dim.height = rowHeight; - } else if (type === LAST_COIN_ROW) { dim.width = deviceUtils.dimensions.width; + } else if (type === LAST_COIN_ROW) { dim.height = rowHeight + LastRowPadding; + dim.width = deviceUtils.dimensions.width; } else { - dim.width = 0; dim.height = 0; + dim.width = 0; } }); - this._renderRow = this._renderRow.bind(this); - this.currentlyOpenContact = undefined; - this.touchedContact = undefined; - this.recentlyRendered = false; } - _renderRow(type, data) { - return this.balancesRenderItem(data); + shouldComponentUpdate = () => { + if (position < 0) { + return false; + } + return true; } componentWillReceiveProps = (props) => { @@ -87,6 +72,15 @@ class SendContactList extends React.Component { } } + changeCurrentlyUsedContact = (address) => { + this.currentlyOpenContact = address; + } + + closeAllDifferentContacts = (address) => { + this.touchedContact = address; + this.recentlyRendered = false; + } + filterContactList = (list, searchPhrase, searchParameter = false, separator = ' ') => { const filteredList = []; if (list && searchPhrase.length > 0) { @@ -108,66 +102,52 @@ class SendContactList extends React.Component { return filteredList; } - shouldComponentUpdate = () => { - if (position < 0) { - return false; + handleScroll = (event, offsetX, offsetY) => { + position = offsetY; + } + + hasRowChanged = (r1, r2) => { + const { contacts } = this.state; + + if (this.touchedContact && this.currentlyOpenContact && this.touchedContact !== this.currentlyOpenContact && !this.recentlyRendered) { + if (r2 === contacts[contacts.length - 1]) { + this.recentlyRendered = true; + } + return true; + } if (r1 !== r2) { + return true; } - return true; + return false; } - render() { - return ( - - {this.state.contacts.length === 0 - ? - - - - - : { - if (this.touchedContact && this.currentlyOpenContact && this.touchedContact !== this.currentlyOpenContact && !this.recentlyRendered) { - if (r2 === this.state.contacts[this.state.contacts.length - 1]) { - this.recentlyRendered = true; - } - return true; - } if (r1 !== r2) { - return true; - } - return false; - }).cloneWithRows(this.state.contacts) - } + renderItem = (type, item) => ( + + ) + + render = () => ( + + {this.state.contacts.length === 0 + ? + : ( + { - position = offsetY; - }} + onScroll={this.handleScroll} optimizeForInsertDeleteAnimations + rowRenderer={this.renderItem} /> - } - - ); - } + ) + } + + ) } -SendContactList.propTypes = { - allAssets: PropTypes.array, - currentInput: PropTypes.string, - navigation: PropTypes.object, - onPressContact: PropTypes.func, - onUpdateContacts: PropTypes.array, -}; - -export default compose(withNavigation)(SendContactList); +export default withNavigation(SendContactList); diff --git a/src/components/send/SendEmptyState.js b/src/components/send/SendEmptyState.js index e52be2975a9..3db294f05a4 100644 --- a/src/components/send/SendEmptyState.js +++ b/src/components/send/SendEmptyState.js @@ -1,36 +1,51 @@ import PropTypes from 'prop-types'; -import React from 'react'; -import { PasteAddressButton } from '../buttons'; +import React, { useEffect, useRef } from 'react'; +import { Transitioning, Transition } from 'react-native-reanimated'; import { Icon } from '../icons'; -import { Centered, Column, Row } from '../layout'; -import { withNeverRerender } from '../../hoc'; +import { Centered } from '../layout'; import { sheetVerticalOffset } from '../../navigation/transitions/effects'; -import { colors, padding } from '../../styles'; +import { colors } from '../../styles'; -const SendEmptyState = ({ onPressPaste }) => ( - - - - - - - - +const duration = 200; +const transition = ( + + + + + + + + + ); +const SendEmptyState = () => { + const ref = useRef(); + useEffect(() => (ref && ref.current ? ref.current.animateNextTransition() : undefined)); + + return ( + + + + + + ); +}; + SendEmptyState.propTypes = { onPressPaste: PropTypes.func.isRequired, }; -export default withNeverRerender(SendEmptyState); +export default SendEmptyState; diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 646c6b7d7e7..d6eb75d52fe 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -1,16 +1,23 @@ +import { + find, + get, + isEmpty, + isNumber, +} from 'lodash'; import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; -import { compose } from 'recompact'; +import React, { Fragment, PureComponent } from 'react'; +import { compose, withProps } from 'recompact'; import styled from 'styled-components/primitives'; import { Keyboard, Clipboard } from 'react-native'; import { withNavigation } from 'react-navigation'; +import { withNeverRerender } from '../../hoc'; import Divider from '../Divider'; import { AddressField } from '../fields'; import { Icon } from '../icons'; import { Row } from '../layout'; import { Label } from '../text'; import { colors, padding } from '../../styles'; -import { PasteAddressButton, AddContactButton } from '../buttons'; +import { AddContactButton, PasteAddressButton } from '../buttons'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { deleteLocalContact } from '../../handlers/commonStorage'; @@ -21,116 +28,159 @@ const AddressInputContainer = styled(Row).attrs({ align: 'center' })` width: 100%; `; -const SendHeader = ({ - onChangeAddressInput, - recipient, - onPressPaste, - isValidAddress, - contacts, - navigation, - onUpdateContacts, -}) => { - let contact = { - address: '', - color: 0, - nickname: '', - }; - if (contacts && contacts.length > 0) { - for (let i = 0; i < contacts.length; i++) { - if (recipient === contacts[i].address) { - contact = contacts[i]; - } - } +const SheetHandle = compose( + withNeverRerender, + withProps({ + color: colors.sendScreen.grey, + height: 11, + marginTop: 13, + name: 'handle', + }), +)(Icon); + +const contactPropType = PropTypes.shape({ + address: PropTypes.string, + color: PropTypes.number, + nickname: PropTypes.string, +}); + +const DefaultContactItem = { + address: '', + color: 0, + nickname: '', +}; + +const getContactForRecipient = ({ contacts, recipient }) => { + let contact = DefaultContactItem; + if (recipient && contacts.length) { + const localContact = find(contacts, ({ address }) => (address === recipient)); + contact = localContact || DefaultContactItem; } - return ( - - - - - - {isValidAddress && contact.nickname.length > 0 - && { - showActionSheetWithOptions({ - cancelButtonIndex: 3, - destructiveButtonIndex: 0, - options: ['Delete Contact', 'Edit Contact', 'Copy Address', 'Cancel'], - }, async (buttonIndex) => { - if (buttonIndex === 2) { - Clipboard.setString(recipient); - } - if (buttonIndex === 1) { - Keyboard.dismiss(); - navigation.navigate('ExpandedAssetScreen', { - address: recipient, - asset: [], - color: contact.color, - contact, - onCloseModal: onUpdateContacts, - type: 'contact', - }); - } - if (buttonIndex === 0) { - showActionSheetWithOptions({ - cancelButtonIndex: 1, - destructiveButtonIndex: 0, - options: ['Delete Contact', 'Cancel'], - }, async (deleteButtonIndex) => { - if (deleteButtonIndex === 0) { - await deleteLocalContact(recipient); - onUpdateContacts(); - } - }); - } - }); - }} /> - } - {isValidAddress && contact.nickname.length === 0 - && { - const contactColor = Math.floor(Math.random() * colors.avatarColor.length); - Keyboard.dismiss(); - navigation.navigate('ExpandedAssetScreen', { - address: recipient, - asset: [], - color: contactColor, - contact: false, - onCloseModal: onUpdateContacts, - type: 'contact', - }); - }} /> - } - {!isValidAddress && } - - - - ); + return { contact }; }; -SendHeader.propTypes = { - contacts: PropTypes.array, - isValidAddress: PropTypes.bool, - navigation: PropTypes.any, - onChangeAddressInput: PropTypes.func, - onPressPaste: PropTypes.func, - onUpdateContacts: PropTypes.func, - recipient: PropTypes.string, +const openConfirmDeleteContactActionSheet = (handleSelection) => { + const config = { + cancelButtonIndex: 1, + destructiveButtonIndex: 0, + options: ['Delete Contact', 'Cancel'], + }; + return showActionSheetWithOptions(config, handleSelection); }; -export default compose(withNavigation)(SendHeader); +const openContactActionSheet = (handleSelection) => { + const config = { + cancelButtonIndex: 3, + destructiveButtonIndex: 0, + options: [ + 'Delete Contact', // <-- destructiveButtonIndex + 'Edit Contact', + 'Copy Address', + 'Cancel', // <-- cancelButtonIndex + ], + }; + return showActionSheetWithOptions(config, handleSelection); +}; + +class SendHeader extends PureComponent { + static propTypes = { + contact: contactPropType, + contacts: PropTypes.arrayOf(contactPropType), + isValidAddress: PropTypes.bool, + navigation: PropTypes.any, + onChangeAddressInput: PropTypes.func, + onPressPaste: PropTypes.func, + onUpdateContacts: PropTypes.func, + recipient: PropTypes.string, + } + + handleConfirmDeleteContactSelection = async (buttonIndex) => { + if (buttonIndex === 0) { + await deleteLocalContact(this.props.recipient); + this.props.onUpdateContacts(); + } + } + + handleContactActionSheetSelection = async (buttonIndex) => { + if (buttonIndex === 0) { + openConfirmDeleteContactActionSheet(this.handleConfirmDeleteContactSelection); + } else if (buttonIndex === 1) { + this.navigateToContact(this.props.contact); + } else if (buttonIndex === 2) { + Clipboard.setString(this.props.recipient); + } + } + + navigateToContact = (contact = {}) => { + const { navigation, onUpdateContacts, recipient } = this.props; + + let color = get(contact, 'color'); + if (!isNumber(color)) { + color = Math.floor(Math.random() * colors.avatarColor.length); + } + + Keyboard.dismiss(); + navigation.navigate('ExpandedAssetScreen', { + address: recipient, + asset: [], + color, + contact: isEmpty(contact) ? false : contact, + onCloseModal: onUpdateContacts, + type: 'contact', + }); + } + + openActionSheet = () => openContactActionSheet(this.handleContactActionSheetSelection) + + render = () => { + const { + contact, + isValidAddress, + onChangeAddressInput, + onPressPaste, + recipient, + } = this.props; + + const isPreExistingContact = contact.nickname.length > 0; + + return ( + + + + + + {isValidAddress && ( + + )} + {!isValidAddress && } + + + + ); + } +} + +export default compose( + withNavigation, + withProps(getContactForRecipient), +)(SendHeader); diff --git a/src/components/send/index.js b/src/components/send/index.js index ad01f3dc097..3d0e15d1b51 100644 --- a/src/components/send/index.js +++ b/src/components/send/index.js @@ -1,8 +1,8 @@ export { default as SendAssetForm } from './SendAssetForm'; +export { default as SendAssetFormField } from './SendAssetFormField'; export { default as SendAssetList } from './SendAssetList'; export { default as SendButton } from './SendButton'; +export { default as SendContactList } from './SendContactList'; export { default as SendEmptyState } from './SendEmptyState'; export { default as SendHeader } from './SendHeader'; export { default as SendTransactionSpeed } from './SendTransactionSpeed'; -export { default as SendAssetFormField } from './SendAssetFormField'; -export { default as SendContactList } from './SendContactList'; diff --git a/src/components/text/TruncatedAddress.js b/src/components/text/TruncatedAddress.js index 690ccc7ae66..6df91c6b0cb 100644 --- a/src/components/text/TruncatedAddress.js +++ b/src/components/text/TruncatedAddress.js @@ -1,31 +1,47 @@ import PropTypes from 'prop-types'; import React from 'react'; import { abbreviations } from '../../utils'; -import Monospace from './Monospace'; +import Text from './Text'; const TruncatedAddress = ({ address, firstSectionLength, + monospace, + shouldTruncate, truncationLength, ...props -}) => ( - - {address +}) => { + let text = 'Error displaying address'; + if (address) { + text = shouldTruncate ? abbreviations.address(address, truncationLength, firstSectionLength) - : 'Error displaying address' - } - -); + : address; + } + + return ( + + {text} + + ); +}; TruncatedAddress.propTypes = { address: PropTypes.string, firstSectionLength: PropTypes.number, + monospace: PropTypes.bool, + shouldTruncate: PropTypes.bool, truncationLength: PropTypes.number, }; +TruncatedAddress.defaultProps = { + monospace: true, + shouldTruncate: true, +}; + export default TruncatedAddress; diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 187c6d4fd13..83740476329 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -91,13 +91,10 @@ class SendSheet extends Component { isValidAddress: false, } - constructor(args) { - super(args); - this.state = { - isAuthorizing: false, - contacts: [], - currentInput: '', - } + state = { + contacts: [], + currentInput: '', + isAuthorizing: false, } componentDidMount = async () => { @@ -232,7 +229,7 @@ class SendSheet extends Component { onUpdateContacts = async () => { const contacts = await getLocalContacts(); - this.setState({ contacts: contacts }); + this.setState({ contacts }); } onChangeInput = (event) => { @@ -262,13 +259,13 @@ class SendSheet extends Component { {showEmptyState && ( Date: Wed, 18 Sep 2019 21:33:35 -0400 Subject: [PATCH 328/636] Cleanup TransactionCoinRow --- src/components/coin-row/TransactionCoinRow.js | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index c7d75b39ca9..9608301f27e 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -8,22 +8,21 @@ import { withHandlers, } from 'recompact'; import { Linking } from 'react-native'; +import { withNavigation } from 'react-navigation'; import { css } from 'styled-components/primitives'; +import { getSelectedLocalContact } from '../../handlers/commonStorage'; import TransactionStatusTypes from '../../helpers/transactionStatusTypes'; import { colors } from '../../styles'; +import { abbreviations } from '../../utils'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { ButtonPressAnimation } from '../animations'; import { FlexItem, Row, RowWithMargins } from '../layout'; -import BottomRowText from './BottomRowText'; import BalanceText from './BalanceText'; +import BottomRowText from './BottomRowText'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; import TransactionStatusBadge from './TransactionStatusBadge'; -import { withNavigation } from 'react-navigation'; -import { abbreviations } from '../../utils'; -import { getSelectedLocalContact, getNumberOfLocalContacts } from '../../handlers/commonStorage'; -// XXX after rebase, not sure if still needed const containerStyles = css` paddingLeft: 15; `; @@ -69,15 +68,8 @@ const BottomRow = ({ name, native, status }) => { BottomRow.propTypes = rowRenderPropTypes; const TopRow = ({ balance, pending, status }) => ( - - + + {get(balance, 'display', '')} @@ -122,39 +114,39 @@ export default compose( withNavigation, withHandlers({ onPressTransaction: ({ hash, item, navigation }) => async () => { - let headerInfo = { - type: "", - divider: "", - address: "", - } - headerInfo.type = item.status.charAt(0).toUpperCase() + item.status.slice(1); - headerInfo.divider = item.status === "sent" ? "to" : "from"; + const { from, to, status } = item; + const isSent = status === 'sent'; + + const headerInfo = { + address: '', + divider: isSent ? 'to' : 'from', + type: status.charAt(0).toUpperCase() + status.slice(1), + }; - const contactAddressNumber = item.status === "sent" ? item.to : item.from; - const contact = await getSelectedLocalContact(contactAddressNumber); - const contactsAmount = await getNumberOfLocalContacts(); + const contactAddress = isSent ? to : from; + const contact = await getSelectedLocalContact(contactAddress); let contactColor = 0; if (contact) { headerInfo.address = contact.nickname; contactColor = contact.color; } else { - headerInfo.address = abbreviations.address(contactAddressNumber, 4, 10); + headerInfo.address = abbreviations.address(contactAddress, 4, 10); contactColor = Math.floor(Math.random() * colors.avatarColor.length); } if (hash) { showActionSheetWithOptions({ - title: `${headerInfo.type} ${headerInfo.divider} ${headerInfo.address}`, cancelButtonIndex: 2, options: [contact ? 'View Contact' : 'Add to Contacts', 'View on Etherscan', 'Cancel'], + title: `${headerInfo.type} ${headerInfo.divider} ${headerInfo.address}`, }, (buttonIndex) => { if (buttonIndex === 0) { navigation.navigate('ExpandedAssetScreen', { - address: contactAddressNumber, - color: contactColor, + address: contactAddress, asset: item, - contact: contact, + color: contactColor, + contact, type: 'contact', }); } else if (buttonIndex === 1) { From 8ccccf64021e7abb9c8a44449a8da4a64d70fbd3 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 18 Sep 2019 21:34:09 -0400 Subject: [PATCH 329/636] Cleanup ExpandedAssetScreen --- src/screens/ExpandedAssetScreen.js | 89 ++++++++++++++---------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/src/screens/ExpandedAssetScreen.js b/src/screens/ExpandedAssetScreen.js index 9ffa3c8875f..f9f7abe50d1 100644 --- a/src/screens/ExpandedAssetScreen.js +++ b/src/screens/ExpandedAssetScreen.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React, { createElement } from 'react'; +import React, { Component, createElement } from 'react'; import { StatusBar } from 'react-native'; import { AddContactState, @@ -26,64 +26,59 @@ const ScreenTypes = { uniswap: InvestmentExpandedState, }; -class ExpandedAssetScreen extends React.Component { - constructor(props) { - super(props); +export default class ExpandedAssetScreen extends Component { + static propTypes = { + address: PropTypes.string, + asset: PropTypes.object, + containerPadding: PropTypes.number.isRequired, + onCloseModal: PropTypes.func, + onPressBackground: PropTypes.func, + panelWidth: PropTypes.number, + type: PropTypes.oneOf(Object.keys(ScreenTypes)).isRequired, + } - this.state = { - value: "", - color: 0, - shouldSave: false, - }; + static defaultProps = { + containerPadding: 15, } - shouldComponentUpdate = () => { - return false; + state = { + color: 0, + shouldSave: false, + value: '', } + shouldComponentUpdate = () => false + componentWillUnmount = async () => { - if (this.state.shouldSave && this.props.type == "contact" && this.state.value.length > 0) { - await addNewLocalContact(this.props.address, this.state.value, this.state.color); - this.props.onCloseModal(); + const { address, onCloseModal, type } = this.props; + const { color, shouldSave, value } = this.state; + + if (type === 'contact' && shouldSave && value.length > 0) { + await addNewLocalContact(address, value, color); + onCloseModal(); } } setNewValuesToSave = (value, color, shouldSave = true) => { this.setState({ - value: value, - color: color, - shouldSave: shouldSave, + color, + shouldSave, + value, }); } - render() { - let newProps = Object.assign({}, this.props); - newProps.onUnmountModal = this.setNewValuesToSave; - - return ( - - - - {createElement(ScreenTypes[this.props.type], newProps)} - + render = () => ( + + + + {createElement(ScreenTypes[this.props.type], { + ...this.props, + onUnmountModal: this.setNewValuesToSave, + })} + ) - } -}; - -ExpandedAssetScreen.propTypes = { - asset: PropTypes.object, - containerPadding: PropTypes.number.isRequired, - onPressBackground: PropTypes.func, - panelWidth: PropTypes.number, - type: PropTypes.oneOf(Object.keys(ScreenTypes)).isRequired, -}; - -ExpandedAssetScreen.defaultProps = { - containerPadding: 15, -}; - -export default ExpandedAssetScreen; +} From 356ca38a6f0f34f5b61013fb3594a4d24e78ad7b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 21 Sep 2019 01:56:17 -0400 Subject: [PATCH 330/636] SQUASH cleanup buttonpressanimation --- src/components/animations/ButtonPressAnimation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 5f1a2233d45..eca6e244eeb 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -293,7 +293,7 @@ export default class ButtonPressAnimation extends PureComponent { contains([FAILED, CANCELLED], this.gestureState), [ set(this.shouldSpring, 0), - this.reset(), + call([], this.reset), ], ), onChange( From 94892d0077e9c133f8d2b6ff8fece0fd990bb37f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 21 Sep 2019 01:57:10 -0400 Subject: [PATCH 331/636] Disable truncation of ENS handles in TruncatedAddress component --- src/components/contacts/ContactRow.js | 1 - src/components/text/TruncatedAddress.js | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/contacts/ContactRow.js b/src/components/contacts/ContactRow.js index 4b621dccdb7..139b0527e68 100644 --- a/src/components/contacts/ContactRow.js +++ b/src/components/contacts/ContactRow.js @@ -48,7 +48,6 @@ const ContactRow = ({ diff --git a/src/components/text/TruncatedAddress.js b/src/components/text/TruncatedAddress.js index 6df91c6b0cb..4f52845f1d1 100644 --- a/src/components/text/TruncatedAddress.js +++ b/src/components/text/TruncatedAddress.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { isENSAddressFormat } from '../../helpers/validators'; import { abbreviations } from '../../utils'; import Text from './Text'; @@ -7,15 +8,15 @@ const TruncatedAddress = ({ address, firstSectionLength, monospace, - shouldTruncate, truncationLength, ...props }) => { let text = 'Error displaying address'; + if (address) { - text = shouldTruncate - ? abbreviations.address(address, truncationLength, firstSectionLength) - : address; + text = isENSAddressFormat(address) + ? address + : abbreviations.address(address, truncationLength, firstSectionLength); } return ( @@ -35,13 +36,11 @@ TruncatedAddress.propTypes = { address: PropTypes.string, firstSectionLength: PropTypes.number, monospace: PropTypes.bool, - shouldTruncate: PropTypes.bool, truncationLength: PropTypes.number, }; TruncatedAddress.defaultProps = { monospace: true, - shouldTruncate: true, }; export default TruncatedAddress; From 7b467107b4f1243a7fa891cc534dc7021e394cc9 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 21 Sep 2019 02:02:07 -0400 Subject: [PATCH 332/636] Cleanup AddContactState component --- src/components/CopyTooltip.js | 14 +- src/components/GestureBlocker.js | 9 +- src/components/buttons/BlockButton.js | 115 ------ src/components/buttons/CancelButton.js | 51 --- src/components/buttons/LongPressButton.js | 106 ----- src/components/buttons/index.js | 9 +- .../expanded-state/AddContactState.js | 383 +++++++----------- .../layout/KeyboardFixedOpenLayout.js | 3 +- 8 files changed, 164 insertions(+), 526 deletions(-) delete mode 100644 src/components/buttons/BlockButton.js delete mode 100644 src/components/buttons/CancelButton.js delete mode 100644 src/components/buttons/LongPressButton.js diff --git a/src/components/CopyTooltip.js b/src/components/CopyTooltip.js index b0ac46f989b..36e428df6a3 100644 --- a/src/components/CopyTooltip.js +++ b/src/components/CopyTooltip.js @@ -10,9 +10,9 @@ class CopyTooltip extends PureComponent { static propTypes = { activeOpacity: PropTypes.number, navigation: PropTypes.object, + setSafeTimeout: PropTypes.func, textToCopy: PropTypes.string, tooltipText: PropTypes.string, - waitForKeyboard: PropTypes.bool, } static defaultProps = { @@ -34,15 +34,7 @@ class CopyTooltip extends PureComponent { handleHideTooltip = () => this.tooltip.hideMenu() - handlePressIn = (isWaitingForKeyboard) => { - if (isWaitingForKeyboard) { - setTimeout(() => { - this.tooltip.showMenu(); - }, 300); - } else { - this.tooltip.showMenu(); - } - } + handlePressIn = () => this.tooltip.showMenu() handleRef = (ref) => { this.tooltip = ref; } @@ -51,7 +43,7 @@ class CopyTooltip extends PureComponent { {...this.props} actions={[{ onPress: this.handleCopy, text: this.props.tooltipText }]} activeOpacity={this.props.activeOpacity} - onPressIn={() => this.handlePressIn(this.props.waitForKeyboard)} + onPressIn={this.handlePressIn} ref={this.handleRef} underlayColor={colors.transparent} /> diff --git a/src/components/GestureBlocker.js b/src/components/GestureBlocker.js index ad5dfaf8611..3cf75c6a61d 100644 --- a/src/components/GestureBlocker.js +++ b/src/components/GestureBlocker.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { PanGestureHandler } from 'react-native-gesture-handler'; import { StyleSheet, View } from 'react-native'; +import { PanGestureHandler } from 'react-native-gesture-handler'; import { deviceUtils } from '../utils'; const { height } = deviceUtils.dimensions; @@ -16,10 +16,7 @@ const GestureBlocker = ({ type }) => ( zIndex: 10, }} > - + @@ -27,6 +24,6 @@ const GestureBlocker = ({ type }) => ( GestureBlocker.propTypes = { type: PropTypes.string, -} +}; export default GestureBlocker; diff --git a/src/components/buttons/BlockButton.js b/src/components/buttons/BlockButton.js deleted file mode 100644 index ba2b1281871..00000000000 --- a/src/components/buttons/BlockButton.js +++ /dev/null @@ -1,115 +0,0 @@ -import withViewLayoutProps from '@hocs/with-view-layout-props'; -import PropTypes from 'prop-types'; -import React from 'react'; -import RadialGradient from 'react-native-radial-gradient'; -import styled, { css } from 'styled-components/primitives'; -import { componentFromProp } from 'recompact'; -import { - colors, - padding, - position, - shadow, -} from '../../styles'; -import ButtonPressAnimation from '../animations'; -import InnerBorder from '../InnerBorder'; -import { Centered } from '../layout'; -import { Text } from '../text'; -import { Icon } from '../icons'; - -const BlockButtonBorderRadius = 14; -const BlockButtonHeight = 59; - -const containerStyles = css` - border-radius: ${BlockButtonBorderRadius}; - flex-grow: 0; - height: ${BlockButtonHeight}; -`; - -const ContainerElement = componentFromProp('component'); - -const Container = styled(ContainerElement)` - border-radius: ${BlockButtonBorderRadius}; -`; - -const Content = styled(Centered)` - ${containerStyles} - ${padding(15, 15)} - overflow: hidden; -`; - -const Shadow = styled.View` - ${containerStyles} - ${shadow.build(0, 6, 10, colors.purple, 0.14)} - ${shadow.build(0, 1, 18, colors.purple, 0.12)} - ${shadow.build(0, 3, 5, colors.purple, 0.2)} -`; - -const LeftIcon = styled(Icon).attrs({ color: colors.white, size: 32 })` - ${position.size(BlockButtonHeight)} - position: absolute; - left: 15px; -`; - -const RightIcon = styled(Icon).attrs({ color: colors.white, size: 32 })` - ${position.size(BlockButtonHeight)} - position: absolute; - right: 15px; -`; - -const BlockButton = ({ - children, - disabled, - height, - onLayout, - width, - leftIconName, - leftIconProps, - rightIconName, - rightIconProps, - ...props -}) => ( - - - - - - {leftIconName ? : null} - - {children} - - {rightIconName ? : null} - - - -); - -BlockButton.propTypes = { - children: PropTypes.node, - disabled: PropTypes.disabled, - height: PropTypes.number, - leftIconName: PropTypes.string, - leftIconProps: PropTypes.object, - onLayout: PropTypes.func, - rightIconName: PropTypes.string, - rightIconProps: PropTypes.object, - width: PropTypes.number, -}; - -BlockButton.defaultProps = { - component: ButtonPressAnimation, - disabled: false, - leftIconProps: {}, - rightIconProps: {}, -}; - -export default withViewLayoutProps(({ height, width }) => ({ height, width }))(BlockButton); diff --git a/src/components/buttons/CancelButton.js b/src/components/buttons/CancelButton.js deleted file mode 100644 index 4c40212a25e..00000000000 --- a/src/components/buttons/CancelButton.js +++ /dev/null @@ -1,51 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { pure } from 'recompact'; -import styled from 'styled-components/primitives'; -import { colors, padding } from '../../styles'; -import { ButtonPressAnimation } from '../animations'; -import { Icon } from '../icons'; -import { RowWithMargins } from '../layout'; -import { Text } from '../text'; - -const Container = styled(RowWithMargins).attrs({ - align: 'center', - margin: 6, -})` - ${padding(8, 9)}; - background-color: ${colors.white}; - opacity: 0.4; -`; - -const CancelButton = ({ - icon, - iconSize, - onPress, - text, - ...props -}) => ( - - - - {text} - - - -); - -CancelButton.propTypes = { - icon: Icon.propTypes.name, - iconSize: PropTypes.number, - onPress: PropTypes.func, - text: PropTypes.string, -}; - -CancelButton.defaultProps = { - iconSize: 16, -}; - -export default pure(CancelButton); diff --git a/src/components/buttons/LongPressButton.js b/src/components/buttons/LongPressButton.js deleted file mode 100644 index 73a38bff31a..00000000000 --- a/src/components/buttons/LongPressButton.js +++ /dev/null @@ -1,106 +0,0 @@ -import React, { Component } from 'react'; -import { InteractionManager } from 'react-native'; -import Animated, { Easing } from 'react-native-reanimated'; -import { LongPressGestureHandler, State, TapGestureHandler } from 'react-native-gesture-handler'; -import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import PropTypes from 'prop-types'; - -const { - timing, - Value, - View, -} = Animated; - -export default class LongPressButton extends Component { - static propTypes = { - children: PropTypes.any, - disabled: PropTypes.bool, - onLongPress: PropTypes.func, - onPress: PropTypes.func, - onRelease: PropTypes.func, - style: PropTypes.object, - }; - - static defaultProps = { - disabled: false, - onLongPress() {}, - onPress() {}, - onRelease() {}, - }; - - constructor(props) { - super(props); - - this.scale = new Value(1); - } - - onTapHandlerStateChange = ({ nativeEvent }) => { - const { disabled, onPress, onRelease } = this.props; - - if (nativeEvent.state === State.BEGAN) { - if (disabled) { - ReactNativeHapticFeedback.trigger('notificationWarning'); - - timing(this.scale, { - duration: 150, - easing: Easing.inOut(Easing.ease), - toValue: 0.975, - }).start(() => { - timing(this.scale, { - duration: 150, - easing: Easing.inOut(Easing.ease), - toValue: 1, - }).start(); - }); - } else { - timing(this.scale, { - duration: 150, - easing: Easing.inOut(Easing.ease), - toValue: 0.875, - }).start(); - - onPress(); - } - } else if (!disabled && nativeEvent.state === State.END) { - timing(this.scale, { - duration: 150, - easing: Easing.inOut(Easing.ease), - toValue: 1, - }).start(); - - InteractionManager.runAfterInteractions(() => { - onRelease(); - }); - } - }; - - onLongPressHandlerStateChange = ({ nativeEvent }) => { - const { disabled, onLongPress } = this.props; - - if (!disabled && nativeEvent.state === State.ACTIVE) { - ReactNativeHapticFeedback.trigger('impactHeavy'); - - timing(this.scale, { - duration: 150, - easing: Easing.inOut(Easing.ease), - toValue: 1, - }).start(() => { - InteractionManager.runAfterInteractions(() => { - onLongPress(); - }); - }); - } - }; - - render() { - const { children, style } = this.props; - - return ( - - - {children} - - - ); - } -} diff --git a/src/components/buttons/index.js b/src/components/buttons/index.js index e5ef08bd30d..1b4333f6714 100644 --- a/src/components/buttons/index.js +++ b/src/components/buttons/index.js @@ -1,8 +1,5 @@ -// export { default as BlockButton } from './BlockButton'; -export { default as Button } from './Button'; -export { default as CancelButton } from './CancelButton'; -export { default as PasteAddressButton } from './PasteAddressButton'; export { default as AddContactButton } from './AddContactButton'; -export { default as HoldToAuthorizeButton } from './HoldToAuthorizeButton'; -// export { default as LongPressButton } from './LongPressButton'; +export { default as Button } from './Button'; export { default as CoolButton } from './CoolButton'; +export { default as HoldToAuthorizeButton } from './HoldToAuthorizeButton'; +export { default as PasteAddressButton } from './PasteAddressButton'; diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 2c2d16618ca..b1100829bad 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -1,66 +1,23 @@ +import { get } from 'lodash'; import PropTypes from 'prop-types'; -import React from 'react'; -import { - InteractionManager, - KeyboardAvoidingView, - View, - Keyboard, -} from 'react-native'; -import { - compose, - onlyUpdateForKeys, - withHandlers, - withProps, -} from 'recompact'; -import GraphemeSplitter from 'grapheme-splitter'; -import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; -import { Text } from 'react-primitives'; +import React, { PureComponent } from 'react'; +import { compose, onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components/primitives'; -import { AssetPanel } from './asset-panel'; -import FloatingPanels from './FloatingPanels'; +import { addNewLocalContact } from '../../handlers/commonStorage'; import { withAccountData, withAccountSettings } from '../../hoc'; -import { Input } from '../inputs'; -import { colors, fonts } from '../../styles'; -import { Button, CancelButton } from '../buttons'; -import { TruncatedAddress } from '../text'; +import { colors, margin, padding } from '../../styles'; import { abbreviations, deviceUtils } from '../../utils'; - -import { - addNewLocalContact, - deleteLocalContact, -} from '../../handlers/commonStorage'; import { ButtonPressAnimation } from '../animations'; +import { Button } from '../buttons'; +import { ContactAvatar, showDeleteContactActionSheet } from '../contacts'; import CopyTooltip from '../CopyTooltip'; -import { showActionSheetWithOptions } from '../../utils/actionsheet'; - -const TopMenu = styled(View)` - justify-content: center; - align-items: center; - width: ${deviceUtils.dimensions.width - 110}; - padding: 24px; -`; - -const Container = styled(View)` - justify-content: center; - align-items: center; -`; - -const NameCircle = styled(View)` - height: 60px; - width: 60px; - border-radius: 30px; - margin-bottom: 19px; -`; - -const FirstLetter = styled(Text)` - width: 100%; - text-align: center; - line-height: 58px; - font-size: 27px; - color: #fff; - padding-left: 1px; - font-weight: 600; -`; +import Divider from '../Divider'; +import { Input } from '../inputs'; +import { Centered, KeyboardFixedOpenLayout } from '../layout'; +import { Text, TruncatedAddress } from '../text'; +import TouchableBackdrop from '../TouchableBackdrop'; +import { AssetPanel } from './asset-panel'; +import FloatingPanels from './FloatingPanels'; const AddressAbbreviation = styled(TruncatedAddress).attrs({ align: 'center', @@ -70,210 +27,178 @@ const AddressAbbreviation = styled(TruncatedAddress).attrs({ truncationLength: 4, weight: 'regular', })` + ${margin(9, 0, 5)}; opacity: 0.6; width: 100%; - margin-top: 9px; - margin-bottom: 5px; `; -const Divider = styled(View)` - width: 93px; - margin: 19px 0; - height: 2px; - opacity: 0.05; - background-color: ${colors.blueGreyLigter}; -`; +class AddContactState extends PureComponent { + static propTypes = { + address: PropTypes.string, + color: PropTypes.number, + contact: PropTypes.object, + navigation: PropTypes.object, + onCloseModal: PropTypes.func, + onUnmountModal: PropTypes.func, + price: PropTypes.string, + subtitle: PropTypes.string, + title: PropTypes.string, + } -const Placeholder = styled(Text)` - color: ${colors.blueGreyDark}; - font-size: ${fonts.size.big}; - font-weight: ${fonts.weight.semibold}; - opacity: 0.3; - margin-bottom: -27px; -`; + state = { + color: this.props.color || 0, + value: get(this.props, 'contact.nickname', ''), + } + inputRef = undefined -class AddContactState extends React.PureComponent { - constructor(props) { - super(props); + handleAddContact = async () => { + const { address, navigation, onCloseModal } = this.props; + const { color, value } = this.state; - this.state = { - color: 0, - value: '', - }; + if (value.length > 0) { + await addNewLocalContact(address, value, color); + onCloseModal(); + navigation.goBack(); + } } - componentDidMount = () => { - const newState = { - color: this.props.color, - value: '', - }; - if (this.props.contact.nickname) { - newState.value = this.props.contact.nickname; - } - this.setState(newState); + handleCancel = () => { + this.props.onUnmountModal('', 0, false); + this.props.onCloseModal(); + this.props.navigation.goBack(); } - format = (string) => ( - this.props.format - ? this.props.format(string) - : string - ) + handleChange = ({ nativeEvent: { text } }) => { + const value = text.charCodeAt(0) === 32 + ? text.substring(1) + : text; - onChange = (event) => { - const { nativeEvent } = event; - let value = nativeEvent.text; - if (value.charCodeAt(0) === 32) { - value = value.substring(1); - } this.setState({ value }); this.props.onUnmountModal(value, this.state.color, true); } - addContact = async () => { - if (this.state.value.length > 0) { - await addNewLocalContact(this.props.address, this.state.value, this.state.color); - this.props.onCloseModal(); - this.props.navigation.goBack(); + handleChangeColor = async () => { + const { color, value } = this.state; + + let newColor = color + 1; + if (newColor > colors.avatarColor.length - 1) { + newColor = 0; } - } - onChangeColor = async () => { - let newColor = this.state.color; - newColor = ++newColor > colors.avatarColor.length - 1 ? 0 : newColor++; this.setState({ color: newColor }); - this.props.onUnmountModal(this.state.value, newColor, true); + this.props.onUnmountModal(value, newColor, true); } - onDeleteContact = () => { - showActionSheetWithOptions({ - cancelButtonIndex: 1, - destructiveButtonIndex: 0, - options: ['Delete Contact', 'Cancel'], - }, async (buttonIndex) => { - if (buttonIndex === 0) { - this.props.onUnmountModal('', 0, false); - await deleteLocalContact(this.props.address); - this.props.onCloseModal(); - this.props.navigation.goBack(); - } - }); + handleDeleteContact = () => ( + showDeleteContactActionSheet({ + address: this.props.address, + nickname: this.state.value, + onDelete: this.handleCancel, + }) + ) + + handleFocusInput = () => { + if (this.inputRef) { + this.inputRef.focus(); + } } + handleInputRef = (ref) => { this.inputRef = ref; } + render() { + const { address, contact } = this.props; + const { color, value } = this.state; + return ( - - - - - - - - - - - {new GraphemeSplitter().splitGraphemes(this.state.value)[0]} - - - - - {this.state.value.length > 0 ? ' ' : 'Name'} - - - Keyboard.dismiss()}> - - - - - - - {!this.props.contact - ? { - this.props.onUnmountModal('', 0, false); - this.props.onCloseModal(); - this.props.navigation.goBack(); - }} - text="Cancel" - /> - : - } - - - - - - - + + + + + + + + + + {value.length > 0 ? ' ' : 'Name'} + + + + + + + + + + + + + {contact ? 'Delete Contact' : 'Cancel'} + + + + + + + ); } } -AddContactState.propTypes = { - address: PropTypes.string, - color: PropTypes.number, - contact: PropTypes.object, - format: PropTypes.func, - navigation: PropTypes.object, - onCloseModal: PropTypes.func, - onPressSend: PropTypes.func, - onUnmountModal: PropTypes.func, - price: PropTypes.string, - subtitle: PropTypes.string, - title: PropTypes.string, -}; - export default compose( withAccountData, withAccountSettings, - withProps(({ - contact: { - nickname, - ...contact - }, - address, - color, - assets, - nativeCurrencySymbol, - }) => { }), - withHandlers({ - onPressSend: ({ navigation, asset: { address } }) => () => { - navigation.goBack(); - - InteractionManager.runAfterInteractions(() => { - navigation.navigate('SendSheet', { asset: address }); - }); - }, - }), onlyUpdateForKeys(['price', 'subtitle']), )(AddContactState); diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index 516ddcceb3d..b2fc06093fa 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -4,7 +4,7 @@ import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { compose, onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components/primitives'; import { withKeyboardHeight } from '../../hoc'; -import { colors, padding, position } from '../../styles'; +import { padding, position } from '../../styles'; import { deviceUtils, safeAreaInsetValues } from '../../utils'; import Centered from './Centered'; @@ -20,7 +20,6 @@ const Container = styled.View` const InnerWrapper = styled(Centered)` ${padding(safeAreaInsetValues.top, 0, 10)}; ${position.size('100%')}; - background-color: ${colors.transparent}; `; class KeyboardFixedOpenLayout extends PureComponent { From 4ab9e3b541128485853ef335d9c6ba77d0ade41c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 21 Sep 2019 02:02:24 -0400 Subject: [PATCH 333/636] minor cleanup + fix typos --- src/components/contacts/SwipeableContactRow.js | 2 +- src/hoc/withUniswapAssets.js | 17 +++-------------- src/screens/SendSheet.js | 4 ++-- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index 718f1166cbb..07fbe7d47d4 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -82,7 +82,7 @@ export default class SwipeableContactRow extends PureComponent { handleDeleteContact = async () => { const { address, nickname, onChange } = this.props; this.close(); - showdeletecontactactionsheet({ + showDeleteContactActionSheet({ address, nickname, onDelete: onChange, diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 73b4fea11ed..73f85967e73 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -7,15 +7,9 @@ import { values, } from 'lodash'; import { connect } from 'react-redux'; -import { - compose, - withProps, -} from 'recompact'; +import { compose, withProps } from 'recompact'; import { createSelector } from 'reselect'; -import { - uniswapAssetAddresses, - uniswapAssetsClean, -} from '../references'; +import { uniswapAssetAddresses, uniswapAssetsClean } from '../references'; import withAccountData from './withAccountData'; const allAssetsSelector = state => state.allAssets; @@ -46,12 +40,7 @@ const withSortedUniswapAssetsSelector = createSelector( withSortedUniswapAssets, ); -const mapStateToProps = ({ - uniswap: { uniswapAssets }, -}) => ({ - uniswapAssets, -}); - +const mapStateToProps = ({ uniswap: { uniswapAssets } }) => ({ uniswapAssets }); export default compose( connect(mapStateToProps), diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 83740476329..9808c930f6d 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -41,7 +41,7 @@ const Container = styled(Column)` height: 100%; `; -const formatGastSpeedItem = (value, key) => { +const formatGasSpeedItem = (value, key) => { const cost = get(value, 'txFee.native.value.display'); const gwei = get(value, 'value.display'); const time = get(value, 'estimatedTime.display'); @@ -56,7 +56,7 @@ const formatGastSpeedItem = (value, key) => { const labelOrder = ['slow', 'average', 'fast']; const formatGasSpeedItems = (gasPrices) => { - const gasItems = map(gasPrices, formatGastSpeedItem); + const gasItems = map(gasPrices, formatGasSpeedItem); return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); }; From 5446071f56f4ae0397190f12dbfa4156db584283 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 21 Sep 2019 02:02:34 -0400 Subject: [PATCH 334/636] Cleanup AddressField --- src/components/fields/AddressField.js | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index c0b38dad175..4eafab90278 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -3,22 +3,14 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import styled from 'styled-components/primitives'; import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; -import { TextInput, Clipboard } from 'react-native'; -import { Row } from '../layout'; -import { colors, fonts } from '../../styles'; -import { Label } from '../text'; +import { Clipboard } from 'react-native'; import { isValidAddress } from '../../helpers/validators'; import { isHexString } from '../../handlers/web3'; +import { colors, fonts } from '../../styles'; import { abbreviations, addressUtils, isNewValueForPath } from '../../utils'; - -const AddressInput = styled(TextInput)` - flex-grow: 1; - font-family: ${fonts.family.SFProText}; - font-size: ${fonts.size.bmedium}; - font-weight: ${fonts.weight.semibold}; - margin-top: 1; - z-index: 1; -`; +import { Input } from '../inputs'; +import { Row } from '../layout'; +import { Label } from '../text'; const Placeholder = styled(Row)` position: absolute; @@ -125,7 +117,7 @@ export default class AddressField extends PureComponent { return ( - {!inputValue && ( From de0c474fadf219db0f58a8cdc81e57017916521f Mon Sep 17 00:00:00 2001 From: osdnk Date: Mon, 23 Sep 2019 18:41:14 +0200 Subject: [PATCH 335/636] bump to 4.0 --- package.json | 6 +- src/components/exchange/ExchangeAssetList.js | 3 +- src/navigation/transitions/effects.js | 33 ++++++--- src/screens/CurrencySelectModal.js | 8 +++ src/screens/Routes.js | 2 +- yarn.lock | 71 +++++++------------- 6 files changed, 62 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 952fe19a008..543a0ec8651 100644 --- a/package.json +++ b/package.json @@ -103,9 +103,9 @@ "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", - "react-navigation": "3.11.1", - "react-navigation-stack": "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", - "react-navigation-tabs": "2.3.0", + "react-navigation": "4.0.7", + "react-navigation-stack": "2.0.0-alpha.16", + "react-navigation-tabs": "2.5.5", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index f4ae3e3640b..7b76b19d551 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -67,7 +67,7 @@ export default class ExchangeAssetList extends PureComponent { componentDidUpdate = (prevProps, prevState) => { if (this.props.items.length !== prevProps.items.length) { - this.rlvRef.current.forceRerender(); + //this.rlvRef.current.forceRerender(); this.updateList(); } } @@ -97,6 +97,7 @@ export default class ExchangeAssetList extends PureComponent { onViewableItemsChanged={this.onViewableItemsChanged} optimizeForInsertDeleteAnimations={true} ref={this.rlvRef} + disableRecycling={true} renderAheadOffset={deviceUtils.dimensions.height} rowRenderer={this.renderRow} scrollViewProps={{ diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index b4eba1c28d7..7dc7a1f226b 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -32,7 +32,7 @@ export const sheetVerticalOffset = statusBarHeight; const expandStyleInterpolator = ({ closing, layouts: { screen }, - progress: { current }, + current: { progress: current }, }) => { const backgroundOpacity = interpolate(current, { extrapolate: 'clamp', @@ -67,8 +67,9 @@ const expandStyleInterpolator = ({ }; const sheetStyleInterpolator = ({ - progress: { current }, + current: { progress: current }, layouts: { screen }, + ...rest }) => { const backgroundOpacity = interpolate(current, { extrapolate: 'clamp', @@ -76,10 +77,14 @@ const sheetStyleInterpolator = ({ outputRange: [0, 0.7], }); - const translateY = interpolate(current, { - inputRange: [0, 1], - outputRange: [screen.height, statusBarHeight], - }); + console.log('tttt', current); + + const translateY = block([ + call([current], ([currentd]) => console.log(currentd, 'llllll', rest)), + interpolate(current, { + inputRange: [0, 1], + outputRange: [screen.height, statusBarHeight], + })]); return { cardStyle: { @@ -95,7 +100,10 @@ const sheetStyleInterpolator = ({ }; }; -const backgroundInterpolator = ({ progress: { next } }) => { +const backgroundInterpolator = ({ next: { progress: next } = { next: undefined } }) => { + if (next === undefined) { + return { cardStyle: {} }; + } const dispatch = cond(call([], () => { store.dispatch(updateStackTransitionProps({ position: next })); })); @@ -108,8 +116,9 @@ const closeSpec = { bounciness: 0, overshootClamping: true, speed: 20, + mass: 1, }), - timing: 'spring', + animation: 'spring', }; const openSpec = { @@ -117,10 +126,12 @@ const openSpec = { ...SpringUtils.makeDefaultConfig(), bounciness: 5, speed: 20, + mass: 1, }), - timing: 'spring', + animation: 'spring', }; + const gestureResponseDistance = { vertical: deviceUtils.dimensions.height, }; @@ -138,7 +149,7 @@ export const expandedPreset = { cardStyleInterpolator: expandStyleInterpolator, cardTransparent: true, gestureDirection: 'vertical', - gestureResponseDistance, + // gestureResponseDistance, onTransitionStart, transitionSpec: { close: closeSpec, open: openSpec }, }; @@ -147,7 +158,7 @@ export const sheetPreset = { cardStyleInterpolator: sheetStyleInterpolator, cardTransparent: true, gestureDirection: 'vertical', - gestureResponseDistance, + //gestureResponseDistance, onTransitionStart, transitionSpec: { close: closeSpec, open: openSpec }, }; diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 6a92e979cd7..ae0f0ca1327 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -113,11 +113,17 @@ class CurrencySelectModal extends PureComponent { const nextAssetsUniqueId = buildUniqueIdForListData(nextAssets); const isNewAssets = currentAssetsUniqueId !== nextAssetsUniqueId; + console.log(this.props, nextProps) const isNewFocus = isNewValueForPath(this.props, nextProps, 'isFocused'); const isNewSearchQuery = isNewValueForPath(this.state, nextState, 'searchQuery'); const isNewTransitioning = isNewValueForPath(this.props, nextProps, 'isTransitioning'); const isNewType = isNewValueForPath(this.props, nextProps, 'type'); + console.log( isNewAssets + , isNewFocus + , isNewSearchQuery + , isNewTransitioning + , isNewType) return ( isNewAssets || isNewFocus @@ -128,6 +134,7 @@ class CurrencySelectModal extends PureComponent { } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { + console.error('xxx', isGestureBlocked) // dangerouslyGetParent is a bad pattern in general, but in this case is exactly what we expect this.props.navigation.dangerouslyGetParent().setParams({ isGestureBlocked }); } @@ -215,6 +222,7 @@ class CurrencySelectModal extends PureComponent { > console.log("XXXxx§")} onWillBlur={this.handleWillBlur} onWillFocus={this.handleWillFocus} /> diff --git a/src/screens/Routes.js b/src/screens/Routes.js index dd48f54abef..42dbc9378b4 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -3,8 +3,8 @@ import { get } from 'lodash'; import React from 'react'; import { createAppContainer, - createMaterialTopTabNavigator, } from 'react-navigation'; +import { createMaterialTopTabNavigator } from 'react-navigation-tabs' import { createStackNavigator } from 'react-navigation-stack'; import { ExchangeModalNavigator, Navigation } from '../navigation'; import { updateStackTransitionProps } from '../redux/navigation'; diff --git a/yarn.lock b/yarn.lock index 21fbe11b440..5a303476676 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1094,20 +1094,20 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== -"@react-navigation/core@~3.4.1": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.4.2.tgz#bec563e94fde40fbab3730cdc97f22afbb2a1498" - integrity sha512-7G+iDzLSTeOUU4vVZeRZKJ+Bd7ds7ZxYNqZcB8i0KlBeQEQfR74Ounfu/p0KIEq2RiNnaE3QT7WVP3C87sebzw== +"@react-navigation/core@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.1.tgz#7a2339fca3496979305fb3a8ab88c2ca8d8c214d" + integrity sha512-q7NyhWVYOhVIWqL2GZKa6G78YarXaVTTtOlSDkvy4ZIggo40wZzamlnrJRvsaQX46gsgw45FAWb5SriHh8o7eA== dependencies: hoist-non-react-statics "^3.3.0" path-to-regexp "^1.7.0" query-string "^6.4.2" react-is "^16.8.6" -"@react-navigation/native@~3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.5.0.tgz#f5d16e0845ac26d1147d1caa481f18a00740e7ae" - integrity sha512-TmGOis++ejEXG3sqNJhCSKqB0/qLu3FQgDtO959qpqif36R/diR8SQwJqeSdofoEiK3CepdhFlTCeHdS1/+MsQ== +"@react-navigation/native@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.6.2.tgz#3634697b6350cc5189657ae4551f2d52b57fbbf0" + integrity sha512-Cybeou6N82ZeRmgnGlu+wzlV3z5BZQR2dmYaNFV1TNLUGHqtvv8E7oNw9uYcz9Ox5LFbiX+FdNTn2d6ZPlK0kg== dependencies: hoist-non-react-statics "^3.0.1" react-native-safe-area-view "^0.14.1" @@ -4980,7 +4980,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: +hoist-non-react-statics@^2.3.1: version "2.5.5" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== @@ -8842,13 +8842,6 @@ react-native-svg@9.7.1: resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.7.1.tgz#a6d270cd51f8f238de7623338211debf4ff9cf5c" integrity sha512-Yr54SyLPCdovLCJ08V7syJUe1iKrTYG9V5wB08z6lh/9FdC2R9CtBnMyz83GDLKfzUONqqH9nN1l+o61CgD3tg== -react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-1.4.1.tgz#f113cd87485808f0c991abec937f70fa380478b9" - integrity sha512-Bke8KkDcDhvB/z0AS7MnQKMD2p6Kwfc1rSKlMOvg9CC5CnClQ2QEnhPSbwegKDYhUkBI92iH/BYy7hNSm5kbUQ== - dependencies: - prop-types "^15.6.1" - react-native-tab-view@^2.9.0: version "2.10.0" resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.0.tgz#5e249e5650502010013449ffd4e5edc18a95364b" @@ -8930,48 +8923,36 @@ react-native@0.60.5: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-drawer@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.2.1.tgz#7bd5efeee7d2f611d3ebb0933e0c8e8eb7cafe52" - integrity sha512-T2kaBjY2c4/3I6noWFnaf/c18ntNH5DsST38i+pdc2NPxn5Yi5lkK+ZZTeKuHSFD4a7G0jWY9OGf1iRkHWLMAQ== +react-navigation-stack@2.0.0-alpha.16: + version "2.0.0-alpha.16" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.16.tgz#04a45c901ca86af8393294131a857774866e5500" + integrity sha512-RJR2UIknMpgLBbhUyB418A3o+n5o83eLa9aDdS8O2iC4Tz5o0JOTQD1455j5SqJVhLulsmofJPBsLwKJvlY7MA== dependencies: - react-native-tab-view "^1.2.0" + react-native-safe-area-view "^0.14.6" -"react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03", react-navigation-stack@~1.4.0: +"react-navigation-stack@https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03": version "2.0.0-alpha.7" resolved "https://github.com/react-navigation/stack#95fe56e11b6f8bca3c4d24b619295651944d4d03" dependencies: react-native-safe-area-view "^0.14.6" -react-navigation-tabs@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.3.0.tgz#0288830e6ac5157f203ee3947bc29b0d6eda66b1" - integrity sha512-0LiTwXEVt7XdzVT02fvg14NMz90zfPUyw1g2mIrWA70+M56br5k6tXKrZg8NjH1MgWVz5TWBx90SI0MhD2OssA== +react-navigation-tabs@2.5.5: + version "2.5.5" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.5.tgz#f651355b140b35ef5753aac434da5e1943abdd26" + integrity sha512-oIL5V4agCxcqbWNZzF1h/cm1bxKXNUeGrWaRQEEnuN3TXTEj1SVRz33CnKYg30pVvgF5L2p28sOk15Z4Ao01NQ== dependencies: hoist-non-react-statics "^3.3.0" react-lifecycles-compat "^3.0.4" + react-native-safe-area-view "^0.14.6" react-native-tab-view "^2.9.0" -react-navigation-tabs@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz#00a312250df3c519c60b7815a523ace5ee11163a" - integrity sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ== +react-navigation@4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.0.7.tgz#cc7ce334fef009242494d623e50e9cf79eb63ddd" + integrity sha512-0tTWanq870Hyr1VGHuj98+myRHNQnKgpRgjgzhAwVuLShyPIB9OnoLGIwIcqEdxgxGo+JMFmIGg8KCr7xapfgg== dependencies: - hoist-non-react-statics "^2.5.0" - prop-types "^15.6.1" - react-lifecycles-compat "^3.0.4" - react-native-tab-view "^1.4.1" - -react-navigation@3.11.1: - version "3.11.1" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.1.tgz#ba696ad6b512088a97a20cc7e6a250c53dbddd26" - integrity sha512-n64HxLG5s5ucVFo1Gs+D9ujChhHDd98lpQ1p27wL7gq8V1PaRJMvsBEIsguhtc2rTIL/TWDynOesXQDG+Eg6FQ== - dependencies: - "@react-navigation/core" "~3.4.1" - "@react-navigation/native" "~3.5.0" - react-navigation-drawer "~1.2.1" - react-navigation-stack "~1.4.0" - react-navigation-tabs "~1.1.4" + "@react-navigation/core" "^3.5.1" + "@react-navigation/native" "^3.6.2" react-primitives@^0.8.0: version "0.8.0" From 85403b67e88f34588dee41a970bca76f1b1a0128 Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 24 Sep 2019 19:52:34 +0200 Subject: [PATCH 336/636] Fix gestures enabled --- package.json | 2 +- src/navigation/ExchangeModalNavigator.js | 2 +- src/screens/CurrencySelectModal.js | 10 +--------- yarn.lock | 8 ++++---- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 543a0ec8651..89b4cd769ea 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.7", - "react-navigation-stack": "2.0.0-alpha.16", + "react-navigation-stack": "2.0.0-alpha.18", "react-navigation-tabs": "2.5.5", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", diff --git a/src/navigation/ExchangeModalNavigator.js b/src/navigation/ExchangeModalNavigator.js index 0b78b523ce6..3d7c829150f 100644 --- a/src/navigation/ExchangeModalNavigator.js +++ b/src/navigation/ExchangeModalNavigator.js @@ -61,7 +61,7 @@ EnhancedExchangeModalNavigator.navigationOptions = ({ navigation }) => { return ({ ...navigation.state.params, - gesturesEnabled: !get(navigation, 'state.params.isGestureBlocked'), + gestureEnabled: !get(navigation, 'state.params.isGestureBlocked'), }); }; diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index ae0f0ca1327..05bb13a0e8e 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -113,17 +113,11 @@ class CurrencySelectModal extends PureComponent { const nextAssetsUniqueId = buildUniqueIdForListData(nextAssets); const isNewAssets = currentAssetsUniqueId !== nextAssetsUniqueId; - console.log(this.props, nextProps) const isNewFocus = isNewValueForPath(this.props, nextProps, 'isFocused'); const isNewSearchQuery = isNewValueForPath(this.state, nextState, 'searchQuery'); const isNewTransitioning = isNewValueForPath(this.props, nextProps, 'isTransitioning'); const isNewType = isNewValueForPath(this.props, nextProps, 'type'); - console.log( isNewAssets - , isNewFocus - , isNewSearchQuery - , isNewTransitioning - , isNewType) return ( isNewAssets || isNewFocus @@ -134,7 +128,6 @@ class CurrencySelectModal extends PureComponent { } dangerouslySetIsGestureBlocked = (isGestureBlocked) => { - console.error('xxx', isGestureBlocked) // dangerouslyGetParent is a bad pattern in general, but in this case is exactly what we expect this.props.navigation.dangerouslyGetParent().setParams({ isGestureBlocked }); } @@ -222,7 +215,6 @@ class CurrencySelectModal extends PureComponent { > console.log("XXXxx§")} onWillBlur={this.handleWillBlur} onWillFocus={this.handleWillFocus} /> @@ -280,7 +272,7 @@ export default compose( navigation, sortedUniswapAssets, tabsTransitionProps: { isTransitioning }, - ...props, + ...props }) => ({ ...props, assetsAvailableOnUniswap: normalizeAssetItems(assetsAvailableOnUniswap), diff --git a/yarn.lock b/yarn.lock index 5a303476676..14618c661ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8923,10 +8923,10 @@ react-native@0.60.5: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.16: - version "2.0.0-alpha.16" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.16.tgz#04a45c901ca86af8393294131a857774866e5500" - integrity sha512-RJR2UIknMpgLBbhUyB418A3o+n5o83eLa9aDdS8O2iC4Tz5o0JOTQD1455j5SqJVhLulsmofJPBsLwKJvlY7MA== +react-navigation-stack@2.0.0-alpha.18: + version "2.0.0-alpha.18" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.18.tgz#9f5e145a30ad861e26c94066fbc89641dee1dc90" + integrity sha512-uUOGLn+QUL5BmcP2DkDoaE2ds9kEM1uRyaKIfQYTbHOUsfyJfvCdK/+YqK/u+BER6ZIZi8VMLejz1zTH/RbwBg== dependencies: react-native-safe-area-view "^0.14.6" From 050c227995a7c4e56efe6eb55f1bfe08917f557f Mon Sep 17 00:00:00 2001 From: osdnk Date: Wed, 25 Sep 2019 18:03:29 +0200 Subject: [PATCH 337/636] Fix callbacks and keyboard handling --- package.json | 2 +- src/screens/ExchangeModal.js | 2 +- src/screens/Routes.js | 12 ++++++++++-- yarn.lock | 8 ++++---- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 89b4cd769ea..e7bd3b2cf53 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.7", - "react-navigation-stack": "2.0.0-alpha.18", + "react-navigation-stack": "2.0.0-alpha.19", "react-navigation-tabs": "2.5.5", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 24beb970972..f8f50c04010 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -133,7 +133,7 @@ class ExchangeModal extends PureComponent { } = this.props; if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { - const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 2]; + const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 1]; if (lastFocusedInput) { InteractionManager.runAfterInteractions(() => { diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 42dbc9378b4..881496d3b91 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -4,7 +4,7 @@ import React from 'react'; import { createAppContainer, } from 'react-navigation'; -import { createMaterialTopTabNavigator } from 'react-navigation-tabs' +import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; import { createStackNavigator } from 'react-navigation-stack'; import { ExchangeModalNavigator, Navigation } from '../navigation'; import { updateStackTransitionProps } from '../redux/navigation'; @@ -69,6 +69,7 @@ const MainNavigator = createStackNavigator({ ConfirmRequest: { navigationOptions: { ...expandedPreset, + onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, }, screen: TransactionConfirmationScreenWithData, }, @@ -79,6 +80,7 @@ const MainNavigator = createStackNavigator({ gestureResponseDistance: { vertical: deviceUtils.dimensions.height, }, + onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, }, params: { isGestureBlocked: false, @@ -88,18 +90,21 @@ const MainNavigator = createStackNavigator({ ExpandedAssetScreen: { navigationOptions: { ...expandedPreset, + onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, }, screen: ExpandedAssetScreenWithData, }, ImportSeedPhraseSheet: { navigationOptions: { ...sheetPreset, + onTransitionStart: props => { sheetPreset.onTransitionStart(props); onTransitionStart(); }, }, screen: ImportSeedPhraseSheetWithData, }, ReceiveModal: { navigationOptions: { ...expandedPreset, + onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, }, screen: ReceiveModal, }, @@ -107,7 +112,8 @@ const MainNavigator = createStackNavigator({ navigationOptions: { ...sheetPreset, onTransitionStart: props => { - onTransitionStartEffect(props); + onTransitionStart(props); + sheetPreset.onTransitionStart(props) restoreKeyboard(); }, }, @@ -117,6 +123,7 @@ const MainNavigator = createStackNavigator({ navigationOptions: { gesturesEnabled: false, ...expandedPreset, + onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, }, screen: SettingsModal, transparentCard: true, @@ -131,6 +138,7 @@ const MainNavigator = createStackNavigator({ WalletConnectConfirmationModal: { navigationOptions: { ...expandedPreset, + onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, }, screen: WalletConnectConfirmationModal, }, diff --git a/yarn.lock b/yarn.lock index 14618c661ac..d448cbcb0a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8923,10 +8923,10 @@ react-native@0.60.5: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.18: - version "2.0.0-alpha.18" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.18.tgz#9f5e145a30ad861e26c94066fbc89641dee1dc90" - integrity sha512-uUOGLn+QUL5BmcP2DkDoaE2ds9kEM1uRyaKIfQYTbHOUsfyJfvCdK/+YqK/u+BER6ZIZi8VMLejz1zTH/RbwBg== +react-navigation-stack@2.0.0-alpha.19: + version "2.0.0-alpha.19" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.19.tgz#2152433ef8ef5623b76c35cf1837da978fd223be" + integrity sha512-5fKoUeUtT3InRqH2IuDD/mBjmiB4u8zvrBiYqNo1VkcK8F2XiG2aN648CCgC41hGoEmyF+xExRbhl/qyVsvhRA== dependencies: react-native-safe-area-view "^0.14.6" From e50a0cfd2691e497a857a6f2ba38984e17a83d9b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 25 Sep 2019 18:56:22 -0400 Subject: [PATCH 338/636] update yarn.lock --- ios/Podfile.lock | 4 +- .../xcshareddata/xcschemes/Rainbow.xcscheme | 22 +- yarn.lock | 415 +++++++++--------- 3 files changed, 224 insertions(+), 217 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1fc9cb9db4c..72a0fe5c7a3 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -118,7 +118,7 @@ PODS: - react-native-fast-image (6.1.1): - React - SDWebImage (~> 5.0) - - react-native-netinfo (4.2.1): + - react-native-netinfo (4.2.2): - React - react-native-version-number (0.3.6): - React @@ -334,7 +334,7 @@ SPEC CHECKSUMS: react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-fast-image: fdfc612dba58fd73136cf5efdaeb8cfcad7f63b2 - react-native-netinfo: aeb1752abb78a9c15cdcea067a6c95d596dcfc45 + react-native-netinfo: 2bb2e5094edcfecfb340a85053608526cb20f185 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 0d412b7196d..10146fdb417 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -55,6 +55,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -67,17 +76,6 @@ - - - - - - - - =7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48" - integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.2.tgz#069a776e8d5e9eefff76236bc8845566bd31dd91" + integrity sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.0" - "@babel/helpers" "^7.6.0" - "@babel/parser" "^7.6.0" + "@babel/generator" "^7.6.2" + "@babel/helpers" "^7.6.2" + "@babel/parser" "^7.6.2" "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.0" + "@babel/traverse" "^7.6.2" "@babel/types" "^7.6.0" convert-source-map "^1.1.0" debug "^4.1.0" @@ -29,16 +29,15 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56" - integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.2.tgz#dac8a3c2df118334c2a29ff3446da1636a8f8c03" + integrity sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ== dependencies: "@babel/types" "^7.6.0" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" - trim-right "^1.0.1" "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" @@ -215,13 +214,13 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e" - integrity sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ== +"@babel/helpers@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.2.tgz#681ffe489ea4dcc55f23ce469e58e59c1c045153" + integrity sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA== dependencies: "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.0" + "@babel/traverse" "^7.6.2" "@babel/types" "^7.6.0" "@babel/highlight@^7.0.0": @@ -233,10 +232,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b" - integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0", "@babel/parser@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.2.tgz#205e9c95e16ba3b8b96090677a67c9d6075b70a1" + integrity sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -270,9 +269,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" - integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096" + integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -387,9 +386,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz#c49e21228c4bbd4068a35667e6d951c75439b1dc" - integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz#96c33ab97a9ae500cc6f5b19e04a7e6553360a79" + integrity sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" @@ -540,9 +539,9 @@ regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e" - integrity sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz#2669f67c1fae0ae8d8bf696e4263ad52cb98b6f8" + integrity sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -557,9 +556,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-spread@^7.0.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd" + integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -589,18 +588,18 @@ "@babel/plugin-syntax-typescript" "^7.2.0" "@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz#b692aad888a7e8d8b1b214be6b9dc03d5031f698" + integrity sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + regexpu-core "^4.6.0" "@babel/register@^7.0.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.0.tgz#76b6f466714680f4becafd45beeb2a7b87431abf" - integrity sha512-78BomdN8el+x/nkup9KwtjJXuptW5oXMFmP11WoM2VJBjxrKv4grC3qjpLL8RGGUYUGsm57xnjYFM2uom+jWUQ== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.2.tgz#25765a922202cb06f8bdac5a3b1e70cd6bf3dd45" + integrity sha512-xgZk2LRZvt6i2SAUWxc7ellk4+OYRgS3Zpsnr13nMS1Qo25w21Uu8o6vTOAqNaxiqrnv30KTYzh9YWY2k21CeQ== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.13" @@ -609,9 +608,9 @@ source-map-support "^0.5.9" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" - integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd" + integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg== dependencies: regenerator-runtime "^0.13.2" @@ -624,16 +623,16 @@ "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516" - integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.2.tgz#b0e2bfd401d339ce0e6c05690206d1e11502ce2c" + integrity sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.0" + "@babel/generator" "^7.6.2" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.6.0" + "@babel/parser" "^7.6.2" "@babel/types" "^7.6.0" debug "^4.1.0" globals "^11.1.0" @@ -671,21 +670,21 @@ "@emotion/memoize" "0.7.1" "@emotion/is-prop-valid@^0.8.1": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.2.tgz#b9692080da79041683021fcc32f96b40c54c59dc" - integrity sha512-ZQIMAA2kLUWiUeMZNJDTeCwYRx1l8SQL0kHktze4COT22occKpDML1GDUXP5/sxhOMrZO8vZw773ni4H5Snrsg== + version "0.8.3" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.3.tgz#cbe62ddbea08aa022cdf72da3971570a33190d29" + integrity sha512-We7VBiltAJ70KQA0dWkdPMXnYoizlxOXpvtjmu5/MBnExd+u0PGgV27WCYanmLAbCwAU30Le/xA0CQs/F/Otig== dependencies: - "@emotion/memoize" "0.7.2" + "@emotion/memoize" "0.7.3" "@emotion/memoize@0.7.1": version "0.7.1" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f" integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg== -"@emotion/memoize@0.7.2": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.2.tgz#7f4c71b7654068dfcccad29553520f984cc66b30" - integrity sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w== +"@emotion/memoize@0.7.3": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78" + integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow== "@emotion/stylis@^0.8.3": version "0.8.4" @@ -770,9 +769,9 @@ "@ethersproject/logger" ">=5.0.0-beta.129" "@hapi/address@2.x.x": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.1.tgz#61395b5ed94c4cb19c2dc4c85969cff3d40d583f" - integrity sha512-DYuHzu978pP1XW1GD3HGvLnAFjbQTIgc2+V153FGkbS2pgo9haigCdwBnUDrbhaOkgiJlbZvoEqDrcxSLHpiWA== + version "2.1.2" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.2.tgz#1c794cd6dbf2354d1eb1ef10e0303f573e1c7222" + integrity sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q== "@hapi/bourne@1.x.x": version "1.3.2" @@ -795,9 +794,9 @@ "@hapi/topo" "3.x.x" "@hapi/topo@3.x.x": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.3.tgz#c7a02e0d936596d29f184e6d7fdc07e8b5efce11" - integrity sha512-JmS9/vQK6dcUYn7wc2YZTqzIKubAQcJKu2KCKAru6es482U5RT5fP1EXCPtlXpiK7PR0On/kpQKI4fRKkzpZBQ== + version "3.1.4" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.4.tgz#42e2fe36f593d90ad258a08b582be128c141c45d" + integrity sha512-aVWQTOI9wBD6zawmOr6f+tdEIxQC8JXfQVLTjgGe8YEStAWGn/GNNVTobKJhbWKveQj2RyYF3oYbO9SC8/eOCA== dependencies: "@hapi/hoek" "8.x.x" @@ -1090,9 +1089,9 @@ integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== "@react-native-community/netinfo@^4.1.4": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.1.tgz#b6309f078da500807ef8afa4d659e56ccd14dee4" - integrity sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA== + version "4.2.2" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.2.2.tgz#15035730a230e743b2e5429f2bbd75b0851a4b98" + integrity sha512-ktMlUCYn+vKL8PQH/e6Vpoygvn3gU+Ibc1uD7m+pYhQwiKHD7eqCRAkR1Xt5vc2L3Xy3N1z0tMXlxzK4IKbYyQ== "@react-navigation/core@~3.4.1": version "3.4.2" @@ -1151,10 +1150,10 @@ resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165" integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w== -"@svgr/babel-plugin-svg-dynamic-title@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.1.tgz#646c2f5b5770c2fe318d6e51492344c3d62ddb63" - integrity sha512-p6z6JJroP989jHWcuraeWpzdejehTmLUpyC9smhTBWyPN0VVGe2phbYxpPTV7Vh8XzmFrcG55idrnfWn/2oQEw== +"@svgr/babel-plugin-svg-dynamic-title@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz#2cdedd747e5b1b29ed4c241e46256aac8110dd93" + integrity sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w== "@svgr/babel-plugin-svg-em-dimensions@^4.2.0": version "4.2.0" @@ -1171,27 +1170,27 @@ resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697" integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw== -"@svgr/babel-preset@^4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.1.tgz#62ffcb85d756580e8ce608e9d2ac3b9063be9e28" - integrity sha512-rPFKLmyhlh6oeBv3j2vEAj2nd2QbWqpoJLKzBLjwQVt+d9aeXajVaPNEqrES2spjXKR4OxfgSs7U0NtmAEkr0Q== +"@svgr/babel-preset@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.3.tgz#a75d8c2f202ac0e5774e6bfc165d028b39a1316c" + integrity sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A== dependencies: "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0" "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0" "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0" "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0" - "@svgr/babel-plugin-svg-dynamic-title" "^4.3.1" + "@svgr/babel-plugin-svg-dynamic-title" "^4.3.3" "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0" "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0" "@svgr/babel-plugin-transform-svg-component" "^4.2.0" "@svgr/cli@^4.3.0": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.2.tgz#fb20fd33429f0d0dfc6c7178e8bfc1e86006e9de" - integrity sha512-QdYzVgsowOWpOwkX+3+EK6zxlttADc2v6t0Baj2xETAdhBcpFAf/nZ0xw6b5zxdbGk8fm3nxJyPUddYuBkgzpg== + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-4.3.3.tgz#90b3acd1e1067b73a4dd6a768eea86d0dccf975c" + integrity sha512-FHsb9+2zMy9XZgEBFEh+1iofE0TBQn7OnJ9JF/2YimdyE93u2/j1p1K71+rJQ0GWKy96aSSbFWkRVR1i3zATOQ== dependencies: - "@svgr/core" "^4.3.2" - "@svgr/plugin-jsx" "^4.3.2" + "@svgr/core" "^4.3.3" + "@svgr/plugin-jsx" "^4.3.3" "@svgr/plugin-prettier" "^4.3.2" "@svgr/plugin-svgo" "^4.3.1" camelcase "^5.3.1" @@ -1202,12 +1201,12 @@ output-file-sync "^2.0.1" recursive-readdir "^2.2.2" -"@svgr/core@^4.3.2": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.2.tgz#939c89be670ad79b762f4c063f213f0e02535f2e" - integrity sha512-N+tP5CLFd1hP9RpO83QJPZY3NL8AtrdqNbuhRgBkjE/49RnMrrRsFm1wY8pueUfAGvzn6tSXUq29o6ah8RuR5w== +"@svgr/core@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.3.tgz#b37b89d5b757dc66e8c74156d00c368338d24293" + integrity sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w== dependencies: - "@svgr/plugin-jsx" "^4.3.2" + "@svgr/plugin-jsx" "^4.3.3" camelcase "^5.3.1" cosmiconfig "^5.2.1" @@ -1218,13 +1217,13 @@ dependencies: "@babel/types" "^7.4.4" -"@svgr/plugin-jsx@^4.3.2": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.2.tgz#ce9ddafc8cdd74da884c9f7af014afcf37f93d3c" - integrity sha512-+1GW32RvmNmCsOkMoclA/TppNjHPLMnNZG3/Ecscxawp051XJ2MkO09Hn11VcotdC2EPrDfT8pELGRo+kbZ1Eg== +"@svgr/plugin-jsx@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz#e2ba913dbdfbe85252a34db101abc7ebd50992fa" + integrity sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w== dependencies: "@babel/core" "^7.4.5" - "@svgr/babel-preset" "^4.3.1" + "@svgr/babel-preset" "^4.3.3" "@svgr/hast-util-to-babel-ast" "^4.3.2" svg-parser "^2.0.0" @@ -1265,9 +1264,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" - integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== + version "7.6.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.0.tgz#f1ec1c104d1bb463556ecb724018ab788d0c172a" + integrity sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw== dependencies: "@babel/types" "^7.0.0" @@ -1336,14 +1335,14 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.7.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" - integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== + version "12.7.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.7.tgz#f9bd8c00fa9e1a8129af910fc829f6139c397d6c" + integrity sha512-4jUncNe2tj1nmrO/34PsRpZqYVnRV1svbU78cKhuQKkMntKB/AmdLyGgswcZKjFHEHGpiY8pVD8CuVI55nP54w== "@types/node@^10.3.2": - version "10.14.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.18.tgz#b7d45fc950e6ffd7edc685e890d13aa7b8535dce" - integrity sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ== + version "10.14.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.19.tgz#f52742c7834a815dedf66edfc8a51547e2a67342" + integrity sha512-j6Sqt38ssdMKutXBUuAcmWF8QtHW1Fwz/mz4Y+Wd9mzpBiVFirjpNQf363hG5itkG+yGaD+oiLyb50HxJ36l9Q== "@types/node@^8.0.7": version "8.10.54" @@ -1388,9 +1387,9 @@ integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== "@types/yargs@^13.0.0": - version "13.0.2" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.2.tgz#a64674fc0149574ecd90ba746e932b5a5f7b3653" - integrity sha512-lwwgizwk/bIIU+3ELORkyuOgDjCh7zuWDFqRtPPhhVgq9N1F7CvLNKg1TX4f2duwtKQ0p044Au9r1PLIXHrIzQ== + version "13.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" + integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== dependencies: "@types/yargs-parser" "*" @@ -1485,9 +1484,9 @@ Base64@~0.2.0: integrity sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg= abab@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.1.tgz#3fa17797032b71410ec372e11668f4b4ffc86a82" - integrity sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw== + version "2.0.2" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.2.tgz#a2fba1b122c69a85caa02d10f9270c7219709a9d" + integrity sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg== abbrev@1: version "1.1.1" @@ -1562,9 +1561,9 @@ acorn@^6.0.1: integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== acorn@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a" - integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ== + version "7.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" + integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== aes-js@3.0.0: version "3.0.0" @@ -2197,9 +2196,9 @@ better-assert@~1.0.0: callsite "1.0.0" big-integer@^1.6.7: - version "1.6.44" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.44.tgz#4ee9ae5f5839fc11ade338fea216b4513454a539" - integrity sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ== + version "1.6.45" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.45.tgz#1bf2fa1271bfd20d4c52c3d6c6f08cab8d91c77e" + integrity sha512-nmb9E7oEtVJ7SmSCH/DeJobXyuRmaofkpoQSimMFu3HKJ5MADtM825SPLhDuWhZ6TElLAQtgJbQmBZuHIRlZoA== bignumber.js@^8.1.1: version "8.1.1" @@ -2532,9 +2531,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== + version "1.0.30000997" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz#ba44a606804f8680894b7042612c2c7f65685b7e" + integrity sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA== capture-exit@^2.0.0: version "2.0.0" @@ -2623,9 +2622,9 @@ child-process-promise@^2.2.0: promise-polyfill "^6.0.1" chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== chroma-js@^1.3.7: version "1.4.1" @@ -2823,9 +2822,9 @@ colorette@^1.0.7: integrity sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg== colors@^1.0.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" - integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" @@ -2917,9 +2916,9 @@ configstore@^3.0.0: xdg-basedir "^3.0.0" confusing-browser-globals@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz#93ffec1f82a6e2bf2bc36769cc3a92fa20e502f3" - integrity sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg== + version "1.0.9" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" + integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== connect@^3.6.5: version "3.7.0" @@ -3225,7 +3224,7 @@ debug@3.2.6, debug@^3.1.0, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -3548,15 +3547,15 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.6.2: +ejs@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.247: - version "1.3.260" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.260.tgz#ffd686b4810bab0e1a428e7af5f08c21fe7c1fa2" - integrity sha512-wGt+OivF1C1MPwaSv3LJ96ebNbLAWlx3HndivDDWqwIVSQxmhL17Y/YmwUdEMtS/bPyommELt47Dct0/VZNQBQ== + version "1.3.266" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.266.tgz#a33fb529c75f8d133e75ea7cbedb73a62f2158d2" + integrity sha512-UTuTZ4v8T0gLPHI7U75PXLQePWI65MTS3mckRrnLCkNljHvsutbYs+hn2Ua/RFul3Jt/L3Ht2rLP+dU/AlBfrQ== elliptic@6.3.3: version "6.3.3" @@ -3604,21 +3603,21 @@ encoding@^0.1.11: iconv-lite "~0.4.13" end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -engine.io-client@~3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.3.2.tgz#04e068798d75beda14375a264bb3d742d7bc33aa" - integrity sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ== +engine.io-client@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" + integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== dependencies: component-emitter "1.2.1" component-inherit "0.0.3" - debug "~3.1.0" - engine.io-parser "~2.1.1" + debug "~4.1.0" + engine.io-parser "~2.2.0" has-cors "1.1.0" indexof "0.0.1" parseqs "0.0.5" @@ -3627,10 +3626,10 @@ engine.io-client@~3.3.1: xmlhttprequest-ssl "~1.5.4" yeast "0.1.2" -engine.io-parser@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" - integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== dependencies: after "0.8.2" arraybuffer.slice "~0.0.7" @@ -3649,9 +3648,9 @@ entities@^2.0.0: integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== envinfo@^7.1.0: - version "7.3.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" - integrity sha512-GvXiDTqLYrORVSCuJCsWHPXF5BFvoWMQA9xX4YVjPT1jyS3aZEHUBwjzxU/6LTPF9ReHgVEbX7IEN5UvSXHw/A== + version "7.4.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.4.0.tgz#bef4ece9e717423aaf0c3584651430b735ad6630" + integrity sha512-FdDfnWnCVjxTTpWE3d6Jgh5JDIA3Cw7LCgpM/pI7kK1ORkjaqI2r6NqQ+ln2j0dfpgxY00AWieSvtkiZQKIItA== errno@^0.1.1, errno@~0.1.1: version "0.1.7" @@ -4548,11 +4547,11 @@ fs-extra@^7.0.1: universalify "^0.1.0" fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: - minipass "^2.2.1" + minipass "^2.6.0" fs.realpath@^1.0.0: version "1.0.0" @@ -4685,9 +4684,9 @@ glob-parent@^3.1.0: path-dirname "^1.0.0" glob-parent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" - integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== dependencies: is-glob "^4.0.1" @@ -4847,9 +4846,9 @@ hammerjs@^2.0.8: integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= handlebars@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.2.0.tgz#57ce8d2175b9bbb3d8b3cf3e4217b1aec8ddcb2e" - integrity sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw== + version "4.3.1" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.1.tgz#6febc1890851f62a8932d495cc88d29390fa850d" + integrity sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -5073,9 +5072,9 @@ i18n-js@^3.0.11: integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== i18next@^17.0.3: - version "17.0.15" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.15.tgz#a4a378910fa06ca1c34f9e481ff6642acdb16dba" - integrity sha512-d+DLqZY1G15jDhSLRtsCVd/+KAWKmcmX1bp/5RjamIhftEFDvSXVgWXXkzsBFIl41VHhBV1y5JORukgz1s3GCQ== + version "17.0.16" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.16.tgz#4bee0f84d6c79db3095f4eca6ded7920eea6b139" + integrity sha512-PtPiycw8H/45AAy2nuS3Ehov1X9k5V/gTJ89Uh8VAA3dx8EbsWwyP3c25fd4PWlLUey3YbRLTNPbre/dPho8Og== dependencies: "@babel/runtime" "^7.3.1" @@ -6497,9 +6496,9 @@ log-symbols@^3.0.0: chalk "^2.4.2" logkitty@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/logkitty/-/logkitty-0.6.0.tgz#e327d4b144dd5c11d912d002cf57ac9fbae20e15" - integrity sha512-+F1ROENmfG3b4N9WGlRz5QGTBw/xgjZe2JzZLADYeCmzdId5c+QI7WTGRofs/10hwP84aAmjK2WStx+/oQVnwA== + version "0.6.1" + resolved "https://registry.yarnpkg.com/logkitty/-/logkitty-0.6.1.tgz#fe29209669d261539cbd6bb998a136fc92a1a05c" + integrity sha512-cHuXN8qUZuzX/7kB6VyS7kB4xyD24e8gyHXIFNhIv+fjW3P+jEXNUhj0o/7qWJtv7UZpbnPgUqzu/AZQ8RAqxQ== dependencies: ansi-fragments "^0.2.1" dayjs "^1.8.15" @@ -7118,10 +7117,10 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.3.5: - version "2.5.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.1.tgz#cf435a9bf9408796ca3a3525a8b851464279c9b8" - integrity sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q== +minipass@^2.2.1, minipass@^2.6.0, minipass@^2.8.6: + version "2.8.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.8.6.tgz#620d889ace26356391d010ecb9458749df9b6db5" + integrity sha512-lFG7d6g3+/UaFDCOtqPiKAC9zngWWsQZl1g5q6gaONqrjq61SX2xFqXMleQiFVyDpYwa018E9hmlAFY22PCb+A== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -7375,9 +7374,9 @@ node-pre-gyp@^0.12.0: tar "^4" node-releases@^1.1.29: - version "1.1.30" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.30.tgz#35eebf129c63baeb6d8ddeda3c35b05abfd37f7f" - integrity sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw== + version "1.1.32" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.32.tgz#485b35c1bf9b4d8baa105d782f8ca731e518276e" + integrity sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A== dependencies: semver "^5.3.0" @@ -7662,7 +7661,7 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -open@^6.2.0, open@^6.3.0, open@^6.4.0: +open@^6.2.0, open@^6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== @@ -7899,9 +7898,9 @@ parent-module@^1.0.0: callsites "^3.0.0" parse-asn1@^5.0.0: - version "5.1.4" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" - integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -8475,9 +8474,9 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" - integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w== + version "1.4.2" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.2.tgz#e7c82a60140916d666541043bd2b0b72ee4e38a6" + integrity sha512-eR6RgxFYPDFH+zFLTJKtoNP/RlsHANQb52AUmQ2bGDPMuUw7jJb0F+DNEgx7qQGIElrbFxWYMc0/B91zLZPF9Q== dependencies: dijkstrajs "^1.0.1" isarray "^2.0.1" @@ -8485,9 +8484,9 @@ qrcode@^1.2.0: yargs "^13.2.4" qs@^6.7.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.8.0.tgz#87b763f0d37ca54200334cd57bb2ef8f68a1d081" - integrity sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w== + version "6.9.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409" + integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA== qs@~6.5.2: version "6.5.2" @@ -8759,9 +8758,9 @@ react-native-os@^1.2.2: integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== react-native-permissions@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.2.0.tgz#0deb616bf1565c17c91f1cb1f953809b2892c29e" - integrity sha512-+KrP1JZ30RI9p30wsGlGQx22qwiClDnznSQZPpvBMkOIZQ9kXOkLAFXS+vwiHRiiRu/pBMBXYHfI7ng6t2+LbQ== + version "1.2.1" + resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.2.1.tgz#cb1f6e53b8992b3912de5a4cfc1553ac2e82d0f6" + integrity sha512-6NOGsA7EsuKT9hfULccQfMrsGmRhBkmN6Uv8nz2QObjEG87XtroQtw4Qi1+tAjIkSHawCeAMJp+SCtiXSGUD5Q== react-native-qrcode-scanner@mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e: version "1.0.1" @@ -9276,7 +9275,7 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpu-core@^4.5.4: +regexpu-core@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== @@ -9942,16 +9941,16 @@ snapdragon@^0.8.1: use "^3.1.0" socket.io-client@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.2.0.tgz#84e73ee3c43d5020ccc1a258faeeb9aec2723af7" - integrity sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== dependencies: backo2 "1.0.2" base64-arraybuffer "0.1.5" component-bind "1.0.0" component-emitter "1.2.1" - debug "~3.1.0" - engine.io-client "~3.3.1" + debug "~4.1.0" + engine.io-client "~3.4.0" has-binary2 "~1.0.2" has-cors "1.1.0" indexof "0.0.1" @@ -9987,21 +9986,21 @@ socks@~2.3.2: smart-buffer "4.0.2" source-map-explorer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.0.1.tgz#988721e8320d7b6925bc40289e5de658fe4cad4d" - integrity sha512-mv2sv2b6oN2L9n18O/eLrYiP5zfWEHESLq4utWBqNw8GnkbuRuXs8twVCOhMT5hxRzfQgS7Yxh7HlQaW8oeiAQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.0.tgz#d80e2a7fef0f15b3c9c1f57bc22bd1aabfaf2309" + integrity sha512-VlOYrBo7gKT72E3IGMzK33ddEWIHGIdyraz8nmpxC7n0ZrzGWq08pWkB8FBxlJJCm9xmP3imlZ9ElUsGbKPpvQ== dependencies: btoa "^1.2.1" chalk "^2.4.2" convert-source-map "^1.6.0" - ejs "^2.6.2" + ejs "^2.7.1" escape-html "^1.0.3" glob "^7.1.4" - lodash "^4.17.11" - open "^6.3.0" + lodash "^4.17.15" + open "^6.4.0" source-map "^0.7.3" temp "^0.9.0" - yargs "^13.2.4" + yargs "^14.0.0" source-map-resolve@^0.5.0: version "0.5.2" @@ -10550,13 +10549,13 @@ tail@^2.0.0: integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.5" + minipass "^2.8.6" minizlib "^1.2.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" @@ -10758,11 +10757,6 @@ trim-newlines@^2.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - trim-trailing-lines@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz#d2f1e153161152e9f02fabc670fb40bec2ea2e3a" @@ -11572,6 +11566,23 @@ yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: y18n "^4.0.0" yargs-parser "^13.1.1" +yargs@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.0.0.tgz#ba4cacc802b3c0b3e36a9e791723763d57a85066" + integrity sha512-ssa5JuRjMeZEUjg7bEL99AwpitxU/zWGAGpdj0di41pOEmJti8NR6kyUIJBkR78DTYNPZOU08luUo0GTHuB+ow== + dependencies: + cliui "^5.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.1" + yargs@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" From 84653a3c959ead00b685d39922385c703c33a66a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 25 Sep 2019 19:29:05 -0400 Subject: [PATCH 339/636] remove console.logs --- src/helpers/buildWalletSections.js | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/helpers/buildWalletSections.js b/src/helpers/buildWalletSections.js index c718df854e9..efde42e7ee3 100644 --- a/src/helpers/buildWalletSections.js +++ b/src/helpers/buildWalletSections.js @@ -1,7 +1,6 @@ import lang from 'i18n-js'; import { compact, - findIndex, flattenDeep, get, groupBy, @@ -35,7 +34,6 @@ const enhanceRenderItem = compose( withNavigation, withHandlers({ onPress: ({ assetType, navigation }) => (item) => { - console.log(assetType); navigation.navigate('ExpandedAssetScreen', { asset: item, type: assetType, @@ -85,8 +83,6 @@ const buildWalletSections = ( const isEmpty = !filteredSections.length; setIsWalletEmpty(isEmpty); - // console.log('filteredSections', filteredSections) - return { isEmpty, sections: filteredSections, @@ -98,19 +94,17 @@ const withUniswapSection = ( nativeCurrency, uniswap, uniswapTotal, -) => { - return { - data: uniswap, - header: { - title: 'Investments', - totalItems: uniswap.length, - totalValue: uniswapTotal, - }, - investments: true, - name: 'investments', - renderItem: uniswapRenderItem, - }; -}; +) => ({ + data: uniswap, + header: { + title: 'Investments', + totalItems: uniswap.length, + totalValue: uniswapTotal, + }, + investments: true, + name: 'investments', + renderItem: uniswapRenderItem, +}); const withBalanceSection = ( allAssets, From 597e56c007c40f3719c616a084369161fc017512 Mon Sep 17 00:00:00 2001 From: osdnk Date: Thu, 26 Sep 2019 12:27:06 +0200 Subject: [PATCH 340/636] Remove dummy code --- src/components/exchange/ExchangeAssetList.js | 44 ++++++++------------ 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index 7b76b19d551..c594e9d4a32 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -25,8 +25,6 @@ const layoutItemAnimator = { animateWillUpdate: NOOP, }; -const buildUniqueIdForListData = (items = []) => items.map(property('address')).join('_'); - const getLayoutTypeForIndex = () => ViewTypes.COIN_ROW; const hasRowChanged = (r1, r2) => isNewValueForPath(r1, r2, 'uniqueId'); @@ -84,30 +82,24 @@ export default class ExchangeAssetList extends PureComponent { render = () => ( - - - + ) } From 9a31632844aabf9e194a54849820039c7c946c42 Mon Sep 17 00:00:00 2001 From: osdnk Date: Thu, 26 Sep 2019 12:37:00 +0200 Subject: [PATCH 341/636] Delay rendering ExchangeAssetList --- src/screens/CurrencySelectModal.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 05bb13a0e8e..8ac6e3688b2 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -239,13 +239,14 @@ class CurrencySelectModal extends PureComponent { ref={this.searchInputRef} /> - + /> : null} Date: Thu, 26 Sep 2019 19:13:11 +0200 Subject: [PATCH 342/636] Fix gestures blockers --- .../exchange/ExchangeOutputField.js | 4 ++ .../expanded-state/FloatingPanel.js | 4 +- src/navigation/ExchangeModalNavigator.js | 1 - src/screens/ExchangeModal.js | 59 ++++++++++--------- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index 0d42c682c5d..b265e145272 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -33,6 +33,7 @@ const FakeNotchThing = withNeverRerender(() => ( export default class ExchangeOutputField extends PureComponent { static propTypes = { + bottomRadius: PropTypes.number, onFocus: PropTypes.func, onPressSelectOutputCurrency: PropTypes.func, outputAmount: PropTypes.string, @@ -61,6 +62,7 @@ export default class ExchangeOutputField extends PureComponent { outputAmount, outputCurrency, setOutputAmount, + bottomRadius, } = this.props; const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); @@ -74,6 +76,8 @@ export default class ExchangeOutputField extends PureComponent { ${padding(25 + paddingValue, 0, 25)}; background-color: ${colors.white}; overflow: hidden; + border-bottom-left-radius: ${bottomRadius}px; + border-bottom-right-radius: ${bottomRadius}px; `} > diff --git a/src/components/expanded-state/FloatingPanel.js b/src/components/expanded-state/FloatingPanel.js index 9a049324ac2..2f21d8c7e4b 100644 --- a/src/components/expanded-state/FloatingPanel.js +++ b/src/components/expanded-state/FloatingPanel.js @@ -18,6 +18,7 @@ const FloatingPanel = pure(({ hideShadow, style, radius, + overflow, ...props }) => ( store.dispatch(updateTabsTransitionProps({ isTransitioning: false })); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index f8f50c04010..91ee1d47bf4 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -598,35 +598,34 @@ class ExchangeModal extends PureComponent { }), }} > - - + + - - - - + + {isSufficientBalance && } {showConfirmButton && ( @@ -650,7 +649,9 @@ class ExchangeModal extends PureComponent { )} - + + + From 6e89c74369fd12238531c5113feaf3514b0ee7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Osadnik?= Date: Fri, 27 Sep 2019 15:17:30 +0200 Subject: [PATCH 343/636] Set up eslint and pre-commit hooks (#169) Since all of us agree that product quality should become more prioritized I think that this is a good first step for making out development workflow better. I decided to use eslint config from @satya164, cause having an experience with this config I need to admit that this config makes my development more confident. I decided not only to set it up but also force us to follow it. Now it's not possible to commit anything which does not pass eslint checks and tests. To understand why it's important I added few TODOs, which seem to be legit issues we tended to ignore. Furthermore, we probably won't find them unless setting up this config, so that's the very visible example of positive impact. Also, I connected the hook with tests. We don't have a lot of them. Maybe we will have more of them someday but even though we were probably not conscious that some of them are broken. Few crashes were easy to fix, but some of them are not super understandable for me and points tt some other issues, which might be more major. I'm super positive for having it merged ASAP to not come across merge conflicts. Also, it's good moment because we just merged a lot of code and not so many lines of codes are pending to be merged. --- .eslintrc | 48 -- __tests__/App-test.js | 14 - __tests__/App.js | 14 - babel.config.js | 8 +- config/test/jest-setup.js | 12 +- e2e/Navigation.js | 4 +- e2e/init.js | 5 +- global.js | 4 +- index.js | 7 +- metro.config.js | 1 + package.json | 19 +- shim.js | 2 + src/App.js | 191 +++---- src/components/ActivityIndicator.js | 7 +- src/components/AddFundsInterstitial.js | 13 +- src/components/Avatar.js | 10 +- src/components/BlurOverlay.js | 5 +- src/components/ContextMenu.js | 22 +- src/components/CopyTooltip.js | 26 +- src/components/Divider.js | 33 +- src/components/Highlight.js | 7 +- src/components/ImageWithCachedDimensions.js | 13 +- src/components/InnerBorder.js | 8 +- src/components/OfflineBadge.js | 29 +- src/components/QRCodeDisplay.js | 6 +- src/components/SendComponentWithData.js | 114 +++-- src/components/Tag.js | 2 +- src/components/TouchableBackdrop.js | 2 +- src/components/activity-list/ActivityList.js | 28 +- .../activity-list/ActivityListHeader.js | 9 +- .../activity-list/RecyclerActivityList.js | 91 ++-- src/components/alerts/Alert.js | 9 +- src/components/alerts/BaseAlert.js | 22 +- src/components/alerts/Prompt.js | 9 +- .../animations/ButtonPressAnimation.js | 173 +++---- src/components/animations/FadeInAnimation.js | 30 +- src/components/animations/FlyInAnimation.js | 18 +- src/components/animations/OpacityToggler.js | 36 +- src/components/animations/RotationArrow.js | 29 +- .../animations/RoundButtonSizeToggler.js | 55 ++- src/components/animations/ScaleInAnimation.js | 41 +- src/components/animations/SizeToggler.js | 38 +- src/components/animations/SpinAnimation.js | 31 +- src/components/asset-list/AssetList.js | 49 +- src/components/asset-list/AssetListHeader.js | 7 +- .../asset-list/AssetListItemSkeleton.js | 28 +- src/components/asset-list/EmptyAssetList.js | 4 +- .../asset-list/RecyclerAssetList.js | 465 ++++++++++++------ src/components/badge/Badge.js | 31 +- src/components/bubble-sheet/BubbleSheet.js | 2 +- src/components/buttons/AddContactButton.js | 26 +- src/components/buttons/Button.js | 36 +- src/components/buttons/CoolButton.js | 61 +-- .../buttons/HoldToAuthorizeButton.js | 74 ++- src/components/buttons/PasteAddressButton.js | 22 +- src/components/coin-divider/CoinDivider.js | 26 +- .../coin-divider/CoinDividerButtonLabel.js | 7 +- .../coin-divider/SmallBalancesWrapper.js | 25 +- src/components/coin-icon/CoinIcon.js | 15 +- src/components/coin-icon/RequestCoinIcon.js | 2 +- .../coin-icon/RequestVendorLogoIcon.js | 34 +- src/components/coin-row/BalanceCoinRow.js | 35 +- src/components/coin-row/CoinRow.js | 60 +-- .../coin-row/CollectiblesSendRow.js | 113 ++--- .../coin-row/ContractInteractionCoinRow.js | 36 +- src/components/coin-row/ExchangeCoinRow.js | 46 +- src/components/coin-row/RequestCoinRow.js | 31 +- src/components/coin-row/SendCoinRow.js | 23 +- src/components/coin-row/TransactionCoinRow.js | 82 ++- .../coin-row/TransactionStatusBadge.js | 2 +- src/components/coin-row/index.js | 4 +- src/components/contacts/ContactAvatar.js | 7 +- src/components/contacts/ContactRow.js | 20 +- .../contacts/SwipeableContactRow.js | 46 +- src/components/contacts/index.js | 4 +- .../contacts/showDeleteContactActionSheet.js | 29 +- .../exchange/ConfirmExchangeButton.js | 20 +- src/components/exchange/ExchangeAssetList.js | 51 +- src/components/exchange/ExchangeInput.js | 25 +- src/components/exchange/ExchangeInputField.js | 91 ++-- .../exchange/ExchangeModalHeader.js | 13 +- .../exchange/ExchangeNativeField.js | 44 +- .../exchange/ExchangeOutputField.js | 12 +- src/components/exchange/ExchangeSearch.js | 44 +- src/components/exchange/SlippageWarning.js | 70 +-- src/components/exchange/UnlockAssetButton.js | 25 +- .../expanded-state/AddContactState.js | 45 +- .../expanded-state/FloatingPanel.js | 24 +- .../expanded-state/FloatingPanels.js | 2 +- .../expanded-state/TokenExpandedState.js | 43 +- .../UniqueTokenExpandedState.js | 72 ++- .../expanded-state/asset-panel/AssetPanel.js | 4 +- .../asset-panel/AssetPanelAction.js | 18 +- .../asset-panel/AssetPanelHeader.js | 7 +- src/components/expanded-state/index.js | 4 +- src/components/fab/DeleteButton.js | 10 +- src/components/fab/ExchangeFab.js | 13 +- src/components/fab/FabWrapper.js | 7 +- src/components/fab/FloatingActionButton.js | 41 +- src/components/fab/MovableFabWrapper.js | 250 ++++++---- src/components/fab/SendFab.js | 58 +-- src/components/fields/AddressField.js | 73 +-- src/components/fields/UnderlineField.js | 27 +- .../floating-emojis/FloatingEmoji.js | 25 +- .../floating-emojis/FloatingEmojis.js | 37 +- src/components/gas/GasSpeedButton.js | 52 +- src/components/gas/GasSpeedLabelPager.js | 2 +- src/components/gas/GasSpeedLabelPagerItem.js | 33 +- src/components/header/BackButton.js | 19 +- src/components/header/CameraHeaderButton.js | 7 +- src/components/header/Header.js | 3 +- src/components/header/HeaderButton.js | 7 +- src/components/header/ProfileHeaderButton.js | 19 +- src/components/icons/BiometryIcon.js | 15 +- src/components/icons/Icon.js | 3 +- src/components/icons/Svg.js | 9 +- src/components/icons/svg/ArrowCircledIcon.js | 2 - src/components/icons/svg/ArrowIcon.js | 9 +- src/components/icons/svg/AvatarIcon.js | 2 - src/components/icons/svg/CameraIcon.js | 2 - src/components/icons/svg/CaretIcon.js | 9 +- src/components/icons/svg/CaretThinIcon.js | 9 +- .../icons/svg/CheckmarkCircledIcon.js | 2 - src/components/icons/svg/CheckmarkIcon.js | 2 - src/components/icons/svg/ClearInputIcon.js | 2 - src/components/icons/svg/ClockIcon.js | 10 +- src/components/icons/svg/CloseCircledIcon.js | 2 - src/components/icons/svg/CloseIcon.js | 2 - src/components/icons/svg/CompassIcon.js | 2 - src/components/icons/svg/CopyIcon.js | 2 - src/components/icons/svg/CrosshairIcon.js | 2 - src/components/icons/svg/DotIcon.js | 7 +- src/components/icons/svg/FaceIdIcon.js | 2 - src/components/icons/svg/GearIcon.js | 2 - src/components/icons/svg/HandleIcon.js | 2 - src/components/icons/svg/InboxIcon.js | 2 - src/components/icons/svg/LockIcon.js | 2 - src/components/icons/svg/OfflineIcon.js | 2 - src/components/icons/svg/ProgressIcon.js | 28 +- src/components/icons/svg/SearchIcon.js | 2 - src/components/icons/svg/SendIcon.js | 2 - src/components/icons/svg/SendSmallIcon.js | 2 - src/components/icons/svg/ShareIcon.js | 2 - src/components/icons/svg/SignatureIcon.js | 2 - src/components/icons/svg/SpinnerIcon.js | 2 +- src/components/icons/svg/SwapIcon.js | 2 - src/components/icons/svg/ThreeDotsIcon.js | 6 +- src/components/icons/svg/TouchIdIcon.js | 2 - src/components/icons/svg/WalletConnectIcon.js | 2 - src/components/icons/svg/WarningIcon.js | 2 - src/components/inputs/Input.js | 10 +- src/components/inputs/MultiLineInput.js | 2 +- .../investment-cards/InvestmentCard.js | 131 ++--- .../investment-cards/InvestmentCardHeader.js | 88 ++-- .../investment-cards/InvestmentCardPill.js | 24 +- .../investment-cards/UniswapInvestmentCard.js | 138 +++--- src/components/layout/Centered.js | 2 +- src/components/layout/Column.js | 2 +- src/components/layout/ColumnWithDividers.js | 2 +- src/components/layout/ColumnWithMargins.js | 9 +- src/components/layout/Flex.js | 38 +- src/components/layout/FlexItem.js | 24 +- .../layout/KeyboardFixedOpenLayout.js | 37 +- src/components/layout/LayoutWithDividers.js | 12 +- src/components/layout/LayoutWithMargins.js | 14 +- src/components/layout/Page.js | 7 +- src/components/layout/Row.js | 2 +- src/components/layout/RowWithDividers.js | 2 +- src/components/layout/RowWithMargins.js | 9 +- src/components/list/List.js | 15 +- src/components/list/ListHeader.js | 52 +- src/components/list/ListItem.js | 92 ++-- src/components/list/ListItemArrowGroup.js | 17 +- src/components/modal/LoadingOverlay.js | 14 +- src/components/modal/Modal.js | 5 +- src/components/modal/ModalFooterButton.js | 11 +- src/components/modal/ModalFooterButtonsRow.js | 2 +- src/components/modal/ModalHeader.js | 8 +- src/components/modal/ModalHeaderButton.js | 13 +- src/components/pager/AnimatedPager.js | 24 +- src/components/pager/AnimatedPagerItem.js | 4 +- src/components/pager/Pager.js | 9 +- src/components/pager/PagerControls.js | 38 +- src/components/pager/PagerItem.js | 4 +- src/components/profile/ProfileAction.js | 14 +- src/components/profile/ProfileMasthead.js | 16 +- .../qrcode-scanner/QRCodeScanner.js | 18 +- .../qrcode-scanner/QRCodeScannerCamera.js | 38 +- .../qrcode-scanner/QRCodeScannerCrosshair.js | 5 +- .../QRCodeScannerNeedsAuthorization.js | 32 +- src/components/qrcode-scanner/index.js | 4 +- src/components/radio-list/RadioList.js | 31 +- src/components/radio-list/RadioListItem.js | 13 +- src/components/send/SendAssetForm.js | 16 +- .../send/SendAssetFormCollectible.js | 71 ++- src/components/send/SendAssetFormField.js | 10 +- src/components/send/SendAssetFormToken.js | 15 +- src/components/send/SendAssetList.js | 239 +++++---- src/components/send/SendContactList.js | 143 +++--- src/components/send/SendEmptyState.js | 30 +- src/components/send/SendHeader.js | 47 +- src/components/send/SendTransactionSpeed.js | 8 +- src/components/settings-menu/BackupSection.js | 81 ++- .../settings-menu/CurrencySection.js | 33 +- .../settings-menu/LanguageSection.js | 15 +- .../settings-menu/SettingsSection.js | 34 +- src/components/shadow-stack/ShadowStack.js | 26 +- src/components/sheet/SheetHandle.js | 2 +- src/components/text/ErrorText.js | 12 +- src/components/text/H1.js | 6 +- src/components/text/Label.js | 7 +- src/components/text/TruncatedAddress.js | 2 +- src/components/text/TruncatedText.js | 3 +- .../token-family/TokenFamilyHeader.js | 58 +-- .../token-family/TokenFamilyWrap.js | 30 +- .../transaction/TransactionSheet.js | 6 +- src/components/transaction/index.js | 12 +- .../DefaultTransactionConfirmationSection.js | 6 +- .../TransactionConfirmationSection.js | 20 +- .../unique-token/UniqueTokenAttributes.js | 42 +- .../unique-token/UniqueTokenCard.js | 30 +- .../unique-token/UniqueTokenImage.js | 75 +-- src/components/unique-token/UniqueTokenRow.js | 15 +- .../WalletConnectExplainerItem.js | 19 +- .../WalletConnectLearnMoreButton.js | 7 +- .../walletconnect-list/WalletConnectList.js | 1 - .../WalletConnectListItem.js | 81 ++- src/components/walletconnect-list/index.js | 8 +- src/handlers/__tests__/web3.test.js | 15 +- src/handlers/commonStorage.js | 201 +++++--- src/handlers/localstorage/common.js | 19 +- src/handlers/localstorage/globalSettings.js | 14 +- src/handlers/localstorage/storage.js | 96 ++-- src/handlers/localstorage/walletconnect.js | 20 +- src/handlers/uniswap.js | 172 ++++--- src/handlers/web3.js | 70 +-- src/helpers/__tests__/utilities.test.js | 17 +- src/helpers/assets.js | 28 +- src/helpers/buildWalletSections.js | 88 ++-- src/helpers/emojiHandler.js | 7 +- src/helpers/sortList.js | 11 +- src/helpers/time.js | 34 +- src/helpers/transactions.js | 39 +- src/helpers/utilities.js | 123 ++--- src/helpers/validators.js | 25 +- .../__tests__/withUniswapLiquidity.test.js | 2 +- src/hoc/assetSelectors.js | 51 +- src/hoc/index.js | 45 +- src/hoc/uniqueTokenSelectors.js | 4 +- src/hoc/withAccountAddress.js | 18 +- src/hoc/withAccountData.js | 11 +- src/hoc/withAccountSettings.js | 38 +- src/hoc/withAccountTransactions.js | 15 +- src/hoc/withActionSheetManager.js | 10 +- src/hoc/withAppState.js | 18 +- src/hoc/withBlockedHorizontalSwipe.js | 18 +- src/hoc/withBlurTransitionProps.js | 11 +- src/hoc/withDataInit.js | 273 +++++----- src/hoc/withFabSelection.js | 22 +- src/hoc/withFabSendAction.js | 25 +- src/hoc/withGas.js | 16 +- src/hoc/withHideSplashScreen.js | 7 +- src/hoc/withImageDimensionsCache.js | 16 +- src/hoc/withIsWalletEmpty.js | 6 +- src/hoc/withIsWalletEthZero.js | 6 +- src/hoc/withIsWalletImporting.js | 6 +- src/hoc/withKeyboardFocusHistory.js | 11 +- src/hoc/withKeyboardHeight.js | 5 +- src/hoc/withMessageSigningScreen.js | 14 +- src/hoc/withNetInfo.js | 35 +- src/hoc/withOpenBalances.js | 14 +- src/hoc/withOpenFamilyTabs.js | 16 +- src/hoc/withOpenInvestmentCards.js | 21 +- src/hoc/withRequests.js | 17 +- src/hoc/withRotationForDirection.js | 21 +- src/hoc/withSafeAreaViewInsetValues.js | 3 +- src/hoc/withSendFeedback.js | 40 +- src/hoc/withStatusBarStyle.js | 8 +- src/hoc/withTransactionConfirmationScreen.js | 20 +- src/hoc/withTransitionProps.js | 5 +- src/hoc/withUniqueTokens.js | 37 +- src/hoc/withUniswapAllowances.js | 24 +- src/hoc/withUniswapAssets.js | 29 +- src/hoc/withUniswapLiquidity.js | 53 +- src/hoc/withWalletConnectConfirmationModal.js | 12 +- src/hoc/withWalletConnectConnections.js | 58 ++- src/hoc/withWalletConnectOnSessionRequest.js | 9 +- src/model/__tests__/wallet.test.js | 25 +- src/model/firebase.js | 30 +- src/model/keychain.js | 16 +- src/model/wallet.js | 62 ++- src/navigation/ExchangeModalNavigator.js | 88 ++-- src/navigation/SpringConfig.js | 8 +- src/navigation/transitions/effects.js | 33 +- src/parsers/accounts.js | 4 +- src/parsers/gas.js | 50 +- src/parsers/newTransaction.js | 9 +- src/parsers/transactions.js | 26 +- src/parsers/uniqueTokens.js | 107 ++-- src/redux/actionSheetManager.js | 14 +- src/redux/data.js | 228 +++++---- src/redux/explorer.js | 82 ++- src/redux/gas.js | 220 +++++---- src/redux/imageDimensionsCache.js | 39 +- src/redux/isWalletEmpty.js | 20 +- src/redux/isWalletEthZero.js | 10 +- src/redux/isWalletImporting.js | 10 +- src/redux/keyboardFocusHistory.js | 30 +- src/redux/keyboardHeight.js | 14 +- src/redux/navigation.js | 12 +- src/redux/nonce.js | 29 +- src/redux/openBalances.js | 14 +- src/redux/openFamilyTabs.js | 30 +- src/redux/openInvestmentCards.js | 29 +- src/redux/requests.js | 101 ++-- src/redux/selectedWithFab.js | 54 +- src/redux/send.js | 227 +++++---- src/redux/settings.js | 145 +++--- src/redux/store.js | 2 +- src/redux/uniqueTokens.js | 167 ++++--- src/redux/uniswap.js | 263 +++++----- src/redux/walletconnect.js | 163 +++--- src/references/index.js | 19 +- src/screens/CurrencySelectModal.js | 168 ++++--- src/screens/ExampleScreen.js | 12 +- src/screens/ExchangeModal.js | 274 +++++++---- src/screens/ExpandedAssetScreen.js | 26 +- src/screens/ExpandedAssetScreenWithData.js | 20 +- src/screens/ImportSeedPhraseSheet.js | 20 +- src/screens/ImportSeedPhraseSheetWithData.js | 38 +- src/screens/ProfileScreen.js | 14 +- src/screens/ProfileScreenWithData.js | 14 +- src/screens/QRScannerScreen.js | 14 +- src/screens/QRScannerScreenWithData.js | 30 +- src/screens/ReceiveModal.js | 40 +- src/screens/Routes.js | 273 +++++----- src/screens/SendSheet.js | 122 ++--- src/screens/SendSheetWithData.js | 6 +- src/screens/SettingsModal.js | 24 +- src/screens/TransactionConfirmationScreen.js | 31 +- .../TransactionConfirmationScreenWithData.js | 59 ++- src/screens/WalletConnectConfirmationModal.js | 22 +- src/screens/WalletScreen.js | 111 +++-- src/styles/animations.js | 5 +- src/styles/buildLayoutStyles.js | 6 +- src/styles/buildTextStyles.js | 29 +- src/styles/colors.js | 26 +- src/styles/fonts.js | 5 +- src/styles/shadow.js | 12 +- src/utils/__tests__/contract.test.js | 30 +- src/utils/__tests__/ethereumUtils.test.js | 11 +- src/utils/__tests__/search.test.js | 9 +- src/utils/abbreviations.js | 5 +- src/utils/address.js | 4 +- src/utils/contract.js | 9 +- src/utils/directionPropType.js | 7 +- src/utils/ethereumUtils.js | 7 +- src/utils/formatters.js | 21 +- src/utils/gas.js | 33 +- src/utils/parseQueryParams.js | 2 +- src/utils/promise.js | 13 +- src/utils/reduceArrayToObject.js | 7 +- src/utils/search.js | 15 +- yarn.lock | 420 ++++++++++------ 364 files changed, 6670 insertions(+), 6148 deletions(-) delete mode 100644 .eslintrc delete mode 100644 __tests__/App-test.js delete mode 100644 __tests__/App.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 69795e61401..00000000000 --- a/.eslintrc +++ /dev/null @@ -1,48 +0,0 @@ -{ - "parser": "babel-eslint", - "plugins": [ - "react", - "react-hooks", - "react-native", - "react-native-animation-linter" - ], - "parserOptions": { - "ecmaFeatures": { - "jsx": true, - "modules": true - } - }, - "extends" : [ - "eslint:recommended", - "plugin:react/recommended", - "airbnb-base" - ], - "rules" : { - "arrow-body-style": "warn", - "arrow-parens": ["off"], - "camelcase": ["error", {ignoreDestructuring: true}], - "class-methods-use-this": "off", - "indent": ["error", 2], - "max-len": ["error", {"code": 160, "comments": 500}], - "no-console": "off", - "no-nested-ternary": "error", - "no-param-reassign": ["off"], - "no-plusplus": ["off"], - "no-tabs": "error", - "no-underscore-dangle": ["off"], - "no-unused-vars": ["error", {"args": "none"}], - "no-use-before-define": ["error", {"functions": false, "variables": false}], - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": "warn", - "react-native-animation-linter/must-tear-down-animations": 2, - "sort-keys": ["error", "asc", {"caseSensitive": false, "natural": false}] - }, - "globals": { - "fetch": false - }, - "settings": { - "react": { - "version": "16.5.0" - } - } -} diff --git a/__tests__/App-test.js b/__tests__/App-test.js deleted file mode 100644 index 178476699b6..00000000000 --- a/__tests__/App-test.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @format - */ - -import 'react-native'; -import React from 'react'; -import App from '../App'; - -// Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer'; - -it('renders correctly', () => { - renderer.create(); -}); diff --git a/__tests__/App.js b/__tests__/App.js deleted file mode 100644 index b5f8100fb5d..00000000000 --- a/__tests__/App.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @format - */ - - import 'react-native'; -import React from 'react'; -import App from '../App'; - - // Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer'; - - it('renders correctly', () => { - renderer.create(); -}); diff --git a/babel.config.js b/babel.config.js index a46794435a1..06246be49af 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,7 +1,13 @@ +// eslint-disable-next-line import/no-commonjs module.exports = { env: { development: { - plugins: [['transform-remove-console', { exclude: ['disableYellowBox', 'error', 'info', 'log'] }]], + plugins: [ + [ + 'transform-remove-console', + { exclude: ['disableYellowBox', 'error', 'info', 'log'] }, + ], + ], }, production: { plugins: [['transform-remove-console', { exclude: ['error'] }]], diff --git a/config/test/jest-setup.js b/config/test/jest-setup.js index c582ef34605..ab0b4caaa14 100644 --- a/config/test/jest-setup.js +++ b/config/test/jest-setup.js @@ -1,7 +1,15 @@ +/* eslint-disable no-undef */ +import { NativeModules } from 'react-native'; + jest.autoMockOff(); jest.mock('react-native-keychain', () => ({ - setGenericPassword: jest.fn(), getGenericPassword: jest.fn(), - resetGenericPassword: jest.fn() + resetGenericPassword: jest.fn(), + setGenericPassword: jest.fn(), })); +NativeModules.RNAnalytics = {}; + +const mockAnalytics = jest.genMockFromModule('@segment/analytics-react-native'); + +jest.mock('@segment/analytics-react-native', () => mockAnalytics); diff --git a/e2e/Navigation.js b/e2e/Navigation.js index 8a89bd673fd..3a2d21a904d 100644 --- a/e2e/Navigation.js +++ b/e2e/Navigation.js @@ -1,3 +1,4 @@ +/* eslint-disable no-undef */ describe('Basic test', () => { beforeEach(async () => { await device.reloadReactNative(); @@ -8,7 +9,7 @@ describe('Basic test', () => { }); it('should navigate without imported wallet', async () => { - const importButton = element(by.label('Import Wallet')).atIndex(1) + const importButton = element(by.label('Import Wallet')).atIndex(1); await expect(importButton).toBeVisible(); await element(by.label('Balances')).swipe('left', 'fast', 0.5); await expect(element(by.label('Scan to send'))).toBeVisible(); @@ -32,6 +33,5 @@ describe('Basic test', () => { await expect(element(by.label('Scan to send'))).toBeVisible(); await element(by.id('goToBalancesFromScanner')).tap(); await expect(element(by.label('Balances'))).toBeVisible(); - }); }); diff --git a/e2e/init.js b/e2e/init.js index 8f248b7a6df..b188daf4976 100644 --- a/e2e/init.js +++ b/e2e/init.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-commonjs,no-undef,babel/no-invalid-this */ const detox = require('detox'); const config = require('../package.json').detox; const adapter = require('detox/runners/mocha/adapter'); @@ -7,11 +8,11 @@ before(async () => { await device.launchApp({ permissions: { camera: 'YES' } }); }); -beforeEach(async function () { +beforeEach(async function() { await adapter.beforeEach(this); }); -afterEach(async function () { +afterEach(async function() { await adapter.afterEach(this); }); diff --git a/global.js b/global.js index e20caa5ac01..a3317d7e3f7 100644 --- a/global.js +++ b/global.js @@ -1,11 +1,11 @@ if (typeof btoa === 'undefined') { - global.btoa = function (str) { + global.btoa = function(str) { return new Buffer(str, 'binary').toString('base64'); }; } if (typeof atob === 'undefined') { - global.atob = function (b64Encoded) { + global.atob = function(b64Encoded) { return new Buffer(b64Encoded, 'base64').toString('binary'); }; } diff --git a/index.js b/index.js index 470c090cc35..f7619235702 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,11 @@ import './global'; import './shim'; -/* eslint-disable import/first */ import RNLanguages from 'react-native-languages'; import lang from 'i18n-js'; import { resources } from './src/languages'; -// eslint-disable-next-line +// eslint-disable-next-line no-unused-vars,import/default import App from './src/App'; // Languages (i18n) @@ -16,7 +15,7 @@ lang.fallbacks = true; lang.translations = Object.assign( {}, - ...Object.keys(resources).map((key, index) => ({ + ...Object.keys(resources).map(key => ({ [key]: resources[key].translation, - })), + })) ); diff --git a/metro.config.js b/metro.config.js index 6a1d15808f0..d9f14d4436c 100644 --- a/metro.config.js +++ b/metro.config.js @@ -5,6 +5,7 @@ * @format */ +// eslint-disable-next-line import/no-commonjs module.exports = { transformer: { getTransformOptions: async () => ({ diff --git a/package.json b/package.json index b69545a093c..6640e9bce95 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,15 @@ "test": "jest test.js", "install-pods": "cd ios && pod install && cd ..", "ios": "react-native run-ios --simulator='iPhone X'", - "lint": "eslint './**/*.js'", + "lint": "eslint --ext '.js,.jsx' .", "nodeify": "./node_modules/.bin/rn-nodeify --install \"crypto\" --hack", "postinstall": "patch-package && rn-nodeify --install --hack" }, + "husky": { + "hooks": { + "pre-commit": "yarn lint && yarn test" + } + }, "dependencies": { "@bankify/react-native-animate-number": "^0.2.1", "@hocs/omit-props": "^0.4.0", @@ -26,6 +31,7 @@ "@tradle/react-native-http": "^2.0.1", "@uniswap/sdk": "^1.0.0-beta.3", "@walletconnect/react-native": "^1.0.0-beta.29", + "@walletconnect/utils": "^1.0.0-beta.36", "assert": "^1.4.1", "asyncstorage-down": "^4.2.0", "axios": "^0.19.0", @@ -46,6 +52,7 @@ "global": "^4.3.2", "grapheme-splitter": "^1.0.4", "https-browserify": "0.0.1", + "husky": "^2.4.0", "i18n-js": "^3.0.11", "i18next": "^17.0.3", "immer": "^3.1.3", @@ -136,7 +143,6 @@ "@babel/core": "^7.5.5", "@babel/runtime": "^7.5.5", "@react-native-community/cli": "2.9.0", - "@react-native-community/eslint-config": "^0.0.5", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^10.0.2", "babel-jest": "^24.8.0", @@ -146,13 +152,8 @@ "babel-plugin-styled-components": "^1.10.6", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", - "eslint": "^6.1.0", - "eslint-config-airbnb-base": "^13.2.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-react": "^7.14.3", - "eslint-plugin-react-hooks": "^2.0.1", - "eslint-plugin-react-native": "^3.7.0", - "eslint-plugin-react-native-animation-linter": "^0.1.2", + "eslint": "6.1.0", + "eslint-config-satya164": "^2.4.1", "jest": "^24.8.0", "metro-react-native-babel-preset": "^0.56.0", "mocha": "^6.1.4", diff --git a/shim.js b/shim.js index d541c845e2a..61dfabb3a92 100644 --- a/shim.js +++ b/shim.js @@ -27,6 +27,7 @@ process.browser = false; if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer; // global.location = global.location || { port: 80 } +// eslint-disable-next-line no-undef const isDev = typeof __DEV__ === 'boolean' && __DEV__; process.env.NODE_ENV = isDev ? 'development' : 'production'; if (typeof localStorage !== 'undefined') { @@ -35,4 +36,5 @@ if (typeof localStorage !== 'undefined') { // If using the crypto shim, uncomment the following line to ensure // crypto is loaded first, so it can populate global.crypto +// eslint-disable-next-line import/no-commonjs require('crypto'); diff --git a/src/App.js b/src/App.js index 10e52d66d36..5ce1e538b82 100644 --- a/src/App.js +++ b/src/App.js @@ -3,15 +3,14 @@ import { get, last } from 'lodash'; import PropTypes from 'prop-types'; import nanoid from 'nanoid/non-secure'; import React, { Component } from 'react'; -import { - AppRegistry, - AppState, - Linking, -} from 'react-native'; +import { AppRegistry, AppState, Linking } from 'react-native'; +// eslint-disable-next-line import/default import CodePush from 'react-native-code-push'; import { REACT_APP_SEGMENT_API_WRITE_KEY } from 'react-native-dotenv'; import firebase from 'react-native-firebase'; +// eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; +// eslint-disable-next-line import/no-unresolved import { useScreens } from 'react-native-screens'; import { connect, Provider } from 'react-redux'; import { compose, withProps } from 'recompact'; @@ -39,96 +38,88 @@ class App extends Component { static propTypes = { appInitTimestamp: PropTypes.number, requestsForTopic: PropTypes.func, - sortedWalletConnectors: PropTypes.arrayOf(PropTypes.object), walletConnectClearTimestamp: PropTypes.func, walletConnectOnSessionRequest: PropTypes.func, walletConnectUpdateTimestamp: PropTypes.func, - } - - state = { appState: AppState.currentState } - - handleOpenLinkingURL = ({ url }) => { - Linking.canOpenURL(url).then((supported) => { - if (supported) { - const { uri, redirectUrl } = parseQueryParams(url); - - const redirect = () => Linking.openURL(redirectUrl); - this.props.walletConnectOnSessionRequest(uri, redirect); - } - }); - } - - onPushNotificationOpened = (topic, autoOpened = false, fromLocal = false) => { - const { appInitTimestamp, requestsForTopic } = this.props; - const requests = requestsForTopic(topic); - - if (requests && requests.length === 1) { - const request = requests[0]; - - const transactionTimestamp = get(request, 'displayDetails.timestampInMs'); - const isNewTransaction = appInitTimestamp && (transactionTimestamp > appInitTimestamp); - - if (!autoOpened || isNewTransaction) { - return Navigation.handleAction({ - params: { autoOpened, transactionDetails: request }, - routeName: 'ConfirmRequest', - }); - } - } - - if (fromLocal) { - return Navigation.handleAction({ - params: { autoOpened, transactionDetails: last(requests) }, - routeName: 'ConfirmRequest', - }); - } - - return Navigation.handleAction({ routeName: 'ProfileScreen' }); }; + state = { appState: AppState.currentState }; + async componentDidMount() { AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.handleInitializeAnalytics(); - firebase.notifications().getInitialNotification().then(notificationOpen => { - if (notificationOpen) { - const topic = get(notificationOpen, 'notification.data.topic'); - this.onPushNotificationOpened(topic, false); - } - }); + firebase + .notifications() + .getInitialNotification() + .then(notificationOpen => { + if (notificationOpen) { + const topic = get(notificationOpen, 'notification.data.topic'); + this.onPushNotificationOpened(topic, false); + } + }); saveFCMToken(); this.onTokenRefreshListener = registerTokenRefreshListener(); // notification while app in foreground - this.notificationListener = firebase.notifications().onNotification(notification => { - const route = Navigation.getActiveRouteName(); - if (route === 'ConfirmRequest') { - const localNotification = new firebase.notifications.Notification() - .setTitle(notification.title) - .setBody(notification.body) - .setData({ ...notification.data, fromLocal: true }); - firebase.notifications().displayNotification(localNotification); - } else { - const topic = get(notification, 'data.topic'); - this.onPushNotificationOpened(topic, true); - } - }); + this.notificationListener = firebase + .notifications() + .onNotification(notification => { + const route = Navigation.getActiveRouteName(); + if (route === 'ConfirmRequest') { + const localNotification = new firebase.notifications.Notification() + .setTitle(notification.title) + .setBody(notification.body) + .setData({ ...notification.data, fromLocal: true }); + firebase.notifications().displayNotification(localNotification); + } else { + const topic = get(notification, 'data.topic'); + this.onPushNotificationOpened(topic, true); + } + }); // notification opened from background - this.notificationOpenedListener = firebase.notifications().onNotificationOpened(notificationOpen => { - const topic = get(notificationOpen, 'notification.data.topic'); - const fromLocal = get(notificationOpen, 'notification.data.fromLocal', false); - this.onPushNotificationOpened(topic, false, fromLocal); - }); + this.notificationOpenedListener = firebase + .notifications() + .onNotificationOpened(notificationOpen => { + const topic = get(notificationOpen, 'notification.data.topic'); + const fromLocal = get( + notificationOpen, + 'notification.data.fromLocal', + false + ); + this.onPushNotificationOpened(topic, false, fromLocal); + }); + } + + componentWillUnmount() { + AppState.removeEventListener('change', this.handleAppStateChange); + Linking.removeEventListener('url', this.handleOpenLinkingURL); + this.notificationListener(); + this.notificationOpenedListener(); + this.onTokenRefreshListener(); } + handleOpenLinkingURL = ({ url }) => { + Linking.canOpenURL(url).then(supported => { + if (supported) { + const { uri, redirectUrl } = parseQueryParams(url); + + const redirect = () => Linking.openURL(redirectUrl); + this.props.walletConnectOnSessionRequest(uri, redirect); + } + }); + }; + handleInitializeAnalytics = async () => { - const storedIdentifier = await keychain.loadString('analyticsUserIdentifier'); + const storedIdentifier = await keychain.loadString( + 'analyticsUserIdentifier' + ); if (!storedIdentifier) { const identifier = await RNIOS11DeviceCheck.getToken() - .then((deviceId) => deviceId) + .then(deviceId => deviceId) .catch(() => nanoid()); await keychain.saveString('analyticsUserIdentifier', identifier); analytics.identify(identifier); @@ -141,9 +132,9 @@ class App extends Component { trackAppLifecycleEvents: true, trackAttributionData: true, }); - } + }; - handleAppStateChange = async (nextAppState) => { + handleAppStateChange = async nextAppState => { if (nextAppState === 'active') { this.props.walletConnectUpdateTimestamp(); await firebase.notifications().removeAllDeliveredNotifications(); @@ -152,28 +143,48 @@ class App extends Component { this.props.walletConnectClearTimestamp(); } this.setState({ appState: nextAppState }); - } + }; - componentWillUnmount() { - AppState.removeEventListener('change', this.handleAppStateChange); - Linking.removeEventListener('url', this.handleOpenLinkingURL); - this.notificationListener(); - this.notificationOpenedListener(); - this.onTokenRefreshListener(); - } + onPushNotificationOpened = (topic, autoOpened = false, fromLocal = false) => { + const { appInitTimestamp, requestsForTopic } = this.props; + const requests = requestsForTopic(topic); + + if (requests && requests.length === 1) { + const request = requests[0]; - handleNavigatorRef = (navigatorRef) => Navigation.setTopLevelNavigator(navigatorRef) + const transactionTimestamp = get(request, 'displayDetails.timestampInMs'); + const isNewTransaction = + appInitTimestamp && transactionTimestamp > appInitTimestamp; + + if (!autoOpened || isNewTransaction) { + return Navigation.handleAction({ + params: { autoOpened, transactionDetails: request }, + routeName: 'ConfirmRequest', + }); + } + } + + if (fromLocal) { + return Navigation.handleAction({ + params: { autoOpened, transactionDetails: last(requests) }, + routeName: 'ConfirmRequest', + }); + } + + return Navigation.handleAction({ routeName: 'ProfileScreen' }); + }; + + handleNavigatorRef = navigatorRef => + Navigation.setTopLevelNavigator(navigatorRef); render = () => ( - + - ) + ); } const AppWithRedux = compose( @@ -184,8 +195,8 @@ const AppWithRedux = compose( ({ walletconnect: { appInitTimestamp } }) => ({ appInitTimestamp }), { requestsForTopic, - }, - ), + } + ) )(App); const AppWithCodePush = CodePush({ diff --git a/src/components/ActivityIndicator.js b/src/components/ActivityIndicator.js index bbc150788c4..2a7842a2ba0 100644 --- a/src/components/ActivityIndicator.js +++ b/src/components/ActivityIndicator.js @@ -6,12 +6,7 @@ import stylePropType from 'react-style-proptype'; import { pure } from 'recompact'; import { colors, position } from '../styles'; -const ActivityIndicator = ({ - color, - isInteraction, - size, - style, -}) => ( +const ActivityIndicator = ({ color, isInteraction, size, style }) => ( ({ transform: [ { translateX: (ButtonContainerWidth / 2) * -1 }, - { translateY: ((ButtonContainerHeight / 2) * -1) + 25 + offsetY }, + { translateY: (ButtonContainerHeight / 2) * -1 + 25 + offsetY }, ], }); @@ -62,7 +62,8 @@ const AddFundsInterstitial = ({ Import Wallet - Use your private key or 12 to 24 word seed phrase from an existing wallet. + Use your private key or 12 to 24 word seed phrase from an existing + wallet. @@ -82,7 +83,9 @@ export default compose( pure, withNavigation, withHandlers({ - onPressAddFunds: ({ navigation }) => () => navigation.navigate('ReceiveModal'), - onPressImportWallet: ({ navigation }) => () => navigation.navigate('ImportSeedPhraseSheet'), - }), + onPressAddFunds: ({ navigation }) => () => + navigation.navigate('ReceiveModal'), + onPressImportWallet: ({ navigation }) => () => + navigation.navigate('ImportSeedPhraseSheet'), + }) )(AddFundsInterstitial); diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 32d3c790ce5..94db9e5137b 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -16,10 +16,7 @@ const Container = styled(Centered)` const Avatar = ({ size, source }) => ( {source ? ( @@ -29,10 +26,7 @@ const Avatar = ({ size, source }) => ( style={position.sizeAsObject(size)} /> ) : ( - + )} diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js index f1056ba6ef3..c36643701ae 100644 --- a/src/components/BlurOverlay.js +++ b/src/components/BlurOverlay.js @@ -14,10 +14,7 @@ const interpolationConfig = { const BlurOverlay = ({ blurType, intensity }) => ( { this.actionSheetRef = ref; } + handleActionSheetRef = ref => { + this.actionSheetRef = ref; + }; showActionSheet = () => { if (this.props.isActionSheetOpen) return; this.props.setIsActionSheetOpen(true); this.actionSheetRef.show(); - } + }; - handlePressActionSheet = (buttonIndex) => { + handlePressActionSheet = buttonIndex => { if (this.props.onPressActionSheet) { this.props.onPressActionSheet(buttonIndex); } this.props.setIsActionSheetOpen(false); - } + }; render = () => ( @@ -63,12 +65,14 @@ class ContextMenu extends PureComponent { - ) + ); } export default withActionSheetManager(ContextMenu); diff --git a/src/components/CopyTooltip.js b/src/components/CopyTooltip.js index 36e428df6a3..6a3b0f6f207 100644 --- a/src/components/CopyTooltip.js +++ b/src/components/CopyTooltip.js @@ -13,30 +13,32 @@ class CopyTooltip extends PureComponent { setSafeTimeout: PropTypes.func, textToCopy: PropTypes.string, tooltipText: PropTypes.string, - } + }; static defaultProps = { activeOpacity: 0.666, tooltipText: 'Copy', - } - - tooltip = null + }; componentDidUpdate = () => { if (this.props.navigation.state.isTransitioning) { this.handleHideTooltip(); } - } + }; + + componentWillUnmount = () => this.handleHideTooltip(); - componentWillUnmount = () => this.handleHideTooltip() + tooltip = null; - handleCopy = () => Clipboard.setString(this.props.textToCopy) + handleCopy = () => Clipboard.setString(this.props.textToCopy); - handleHideTooltip = () => this.tooltip.hideMenu() + handleHideTooltip = () => this.tooltip.hideMenu(); - handlePressIn = () => this.tooltip.showMenu() + handlePressIn = () => this.tooltip.showMenu(); - handleRef = (ref) => { this.tooltip = ref; } + handleRef = ref => { + this.tooltip = ref; + }; render = () => ( - ) + ); } export default compose( withNavigation, - onlyUpdateForKeys(['textToCopy', 'tooltipText']), + onlyUpdateForKeys(['textToCopy', 'tooltipText']) )(CopyTooltip); diff --git a/src/components/Divider.js b/src/components/Divider.js index 042cd27fa82..af915fc2049 100644 --- a/src/components/Divider.js +++ b/src/components/Divider.js @@ -1,9 +1,4 @@ -import { - constant, - isNil, - isNumber, - times, -} from 'lodash'; +import { constant, isNil, isNumber, times } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { onlyUpdateForKeys } from 'recompact'; @@ -12,7 +7,7 @@ import { borders, colors, position } from '../styles'; const DefaultDividerSize = 2; -const buildInsetFromProps = (inset) => { +const buildInsetFromProps = inset => { if (!inset) return times(4, constant(0)); if (isNumber(inset)) return times(4, inset); @@ -26,14 +21,14 @@ const buildInsetFromProps = (inset) => { ]; }; -const horizontalBorderLineStyles = (inset) => css` +const horizontalBorderLineStyles = inset => css` ${inset[3] ? borders.buildRadius('left', 2) : null} ${inset[1] ? borders.buildRadius('right', 2) : null} left: ${inset[3]}; right: ${inset[1]}; `; -const verticalBorderLineStyles = (inset) => css` +const verticalBorderLineStyles = inset => css` ${inset[2] ? borders.buildRadius('bottom', 2) : null} ${inset[0] ? borders.buildRadius('top', 2) : null} bottom: ${inset[2]}; @@ -42,18 +37,17 @@ const verticalBorderLineStyles = (inset) => css` const BorderLine = styled.View` ${position.cover}; - ${({ horizontal, inset }) => ( + ${({ horizontal, inset }) => horizontal ? horizontalBorderLineStyles(inset) - : verticalBorderLineStyles(inset) - )}; + : verticalBorderLineStyles(inset)}; background-color: ${({ color }) => color}; bottom: 0; top: 0; `; const Container = styled.View` - background-color: ${({ backgroundColor }) => (backgroundColor || colors.white)}; + background-color: ${({ backgroundColor }) => backgroundColor || colors.white}; flex-shrink: 0; height: ${({ horizontal, size }) => (horizontal ? size : '100%')}; width: ${({ horizontal, size }) => (horizontal ? '100%' : size)}; @@ -61,13 +55,7 @@ const Container = styled.View` const enhance = onlyUpdateForKeys(['color', 'inset']); -const Divider = enhance(({ - color, - horizontal, - inset, - size, - ...props -}) => ( +const Divider = enhance(({ color, horizontal, inset, size, ...props }) => ( ( +const Highlight = ({ backgroundColor, borderRadius, visible, ...props }) => ( event => { + onLoad: ({ id, imageDimensionsCache, onLoad, updateCache }) => event => { event.persist(); - const { nativeEvent: { height, width } } = event; + const { + nativeEvent: { height, width }, + } = event; if (!imageDimensionsCache[id]) { updateCache({ @@ -29,7 +26,7 @@ const ImageWithCachedDimensions = compose( onLoad(event); } }, - }), + }) )(FastImage); export default ImageWithCachedDimensions; diff --git a/src/components/InnerBorder.js b/src/components/InnerBorder.js index 4b097c8c0da..9b04652382c 100644 --- a/src/components/InnerBorder.js +++ b/src/components/InnerBorder.js @@ -4,13 +4,7 @@ import { View } from 'react-primitives'; import { onlyUpdateForPropTypes } from 'recompact'; import { colors, position } from '../styles'; -const InnerBorder = ({ - color, - opacity, - radius, - width, - ...props -}) => ( +const InnerBorder = ({ color, opacity, radius, width, ...props }) => ( this.runAnimation(); - componentDidMount = () => this.runAnimation() + componentDidUpdate = () => this.runAnimation(); - componentDidUpdate = () => this.runAnimation() + animation = new Value(DefaultAnimationValue); runAnimation = () => { const { isConnected } = this.props; @@ -67,7 +62,7 @@ class OfflineBadge extends PureComponent { ? analytics.track('Reconnected after offline') : analytics.track('Offline / lost connection'); }); - } + }; render = () => ( - + Offline - ) + ); } export default compose( withNetInfo, - onlyUpdateForKeys(['isConnected']), + onlyUpdateForKeys(['isConnected']) )(OfflineBadge); diff --git a/src/components/QRCodeDisplay.js b/src/components/QRCodeDisplay.js index 0cb058f17a5..42731fc27e7 100644 --- a/src/components/QRCodeDisplay.js +++ b/src/components/QRCodeDisplay.js @@ -4,11 +4,7 @@ import QRCode from 'react-native-qrcode-svg'; import { onlyUpdateForPropTypes } from 'recompact'; const QRCodeDisplay = ({ size, value, ...props }) => ( - + ); QRCodeDisplay.propTypes = { diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index d8c3fd582d6..375266524e0 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -6,11 +6,7 @@ import { compose } from 'recompact'; import { estimateGasLimit } from '../handlers/web3'; import { greaterThan } from '../helpers/utilities'; import { isValidAddress } from '../helpers/validators'; -import { - withAccountData, - withGas, - withUniqueTokens, -} from '../hoc'; +import { withAccountData, withGas, withUniqueTokens } from '../hoc'; import lang from '../languages'; import { sendClearFields, @@ -92,39 +88,42 @@ export const withSendComponentWithData = (SendComponent, options) => { this.defaultAsset = options.defaultAsset; this.gasFormat = options.gasFormat || 'long'; - this.sendTransactionCallback = options.sendTransactionCallback || function noop() {}; + this.sendTransactionCallback = + options.sendTransactionCallback || function noop() {}; } componentDidMount() { - this.props.sendModalInit({ defaultAsset: this.defaultAsset, gasFormat: this.gasFormat }); + this.props.sendModalInit({ + defaultAsset: this.defaultAsset, + gasFormat: this.gasFormat, + }); } async componentDidUpdate(prevProps) { - const { - address, - assetAmount, - recipient, - selected, - } = this.props; + const { address, assetAmount, recipient, selected } = this.props; if (recipient !== prevProps.recipient) { const validAddress = await isValidAddress(recipient); + // eslint-disable-next-line react/no-did-update-set-state this.setState({ isValidAddress: validAddress }); } if (this.state.isValidAddress) { - if ((selected.symbol !== prevProps.selected.symbol) - || (recipient !== prevProps.recipient) - || (assetAmount !== prevProps.assetAmount)) { + if ( + selected.symbol !== prevProps.selected.symbol || + recipient !== prevProps.recipient || + assetAmount !== prevProps.assetAmount + ) { estimateGasLimit({ address, amount: assetAmount, asset: selected, recipient, - }).then(gasLimit => { - this.props.gasUpdateTxFee(gasLimit); - }).catch(error => { - }); + }) + .then(gasLimit => { + this.props.gasUpdateTxFee(gasLimit); + }) + .catch(() => {}); } } } @@ -153,7 +152,7 @@ export const withSendComponentWithData = (SendComponent, options) => { this.props.sendModalInit({ defaultAsset: this.defaultAsset }); }; - onSubmit = async (event) => { + onSubmit = async event => { if (event && typeof event.preventDefault === 'function') { event.preventDefault(); } @@ -170,10 +169,14 @@ export const withSendComponentWithData = (SendComponent, options) => { return; } if (this.props.selected.address === 'eth') { - const { requestedAmount, balance, amountWithFees } = ethereumUtils.transactionData( + const { + requestedAmount, + balance, + amountWithFees, + } = ethereumUtils.transactionData( this.props.assets, this.props.assetAmount, - this.props.selectedGasPrice, + this.props.selectedGasPrice ); if (greaterThan(requestedAmount, balance)) { @@ -183,10 +186,14 @@ export const withSendComponentWithData = (SendComponent, options) => { return; } } else if (!this.props.selected.isNft) { - const { requestedAmount, balance, txFee } = ethereumUtils.transactionData( + const { + requestedAmount, + balance, + txFee, + } = ethereumUtils.transactionData( this.props.assets, this.props.assetAmount, - this.props.selectedGasPrice, + this.props.selectedGasPrice ); const tokenBalance = get(this.props, 'selected.balance.amount'); @@ -201,14 +208,17 @@ export const withSendComponentWithData = (SendComponent, options) => { this.props.sendToggleConfirmationView(true); - return this.props.sendTransaction({ - address: this.props.address, - amount: this.props.assetAmount, - asset: this.props.selected, - gasLimit: this.props.gasLimit, - gasPrice: this.props.selectedGasPrice, - recipient: this.props.recipient, - }, this.sendTransactionCallback); + return this.props.sendTransaction( + { + address: this.props.address, + amount: this.props.assetAmount, + asset: this.props.selected, + gasLimit: this.props.gasLimit, + gasPrice: this.props.selectedGasPrice, + recipient: this.props.recipient, + }, + this.sendTransactionCallback + ); } }; @@ -217,9 +227,12 @@ export const withSendComponentWithData = (SendComponent, options) => { }; // QR Code Reader Handlers - toggleQRCodeReader = () => this.setState({ showQRCodeReader: !this.state.showQRCodeReader }); + toggleQRCodeReader = () => + this.setState(prevState => ({ + showQRCodeReader: !prevState.showQRCodeReader, + })); - onQRCodeValidate = async (rawData) => { + onQRCodeValidate = async rawData => { const data = rawData.match(/0x\w{40}/g) ? rawData.match(/0x\w{40}/g)[0] : null; @@ -227,7 +240,8 @@ export const withSendComponentWithData = (SendComponent, options) => { if (data) { result = await isValidAddress(data); } - const onError = () => console.log(lang.t('notification.error.invalid_address_scanned')); + const onError = () => + console.log(lang.t('notification.error.invalid_address_scanned')); return { data, onError, result }; }; @@ -261,19 +275,23 @@ export const withSendComponentWithData = (SendComponent, options) => { } return compose( - connect(mapStateToProps, { - sendClearFields, - sendMaxBalance, - sendModalInit, - sendToggleConfirmationView, - sendTransaction, - sendUpdateAssetAmount, - sendUpdateNativeAmount, - sendUpdateRecipient, - sendUpdateSelected, - }), + connect( + mapStateToProps, + { + sendClearFields, + sendMaxBalance, + sendModalInit, + sendToggleConfirmationView, + sendTransaction, + sendUpdateAssetAmount, + + sendUpdateNativeAmount, + sendUpdateRecipient, + sendUpdateSelected, + } + ), withGas, withAccountData, - withUniqueTokens, + withUniqueTokens )(SendComponentWithData); }; diff --git a/src/components/Tag.js b/src/components/Tag.js index d8d46f1316e..4815c834304 100644 --- a/src/components/Tag.js +++ b/src/components/Tag.js @@ -51,7 +51,7 @@ const enhance = compose( text: upperFirst(text), title: upperCase(title), })), - onlyUpdateForKeys(['text', 'title']), + onlyUpdateForKeys(['text', 'title']) ); const Tag = enhance(({ text, title, ...props }) => ( diff --git a/src/components/TouchableBackdrop.js b/src/components/TouchableBackdrop.js index 1ea865bed17..c8978cad0b5 100644 --- a/src/components/TouchableBackdrop.js +++ b/src/components/TouchableBackdrop.js @@ -9,7 +9,7 @@ const TouchableBackdrop = props => ( css={` ${position.cover}; background-color: ${colors.transparent}; - z-index: ${({ zIndex }) => (zIndex)}; + z-index: ${({ zIndex }) => zIndex}; `} {...props} /> diff --git a/src/components/activity-list/ActivityList.js b/src/components/activity-list/ActivityList.js index cbcb13f8d13..c327b233753 100644 --- a/src/components/activity-list/ActivityList.js +++ b/src/components/activity-list/ActivityList.js @@ -1,11 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { - compose, - mapProps, - onlyUpdateForKeys, - withProps, -} from 'recompact'; +import { compose, mapProps, onlyUpdateForKeys, withProps } from 'recompact'; import { buildTransactionsSectionsSelector } from '../../helpers/transactions'; import { withAccountAddress, @@ -25,11 +20,13 @@ const ActivityList = ({ header, isEmpty, sections }) => ( ActivityList.propTypes = { header: PropTypes.node, isEmpty: PropTypes.bool, - sections: PropTypes.arrayOf(PropTypes.shape({ - data: PropTypes.array, - renderItem: PropTypes.func, - title: PropTypes.string.isRequired, - })), + sections: PropTypes.arrayOf( + PropTypes.shape({ + data: PropTypes.array, + renderItem: PropTypes.func, + title: PropTypes.string.isRequired, + }) + ), }; export default compose( @@ -37,12 +34,7 @@ export default compose( withAccountSettings, withAccountTransactions, withProps(buildTransactionsSectionsSelector), - mapProps(({ - nativeCurrency, - requests, - sections, - ...props - }) => { + mapProps(({ nativeCurrency, requests, sections, ...props }) => { let pendingTransactionsCount = 0; const pendingTxSection = sections[requests.length ? 1 : 0]; @@ -63,5 +55,5 @@ export default compose( 'nativeCurrency', 'pendingTransactionsCount', 'sections', - ]), + ]) )(ActivityList); diff --git a/src/components/activity-list/ActivityListHeader.js b/src/components/activity-list/ActivityListHeader.js index 28286ecd584..c88fd71db3f 100644 --- a/src/components/activity-list/ActivityListHeader.js +++ b/src/components/activity-list/ActivityListHeader.js @@ -1,9 +1,4 @@ -import { - compose, - onlyUpdateForKeys, - pickProps, - withProps, -} from 'recompact'; +import { compose, onlyUpdateForKeys, pickProps, withProps } from 'recompact'; import { ListHeader } from '../list'; import { Text } from '../text'; @@ -20,5 +15,5 @@ export default compose( showDivider: false, titleRenderer, }), - onlyUpdateForKeys(['title']), + onlyUpdateForKeys(['title']) )(ListHeader); diff --git a/src/components/activity-list/RecyclerActivityList.js b/src/components/activity-list/RecyclerActivityList.js index 62addde8af6..7a11f93a82e 100644 --- a/src/components/activity-list/RecyclerActivityList.js +++ b/src/components/activity-list/RecyclerActivityList.js @@ -1,12 +1,20 @@ import { get, times } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { RecyclerListView, DataProvider, LayoutProvider } from 'recyclerlistview'; +import { + RecyclerListView, + DataProvider, + LayoutProvider, +} from 'recyclerlistview'; import StickyContainer from 'recyclerlistview/dist/reactnative/core/StickyContainer'; import styled from 'styled-components/primitives/dist/styled-components-primitives.esm'; import { buildTransactionUniqueIdentifier } from '../../helpers/transactions'; import { colors } from '../../styles'; -import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; +import { + deviceUtils, + isNewValueForPath, + safeAreaInsetValues, +} from '../../utils'; import { AssetListItemSkeleton } from '../asset-list'; import { ContractInteractionCoinRow, @@ -35,38 +43,49 @@ const LoadingState = ({ children }) => ( {children} - + - {times(11, index => )} + {times(11, index => ( + + ))} ); const hasRowChanged = (r1, r2) => { - if (r1.hash === '_header' && isNewValueForPath(r1, r2, 'header.props.accountAddress')) { + if ( + r1.hash === '_header' && + isNewValueForPath(r1, r2, 'header.props.accountAddress') + ) { return true; } const r1Key = r1.hash ? r1.hash : get(r1, 'displayDetails.timestampInMs', ''); const r2Key = r2.hash ? r2.hash : get(r2, 'displayDetails.timestampInMs', ''); - return (r1Key !== r2Key) - || isNewValueForPath(r1, r2, 'native.symbol') - || isNewValueForPath(r1, r2, 'pending'); + return ( + r1Key !== r2Key || + isNewValueForPath(r1, r2, 'native.symbol') || + isNewValueForPath(r1, r2, 'pending') + ); }; export default class RecyclerActivityList extends PureComponent { static propTypes = { header: PropTypes.node, isLoading: PropTypes.bool, - sections: PropTypes.arrayOf(PropTypes.shape({ - data: PropTypes.array, - title: PropTypes.string.isRequired, - })), + sections: PropTypes.arrayOf( + PropTypes.shape({ + data: PropTypes.array, + title: PropTypes.string.isRequired, + }) + ), }; constructor(args) { @@ -103,24 +122,31 @@ export default class RecyclerActivityList extends PureComponent { } else if (type === ViewTypes.HEADER) { dim.height = 35; } else { - dim.height = this.props.isLoading ? deviceUtils.dimensions.height : 204; + dim.height = this.props.isLoading + ? deviceUtils.dimensions.height + : 204; } - }, + } ); } static getDerivedStateFromProps(props, state) { const headersIndices = []; - const items = props.sections.reduce((ctx, section) => { - headersIndices.push(ctx.length); - return ctx - .concat([{ - hash: section.title, - title: section.title, - }]) - .concat(section.data) - .concat([{ hash: `${section.title}_end` }]); // footer - }, [{ hash: '_header', header: props.header }]); // header + const items = props.sections.reduce( + (ctx, section) => { + headersIndices.push(ctx.length); + return ctx + .concat([ + { + hash: section.title, + title: section.title, + }, + ]) + .concat(section.data) + .concat([{ hash: `${section.title}_end` }]); // footer + }, + [{ hash: '_header', header: props.header }] + ); // header if (items.length > 1) { items.pop(); // remove last footer } @@ -130,25 +156,28 @@ export default class RecyclerActivityList extends PureComponent { }; } - getStableId = (index) => { + getStableId = index => { const row = get(this.state, `dataProvider._data[${index}]`); return buildTransactionUniqueIdentifier(row); }; rowRenderer = (type, data) => { if (type === ViewTypes.COMPONENT_HEADER) { - return this.props.isLoading - ? {data.header} - : data.header; + return this.props.isLoading ? ( + {data.header} + ) : ( + data.header + ); } if (type === ViewTypes.HEADER) return ; if (type === ViewTypes.FOOTER) return ; if (!data) return null; if (!data.hash) return ; - if (!data.symbol && data.dappName) return ; + if (!data.symbol && data.dappName) + return ; return ; - } + }; render = () => ( @@ -165,5 +194,5 @@ export default class RecyclerActivityList extends PureComponent { /> - ) + ); } diff --git a/src/components/alerts/Alert.js b/src/components/alerts/Alert.js index 4b1564e6762..de9b3df78d7 100644 --- a/src/components/alerts/Alert.js +++ b/src/components/alerts/Alert.js @@ -1,8 +1,9 @@ import BaseAlert from './BaseAlert'; -const Alert = (options) => BaseAlert({ - ...options, - alertType: 'alert', -}); +const Alert = options => + BaseAlert({ + ...options, + alertType: 'alert', + }); export default Alert; diff --git a/src/components/alerts/BaseAlert.js b/src/components/alerts/BaseAlert.js index e4bd083c106..49e55ed5954 100644 --- a/src/components/alerts/BaseAlert.js +++ b/src/components/alerts/BaseAlert.js @@ -1,22 +1,18 @@ import PropTypes from 'prop-types'; import { Alert } from 'react-native'; -const BaseAlert = ({ - alertType, - buttons, - callback, - message, - title, - type, -}) => Alert[alertType](title, message, buttons || callback, type); +const BaseAlert = ({ alertType, buttons, callback, message, title, type }) => + Alert[alertType](title, message, buttons || callback, type); BaseAlert.propTypes = { alertType: PropTypes.oneOf(['alert', 'prompt']).isRequired, - buttons: PropTypes.arrayOf(PropTypes.shape({ - onPress: PropTypes.func, - style: PropTypes.oneOf(['cancel', 'default', 'destructive']), - text: PropTypes.string.isRequired, - })), + buttons: PropTypes.arrayOf( + PropTypes.shape({ + onPress: PropTypes.func, + style: PropTypes.oneOf(['cancel', 'default', 'destructive']), + text: PropTypes.string.isRequired, + }) + ), callback: PropTypes.func, message: PropTypes.string, title: PropTypes.string.isRequired, diff --git a/src/components/alerts/Prompt.js b/src/components/alerts/Prompt.js index 5838eaa8d45..f3ba639dd03 100644 --- a/src/components/alerts/Prompt.js +++ b/src/components/alerts/Prompt.js @@ -1,8 +1,9 @@ import BaseAlert from './BaseAlert'; -const Prompt = (options) => BaseAlert({ - ...options, - alertType: 'prompt', -}); +const Prompt = options => + BaseAlert({ + ...options, + alertType: 'prompt', + }); export default Prompt; diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index eca6e244eeb..c540b2194a2 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -2,7 +2,11 @@ import { omit, pick, toUpper } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { InteractionManager } from 'react-native'; -import { createNativeWrapper, PureNativeButton, State } from 'react-native-gesture-handler'; +import { + createNativeWrapper, + PureNativeButton, + State, +} from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { @@ -34,14 +38,7 @@ const { Value, } = Animated; -const { - ACTIVE, - BEGAN, - CANCELLED, - END, - FAILED, - UNDETERMINED, -} = State; +const { ACTIVE, BEGAN, CANCELLED, END, FAILED, UNDETERMINED } = State; const TransformOriginMap = { BOTTOM: 3, @@ -50,19 +47,14 @@ const TransformOriginMap = { TOP: 1, }; -const { - BOTTOM, - LEFT, - RIGHT, - TOP, -} = TransformOriginMap; +const { BOTTOM, LEFT, RIGHT, TOP } = TransformOriginMap; const AnimatedRawButton = createNativeWrapper( createAnimatedComponent(PureNativeButton), { shouldActivateOnStart: true, shouldCancelWhenOutside: true, - }, + } ); const AnimatedRawButtonPropBlacklist = [ @@ -103,7 +95,7 @@ export default class ButtonPressAnimation extends PureComponent { style: stylePropType, tapRef: PropTypes.object, transformOrigin: directionPropType, - } + }; static defaultProps = { activeOpacity: 1, @@ -115,7 +107,7 @@ export default class ButtonPressAnimation extends PureComponent { hapticType: HapticFeedbackTypes.selection, minLongPressDuration: 500, scaleTo: animations.keyframes.button.to.scale, - } + }; constructor(props) { super(props); @@ -139,48 +131,53 @@ export default class ButtonPressAnimation extends PureComponent { const isDirectionNegative = or( eq(this.transformOrigin, LEFT), - eq(this.transformOrigin, TOP), + eq(this.transformOrigin, TOP) ); this.directionMultiple = cond(isDirectionNegative, -1, 1); - this.onGestureEvent = event([{ - nativeEvent: { - state: this.gestureState, + this.onGestureEvent = event([ + { + nativeEvent: { + state: this.gestureState, + }, }, - }]); + ]); } componentWillUnmount = () => { this.reset(); - } + }; clearInteraction = () => { if (this.props.isInteraction && this.handle) { InteractionManager.clearInteractionHandle(this.handle); this.handle = undefined; } - } + }; clearLongPressListener = () => { this.longPressDetected = false; if (this.longPressTimeout) { clearTimeout(this.longPressTimeout); } - } + }; createInteraction = () => { if (this.props.isInteraction && !this.handle) { this.handle = InteractionManager.createInteractionHandle(); } - } + }; createLongPressListener = () => { const { minLongPressDuration, onLongPress } = this.props; if (onLongPress) { - this.longPressTimeout = setTimeout(this.handleDetectedLongPress, minLongPressDuration); + this.longPressTimeout = setTimeout( + this.handleDetectedLongPress, + minLongPressDuration + ); } - } + }; handleHaptic = () => { const { enableHapticFeedback, hapticType } = this.props; @@ -188,42 +185,43 @@ export default class ButtonPressAnimation extends PureComponent { if (enableHapticFeedback) { ReactNativeHapticFeedback.trigger(hapticType); } - } + }; handleLayout = ({ nativeEvent: { layout } }) => { // only setState if height+width dont already exist if (!Object.values(this.state).reduce((a, b) => a + b)) { + // TODO ??? + // eslint-disable-next-line react/no-access-state-in-setstate this.setState(pick(layout, Object.keys(this.state))); } - } + }; handleDetectedLongPress = () => { this.longPressDetected = true; this.props.onLongPress(); - } + }; handlePress = () => { if (!this.longPressDetected && this.props.onPress) { this.props.onPress(); } - } + }; handlePressStart = () => { if (this.props.onPressStart) { this.props.onPressStart(); } - } + }; - handleRunInteraction = () => ( + handleRunInteraction = () => this.props.isInteraction ? InteractionManager.runAfterInteractions(this.handlePress) - : this.handlePress() - ) + : this.handlePress(); reset = () => { this.clearInteraction(); this.clearLongPressListener(); - } + }; render = () => { const { @@ -243,13 +241,13 @@ export default class ButtonPressAnimation extends PureComponent { const offsetX = cond( or(eq(this.transformOrigin, LEFT), eq(this.transformOrigin, RIGHT)), divide(multiply(floor(this.state.width), this.directionMultiple), 2), - 0, + 0 ); const offsetY = cond( or(eq(this.transformOrigin, BOTTOM), eq(this.transformOrigin, TOP)), divide(multiply(floor(this.state.height), this.directionMultiple), 2), - 0, + 0 ); const opacity = cond( @@ -258,10 +256,12 @@ export default class ButtonPressAnimation extends PureComponent { interpolate(divide(this.scale, defaultScale), { inputRange: [scaleTo, defaultScale], outputRange: [activeOpacity, 1], - }), + }) ); - const transform = transformOriginUtil(offsetX, offsetY, { scale: this.scale }); + const transform = transformOriginUtil(offsetX, offsetY, { + scale: this.scale, + }); return ( @@ -283,60 +283,49 @@ export default class ButtonPressAnimation extends PureComponent { ); - } + }; } diff --git a/src/components/animations/FadeInAnimation.js b/src/components/animations/FadeInAnimation.js index ea3597c1310..f39ae76ab43 100644 --- a/src/components/animations/FadeInAnimation.js +++ b/src/components/animations/FadeInAnimation.js @@ -25,7 +25,7 @@ export default class FadeInAnimation extends PureComponent { isInteraction: PropTypes.bool, style: PropTypes.object, to: PropTypes.number, - } + }; static defaultProps = { duration: 315, @@ -33,18 +33,13 @@ export default class FadeInAnimation extends PureComponent { from: 0, isInteraction: false, to: 1, - } + }; runTiming = () => { - const { - duration, - easing, - from, - isInteraction, - to, - } = this.props; + const { duration, easing, from, isInteraction, to } = this.props; - const handle = isInteraction && InteractionManager.createInteractionHandle(); + const handle = + isInteraction && InteractionManager.createInteractionHandle(); const state = { finished: new Value(0), @@ -73,21 +68,22 @@ export default class FadeInAnimation extends PureComponent { timing(clock, state, config), cond(state.finished, [ stopClock(clock), - call([], () => isInteraction && InteractionManager.clearInteractionHandle(handle)), + call( + [], + () => + isInteraction && InteractionManager.clearInteractionHandle(handle) + ), ]), state.position, ]); - } + }; animatedOpacity = this.runTiming(); render = () => ( - ) + ); } diff --git a/src/components/animations/FlyInAnimation.js b/src/components/animations/FlyInAnimation.js index 18fa2836fb4..61d74451ab3 100644 --- a/src/components/animations/FlyInAnimation.js +++ b/src/components/animations/FlyInAnimation.js @@ -2,15 +2,14 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import Animated, { Easing } from 'react-native-reanimated'; -const buildAnimation = (value, toValue) => ( +const buildAnimation = (value, toValue) => Animated.timing(value, { duration: 175, easing: Easing.bezier(0.165, 0.84, 0.44, 1), isInteraction: false, toValue, useNativeDriver: true, - }).start() -); + }).start(); export default class FlyInAnimation extends PureComponent { static propTypes = { @@ -18,18 +17,17 @@ export default class FlyInAnimation extends PureComponent { style: PropTypes.object, }; - animation = new Animated.Value(0) + componentDidMount = () => buildAnimation(this.animation, 1); - componentDidMount = () => buildAnimation(this.animation, 1) + componentWillUnmount = () => buildAnimation(this.animation, 0); - componentWillUnmount = () => buildAnimation(this.animation, 0) + animation = new Animated.Value(0); - buildInterpolation = outputRange => ( + buildInterpolation = outputRange => Animated.interpolate(this.animation, { inputRange: [0, 1], outputRange, - }) - ) + }); render = () => ( {this.props.children} - ) + ); } diff --git a/src/components/animations/OpacityToggler.js b/src/components/animations/OpacityToggler.js index 829de30261e..b16fb6c4488 100644 --- a/src/components/animations/OpacityToggler.js +++ b/src/components/animations/OpacityToggler.js @@ -38,10 +38,7 @@ function runTiming(clock, value, dest, friction, tension) { ]; return block([ - cond(state.finished, [ - ...reset, - set(config.toValue, dest), - ]), + cond(state.finished, [...reset, set(config.toValue, dest)]), cond(clockRunning(clock), 0, startClock(clock)), spring(clock, state, config), state.position, @@ -57,14 +54,14 @@ export default class OpacityToggler extends Component { isVisible: PropTypes.bool, startingOpacity: PropTypes.number, tension: PropTypes.number, - } + }; static defaultProps = { endingOpacity: 0, friction: 20, startingOpacity: 1, tension: 200, - } + }; componentWillMount() { if (!this.props.animationNode) { @@ -82,9 +79,19 @@ export default class OpacityToggler extends Component { tension, } = this.props; - if (prevProps.isVisible !== undefined && prevProps.isVisible !== isVisible && !animationNode) { + if ( + prevProps.isVisible !== undefined && + prevProps.isVisible !== isVisible && + !animationNode + ) { const clock = new Clock(); - const base = runTiming(clock, isVisible ? -1 : 1, isVisible ? 1 : -1, friction, tension); + const base = runTiming( + clock, + isVisible ? -1 : 1, + isVisible ? 1 : -1, + friction, + tension + ); this._opacity = interpolate(base, { inputRange: [-1, 1], outputRange: [endingOpacity, startingOpacity], @@ -103,17 +110,14 @@ export default class OpacityToggler extends Component { let opacity = !this._isVisible ? startingOpacity : endingOpacity; if (animationNode) { - opacity = (startingOpacity === 0) - ? animationNode - : multiply(add(animationNode, -1), -1); + opacity = + startingOpacity === 0 + ? animationNode + : multiply(add(animationNode, -1), -1); } else if (this._opacity) { opacity = this._opacity; } - return ( - - {children} - - ); + return {children}; } } diff --git a/src/components/animations/RotationArrow.js b/src/components/animations/RotationArrow.js index e143f4524c0..4aacffaf35b 100644 --- a/src/components/animations/RotationArrow.js +++ b/src/components/animations/RotationArrow.js @@ -39,10 +39,7 @@ function runTiming(clock, value, dest, friction, tension) { ]; return block([ - cond(state.finished, [ - ...reset, - set(config.toValue, dest), - ]), + cond(state.finished, [...reset, set(config.toValue, dest)]), cond(clockRunning(clock), 0, startClock(clock)), spring(clock, state, config), state.position, @@ -56,14 +53,13 @@ export default class RotationArrow extends Component { endingPosition: PropTypes.number, friction: PropTypes.number, isOpen: PropTypes.bool, - reversed: PropTypes.bool, tension: PropTypes.number, - } + }; static defaultProps = { friction: 20, tension: 200, - } + }; componentWillMount() { if (!this.props.isOpen === true) { @@ -78,7 +74,13 @@ export default class RotationArrow extends Component { if (prevProps.isOpen !== undefined && prevProps.isOpen !== isOpen) { const clock = new Clock(); - const base = runTiming(clock, isOpen ? -1 : 1, isOpen ? 1 : -1, friction, tension); + const base = runTiming( + clock, + isOpen ? -1 : 1, + isOpen ? 1 : -1, + friction, + tension + ); this._transform = interpolate(base, { inputRange: [-1, 1], outputRange: [0, 1], @@ -87,11 +89,7 @@ export default class RotationArrow extends Component { } render() { - const { - children, - endingOffset, - endingPosition, - } = this.props; + const { children, endingOffset, endingPosition } = this.props; let translateX = 0; if (endingOffset) { @@ -102,7 +100,10 @@ export default class RotationArrow extends Component { let rotate = `${endingPosition}deg`; if (this._transform) { - rotate = concat(sub(endingPosition, multiply(this._transform, endingPosition)), 'deg'); + rotate = concat( + sub(endingPosition, multiply(this._transform, endingPosition)), + 'deg' + ); } return ( diff --git a/src/components/animations/RoundButtonSizeToggler.js b/src/components/animations/RoundButtonSizeToggler.js index 79bee18c197..ba6352d1087 100644 --- a/src/components/animations/RoundButtonSizeToggler.js +++ b/src/components/animations/RoundButtonSizeToggler.js @@ -25,7 +25,8 @@ const { const RoundButtonCapSize = 30; const RoundButtonCap = styled(Animated.View)` - ${({ capDirection }) => borders.buildRadius(capDirection, RoundButtonCapSize / 2)}; + ${({ capDirection }) => + borders.buildRadius(capDirection, RoundButtonCapSize / 2)}; ${position.size(RoundButtonCapSize)}; background-color: ${({ color }) => color}; `; @@ -51,10 +52,7 @@ function runTiming(clock, value, dest, friction, tension) { ]; return block([ - cond(state.finished, [ - ...reset, - set(config.toValue, dest), - ]), + cond(state.finished, [...reset, set(config.toValue, dest)]), cond(clockRunning(clock), 0, startClock(clock)), spring(clock, state, config), state.position, @@ -72,13 +70,13 @@ export default class RoundButtonSizeToggler extends PureComponent { startingWidth: PropTypes.number, tension: PropTypes.number, toggle: PropTypes.bool, - } + }; static defaultProps = { color: colors.lightBlueGrey, friction: 20, tension: 200, - } + }; static capSize = RoundButtonCapSize; @@ -87,16 +85,21 @@ export default class RoundButtonSizeToggler extends PureComponent { } componentWillUpdate(prevProps) { - const { - animationNode, - friction, - tension, - toggle, - } = this.props; + const { animationNode, friction, tension, toggle } = this.props; - if (!isNil(prevProps.toggle) && prevProps.toggle !== toggle && !animationNode) { + if ( + !isNil(prevProps.toggle) && + prevProps.toggle !== toggle && + !animationNode + ) { const clock = new Clock(); - const base = runTiming(clock, toggle ? -1 : 1, toggle ? 1 : -1, friction, tension); + const base = runTiming( + clock, + toggle ? -1 : 1, + toggle ? 1 : -1, + friction, + tension + ); this._width = interpolate(base, { inputRange: [-1, 1], outputRange: [1, 0], @@ -114,10 +117,13 @@ export default class RoundButtonSizeToggler extends PureComponent { startingWidth, } = this.props; - let contentScaleX = (startingWidth + (reversed ? 0 : (endingWidth + 5))) / 100; + let contentScaleX = + (startingWidth + (reversed ? 0 : endingWidth + 5)) / 100; if (animationNode) { - // eslint-disable-next-line max-len - contentScaleX = add(multiply(animationNode, (endingWidth / 100 - startingWidth / 100)), startingWidth / 100); + contentScaleX = add( + multiply(animationNode, endingWidth / 100 - startingWidth / 100), + startingWidth / 100 + ); } let contentTranslateX = reversed ? startingWidth : endingWidth; @@ -125,23 +131,24 @@ export default class RoundButtonSizeToggler extends PureComponent { contentTranslateX = multiply(divide(sub(1, contentScaleX, 100), 2), -1); } - let rightCapTranslateX = (-1 * (100 - (reversed ? startingWidth : endingWidth)) - 11); + let rightCapTranslateX = + -1 * (100 - (reversed ? startingWidth : endingWidth)) - 11; if (animationNode) { rightCapTranslateX = sub(multiply(-100, sub(1, contentScaleX)), 11); } return ( - + diff --git a/src/components/animations/ScaleInAnimation.js b/src/components/animations/ScaleInAnimation.js index d0f0bc63147..a9683af7694 100644 --- a/src/components/animations/ScaleInAnimation.js +++ b/src/components/animations/ScaleInAnimation.js @@ -10,30 +10,29 @@ const { createAnimatedComponent, interpolate } = Animated; const AnimatedCentered = createAnimatedComponent(toClass(Centered)); -const ScaleInAnimation = ({ - range, - scaleTo, - style, - value, - ...props -}) => ( +const ScaleInAnimation = ({ range, scaleTo, style, value, ...props }) => ( ); @@ -52,7 +51,7 @@ ScaleInAnimation.defaultProps = { from: 0, to: 100, }, - scaleTo: 0.420, + scaleTo: 0.42, }; export default pure(ScaleInAnimation); diff --git a/src/components/animations/SizeToggler.js b/src/components/animations/SizeToggler.js index c678edf8bbc..4a72fbd1364 100644 --- a/src/components/animations/SizeToggler.js +++ b/src/components/animations/SizeToggler.js @@ -38,10 +38,7 @@ function runTiming(clock, value, dest, friction, tension) { ]; return block([ - cond(state.finished, [ - ...reset, - set(config.toValue, dest), - ]), + cond(state.finished, [...reset, set(config.toValue, dest)]), cond(clockRunning(clock), 0, startClock(clock)), spring(clock, state, config), state.position, @@ -57,14 +54,14 @@ export default class SizeToggler extends Component { startingWidth: PropTypes.number, tension: PropTypes.number, toggle: PropTypes.bool, - } + }; static defaultProps = { endingOpacity: 0, friction: 20, startingOpacity: 1, tension: 200, - } + }; componentWillMount() { const { endingWidth, startingWidth, toggle } = this.props; @@ -86,9 +83,19 @@ export default class SizeToggler extends Component { toggle, } = this.props; - if (prevProps.toggle !== undefined && prevProps.toggle !== toggle && !animationNode) { + if ( + prevProps.toggle !== undefined && + prevProps.toggle !== toggle && + !animationNode + ) { const clock = new Clock(); - const base = runTiming(clock, toggle ? -1 : 1, toggle ? 1 : -1, friction, tension); + const base = runTiming( + clock, + toggle ? -1 : 1, + toggle ? 1 : -1, + friction, + tension + ); this._height = interpolate(base, { inputRange: [-1, 1], outputRange: [endingWidth, startingWidth], @@ -97,21 +104,12 @@ export default class SizeToggler extends Component { } render() { - const { - animationNode, - children, - endingWidth, - startingWidth, - } = this.props; + const { animationNode, children, endingWidth, startingWidth } = this.props; const height = animationNode - ? add(multiply(animationNode, (endingWidth - startingWidth)), startingWidth) + ? add(multiply(animationNode, endingWidth - startingWidth), startingWidth) : this._height; - return ( - - {children} - - ); + return {children}; } } diff --git a/src/components/animations/SpinAnimation.js b/src/components/animations/SpinAnimation.js index 69a57dad28c..42aa796f3aa 100644 --- a/src/components/animations/SpinAnimation.js +++ b/src/components/animations/SpinAnimation.js @@ -8,15 +8,13 @@ export default class SpinAnimation extends PureComponent { children: PropTypes.node, duration: PropTypes.number, style: stylePropType, - } + }; static defaultProps = { duration: 2000, - } + }; - animatedValue = new Animated.Value(0) - - componentDidMount = () => ( + componentDidMount = () => Animated.loop( Animated.timing(this.animatedValue, { duration: this.props.duration, @@ -24,26 +22,31 @@ export default class SpinAnimation extends PureComponent { isInteraction: false, toValue: 1, useNativeDriver: true, - }), - ).start() - ) + }) + ).start(); + + componentWillUnmount = () => this.animatedValue.stopAnimation(); - componentWillUnmount = () => this.animatedValue.stopAnimation() + animatedValue = new Animated.Value(0); - interpolatedAnimation = () => ( + interpolatedAnimation = () => this.animatedValue.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'], - }) - ) + }); render = () => { const { children, style } = this.props; return ( - + {children} ); - } + }; } diff --git a/src/components/asset-list/AssetList.js b/src/components/asset-list/AssetList.js index 2fa4bc73bf7..4cc39fb77e0 100644 --- a/src/components/asset-list/AssetList.js +++ b/src/components/asset-list/AssetList.js @@ -8,8 +8,10 @@ import { ListFooter } from '../list'; import EmptyAssetList from './EmptyAssetList'; import RecyclerAssetList from './RecyclerAssetList'; -const FabSizeWithPadding = FloatingActionButton.size + (FabWrapper.bottomPosition * 2); -const PaddingBottom = (safeAreaInsetValues.bottom + FabSizeWithPadding) - ListFooter.height; +const FabSizeWithPadding = + FloatingActionButton.size + FabWrapper.bottomPosition * 2; +const PaddingBottom = + safeAreaInsetValues.bottom + FabSizeWithPadding - ListFooter.height; const AssetList = ({ fetchData, @@ -20,25 +22,23 @@ const AssetList = ({ scrollViewTracker, sections, ...props -}) => ( - (isEmpty || isImporting) - ? ( - - ) : ( - - ) -); +}) => + isEmpty || isImporting ? ( + + ) : ( + + ); AssetList.propTypes = { fetchData: PropTypes.func.isRequired, @@ -52,10 +52,5 @@ AssetList.propTypes = { export default compose( withIsWalletImporting, - onlyUpdateForKeys([ - 'isEmpty', - 'isImporting', - 'isWalletEthZero', - 'sections', - ]), + onlyUpdateForKeys(['isEmpty', 'isImporting', 'isWalletEthZero', 'sections']) )(AssetList); diff --git a/src/components/asset-list/AssetListHeader.js b/src/components/asset-list/AssetListHeader.js index aff6a968c14..33cf9b0fe1f 100644 --- a/src/components/asset-list/AssetListHeader.js +++ b/src/components/asset-list/AssetListHeader.js @@ -7,12 +7,7 @@ import { ListHeader } from '../list'; const enhance = onlyUpdateForKeys(['title', 'totalValue']); -const AssetListHeader = enhance(({ - title, - totalValue, - isSticky, - ...props -}) => ( +const AssetListHeader = enhance(({ title, totalValue, isSticky, ...props }) => ( {totalValue ? ( diff --git a/src/components/asset-list/AssetListItemSkeleton.js b/src/components/asset-list/AssetListItemSkeleton.js index 5ff4fd15782..cd1740fa08c 100644 --- a/src/components/asset-list/AssetListItemSkeleton.js +++ b/src/components/asset-list/AssetListItemSkeleton.js @@ -27,7 +27,8 @@ const AnimatedLinearGradient = Animated.createAnimatedComponent(LinearGradient); const Container = styled.View` height: ${CoinRow.height}; - opacity: ${({ descendingOpacity, index }) => (1 - (0.2 * (descendingOpacity ? index : 0)))}; + opacity: ${({ descendingOpacity, index }) => + 1 - 0.2 * (descendingOpacity ? index : 0)}; width: 100%; `; @@ -54,7 +55,7 @@ const Wrapper = styled(RowWithMargins).attrs({ justify: 'space-between', margin: 11, })` - ${({ index }) => padding((index === 0 ? 15 : 12.5), 19, 12.5, 15)}; + ${({ index }) => padding(index === 0 ? 15 : 12.5, 19, 12.5, 15)}; ${position.size('100%')}; background-color: ${colors.transparent}; `; @@ -64,12 +65,12 @@ export default class AssetListItemSkeleton extends PureComponent { animated: PropTypes.bool, descendingOpacity: PropTypes.bool, index: PropTypes.number, - } + }; static defaultProps = { animated: true, index: 0, - } + }; startShimmerLoop = () => { const clock = new Clock(); @@ -100,9 +101,9 @@ export default class AssetListItemSkeleton extends PureComponent { ]), state.position, ]); - } + }; - animation = this.startShimmerLoop() + animation = this.startShimmerLoop(); renderShimmer = () => { const gradientColors = [ @@ -134,7 +135,7 @@ export default class AssetListItemSkeleton extends PureComponent { /> ); - } + }; render = () => { const { animated, descendingOpacity, index } = this.props; @@ -161,11 +162,14 @@ export default class AssetListItemSkeleton extends PureComponent { return ( - {animated - ? {this.renderShimmer()} - : skeletonElement - } + {animated ? ( + + {this.renderShimmer()} + + ) : ( + skeletonElement + )} ); - } + }; } diff --git a/src/components/asset-list/EmptyAssetList.js b/src/components/asset-list/EmptyAssetList.js index a367368ae80..87356881e30 100644 --- a/src/components/asset-list/EmptyAssetList.js +++ b/src/components/asset-list/EmptyAssetList.js @@ -32,7 +32,9 @@ const EmptyAssetList = ({ {times(skeletonCount, index => renderSkeleton(index, isWalletEthZero))} - {isWalletEthZero && ()} + {isWalletEthZero && ( + + )} ); diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index ac58d70a442..3e74cab417f 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -1,9 +1,4 @@ -import { - findIndex, - get, - has, - isNil, -} from 'lodash'; +import { findIndex, get, has, isNil } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { LayoutAnimation, RefreshControl, View } from 'react-native'; @@ -14,7 +9,6 @@ import { RecyclerListView, } from 'recyclerlistview'; import StickyContainer from 'recyclerlistview/dist/reactnative/core/StickyContainer'; -import styled from 'styled-components/primitives'; import { withFabSelection, withOpenBalances, @@ -22,12 +16,20 @@ import { withOpenInvestmentCards, } from '../../hoc'; import { colors } from '../../styles'; -import { deviceUtils, isNewValueForPath, safeAreaInsetValues } from '../../utils'; +import { + deviceUtils, + isNewValueForPath, + safeAreaInsetValues, +} from '../../utils'; import { CoinDivider, SmallBalancesWrapper } from '../coin-divider'; import { CoinRow } from '../coin-row'; import { TokenFamilyHeader } from '../token-family'; import { FloatingActionButton } from '../fab'; -import { InvestmentCard, UniswapInvestmentCard, InvestmentCardHeader } from '../investment-cards'; +import { + InvestmentCard, + UniswapInvestmentCard, + InvestmentCardHeader, +} from '../investment-cards'; import { ListFooter } from '../list'; import { UniqueTokenRow } from '../unique-token'; import AssetListHeader from './AssetListHeader'; @@ -56,14 +58,15 @@ const NOOP = () => undefined; const layoutItemAnimator = { animateDidMount: NOOP, - animateShift: () => LayoutAnimation.configureNext({ - duration: 200, - update: { - initialVelocity: 0, - springDamping: 1, - type: LayoutAnimation.Types.spring, - }, - }), + animateShift: () => + LayoutAnimation.configureNext({ + duration: 200, + update: { + initialVelocity: 0, + springDamping: 1, + type: LayoutAnimation.Types.spring, + }, + }), animateWillMount: NOOP, animateWillUnmount: NOOP, animateWillUpdate: NOOP, @@ -72,7 +75,6 @@ const layoutItemAnimator = { const reloadHeightOffsetTop = -60; const reloadHeightOffsetBottom = -62; -// eslint-disable-next-line react/prop-types const AssetListHeaderRenderer = pure(data => ); const hasRowChanged = (r1, r2) => { @@ -84,27 +86,37 @@ const hasRowChanged = (r1, r2) => { const isNewTokenFamilyId = isNewValueForPath(r1, r2, 'item.familyId'); const isNewTokenFamilyName = isNewValueForPath(r1, r2, 'item.familyName'); const isNewTokenFamilySize = isNewValueForPath(r1, r2, 'item.childrenAmount'); - const isNewUniswapPercentageOwned = isNewValueForPath(r1, r2, 'item.percentageOwned'); + const isNewUniswapPercentageOwned = isNewValueForPath( + r1, + r2, + 'item.percentageOwned' + ); const isNewUniswapToken = isNewValueForPath(r1, r2, 'item.tokenSymbol'); const isCollectiblesRow = has(r1, 'item.tokens') && has(r2, 'item.tokens'); let isNewAssetBalance = false; if (!isCollectiblesRow) { - isNewAssetBalance = isNewValueForPath(r1, r2, 'item.native.balance.display'); + isNewAssetBalance = isNewValueForPath( + r1, + r2, + 'item.native.balance.display' + ); } - return isNewAsset - || isNewAssetBalance - || isNewShowShitcoinsValue - || isNewTitle - || isNewTokenFamilyId - || isNewTokenFamilyName - || isNewTokenFamilySize - || isNewTotalItems - || isNewTotalValue - || isNewUniswapPercentageOwned - || isNewUniswapToken; + return ( + isNewAsset || + isNewAssetBalance || + isNewShowShitcoinsValue || + isNewTitle || + isNewTokenFamilyId || + isNewTokenFamilyName || + isNewTokenFamilySize || + isNewTotalItems || + isNewTotalValue || + isNewUniswapPercentageOwned || + isNewUniswapToken + ); }; class RecyclerAssetList extends Component { @@ -119,36 +131,28 @@ class RecyclerAssetList extends Component { renderAheadOffset: PropTypes.number, scrollingVelocity: PropTypes.number, scrollViewTracker: PropTypes.object, - sections: PropTypes.arrayOf(PropTypes.shape({ - balances: PropTypes.bool, - collectibles: PropTypes.bool, - data: PropTypes.array.isRequired, - header: PropTypes.shape({ - title: PropTypes.string, - totalItems: PropTypes.number, - totalValue: PropTypes.string, - }), - investments: PropTypes.bool, - perData: PropTypes.object, - renderItem: PropTypes.func.isRequired, - type: PropTypes.string, - })), + sections: PropTypes.arrayOf( + PropTypes.shape({ + balances: PropTypes.bool, + collectibles: PropTypes.bool, + data: PropTypes.array.isRequired, + header: PropTypes.shape({ + title: PropTypes.string, + totalItems: PropTypes.number, + totalValue: PropTypes.string, + }), + investments: PropTypes.bool, + perData: PropTypes.object, + renderItem: PropTypes.func.isRequired, + type: PropTypes.string, + }) + ), }; static defaultProps = { renderAheadOffset: deviceUtils.dimensions.height, }; - rlv = React.createRef(); - - contentSize = 0; - - layoutMeasurement = 0; - - position = 0; - - refresh = false; - constructor(props) { super(props); @@ -161,9 +165,7 @@ class RecyclerAssetList extends Component { this.layoutProvider = new LayoutProvider( index => { - const { - openFamilyTabs, openInvestmentCards, sections, - } = this.props; + const { openFamilyTabs, openInvestmentCards, sections } = this.props; const { headersIndices } = this.state; if (headersIndices.includes(index)) { @@ -174,15 +176,32 @@ class RecyclerAssetList extends Component { return ViewTypes.FOOTER; } - const balancesIndex = findIndex(sections, ({ name }) => name === 'balances'); - const collectiblesIndex = findIndex(sections, ({ name }) => name === 'collectibles'); - const investmentsIndex = findIndex(sections, ({ name }) => name === 'investments'); + const balancesIndex = findIndex( + sections, + ({ name }) => name === 'balances' + ); + const collectiblesIndex = findIndex( + sections, + ({ name }) => name === 'collectibles' + ); + const investmentsIndex = findIndex( + sections, + ({ name }) => name === 'investments' + ); if (balancesIndex > -1) { - const balanceItemsCount = get(sections, `[${balancesIndex}].data.length`, 0); - const lastBalanceIndex = headersIndices[balancesIndex] + balanceItemsCount; + const balanceItemsCount = get( + sections, + `[${balancesIndex}].data.length`, + 0 + ); + const lastBalanceIndex = + headersIndices[balancesIndex] + balanceItemsCount; if (index === lastBalanceIndex) { - if (sections[balancesIndex].data[lastBalanceIndex - 1].smallBalancesContainer) { + if ( + sections[balancesIndex].data[lastBalanceIndex - 1] + .smallBalancesContainer + ) { return ViewTypes.COIN_SMALL_BALANCES; } return ViewTypes.COIN_ROW_LAST; @@ -190,11 +209,25 @@ class RecyclerAssetList extends Component { } if (investmentsIndex > -1) { - const investmentItemsCount = get(sections, `[${investmentsIndex}].data.length`, 0); - const lastInvestmentIndex = headersIndices[investmentsIndex] + investmentItemsCount; - - if ((index > headersIndices[investmentsIndex]) && (index <= lastInvestmentIndex)) { - if (!openInvestmentCards[sections[investmentsIndex].data[index - headersIndices[investmentsIndex] - 1].uniqueId]) { + const investmentItemsCount = get( + sections, + `[${investmentsIndex}].data.length`, + 0 + ); + const lastInvestmentIndex = + headersIndices[investmentsIndex] + investmentItemsCount; + + if ( + index > headersIndices[investmentsIndex] && + index <= lastInvestmentIndex + ) { + if ( + !openInvestmentCards[ + sections[investmentsIndex].data[ + index - headersIndices[investmentsIndex] - 1 + ].uniqueId + ] + ) { return index === lastInvestmentIndex ? ViewTypes.UNISWAP_ROW_LAST : ViewTypes.UNISWAP_ROW; @@ -209,12 +242,21 @@ class RecyclerAssetList extends Component { if (index > headersIndices[collectiblesIndex]) { const familyIndex = index - headersIndices[collectiblesIndex] - 1; if (openFamilyTabs[familyIndex]) { - if (get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`)) { + if ( + get( + sections, + `[${collectiblesIndex}].data[${familyIndex}].tokens` + ) + ) { return { get: ViewTypes.UNIQUE_TOKEN_ROW, isFirst: index === headersIndices[collectiblesIndex] + 1, isLast: index === this.state.itemsCount - 2, - rowCount: get(sections, `[${collectiblesIndex}].data[${familyIndex}].tokens`, []).length, + rowCount: get( + sections, + `[${collectiblesIndex}].data[${familyIndex}].tokens`, + [] + ).length, }; } } @@ -245,47 +287,68 @@ class RecyclerAssetList extends Component { return; } - const fabPositionBottom = type.isLast ? (paddingBottom - (FloatingActionButton.size / 2)) : 0; - const TokenFamilyHeaderHeight = TokenFamilyHeader.height + fabPositionBottom; + const fabPositionBottom = type.isLast + ? paddingBottom - FloatingActionButton.size / 2 + : 0; + const TokenFamilyHeaderHeight = + TokenFamilyHeader.height + fabPositionBottom; const firstRowExtraTopPadding = type.isFirst ? 4 : 0; if (type.get === ViewTypes.UNIQUE_TOKEN_ROW) { const heightOfRows = type.rowCount * UniqueTokenRow.cardSize; - const heightOfRowMargins = UniqueTokenRow.cardMargin * (type.rowCount - 1); + const heightOfRowMargins = + UniqueTokenRow.cardMargin * (type.rowCount - 1); const extraSpaceForDropShadow = 19; - dim.height = ( - TokenFamilyHeaderHeight - + heightOfRows - + heightOfRowMargins - + firstRowExtraTopPadding - + extraSpaceForDropShadow - ); + dim.height = + TokenFamilyHeaderHeight + + heightOfRows + + heightOfRowMargins + + firstRowExtraTopPadding + + extraSpaceForDropShadow; } else if (type.get === ViewTypes.UNIQUE_TOKEN_ROW_CLOSED) { dim.height = TokenFamilyHeaderHeight + firstRowExtraTopPadding; } else if (type === ViewTypes.COIN_ROW_LAST) { - dim.height = areSmallCollectibles ? CoinRow.height : CoinRow.height + ListFooter.height + 1; + dim.height = areSmallCollectibles + ? CoinRow.height + : CoinRow.height + ListFooter.height + 1; } else if (type === ViewTypes.COIN_SMALL_BALANCES) { - const balancesIndex = findIndex(sections, ({ name }) => name === 'balances'); - const size = sections[balancesIndex].data[sections[balancesIndex].data.length - 1].assets.length; + const balancesIndex = findIndex( + sections, + ({ name }) => name === 'balances' + ); + const size = + sections[balancesIndex].data[ + sections[balancesIndex].data.length - 1 + ].assets.length; dim.height = openSmallBalances - ? CoinDivider.height + (size * CoinRow.height) + ListFooter.height + 9 + ? CoinDivider.height + size * CoinRow.height + ListFooter.height + 9 : CoinDivider.height + ListFooter.height + 16; } else if (type === ViewTypes.COIN_ROW) { dim.height = CoinRow.height; } else if (type === ViewTypes.UNISWAP_ROW_LAST) { - dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical + ListFooter.height + 8; + dim.height = + UniswapInvestmentCard.height + + InvestmentCard.margin.vertical + + ListFooter.height + + 8; } else if (type === ViewTypes.UNISWAP_ROW) { - dim.height = UniswapInvestmentCard.height + InvestmentCard.margin.vertical; + dim.height = + UniswapInvestmentCard.height + InvestmentCard.margin.vertical; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED_LAST) { - dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical + ListFooter.height + 8; + dim.height = + InvestmentCardHeader.height + + InvestmentCard.margin.vertical + + ListFooter.height + + 8; } else if (type === ViewTypes.UNISWAP_ROW_CLOSED) { - dim.height = InvestmentCardHeader.height + InvestmentCard.margin.vertical; + dim.height = + InvestmentCardHeader.height + InvestmentCard.margin.vertical; } else if (type === ViewTypes.HEADER) { dim.height = hideHeader ? 0 : AssetListHeader.height; } else if (type === ViewTypes.FOOTER) { dim.height = 0; } - }, + } ); } @@ -294,14 +357,23 @@ class RecyclerAssetList extends Component { const items = sections.reduce((ctx, section) => { headersIndices.push(ctx.length); return ctx - .concat([{ - isHeader: true, - ...section.header, - }]) - .concat(section.data.map(item => ({ item: { ...item, ...section.perData }, renderItem: section.renderItem }))); + .concat([ + { + isHeader: true, + ...section.header, + }, + ]) + .concat( + section.data.map(item => ({ + item: { ...item, ...section.perData }, + renderItem: section.renderItem, + })) + ); }, []); items.push({ item: { isLastPlaceholder: true }, renderItem: () => NOOP }); - const areSmallCollectibles = (c => c && get(c, 'type') === 'small')(sections.find(e => e.collectibles)); + const areSmallCollectibles = (c => c && get(c, 'type') === 'small')( + sections.find(e => e.collectibles) + ); return { areSmallCollectibles, dataProvider: state.dataProvider.cloneWithRows(items), @@ -327,7 +399,7 @@ class RecyclerAssetList extends Component { let collectibles = {}; let investments = {}; - sections.forEach((section) => { + sections.forEach(section => { if (section.balances) { balances = section; } else if (section.collectibles) { @@ -341,7 +413,10 @@ class RecyclerAssetList extends Component { clearInterval(this.interval); } - if (scrollingVelocity && scrollingVelocity !== prevProps.scrollingVelocity) { + if ( + scrollingVelocity && + scrollingVelocity !== prevProps.scrollingVelocity + ) { clearInterval(this.interval); this.interval = setInterval(() => { this.rlv.scrollToOffset(0, this.position + scrollingVelocity * 10); @@ -355,7 +430,11 @@ class RecyclerAssetList extends Component { let collectiblesHeight = 0; for (let j = 0; j < i; j++) { if (openFamilyTabs[j] && collectibles.data[j].tokens) { - collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; + collectiblesHeight += + TokenFamilyHeader.height + + collectibles.data[j].tokens.length * UniqueTokenRow.height + + TokenFamilyWrapPaddingTop - + 2; } else { collectiblesHeight += TokenFamilyHeader.height; } @@ -364,33 +443,50 @@ class RecyclerAssetList extends Component { if (investments.data) { for (let k = 0; k < investments.data.length; k++) { if (!openInvestmentCards[investments.data[k].uniqueId]) { - investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + investmentHeight += + UniswapInvestmentCard.height + InvestmentCard.margin.vertical; } else { - investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + investmentHeight += + InvestmentCardHeader.height + InvestmentCard.margin.vertical; } } } let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); - if (balances.data[balances.data.length - 1].smallBalancesContainer) { + if ( + balances.data[balances.data.length - 1].smallBalancesContainer + ) { balancesHeight += CoinDivider.height + ListFooter.height + 9; if (openSmallBalances) { - balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; + balancesHeight += + CoinRow.height * + balances.data[balances.data.length - 1].assets.length; } } else { balancesHeight += CoinDivider.height + ListFooter.height + 16; } } const verticalOffset = 10; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 210 : 235); - const sectionBeforeCollectibles = AssetListHeader.height * (sections.length - 1) + ListFooter.height * (sections.length - 1) + balancesHeight + investmentHeight; + const deviceDimensions = + deviceUtils.dimensions.height - + (deviceUtils.isSmallPhone ? 210 : 235); + const sectionBeforeCollectibles = + AssetListHeader.height * (sections.length - 1) + + ListFooter.height * (sections.length - 1) + + balancesHeight + + investmentHeight; const sectionsHeight = sectionBeforeCollectibles + collectiblesHeight; - const renderSize = collectibles.data[i].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop; + const renderSize = + collectibles.data[i].tokens.length * UniqueTokenRow.height + + TokenFamilyWrapPaddingTop; if (renderSize >= deviceDimensions) { const scrollDistance = sectionsHeight - this.position; - this.scrollToOffset(this.position + scrollDistance - verticalOffset, true); + this.scrollToOffset( + this.position + scrollDistance - verticalOffset, + true + ); } else { const diff = this.position - sectionsHeight + deviceDimensions; if (renderSize > diff) { @@ -407,7 +503,10 @@ class RecyclerAssetList extends Component { let shouldAutoscrollBack = false; if (collectibles.data) { for (let i = 0; i < collectibles.data.length; i++) { - if (openFamilyTabs[i] === false && prevProps.openFamilyTabs[i] === true) { + if ( + openFamilyTabs[i] === false && + prevProps.openFamilyTabs[i] === true + ) { shouldAutoscrollBack = true; break; } @@ -416,22 +515,29 @@ class RecyclerAssetList extends Component { if (investments.data && !shouldAutoscrollBack) { for (let i = 0; i < investments.data.length; i++) { - if (openInvestmentCards[investments.data[i].uniqueId] === true && prevProps.openInvestmentCards[investments.data[i].uniqueId] === false) { + if ( + openInvestmentCards[investments.data[i].uniqueId] === true && + prevProps.openInvestmentCards[investments.data[i].uniqueId] === false + ) { shouldAutoscrollBack = true; break; } } } - if (shouldAutoscrollBack - || (openSmallBalances === false && prevProps.openSmallBalances === true)) { + if ( + shouldAutoscrollBack || + (openSmallBalances === false && prevProps.openSmallBalances === true) + ) { let balancesHeight = 0; if (balances.data) { balancesHeight += CoinRow.height * (balances.data.length - 1); if (balances.data[balances.data.length - 1].smallBalancesContainer) { balancesHeight += CoinDivider.height + ListFooter.height; if (openSmallBalances) { - balancesHeight += CoinRow.height * balances.data[balances.data.length - 1].assets.length; + balancesHeight += + CoinRow.height * + balances.data[balances.data.length - 1].assets.length; } } else { balancesHeight += CoinRow.height + ListFooter.height; @@ -442,31 +548,52 @@ class RecyclerAssetList extends Component { if (investments.data) { for (let k = 0; k < investments.data.length; k++) { if (!openInvestmentCards[investments.data[k].uniqueId]) { - investmentHeight += (UniswapInvestmentCard.height + InvestmentCard.margin.vertical); + investmentHeight += + UniswapInvestmentCard.height + InvestmentCard.margin.vertical; } else { - investmentHeight += (InvestmentCardHeader.height + InvestmentCard.margin.vertical); + investmentHeight += + InvestmentCardHeader.height + InvestmentCard.margin.vertical; } } } let collectiblesHeight = 0; if (balances.data) { - collectiblesHeight = collectibles.data.length > 0 ? AssetListHeader.height : 0; + collectiblesHeight = + collectibles.data.length > 0 ? AssetListHeader.height : 0; for (let j = 0; j < collectibles.data.length; j++) { if (openFamilyTabs[j] && collectibles.data[j].tokens) { - collectiblesHeight += TokenFamilyHeader.height + collectibles.data[j].tokens.length * UniqueTokenRow.height + TokenFamilyWrapPaddingTop - 2; + collectiblesHeight += + TokenFamilyHeader.height + + collectibles.data[j].tokens.length * UniqueTokenRow.height + + TokenFamilyWrapPaddingTop - + 2; } else { collectiblesHeight += TokenFamilyHeader.height; } } } - const renderSize = balancesHeight + investmentHeight + collectiblesHeight + ListFooter.height; - const deviceDimensions = deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); - if (this.position + deviceDimensions > renderSize && renderSize > deviceDimensions) { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(310, 'easeInEaseOut', 'opacity')); + const renderSize = + balancesHeight + + investmentHeight + + collectiblesHeight + + ListFooter.height; + const deviceDimensions = + deviceUtils.dimensions.height - (deviceUtils.isSmallPhone ? 240 : 360); + if ( + this.position + deviceDimensions > renderSize && + renderSize > deviceDimensions + ) { + layoutItemAnimator.animateShift = () => + LayoutAnimation.configureNext( + LayoutAnimation.create(310, 'easeInEaseOut', 'opacity') + ); this.scrollToOffset(renderSize - deviceDimensions, true); setTimeout(() => { - layoutItemAnimator.animateShift = () => LayoutAnimation.configureNext(LayoutAnimation.create(200, 'easeInEaseOut', 'opacity')); + layoutItemAnimator.animateShift = () => + LayoutAnimation.configureNext( + LayoutAnimation.create(200, 'easeInEaseOut', 'opacity') + ); }, 300); } } @@ -477,13 +604,21 @@ class RecyclerAssetList extends Component { clearInterval(this.interval); }; + rlv = React.createRef(); + + contentSize = 0; + + layoutMeasurement = 0; + + position = 0; + scrollToOffset = (position, animated) => { setTimeout(() => { this.rlv.scrollToOffset(0, position, animated); }, 5); - } + }; - getStableId = (index) => { + getStableId = index => { const { dataProvider } = this.state; const row = get(dataProvider, `_data[${index}]`); @@ -514,21 +649,26 @@ class RecyclerAssetList extends Component { return index; }; - handleListRef = (ref) => { this.rlv = ref; } + handleListRef = ref => { + this.rlv = ref; + }; handleRefresh = () => { if (this.state.isRefreshing) return; this.setState({ isRefreshing: true }, () => { - this.props.fetchData().then(() => { - if (!this.isCancelled) { - this.setState({ isRefreshing: false }); - } - }).catch(error => { - if (!this.isCancelled) { - this.setState({ isRefreshing: false }); - } - }); + this.props + .fetchData() + .then(() => { + if (!this.isCancelled) { + this.setState({ isRefreshing: false }); + } + }) + .catch(() => { + if (!this.isCancelled) { + this.setState({ isRefreshing: false }); + } + }); }); }; @@ -545,8 +685,11 @@ class RecyclerAssetList extends Component { this.layoutMeasurement = layoutMeasurement.height; } - if ((contentSize.height - layoutMeasurement.height >= offsetY && offsetY >= 0) - || (offsetY < reloadHeightOffsetTop && offsetY > reloadHeightOffsetBottom)) { + if ( + (contentSize.height - layoutMeasurement.height >= offsetY && + offsetY >= 0) || + (offsetY < reloadHeightOffsetTop && offsetY > reloadHeightOffsetBottom) + ) { if (this.props.scrollViewTracker) { this.props.scrollViewTracker.setValue(offsetY); } @@ -576,40 +719,42 @@ class RecyclerAssetList extends Component { if (type === ViewTypes.COIN_SMALL_BALANCES) { const renderList = []; for (let i = 0; i < item.assets.length; i++) { - renderList.push(renderItem({ - item: { - ...item.assets[i], - isSmall: true, - }, - })); + renderList.push( + renderItem({ + item: { + ...item.assets[i], + isSmall: true, + }, + }) + ); } return ; } - const isNotUniqueToken = ( - type === ViewTypes.COIN_ROW - || type === ViewTypes.COIN_ROW_LAST - || type === ViewTypes.UNISWAP_ROW - || type === ViewTypes.UNISWAP_ROW_LAST - || type === ViewTypes.UNISWAP_ROW_CLOSED - || type === ViewTypes.UNISWAP_ROW_CLOSED_LAST - || type === ViewTypes.FOOTER - ); + const isNotUniqueToken = + type === ViewTypes.COIN_ROW || + type === ViewTypes.COIN_ROW_LAST || + type === ViewTypes.UNISWAP_ROW || + type === ViewTypes.UNISWAP_ROW_LAST || + type === ViewTypes.UNISWAP_ROW_CLOSED || + type === ViewTypes.UNISWAP_ROW_CLOSED_LAST || + type === ViewTypes.FOOTER; // TODO sections return isNotUniqueToken ? renderItem({ item }) : renderItem({ - childrenAmount: item.childrenAmount, - familyId: item.familyId, - familyImage: item.familyImage, - familyName: item.familyName, - item: item.tokens, - marginTop: type.isFirst ? 4 : 0, - shouldPrioritizeImageLoading: index < get(sections, '[0].data.length', 0) + 9, - uniqueId: item.uniqueId, - }); + childrenAmount: item.childrenAmount, + familyId: item.familyId, + familyImage: item.familyImage, + familyName: item.familyName, + item: item.tokens, + marginTop: type.isFirst ? 4 : 0, + shouldPrioritizeImageLoading: + index < get(sections, '[0].data.length', 0) + 9, + uniqueId: item.uniqueId, + }); }; render() { @@ -657,5 +802,5 @@ export default compose( withFabSelection, withOpenFamilyTabs, withOpenInvestmentCards, - withOpenBalances, + withOpenBalances )(RecyclerAssetList); diff --git a/src/components/badge/Badge.js b/src/components/badge/Badge.js index e83b9048fcc..b04210c68e3 100644 --- a/src/components/badge/Badge.js +++ b/src/components/badge/Badge.js @@ -2,19 +2,9 @@ import PropTypes from 'prop-types'; import React from 'react'; import { View } from 'react-primitives'; import { animated, interpolate, Transition } from 'react-spring/dist/native'; -import { - compose, - defaultProps, - onlyUpdateForKeys, - withProps, -} from 'recompact'; +import { compose, defaultProps, onlyUpdateForKeys, withProps } from 'recompact'; import styled, { css } from 'styled-components/primitives'; -import { - animations, - borders, - colors, - padding, -} from '../../styles'; +import { animations, borders, colors, padding } from '../../styles'; import { Centered } from '../layout'; import { Text } from '../text'; @@ -23,13 +13,13 @@ const AnimatedView = animated(View); const Container = styled(Centered)` height: ${({ size }) => size}; position: absolute; - right: ${({ offset }) => (offset * -1)}; - top: ${({ offset }) => (offset * -1)}; + right: ${({ offset }) => offset * -1}; + top: ${({ offset }) => offset * -1}; `; const MultiDigitValue = css` ${padding(2, 5.5, 3)} - transform: translateX(${({ offset }) => (Math.floor(offset / 2))}px); + transform: translateX(${({ offset }) => Math.floor(offset / 2)}px); `; const SingleDigitValue = css` @@ -38,11 +28,8 @@ const SingleDigitValue = css` `; const Circle = styled(Centered)` - ${({ valueLength }) => ( - (valueLength === 1) - ? SingleDigitValue - : MultiDigitValue - )} + ${({ valueLength }) => + valueLength === 1 ? SingleDigitValue : MultiDigitValue} background-color: ${colors.primaryBlue}; border-radius: 15; `; @@ -96,6 +83,6 @@ export default compose( onlyUpdateForKeys(['value']), withProps(({ value }) => ({ valueLength: value.toString().length })), withProps(({ maxLength, value, valueLength }) => ({ - value: (valueLength > maxLength) ? `${'9'.repeat(maxLength)}+` : value, - })), + value: valueLength > maxLength ? `${'9'.repeat(maxLength)}+` : value, + })) )(Badge); diff --git a/src/components/bubble-sheet/BubbleSheet.js b/src/components/bubble-sheet/BubbleSheet.js index 4b66cbe0c7a..22e4ece86f0 100644 --- a/src/components/bubble-sheet/BubbleSheet.js +++ b/src/components/bubble-sheet/BubbleSheet.js @@ -4,7 +4,7 @@ import { Column } from '../layout'; const BubbleSheetBorderRadius = 30; -const BubbleSheet = (props) => ( +const BubbleSheet = props => ( - - + + - - + + ); const enhanceButton = compose( setPropTypes({ onPress: PropTypes.func.isRequired }), - withNeverRerender, + withNeverRerender ); const AddButton = enhanceButton(({ onPress }) => ( diff --git a/src/components/buttons/Button.js b/src/components/buttons/Button.js index eefa7030c20..1464bb33587 100644 --- a/src/components/buttons/Button.js +++ b/src/components/buttons/Button.js @@ -35,15 +35,12 @@ const Container = styled(Centered)` ${({ showShadow }) => (showShadow ? shadowStyles : '')} ${({ size }) => padding(...ButtonSizeTypes[size].padding)} background-color: ${({ backgroundColor }) => backgroundColor}; - border-radius: ${({ type }) => ((type === 'rounded') ? 14 : 50)}; + border-radius: ${({ type }) => (type === 'rounded' ? 14 : 50)}; flex-grow: 0; `; -const shouldRenderChildrenAsText = (children) => ( - isArray(children) - ? isString(children[0]) - : isString(children) -); +const shouldRenderChildrenAsText = children => + isArray(children) ? isString(children[0]) : isString(children); const Button = ({ backgroundColor, @@ -77,24 +74,23 @@ const Button = ({ style={style} type={type} > - {!shouldRenderChildrenAsText(children) - ? children - : ( - - {children} - - ) - } + {!shouldRenderChildrenAsText(children) ? ( + children + ) : ( + + {children} + + )} {(!onPress || !disabled) && ( )} diff --git a/src/components/buttons/CoolButton.js b/src/components/buttons/CoolButton.js index b43d421fa77..55673071dea 100644 --- a/src/components/buttons/CoolButton.js +++ b/src/components/buttons/CoolButton.js @@ -2,12 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { compose, onlyUpdateForKeys, withProps } from 'recompact'; import { withNeverRerender } from '../../hoc'; -import { - colors, - margin, - padding, - position, -} from '../../styles'; +import { colors, margin, padding, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import { Icon } from '../icons'; import InnerBorder from '../InnerBorder'; @@ -22,7 +17,7 @@ const CoolCaretIcon = compose( flex: 0, name: 'caret', size: 7.5, - }), + }) )(Icon); const CoolLabel = withProps({ @@ -34,34 +29,30 @@ const CoolLabel = withProps({ const enhance = onlyUpdateForKeys(['children', 'color']); -const CoolButton = enhance(({ - borderRadius, - children, - color, - onPress, - shadows, -}) => ( - - - - - {children} - - - - - -)); +const CoolButton = enhance( + ({ borderRadius, children, color, onPress, shadows }) => ( + + + + + {children} + + + + + + ) +); CoolButton.propTypes = { borderRadius: PropTypes.number, diff --git a/src/components/buttons/HoldToAuthorizeButton.js b/src/components/buttons/HoldToAuthorizeButton.js index 3f7de7e4831..0aeb3dc7196 100644 --- a/src/components/buttons/HoldToAuthorizeButton.js +++ b/src/components/buttons/HoldToAuthorizeButton.js @@ -1,6 +1,10 @@ import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; -import { LongPressGestureHandler, State, TapGestureHandler } from 'react-native-gesture-handler'; +import { + LongPressGestureHandler, + State, + TapGestureHandler, +} from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { withProps } from 'recompact'; @@ -38,10 +42,7 @@ const ButtonShadows = { [0, 6, 10, colors.dark, 0.14], [0, 1, 18, colors.dark, 0.12], ], - disabled: [ - [0, 2, 6, colors.dark, 0.06], - [0, 3, 9, colors.dark, 0.08], - ], + disabled: [[0, 2, 6, colors.dark, 0.06], [0, 3, 9, colors.dark, 0.08]], }; const progressDurationMs = 500; // @christian approves @@ -71,11 +72,7 @@ const Title = withProps({ })(Text); const buildAnimation = (value, options) => { - const { - duration = 150, - isInteraction = false, - toValue, - } = options; + const { duration = 150, isInteraction = false, toValue } = options; return timing(value, { duration, @@ -86,9 +83,10 @@ const buildAnimation = (value, options) => { }); }; -const calculateReverseDuration = progess => multiply(divide(progess, 100), progressDurationMs); +const calculateReverseDuration = progess => + multiply(divide(progess, 100), progressDurationMs); -const HoldToAuthorizeButtonIcon = ({ animatedValue, isAuthorizing }) => { +const HoldToAuthorizeButtonIcon = ({ animatedValue }) => { const isSpinnerVisible = greaterThan(animatedValue, 0); const spinnerIn = sub(22, animatedValue); const spinnerOut = divide(1, animatedValue); @@ -112,7 +110,6 @@ const HoldToAuthorizeButtonIcon = ({ animatedValue, isAuthorizing }) => { HoldToAuthorizeButtonIcon.propTypes = { animatedValue: PropTypes.object, - isAuthorizing: PropTypes.bool, }; export default class HoldToAuthorizeButton extends PureComponent { @@ -129,31 +126,30 @@ export default class HoldToAuthorizeButton extends PureComponent { shadows: PropTypes.arrayOf(PropTypes.array), style: PropTypes.object, theme: PropTypes.oneOf(['light', 'dark']), - } + }; static defaultProps = { backgroundColor: colors.appleBlue, disabled: false, theme: 'light', - } + }; state = { isAuthorizing: false, - } - - animation = new Value(0) - - progress = new Value(0) - - scale = new Value(1) - - tapHandlerState = 1 + }; componentDidUpdate = () => { if (this.state.isAuthorizing && !this.props.isAuthorizing) { + // eslint-disable-next-line react/no-did-update-set-state this.setState({ isAuthorizing: false }); } - } + }; + + scale = new Value(1); + + tapHandlerState = 1; + + animation = new Value(0); onTapChange = ({ nativeEvent: { state } }) => { const { disabled, onPress } = this.props; @@ -185,7 +181,7 @@ export default class HoldToAuthorizeButton extends PureComponent { toValue: 0, }).start(); } - } + }; onLongPressChange = ({ nativeEvent }) => { const { disabled, onLongPress } = this.props; @@ -202,15 +198,10 @@ export default class HoldToAuthorizeButton extends PureComponent { onLongPress(); } } - } + }; renderContent = () => { - const { - children, - disabled, - hideBiometricIcon, - label, - } = this.props; + const { children, disabled, hideBiometricIcon, label } = this.props; const { isAuthorizing } = this.state; @@ -220,18 +211,16 @@ export default class HoldToAuthorizeButton extends PureComponent { return ( - {(!disabled && !hideBiometricIcon) && ( + {!disabled && !hideBiometricIcon && ( )} - - {isAuthorizing ? 'Authorizing' : label} - + {isAuthorizing ? 'Authorizing' : label} ); - } + }; render() { const { @@ -255,12 +244,17 @@ export default class HoldToAuthorizeButton extends PureComponent { minDurationMs={progressDurationMs} onHandlerStateChange={this.onLongPressChange} > - + diff --git a/src/components/buttons/PasteAddressButton.js b/src/components/buttons/PasteAddressButton.js index e6f82968234..53ca9640951 100644 --- a/src/components/buttons/PasteAddressButton.js +++ b/src/components/buttons/PasteAddressButton.js @@ -10,40 +10,46 @@ class PasteAddressButton extends PureComponent { static propTypes = { appState: PropTypes.string, onPress: PropTypes.func.isRequired, - } + }; - state = { clipboardContents: null } + state = { clipboardContents: null }; componentDidMount() { this.getClipboardContents(); } componentDidUpdate(prevProps) { - if (prevProps.appState === 'background' && this.props.appState === 'active') { + if ( + prevProps.appState === 'background' && + this.props.appState === 'active' + ) { this.getClipboardContents(); } } - getClipboardContents = async () => Clipboard.getString().then(this.setClipboardContents) + getClipboardContents = async () => + Clipboard.getString().then(this.setClipboardContents); handlePress = () => { if (this.state.clipboardContents) { this.props.onPress(this.state.clipboardContents); } - } + }; - setClipboardContents = async (clipboardContents) => { + setClipboardContents = async clipboardContents => { if (await isValidAddress(clipboardContents)) { this.setState({ clipboardContents }); } - } + }; render() { const { clipboardContents } = this.state; return (

`D^wi>e1M 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᎗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℞t1?VA@TQ(NN-%X92`xeXjyW_6wi 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�ctbI-WDVN%ZdJ%HvtZg z{`c<*9HM{6Ej%{m0L{AMwH6fl@%~bQd3_1TbNpHlH`L{N}xhl&W};frO4}MR{G+0Zv+kh2*L3 zsC2eGd_dfN>7=lhfApnZ7aA z(O8^>yfSmmz#)wap zWYA*|+DHhsCXqZh7?rMB^8PaQ7qw`^#EY5EftZ}T>C=G%WU~d6 zvZ4st&<+w^thZGl?!h(v+rHZlzq`X!z)?p67S03MGWEahGzxr-VF24+(0{>EzDIh& z4v!!318Ofbrpw<}L&sCyLoFe=wlid*2cf6>ECv++H@X)tK z8Fp+0Xkuhi$uCtXo#<6M79$v<_z0<$)Jd6EAT=DqT=7oPSFJ=N5Y>L!>14_WP*+KY zq+V<0;mx#ap1^%>WrL9Ngkj0>QE6G@n}}JFJc}Tz9k;TS!-lTaX@)-!3^faQR44Lnv?qGV@}DOEs75>lvua7I1yZ-TQr+yCt{g2HAmQ#YKg8s4h3obt^SVj-d-n{$#&wcIe zjXSpGWU!!88@l~;4xy&6UpN+QBRk85_Mm&C{Nr+fxet93F1Gbk8|V<%Blxw~>1D1# zt4E$Y!JmBnM<1I4xeay9!-{1%0y#OR40}uU!_LhUDUe2d4J|oqG7YTK*#WaqmWh<` ziFVlQcWKJ8WhpTg)>a}1B&Rn-p|L`3zxgwaW18|O<03WMX=$(2 zdS|?cxq*Mug(MkqVE0vPA`PSZ*m863d?No&L8|n8QZ$u|Y14)Q*Qx1Wel)XB5Oo4L z3{sQQL!xNa+?*N*=8#a!uuhJ2H#F}h_LOT?i}nUq6zSu#OG~2~87@+nC?WOR&I~s! z;Jpyff;z?W37wpQvD_GiW2RXg=3$i+rGt^}2O+@8&X?(WA9!;rqNCF}G)Y$*X=Wk` zL~T7ym{nMR$X3YG(}#)ruXa?NXh}_8)>nckGOUp$gv^djpy>S2b}mD*<~V+=JFwDs zN?!!7Hk4*fBJEC6%T}gC$ZDeHRhLj2g0sq@<9UEyOgCUpVsJV80GBfjz;>bpPX+y7 ze2xF&S%EFx8@T>BGx+-FzcmU9Sl|w{)FE_`5}@^C8+eH>u?Cv82i+zj;3;r`bwJ;^ z!&7Ekd<#YG%gX$gh~KO+=wnl$f8({EJdsgxzd`x{pNRtt+WidL3ujWEnJB)+wwrp{ zgvFd@stM*Ao>rAj8xVmzS)3=eH?R4+I_;-{P|THT3oAbq)YagU&jm0K5kqM31mDnU zp#+mKbnAwZUwN{0*NS7

- )} + } isEmpty={isEmpty} nativeCurrency={nativeCurrency} requests={requests} @@ -47,10 +44,7 @@ const ProfileScreen = ({ transactionsCount={transactionsCount} /> {isEmpty && } - +
); diff --git a/src/screens/ProfileScreenWithData.js b/src/screens/ProfileScreenWithData.js index b97227c9f71..f740720ff6d 100644 --- a/src/screens/ProfileScreenWithData.js +++ b/src/screens/ProfileScreenWithData.js @@ -1,8 +1,4 @@ -import { - compose, - withHandlers, - withProps, -} from 'recompact'; +import { compose, withHandlers, withProps } from 'recompact'; import { setDisplayName } from 'recompose'; import { withAccountAddress, @@ -23,10 +19,12 @@ export default compose( withIsWalletEmpty, withRequests, withHandlers({ - onPressBackButton: ({ navigation }) => () => navigation.navigate('WalletScreen'), - onPressSettings: ({ navigation }) => () => navigation.navigate('SettingsModal'), + onPressBackButton: ({ navigation }) => () => + navigation.navigate('WalletScreen'), + onPressSettings: ({ navigation }) => () => + navigation.navigate('SettingsModal'), }), withProps(({ isWalletEmpty, transactionsCount }) => ({ isEmpty: isWalletEmpty && !transactionsCount, - })), + })) )(ProfileScreen); diff --git a/src/screens/QRScannerScreen.js b/src/screens/QRScannerScreen.js index 5c38986a09d..0661191906f 100644 --- a/src/screens/QRScannerScreen.js +++ b/src/screens/QRScannerScreen.js @@ -8,7 +8,10 @@ import { Button } from '../components/buttons'; import { BackButton, Header } from '../components/header'; import { Centered } from '../components/layout'; import { QRCodeScanner } from '../components/qrcode-scanner'; -import { WalletConnectExplainer, WalletConnectList } from '../components/walletconnect-list'; +import { + WalletConnectExplainer, + WalletConnectList, +} from '../components/walletconnect-list'; import { colors, position } from '../styles'; import { safeAreaInsetValues } from '../utils'; @@ -75,10 +78,11 @@ const QRScannerScreen = ({ bottom={safeAreaInsetValues.bottom ? 21 : 0} onLayout={onSheetLayout} > - {walletConnectorsCount - ? - : - } + {walletConnectorsCount ? ( + + ) : ( + + )} ); diff --git a/src/screens/QRScannerScreenWithData.js b/src/screens/QRScannerScreenWithData.js index d3ee2a9c933..03802d9301e 100644 --- a/src/screens/QRScannerScreenWithData.js +++ b/src/screens/QRScannerScreenWithData.js @@ -31,7 +31,7 @@ class QRScannerScreenWithData extends Component { enableScanning: true, isCameraAuthorized: true, sheetHeight: 240, - } + }; componentDidUpdate = (prevProps, prevState) => { if (this.props.isFocused && !prevProps.isFocused) { @@ -43,17 +43,18 @@ class QRScannerScreenWithData extends Component { } }); + // eslint-disable-next-line react/no-did-update-set-state this.setState({ enableScanning: true }); } - } + }; handleSheetLayout = ({ nativeEvent }) => { this.setState({ sheetHeight: get(nativeEvent, 'layout.height') }); - } + }; - handlePastedUri = async (uri) => this.props.walletConnectOnSessionRequest(uri) + handlePastedUri = async uri => this.props.walletConnectOnSessionRequest(uri); - handlePressBackButton = () => this.props.navigation.navigate('WalletScreen') + handlePressBackButton = () => this.props.navigation.navigate('WalletScreen'); handlePressPasteSessionUri = () => { Prompt({ @@ -62,9 +63,9 @@ class QRScannerScreenWithData extends Component { title: 'New WalletConnect Session', type: 'plain-text', }); - } + }; - handleReenableScanning = () => this.setState({ enableScanning: true }) + handleReenableScanning = () => this.setState({ enableScanning: true }); handleScanSuccess = async ({ data }) => { const { @@ -92,28 +93,27 @@ class QRScannerScreenWithData extends Component { return setSafeTimeout(this.handleReenableScanning, 2000); } - analytics.track('Scanned broken or unsupported QR code', { qrCodeData: data }); + analytics.track('Scanned broken or unsupported QR code', { + qrCodeData: data, + }); return Alert({ callback: this.handleReenableScanning, message: lang.t('wallet.unrecognized_qrcode'), title: lang.t('wallet.unrecognized_qrcode_title'), }); - } + }; render = () => ( - ) + ); } export default compose( @@ -122,5 +122,5 @@ export default compose( withAccountAddress, withSafeTimeout, withWalletConnectConnections, - withStatusBarStyle('light-content'), + withStatusBarStyle('light-content') )(QRScannerScreenWithData); diff --git a/src/screens/ReceiveModal.js b/src/screens/ReceiveModal.js index d8e71295e8d..b79668df467 100644 --- a/src/screens/ReceiveModal.js +++ b/src/screens/ReceiveModal.js @@ -2,12 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { Clipboard, Share } from 'react-native'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import { - compose, - onlyUpdateForKeys, - withHandlers, - withState, -} from 'recompact'; +import { compose, onlyUpdateForKeys, withHandlers, withState } from 'recompact'; import styled from 'styled-components/primitives'; import Divider from '../components/Divider'; import { Column } from '../components/layout'; @@ -19,11 +14,7 @@ import { } from '../components/modal'; import QRCodeDisplay from '../components/QRCodeDisplay'; import { FloatingEmojis } from '../components/floating-emojis'; -import { - Br, - Monospace, - Text, -} from '../components/text'; +import { Br, Monospace, Text } from '../components/text'; import { withAccountAddress } from '../hoc'; import { colors, padding } from '../styles'; @@ -65,20 +56,15 @@ const ReceiveScreen = ({ onPressShareAddress, }) => ( - + - Send Ether, ERC-20 tokens, or
+ Send Ether, ERC-20 tokens, or +
collectibles to your wallet:
- + {accountAddress.substring(0, accountAddress.length / 2)} @@ -114,7 +100,6 @@ const ReceiveScreen = ({ ReceiveScreen.propTypes = { accountAddress: PropTypes.string.isRequired, emojiCount: PropTypes.number, - navigation: PropTypes.object.isRequired, onCloseModal: PropTypes.func.isRequired, onPressCopyAddress: PropTypes.func, onPressShareAddress: PropTypes.func, @@ -125,17 +110,20 @@ export default compose( withState('emojiCount', 'setEmojiCount', 0), withHandlers({ onCloseModal: ({ navigation }) => () => navigation.goBack(), - onPressCopyAddress: ({ accountAddress, emojiCount, setEmojiCount }) => () => { + onPressCopyAddress: ({ + accountAddress, + emojiCount, + setEmojiCount, + }) => () => { ReactNativeHapticFeedback.trigger('impactLight'); setEmojiCount(emojiCount + 1); Clipboard.setString(accountAddress); }, - onPressShareAddress: ({ accountAddress }) => () => ( + onPressShareAddress: ({ accountAddress }) => () => Share.share({ message: accountAddress, title: 'My account address:', - }) - ), + }), }), - onlyUpdateForKeys(['accountAddress', 'emojiCount']), + onlyUpdateForKeys(['accountAddress', 'emojiCount']) )(ReceiveScreen); diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 881496d3b91..c9e6963036c 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -1,9 +1,7 @@ import analytics from '@segment/analytics-react-native'; import { get } from 'lodash'; import React from 'react'; -import { - createAppContainer, -} from 'react-navigation'; +import { createAppContainer } from 'react-navigation'; import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; import { createStackNavigator } from 'react-navigation-stack'; import { ExchangeModalNavigator, Navigation } from '../navigation'; @@ -26,162 +24,201 @@ import { expandedPreset, sheetPreset, backgroundPreset, - onTransitionStart as onTransitionStartEffect, } from '../navigation/transitions/effects'; import restoreKeyboard from './restoreKeyboard'; -const onTransitionEnd = () => store.dispatch(updateStackTransitionProps({ isTransitioning: false })); -const onTransitionStart = () => store.dispatch(updateStackTransitionProps({ isTransitioning: true })); +const onTransitionEnd = () => + store.dispatch(updateStackTransitionProps({ isTransitioning: false })); +const onTransitionStart = () => + store.dispatch(updateStackTransitionProps({ isTransitioning: true })); -const SwipeStack = createMaterialTopTabNavigator({ - ProfileScreen: { - name: 'ProfileScreen', - screen: ProfileScreenWithData, - }, - WalletScreen: { - name: 'WalletScreen', - screen: WalletScreen, - }, - // eslint-disable-next-line sort-keys - QRScannerScreen: { - name: 'QRScannerScreen', - screen: QRScannerScreenWithData, - }, -}, { - headerMode: 'none', - initialLayout: deviceUtils.dimensions, - initialRouteName: 'WalletScreen', - mode: 'modal', - springConfig: { - damping: 16, - mass: 0.3, - overshootClamping: false, - restDisplacementThreshold: 1, - restSpeedThreshold: 1, - stiffness: 140, +const SwipeStack = createMaterialTopTabNavigator( + { + ProfileScreen: { + name: 'ProfileScreen', + screen: ProfileScreenWithData, + }, + WalletScreen: { + name: 'WalletScreen', + screen: WalletScreen, + }, + // eslint-disable-next-line sort-keys + QRScannerScreen: { + name: 'QRScannerScreen', + screen: QRScannerScreenWithData, + }, }, - swipeDistanceThreshold: 30, - swipeVelocityThreshold: 10, - tabBarComponent: null, -}); + { + headerMode: 'none', + initialLayout: deviceUtils.dimensions, + initialRouteName: 'WalletScreen', + mode: 'modal', + springConfig: { + damping: 16, + mass: 0.3, + overshootClamping: false, + restDisplacementThreshold: 1, + restSpeedThreshold: 1, + stiffness: 140, + }, + swipeDistanceThreshold: 30, + swipeVelocityThreshold: 10, + tabBarComponent: null, + } +); -const MainNavigator = createStackNavigator({ - ConfirmRequest: { - navigationOptions: { - ...expandedPreset, - onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, +const MainNavigator = createStackNavigator( + { + ConfirmRequest: { + navigationOptions: { + ...expandedPreset, + onTransitionStart: props => { + expandedPreset.onTransitionStart(props); + onTransitionStart(); + }, + }, + screen: TransactionConfirmationScreenWithData, }, - screen: TransactionConfirmationScreenWithData, - }, - ExampleScreen, - ExchangeModal: { - navigationOptions: { - ...expandedPreset, - gestureResponseDistance: { - vertical: deviceUtils.dimensions.height, + ExampleScreen, + ExchangeModal: { + navigationOptions: { + ...expandedPreset, + gestureResponseDistance: { + vertical: deviceUtils.dimensions.height, + }, + onTransitionStart: props => { + expandedPreset.onTransitionStart(props); + onTransitionStart(); + }, }, - onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, + params: { + isGestureBlocked: false, + }, + screen: ExchangeModalNavigator, }, - params: { - isGestureBlocked: false, + ExpandedAssetScreen: { + navigationOptions: { + ...expandedPreset, + onTransitionStart: props => { + expandedPreset.onTransitionStart(props); + onTransitionStart(); + }, + }, + screen: ExpandedAssetScreenWithData, }, - screen: ExchangeModalNavigator, - }, - ExpandedAssetScreen: { - navigationOptions: { - ...expandedPreset, - onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, + ImportSeedPhraseSheet: { + navigationOptions: { + ...sheetPreset, + onTransitionStart: props => { + sheetPreset.onTransitionStart(props); + onTransitionStart(); + }, + }, + screen: ImportSeedPhraseSheetWithData, }, - screen: ExpandedAssetScreenWithData, - }, - ImportSeedPhraseSheet: { - navigationOptions: { - ...sheetPreset, - onTransitionStart: props => { sheetPreset.onTransitionStart(props); onTransitionStart(); }, + ReceiveModal: { + navigationOptions: { + ...expandedPreset, + onTransitionStart: props => { + expandedPreset.onTransitionStart(props); + onTransitionStart(); + }, + }, + screen: ReceiveModal, }, - screen: ImportSeedPhraseSheetWithData, - }, - ReceiveModal: { - navigationOptions: { - ...expandedPreset, - onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, + SendSheet: { + navigationOptions: { + ...sheetPreset, + onTransitionStart: props => { + onTransitionStart(props); + sheetPreset.onTransitionStart(props); + restoreKeyboard(); + }, + }, + screen: SendSheetWithData, }, - screen: ReceiveModal, - }, - SendSheet: { - navigationOptions: { - ...sheetPreset, - onTransitionStart: props => { - onTransitionStart(props); - sheetPreset.onTransitionStart(props) - restoreKeyboard(); + SettingsModal: { + navigationOptions: { + gesturesEnabled: false, + ...expandedPreset, + onTransitionStart: props => { + expandedPreset.onTransitionStart(props); + onTransitionStart(); + }, }, + screen: SettingsModal, + transparentCard: true, }, - screen: SendSheetWithData, - }, - SettingsModal: { - navigationOptions: { - gesturesEnabled: false, - ...expandedPreset, - onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, + SwipeLayout: { + navigationOptions: { + ...backgroundPreset, + }, + screen: SwipeStack, }, - screen: SettingsModal, - transparentCard: true, - - }, - SwipeLayout: { - navigationOptions: { - ...backgroundPreset, + WalletConnectConfirmationModal: { + navigationOptions: { + ...expandedPreset, + onTransitionStart: props => { + expandedPreset.onTransitionStart(props); + onTransitionStart(); + }, + }, + screen: WalletConnectConfirmationModal, }, - screen: SwipeStack, }, - WalletConnectConfirmationModal: { - navigationOptions: { - ...expandedPreset, - onTransitionStart: props => { expandedPreset.onTransitionStart(props); onTransitionStart(); }, + { + defaultNavigationOptions: { + onTransitionEnd, + onTransitionStart, }, - screen: WalletConnectConfirmationModal, - }, -}, { - defaultNavigationOptions: { - onTransitionEnd, - onTransitionStart, - }, - disableKeyboardHandling: true, // XXX not sure about this from rebase - headerMode: 'none', - initialRouteName: 'SwipeLayout', - keyboardDismissMode: 'none', // true? - mode: 'modal', -}); + disableKeyboardHandling: true, // XXX not sure about this from rebase + headerMode: 'none', + initialRouteName: 'SwipeLayout', + keyboardDismissMode: 'none', // true? + mode: 'modal', + } +); const AppContainer = createAppContainer(MainNavigator); -// eslint-disable-next-line react/prop-types const AppContainerWithAnalytics = ({ ref, screenProps }) => ( { + onNavigationStateChange={(prevState, currentState) => { const { params, routeName } = Navigation.getActiveRoute(currentState); const prevRouteName = Navigation.getActiveRouteName(prevState); if (routeName === 'SettingsModal') { let subRoute = get(params, 'section.title'); if (subRoute === 'Settings') subRoute = null; - return analytics.screen(`${routeName}${subRoute ? `>${subRoute}` : ''}`); + return analytics.screen( + `${routeName}${subRoute ? `>${subRoute}` : ''}` + ); } if (routeName !== prevRouteName) { let paramsToTrack = null; - if (prevRouteName === 'MainExchangeScreen' && routeName === 'WalletScreen') { + if ( + prevRouteName === 'MainExchangeScreen' && + routeName === 'WalletScreen' + ) { store.dispatch(updateStackTransitionProps({ blurColor: null })); - } else if (prevRouteName === 'WalletScreen' && routeName === 'MainExchangeScreen') { - store.dispatch(updateStackTransitionProps({ blurColor: colors.alpha(colors.black, 0.9) })); + } else if ( + prevRouteName === 'WalletScreen' && + routeName === 'MainExchangeScreen' + ) { + store.dispatch( + updateStackTransitionProps({ + blurColor: colors.alpha(colors.black, 0.9), + }) + ); } if (routeName === 'ExpandedAssetScreen') { const { asset, type } = params; paramsToTrack = { - assetContractAddress: asset.address || get(asset, 'asset_contract.address'), + assetContractAddress: + asset.address || get(asset, 'asset_contract.address'), assetName: asset.name, assetSymbol: asset.symbol || get(asset, 'asset_contract.symbol'), assetType: type, diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 9808c930f6d..2733581e90c 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -55,7 +55,7 @@ const formatGasSpeedItem = (value, key) => { const labelOrder = ['slow', 'average', 'fast']; -const formatGasSpeedItems = (gasPrices) => { +const formatGasSpeedItems = gasPrices => { const gasItems = map(gasPrices, formatGasSpeedItem); return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); }; @@ -83,19 +83,19 @@ class SendSheet extends Component { sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, sendUpdateSelected: PropTypes.func, - } + }; static defaultProps = { isSufficientBalance: false, isSufficientGas: false, isValidAddress: false, - } + }; state = { contacts: [], currentInput: '', isAuthorizing: false, - } + }; componentDidMount = async () => { const { navigation, sendUpdateRecipient } = this.props; @@ -104,8 +104,8 @@ class SendSheet extends Component { if (address) { sendUpdateRecipient(address); } - this.onUpdateContacts() - } + this.onUpdateContacts(); + }; componentDidUpdate(prevProps) { const { @@ -126,13 +126,19 @@ class SendSheet extends Component { } const isNewSelected = isNewValueForPath(this.props, prevProps, 'selected'); - const isNewValidAddress = isNewValueForPath(this.props, prevProps, 'isValidAddress'); + const isNewValidAddress = isNewValueForPath( + this.props, + prevProps, + 'isValidAddress' + ); if (isNewValidAddress || isNewSelected) { let verticalGestureResponseDistance = 0; if (isValidAddress) { - verticalGestureResponseDistance = isEmpty(selected) ? 150 : deviceUtils.dimensions.height; + verticalGestureResponseDistance = isEmpty(selected) + ? 150 + : deviceUtils.dimensions.height; } else { verticalGestureResponseDistance = deviceUtils.dimensions.height; } @@ -145,19 +151,19 @@ class SendSheet extends Component { this.props.sendClearFields(); } - onChangeAssetAmount = (assetAmount) => { + onChangeAssetAmount = assetAmount => { if (isString(assetAmount)) { this.props.sendUpdateAssetAmount(assetAmount); analytics.track('Changed token input in Send flow'); } - } + }; - onChangeNativeAmount = (nativeAmount) => { + onChangeNativeAmount = nativeAmount => { if (isString(nativeAmount)) { this.props.sendUpdateNativeAmount(nativeAmount); analytics.track('Changed native currency input in Send flow'); } - } + }; onLongPressSend = () => { this.setState({ isAuthorizing: true }); @@ -167,39 +173,41 @@ class SendSheet extends Component { } else { this.onPressTransactionSpeed(this.sendTransaction); } - } + }; - onPressTransactionSpeed = (onSuccess) => { + onPressTransactionSpeed = onSuccess => { const { gasPrices, sendUpdateGasPrice } = this.props; - const options = [ - { label: 'Cancel' }, - ...formatGasSpeedItems(gasPrices), - ]; - - showActionSheetWithOptions({ - cancelButtonIndex: 0, - options: options.map(property('label')), - }, (buttonIndex) => { - if (buttonIndex > 0) { - const selectedGasPriceItem = options[buttonIndex]; - - sendUpdateGasPrice(selectedGasPriceItem.value); - analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); - } - - if (isFunction(onSuccess)) { - onSuccess(); + const options = [{ label: 'Cancel' }, ...formatGasSpeedItems(gasPrices)]; + + showActionSheetWithOptions( + { + cancelButtonIndex: 0, + options: options.map(property('label')), + }, + buttonIndex => { + if (buttonIndex > 0) { + const selectedGasPriceItem = options[buttonIndex]; + + sendUpdateGasPrice(selectedGasPriceItem.value); + analytics.track('Updated Gas Price', { + gasPrice: selectedGasPriceItem.gweiValue, + }); + } + + if (isFunction(onSuccess)) { + onSuccess(); + } } - }); - } + ); + }; onResetAssetSelection = () => { analytics.track('Reset asset selection in Send flow'); this.props.sendUpdateSelected({}); - } + }; - onSelectAsset = asset => this.props.sendUpdateSelected(asset) + onSelectAsset = asset => this.props.sendUpdateSelected(asset); sendTransaction = () => { const { @@ -213,29 +221,31 @@ class SendSheet extends Component { if (Number(assetAmount) <= 0) return false; - return onSubmit().then(() => { - this.setState({ isAuthorizing: false }); - analytics.track('Sent transaction', { - assetName: selected.name, - assetType: selected.isNft ? 'unique_token' : 'token', - isRecepientENS: recipient.slice(-4).toLowerCase() === '.eth', + return onSubmit() + .then(() => { + this.setState({ isAuthorizing: false }); + analytics.track('Sent transaction', { + assetName: selected.name, + assetType: selected.isNft ? 'unique_token' : 'token', + isRecepientENS: recipient.slice(-4).toLowerCase() === '.eth', + }); + sendClearFields(); + navigation.navigate('ProfileScreen'); + }) + .catch(() => { + this.setState({ isAuthorizing: false }); }); - sendClearFields(); - navigation.navigate('ProfileScreen'); - }).catch(error => { - this.setState({ isAuthorizing: false }); - }); - } + }; onUpdateContacts = async () => { const contacts = await getLocalContacts(); this.setState({ contacts }); - } + }; - onChangeInput = (event) => { + onChangeInput = event => { this.setState({ currentInput: event }); this.props.sendUpdateRecipient(event); - } + }; render() { const { @@ -287,18 +297,18 @@ class SendSheet extends Component { - )} + } onChangeAssetAmount={this.onChangeAssetAmount} onChangeNativeAmount={this.onChangeNativeAmount} onResetAssetSelection={this.onResetAssetSelection} selected={selected} - txSpeedRenderer={( + txSpeedRenderer={ isIphoneX() && ( ) - )} + } /> )} @@ -323,5 +333,5 @@ export default compose( withDataInit, withHandlers({ fetchData: ({ refreshAccountData }) => async () => refreshAccountData(), - }), + }) )(SendSheet); diff --git a/src/screens/SendSheetWithData.js b/src/screens/SendSheetWithData.js index 6ee8fd0d081..3e8d7a77d6b 100644 --- a/src/screens/SendSheetWithData.js +++ b/src/screens/SendSheetWithData.js @@ -7,7 +7,11 @@ const SendSheetWithData = withSendComponentWithData(SendSheet, { sendTransactionCallback: sendTransaction, }); -SendSheetWithData.navigationOptions = ({ navigation: { state: { params } } }) => ({ +SendSheetWithData.navigationOptions = ({ + navigation: { + state: { params }, + }, +}) => ({ gestureResponseDistance: { vertical: params && params.verticalGestureResponseDistance, }, diff --git a/src/screens/SettingsModal.js b/src/screens/SettingsModal.js index da9313d1fd6..f89d690ae41 100644 --- a/src/screens/SettingsModal.js +++ b/src/screens/SettingsModal.js @@ -1,14 +1,8 @@ - import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { createElement } from 'react'; import { InteractionManager } from 'react-native'; -import { - compose, - onlyUpdateForKeys, - withHandlers, - withProps, -} from 'recompact'; +import { compose, onlyUpdateForKeys, withHandlers, withProps } from 'recompact'; import { Column } from '../components/layout'; import { Modal, ModalHeader } from '../components/modal'; import { AnimatedPager } from '../components/pager'; @@ -93,18 +87,24 @@ SettingsModal.propTypes = { export default compose( withProps(({ navigation }) => ({ - currentSettingsPage: get(navigation, 'state.params.section', SettingsPages.default), + currentSettingsPage: get( + navigation, + 'state.params.section', + SettingsPages.default + ), })), withHandlers({ onCloseModal: ({ navigation }) => () => navigation.goBack(), - onPressBack: ({ navigation }) => () => navigation.setParams({ section: SettingsPages.default }), - onPressImportSeedPhrase: ({ navigation, setSafeTimeout }) => () => { + onPressBack: ({ navigation }) => () => + navigation.setParams({ section: SettingsPages.default }), + onPressImportSeedPhrase: ({ navigation }) => () => { navigation.goBack(); InteractionManager.runAfterInteractions(() => { navigation.navigate('ImportSeedPhraseSheet'); }); }, - onPressSection: ({ navigation }) => (section) => () => navigation.setParams({ section }), + onPressSection: ({ navigation }) => section => () => + navigation.setParams({ section }), }), - onlyUpdateForKeys(['currentSettingsPage']), + onlyUpdateForKeys(['currentSettingsPage']) )(SettingsModal); diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 72538bdf236..38274a28e10 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -46,12 +46,12 @@ export default class TransactionConfirmationScreen extends PureComponent { onConfirm: PropTypes.func, request: PropTypes.object, requestType: PropTypes.string, - } + }; state = { biometryType: null, sendLongPressProgress: new Animated.Value(0), - } + }; componentDidMount() { TouchID.isSupported() @@ -74,7 +74,7 @@ export default class TransactionConfirmationScreen extends PureComponent { duration: 800, toValue: 100, }).start(); - } + }; onReleaseSend = () => { const { sendLongPressProgress } = this.state; @@ -83,7 +83,7 @@ export default class TransactionConfirmationScreen extends PureComponent { duration: (sendLongPressProgress._value / 100) * 800, toValue: 0, }).start(); - } + }; onLongPressSend = async () => { const { onConfirm, requestType } = this.props; @@ -95,11 +95,12 @@ export default class TransactionConfirmationScreen extends PureComponent { }).start(); await onConfirm(requestType); - } + }; renderSendButton = () => { const { requestType } = this.props; - const isMessage = requestType === 'message' || requestType === 'messagePersonal'; + const isMessage = + requestType === 'message' || requestType === 'messagePersonal'; return ( ); - } + }; renderTransactionSection = () => { const { request, requestType } = this.props; - if (requestType === 'message' - || requestType === 'messagePersonal') { + if (requestType === 'message' || requestType === 'messagePersonal') { return ( ); - } + }; render = () => ( @@ -156,16 +156,11 @@ export default class TransactionConfirmationScreen extends PureComponent { - + {this.props.dappName} @@ -184,5 +179,5 @@ export default class TransactionConfirmationScreen extends PureComponent { {this.renderTransactionSection()} - ) + ); } diff --git a/src/screens/TransactionConfirmationScreenWithData.js b/src/screens/TransactionConfirmationScreenWithData.js index bda00faf3c6..f2de8214674 100644 --- a/src/screens/TransactionConfirmationScreenWithData.js +++ b/src/screens/TransactionConfirmationScreenWithData.js @@ -4,7 +4,7 @@ import lang from 'i18n-js'; import { get, isNil, omit } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { Alert, StatusBar, Vibration } from 'react-native'; +import { Alert, Vibration } from 'react-native'; import { withNavigationFocus } from 'react-navigation'; import { compose } from 'recompact'; import { withTransactionConfirmationScreen } from '../hoc'; @@ -19,13 +19,12 @@ import TransactionConfirmationScreen from './TransactionConfirmationScreen'; class TransactionConfirmationScreenWithData extends PureComponent { static propTypes = { dataAddNewTransaction: PropTypes.func, - isFocused: PropTypes.bool.isRequired, navigation: PropTypes.any, removeRequest: PropTypes.func, transactionCountNonce: PropTypes.number, updateTransactionCountNonce: PropTypes.func, walletConnectSendStatus: PropTypes.func, - } + }; componentDidMount() { const autoOpened = get(this.props, 'navigation.state.params.autoOpened'); @@ -34,7 +33,7 @@ class TransactionConfirmationScreenWithData extends PureComponent { } } - handleConfirm = async (requestType) => { + handleConfirm = async requestType => { if (requestType === 'message' || requestType === 'messagePersonal') { return this.handleSignMessage(requestType); } @@ -56,7 +55,10 @@ class TransactionConfirmationScreenWithData extends PureComponent { } } const web3TxnCount = await getTransactionCount(txPayload.from); - const maxTxnCount = Math.max(this.props.transactionCountNonce, web3TxnCount); + const maxTxnCount = Math.max( + this.props.transactionCountNonce, + web3TxnCount + ); const nonce = ethers.utils.hexlify(maxTxnCount); let txPayloadLatestNonce = { ...txPayload, nonce }; txPayloadLatestNonce = omit(txPayloadLatestNonce, 'from'); @@ -80,9 +82,13 @@ class TransactionConfirmationScreenWithData extends PureComponent { this.props.dataAddNewTransaction(txDetails); this.props.removeRequest(transactionDetails.requestId); try { - await this.props.walletConnectSendStatus(transactionDetails.peerId, transactionDetails.requestId, transactionHash); - } catch (error) { - } + await this.props.walletConnectSendStatus( + transactionDetails.peerId, + transactionDetails.requestId, + transactionHash + ); + // eslint-disable-next-line no-empty + } catch (error) {} analytics.track('Approved WalletConnect transaction request'); this.closeScreen(); } else { @@ -90,7 +96,7 @@ class TransactionConfirmationScreenWithData extends PureComponent { } }; - handleSignMessage = async (requestType) => { + handleSignMessage = async requestType => { const { transactionDetails } = this.props.navigation.state.params; let message = null; let flatFormatSignature = null; @@ -104,7 +110,11 @@ class TransactionConfirmationScreenWithData extends PureComponent { if (flatFormatSignature) { this.props.removeRequest(transactionDetails.requestId); - await this.props.walletConnectSendStatus(transactionDetails.peerId, transactionDetails.requestId, flatFormatSignature); + await this.props.walletConnectSendStatus( + transactionDetails.peerId, + transactionDetails.requestId, + flatFormatSignature + ); analytics.track('Approved WalletConnect signature request'); this.closeScreen(); } else { @@ -116,40 +126,45 @@ class TransactionConfirmationScreenWithData extends PureComponent { try { this.closeScreen(); const { transactionDetails } = this.props.navigation.state.params; - await this.props.walletConnectSendStatus(transactionDetails.peerId, transactionDetails.requestId, null); + await this.props.walletConnectSendStatus( + transactionDetails.peerId, + transactionDetails.requestId, + null + ); } catch (error) { this.closeScreen(); Alert.alert(lang.t('wallet.transaction.alert.cancelled_transaction')); } - } + }; handleCancelRequest = async () => { try { await this.sendFailedTransactionStatus(); const { transactionDetails } = this.props.navigation.state.params; - const { requestId, displayDetails: { requestType } } = transactionDetails; + const { + requestId, + displayDetails: { requestType }, + } = transactionDetails; this.props.removeRequest(requestId); - const rejectionType = requestType === 'message' ? 'signature' : 'transaction'; + const rejectionType = + requestType === 'message' ? 'signature' : 'transaction'; analytics.track(`Rejected WalletConnect ${rejectionType} request`); } catch (error) { this.closeScreen(); Alert.alert('Failed to send rejected transaction status'); } - } + }; closeScreen = () => { this.props.navigation.popToTop(); - } + }; render = () => { const { transactionDetails: { dappName, imageUrl, - displayDetails: { - type, - payload, - }, + displayDetails: { type, payload }, }, } = this.props.navigation.state.params; @@ -165,10 +180,10 @@ class TransactionConfirmationScreenWithData extends PureComponent { /> ); - } + }; } export default compose( withNavigationFocus, - withTransactionConfirmationScreen, + withTransactionConfirmationScreen )(TransactionConfirmationScreenWithData); diff --git a/src/screens/WalletConnectConfirmationModal.js b/src/screens/WalletConnectConfirmationModal.js index fe86b85c5dd..e7afc75486b 100644 --- a/src/screens/WalletConnectConfirmationModal.js +++ b/src/screens/WalletConnectConfirmationModal.js @@ -25,15 +25,13 @@ const WalletConnectConfirmationModal = ({ peerMeta, }) => ( - + {get(peerMeta, 'name', 'Unknown dapp')} - wants to connect to your wallet. + + + wants to connect to your wallet. + @@ -43,11 +41,9 @@ const WalletConnectConfirmationModal = ({ ); WalletConnectConfirmationModal.propTypes = { - navigation: PropTypes.object.isRequired, onApprove: PropTypes.func.isRequired, onCloseModal: PropTypes.func.isRequired, onReject: PropTypes.func.isRequired, - peerId: PropTypes.string.isRequired, peerMeta: PropTypes.object.isRequired, }; @@ -59,7 +55,11 @@ export default compose( })), withHandlers({ onCloseModal: ({ navigation }) => () => navigation.goBack() }), withHandlers({ - onApprove: ({ onCloseModal, peerId, walletConnectApproveSession }) => () => { + onApprove: ({ + onCloseModal, + peerId, + walletConnectApproveSession, + }) => () => { walletConnectApproveSession(peerId); return onCloseModal(); }, @@ -67,5 +67,5 @@ export default compose( walletConnectRejectSession(peerId); onCloseModal(); }, - }), + }) )(WalletConnectConfirmationModal); diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index f469e380942..7d0f71daa15 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -1,19 +1,17 @@ import { withSafeTimeout } from '@hocs/safe-timers'; -import analytics from '@segment/analytics-react-native'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; import { withNavigation, withNavigationFocus } from 'react-navigation'; -import { - compose, - withHandlers, - withProps, - withState, -} from 'recompact'; +import { compose, withProps } from 'recompact'; import { AssetList } from '../components/asset-list'; import BlurOverlay from '../components/BlurOverlay'; import { FabWrapper } from '../components/fab'; -import { CameraHeaderButton, Header, ProfileHeaderButton } from '../components/header'; +import { + CameraHeaderButton, + Header, + ProfileHeaderButton, +} from '../components/header'; import { Page } from '../components/layout'; import { getSmallBalanceToggle, @@ -37,7 +35,7 @@ import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; -import { deviceUtils, isNewValueForPath } from '../utils'; +import { isNewValueForPath } from '../utils'; class WalletScreen extends Component { static propTypes = { @@ -55,17 +53,7 @@ class WalletScreen extends Component { sections: PropTypes.array, setSafeTimeout: PropTypes.func, uniqueTokens: PropTypes.array, - } - - setInitialStatesForOpenAssets = async () => { - const toggle = await getSmallBalanceToggle(); - const openInvestmentCards = await getOpenInvestmentCards(); - const openFamilies = await getOpenFamilies(); - await store.dispatch(setOpenSmallBalances(toggle)); - await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); - await store.dispatch(pushOpenFamilyTab(openFamilies)); - return true; - } + }; componentDidMount = async () => { try { @@ -74,33 +62,74 @@ class WalletScreen extends Component { } catch (error) { // TODO error state } - } + }; - shouldComponentUpdate = (nextProps) => { - const isNewBlurIntensity = isNewValueForPath(this.props, nextProps, 'blurIntensity'); - const isNewCurrency = isNewValueForPath(this.props, nextProps, 'nativeCurrency'); - const isNewFetchingAssets = isNewValueForPath(this.props, nextProps, 'fetchingAssets'); - const isNewFetchingUniqueTokens = isNewValueForPath(this.props, nextProps, 'fetchingUniqueTokens'); - const isNewIsWalletEmpty = isNewValueForPath(this.props, nextProps, 'isEmpty'); - const isNewIsWalletEthZero = isNewValueForPath(this.props, nextProps, 'isWalletEthZero'); + shouldComponentUpdate = nextProps => { + const isNewBlurIntensity = isNewValueForPath( + this.props, + nextProps, + 'blurIntensity' + ); + const isNewCurrency = isNewValueForPath( + this.props, + nextProps, + 'nativeCurrency' + ); + const isNewFetchingAssets = isNewValueForPath( + this.props, + nextProps, + 'fetchingAssets' + ); + const isNewFetchingUniqueTokens = isNewValueForPath( + this.props, + nextProps, + 'fetchingUniqueTokens' + ); + const isNewIsWalletEmpty = isNewValueForPath( + this.props, + nextProps, + 'isEmpty' + ); + const isNewIsWalletEthZero = isNewValueForPath( + this.props, + nextProps, + 'isWalletEthZero' + ); const isNewLanguage = isNewValueForPath(this.props, nextProps, 'language'); const isNewSections = isNewValueForPath(this.props, nextProps, 'sections'); - const isNewTransitionProps = isNewValueForPath(this.props, nextProps, 'transitionProps'); + + const isNewTransitionProps = isNewValueForPath( + this.props, + nextProps, + 'transitionProps' + ); if (!nextProps.isFocused) { return isNewBlurIntensity || isNewTransitionProps; } - return isNewFetchingAssets - || isNewFetchingUniqueTokens - || isNewIsWalletEmpty - || isNewIsWalletEthZero - || isNewLanguage - || isNewCurrency - || isNewBlurIntensity - || isNewSections - || isNewTransitionProps; - } + return ( + isNewFetchingAssets || + isNewFetchingUniqueTokens || + isNewIsWalletEmpty || + isNewIsWalletEthZero || + isNewLanguage || + isNewCurrency || + isNewBlurIntensity || + isNewSections || + isNewTransitionProps + ); + }; + + setInitialStatesForOpenAssets = async () => { + const toggle = await getSmallBalanceToggle(); + const openInvestmentCards = await getOpenInvestmentCards(); + const openFamilies = await getOpenFamilies(); + await store.dispatch(setOpenSmallBalances(toggle)); + await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); + await store.dispatch(pushOpenFamilyTab(openFamilies)); + return true; + }; render = () => { const { @@ -138,7 +167,7 @@ class WalletScreen extends Component {
); - } + }; } export default compose( @@ -155,5 +184,5 @@ export default compose( withIsWalletEthZero, withStatusBarStyle('dark-content'), withProps(buildWalletSectionsSelector), - withProps({ scrollViewTracker: new Animated.Value(0) }), + withProps({ scrollViewTracker: new Animated.Value(0) }) )(WalletScreen); diff --git a/src/styles/animations.js b/src/styles/animations.js index afa9eb140b4..94a28484b19 100644 --- a/src/styles/animations.js +++ b/src/styles/animations.js @@ -29,14 +29,13 @@ const buildSpring = ({ to, useNativeDriver = true, value, -}) => ( +}) => Animated.spring(value, { ...spring.default, toValue: isActive ? to : from, useNativeDriver, ...config, - }) -); + }); export default { buildSpring, diff --git a/src/styles/buildLayoutStyles.js b/src/styles/buildLayoutStyles.js index 334fe7e7eee..cb4f813596b 100644 --- a/src/styles/buildLayoutStyles.js +++ b/src/styles/buildLayoutStyles.js @@ -14,10 +14,12 @@ export default (values, type, shouldReturnCss) => { top: values[0], }; - return shouldReturnCss ? css` + return shouldReturnCss + ? css` ${type}${separator}bottom: ${coordinates.bottom}; ${type}${separator}left: ${coordinates.left}; ${type}${separator}right: ${coordinates.right}; ${type}${separator}top: ${coordinates.top}; - ` : coordinates; + ` + : coordinates; }; diff --git a/src/styles/buildTextStyles.js b/src/styles/buildTextStyles.js index de3c2a87324..f5429e74ecc 100644 --- a/src/styles/buildTextStyles.js +++ b/src/styles/buildTextStyles.js @@ -3,28 +3,17 @@ import colors from './colors'; import fonts from './fonts'; export default css` - ${({ align }) => ( - align - ? `text-align: ${align};` - : '' - )} - ${({ letterSpacing }) => ( + ${({ align }) => (align ? `text-align: ${align};` : '')} + ${({ letterSpacing }) => letterSpacing ? `letter-spacing: ${fonts.letterSpacing[letterSpacing]};` - : '' - )} - ${({ lineHeight }) => ( - lineHeight - ? `line-height: ${fonts.lineHeight[lineHeight]};` - : '' - )} - ${({ uppercase }) => ( - uppercase - ? 'text-transform: uppercase;' - : '' - )} - color: ${({ color }) => (colors.get(color) || colors.dark)} - font-family: ${({ family = 'SFProText', mono }) => fonts.family[mono ? 'SFMono' : family]}; + : ''} + ${({ lineHeight }) => + lineHeight ? `line-height: ${fonts.lineHeight[lineHeight]};` : ''} + ${({ uppercase }) => (uppercase ? 'text-transform: uppercase;' : '')} + color: ${({ color }) => colors.get(color) || colors.dark} + font-family: ${({ family = 'SFProText', mono }) => + fonts.family[mono ? 'SFMono' : family]}; font-size: ${({ size }) => fonts.size[size || 'medium']}; font-weight: ${({ weight }) => fonts.weight[weight || 'regular']}; `; diff --git a/src/styles/colors.js b/src/styles/colors.js index a94a23e8f54..400e23df88a 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -80,24 +80,23 @@ const vendor = { const buildRgba = (color, alpha) => `rgba(${chroma(color).rgb()}, ${alpha})`; -const isColorLight = targetColor => (chroma(targetColor || base.white).luminance() > 0.5); +const isColorLight = targetColor => + chroma(targetColor || base.white).luminance() > 0.5; -const isHex = (color = '') => ((color.length >= 3) && (color.charAt(0) === '#')); -const isRGB = (color = '') => (color.toLowerCase().substring(0, 3) === 'rgb'); +const isHex = (color = '') => color.length >= 3 && color.charAt(0) === '#'; +const isRGB = (color = '') => color.toLowerCase().substring(0, 3) === 'rgb'; const getTextColorForBackground = (targetColor, textColors = {}) => { - const { - dark = base.black, - light = base.white, - } = textColors; + const { dark = base.black, light = base.white } = textColors; return isColorLight(targetColor) ? dark : light; }; -const getFallbackTextColor = bg => colors.getTextColorForBackground(bg, { - dark: colors.blueGreyLight, - light: colors.white, -}); +const getFallbackTextColor = bg => + colors.getTextColorForBackground(bg, { + dark: colors.blueGreyLight, + light: colors.white, + }); const transparent = { blueGreyDarkTransparent: buildRgba(base.blueGreyDark, 0.6), @@ -128,8 +127,5 @@ const getColorForString = (colorString = '') => { export default { ...colors, get: getColorForString, - propType: PropTypes.oneOf([ - ...Object.keys(colors), - ...Object.values(colors), - ]), + propType: PropTypes.oneOf([...Object.keys(colors), ...Object.values(colors)]), }; diff --git a/src/styles/fonts.js b/src/styles/fonts.js index d1f9b6ed83d..72d97c29fa5 100644 --- a/src/styles/fonts.js +++ b/src/styles/fonts.js @@ -1,3 +1,4 @@ +/* eslint-disable sort-keys */ const font = {}; font.family = { @@ -8,7 +9,6 @@ font.family = { }; font.letterSpacing = { - /* eslint-disable sort-keys */ tightest: -0.3, tighter: -0.2, tight: -0.1, @@ -17,7 +17,6 @@ font.letterSpacing = { }; font.lineHeight = { - /* eslint-disable sort-keys */ none: 0, tight: 16, normal: 20, @@ -27,7 +26,6 @@ font.lineHeight = { }; font.size = { - /* eslint-disable sort-keys */ micro: '9px', tiny: '11px', smaller: '12px', @@ -52,7 +50,6 @@ font.size = { // react-native requires font weights to be defined as strings font.weight = { - /* eslint-disable sort-keys */ thin: '100', ultraLight: '200', light: '300', diff --git a/src/styles/shadow.js b/src/styles/shadow.js index dec92d36441..cb106055d92 100644 --- a/src/styles/shadow.js +++ b/src/styles/shadow.js @@ -1,16 +1,20 @@ import { isNumber } from 'lodash'; import colors from './colors'; -const addUnitToNumberValues = value => ( - isNumber(value) ? `${value}px` : value -); +const addUnitToNumberValues = value => (isNumber(value) ? `${value}px` : value); const shadow = {}; shadow.color = colors.black; shadow.opacity = 0.4; -shadow.build = (x, y, radius, color = shadow.color, opacity = shadow.opacity) => ` +shadow.build = ( + x, + y, + radius, + color = shadow.color, + opacity = shadow.opacity +) => ` shadow-color: ${color}; shadow-offset: ${addUnitToNumberValues(x)} ${addUnitToNumberValues(y)}; shadow-opacity: ${opacity}; diff --git a/src/utils/__tests__/contract.test.js b/src/utils/__tests__/contract.test.js index a5869727120..3026c60c0b0 100644 --- a/src/utils/__tests__/contract.test.js +++ b/src/utils/__tests__/contract.test.js @@ -1,29 +1,43 @@ import { greaterThan } from '../../helpers/utilities'; -import { getAllowance } from '../contract'; +import Contract from '../contract'; + +const { getAllowance } = Contract; const accountAddress = '0x1492004547FF0eFd778CC2c14E794B26B4701105'; -test('getAllowanceZrx', async () => { +it('getAllowanceZrx', async () => { const exchangeAddress = '0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF'; const tokenAddress = '0xe41d2489571d322189246dafa5ebde1f4699f498'; - const allowance = await getAllowance(accountAddress, { address: tokenAddress, decimals: 18 }, exchangeAddress); + const allowance = await getAllowance( + accountAddress, + { address: tokenAddress, decimals: 18 }, + exchangeAddress + ); const result = greaterThan(allowance, 0); expect(result).toBeTruthy(); }); -test('getAllowanceMkr', async () => { +it('getAllowanceMkr', async () => { const exchangeAddress = '0x2C4Bd064b998838076fa341A83d007FC2FA50957'; const tokenAddress = '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2'; - const allowance = await getAllowance(accountAddress, { address: tokenAddress, decimals: 18 }, exchangeAddress); + const allowance = await getAllowance( + accountAddress, + { address: tokenAddress, decimals: 18 }, + exchangeAddress + ); const result = greaterThan(allowance, 0); expect(result).toBeTruthy(); }); -test('getAllowanceBatNotApproved', async () => { +// TODO +xit('getAllowanceBatNotApproved', async () => { const exchangeAddress = '0x2E642b8D59B45a1D8c5aEf716A84FF44ea665914'; const tokenAddress = '0x0d8775f648430679a709e98d2b0cb6250d2887ef'; - const allowance = await getAllowance(accountAddress, { address: tokenAddress, decimals: 18 }, exchangeAddress); + const allowance = await getAllowance( + accountAddress, + { address: tokenAddress, decimals: 18 }, + exchangeAddress + ); const result = greaterThan(allowance, 0); expect(result).toBeFalsy(); }); - diff --git a/src/utils/__tests__/ethereumUtils.test.js b/src/utils/__tests__/ethereumUtils.test.js index 45987472c2c..578be29045f 100644 --- a/src/utils/__tests__/ethereumUtils.test.js +++ b/src/utils/__tests__/ethereumUtils.test.js @@ -4,11 +4,11 @@ const gasPrice = { txFee: { value: { amount: 21000, - } - } + }, + }, }; -test('getBalanceAmountEth', () => { +it('getBalanceAmountEth', () => { const selected = { address: 'eth', balance: { amount: '1' }, @@ -17,7 +17,7 @@ test('getBalanceAmountEth', () => { expect(updatedBalance).toBe('0.999999999999979'); }); -test('getBalanceAmountInsufficientEth', () => { +it('getBalanceAmountInsufficientEth', () => { const selected = { address: 'eth', balance: { amount: '0.00000000000000001' }, @@ -26,7 +26,7 @@ test('getBalanceAmountInsufficientEth', () => { expect(updatedBalance).toBe('0'); }); -test('getBalanceAmountToken', () => { +it('getBalanceAmountToken', () => { const selected = { address: '0x12345', balance: { amount: '1' }, @@ -34,4 +34,3 @@ test('getBalanceAmountToken', () => { const updatedBalance = getBalanceAmount(gasPrice, selected); expect(updatedBalance).toBe('1'); }); - diff --git a/src/utils/__tests__/search.test.js b/src/utils/__tests__/search.test.js index 493b047b925..e8e3a282c5b 100644 --- a/src/utils/__tests__/search.test.js +++ b/src/utils/__tests__/search.test.js @@ -1,19 +1,18 @@ import { filterList } from '../search'; -test('filterListSimpleArray', () => { +it('filterListSimpleArray', () => { const list = ['a dog', 'black cat']; const searchPhrase = 'cat'; const result = filterList(list, searchPhrase); expect(result.length).toBe(1); }); -test('filterListWithParameter', () => { +it('filterListWithParameter', () => { const list = [ { name: 'Ethereum', symbol: 'ETH' }, - { name: '0x Protocol Token', symbol: 'ZRX'}, + { name: '0x Protocol Token', symbol: 'ZRX' }, ]; const searchPhrase = 'eth'; - const result = filterList(list, searchPhrase, searchParameter = 'name'); + const result = filterList(list, searchPhrase, 'name'); expect(result.length).toBe(1); }); - diff --git a/src/utils/abbreviations.js b/src/utils/abbreviations.js index 1da2093ce3c..14c77e10452 100644 --- a/src/utils/abbreviations.js +++ b/src/utils/abbreviations.js @@ -12,7 +12,10 @@ export function address(currentAddress, truncationLength, firstSectionLength) { } export function isAddress(currentAddress) { - return (currentAddress || '').substring(0, 2) === '0x' && (currentAddress || '').indexOf('...') > -1; + return ( + (currentAddress || '').substring(0, 2) === '0x' && + (currentAddress || '').indexOf('...') > -1 + ); } export default { diff --git a/src/utils/address.js b/src/utils/address.js index 82e0c3cbf00..2d988290dbc 100644 --- a/src/utils/address.js +++ b/src/utils/address.js @@ -5,12 +5,12 @@ import { isValidAddress } from '../helpers/validators'; * @param {String} data - qr code data * @return {String} address - ethereum address */ -export const getEthereumAddressFromQRCodeData = async (data) => { +export const getEthereumAddressFromQRCodeData = async data => { if (!data) return null; const parts = data.split(':'); - if (parts[0] === 'ethereum' && await isValidAddress(parts[1])) { + if (parts[0] === 'ethereum' && (await isValidAddress(parts[1]))) { return parts[1]; } if (await isValidAddress(parts[0])) { diff --git a/src/utils/contract.js b/src/utils/contract.js index c107b8fb7e9..9ed086599f0 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -4,7 +4,8 @@ import { convertRawAmountToDecimalFormat } from '../helpers/utilities'; import { loadWallet } from '../model/wallet'; import erc20ABI from '../references/erc20-abi.json'; -const estimateApproveWithExchange = (spender, exchange) => exchange.estimate.approve(spender, ethers.constants.MaxUint256); +const estimateApproveWithExchange = (spender, exchange) => + exchange.estimate.approve(spender, ethers.constants.MaxUint256); const estimateApprove = (tokenAddress, spender) => { const exchange = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); @@ -21,7 +22,11 @@ const approve = async (tokenAddress, spender) => { const getAllowance = async (owner, token, spender) => { const { address: tokenAddress, decimals } = token; - const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); + const tokenContract = new ethers.Contract( + tokenAddress, + erc20ABI, + web3Provider + ); const allowance = await tokenContract.allowance(owner, spender); const rawAllowance = ethers.utils.bigNumberify(allowance.toString()); return convertRawAmountToDecimalFormat(rawAllowance, decimals); diff --git a/src/utils/directionPropType.js b/src/utils/directionPropType.js index 1eb4530d6e8..b09bc5b224e 100644 --- a/src/utils/directionPropType.js +++ b/src/utils/directionPropType.js @@ -1,8 +1,3 @@ import PropTypes from 'prop-types'; -export default PropTypes.oneOf([ - 'down', - 'left', - 'right', - 'up', -]); +export default PropTypes.oneOf(['down', 'left', 'right', 'up']); diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index fcb14b8f780..28fc9b59f5e 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -22,7 +22,8 @@ export const getBalanceAmount = (selectedGasPrice, selected) => { return amount; }; -export const getAsset = (assets, address = 'eth') => find(assets, asset => asset.address === address); +export const getAsset = (assets, address = 'eth') => + find(assets, asset => asset.address === address); /** * @desc remove hex prefix @@ -61,7 +62,7 @@ export const getDataString = (func, arrVals) => { * @desc get network string from chainId * @param {Number} chainId */ -export const getNetworkFromChainId = (chainId) => { +export const getNetworkFromChainId = chainId => { const networkData = find(chains, ['chain_id', chainId]); return get(networkData, 'network', 'mainnet'); }; @@ -70,7 +71,7 @@ export const getNetworkFromChainId = (chainId) => { * @desc get chainId from network string * @param {String} network */ -export const getChainIdFromNetwork = (network) => { +export const getChainIdFromNetwork = network => { const chainData = find(chains, ['network', network]); return get(chainData, 'chain_id', 1); }; diff --git a/src/utils/formatters.js b/src/utils/formatters.js index 297a16df8f4..f337aff7a9c 100644 --- a/src/utils/formatters.js +++ b/src/utils/formatters.js @@ -7,18 +7,27 @@ const firstCharacterOfString = n => n.charAt(0); export const getFirstGrapheme = string => grapheme.splitGraphemes(string)[0]; -export const initials = (string) => ( - (!string || !isString(string)) +export const initials = string => + !string || !isString(string) ? '?' - : string.split(' ').map(firstCharacterOfString).join('') -); + : string + .split(' ') + .map(firstCharacterOfString) + .join(''); export function removeLeadingZeros(value = '') { - if (value.length > 1 && value.substring(0, 1) === '0' && value.substring(1, 2) !== '.') { + if ( + value.length > 1 && + value.substring(0, 1) === '0' && + value.substring(1, 2) !== '.' + ) { return removeLeadingZeros(value.substring(1)); } - if (value.substring(value.length - 1, value.length) === '.' && value.indexOf('.') !== value.length - 1) { + if ( + value.substring(value.length - 1, value.length) === '.' && + value.indexOf('.') !== value.length - 1 + ) { return value.substring(0, value.length - 1); } diff --git a/src/utils/gas.js b/src/utils/gas.js index f2328f0f609..bfebd96d0c4 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -16,32 +16,37 @@ const showTransactionSpeedOptions = ( gasPrices, txFees, updateGasOption, - onSuccess, + onSuccess ) => { const options = [ { label: 'Cancel' }, ...formatGasSpeedItems(gasPrices, txFees), ]; - showActionSheetWithOptions({ - cancelButtonIndex: 0, - options: options.map(property('label')), - }, (buttonIndex) => { - if (buttonIndex > 0) { - const selectedGasPriceItem = options[buttonIndex]; + showActionSheetWithOptions( + { + cancelButtonIndex: 0, + options: options.map(property('label')), + }, + buttonIndex => { + if (buttonIndex > 0) { + const selectedGasPriceItem = options[buttonIndex]; - updateGasOption(selectedGasPriceItem.value); - analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue }); - } + updateGasOption(selectedGasPriceItem.value); + analytics.track('Updated Gas Price', { + gasPrice: selectedGasPriceItem.gweiValue, + }); + } - if (isFunction(onSuccess)) { - onSuccess(); + if (isFunction(onSuccess)) { + onSuccess(); + } } - }); + ); }; const formatGasSpeedItems = (gasPrices, txFees) => { - const gasItems = map(GasSpeedTypes, (label) => { + const gasItems = map(GasSpeedTypes, label => { let speed = label; if (label === 'normal') { speed = 'average'; diff --git a/src/utils/parseQueryParams.js b/src/utils/parseQueryParams.js index 59e809347f1..190da5efd3b 100644 --- a/src/utils/parseQueryParams.js +++ b/src/utils/parseQueryParams.js @@ -11,7 +11,7 @@ export default queryString => { const valueArr = pairs[i].match(/=.+/i) || []; if (keyArr[0]) { result[decodeURIComponent(keyArr[0])] = decodeURIComponent( - valueArr[0].substr(1), + valueArr[0].substr(1) ); } } diff --git a/src/utils/promise.js b/src/utils/promise.js index 42f1ce4f153..8f590a40ca1 100644 --- a/src/utils/promise.js +++ b/src/utils/promise.js @@ -1,11 +1,10 @@ -const PromiseAllWithFails = async (promises) => ( -Promise.all(promises.map(promise => ( - (promise && promise.catch) - ? promise.catch(error => error) - : promise -)))); +const PromiseAllWithFails = async promises => + Promise.all( + promises.map(promise => + promise && promise.catch ? promise.catch(error => error) : promise + ) + ); export default { PromiseAllWithFails, }; - diff --git a/src/utils/reduceArrayToObject.js b/src/utils/reduceArrayToObject.js index 2b18a0371ae..4abbeef6564 100644 --- a/src/utils/reduceArrayToObject.js +++ b/src/utils/reduceArrayToObject.js @@ -2,8 +2,5 @@ import { compact } from 'lodash'; const reduceArrayToObject = (item, culm) => Object.assign(culm, item); -export default array => ( - Array.isArray(array) - ? compact(array).reduce(reduceArrayToObject, {}) - : array -); +export default array => + Array.isArray(array) ? compact(array).reduce(reduceArrayToObject, {}) : array; diff --git a/src/utils/search.js b/src/utils/search.js index f44bb2738c1..777633587d8 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -1,4 +1,9 @@ -export const filterList = (list, searchPhrase, searchParameter = false, separator = ' ') => { +export const filterList = ( + list, + searchPhrase, + searchParameter = false, + separator = ' ' +) => { const filteredList = []; if (list && searchPhrase.length > 0) { for (let i = 0; i < list.length; i++) { @@ -6,7 +11,11 @@ export const filterList = (list, searchPhrase, searchParameter = false, separato const splitedWordList = (searchedItem || '').split(separator); splitedWordList.push(searchedItem); for (let j = 0; j < splitedWordList.length; j++) { - if (splitedWordList[j].toLowerCase().startsWith(searchPhrase.toLowerCase())) { + if ( + splitedWordList[j] + .toLowerCase() + .startsWith(searchPhrase.toLowerCase()) + ) { filteredList.push(list[i]); break; } @@ -16,4 +25,4 @@ export const filterList = (list, searchPhrase, searchParameter = false, separato return list; } return filteredList; -} +}; diff --git a/yarn.lock b/yarn.lock index 1cfc7e5c074..61b2347e4b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1066,23 +1066,6 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/eslint-config@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795" - integrity sha512-jwO2tnKaTPTLX5XYXMHGEnFdf543SU7jz98/OF5mDH3b7lP+BOaCD+jVfqqHoDRkcqyPlYiR1CgwVGWpi0vMWg== - dependencies: - "@typescript-eslint/eslint-plugin" "^1.5.0" - "@typescript-eslint/parser" "^1.5.0" - babel-eslint "10.0.1" - eslint-plugin-eslint-comments "^3.1.1" - eslint-plugin-flowtype "2.50.3" - eslint-plugin-jest "22.4.1" - eslint-plugin-prettier "2.6.2" - eslint-plugin-react "7.12.4" - eslint-plugin-react-hooks "^1.5.1" - eslint-plugin-react-native "3.6.0" - prettier "1.16.4" - "@react-native-community/masked-view@^0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.1.tgz#dbcfc5ec08efbb02d4142dd9426c8d7a396829d7" @@ -1349,6 +1332,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" @@ -1393,7 +1381,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^1.5.0": +"@typescript-eslint/eslint-plugin@^1.6.0": version "1.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz#22fed9b16ddfeb402fd7bcde56307820f6ebc49f" integrity sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g== @@ -1404,7 +1392,7 @@ regexpp "^2.0.1" tsutils "^3.7.0" -"@typescript-eslint/experimental-utils@1.13.0": +"@typescript-eslint/experimental-utils@1.13.0", "@typescript-eslint/experimental-utils@^1.13.0": version "1.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e" integrity sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg== @@ -1413,7 +1401,7 @@ "@typescript-eslint/typescript-estree" "1.13.0" eslint-scope "^4.0.0" -"@typescript-eslint/parser@^1.5.0": +"@typescript-eslint/parser@^1.6.0": version "1.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-1.13.0.tgz#61ac7811ea52791c47dc9fd4dd4a184fae9ac355" integrity sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ== @@ -1947,19 +1935,7 @@ babel-core@7.0.0-bridge.0: resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== -babel-eslint@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" - integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - eslint-scope "3.7.1" - eslint-visitor-keys "^1.0.0" - -babel-eslint@^10.0.2: +babel-eslint@^10.0.1, babel-eslint@^10.0.2: version "10.0.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== @@ -2915,11 +2891,6 @@ configstore@^3.0.0: write-file-atomic "^2.0.0" xdg-basedir "^3.0.0" -confusing-browser-globals@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" - integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== - connect@^3.6.5: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -3733,16 +3704,35 @@ escodegen@1.x.x, escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" -eslint-config-airbnb-base@^13.2.0: - version "13.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.2.0.tgz#f6ea81459ff4dec2dda200c35f1d8f7419d57943" - integrity sha512-1mg/7eoB4AUeB0X1c/ho4vb2gYkNH8Trr/EgCT/aGmKhhG+F6vF5s8+iRBlWAzFIAphxIdp3YfEKgEl0f9Xg+w== +eslint-config-prettier@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz#c55c1fcac8ce4518aeb77906984e134d9eb5a4f0" + integrity sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA== dependencies: - confusing-browser-globals "^1.0.5" - object.assign "^4.1.0" - object.entries "^1.1.0" + get-stdin "^6.0.0" -eslint-import-resolver-node@^0.3.1, eslint-import-resolver-node@^0.3.2: +eslint-config-satya164@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/eslint-config-satya164/-/eslint-config-satya164-2.4.1.tgz#139909a590d4503197d501051deef9aa67768990" + integrity sha512-i9fqMDq4XywgRrcYdaPwmv/i+FtGI1FTXz9yKb4JktlWnU555cxmryFDknNJJj9cL06RR5a/O5hnJSoLksGWbQ== + dependencies: + "@typescript-eslint/eslint-plugin" "^1.6.0" + "@typescript-eslint/parser" "^1.6.0" + babel-eslint "^10.0.1" + eslint-config-prettier "^4.1.0" + eslint-plugin-babel "^5.3.0" + eslint-plugin-eslint-comments "^3.1.1" + eslint-plugin-flowtype "^3.6.1" + eslint-plugin-import "^2.16.0" + eslint-plugin-jest "^22.4.1" + eslint-plugin-json "^1.4.0" + eslint-plugin-markdown "^1.0.0" + eslint-plugin-prettier "^3.0.1" + eslint-plugin-react "^7.12.4" + eslint-plugin-react-hooks "^1.6.0" + eslint-plugin-react-native "^3.6.0" + +eslint-import-resolver-node@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== @@ -3750,7 +3740,7 @@ eslint-import-resolver-node@^0.3.1, eslint-import-resolver-node@^0.3.2: debug "^2.6.9" resolve "^1.5.0" -eslint-module-utils@^2.2.0, eslint-module-utils@^2.4.0: +eslint-module-utils@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c" integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw== @@ -3758,6 +3748,13 @@ eslint-module-utils@^2.2.0, eslint-module-utils@^2.4.0: debug "^2.6.8" pkg-dir "^2.0.0" +eslint-plugin-babel@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-5.3.0.tgz#2e7f251ccc249326da760c1a4c948a91c32d0023" + integrity sha512-HPuNzSPE75O+SnxHIafbW5QB45r2w78fxqwK3HmjqIUoPfPzVrq6rD+CINU3yzoDSzEhUkX07VUphbF73Lth/w== + dependencies: + eslint-rule-composer "^0.3.0" + eslint-plugin-eslint-comments@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz#4ef6c488dbe06aa1627fea107b3e5d059fc8a395" @@ -3766,14 +3763,14 @@ eslint-plugin-eslint-comments@^3.1.1: escape-string-regexp "^1.0.5" ignore "^5.0.5" -eslint-plugin-flowtype@2.50.3: - version "2.50.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f" - integrity sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ== +eslint-plugin-flowtype@^3.6.1: + version "3.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.13.0.tgz#e241ebd39c0ce519345a3f074ec1ebde4cf80f2c" + integrity sha512-bhewp36P+t7cEV0b6OdmoRWJCBYRiHFlqPZAG1oS3SF+Y0LQkeDvFSM4oxoxvczD1OdONCXMlJfQFiWLcV9urw== dependencies: - lodash "^4.17.10" + lodash "^4.17.15" -eslint-plugin-import@2.14.0: +eslint-plugin-import@2.14.0, eslint-plugin-import@^2.16.0: version "2.14.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== @@ -3789,84 +3786,54 @@ eslint-plugin-import@2.14.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -eslint-plugin-import@^2.18.2: - version "2.18.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" - integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== +eslint-plugin-jest@^22.4.1: + version "22.17.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.17.0.tgz#dc170ec8369cd1bff9c5dd8589344e3f73c88cf6" + integrity sha512-WT4DP4RoGBhIQjv+5D0FM20fAdAUstfYAf/mkufLNTojsfgzc5/IYW22cIg/Q4QBavAZsROQlqppiWDpFZDS8Q== dependencies: - array-includes "^3.0.3" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.0" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.0" - read-pkg-up "^2.0.0" - resolve "^1.11.0" + "@typescript-eslint/experimental-utils" "^1.13.0" -eslint-plugin-jest@22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.4.1.tgz#a5fd6f7a2a41388d16f527073b778013c5189a9c" - integrity sha512-gcLfn6P2PrFAVx3AobaOzlIEevpAEf9chTpFZz7bYfc7pz8XRv7vuKTIE4hxPKZSha6XWKKplDQ0x9Pq8xX2mg== +eslint-plugin-json@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-1.4.0.tgz#4d29f3a4c08d412df739bd65049ce23636515af8" + integrity sha512-CECvgRAWtUzuepdlPWd+VA7fhyF9HT183pZnl8wQw5x699Mk/MbME/q8xtULBfooi3LUbj6fToieNmsvUcDxWA== + dependencies: + vscode-json-languageservice "^3.2.1" + +eslint-plugin-markdown@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-markdown/-/eslint-plugin-markdown-1.0.0.tgz#2d381b44fcf367f1bb53ae166eccf111cd4e1174" + integrity sha512-YIrClt3yLgyGov+rInjIoC/05zMxb/c6YXQZkyI9UKuBRFLgCrL37cxthj0JYWiTYtiHq0p8O0Nt0/HrvO48iQ== + dependencies: + object-assign "^4.0.1" + remark-parse "^5.0.0" + unified "^6.1.2" -eslint-plugin-prettier@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.2.tgz#71998c60aedfa2141f7bfcbf9d1c459bf98b4fad" - integrity sha512-tGek5clmW5swrAx1mdPYM8oThrBE83ePh7LeseZHBWfHVGrHPhKn7Y5zgRMbU/9D5Td9K4CEmUPjGxA7iw98Og== +eslint-plugin-prettier@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba" + integrity sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA== dependencies: - fast-diff "^1.1.1" - jest-docblock "^21.0.0" + prettier-linter-helpers "^1.0.0" -eslint-plugin-react-hooks@^1.5.1: +eslint-plugin-react-hooks@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== -eslint-plugin-react-hooks@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.0.1.tgz#e898ec26a0a335af6f7b0ad1f0bedda7143ed756" - integrity sha512-xir+3KHKo86AasxlCV8AHRtIZPHljqCRRUYgASkbatmt0fad4+5GgC7zkT7o/06hdKM6MIwp8giHVXqBPaarHQ== - -eslint-plugin-react-native-animation-linter@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-native-animation-linter/-/eslint-plugin-react-native-animation-linter-0.1.2.tgz#07edd97544f5db7e04c640480d3683e99d264ff1" - integrity sha512-BYIzn3/CP95Wm7pMS6+hJjFZpWwFR4qzOwCdGZaAAQqdbGhQWX2GnsaWQwWKq/FKOhZHdQ4cpmEaFcwzoEamqA== - eslint-plugin-react-native-globals@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react-native-globals/-/eslint-plugin-react-native-globals-0.1.2.tgz#ee1348bc2ceb912303ce6bdbd22e2f045ea86ea2" integrity sha512-9aEPf1JEpiTjcFAmmyw8eiIXmcNZOqaZyHO77wgm0/dWfT/oxC1SrIq8ET38pMxHYrcB6Uew+TzUVsBeczF88g== -eslint-plugin-react-native@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-native/-/eslint-plugin-react-native-3.6.0.tgz#7cad3b7c6159df6d26fe3252c6c5417a17f27b4b" - integrity sha512-BEQcHZ06hZSBYWFVuNEq0xuui5VEsWpHDsZGBtfadHfCRqRMUrkYPgdDb3bpc60qShHE83kqIv59uKdinEg91Q== - dependencies: - eslint-plugin-react-native-globals "^0.1.1" - -eslint-plugin-react-native@^3.7.0: +eslint-plugin-react-native@^3.6.0: version "3.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-native/-/eslint-plugin-react-native-3.7.0.tgz#7e2cc1f3cf24919c4c0ea7fac13301e7444e105f" integrity sha512-krLtQmGih/uJDPxF8DBpnU8J3kRUsDm/Dey5yEhOO8LN1I3Wesbk4PGCg8Zah57azKFU+9YtGooFjJcDJWUs+g== dependencies: eslint-plugin-react-native-globals "^0.1.1" -eslint-plugin-react@7.12.4: - version "7.12.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" - integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ== - dependencies: - array-includes "^3.0.3" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.0.1" - object.fromentries "^2.0.0" - prop-types "^15.6.2" - resolve "^1.9.0" - -eslint-plugin-react@^7.14.3: +eslint-plugin-react@^7.12.4: version "7.14.3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== @@ -3881,13 +3848,10 @@ eslint-plugin-react@^7.14.3: prop-types "^15.7.2" resolve "^1.10.1" -eslint-scope@3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== eslint-scope@^4.0.0: version "4.0.3" @@ -3905,7 +3869,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.3.1, eslint-utils@^1.4.2: +eslint-utils@^1.3.1: version "1.4.2" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== @@ -3917,10 +3881,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.1.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" - integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== +eslint@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" + integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -3929,9 +3893,9 @@ eslint@^6.1.0: debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.4.2" - eslint-visitor-keys "^1.1.0" - espree "^6.1.1" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^6.0.0" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -3960,7 +3924,7 @@ eslint@^6.1.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.1: +espree@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== @@ -4240,7 +4204,7 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= -fast-diff@^1.1.1: +fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== @@ -4407,6 +4371,14 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + find-yarn-workspace-root@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" @@ -4627,6 +4599,11 @@ get-port@^2.1.0: dependencies: pinkie-promise "^2.0.0" +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + get-stdin@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" @@ -5066,6 +5043,22 @@ https-proxy-agent@^2.2.1: agent-base "^4.3.0" debug "^3.1.0" +husky@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-2.7.0.tgz#c0a9a6a3b51146224e11bba0b46bba546e461d05" + integrity sha512-LIi8zzT6PyFpcYKdvWRCn/8X+6SuG2TgYYMrM6ckEYhlp44UcEduVymZGIZNLiwOUjrEud+78w/AsAiqJA/kRg== + dependencies: + cosmiconfig "^5.2.0" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^7.0.0" + is-ci "^2.0.0" + pkg-dir "^4.1.0" + please-upgrade-node "^3.1.1" + read-pkg "^5.1.1" + run-node "^1.0.0" + slash "^3.0.0" + i18n-js@^3.0.11: version "3.3.0" resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.3.0.tgz#05512f7184b5117c087ab597be649720a834c068" @@ -5346,7 +5339,7 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-buffer@^1.0.2, is-buffer@^1.1.5: +is-buffer@^1.0.2, is-buffer@^1.1.4, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== @@ -5769,11 +5762,6 @@ jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-docblock@^21.0.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" - integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== - jest-docblock@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" @@ -6181,6 +6169,11 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" +jsonc-parser@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.1.1.tgz#83dc3d7a6e7186346b889b1280eefa04446c6d3e" + integrity sha512-VC0CjnWJylKB1iov4u76/W/5Ef0ydDkjtYWxoZ9t3HdWlSnZQwZL5MgFikaB/EtQ4RmMEw3tmQzuYnZA2/Ja1g== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -6210,7 +6203,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsx-ast-utils@^2.0.1, jsx-ast-utils@^2.1.0: +jsx-ast-utils@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz#4d4973ebf8b9d2837ee91a8208cc66f3a2776cfb" integrity sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ== @@ -6405,6 +6398,11 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -6441,6 +6439,13 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + lodash.clonedeepwith@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" @@ -7398,7 +7403,7 @@ normalize-css-color@^1.0.1: resolved "https://registry.yarnpkg.com/normalize-css-color/-/normalize-css-color-1.0.2.tgz#02991e97cccec6623fe573afbbf0de6a1f3e9f8d" integrity sha1-Apkel8zOxmI/5XOvu/Deah8+n40= -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -7814,7 +7819,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== @@ -7835,6 +7840,13 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" @@ -7936,6 +7948,16 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + parse-ms@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" @@ -8014,6 +8036,11 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -8141,6 +8168,20 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +please-upgrade-node@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + plist@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" @@ -8309,10 +8350,12 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -prettier@1.16.4: - version "1.16.4" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" - integrity sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" prettier@^1.17.1: version "1.18.2" @@ -9082,6 +9125,16 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" +read-pkg@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, readable-stream@^1.0.33: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -9295,6 +9348,27 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" +remark-parse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95" + integrity sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA== + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.1.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + remark-parse@^6.0.0: version "6.0.3" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" @@ -9459,7 +9533,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7, resolve@1.8.1, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1, resolve@^1.9.0: +resolve@1.1.7, resolve@1.8.1, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== @@ -9558,6 +9632,11 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + run-parallel@^1.1.2: version "1.1.9" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" @@ -9676,6 +9755,11 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -10801,6 +10885,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + type-fest@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" @@ -10873,6 +10962,18 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== +unified@^6.1.2: + version "6.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-6.2.0.tgz#7fbd630f719126d67d40c644b7e3f617035f6dba" + integrity sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^1.1.0" + trough "^1.0.0" + vfile "^2.0.0" + x-is-string "^0.1.0" + unified@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" @@ -11119,6 +11220,16 @@ vfile-message@^1.0.0: dependencies: unist-util-stringify-position "^1.1.1" +vfile@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a" + integrity sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w== + dependencies: + is-buffer "^1.1.4" + replace-ext "1.0.0" + unist-util-stringify-position "^1.0.0" + vfile-message "^1.0.0" + vfile@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" @@ -11141,6 +11252,31 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" +vscode-json-languageservice@^3.2.1: + version "3.3.4" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.4.tgz#4ff67580491d3a5dc469f4a78643f20adff0278d" + integrity sha512-/nuI4uDBfxyVyeGtBdYwP/tIaXYKOoymUOSozYKLzsmrDmu555gZpzc11LrARa96z92wSaa5hfjTtNMAoM2mxw== + dependencies: + jsonc-parser "^2.1.1" + vscode-languageserver-types "^3.15.0-next.2" + vscode-nls "^4.1.1" + vscode-uri "^2.0.3" + +vscode-languageserver-types@^3.15.0-next.2: + version "3.15.0-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.5.tgz#863d711bf47b338ff5e63ae19fb20d4fcd4d713b" + integrity sha512-7hrELhTeWieUgex3+6692KjCkcmO/+V/bFItM5MHGcBotzwmjEuXjapLLYTYhIspuJ1ibRSik5MhX5YwLpsPiw== + +vscode-nls@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" + integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== + +vscode-uri@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543" + integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw== + w3c-hr-time@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" From f2a51bff87f534ddbc202aaa60c24d96be38ddd1 Mon Sep 17 00:00:00 2001 From: osdnk Date: Sat, 28 Sep 2019 08:58:55 +0200 Subject: [PATCH 344/636] Add .eslintrc.json --- .eslintrc.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000000..950715436a3 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "extends": "satya164", + "settings": { + "react": { "version": "16" } + }, + "rules": { + "sort-keys": ["error", "asc", {"caseSensitive": false, "natural": false}], + "jest/no-truthy-falsy": 0, + "react-native/no-inline-styles": 0, + "import/named": 0, + "react/display-name": 2, + "jest/no-test-prefixes": 0, //TODO + "jest/no-disabled-tests": 0 //TODO + }, + "env": { "browser": true, "node": true } +} From 8dbc48cc95181b9dfcf4e9dde2bf97367a3432bf Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 11 Sep 2019 00:56:45 -0400 Subject: [PATCH 345/636] setup for approval states; optimize parsers --- .../coin-row/TransactionStatusBadge.js | 10 +- .../exchange/ConfirmExchangeButton.js | 46 ++-- src/handlers/localstorage/common.js | 5 +- src/handlers/uniswap.js | 15 +- src/helpers/sortList.js | 11 +- src/helpers/transactionStatusTypes.js | 1 + src/helpers/transactions.js | 47 +---- src/hoc/withUniswapAllowances.js | 25 ++- src/parsers/accounts.js | 31 ++- src/parsers/transactions.js | 119 +++++++++-- src/parsers/uniqueTokens.js | 23 +- src/redux/data.js | 136 ++---------- src/redux/explorer.js | 9 +- src/redux/uniqueTokens.js | 8 +- src/redux/uniswap.js | 198 +++++++++++++----- src/screens/ExchangeModal.js | 61 ++++-- src/screens/SendSheet.js | 3 +- src/styles/colors.js | 3 +- src/utils/contract.js | 7 +- src/utils/ethereumUtils.js | 9 +- src/utils/isLowerCaseMatch.js | 6 +- src/utils/search.js | 10 +- 22 files changed, 451 insertions(+), 332 deletions(-) diff --git a/src/components/coin-row/TransactionStatusBadge.js b/src/components/coin-row/TransactionStatusBadge.js index 2ded99d3ee8..404b3e3b806 100644 --- a/src/components/coin-row/TransactionStatusBadge.js +++ b/src/components/coin-row/TransactionStatusBadge.js @@ -12,18 +12,18 @@ import { RowWithMargins } from '../layout'; import { Text } from '../text'; const StatusProps = { - failed: { + [TransactionStatusTypes.failed]: { name: 'closeCircled', style: position.maxSizeAsObject(12), }, - received: { + [TransactionStatusTypes.received]: { direction: 'down', name: 'arrow', }, - self: { + [TransactionStatusTypes.self]: { name: 'dot', }, - sent: { + [TransactionStatusTypes.sent]: { name: 'sendSmall', }, }; @@ -49,7 +49,7 @@ const TransactionStatusBadge = ({ pending, status, ...props }) => { /> )} - {upperFirst(status || 'Unknown status')} + {upperFirst(status)} ); diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 43ad4d823bf..fe01a35315e 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -7,21 +7,32 @@ import { Centered, RowWithMargins } from '../layout'; import { Text } from '../text'; import { SlippageWarningTheshold } from './SlippageWarning'; -const UnlockingSpinner = () => { - // lol this isnt done - return ( - - - - - Unlocking - - - - {`~ 12s Remaining`} +// lol this isnt done +const UnlockingSpinner = ({ timeRemaining, ...props }) => ( + + + + + Unlocking - - ); + + + {`~ ${timeRemaining} Remaining`} + + +); + +UnlockingSpinner.propTypes = { + timeRemaining: PropTypes.string, }; const ConfirmExchangeButton = ({ @@ -33,6 +44,7 @@ const ConfirmExchangeButton = ({ onSubmit, onUnlockAsset, slippage, + timeRemaining, ...props }) => { let label = 'Hold to Swap'; @@ -63,7 +75,10 @@ const ConfirmExchangeButton = ({ theme="dark" {...props} > - {isUnlockingAsset ? : undefined} + {isUnlockingAsset + ? + : undefined + } ); }; @@ -77,6 +92,7 @@ ConfirmExchangeButton.propTypes = { onSubmit: PropTypes.func, onUnlockAsset: PropTypes.func, slippage: PropTypes.number, + timeRemaining: PropTypes.string, }; export default ConfirmExchangeButton; diff --git a/src/handlers/localstorage/common.js b/src/handlers/localstorage/common.js index 9de7c92d5eb..20f8da84c96 100644 --- a/src/handlers/localstorage/common.js +++ b/src/handlers/localstorage/common.js @@ -1,8 +1,9 @@ -/* eslint-disable no-undef */ +import { toLower } from 'lodash'; + const defaultVersion = '0.1.0'; export const getKey = (prefix, accountAddress, network) => - `${prefix}-${accountAddress.toLowerCase()}-${network.toLowerCase()}`; + `${prefix}-${toLower(accountAddress)}-${toLower(network)}`; /** * @desc save to storage diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index cebba7b4aae..b1ce33cd194 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -1,7 +1,15 @@ import { getExecutionDetails, getTokenReserves } from '@uniswap/sdk'; import contractMap from 'eth-contract-metadata'; import { ethers } from 'ethers'; -import { compact, get, keyBy, map, slice, zipObject } from 'lodash'; +import { + compact, + get, + keyBy, + map, + slice, + toLower, + zipObject, +} from 'lodash'; import { convertRawAmountToDecimalFormat, divide, @@ -32,10 +40,7 @@ export const getReserves = async () => { const reserves = await promiseUtils.PromiseAllWithFails( map(uniswapTokens, token => getTokenReserves(token)) ); - return keyBy(compact(reserves), reserve => { - const address = get(reserve, 'token.address') || ''; - return address.toLowerCase(); - }); + return keyBy(compact(reserves), reserve => toLower(get(reserve, 'token.address'))); }; const getGasLimit = (exchange, methodName, updatedMethodArgs, value) => { diff --git a/src/helpers/sortList.js b/src/helpers/sortList.js index bf40ead5846..210a5fc9ff1 100644 --- a/src/helpers/sortList.js +++ b/src/helpers/sortList.js @@ -1,4 +1,9 @@ -import { get, isFunction, isString } from 'lodash'; +import { + get, + isFunction, + isString, + toLower, +} from 'lodash'; export const sortList = ( array = [], @@ -24,8 +29,8 @@ export const sortList = ( } if (isString(itemA) && isString(itemB)) { - itemA = itemA.toLowerCase(); - itemB = itemB.toLowerCase(); + itemA = toLower(itemA); + itemB = toLower(itemB); } if (itemA < itemB) return isAscending ? -1 : 1; diff --git a/src/helpers/transactionStatusTypes.js b/src/helpers/transactionStatusTypes.js index 07e5e9db2cf..f9164f3afea 100644 --- a/src/helpers/transactionStatusTypes.js +++ b/src/helpers/transactionStatusTypes.js @@ -5,4 +5,5 @@ export default { self: 'self', sending: 'sending', sent: 'sent', + unknown: 'unknown status', }; diff --git a/src/helpers/transactions.js b/src/helpers/transactions.js index 4a765a17e91..f266d241197 100644 --- a/src/helpers/transactions.js +++ b/src/helpers/transactions.js @@ -7,40 +7,14 @@ import { } from 'date-fns'; import { get, groupBy, isEmpty } from 'lodash'; import { createSelector } from 'reselect'; -import TransactionStatusTypes from './transactionStatusTypes'; -import { isLowerCaseMatch } from '../utils'; const accountAddressSelector = state => state.accountAddress; -const nativeCurrencySelector = state => state.nativeCurrency; const requestsSelector = state => state.requests; const transactionsSelector = state => state.transactions; export const buildTransactionUniqueIdentifier = ({ hash, displayDetails }) => hash || get(displayDetails, 'timestampInMs'); -export const getTransactionStatus = ({ - accountAddress, - from, - pending, - status, - to, -}) => { - const isFromAccount = isLowerCaseMatch(from, accountAddress); - const isToAccount = isLowerCaseMatch(to, accountAddress); - - if (pending && isFromAccount) return TransactionStatusTypes.sending; - if (pending && isToAccount) return TransactionStatusTypes.receiving; - - if (status === 'failed') return TransactionStatusTypes.failed; - - if (isFromAccount && isToAccount) return TransactionStatusTypes.self; - - if (isFromAccount) return TransactionStatusTypes.sent; - if (isToAccount) return TransactionStatusTypes.received; - - return undefined; -}; - const groupTransactionByDate = ({ pending, mined_at: time }) => { if (pending) return 'Pending'; @@ -53,33 +27,15 @@ const groupTransactionByDate = ({ pending, mined_at: time }) => { return format(timestamp, `MMMM${isThisYear(timestamp) ? '' : ' YYYY'}`); }; -const normalizeTransactions = ({ accountAddress, transactions }) => - transactions.map(({ asset, ...tx }) => ({ - ...tx, - name: get(asset, 'name', ''), - status: getTransactionStatus({ accountAddress, ...tx }), - symbol: get(asset, 'symbol', ''), - })); - const buildTransactionsSections = ( accountAddress, - nativeCurrency, requests, transactions ) => { let sectionedTransactions = []; if (!isEmpty(transactions)) { - const normalizedTransactions = normalizeTransactions({ - accountAddress, - nativeCurrency, - transactions, - }); - - const transactionsByDate = groupBy( - normalizedTransactions, - groupTransactionByDate - ); + const transactionsByDate = groupBy(transactions, groupTransactionByDate); sectionedTransactions = Object.keys(transactionsByDate).map(section => ({ data: transactionsByDate[section], @@ -105,7 +61,6 @@ const buildTransactionsSections = ( export const buildTransactionsSectionsSelector = createSelector( [ accountAddressSelector, - nativeCurrencySelector, requestsSelector, transactionsSelector, ], diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 4a04bfe3d95..cce1986889f 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -2,18 +2,25 @@ import { connect } from 'react-redux'; import { uniswapGetTokenReserve, uniswapUpdateAllowances, + uniswapUpdatePendingApprovals, } from '../redux/uniswap'; -const mapStateToProps = ({ uniswap: { allowances, tokenReserves } }) => ({ +const mapStateToProps = ({ + uniswap: { + allowances, + pendingApprovals, + tokenReserves, + }, +}) => ({ allowances, + pendingApprovals, tokenReserves, }); -export default Component => - connect( - mapStateToProps, - { - uniswapGetTokenReserve, - uniswapUpdateAllowances, - } - )(Component); +export default Component => ( + connect(mapStateToProps, { + uniswapGetTokenReserve, + uniswapUpdateAllowances, + uniswapUpdatePendingApprovals, + })(Component) +); diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index a35327e4fe8..6138e312bc8 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -1,27 +1,26 @@ -import { get } from 'lodash'; +import { get, toUpper } from 'lodash'; import { convertRawAmountToBalance } from '../helpers/utilities'; import { loweredTokenOverrides } from '../references'; +import { dedupeUniqueTokens } from './uniqueTokens'; /** * @desc parse account assets * @param {Object} [data] * @return {Array} */ -export const parseAccountAssets = data => { - try { - let assets = [...data]; - assets = assets.map(assetData => { - const asset = parseAsset(assetData.asset); - return { - ...asset, - balance: convertRawAmountToBalance(assetData.quantity, asset), - }; - }); +export const parseAccountAssets = (data, uniqueTokens) => { + const dedupedAssets = dedupeUniqueTokens(data, uniqueTokens); + let assets = dedupedAssets.map(assetData => { + const asset = parseAsset(assetData.asset); + return { + ...asset, + balance: convertRawAmountToBalance(assetData.quantity, asset), + }; + }); - return assets.filter(asset => !!Number(get(asset, 'balance.amount'))); - } catch (error) { - throw error; - } + return assets.filter( + asset => !!Number(get(asset, 'balance.amount')), + ); }; /** @@ -38,7 +37,7 @@ export const parseAsset = assetData => { decimals: get(assetData, 'decimals'), name, price: get(assetData, 'price'), - symbol: symbol.toUpperCase(), + symbol: toUpper(symbol), uniqueId: address || name, ...loweredTokenOverrides[address], }; diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index 6ef8475018b..0cd6790d248 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -1,15 +1,57 @@ -import { flatten, get, isEmpty, pick, reverse } from 'lodash'; +import { + concat, + filter, + find, + findIndex, + flatten, + get, + isEmpty, + partition, + pick, + reverse, + slice, + startsWith, + toLower, + toUpper, + uniqBy, +} from 'lodash'; +import TransactionStatusTypes from '../helpers/transactionStatusTypes'; import { convertRawAmountToBalance, convertRawAmountToNativeDisplay, } from '../helpers/utilities'; +import { isLowerCaseMatch } from '../utils'; -export const parseTransactions = (data, nativeCurrency) => { - const allTxns = data.map(txn => parseTransaction(txn, nativeCurrency)); - return flatten(allTxns); +const dataFromLastTxHash = (transactionData, transactions) => { + const lastSuccessfulTxn = find(transactions, (txn) => txn.hash && !txn.pending); + const lastTxHash = lastSuccessfulTxn ? lastSuccessfulTxn.hash : ''; + if (lastTxHash) { + const lastTxnHashIndex = findIndex(transactionData, (txn) => lastTxHash.startsWith(txn.hash)); + if (lastTxnHashIndex > -1) { + return slice(transactionData, 0, lastTxnHashIndex); + } + } + return transactionData; }; -const parseTransaction = (txn, nativeCurrency) => { +export default ( + transactionData, + accountAddress, + nativeCurrency, + existingTransactions, + appended = false, +) => { + const data = appended ? dataFromLastTxHash(transactionData, existingTransactions) : transactionData; + const parsedNewTransactions = flatten(data.map(txn => parseTransaction(txn, accountAddress, nativeCurrency))); + const [pendingTransactions, remainingTransactions] = partition(existingTransactions, (txn) => txn.pending); + const [approvalTransactions, parsedTransactions] = partition(parsedNewTransactions, txn => txn.type === 'authorize'); + const updatedPendingTransactions = dedupePendingTransactions(pendingTransactions, parsedTransactions); + const updatedResults = concat(updatedPendingTransactions, parsedTransactions, remainingTransactions); + const dedupedResults = uniqBy(updatedResults, (txn) => txn.hash); + return { approvalTransactions, dedupedResults }; +}; + +const parseTransaction = (txn, accountAddress, nativeCurrency) => { const transaction = pick(txn, [ 'hash', 'mined_at', @@ -23,13 +65,20 @@ const parseTransaction = (txn, nativeCurrency) => { transaction.to = txn.address_to; const changes = get(txn, 'changes', []); let internalTransactions = changes; - if ( - changes.length === 2 && - get(changes, '[0].asset.asset_code') === - get(changes, '[1].asset.asset_code') - ) { + if (isEmpty(changes) && txn.type === 'authorize') { + const assetInternalTransaction = { + address_from: transaction.from, // eslint-disable-line camelcase + address_to: transaction.to, // eslint-disable-line camelcase + asset: get(txn, 'meta.asset'), + spender: get(txn, 'meta.spender'), + }; + internalTransactions = [assetInternalTransaction]; + } + // logic below: prevent sending yourself money to be seen as a trade + if (changes.length === 2 && get(changes, '[0].asset.asset_code') === get(changes, '[1].asset.asset_code')) { internalTransactions = [changes[0]]; } + // logic below: prevent sending a WalletConnect 0 amount to be seen as a Cancel if (isEmpty(internalTransactions) && transaction.type === 'cancel') { const ethInternalTransaction = { address_from: transaction.from, @@ -48,7 +97,7 @@ const parseTransaction = (txn, nativeCurrency) => { const symbol = get(internalTxn, 'asset.symbol') || ''; const updatedAsset = { ...internalTxn.asset, - symbol: symbol.toUpperCase(), + symbol: toUpper(symbol), }; const priceUnit = internalTxn.price || 0; const nativeDisplay = convertRawAmountToNativeDisplay( @@ -58,15 +107,61 @@ const parseTransaction = (txn, nativeCurrency) => { nativeCurrency ); + const status = getTransactionLabel( + accountAddress, + internalTxn.address_from, + transaction.pending, + transaction.status, + internalTxn.address_to, + ); + return { ...transaction, - asset: updatedAsset, balance: convertRawAmountToBalance(internalTxn.value, updatedAsset), from: internalTxn.address_from, hash: `${transaction.hash}-${index}`, + name: get(updatedAsset, 'name', ''), native: nativeDisplay, + status, + symbol: get(updatedAsset, 'symbol', ''), to: internalTxn.address_to, }; }); return reverse(internalTransactions); }; + +const dedupePendingTransactions = (pendingTransactions, parsedTransactions) => { + let updatedPendingTransactions = pendingTransactions; + if (pendingTransactions.length) { + updatedPendingTransactions = filter(updatedPendingTransactions, (pendingTxn) => { + const matchingElement = find(parsedTransactions, (txn) => txn.hash + && (startsWith(toLower(txn.hash), toLower(pendingTxn.hash)) + || (txn.nonce && (txn.nonce >= pendingTxn.nonce)))); + return !matchingElement; + }); + } + return updatedPendingTransactions; +}; + +const getTransactionLabel = ( + accountAddress, + from, + pending, + status, + to, +) => { + const isFromAccount = isLowerCaseMatch(from, accountAddress); + const isToAccount = isLowerCaseMatch(to, accountAddress); + + if (pending && isFromAccount) return TransactionStatusTypes.sending; + if (pending && isToAccount) return TransactionStatusTypes.receiving; + + if (status === 'failed') return TransactionStatusTypes.failed; + + if (isFromAccount && isToAccount) return TransactionStatusTypes.self; + + if (isFromAccount) return TransactionStatusTypes.sent; + if (isToAccount) return TransactionStatusTypes.received; + + return TransactionStatusTypes.unknown; +}; diff --git a/src/parsers/uniqueTokens.js b/src/parsers/uniqueTokens.js index 7b6003c849a..02241c17587 100644 --- a/src/parsers/uniqueTokens.js +++ b/src/parsers/uniqueTokens.js @@ -1,4 +1,11 @@ -import { filter, get, map, pick, uniq } from 'lodash'; +import { + filter, + find, + get, + map, + pick, + uniq, +} from 'lodash'; /** * @desc parse unique tokens from opensea @@ -56,3 +63,17 @@ export const parseAccountUniqueTokens = data => { export const getFamilies = uniqueTokens => uniq(map(uniqueTokens, u => get(u, 'asset_contract.address', ''))); + +export const dedupeUniqueTokens = (assets, uniqueTokens) => { + const uniqueTokenFamilies = getFamilies(uniqueTokens); + let updatedAssets = assets; + if (assets.length) { + updatedAssets = filter(updatedAssets, (asset) => { + const matchingElement = find(uniqueTokenFamilies, (uniqueTokenFamily) => uniqueTokenFamily === get(asset, 'asset.asset_code')); + return !matchingElement; + }); + } + return updatedAssets; +}; + +export const dedupeAssetsWithFamilies = (assets, families) => filter(assets, (asset) => !find(families, (family) => family === get(asset, 'address'))); diff --git a/src/redux/data.js b/src/redux/data.js index 6cdc8ef767e..399b00cf9a3 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -1,15 +1,10 @@ import { concat, - filter, - find, - findIndex, get, includes, isNil, map, - partition, remove, - slice, uniqBy, } from 'lodash'; import { @@ -22,11 +17,11 @@ import { } from '../handlers/localstorage/storage'; import { parseAccountAssets, parseAsset } from '../parsers/accounts'; import { parseNewTransaction } from '../parsers/newTransaction'; -import { parseTransactions } from '../parsers/transactions'; -import { getFamilies } from '../parsers/uniqueTokens'; +import parseTransactions from '../parsers/transactions'; import { isLowerCaseMatch } from '../utils'; import { uniswapAddLiquidityTokens, + uniswapRemovePendingApproval, uniswapUpdateAssetPrice, uniswapUpdateAssets, uniswapUpdateLiquidityTokens, @@ -82,62 +77,17 @@ export const dataClearState = () => (dispatch, getState) => { dispatch({ type: DATA_CLEAR_STATE }); }; -const dedupePendingTransactions = (pendingTransactions, parsedTransactions) => { - let updatedPendingTransactions = pendingTransactions; - if (pendingTransactions.length) { - updatedPendingTransactions = filter( - updatedPendingTransactions, - pendingTxn => { - const matchingElement = find( - parsedTransactions, - txn => - txn.hash && - (txn.hash.toLowerCase().startsWith(pendingTxn.hash.toLowerCase()) || - (txn.nonce && txn.nonce >= pendingTxn.nonce)) - ); - return !matchingElement; - } - ); - } - return updatedPendingTransactions; -}; - -export const dedupeAssetsWithFamilies = families => (dispatch, getState) => { +export const dataUpdateAssets = (assets) => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - const { assets } = getState().data; if (assets.length) { - const dedupedAssets = filter(assets, asset => { - const matchingElement = find( - families, - family => family === get(asset, 'address') - ); - return !matchingElement; - }); - saveAssets(accountAddress, dedupedAssets, network); + saveAssets(accountAddress, assets, network); dispatch({ - payload: dedupedAssets, + payload: assets, type: DATA_UPDATE_ASSETS, }); } }; -const dedupeUniqueTokens = assets => (dispatch, getState) => { - const { uniqueTokens } = getState().uniqueTokens; - const uniqueTokenFamilies = getFamilies(uniqueTokens); - let updatedAssets = assets; - if (assets.length) { - updatedAssets = filter(updatedAssets, asset => { - const matchingElement = find( - uniqueTokenFamilies, - uniqueTokenFamily => - uniqueTokenFamily === get(asset, 'asset.asset_code') - ); - return !matchingElement; - }); - } - return updatedAssets; -}; - const checkMeta = message => (dispatch, getState) => { const { accountAddress, nativeCurrency } = getState().settings; const address = get(message, 'meta.address'); @@ -148,44 +98,23 @@ const checkMeta = message => (dispatch, getState) => { ); }; -export const transactionsReceived = message => (dispatch, getState) => { +export const transactionsReceived = (message, appended = false) => (dispatch, getState) => { + console.log('txns received', message); const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; - - let transactionData = get(message, 'payload.transactions', []); + const transactionData = get(message, 'payload.transactions', []); if (!transactionData.length) return; - const { accountAddress, nativeCurrency, network } = getState().settings; const { transactions } = getState().data; - - const lastSuccessfulTxn = find(transactions, txn => txn.hash && !txn.pending); - const lastTxHash = lastSuccessfulTxn ? lastSuccessfulTxn.hash : ''; - if (lastTxHash) { - const lastTxnHashIndex = findIndex(transactionData, txn => - lastTxHash.startsWith(txn.hash) - ); - if (lastTxnHashIndex > -1) { - transactionData = slice(transactionData, 0, lastTxnHashIndex); - } - } if (!transactionData.length) return; - - const parsedTransactions = parseTransactions(transactionData, nativeCurrency); - const partitions = partition(transactions, txn => txn.pending); - const pendingTransactions = partitions[0]; - const remainingTransactions = partitions[1]; - - const updatedPendingTransactions = dedupePendingTransactions( - pendingTransactions, - parsedTransactions + const { approvalTransactions, dedupedResults } = parseTransactions( + transactionData, + accountAddress, + nativeCurrency, + transactions, + appended, ); - const updatedResults = concat( - updatedPendingTransactions, - parsedTransactions, - remainingTransactions - ); - const dedupedResults = uniqBy(updatedResults, txn => txn.hash); - + dispatch(uniswapRemovePendingApproval(approvalTransactions)); saveLocalTransactions(accountAddress, dedupedResults, network); dispatch({ payload: dedupedResults, @@ -193,37 +122,6 @@ export const transactionsReceived = message => (dispatch, getState) => { }); }; -export const transactionsAppended = message => (dispatch, getState) => { - const isValidMeta = dispatch(checkMeta(message)); - if (!isValidMeta) return; - - const transactionData = get(message, 'payload.transactions', []); - if (!transactionData.length) return; - const { accountAddress, nativeCurrency, network } = getState().settings; - const { transactions } = getState().data; - const partitions = partition(transactions, txn => txn.pending); - const pendingTransactions = partitions[0]; - const remainingTransactions = partitions[1]; - - const parsedTransactions = parseTransactions(transactionData, nativeCurrency); - const updatedPendingTransactions = dedupePendingTransactions( - pendingTransactions, - parsedTransactions - ); - const updatedResults = concat( - updatedPendingTransactions, - parsedTransactions, - remainingTransactions - ); - const dedupedResults = uniqBy(updatedResults, txn => txn.hash); - - saveLocalTransactions(accountAddress, updatedResults, network); - dispatch({ - payload: dedupedResults, - type: DATA_UPDATE_TRANSACTIONS, - }); -}; - export const transactionsRemoved = message => (dispatch, getState) => { const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; @@ -251,6 +149,7 @@ export const addressAssetsReceived = ( if (!isValidMeta) return; const { accountAddress, network } = getState().settings; + const { uniqueTokens } = getState().uniqueTokens; const assets = get(message, 'payload.assets', []); const liquidityTokens = remove(assets, asset => { const symbol = get(asset, 'asset.symbol', ''); @@ -262,8 +161,7 @@ export const addressAssetsReceived = ( if (!append && !change) { dispatch(uniswapUpdateLiquidityTokens(liquidityTokens)); } - const updatedAssets = dispatch(dedupeUniqueTokens(assets)); - let parsedAssets = parseAccountAssets(updatedAssets); + let parsedAssets = parseAccountAssets(assets, uniqueTokens); if (append || change) { const { assets: existingAssets } = getState().data; parsedAssets = uniqBy( diff --git a/src/redux/explorer.js b/src/redux/explorer.js index ccd0f305ba6..cea477d65c4 100644 --- a/src/redux/explorer.js +++ b/src/redux/explorer.js @@ -1,4 +1,4 @@ -import { isNil } from 'lodash'; +import { isNil, toLower } from 'lodash'; import { DATA_API_KEY, DATA_ORIGIN } from 'react-native-dotenv'; import io from 'socket.io-client'; import { uniswapAssetAddresses } from '../references'; @@ -6,7 +6,6 @@ import { addressAssetsReceived, assetsReceived, priceChanged, - transactionsAppended, transactionsReceived, transactionsRemoved, } from './data'; @@ -50,7 +49,7 @@ const addressSubscription = (address, currency, action = 'subscribe') => [ { payload: { address, - currency: currency.toLowerCase(), + currency: toLower(currency), transactions_limit: 1000, }, scope: ['assets', 'transactions'], @@ -62,7 +61,7 @@ const assetsSubscription = (assetCodes, currency, action = 'subscribe') => [ { payload: { asset_codes: assetCodes, - currency: currency.toLowerCase(), + currency: toLower(currency), }, }, ]; @@ -129,7 +128,7 @@ const listenOnAddressMessages = socket => dispatch => { }); socket.on(messages.ADDRESS_TRANSACTIONS.APPENDED, message => { - dispatch(transactionsAppended(message)); + dispatch(transactionsReceived(message, true)); }); socket.on(messages.ADDRESS_TRANSACTIONS.REMOVED, message => { diff --git a/src/redux/uniqueTokens.js b/src/redux/uniqueTokens.js index 64866e8d11f..e3d415cba33 100644 --- a/src/redux/uniqueTokens.js +++ b/src/redux/uniqueTokens.js @@ -5,8 +5,8 @@ import { saveUniqueTokens, removeUniqueTokens, } from '../handlers/localstorage/storage'; -import { dedupeAssetsWithFamilies } from './data'; -import { getFamilies } from '../parsers/uniqueTokens'; +import { dedupeAssetsWithFamilies, getFamilies } from '../parsers/uniqueTokens'; +import { dataUpdateAssets } from './data'; // -- Constants ------------------------------------------------------------- // const UNIQUE_TOKENS_LOAD_UNIQUE_TOKENS_REQUEST = @@ -55,6 +55,7 @@ export const uniqueTokensRefreshState = () => (dispatch, getState) => new Promise((fetchResolve, fetchReject) => { dispatch({ type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_REQUEST }); const { accountAddress, network } = getState().settings; + const { assets } = getState().data; const { uniqueTokens: existingUniqueTokens } = getState().uniqueTokens; apiGetAccountUniqueTokens(accountAddress) .then(uniqueTokens => { @@ -62,7 +63,8 @@ export const uniqueTokensRefreshState = () => (dispatch, getState) => const newFamilies = getFamilies(uniqueTokens); const incomingFamilies = without(newFamilies, ...existingFamilies); if (incomingFamilies.length) { - dispatch(dedupeAssetsWithFamilies(incomingFamilies)); + const dedupedAssets = dedupeAssetsWithFamilies(assets, incomingFamilies); + dispatch(dataUpdateAssets(dedupedAssets)); } saveUniqueTokens(accountAddress, uniqueTokens, network); dispatch({ diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 6ab37519dcf..001246fb4ce 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -1,12 +1,32 @@ import produce from 'immer'; -import { concat, forEach, get, isEmpty, keyBy, map, toLower } from 'lodash'; +import { + compact, + concat, + forEach, + fromPairs, + get, + invert, + isEmpty, + keyBy, + map, + omit, + reject, + toLower, + zip, +} from 'lodash'; import { getAccountLocal, removeAccountLocal, saveAccountLocal, } from '../handlers/localstorage/common'; -import { getLiquidityInfo, getReserve, getReserves } from '../handlers/uniswap'; +import { + getLiquidityInfo, + getReserve, + getReserves, +} from '../handlers/uniswap'; +import TransactionStatusTypes from '../helpers/transactionStatusTypes'; import { uniswapAssetsClean } from '../references'; +import { contractUtils, promiseUtils } from '../utils'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -24,6 +44,7 @@ const UNISWAP_GET_TOKEN_RESERVES_SUCCESS = const UNISWAP_GET_TOKEN_RESERVES_FAILURE = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_FAILURE'; +const UNISWAP_UPDATE_PENDING_APPROVALS = 'uniswap/UNISWAP_UPDATE_PENDING_APPROVALS'; const UNISWAP_UPDATE_ASSETS = 'uniswap/UNISWAP_UPDATE_ASSETS'; const UNISWAP_UPDATE_ALLOWANCES = 'uniswap/UNISWAP_UPDATE_ALLOWANCES'; const UNISWAP_UPDATE_LIQUIDITY_TOKENS = @@ -34,6 +55,7 @@ const UNISWAP_CLEAR_STATE = 'uniswap/UNISWAP_CLEAR_STATE'; export const ALLOWANCES = 'uniswapallowances'; export const LIQUIDITY = 'uniswapliquidity'; export const LIQUIDITY_INFO = 'uniswap'; +export const PENDING_APPROVALS = 'uniswappendingapprovals'; export const RESERVES = 'uniswapreserves'; export const ASSETS = 'uniswapassets'; @@ -73,10 +95,17 @@ export const uniswapLoadState = () => async (dispatch, getState) => { network, {} ); + const pendingApprovals = await getAccountLocal( + PENDING_APPROVALS, + accountAddress, + network, + {}, + ); dispatch({ payload: { allowances, liquidityTokens, + pendingApprovals, tokenReserves, uniswap, uniswapAssets, @@ -89,7 +118,7 @@ export const uniswapLoadState = () => async (dispatch, getState) => { }; export const uniswapGetTokenReserve = tokenAddress => (dispatch, getState) => - new Promise((resolve, reject) => { + new Promise((resolve, promiseReject) => { tokenAddress = toLower(tokenAddress); dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_REQUEST }); const { accountAddress, network } = getState().settings; @@ -114,12 +143,12 @@ export const uniswapGetTokenReserve = tokenAddress => (dispatch, getState) => }) .catch(error => { dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_FAILURE }); - reject(error); + promiseReject(error); }); }); export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => - new Promise((resolve, reject) => { + new Promise((resolve, promiseReject) => { const fetchTokenReserves = () => new Promise((fetchResolve, fetchReject) => { dispatch({ type: UNISWAP_GET_TOKEN_RESERVES_REQUEST }); @@ -148,25 +177,79 @@ export const uniswapTokenReservesRefreshState = () => (dispatch, getState) => .catch(error => { clearInterval(getTokenReservesInterval); getTokenReservesInterval = setInterval(fetchTokenReserves, 15000); // 15 secs - reject(error); + promiseReject(error); }); }); export const uniswapClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - const storageKeys = [ASSETS, ALLOWANCES, LIQUIDITY_INFO, LIQUIDITY, RESERVES]; + const storageKeys = [ + ASSETS, + ALLOWANCES, + LIQUIDITY_INFO, + LIQUIDITY, + PENDING_APPROVALS, + RESERVES, + ]; forEach(storageKeys, key => removeAccountLocal(key, accountAddress, network)); clearInterval(getTokenReservesInterval); dispatch({ type: UNISWAP_CLEAR_STATE }); }; -export const uniswapUpdateAllowances = (tokenAddress, allowance) => ( - dispatch, - getState -) => { +export const uniswapUpdatePendingApprovals = (tokenAddress, txHash) => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + const { pendingApprovals } = getState().uniswap; + const updatedPendingApprovals = { ...pendingApprovals, [toLower(tokenAddress)]: toLower(txHash) }; + dispatch({ + payload: updatedPendingApprovals, + type: UNISWAP_UPDATE_PENDING_APPROVALS, + }); + saveAccountLocal(PENDING_APPROVALS, updatedPendingApprovals, accountAddress, network); +}; + + +const updateAllowancesForSuccessfulTransactions = (assetAddresses) => (dispatch, getState) => { + const { accountAddress } = getState().settings; + promiseUtils.PromiseAllWithFails(map(assetAddresses, async (assetAddress) => { + const asset = uniswapAssetsRawLoweredKeys[assetAddress]; + return contractUtils.getAllowance( + accountAddress, + asset, + asset.exchangeAddress, + ); + })).then(allowances => { + const tokenAddressAllowances = fromPairs(zip(assetAddresses, allowances)); + console.log('token address allowances', tokenAddressAllowances); + dispatch(uniswapUpdateAllowances(tokenAddressAllowances)); + }).catch(error => { + // TODO error handling + }); +}; + +export const uniswapRemovePendingApproval = (newTransactions) => (dispatch, getState) => { + const { pendingApprovals } = getState().uniswap; + const loweredTxHashes = map(newTransactions, txn => toLower(txn.hash)); + const invertedPendingApprovals = invert(pendingApprovals); + const updatedAddresses = compact(map(loweredTxHashes, hash => invertedPendingApprovals[hash])); + const updatedPendingApprovals = omit(pendingApprovals, ...updatedAddresses); + dispatch({ + payload: updatedPendingApprovals, + type: UNISWAP_UPDATE_PENDING_APPROVALS, + }); + const successfulApprovalHashes = map(reject(newTransactions, txn => txn.status === TransactionStatusTypes.failed), txn => toLower(txn.hash)); + const successfullyApprovedAddresses = compact(map(successfulApprovalHashes, hash => invertedPendingApprovals[hash])); + dispatch(updateAllowancesForSuccessfulTransactions(successfullyApprovedAddresses)); + const { accountAddress, network } = getState().settings; + saveAccountLocal(PENDING_APPROVALS, updatedPendingApprovals, accountAddress, network); +}; + +export const uniswapUpdateAllowances = (tokenAddressAllowances) => (dispatch, getState) => { const { accountAddress, network } = getState().settings; const { allowances } = getState().uniswap; - const updatedAllowances = { ...allowances, [tokenAddress]: allowance }; + const updatedAllowances = { + ...allowances, + ...tokenAddressAllowances, + }; dispatch({ payload: updatedAllowances, type: UNISWAP_UPDATE_ALLOWANCES, @@ -246,7 +329,7 @@ export const uniswapAddLiquidityTokens = newLiquidityTokens => ( }; export const uniswapUpdateState = () => (dispatch, getState) => - new Promise((resolve, reject) => { + new Promise((resolve, promiseReject) => { const { accountAddress, network } = getState().settings; const { liquidityTokens } = getState().uniswap; @@ -270,7 +353,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => }) .catch(error => { dispatch({ type: UNISWAP_UPDATE_FAILURE }); - reject(error); + promiseReject(error); }); }); @@ -280,6 +363,7 @@ export const INITIAL_UNISWAP_STATE = { fetchingUniswap: false, liquidityTokens: [], loadingUniswap: false, + pendingApprovals: {}, tokenReserves: {}, uniswap: {}, uniswapAssets: {}, @@ -288,45 +372,49 @@ export const INITIAL_UNISWAP_STATE = { export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft => { switch (action.type) { - case UNISWAP_LOAD_REQUEST: - draft.loadingUniswap = true; - break; - case UNISWAP_LOAD_SUCCESS: - draft.loadingUniswap = false; - draft.allowances = action.payload.allowances; - draft.uniswap = action.payload.uniswap; - draft.uniswapAssets = action.payload.uniswapAssets; - draft.liquidityTokens = action.payload.liquidityTokens; - draft.tokenReserves = action.payload.tokenReserves; - break; - case UNISWAP_LOAD_FAILURE: - draft.loadingUniswap = false; - break; - case UNISWAP_UPDATE_REQUEST: - draft.fetchingUniswap = true; - break; - case UNISWAP_UPDATE_SUCCESS: - draft.fetchingUniswap = false; - draft.uniswap = action.payload; - break; - case UNISWAP_UPDATE_FAILURE: - draft.fetchingUniswap = false; - break; - case UNISWAP_UPDATE_LIQUIDITY_TOKENS: - draft.liquidityTokens = action.payload; - break; - case UNISWAP_UPDATE_ALLOWANCES: - draft.allowances = action.payload; - break; - case UNISWAP_UPDATE_ASSETS: - draft.uniswapAssets = action.payload; - break; - case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: - draft.tokenReserves = action.payload; - break; - case UNISWAP_CLEAR_STATE: - return INITIAL_UNISWAP_STATE; - default: - break; + case UNISWAP_LOAD_REQUEST: + draft.loadingUniswap = true; + break; + case UNISWAP_LOAD_SUCCESS: + draft.allowances = action.payload.allowances; + draft.liquidityTokens = action.payload.liquidityTokens; + draft.loadingUniswap = false; + draft.pendingApprovals = action.payload.pendingApprovals; + draft.tokenReserves = action.payload.tokenReserves; + draft.uniswap = action.payload.uniswap; + draft.uniswapAssets = action.payload.uniswapAssets; + break; + case UNISWAP_LOAD_FAILURE: + draft.loadingUniswap = false; + break; + case UNISWAP_UPDATE_REQUEST: + draft.fetchingUniswap = true; + break; + case UNISWAP_UPDATE_SUCCESS: + draft.fetchingUniswap = false; + draft.uniswap = action.payload; + break; + case UNISWAP_UPDATE_FAILURE: + draft.fetchingUniswap = false; + break; + case UNISWAP_UPDATE_LIQUIDITY_TOKENS: + draft.liquidityTokens = action.payload; + break; + case UNISWAP_UPDATE_PENDING_APPROVALS: + draft.pendingApprovals = action.payload; + break; + case UNISWAP_UPDATE_ALLOWANCES: + draft.allowances = action.payload; + break; + case UNISWAP_UPDATE_ASSETS: + draft.uniswapAssets = action.payload; + break; + case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: + draft.tokenReserves = action.payload; + break; + case UNISWAP_CLEAR_STATE: + return INITIAL_UNISWAP_STATE; + default: + break; } - }); +}); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 6dc497c9a03..47d24ce1879 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -7,7 +7,7 @@ import { tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; import BigNumber from 'bignumber.js'; -import { get, isNil } from 'lodash'; +import { get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; import { InteractionManager, LayoutAnimation, TextInput } from 'react-native'; @@ -72,8 +72,8 @@ const isSameAsset = (firstAsset, secondAsset) => { return false; } - const firstAddress = get(firstAsset, 'address', '').toLowerCase(); - const secondAddress = get(secondAsset, 'address', '').toLowerCase(); + const firstAddress = toLower(get(firstAsset, 'address', '')); + const secondAddress = toLower(get(secondAsset, 'address', '')); return firstAddress === secondAddress; }; @@ -94,6 +94,7 @@ class ExchangeModal extends PureComponent { keyboardFocusHistory: PropTypes.array, nativeCurrency: PropTypes.string, navigation: PropTypes.object, + pendingApprovals: PropTypes.object, pushKeyboardFocusHistory: PropTypes.func, resetGasTxFees: PropTypes.func, selectedGasPrice: PropTypes.object, @@ -103,9 +104,11 @@ class ExchangeModal extends PureComponent { txFees: PropTypes.object, uniswapGetTokenReserve: PropTypes.func, uniswapUpdateAllowances: PropTypes.func, + uniswapUpdatePendingApprovals: PropTypes.func, }; state = { + approvalCreationTimestamp: null, inputAllowance: null, inputAmount: null, inputAmountDisplay: null, @@ -218,7 +221,12 @@ class ExchangeModal extends PureComponent { }; getCurrencyAllowance = async () => { - const { accountAddress, allowances, uniswapUpdateAllowances } = this.props; + const { + accountAddress, + allowances, + pendingApprovals, + uniswapUpdateAllowances, + } = this.props; const { inputCurrency } = this.state; const { address: inputAddress, exchangeAddress } = inputCurrency; @@ -233,20 +241,33 @@ class ExchangeModal extends PureComponent { inputCurrency, exchangeAddress ); - uniswapUpdateAllowances(inputAddress, allowance); + uniswapUpdateAllowances({ [toLower(inputAddress)]: allowance }); } const isAssetApproved = greaterThan(allowance, 0); if (isAssetApproved) { - return this.setState({ isAssetApproved }); + return this.setState({ + isAssetApproved, + isUnlockingAsset: false, + }); } + const pendingApproval = pendingApprovals[toLower(inputCurrency.address)]; + const isUnlockingAsset = !!pendingApproval; + try { const gasLimit = await contractUtils.estimateApprove( inputCurrency.address, exchangeAddress ); - return this.setState({ gasLimit: gasLimit.toFixed(), isAssetApproved }); + return this.setState({ + gasLimit: gasLimit.toFixed(), + isAssetApproved, + isUnlockingAsset, + }); } catch (error) { - return this.setState({ isAssetApproved }); + return this.setState({ + isAssetApproved, + isUnlockingAsset: false, + }); } }; @@ -445,7 +466,6 @@ class ExchangeModal extends PureComponent { if (!reserve) { reserve = await uniswapGetTokenReserve(tokenAddress); } - return reserve; }; @@ -512,19 +532,15 @@ class ExchangeModal extends PureComponent { }; handleUnlockAsset = async () => { - /* - const { - inputCurrency: { - address: tokenAddress, - exchangeAddress: spender, - }, - } = this.state; - */ - - // const approval = await contractUtils.approve(tokenAddress, spender); - - this.setState({ isUnlockingAsset: true }); - }; + const { inputCurrency } = this.state; + const { uniswapUpdatePendingApprovals } = this.props; + const { creationTimestamp, approval: { hash } } = await contractUtils.approve(inputCurrency.address, inputCurrency.exchangeAddress); + uniswapUpdatePendingApprovals(inputCurrency.address, hash); + this.setState({ + approvalCreationTimestamp: creationTimestamp, + isUnlockingAsset: true, + }); + } navigateToSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { @@ -716,6 +732,7 @@ class ExchangeModal extends PureComponent { onSubmit={this.handleSubmit} onUnlockAsset={this.handleUnlockAsset} slippage={slippage} + timeRemaining={get(selectedGasPrice, 'estimatedTime.display')} /> diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 2733581e90c..58716588a0a 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -9,6 +9,7 @@ import { property, sortBy, upperFirst, + toLower, } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -227,7 +228,7 @@ class SendSheet extends Component { analytics.track('Sent transaction', { assetName: selected.name, assetType: selected.isNft ? 'unique_token' : 'token', - isRecepientENS: recipient.slice(-4).toLowerCase() === '.eth', + isRecepientENS: toLower(recipient.slice(-4)) === '.eth', }); sendClearFields(); navigation.navigate('ProfileScreen'); diff --git a/src/styles/colors.js b/src/styles/colors.js index 400e23df88a..ac5a340854c 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -1,4 +1,5 @@ import chroma from 'chroma-js'; +import { toLower } from 'lodash'; import PropTypes from 'prop-types'; const base = { @@ -84,7 +85,7 @@ const isColorLight = targetColor => chroma(targetColor || base.white).luminance() > 0.5; const isHex = (color = '') => color.length >= 3 && color.charAt(0) === '#'; -const isRGB = (color = '') => color.toLowerCase().substring(0, 3) === 'rgb'; +const isRGB = (color = '') => toLower(color).substring(0, 3) === 'rgb'; const getTextColorForBackground = (targetColor, textColors = {}) => { const { dark = base.black, light = base.white } = textColors; diff --git a/src/utils/contract.js b/src/utils/contract.js index 9ed086599f0..edf496c529f 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -17,7 +17,12 @@ const approve = async (tokenAddress, spender) => { if (!wallet) return null; const exchange = new ethers.Contract(tokenAddress, erc20ABI, wallet); const gasLimit = await estimateApproveWithExchange(spender, exchange); - return exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); + const creationTimestamp = Date.now(); + const approval = await exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); + return { + approval, + creationTimestamp, + }; }; const getAllowance = async (owner, token, spender) => { diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index 28fc9b59f5e..d62e2481784 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -1,4 +1,9 @@ -import { find, get } from 'lodash'; +import { + find, + get, + replace, + toLower, +} from 'lodash'; import chains from '../references/chains.json'; import { add, @@ -30,7 +35,7 @@ export const getAsset = (assets, address = 'eth') => * @param {String} hex * @return {String} */ -export const removeHexPrefix = hex => hex.toLowerCase().replace('0x', ''); +export const removeHexPrefix = hex => replace(toLower(hex), '0x', ''); /** * @desc pad string to specific width and padding diff --git a/src/utils/isLowerCaseMatch.js b/src/utils/isLowerCaseMatch.js index ac142257e7b..96f92ba1ba7 100644 --- a/src/utils/isLowerCaseMatch.js +++ b/src/utils/isLowerCaseMatch.js @@ -1,5 +1,5 @@ +import { toLower } from 'lodash'; + export default function isLowerCaseMatch(a, b) { - const _a = a || ''; - const _b = b || ''; - return _a.toLowerCase() === _b.toLowerCase(); + return toLower(a) === toLower(b); } diff --git a/src/utils/search.js b/src/utils/search.js index 777633587d8..7fa3f8e841c 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -1,3 +1,5 @@ +import { startsWith, toLower } from 'lodash'; + export const filterList = ( list, searchPhrase, @@ -7,15 +9,11 @@ export const filterList = ( const filteredList = []; if (list && searchPhrase.length > 0) { for (let i = 0; i < list.length; i++) { - let searchedItem = searchParameter ? list[i][searchParameter] : list[i]; + const searchedItem = searchParameter ? list[i][searchParameter] : list[i]; const splitedWordList = (searchedItem || '').split(separator); splitedWordList.push(searchedItem); for (let j = 0; j < splitedWordList.length; j++) { - if ( - splitedWordList[j] - .toLowerCase() - .startsWith(searchPhrase.toLowerCase()) - ) { + if (startsWith(toLower(splitedWordList[j]), toLower(searchPhrase))) { filteredList.push(list[i]); break; } From 36886fff93c76584f7bdbbb4fe1e4e627d6ed9ad Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 11 Sep 2019 16:59:00 -0400 Subject: [PATCH 346/636] exposing time remaining and creation start time --- .../exchange/ConfirmExchangeButton.js | 8 +++- src/redux/uniswap.js | 20 ++++++++-- src/screens/ExchangeModal.js | 40 ++++++++++++++----- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index fe01a35315e..e064d0fba7c 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -32,10 +32,12 @@ const UnlockingSpinner = ({ timeRemaining, ...props }) => ( ); UnlockingSpinner.propTypes = { + creationTimestamp: PropTypes.string, timeRemaining: PropTypes.string, }; const ConfirmExchangeButton = ({ + creationTimestamp, disabled, inputCurrencyName, isAssetApproved, @@ -76,7 +78,10 @@ const ConfirmExchangeButton = ({ {...props} > {isUnlockingAsset - ? + ? : undefined } @@ -84,6 +89,7 @@ const ConfirmExchangeButton = ({ }; ConfirmExchangeButton.propTypes = { + creationTimestamp: PropTypes.string, disabled: PropTypes.bool, inputCurrencyName: PropTypes.string, isAssetApproved: PropTypes.bool, diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 001246fb4ce..64a3d63daa3 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -5,7 +5,7 @@ import { forEach, fromPairs, get, - invert, + invertBy, isEmpty, keyBy, map, @@ -196,10 +196,22 @@ export const uniswapClearState = () => (dispatch, getState) => { dispatch({ type: UNISWAP_CLEAR_STATE }); }; -export const uniswapUpdatePendingApprovals = (tokenAddress, txHash) => (dispatch, getState) => { +export const uniswapUpdatePendingApprovals = ( + tokenAddress, + txHash, + creationTimestamp, + estimatedTimeInMs, +) => (dispatch, getState) => { const { accountAddress, network } = getState().settings; const { pendingApprovals } = getState().uniswap; - const updatedPendingApprovals = { ...pendingApprovals, [toLower(tokenAddress)]: toLower(txHash) }; + const updatedPendingApprovals = { + ...pendingApprovals, + [toLower(tokenAddress)]: { + creationTimestamp, + estimatedTimeInMs, + hash: toLower(txHash), + }, + }; dispatch({ payload: updatedPendingApprovals, type: UNISWAP_UPDATE_PENDING_APPROVALS, @@ -229,7 +241,7 @@ const updateAllowancesForSuccessfulTransactions = (assetAddresses) => (dispatch, export const uniswapRemovePendingApproval = (newTransactions) => (dispatch, getState) => { const { pendingApprovals } = getState().uniswap; const loweredTxHashes = map(newTransactions, txn => toLower(txn.hash)); - const invertedPendingApprovals = invert(pendingApprovals); + const invertedPendingApprovals = invertBy(pendingApprovals, value => value.hash); const updatedAddresses = compact(map(loweredTxHashes, hash => invertedPendingApprovals[hash])); const updatedPendingApprovals = omit(pendingApprovals, ...updatedAddresses); dispatch({ diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 47d24ce1879..b1081c72957 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -109,6 +109,7 @@ class ExchangeModal extends PureComponent { state = { approvalCreationTimestamp: null, + approvalEstimatedTimeInMs: null, inputAllowance: null, inputAmount: null, inputAmountDisplay: null, @@ -131,8 +132,12 @@ class ExchangeModal extends PureComponent { }; componentDidUpdate = (prevProps, prevState) => { - const { isFocused, isTransitioning, keyboardFocusHistory } = this.props; - + const { + isFocused, + isTransitioning, + pendingApprovals, + keyboardFocusHistory, + } = this.props; if (isFocused && (!isTransitioning && prevProps.isTransitioning)) { const lastFocusedInput = keyboardFocusHistory[keyboardFocusHistory.length - 1]; @@ -185,12 +190,15 @@ class ExchangeModal extends PureComponent { isNewNativeAmount || isNewInputAmount || isNewOutputAmount; const isNewCurrency = isNewInputCurrency || isNewOutputCurrency; + const input = toLower(get(this.state.inputCurrency, 'address')); + const removedFromPending = (!get(pendingApprovals, `[${input}]`, null) + && get(prevProps, `pendingApprovals[${input}]`, null)); + if (isNewAmount || isNewCurrency) { this.getMarketDetails(); LayoutAnimation.easeInEaseOut(); } - - if (isNewValueForPath(this.state, prevState, 'inputCurrency.address')) { + if (removedFromPending || isNewValueForPath(this.state, prevState, 'inputCurrency.address')) { this.getCurrencyAllowance(); } }; @@ -246,6 +254,8 @@ class ExchangeModal extends PureComponent { const isAssetApproved = greaterThan(allowance, 0); if (isAssetApproved) { return this.setState({ + approvalCreationTimestamp: null, + approvalEstimatedTimeInMs: null, isAssetApproved, isUnlockingAsset: false, }); @@ -259,12 +269,16 @@ class ExchangeModal extends PureComponent { exchangeAddress ); return this.setState({ + approvalCreationTimestamp: isUnlockingAsset ? pendingApproval.creationTimestamp : null, + approvalEstimatedTimeInMs: isUnlockingAsset ? pendingApproval.estimatedTimeInMs : null, gasLimit: gasLimit.toFixed(), isAssetApproved, isUnlockingAsset, }); } catch (error) { return this.setState({ + approvalCreationTimestamp: null, + approvalEstimatedTimeInMs: null, isAssetApproved, isUnlockingAsset: false, }); @@ -533,11 +547,16 @@ class ExchangeModal extends PureComponent { handleUnlockAsset = async () => { const { inputCurrency } = this.state; - const { uniswapUpdatePendingApprovals } = this.props; - const { creationTimestamp, approval: { hash } } = await contractUtils.approve(inputCurrency.address, inputCurrency.exchangeAddress); - uniswapUpdatePendingApprovals(inputCurrency.address, hash); + const { selectedGasPrice, uniswapUpdatePendingApprovals } = this.props; + const { + creationTimestamp: approvalCreationTimestamp, + approval: { hash }, + } = await contractUtils.approve(inputCurrency.address, inputCurrency.exchangeAddress); + const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.value'); + uniswapUpdatePendingApprovals(inputCurrency.address, hash, approvalCreationTimestamp, approvalEstimatedTimeInMs); this.setState({ - approvalCreationTimestamp: creationTimestamp, + approvalCreationTimestamp, + approvalEstimatedTimeInMs, isUnlockingAsset: true, }); } @@ -648,6 +667,8 @@ class ExchangeModal extends PureComponent { const { nativeCurrency, transitionPosition } = this.props; const { + approvalCreationTimestamp, + approvalEstimatedTimeInMs, inputAmountDisplay, inputCurrency, // inputExecutionRate, @@ -724,6 +745,7 @@ class ExchangeModal extends PureComponent { From 5493f3778772af9eaf289a22779bff6d3acbb933 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 13 Sep 2019 13:15:53 -0400 Subject: [PATCH 347/636] consolidate transaction format --- .../exchange/ConfirmExchangeButton.js | 4 ++-- src/helpers/transactions.js | 4 ++-- src/parsers/newTransaction.js | 8 ++++--- src/parsers/transactions.js | 6 ++--- src/redux/uniswap.js | 14 +++++++---- src/screens/ExchangeModal.js | 23 +++++++++++-------- 6 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index e064d0fba7c..ad2d36894e7 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -32,7 +32,7 @@ const UnlockingSpinner = ({ timeRemaining, ...props }) => ( ); UnlockingSpinner.propTypes = { - creationTimestamp: PropTypes.string, + creationTimestamp: PropTypes.number, timeRemaining: PropTypes.string, }; @@ -89,7 +89,7 @@ const ConfirmExchangeButton = ({ }; ConfirmExchangeButton.propTypes = { - creationTimestamp: PropTypes.string, + creationTimestamp: PropTypes.number, disabled: PropTypes.bool, inputCurrencyName: PropTypes.string, isAssetApproved: PropTypes.bool, diff --git a/src/helpers/transactions.js b/src/helpers/transactions.js index f266d241197..c3680fd477e 100644 --- a/src/helpers/transactions.js +++ b/src/helpers/transactions.js @@ -15,10 +15,10 @@ const transactionsSelector = state => state.transactions; export const buildTransactionUniqueIdentifier = ({ hash, displayDetails }) => hash || get(displayDetails, 'timestampInMs'); -const groupTransactionByDate = ({ pending, mined_at: time }) => { +const groupTransactionByDate = ({ pending, minedAt }) => { if (pending) return 'Pending'; - const timestamp = new Date(parseInt(time, 10) * 1000); + const timestamp = new Date(parseInt(minedAt, 10) * 1000); if (isToday(timestamp)) return 'Today'; if (isYesterday(timestamp)) return 'Yesterday'; diff --git a/src/parsers/newTransaction.js b/src/parsers/newTransaction.js index f2d83b26c10..dd845b896ee 100644 --- a/src/parsers/newTransaction.js +++ b/src/parsers/newTransaction.js @@ -4,6 +4,7 @@ import { convertAmountToBalanceDisplay, } from '../helpers/utilities'; import { getTransactionCount } from '../handlers/web3'; +import TransactionStatusTypes from '../helpers/transactionStatusTypes'; /** * @desc parse transactions from native prices @@ -29,7 +30,6 @@ export const parseNewTransaction = async ( nativeCurrency ); let tx = pick(txDetails, [ - 'asset', 'dappName', 'from', 'hash', @@ -40,11 +40,13 @@ export const parseNewTransaction = async ( tx = { ...tx, balance, - error: false, - mined_at: null, + minedAt: null, + name: get(txDetails, 'asset.name'), native, nonce, pending: !!txDetails.hash, + status: TransactionStatusTypes.sending, + symbol: get(txDetails, 'asset.symbol'), }; return tx; diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index 0cd6790d248..459c42300d1 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -54,15 +54,15 @@ export default ( const parseTransaction = (txn, accountAddress, nativeCurrency) => { const transaction = pick(txn, [ 'hash', - 'mined_at', 'nonce', 'protocol', 'status', 'type', ]); + transaction.from = txn.address_from; // eslint-disable-line camelcase + transaction.minedAt = txn.mined_at; // eslint-disable-line camelcase transaction.pending = false; - transaction.from = txn.address_from; - transaction.to = txn.address_to; + transaction.to = txn.address_to; // eslint-disable-line camelcase const changes = get(txn, 'changes', []); let internalTransactions = changes; if (isEmpty(changes) && txn.type === 'authorize') { diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 64a3d63daa3..0d51401a79e 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -9,6 +9,7 @@ import { isEmpty, keyBy, map, + mapValues, omit, reject, toLower, @@ -221,6 +222,7 @@ export const uniswapUpdatePendingApprovals = ( const updateAllowancesForSuccessfulTransactions = (assetAddresses) => (dispatch, getState) => { + if (isEmpty(assetAddresses)) return; const { accountAddress } = getState().settings; promiseUtils.PromiseAllWithFails(map(assetAddresses, async (assetAddress) => { const asset = uniswapAssetsRawLoweredKeys[assetAddress]; @@ -231,18 +233,22 @@ const updateAllowancesForSuccessfulTransactions = (assetAddresses) => (dispatch, ); })).then(allowances => { const tokenAddressAllowances = fromPairs(zip(assetAddresses, allowances)); - console.log('token address allowances', tokenAddressAllowances); dispatch(uniswapUpdateAllowances(tokenAddressAllowances)); }).catch(error => { // TODO error handling }); }; -export const uniswapRemovePendingApproval = (newTransactions) => (dispatch, getState) => { +export const uniswapRemovePendingApproval = (transactions) => (dispatch, getState) => { + const newTransactions = map(transactions, txn => ({ + ...txn, + hash: toLower(txn.hash).split('-')[0], + })); const { pendingApprovals } = getState().uniswap; - const loweredTxHashes = map(newTransactions, txn => toLower(txn.hash)); - const invertedPendingApprovals = invertBy(pendingApprovals, value => value.hash); + const loweredTxHashes = map(newTransactions, txn => txn.hash); + const invertedPendingApprovals = mapValues(invertBy(pendingApprovals, value => value.hash), value => get(value, '[0]')); const updatedAddresses = compact(map(loweredTxHashes, hash => invertedPendingApprovals[hash])); + if (isEmpty(updatedAddresses)) return; const updatedPendingApprovals = omit(pendingApprovals, ...updatedAddresses); dispatch({ payload: updatedPendingApprovals, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index b1081c72957..ba3165bd9f4 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -87,7 +87,7 @@ class ExchangeModal extends PureComponent { dataAddNewTransaction: PropTypes.func, gasLimit: PropTypes.string, gasPrices: PropTypes.object, - gasUpdateGasPriceOption: PropTypes.string, + gasUpdateGasPriceOption: PropTypes.func, gasUpdateTxFee: PropTypes.func, isFocused: PropTypes.bool, isTransitioning: PropTypes.bool, @@ -98,7 +98,7 @@ class ExchangeModal extends PureComponent { pushKeyboardFocusHistory: PropTypes.func, resetGasTxFees: PropTypes.func, selectedGasPrice: PropTypes.object, - tokenReserves: PropTypes.array, + tokenReserves: PropTypes.object, tradeDetails: PropTypes.object, transitionPosition: PropTypes.object, // animated value txFees: PropTypes.object, @@ -243,7 +243,7 @@ class ExchangeModal extends PureComponent { } let allowance = allowances[inputAddress]; - if (!allowance) { + if (!greaterThan(allowance, 0)) { allowance = await contractUtils.getAllowance( accountAddress, inputCurrency, @@ -252,7 +252,7 @@ class ExchangeModal extends PureComponent { uniswapUpdateAllowances({ [toLower(inputAddress)]: allowance }); } const isAssetApproved = greaterThan(allowance, 0); - if (isAssetApproved) { + if (greaterThan(allowance, 0)) { return this.setState({ approvalCreationTimestamp: null, approvalEstimatedTimeInMs: null, @@ -271,11 +271,12 @@ class ExchangeModal extends PureComponent { return this.setState({ approvalCreationTimestamp: isUnlockingAsset ? pendingApproval.creationTimestamp : null, approvalEstimatedTimeInMs: isUnlockingAsset ? pendingApproval.estimatedTimeInMs : null, - gasLimit: gasLimit.toFixed(), + gasLimit: gasLimit.toString(), isAssetApproved, isUnlockingAsset, }); } catch (error) { + console.log('error getting gas limit', error); return this.setState({ approvalCreationTimestamp: null, approvalEstimatedTimeInMs: null, @@ -402,7 +403,7 @@ class ExchangeModal extends PureComponent { ); } - const slippage = get(tradeDetails, 'marketRateSlippage', 0).toFixed(); + const slippage = get(tradeDetails, 'marketRateSlippage', 0).toString(); this.setState({ inputExecutionRate, @@ -552,8 +553,13 @@ class ExchangeModal extends PureComponent { creationTimestamp: approvalCreationTimestamp, approval: { hash }, } = await contractUtils.approve(inputCurrency.address, inputCurrency.exchangeAddress); - const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.value'); - uniswapUpdatePendingApprovals(inputCurrency.address, hash, approvalCreationTimestamp, approvalEstimatedTimeInMs); + const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.amount'); + uniswapUpdatePendingApprovals( + inputCurrency.address, + hash, + approvalCreationTimestamp, + approvalEstimatedTimeInMs, + ); this.setState({ approvalCreationTimestamp, approvalEstimatedTimeInMs, @@ -684,7 +690,6 @@ class ExchangeModal extends PureComponent { showConfirmButton, slippage, } = this.state; - return ( Date: Sat, 14 Sep 2019 14:27:14 -0400 Subject: [PATCH 348/636] gas price and limit fixes --- src/components/SendComponentWithData.js | 14 ++- src/handlers/uniswap.js | 90 +++++++------- src/handlers/web3.js | 23 ++-- src/hoc/withGas.js | 2 + src/parsers/gas.js | 7 +- src/redux/gas.js | 117 ++++++++++-------- src/references/ethereum-units.json | 1 + src/screens/ExchangeModal.js | 30 +++-- .../TransactionConfirmationScreenWithData.js | 14 +-- src/utils/contract.js | 25 +++- 10 files changed, 182 insertions(+), 141 deletions(-) diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index 375266524e0..93eaba019f1 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -53,8 +53,9 @@ export const withSendComponentWithData = (SendComponent, options) => { assets: PropTypes.array.isRequired, confirm: PropTypes.bool.isRequired, fetching: PropTypes.bool.isRequired, - gasLimit: PropTypes.number.isRequired, + gasLimit: PropTypes.number, gasPrices: PropTypes.object.isRequired, + gasUpdateDefaultGasLimit: PropTypes.func, gasUpdateTxFee: PropTypes.func.isRequired, isSufficientBalance: PropTypes.bool.isRequired, isSufficientGas: PropTypes.bool.isRequired, @@ -97,6 +98,7 @@ export const withSendComponentWithData = (SendComponent, options) => { defaultAsset: this.defaultAsset, gasFormat: this.gasFormat, }); + this.props.gasUpdateDefaultGasLimit(); } async componentDidUpdate(prevProps) { @@ -119,11 +121,11 @@ export const withSendComponentWithData = (SendComponent, options) => { amount: assetAmount, asset: selected, recipient, - }) - .then(gasLimit => { - this.props.gasUpdateTxFee(gasLimit); - }) - .catch(() => {}); + }).then(gasLimit => { + this.props.gasUpdateTxFee(gasLimit); + }).catch(error => { + this.props.gasUpdateTxFee(null); + }); } } } diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index b1ce33cd194..33db1bdaeda 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -21,7 +21,7 @@ import { loadWallet } from '../model/wallet'; import exchangeABI from '../references/uniswap-exchange-abi.json'; import erc20ABI from '../references/erc20-abi.json'; import { promiseUtils } from '../utils'; -import { web3Provider } from './web3'; +import { toHex, web3Provider } from './web3'; const convertArgsForEthers = methodArguments => methodArguments.map(arg => @@ -74,14 +74,19 @@ const getGasLimit = (exchange, methodName, updatedMethodArgs, value) => { } }; -export const estimateSwapGasLimit = tradeDetails => { +export const estimateSwapGasLimit = async tradeDetails => { const { exchange, methodName, updatedMethodArgs, value, } = getContractExecutionDetails(tradeDetails, web3Provider); - return getGasLimit(exchange, methodName, updatedMethodArgs, value); + try { + const gasLimit = await getGasLimit(exchange, methodName, updatedMethodArgs, value); + return gasLimit ? gasLimit.toString : null; + } catch (error) { + return null; + } }; export const getContractExecutionDetails = (tradeDetails, providerOrSigner) => { @@ -107,7 +112,7 @@ export const getContractExecutionDetails = (tradeDetails, providerOrSigner) => { }; }; -export const executeSwap = async (tradeDetails, gasLimit) => { +export const executeSwap = async (tradeDetails, gasLimit, gasPrice) => { const wallet = await loadWallet(); if (!wallet) return null; const { @@ -116,47 +121,44 @@ export const executeSwap = async (tradeDetails, gasLimit) => { updatedMethodArgs, value, } = getContractExecutionDetails(tradeDetails, wallet); + const transactionParams = { + gasLimit: gasLimit ? toHex(gasLimit) : undefined, + gasPrice: gasPrice ? toHex(gasPrice) : undefined, + value, + }; switch (methodName) { - case 'ethToTokenSwapInput': - return exchange.ethToTokenSwapInput(...updatedMethodArgs, { - gasLimit, - value, - }); - case 'ethToTokenSwapOutput': - return exchange.ethToTokenSwapOutput(...updatedMethodArgs, { - gasLimit, - value, - }); - case 'tokenToEthSwapInput': { - // TODO approval check - return exchange.tokenToEthSwapInput(...updatedMethodArgs, { - gasLimit, - value, - }); - } - case 'tokenToEthSwapOutput': { - // TODO approval check - return exchange.tokenToEthSwapOutput(...updatedMethodArgs, { - gasLimit, - value, - }); - } - case 'tokenToTokenSwapInput': { - // TODO approval check - return exchange.tokenToTokenSwapInput(...updatedMethodArgs, { - gasLimit, - value, - }); - } - case 'tokenToTokenSwapOutput': { - // TODO approval check - return exchange.tokenToTokenSwapOutput(...updatedMethodArgs, { - gasLimit, - value, - }); - } - default: - return null; + case 'ethToTokenSwapInput': + return exchange.ethToTokenSwapInput( + ...updatedMethodArgs, + transactionParams, + ); + case 'ethToTokenSwapOutput': + return exchange.ethToTokenSwapOutput( + ...updatedMethodArgs, + transactionParams, + ); + case 'tokenToEthSwapInput': + return exchange.tokenToEthSwapInput( + ...updatedMethodArgs, + transactionParams, + ); + case 'tokenToEthSwapOutput': + return exchange.tokenToEthSwapOutput( + ...updatedMethodArgs, + transactionParams, + ); + case 'tokenToTokenSwapInput': + return exchange.tokenToTokenSwapInput( + ...updatedMethodArgs, + transactionParams, + ); + case 'tokenToTokenSwapOutput': + return exchange.tokenToTokenSwapOutput( + ...updatedMethodArgs, + transactionParams, + ); + default: + return null; } }; diff --git a/src/handlers/web3.js b/src/handlers/web3.js index 41055164625..a09bd8ee8ad 100644 --- a/src/handlers/web3.js +++ b/src/handlers/web3.js @@ -46,7 +46,7 @@ export const isHexStringIgnorePrefix = value => { }; export const addHexPrefix = value => - startsWith(value, '0x') ? value : '0x' + value; + ((startsWith(value, '0x')) ? value : `0x${value}`); export const mnemonicToSeed = value => ethers.utils.HDNode.mnemonicToSeed(value); @@ -100,7 +100,7 @@ export const estimateGas = async estimateGasData => { const gasLimit = await web3Provider.estimateGas(estimateGasData); return gasLimit.toNumber(); } catch (error) { - return 21000; + return null; } }; @@ -140,20 +140,17 @@ export const getTxDetails = async transaction => { const { from, to } = transaction; const data = transaction.data ? transaction.data : '0x'; const value = transaction.amount ? toWei(transaction.amount) : '0x00'; - const estimateGasData = { - data, - from, - to, - value, - }; - const _gasLimit = - transaction.gasLimit || (await estimateGas(estimateGasData)); - const _gasPrice = transaction.gasPrice || (await getGasPrice()); + const gasLimit = transaction.gasLimit + ? toHex(transaction.gasLimit) + : undefined; + const gasPrice = transaction.gasPrice + ? toHex(transaction.gasPrice) + : undefined; const nonce = await getTransactionCount(from); const tx = { data, - gasLimit: toHex(_gasLimit), - gasPrice: toHex(_gasPrice), + gasLimit, + gasPrice, nonce: toHex(nonce), to, value: toHex(value), diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js index 04e15d3a057..4e06ab603ab 100644 --- a/src/hoc/withGas.js +++ b/src/hoc/withGas.js @@ -1,5 +1,6 @@ import { connect } from 'react-redux'; import { + gasUpdateDefaultGasLimit, gasUpdateGasPriceOption, gasUpdateTxFee, resetGasTxFees, @@ -27,6 +28,7 @@ export default Component => connect( mapStateToProps, { + gasUpdateDefaultGasLimit, gasUpdateGasPriceOption, gasUpdateTxFee, resetGasTxFees, diff --git a/src/parsers/gas.js b/src/parsers/gas.js index 13625bdd36c..7338c119315 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -45,7 +45,8 @@ export const parseGasPrices = (data, short = true) => const defaultGasPriceFormat = (option, timeWait, value) => { const timeAmount = multiply(timeWait, timeUnits.ms.minute); - const valueAmount = multiply(divide(value, 10), ethUnits.gwei); + const gweiAmount = divide(value, 10); + const weiAmount = multiply(gweiAmount, ethUnits.gwei); return { estimatedTime: { @@ -54,8 +55,8 @@ const defaultGasPriceFormat = (option, timeWait, value) => { }, option, value: { - amount: valueAmount, - display: `${valueAmount} Gwei`, + amount: weiAmount, + display: `${gweiAmount} Gwei`, }, }; }; diff --git a/src/redux/gas.js b/src/redux/gas.js index da1c4076f2e..35dbc1dfaa5 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -11,6 +11,7 @@ import { ethereumUtils } from '../utils'; // -- Constants ------------------------------------------------------------- // +const GAS_LIMIT_DEFAULT = 'gas/GAS_LIMIT_DEFAULT'; const GAS_PRICES_DEFAULT = 'gas/GAS_PRICES_DEFAULT'; const GAS_PRICES_SUCCESS = 'gas/GAS_PRICES_SUCCESS'; const GAS_PRICES_FAILURE = 'gas/GAS_PRICES_FAILURE'; @@ -121,13 +122,23 @@ export const gasUpdateGasPriceOption = newGasPriceOption => ( }); }; +export const gasUpdateDefaultGasLimit = (gasLimit = ethUnits.basic_tx) => dispatch => dispatch({ + payload: gasLimit, + type: GAS_LIMIT_DEFAULT, +}); + export const gasUpdateTxFee = gasLimit => (dispatch, getState) => { - const { gasPrices, selectedGasPriceOption } = getState().gas; + const { + defaultGasLimit, + gasPrices, + selectedGasPriceOption, + } = getState().gas; + const _gasLimit = gasLimit || defaultGasLimit; if (isEmpty(gasPrices)) return; const { assets } = getState().data; const { nativeCurrency } = getState().settings; const ethPriceUnit = getEthPriceUnit(assets); - const txFees = parseTxFees(gasPrices, ethPriceUnit, gasLimit, nativeCurrency); + const txFees = parseTxFees(gasPrices, ethPriceUnit, _gasLimit, nativeCurrency); const results = getSelectedGasPrice( assets, gasPrices, @@ -181,8 +192,9 @@ export const gasClearFields = () => dispatch => { // -- Reducer --------------------------------------------------------------- // const INITIAL_STATE = { + defaultGasLimit: ethUnits.basic_tx, fetchingGasPrices: false, - gasLimit: ethUnits.basic_tx, + gasLimit: null, gasPrices: {}, isSufficientGas: false, selectedGasPrice: {}, @@ -193,52 +205,57 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => { switch (action.type) { - case GAS_PRICES_DEFAULT: - return { - ...state, - fetchingGasPrices: true, - gasPrices: action.payload.gasPrices, - selectedGasPrice: action.payload.selectedGasPrice, - txFees: action.payload.txFees, - }; - case GAS_PRICES_SUCCESS: - return { - ...state, - fetchingGasPrices: false, - gasPrices: action.payload, - }; - case GAS_PRICES_FAILURE: - return { - ...state, - fetchingGasPrices: false, - gasPrices: action.payload, - }; - case GAS_UPDATE_TX_FEE: - return { - ...state, - gasLimit: action.payload.gasLimit, - isSufficientGas: action.payload.isSufficientGas, - selectedGasPrice: action.payload.selectedGasPrice, - txFees: action.payload.txFees, - }; - case GAS_UPDATE_GAS_PRICE_OPTION: - return { - ...state, - isSufficientGas: action.payload.isSufficientGas, - selectedGasPrice: action.payload.selectedGasPrice, - selectedGasPriceOption: action.payload.selectedGasPriceOption, - }; - case GAS_RESET_FIELDS: { - return { - ...INITIAL_STATE, - fetchingGasPrices: state.fetchingGasPrices, - gasPrices: state.gasPrices, - selectedGasPrice: action.payload.selectedGasPrice, - selectedGasPriceOption: state.selectedGasPriceOption, - txFees: action.payload.txFees, - }; - } - default: - return state; + case GAS_LIMIT_DEFAULT: + return { + ...state, + gasLimit: action.payload, + }; + case GAS_PRICES_DEFAULT: + return { + ...state, + fetchingGasPrices: true, + gasPrices: action.payload.gasPrices, + selectedGasPrice: action.payload.selectedGasPrice, + txFees: action.payload.txFees, + }; + case GAS_PRICES_SUCCESS: + return { + ...state, + fetchingGasPrices: false, + gasPrices: action.payload, + }; + case GAS_PRICES_FAILURE: + return { + ...state, + fetchingGasPrices: false, + gasPrices: action.payload, + }; + case GAS_UPDATE_TX_FEE: + return { + ...state, + gasLimit: action.payload.gasLimit, + isSufficientGas: action.payload.isSufficientGas, + selectedGasPrice: action.payload.selectedGasPrice, + txFees: action.payload.txFees, + }; + case GAS_UPDATE_GAS_PRICE_OPTION: + return { + ...state, + isSufficientGas: action.payload.isSufficientGas, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: action.payload.selectedGasPriceOption, + }; + case GAS_RESET_FIELDS: { + return { + ...INITIAL_STATE, + fetchingGasPrices: state.fetchingGasPrices, + gasPrices: state.gasPrices, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: state.selectedGasPriceOption, + txFees: action.payload.txFees, + }; + } + default: + return state; } }; diff --git a/src/references/ethereum-units.json b/src/references/ethereum-units.json index 8674ee3aaac..3acf717a9a7 100644 --- a/src/references/ethereum-units.json +++ b/src/references/ethereum-units.json @@ -1,4 +1,5 @@ { + "basic_swap": 80000, "basic_tx": 21000, "noether": 0, "wei": 1, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index ba3165bd9f4..e1f78691279 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -37,6 +37,7 @@ import { withUniswapAllowances, withUniswapAssets, } from '../hoc'; +import ethUnits from '../references/ethereum-units.json'; import { colors, padding, position } from '../styles'; import { contractUtils, @@ -87,6 +88,7 @@ class ExchangeModal extends PureComponent { dataAddNewTransaction: PropTypes.func, gasLimit: PropTypes.string, gasPrices: PropTypes.object, + gasUpdateDefaultGasLimit: PropTypes.func, gasUpdateGasPriceOption: PropTypes.func, gasUpdateTxFee: PropTypes.func, isFocused: PropTypes.bool, @@ -131,6 +133,10 @@ class ExchangeModal extends PureComponent { tradeDetails: null, }; + componentDidMount = () => { + this.props.gasUpdateDefaultGasLimit(ethUnits.basic_swap); + } + componentDidUpdate = (prevProps, prevState) => { const { isFocused, @@ -271,7 +277,7 @@ class ExchangeModal extends PureComponent { return this.setState({ approvalCreationTimestamp: isUnlockingAsset ? pendingApproval.creationTimestamp : null, approvalEstimatedTimeInMs: isUnlockingAsset ? pendingApproval.estimatedTimeInMs : null, - gasLimit: gasLimit.toString(), + gasLimit, isAssetApproved, isUnlockingAsset, }); @@ -280,6 +286,7 @@ class ExchangeModal extends PureComponent { return this.setState({ approvalCreationTimestamp: null, approvalEstimatedTimeInMs: null, + gasLimit: null, isAssetApproved, isUnlockingAsset: false, }); @@ -462,9 +469,7 @@ class ExchangeModal extends PureComponent { } if (isAssetApproved) { const gasLimit = await estimateSwapGasLimit(tradeDetails); - if (gasLimit) { - gasUpdateTxFee(gasLimit.toString()); - } + gasUpdateTxFee(gasLimit); } } catch (error) { console.log('error getting market details', error); @@ -510,11 +515,13 @@ class ExchangeModal extends PureComponent { dataAddNewTransaction, gasLimit, navigation, + selectedGasPrice, } = this.props; const { inputAmount, inputCurrency, tradeDetails } = this.state; try { - const txn = await executeSwap(tradeDetails, gasLimit); + const gasPrice = get(selectedGasPrice, 'value.amount'); + const txn = await executeSwap(tradeDetails, gasLimit, gasPrice); if (txn) { dataAddNewTransaction({ amount: inputAmount, @@ -548,11 +555,20 @@ class ExchangeModal extends PureComponent { handleUnlockAsset = async () => { const { inputCurrency } = this.state; - const { selectedGasPrice, uniswapUpdatePendingApprovals } = this.props; + const { + gasLimit, + selectedGasPrice, + uniswapUpdatePendingApprovals, + } = this.props; const { creationTimestamp: approvalCreationTimestamp, approval: { hash }, - } = await contractUtils.approve(inputCurrency.address, inputCurrency.exchangeAddress); + } = await contractUtils.approve( + inputCurrency.address, + inputCurrency.exchangeAddress, + gasLimit, + get(selectedGasPrice, 'value.amount'), + ); const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.amount'); uniswapUpdatePendingApprovals( inputCurrency.address, diff --git a/src/screens/TransactionConfirmationScreenWithData.js b/src/screens/TransactionConfirmationScreenWithData.js index f2de8214674..c593feaf758 100644 --- a/src/screens/TransactionConfirmationScreenWithData.js +++ b/src/screens/TransactionConfirmationScreenWithData.js @@ -1,7 +1,7 @@ import analytics from '@segment/analytics-react-native'; import { ethers } from 'ethers'; import lang from 'i18n-js'; -import { get, isNil, omit } from 'lodash'; +import { get, omit } from 'lodash'; import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { Alert, Vibration } from 'react-native'; @@ -13,7 +13,7 @@ import { signPersonalMessage, sendTransaction, } from '../model/wallet'; -import { estimateGas, getTransactionCount, toHex } from '../handlers/web3'; +import { getTransactionCount } from '../handlers/web3'; import TransactionConfirmationScreen from './TransactionConfirmationScreen'; class TransactionConfirmationScreenWithData extends PureComponent { @@ -44,16 +44,6 @@ class TransactionConfirmationScreenWithData extends PureComponent { const { transactionDetails } = this.props.navigation.state.params; const txPayload = get(transactionDetails, 'payload.params[0]'); - let { gasLimit } = txPayload; - - if (isNil(gasLimit)) { - try { - const rawGasLimit = await estimateGas(txPayload); - gasLimit = toHex(rawGasLimit); - } catch (error) { - console.log('error estimating gas', error); - } - } const web3TxnCount = await getTransactionCount(txPayload.from); const maxTxnCount = Math.max( this.props.transactionCountNonce, diff --git a/src/utils/contract.js b/src/utils/contract.js index edf496c529f..88ac56e489e 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -1,24 +1,37 @@ import { ethers } from 'ethers'; -import { web3Provider } from '../handlers/web3'; +import { toHex, web3Provider } from '../handlers/web3'; import { convertRawAmountToDecimalFormat } from '../helpers/utilities'; import { loadWallet } from '../model/wallet'; import erc20ABI from '../references/erc20-abi.json'; -const estimateApproveWithExchange = (spender, exchange) => - exchange.estimate.approve(spender, ethers.constants.MaxUint256); +const estimateApproveWithExchange = async (spender, exchange) => { + try { + const gasLimit = await exchange.estimate.approve(spender, ethers.constants.MaxUint256); + return gasLimit ? gasLimit.toString() : null; + } catch (error) { + console.log('error estimating approval', error); + return null; + } +}; const estimateApprove = (tokenAddress, spender) => { const exchange = new ethers.Contract(tokenAddress, erc20ABI, web3Provider); return estimateApproveWithExchange(spender, exchange); }; -const approve = async (tokenAddress, spender) => { +const approve = async (tokenAddress, spender, gasLimit, gasPrice) => { const wallet = await loadWallet(); if (!wallet) return null; const exchange = new ethers.Contract(tokenAddress, erc20ABI, wallet); - const gasLimit = await estimateApproveWithExchange(spender, exchange); const creationTimestamp = Date.now(); - const approval = await exchange.approve(spender, ethers.constants.MaxUint256, { gasLimit }); + const approval = await exchange.approve( + spender, + ethers.constants.MaxUint256, + { + gasLimit: gasLimit ? toHex(gasLimit) : undefined, + gasPrice: gasPrice ? toHex(gasPrice) : undefined, + }, + ); return { approval, creationTimestamp, From f03097aa58e279d0f89219d43f8ef49c19491faf Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 15 Sep 2019 14:13:42 -0400 Subject: [PATCH 349/636] exchange gas fee button fixes and normalize labels for gas speed --- src/handlers/uniswap.js | 15 ++--- src/parsers/gas.js | 106 ++++++++++++++--------------------- src/redux/gas.js | 20 ++++--- src/screens/ExchangeModal.js | 69 +++++++++++++---------- src/utils/contract.js | 3 +- src/utils/gas.js | 24 ++++---- 6 files changed, 115 insertions(+), 122 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 33db1bdaeda..2e0400ab46b 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -75,16 +75,17 @@ const getGasLimit = (exchange, methodName, updatedMethodArgs, value) => { }; export const estimateSwapGasLimit = async tradeDetails => { - const { - exchange, - methodName, - updatedMethodArgs, - value, - } = getContractExecutionDetails(tradeDetails, web3Provider); try { + const { + exchange, + methodName, + updatedMethodArgs, + value, + } = getContractExecutionDetails(tradeDetails, web3Provider); const gasLimit = await getGasLimit(exchange, methodName, updatedMethodArgs, value); - return gasLimit ? gasLimit.toString : null; + return gasLimit ? gasLimit.toString() : null; } catch (error) { + console.log('error getting swap gas limit', error); return null; } }; diff --git a/src/parsers/gas.js b/src/parsers/gas.js index 7338c119315..280f8c8f6bd 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -1,3 +1,9 @@ +import { + get, + map, + values, + zipObject, +} from 'lodash'; import { getMinimalTimeUnitStringForMs } from '../helpers/time'; import { convertRawAmountToBalance, @@ -7,6 +13,7 @@ import { } from '../helpers/utilities'; import timeUnits from '../references/time-units.json'; import ethUnits from '../references/ethereum-units.json'; +import { GasSpeed } from '../utils/gas'; /** * @desc parse ether gas prices @@ -14,9 +21,9 @@ import ethUnits from '../references/ethereum-units.json'; * @param {Boolean} short - use short format or not */ export const getFallbackGasPrices = (short = true) => ({ - average: defaultGasPriceFormat('average', '2.5', '100', short), - fast: defaultGasPriceFormat('fast', '0.5', '200', short), - slow: defaultGasPriceFormat('slow', '2.5', '100', short), + [GasSpeed.fast]: defaultGasPriceFormat(GasSpeed.fast, '0.5', '200', short), + [GasSpeed.normal]: defaultGasPriceFormat(GasSpeed.normal, '2.5', '100', short), + [GasSpeed.slow]: defaultGasPriceFormat(GasSpeed.slow, '2.5', '100', short), }); /** @@ -27,27 +34,17 @@ export const getFallbackGasPrices = (short = true) => ({ export const parseGasPrices = (data, short = true) => !data ? getFallbackGasPrices() - : { - average: defaultGasPriceFormat( - 'average', - data.avgWait, - data.average, - short - ), - fast: defaultGasPriceFormat('fast', data.fastWait, data.fast, short), - slow: defaultGasPriceFormat( - 'slow', - data.safeLowWait, - data.safeLow, - short - ), - }; + : ({ + [GasSpeed.fast]: defaultGasPriceFormat(GasSpeed.fast, data.fastWait, data.fast, short), + [GasSpeed.normal]: defaultGasPriceFormat(GasSpeed.normal, data.avgWait, data.average, short), + [GasSpeed.slow]: defaultGasPriceFormat(GasSpeed.slow, data.safeLowWait, data.safeLow, short), + }) +); const defaultGasPriceFormat = (option, timeWait, value) => { const timeAmount = multiply(timeWait, timeUnits.ms.minute); const gweiAmount = divide(value, 10); const weiAmount = multiply(gweiAmount, ethUnits.gwei); - return { estimatedTime: { amount: timeAmount, @@ -68,53 +65,36 @@ const defaultGasPriceFormat = (option, timeWait, value) => { * @param {Number} gasLimit */ export const parseTxFees = (gasPrices, priceUnit, gasLimit, nativeCurrency) => { - const txFees = { - average: { txFee: getTxFee(gasPrices.average.value.amount, gasLimit) }, - fast: { txFee: getTxFee(gasPrices.fast.value.amount, gasLimit) }, - slow: { txFee: getTxFee(gasPrices.slow.value.amount, gasLimit) }, - }; - - return convertTxFeesToNative(priceUnit, txFees, nativeCurrency); + const gasSpeedLabels = values(GasSpeed); + const txFees = map(gasSpeedLabels, (speed) => { + const gasPrice = get(gasPrices, `${speed}.value.amount`); + return { + txFee: getTxFee(gasPrice, gasLimit, priceUnit, nativeCurrency), + }; + }); + return zipObject(gasSpeedLabels, txFees); }; -const getTxFee = (gasPrice, gasLimit) => { +const getTxFee = (gasPrice, gasLimit, priceUnit, nativeCurrency) => { const amount = multiply(gasPrice, gasLimit); - const display = convertRawAmountToBalance(amount, { - decimals: 18, - symbol: 'ETH', - }); - return { - native: null, - value: { amount, display }, + native: { + value: convertRawAmountToNativeDisplay( + amount, + 18, + priceUnit, + nativeCurrency, + ), + }, + value: { + amount, + display: convertRawAmountToBalance( + amount, + { + decimals: 18, + symbol: 'ETH', + }, + ), + }, }; }; - -const convertTxFeesToNative = (priceUnit, txFees, nativeCurrency) => { - const nativeTxFees = { ...txFees }; - nativeTxFees.fast.txFee.native = getNativeTxFee( - priceUnit, - txFees.fast.txFee.value.amount, - nativeCurrency - ); - nativeTxFees.average.txFee.native = getNativeTxFee( - priceUnit, - txFees.average.txFee.value.amount, - nativeCurrency - ); - nativeTxFees.slow.txFee.native = getNativeTxFee( - priceUnit, - txFees.slow.txFee.value.amount, - nativeCurrency - ); - return nativeTxFees; -}; - -const getNativeTxFee = (priceUnit, feeAmount, nativeCurrency) => ({ - value: convertRawAmountToNativeDisplay( - feeAmount, - 18, - priceUnit, - nativeCurrency - ), -}); diff --git a/src/redux/gas.js b/src/redux/gas.js index 35dbc1dfaa5..21651b019c2 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -8,10 +8,11 @@ import { } from '../parsers/gas'; import ethUnits from '../references/ethereum-units.json'; import { ethereumUtils } from '../utils'; +import { GasSpeed } from '../utils/gas'; // -- Constants ------------------------------------------------------------- // -const GAS_LIMIT_DEFAULT = 'gas/GAS_LIMIT_DEFAULT'; +const GAS_UPDATE_DEFAULT_GAS_LIMIT = 'gas/GAS_UPDATE_DEFAULT_GAS_LIMIT'; const GAS_PRICES_DEFAULT = 'gas/GAS_PRICES_DEFAULT'; const GAS_PRICES_SUCCESS = 'gas/GAS_PRICES_SUCCESS'; const GAS_PRICES_FAILURE = 'gas/GAS_PRICES_FAILURE'; @@ -122,10 +123,13 @@ export const gasUpdateGasPriceOption = newGasPriceOption => ( }); }; -export const gasUpdateDefaultGasLimit = (gasLimit = ethUnits.basic_tx) => dispatch => dispatch({ - payload: gasLimit, - type: GAS_LIMIT_DEFAULT, -}); +export const gasUpdateDefaultGasLimit = (defaultGasLimit = ethUnits.basic_tx) => dispatch => { + dispatch({ + payload: defaultGasLimit, + type: GAS_UPDATE_DEFAULT_GAS_LIMIT, + }); + dispatch(gasUpdateTxFee(defaultGasLimit)); +}; export const gasUpdateTxFee = gasLimit => (dispatch, getState) => { const { @@ -198,17 +202,17 @@ const INITIAL_STATE = { gasPrices: {}, isSufficientGas: false, selectedGasPrice: {}, - selectedGasPriceOption: 'average', + selectedGasPriceOption: GasSpeed.normal, txFees: {}, useShortGasFormat: true, }; export default (state = INITIAL_STATE, action) => { switch (action.type) { - case GAS_LIMIT_DEFAULT: + case GAS_UPDATE_DEFAULT_GAS_LIMIT: return { ...state, - gasLimit: action.payload, + defaultGasLimit: action.payload, }; case GAS_PRICES_DEFAULT: return { diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index e1f78691279..fa0c7a1b0c1 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -238,6 +238,7 @@ class ExchangeModal extends PureComponent { const { accountAddress, allowances, + gasUpdateTxFee, pendingApprovals, uniswapUpdateAllowances, } = this.props; @@ -274,19 +275,18 @@ class ExchangeModal extends PureComponent { inputCurrency.address, exchangeAddress ); + gasUpdateTxFee(gasLimit); return this.setState({ approvalCreationTimestamp: isUnlockingAsset ? pendingApproval.creationTimestamp : null, approvalEstimatedTimeInMs: isUnlockingAsset ? pendingApproval.estimatedTimeInMs : null, - gasLimit, isAssetApproved, isUnlockingAsset, }); } catch (error) { - console.log('error getting gas limit', error); + gasUpdateTxFee(); return this.setState({ approvalCreationTimestamp: null, approvalEstimatedTimeInMs: null, - gasLimit: null, isAssetApproved, isUnlockingAsset: false, }); @@ -554,33 +554,42 @@ class ExchangeModal extends PureComponent { }; handleUnlockAsset = async () => { - const { inputCurrency } = this.state; - const { - gasLimit, - selectedGasPrice, - uniswapUpdatePendingApprovals, - } = this.props; - const { - creationTimestamp: approvalCreationTimestamp, - approval: { hash }, - } = await contractUtils.approve( - inputCurrency.address, - inputCurrency.exchangeAddress, - gasLimit, - get(selectedGasPrice, 'value.amount'), - ); - const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.amount'); - uniswapUpdatePendingApprovals( - inputCurrency.address, - hash, - approvalCreationTimestamp, - approvalEstimatedTimeInMs, - ); - this.setState({ - approvalCreationTimestamp, - approvalEstimatedTimeInMs, - isUnlockingAsset: true, - }); + try { + const { inputCurrency } = this.state; + const { + gasLimit, + selectedGasPrice, + uniswapUpdatePendingApprovals, + } = this.props; + const { + creationTimestamp: approvalCreationTimestamp, + approval: { hash }, + } = await contractUtils.approve( + inputCurrency.address, + inputCurrency.exchangeAddress, + gasLimit, + get(selectedGasPrice, 'value.amount'), + ); + const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.amount'); + uniswapUpdatePendingApprovals( + inputCurrency.address, + hash, + approvalCreationTimestamp, + approvalEstimatedTimeInMs, + ); + this.setState({ + approvalCreationTimestamp, + approvalEstimatedTimeInMs, + isUnlockingAsset: true, + }); + } catch (error) { + console.log('could not unlock asset', error); + this.setState({ + approvalCreationTimestamp: null, + approvalEstimatedTimeInMs: null, + isUnlockingAsset: false, + }); + } } navigateToSelectInputCurrency = () => { diff --git a/src/utils/contract.js b/src/utils/contract.js index 88ac56e489e..72a5187d14a 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -46,8 +46,7 @@ const getAllowance = async (owner, token, spender) => { web3Provider ); const allowance = await tokenContract.allowance(owner, spender); - const rawAllowance = ethers.utils.bigNumberify(allowance.toString()); - return convertRawAmountToDecimalFormat(rawAllowance, decimals); + return convertRawAmountToDecimalFormat(allowance.toString(), decimals); }; export default { diff --git a/src/utils/gas.js b/src/utils/gas.js index bfebd96d0c4..b0042260405 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -10,7 +10,13 @@ import { } from 'lodash'; import { showActionSheetWithOptions } from './actionsheet'; -const GasSpeedTypes = ['slow', 'normal', 'fast']; +export const GasSpeed = { + fast: 'fast', + normal: 'normal', + slow: 'slow', +}; + +const labelOrder = [GasSpeed.slow, GasSpeed.normal, GasSpeed.fast]; const showTransactionSpeedOptions = ( gasPrices, @@ -31,8 +37,7 @@ const showTransactionSpeedOptions = ( buttonIndex => { if (buttonIndex > 0) { const selectedGasPriceItem = options[buttonIndex]; - - updateGasOption(selectedGasPriceItem.value); + updateGasOption(selectedGasPriceItem.speed); analytics.track('Updated Gas Price', { gasPrice: selectedGasPriceItem.gweiValue, }); @@ -46,23 +51,18 @@ const showTransactionSpeedOptions = ( }; const formatGasSpeedItems = (gasPrices, txFees) => { - const gasItems = map(GasSpeedTypes, label => { - let speed = label; - if (label === 'normal') { - speed = 'average'; - } - + const gasItems = map(labelOrder, (speed) => { const cost = get(txFees, `[${speed}].txFee.native.value.display`); const gwei = get(gasPrices, `[${speed}].value.display`); const time = get(gasPrices, `[${speed}].estimatedTime.display`); return { gweiValue: gwei, - label: `${upperFirst(label)}: ${cost} ~${time.slice(0, -1)}`, - value: speed, + label: `${upperFirst(speed)}: ${cost} ~${time}`, + speed, }; }); - return sortBy(gasItems, ({ value }) => indexOf(GasSpeedTypes, value)); + return sortBy(gasItems, ({ speed }) => indexOf(labelOrder, speed)); }; export default { From 1c9a3d686dec894f00c3840b197060b40ce79f53 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 17 Sep 2019 17:40:40 -0400 Subject: [PATCH 350/636] estimate gas for swap fix --- src/handlers/uniswap.js | 66 ++++++++++++++++++++---------------- src/screens/ExchangeModal.js | 9 +++-- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 2e0400ab46b..6fa7ea866c0 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -43,38 +43,45 @@ export const getReserves = async () => { return keyBy(compact(reserves), reserve => toLower(get(reserve, 'token.address'))); }; -const getGasLimit = (exchange, methodName, updatedMethodArgs, value) => { +const getGasLimit = async (accountAddress, exchange, methodName, updatedMethodArgs, value) => { + const params = { from: accountAddress, value }; switch (methodName) { - case 'ethToTokenSwapInput': - return exchange.estimate.ethToTokenSwapInput(...updatedMethodArgs, { - value, - }); - case 'ethToTokenSwapOutput': - return exchange.estimate.ethToTokenSwapOutput(...updatedMethodArgs, { - value, - }); - case 'tokenToEthSwapInput': - return exchange.estimate.tokenToEthSwapInput(...updatedMethodArgs, { - value, - }); - case 'tokenToEthSwapOutput': - return exchange.estimate.tokenToEthSwapOutput(...updatedMethodArgs, { - value, - }); - case 'tokenToTokenSwapInput': - return exchange.estimate.tokenToTokenSwapInput(...updatedMethodArgs, { - value, - }); - case 'tokenToTokenSwapOutput': - return exchange.estimate.tokenToTokenSwapOutput(...updatedMethodArgs, { - value, - }); - default: - return null; + case 'ethToTokenSwapInput': + return exchange.estimate.ethToTokenSwapInput( + ...updatedMethodArgs, + params, + ); + case 'ethToTokenSwapOutput': + return exchange.estimate.ethToTokenSwapOutput( + ...updatedMethodArgs, + params, + ); + case 'tokenToEthSwapInput': + return exchange.estimate.tokenToEthSwapInput( + ...updatedMethodArgs, + params, + ); + case 'tokenToEthSwapOutput': + return exchange.estimate.tokenToEthSwapOutput( + ...updatedMethodArgs, + params, + ); + case 'tokenToTokenSwapInput': + return exchange.estimate.tokenToTokenSwapInput( + ...updatedMethodArgs, + params, + ); + case 'tokenToTokenSwapOutput': + return exchange.estimate.tokenToTokenSwapOutput( + ...updatedMethodArgs, + params, + ); + default: + return null; } }; -export const estimateSwapGasLimit = async tradeDetails => { +export const estimateSwapGasLimit = async (accountAddress, tradeDetails) => { try { const { exchange, @@ -82,10 +89,9 @@ export const estimateSwapGasLimit = async tradeDetails => { updatedMethodArgs, value, } = getContractExecutionDetails(tradeDetails, web3Provider); - const gasLimit = await getGasLimit(exchange, methodName, updatedMethodArgs, value); + const gasLimit = await getGasLimit(accountAddress, exchange, methodName, updatedMethodArgs, value); return gasLimit ? gasLimit.toString() : null; } catch (error) { - console.log('error getting swap gas limit', error); return null; } }; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index fa0c7a1b0c1..897b961ed39 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -294,7 +294,12 @@ class ExchangeModal extends PureComponent { }; getMarketDetails = async () => { - const { chainId, gasUpdateTxFee, nativeCurrency } = this.props; + const { + accountAddress, + chainId, + gasUpdateTxFee, + nativeCurrency, + } = this.props; const { inputAmount, inputAsExactAmount, @@ -468,7 +473,7 @@ class ExchangeModal extends PureComponent { } } if (isAssetApproved) { - const gasLimit = await estimateSwapGasLimit(tradeDetails); + const gasLimit = await estimateSwapGasLimit(accountAddress, tradeDetails); gasUpdateTxFee(gasLimit); } } catch (error) { From d7dfb4cd1fb745167e6ec34013745ccdcfb30a34 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 18 Sep 2019 19:01:08 -0400 Subject: [PATCH 351/636] prevent reset of inputAsExactAmount when auto-updating values --- src/screens/ExchangeModal.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 897b961ed39..f542232ed37 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -193,7 +193,9 @@ class ExchangeModal extends PureComponent { ); const isNewAmount = - isNewNativeAmount || isNewInputAmount || isNewOutputAmount; + (this.state.inputAsExactAmount + && (isNewNativeAmount || isNewInputAmount)) + || (!this.state.inputAsExactAmount && isNewOutputAmount); const isNewCurrency = isNewInputCurrency || isNewOutputCurrency; const input = toLower(get(this.state.inputCurrency, 'address')); @@ -450,7 +452,7 @@ class ExchangeModal extends PureComponent { get(outputCurrency, 'price.value') ); - this.setOutputAmount(rawUpdatedAmount, updatedAmountDisplay); + this.setOutputAmount(rawUpdatedAmount, updatedAmountDisplay, inputAsExactAmount); } } @@ -469,7 +471,7 @@ class ExchangeModal extends PureComponent { get(inputCurrency, 'price.value') ); - this.setInputAmount(rawUpdatedAmount, updatedAmountDisplay); + this.setInputAmount(rawUpdatedAmount, updatedAmountDisplay, inputAsExactAmount); } } if (isAssetApproved) { @@ -611,13 +613,13 @@ class ExchangeModal extends PureComponent { }); }; - setInputAmount = (inputAmount, amountDisplay) => { + setInputAmount = (inputAmount, amountDisplay, inputAsExactAmount = true) => { this.setState(({ inputCurrency }) => { const newState = { inputAmount, inputAmountDisplay: amountDisplay !== undefined ? amountDisplay : inputAmount, - inputAsExactAmount: true, + inputAsExactAmount, }; if (!this.nativeFieldRef.isFocused()) { @@ -672,9 +674,9 @@ class ExchangeModal extends PureComponent { }); }; - setOutputAmount = (outputAmount, amountDisplay) => { - this.setState(() => ({ - inputAsExactAmount: false, + setOutputAmount = (outputAmount, amountDisplay, inputAsExactAmount = false) => { + this.setState(({ outputCurrency }) => ({ + inputAsExactAmount, outputAmount, outputAmountDisplay: amountDisplay !== undefined ? amountDisplay : outputAmount, From 879f819a0e3bf9b193ba1387edb734a838823be5 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 18 Sep 2019 17:16:42 -0400 Subject: [PATCH 352/636] subtract refund when it exists for swaps --- src/parsers/transactions.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index 459c42300d1..e06539f7800 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -1,4 +1,5 @@ import { + compact, concat, filter, find, @@ -19,9 +20,12 @@ import TransactionStatusTypes from '../helpers/transactionStatusTypes'; import { convertRawAmountToBalance, convertRawAmountToNativeDisplay, + subtract, } from '../helpers/utilities'; import { isLowerCaseMatch } from '../utils'; +const DIRECTION_OUT = 'out'; + const dataFromLastTxHash = (transactionData, transactions) => { const lastSuccessfulTxn = find(transactions, (txn) => txn.hash && !txn.pending); const lastTxHash = lastSuccessfulTxn ? lastSuccessfulTxn.hash : ''; @@ -51,6 +55,24 @@ export default ( return { approvalTransactions, dedupedResults }; }; +const transformUniswapRefund = (internalTransactions) => { + const [txnsOut, txnsIn] = partition(internalTransactions, txn => txn.direction === DIRECTION_OUT); + const isSuccessfulSwap = txnsOut.length === 1 && (txnsIn.length === 1 || txnsIn.length === 2); + if (!isSuccessfulSwap) return internalTransactions; + + const txnOut = txnsOut[0]; + const txnIn = find(txnsIn, (txn) => txn.asset.asset_code !== txnOut.asset.asset_code); + const refund = find(txnsIn, (txn) => txn.asset.asset_code === txnOut.asset.asset_code); + let updatedOut = txnOut; + if (refund && txnOut) { + updatedOut = { + ...txnOut, + value: txnOut.value - refund.value, + }; + } + return compact([updatedOut, txnIn]); +}; + const parseTransaction = (txn, accountAddress, nativeCurrency) => { const transaction = pick(txn, [ 'hash', @@ -93,6 +115,9 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { }; internalTransactions = [ethInternalTransaction]; } + if (transaction.type === 'trade' && transaction.protocol === 'uniswap') { + internalTransactions = transformUniswapRefund(internalTransactions); + } internalTransactions = internalTransactions.map((internalTxn, index) => { const symbol = get(internalTxn, 'asset.symbol') || ''; const updatedAsset = { From 7ae8c4a693cb89081557158742a0f894a8048d05 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 15 Sep 2019 16:02:04 -0400 Subject: [PATCH 353/636] catching up with mike swap changes and updates to gas speed rotation --- ios/Podfile.lock | 71 +++++++++++-------- src/components/gas/GasSpeedButton.js | 38 ++++------- src/components/gas/GasSpeedEmoji.js | 10 +-- src/components/gas/GasSpeedLabelPager.js | 4 +- src/components/gas/GasSpeedLabelPagerItem.js | 6 +- src/parsers/gas.js | 20 +++--- src/redux/gas.js | 9 ++- src/utils/gas.js | 19 +++--- yarn.lock | 72 ++++++++++++++++---- 9 files changed, 145 insertions(+), 104 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 72a0fe5c7a3..b603fc34ed3 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Analytics (3.7.0) + - Analytics (3.6.10) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React @@ -40,26 +40,41 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - GoogleToolboxForMac/Defines (2.2.1) - - GoogleToolboxForMac/Logger (2.2.1): - - GoogleToolboxForMac/Defines (= 2.2.1) - - "GoogleToolboxForMac/NSData+zlib (2.2.1)": - - GoogleToolboxForMac/Defines (= 2.2.1) - - libwebp (1.0.3): - - libwebp/demux (= 1.0.3) - - libwebp/mux (= 1.0.3) - - libwebp/webp (= 1.0.3) - - libwebp/demux (1.0.3): + - GoogleToolboxForMac/Defines (2.2.0) + - GoogleToolboxForMac/Logger (2.2.0): + - GoogleToolboxForMac/Defines (= 2.2.0) + - "GoogleToolboxForMac/NSData+zlib (2.2.0)": + - GoogleToolboxForMac/Defines (= 2.2.0) + - libwebp (1.0.2): + - libwebp/core (= 1.0.2) + - libwebp/dec (= 1.0.2) + - libwebp/demux (= 1.0.2) + - libwebp/dsp (= 1.0.2) + - libwebp/enc (= 1.0.2) + - libwebp/mux (= 1.0.2) + - libwebp/utils (= 1.0.2) + - libwebp/webp (= 1.0.2) + - libwebp/core (1.0.2): - libwebp/webp - - libwebp/mux (1.0.3): - - libwebp/demux - - libwebp/webp (1.0.3) + - libwebp/dec (1.0.2): + - libwebp/core + - libwebp/demux (1.0.2): + - libwebp/core + - libwebp/dsp (1.0.2): + - libwebp/core + - libwebp/enc (1.0.2): + - libwebp/core + - libwebp/mux (1.0.2): + - libwebp/core + - libwebp/utils (1.0.2): + - libwebp/core + - libwebp/webp (1.0.2) - nanopb (0.3.901): - nanopb/decode (= 0.3.901) - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - - Protobuf (3.9.0) + - Protobuf (3.7.0) - React (0.60.5): - React-Core (= 0.60.5) - React-DevSupport (= 0.60.5) @@ -164,9 +179,9 @@ PODS: - React - RNStoreReview (0.1.5): - React - - SDWebImage (5.1.1): - - SDWebImage/Core (= 5.1.1) - - SDWebImage/Core (5.1.1) + - SDWebImage (5.0.2): + - SDWebImage/Core (= 5.0.2) + - SDWebImage/Core (5.0.2) - yoga (0.60.5.React) DEPENDENCIES: @@ -306,24 +321,24 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 + Analytics: 63744ad4afa65c3bcdcdb7a94b62515bde5b3900 boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa - FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 - FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 - FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 - FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb + Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 + FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d + FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 + FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 + FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 - libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e + GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d + libwebp: b068a3bd7c45f7460f6715be7bed1a18fd5d6b48 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a + Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a React: 53c53c4d99097af47cf60594b8706b4e3321e722 React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64 React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395 @@ -355,7 +370,7 @@ SPEC CHECKSUMS: RNReanimated: da57ffa32f04cebe2107da0b281999a01c0d1ecc RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8 + SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 PODFILE CHECKSUM: c393ff0cebe4b167e23b61fa2c324eace3cbf57e diff --git a/src/components/gas/GasSpeedButton.js b/src/components/gas/GasSpeedButton.js index 3f21eaafd96..53ed6ef312c 100644 --- a/src/components/gas/GasSpeedButton.js +++ b/src/components/gas/GasSpeedButton.js @@ -35,37 +35,24 @@ class GasSpeedButton extends PureComponent { estimatedTimeValue: PropTypes.string, gasPrices: PropTypes.object, gasUpdateGasPriceOption: PropTypes.func, - label: PropTypes.string, nativeCurrencySymbol: PropTypes.string, price: PropTypes.string, - }; - - getLabel = nextLabel => { - let label = nextLabel || this.props.label; - const shouldReverse = !!nextLabel; - - if (shouldReverse && label === 'normal') { - label = 'average'; - } else if (label === 'average') { - label = 'normal'; - } - - return label; - }; + selectedGasPriceOption: PropTypes.oneOf(gasUtils.GasSpeedOrder), + } handlePress = () => { - const { gasPrices, gasUpdateGasPriceOption } = this.props; + const { + gasPrices, + gasUpdateGasPriceOption, + selectedGasPriceOption, + } = this.props; LayoutAnimation.easeInEaseOut(); - const currentSpeedIndex = gasUtils.GasSpeedTypes.indexOf(this.getLabel()); - - let nextSpeedIndex = currentSpeedIndex + 1; - if (nextSpeedIndex > gasUtils.GasSpeedTypes.length - 1) { - nextSpeedIndex = 0; - } + const currentSpeedIndex = gasUtils.GasSpeedOrder.indexOf(selectedGasPriceOption); + const nextSpeedIndex = (currentSpeedIndex + 1) % gasUtils.GasSpeedOrder.length; - const nextSpeed = this.getLabel(gasUtils.GasSpeedTypes[nextSpeedIndex]); + const nextSpeed = gasUtils.GasSpeedOrder[nextSpeedIndex]; const nextSpeedGweiValue = get(gasPrices, `[${nextSpeed}].value.display`); gasUpdateGasPriceOption(nextSpeed); @@ -99,7 +86,7 @@ class GasSpeedButton extends PureComponent { timing="linear" value={this.props.price} /> - + @@ -130,7 +117,6 @@ export default compose( return { estimatedTimeUnit: estimatedTime[1] || 'min', estimatedTimeValue: estimatedTime[0] || 0, - label: get(selectedGasPrice, 'option', 'normal'), price: get(selectedGasPrice, 'txFee.native.value.amount', '0.00'), ...props, }; @@ -138,7 +124,7 @@ export default compose( onlyUpdateForKeys([ 'estimatedTimeUnit', 'estimatedTimeValue', - 'label', 'price', + 'selectedGasPriceOption', ]) )(GasSpeedButton); diff --git a/src/components/gas/GasSpeedEmoji.js b/src/components/gas/GasSpeedEmoji.js index bf316116b59..a959141ce81 100644 --- a/src/components/gas/GasSpeedEmoji.js +++ b/src/components/gas/GasSpeedEmoji.js @@ -7,15 +7,15 @@ import { gasUtils } from '../../utils'; import { Emoji } from '../text'; const EmojiForGasSpeedType = { - fast: { + [gasUtils.FAST]: { emoji: 'rocket', // 🚀️ position: [1, 2], // x: 1, y: 2 }, - normal: { + [gasUtils.NORMAL]: { emoji: 'stopwatch', // ⏱️ position: [2, 1], // x: 2, y: 1 }, - slow: { + [gasUtils.SLOW]: { emoji: 'snail', // 🐌️ position: [1, 0], // x: 1, y: 0 }, @@ -24,7 +24,7 @@ const EmojiForGasSpeedType = { const GasSpeedEmoji = ({ label }) => { const gasSpeed = has(EmojiForGasSpeedType, label) ? EmojiForGasSpeedType[label] - : EmojiForGasSpeedType.normal; + : EmojiForGasSpeedType[gasUtils.NORMAL]; return ( @@ -43,7 +43,7 @@ const GasSpeedEmoji = ({ label }) => { }; GasSpeedEmoji.propTypes = { - label: PropTypes.oneOf(gasUtils.GasSpeedTypes), + label: PropTypes.oneOf(gasUtils.GasSpeedOrder), }; export default onlyUpdateForKeys(['label'])(GasSpeedEmoji); diff --git a/src/components/gas/GasSpeedLabelPager.js b/src/components/gas/GasSpeedLabelPager.js index 4e93fb18c2d..aa2481c3cd4 100644 --- a/src/components/gas/GasSpeedLabelPager.js +++ b/src/components/gas/GasSpeedLabelPager.js @@ -10,7 +10,7 @@ const GasSpeedLabelPager = ({ label }) => { return ( - {gasUtils.GasSpeedTypes.map(speed => ( + {gasUtils.GasSpeedOrder.map(speed => ( { }; GasSpeedLabelPager.propTypes = { - label: PropTypes.oneOf(gasUtils.GasSpeedTypes), + label: PropTypes.oneOf(gasUtils.GasSpeedOrder), }; export default React.memo(GasSpeedLabelPager); diff --git a/src/components/gas/GasSpeedLabelPagerItem.js b/src/components/gas/GasSpeedLabelPagerItem.js index e933d1a6372..f59c86ab3f7 100644 --- a/src/components/gas/GasSpeedLabelPagerItem.js +++ b/src/components/gas/GasSpeedLabelPagerItem.js @@ -42,9 +42,9 @@ const GasSpeedLabelPagerItem = ({ label, selected, shouldAnimate }) => { ref.current.animateNextTransition(); } - const index = gasUtils.GasSpeedTypes.indexOf(label); + const index = gasUtils.GasSpeedOrder.indexOf(label); const isFirst = index === 0; - const isLast = index === gasUtils.GasSpeedTypes.length - 1; + const isLast = index === gasUtils.GasSpeedOrder.length - 1; const transitionVal = useTransition( selected, @@ -111,7 +111,7 @@ const GasSpeedLabelPagerItem = ({ label, selected, shouldAnimate }) => { }; GasSpeedLabelPagerItem.propTypes = { - label: PropTypes.oneOf(gasUtils.GasSpeedTypes), + label: PropTypes.oneOf(gasUtils.GasSpeedOrder), selected: PropTypes.bool, shouldAnimate: PropTypes.bool, }; diff --git a/src/parsers/gas.js b/src/parsers/gas.js index 280f8c8f6bd..33374338c56 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -1,7 +1,6 @@ import { get, map, - values, zipObject, } from 'lodash'; import { getMinimalTimeUnitStringForMs } from '../helpers/time'; @@ -13,7 +12,7 @@ import { } from '../helpers/utilities'; import timeUnits from '../references/time-units.json'; import ethUnits from '../references/ethereum-units.json'; -import { GasSpeed } from '../utils/gas'; +import { gasUtils } from '../utils'; /** * @desc parse ether gas prices @@ -21,9 +20,9 @@ import { GasSpeed } from '../utils/gas'; * @param {Boolean} short - use short format or not */ export const getFallbackGasPrices = (short = true) => ({ - [GasSpeed.fast]: defaultGasPriceFormat(GasSpeed.fast, '0.5', '200', short), - [GasSpeed.normal]: defaultGasPriceFormat(GasSpeed.normal, '2.5', '100', short), - [GasSpeed.slow]: defaultGasPriceFormat(GasSpeed.slow, '2.5', '100', short), + [gasUtils.FAST]: defaultGasPriceFormat(gasUtils.FAST, '0.5', '200', short), + [gasUtils.NORMAL]: defaultGasPriceFormat(gasUtils.NORMAL, '2.5', '100', short), + [gasUtils.SLOW]: defaultGasPriceFormat(gasUtils.SLOW, '2.5', '100', short), }); /** @@ -35,9 +34,9 @@ export const parseGasPrices = (data, short = true) => !data ? getFallbackGasPrices() : ({ - [GasSpeed.fast]: defaultGasPriceFormat(GasSpeed.fast, data.fastWait, data.fast, short), - [GasSpeed.normal]: defaultGasPriceFormat(GasSpeed.normal, data.avgWait, data.average, short), - [GasSpeed.slow]: defaultGasPriceFormat(GasSpeed.slow, data.safeLowWait, data.safeLow, short), + [gasUtils.FAST]: defaultGasPriceFormat(gasUtils.FAST, data.fastWait, data.fast, short), + [gasUtils.NORMAL]: defaultGasPriceFormat(gasUtils.NORMAL, data.avgWait, data.average, short), + [gasUtils.SLOW]: defaultGasPriceFormat(gasUtils.SLOW, data.safeLowWait, data.safeLow, short), }) ); @@ -65,14 +64,13 @@ const defaultGasPriceFormat = (option, timeWait, value) => { * @param {Number} gasLimit */ export const parseTxFees = (gasPrices, priceUnit, gasLimit, nativeCurrency) => { - const gasSpeedLabels = values(GasSpeed); - const txFees = map(gasSpeedLabels, (speed) => { + const txFees = map(gasUtils.GasSpeedOrder, (speed) => { const gasPrice = get(gasPrices, `${speed}.value.amount`); return { txFee: getTxFee(gasPrice, gasLimit, priceUnit, nativeCurrency), }; }); - return zipObject(gasSpeedLabels, txFees); + return zipObject(gasUtils.GasSpeedOrder, txFees); }; const getTxFee = (gasPrice, gasLimit, priceUnit, nativeCurrency) => { diff --git a/src/redux/gas.js b/src/redux/gas.js index 21651b019c2..f5a44ee6472 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -7,8 +7,7 @@ import { parseTxFees, } from '../parsers/gas'; import ethUnits from '../references/ethereum-units.json'; -import { ethereumUtils } from '../utils'; -import { GasSpeed } from '../utils/gas'; +import { ethereumUtils, gasUtils } from '../utils'; // -- Constants ------------------------------------------------------------- // @@ -43,8 +42,8 @@ const getDefaultTxFees = () => (dispatch, getState) => { nativeCurrency ); const selectedGasPrice = { - ...txFees.average, - ...fallbackGasPrices.average, + ...txFees[gasUtils.NORMAL], + ...fallbackGasPrices[gasUtils.NORMAL], }; return { fallbackGasPrices, @@ -202,7 +201,7 @@ const INITIAL_STATE = { gasPrices: {}, isSufficientGas: false, selectedGasPrice: {}, - selectedGasPriceOption: GasSpeed.normal, + selectedGasPriceOption: gasUtils.NORMAL, txFees: {}, useShortGasFormat: true, }; diff --git a/src/utils/gas.js b/src/utils/gas.js index b0042260405..ee8081d2d42 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -10,13 +10,11 @@ import { } from 'lodash'; import { showActionSheetWithOptions } from './actionsheet'; -export const GasSpeed = { - fast: 'fast', - normal: 'normal', - slow: 'slow', -}; +const FAST = 'fast'; +const NORMAL = 'normal'; +const SLOW = 'slow'; -const labelOrder = [GasSpeed.slow, GasSpeed.normal, GasSpeed.fast]; +const GasSpeedOrder = [SLOW, NORMAL, FAST]; const showTransactionSpeedOptions = ( gasPrices, @@ -51,7 +49,7 @@ const showTransactionSpeedOptions = ( }; const formatGasSpeedItems = (gasPrices, txFees) => { - const gasItems = map(labelOrder, (speed) => { + const gasItems = map(GasSpeedOrder, (speed) => { const cost = get(txFees, `[${speed}].txFee.native.value.display`); const gwei = get(gasPrices, `[${speed}].value.display`); const time = get(gasPrices, `[${speed}].estimatedTime.display`); @@ -62,10 +60,13 @@ const formatGasSpeedItems = (gasPrices, txFees) => { speed, }; }); - return sortBy(gasItems, ({ speed }) => indexOf(labelOrder, speed)); + return sortBy(gasItems, ({ speed }) => indexOf(GasSpeedOrder, speed)); }; export default { - GasSpeedTypes, + FAST, + GasSpeedOrder, + NORMAL, showTransactionSpeedOptions, + SLOW, }; diff --git a/yarn.lock b/yarn.lock index 61b2347e4b2..89072ab21ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1318,19 +1318,28 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": +<<<<<<< HEAD version "12.7.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.7.tgz#f9bd8c00fa9e1a8129af910fc829f6139c397d6c" integrity sha512-4jUncNe2tj1nmrO/34PsRpZqYVnRV1svbU78cKhuQKkMntKB/AmdLyGgswcZKjFHEHGpiY8pVD8CuVI55nP54w== +======= + version "12.7.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.8.tgz#cb1bf6800238898bc2ff6ffa5702c3cadd350708" + integrity sha512-FMdVn84tJJdV+xe+53sYiZS4R5yn1mAIxfj+DVoNiQjTYz1+OYmjwEZr1ev9nU0axXwda0QDbYl06QHanRVH3A== +>>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation "@types/node@^10.3.2": version "10.14.19" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.19.tgz#f52742c7834a815dedf66edfc8a51547e2a67342" integrity sha512-j6Sqt38ssdMKutXBUuAcmWF8QtHW1Fwz/mz4Y+Wd9mzpBiVFirjpNQf363hG5itkG+yGaD+oiLyb50HxJ36l9Q== +<<<<<<< HEAD "@types/node@^8.0.7": version "8.10.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== +======= +>>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2891,6 +2900,14 @@ configstore@^3.0.0: write-file-atomic "^2.0.0" xdg-basedir "^3.0.0" +<<<<<<< HEAD +======= +confusing-browser-globals@^1.0.5: + version "1.0.9" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" + integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== + +>>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation connect@^3.6.5: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -3139,11 +3156,9 @@ dashify@^2.0.0: integrity sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A== data-uri-to-buffer@2: - version "2.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.1.tgz#ca8f56fe38b1fd329473e9d1b4a9afcd8ce1c045" - integrity sha512-OkVVLrerfAKZlW2ZZ3Ve2y65jgiWqBKsTfUIAFbn8nVbPcCZg6l6gikKlEYv0kXcmzqGm6mFq/Jf2vriuEkv8A== - dependencies: - "@types/node" "^8.0.7" + version "2.0.2" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz#d296973d5a4897a5dbe31716d118211921f04770" + integrity sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA== data-urls@^1.0.0: version "1.1.0" @@ -3524,9 +3539,15 @@ ejs@^2.7.1: integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.247: +<<<<<<< HEAD version "1.3.266" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.266.tgz#a33fb529c75f8d133e75ea7cbedb73a62f2158d2" integrity sha512-UTuTZ4v8T0gLPHI7U75PXLQePWI65MTS3mckRrnLCkNljHvsutbYs+hn2Ua/RFul3Jt/L3Ht2rLP+dU/AlBfrQ== +======= + version "1.3.267" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.267.tgz#7745ff9d447fd2a9802e1c6dfa518631e0cf5357" + integrity sha512-9Q2ixAJC+oHjWNtJV0MQ4vJMCWSowIrC6V6vcr+bwPddTDHj2ddv9xxXCzf4jT/fy6HP7maPoW0gifXkRxCttQ== +>>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation elliptic@6.3.3: version "6.3.3" @@ -4823,9 +4844,15 @@ hammerjs@^2.0.8: integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= handlebars@^4.1.2: +<<<<<<< HEAD version "4.3.1" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.1.tgz#6febc1890851f62a8932d495cc88d29390fa850d" integrity sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA== +======= + version "4.3.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.3.tgz#56dd05fe33d6bd8a7d797351c39a0cdcfd576be5" + integrity sha512-VupOxR91xcGojfINrzMqrvlyYbBs39sXIrWa7YdaQWeBudOlvKEGvCczMfJPgnuwHE/zyH1M6J+IUP6cgDVyxg== +>>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -7027,9 +7054,9 @@ mime-db@1.40.0: integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== "mime-db@>= 1.40.0 < 2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.41.0.tgz#9110408e1f6aa1b34aef51f2c9df3caddf46b6a0" - integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw== + version "1.42.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" + integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== mime-db@~1.23.0: version "1.23.0" @@ -7122,20 +7149,35 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= +<<<<<<< HEAD minipass@^2.2.1, minipass@^2.6.0, minipass@^2.8.6: version "2.8.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.8.6.tgz#620d889ace26356391d010ecb9458749df9b6db5" integrity sha512-lFG7d6g3+/UaFDCOtqPiKAC9zngWWsQZl1g5q6gaONqrjq61SX2xFqXMleQiFVyDpYwa018E9hmlAFY22PCb+A== +======= +minipass@^2.6.0, minipass@^2.8.6: + version "2.8.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.8.6.tgz#620d889ace26356391d010ecb9458749df9b6db5" + integrity sha512-lFG7d6g3+/UaFDCOtqPiKAC9zngWWsQZl1g5q6gaONqrjq61SX2xFqXMleQiFVyDpYwa018E9hmlAFY22PCb+A== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== +>>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" minizlib@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.2.tgz#6f0ccc82fa53e1bf2ff145f220d2da9fa6e3a166" - integrity sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.2.tgz#5d24764998f98112586f7e566bd4c0999769dad4" + integrity sha512-lsNFqSHdJ21EwKzCp12HHJGxSMtHkCW1EMA9cceG3MkMNARjuWotZnMe3NKNshAvFXpm4loZqmYsCmRwhS2JMw== dependencies: - minipass "^2.2.1" + minipass "^2.9.0" mixin-deep@^1.2.0: version "1.3.2" @@ -11581,9 +11623,9 @@ yallist@^2.1.2: integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + version "3.1.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.0.tgz#906cc2100972dc2625ae78f566a2577230a1d6f7" + integrity sha512-6gpP93MR+VOOehKbCPchro3wFZNSNmek8A2kbkOAZLIZAYx1KP/zAqwO0sOHi3xJEb+UBz8NaYt/17UNit1Q9w== yargs-parser@13.0.0: version "13.0.0" From a4b9846ea342a25b13feb65ea0f298587c2cb004 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 28 Sep 2019 22:18:42 -0400 Subject: [PATCH 354/636] cleanup given new eslint rules --- src/components/SendComponentWithData.js | 14 +- .../exchange/ConfirmExchangeButton.js | 30 +-- src/components/gas/GasSpeedButton.js | 9 +- src/handlers/localstorage/common.js | 1 + src/handlers/uniswap.js | 158 ++++++++------- src/handlers/web3.js | 2 +- src/helpers/sortList.js | 7 +- src/helpers/transactions.js | 12 +- src/hoc/withUniswapAllowances.js | 22 +-- src/parsers/accounts.js | 4 +- src/parsers/gas.js | 54 +++-- src/parsers/newTransaction.js | 8 +- src/parsers/transactions.js | 105 ++++++---- src/parsers/uniqueTokens.js | 23 +-- src/redux/data.js | 20 +- src/redux/gas.js | 121 ++++++------ src/redux/uniqueTokens.js | 5 +- src/redux/uniswap.js | 187 ++++++++++-------- src/screens/ExchangeModal.js | 64 +++--- src/utils/contract.js | 7 +- src/utils/ethereumUtils.js | 7 +- src/utils/gas.js | 2 +- yarn.lock | 107 ++++------ 23 files changed, 500 insertions(+), 469 deletions(-) diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index 93eaba019f1..f10dd76ad6d 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -55,7 +55,7 @@ export const withSendComponentWithData = (SendComponent, options) => { fetching: PropTypes.bool.isRequired, gasLimit: PropTypes.number, gasPrices: PropTypes.object.isRequired, - gasUpdateDefaultGasLimit: PropTypes.func, + gasUpdateDefaultGasLimit: PropTypes.func.isRequired, gasUpdateTxFee: PropTypes.func.isRequired, isSufficientBalance: PropTypes.bool.isRequired, isSufficientGas: PropTypes.bool.isRequired, @@ -121,11 +121,13 @@ export const withSendComponentWithData = (SendComponent, options) => { amount: assetAmount, asset: selected, recipient, - }).then(gasLimit => { - this.props.gasUpdateTxFee(gasLimit); - }).catch(error => { - this.props.gasUpdateTxFee(null); - }); + }) + .then(gasLimit => { + this.props.gasUpdateTxFee(gasLimit); + }) + .catch(() => { + this.props.gasUpdateTxFee(null); + }); } } } diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index ad2d36894e7..01c040a1d9d 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -8,36 +8,25 @@ import { Text } from '../text'; import { SlippageWarningTheshold } from './SlippageWarning'; // lol this isnt done -const UnlockingSpinner = ({ timeRemaining, ...props }) => ( +const UnlockingSpinner = ({ timeRemaining }) => ( - + Unlocking - + {`~ ${timeRemaining} Remaining`} ); UnlockingSpinner.propTypes = { - creationTimestamp: PropTypes.number, timeRemaining: PropTypes.string, }; const ConfirmExchangeButton = ({ - creationTimestamp, disabled, inputCurrencyName, isAssetApproved, @@ -77,19 +66,16 @@ const ConfirmExchangeButton = ({ theme="dark" {...props} > - {isUnlockingAsset - ? - : undefined - } + {isUnlockingAsset ? ( + + ) : ( + undefined + )} ); }; ConfirmExchangeButton.propTypes = { - creationTimestamp: PropTypes.number, disabled: PropTypes.bool, inputCurrencyName: PropTypes.string, isAssetApproved: PropTypes.bool, diff --git a/src/components/gas/GasSpeedButton.js b/src/components/gas/GasSpeedButton.js index 53ed6ef312c..c2ce246fae3 100644 --- a/src/components/gas/GasSpeedButton.js +++ b/src/components/gas/GasSpeedButton.js @@ -38,7 +38,7 @@ class GasSpeedButton extends PureComponent { nativeCurrencySymbol: PropTypes.string, price: PropTypes.string, selectedGasPriceOption: PropTypes.oneOf(gasUtils.GasSpeedOrder), - } + }; handlePress = () => { const { @@ -49,8 +49,11 @@ class GasSpeedButton extends PureComponent { LayoutAnimation.easeInEaseOut(); - const currentSpeedIndex = gasUtils.GasSpeedOrder.indexOf(selectedGasPriceOption); - const nextSpeedIndex = (currentSpeedIndex + 1) % gasUtils.GasSpeedOrder.length; + const currentSpeedIndex = gasUtils.GasSpeedOrder.indexOf( + selectedGasPriceOption + ); + const nextSpeedIndex = + (currentSpeedIndex + 1) % gasUtils.GasSpeedOrder.length; const nextSpeed = gasUtils.GasSpeedOrder[nextSpeedIndex]; const nextSpeedGweiValue = get(gasPrices, `[${nextSpeed}].value.display`); diff --git a/src/handlers/localstorage/common.js b/src/handlers/localstorage/common.js index 20f8da84c96..6e16f349e1e 100644 --- a/src/handlers/localstorage/common.js +++ b/src/handlers/localstorage/common.js @@ -1,3 +1,4 @@ +/*global storage*/ import { toLower } from 'lodash'; const defaultVersion = '0.1.0'; diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 6fa7ea866c0..fb824c06963 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -1,15 +1,7 @@ import { getExecutionDetails, getTokenReserves } from '@uniswap/sdk'; import contractMap from 'eth-contract-metadata'; import { ethers } from 'ethers'; -import { - compact, - get, - keyBy, - map, - slice, - toLower, - zipObject, -} from 'lodash'; +import { compact, get, keyBy, map, slice, toLower, zipObject } from 'lodash'; import { convertRawAmountToDecimalFormat, divide, @@ -40,44 +32,52 @@ export const getReserves = async () => { const reserves = await promiseUtils.PromiseAllWithFails( map(uniswapTokens, token => getTokenReserves(token)) ); - return keyBy(compact(reserves), reserve => toLower(get(reserve, 'token.address'))); + return keyBy(compact(reserves), reserve => + toLower(get(reserve, 'token.address')) + ); }; -const getGasLimit = async (accountAddress, exchange, methodName, updatedMethodArgs, value) => { +const getGasLimit = async ( + accountAddress, + exchange, + methodName, + updatedMethodArgs, + value +) => { const params = { from: accountAddress, value }; switch (methodName) { - case 'ethToTokenSwapInput': - return exchange.estimate.ethToTokenSwapInput( - ...updatedMethodArgs, - params, - ); - case 'ethToTokenSwapOutput': - return exchange.estimate.ethToTokenSwapOutput( - ...updatedMethodArgs, - params, - ); - case 'tokenToEthSwapInput': - return exchange.estimate.tokenToEthSwapInput( - ...updatedMethodArgs, - params, - ); - case 'tokenToEthSwapOutput': - return exchange.estimate.tokenToEthSwapOutput( - ...updatedMethodArgs, - params, - ); - case 'tokenToTokenSwapInput': - return exchange.estimate.tokenToTokenSwapInput( - ...updatedMethodArgs, - params, - ); - case 'tokenToTokenSwapOutput': - return exchange.estimate.tokenToTokenSwapOutput( - ...updatedMethodArgs, - params, - ); - default: - return null; + case 'ethToTokenSwapInput': + return exchange.estimate.ethToTokenSwapInput( + ...updatedMethodArgs, + params + ); + case 'ethToTokenSwapOutput': + return exchange.estimate.ethToTokenSwapOutput( + ...updatedMethodArgs, + params + ); + case 'tokenToEthSwapInput': + return exchange.estimate.tokenToEthSwapInput( + ...updatedMethodArgs, + params + ); + case 'tokenToEthSwapOutput': + return exchange.estimate.tokenToEthSwapOutput( + ...updatedMethodArgs, + params + ); + case 'tokenToTokenSwapInput': + return exchange.estimate.tokenToTokenSwapInput( + ...updatedMethodArgs, + params + ); + case 'tokenToTokenSwapOutput': + return exchange.estimate.tokenToTokenSwapOutput( + ...updatedMethodArgs, + params + ); + default: + return null; } }; @@ -89,7 +89,13 @@ export const estimateSwapGasLimit = async (accountAddress, tradeDetails) => { updatedMethodArgs, value, } = getContractExecutionDetails(tradeDetails, web3Provider); - const gasLimit = await getGasLimit(accountAddress, exchange, methodName, updatedMethodArgs, value); + const gasLimit = await getGasLimit( + accountAddress, + exchange, + methodName, + updatedMethodArgs, + value + ); return gasLimit ? gasLimit.toString() : null; } catch (error) { return null; @@ -134,38 +140,38 @@ export const executeSwap = async (tradeDetails, gasLimit, gasPrice) => { value, }; switch (methodName) { - case 'ethToTokenSwapInput': - return exchange.ethToTokenSwapInput( - ...updatedMethodArgs, - transactionParams, - ); - case 'ethToTokenSwapOutput': - return exchange.ethToTokenSwapOutput( - ...updatedMethodArgs, - transactionParams, - ); - case 'tokenToEthSwapInput': - return exchange.tokenToEthSwapInput( - ...updatedMethodArgs, - transactionParams, - ); - case 'tokenToEthSwapOutput': - return exchange.tokenToEthSwapOutput( - ...updatedMethodArgs, - transactionParams, - ); - case 'tokenToTokenSwapInput': - return exchange.tokenToTokenSwapInput( - ...updatedMethodArgs, - transactionParams, - ); - case 'tokenToTokenSwapOutput': - return exchange.tokenToTokenSwapOutput( - ...updatedMethodArgs, - transactionParams, - ); - default: - return null; + case 'ethToTokenSwapInput': + return exchange.ethToTokenSwapInput( + ...updatedMethodArgs, + transactionParams + ); + case 'ethToTokenSwapOutput': + return exchange.ethToTokenSwapOutput( + ...updatedMethodArgs, + transactionParams + ); + case 'tokenToEthSwapInput': + return exchange.tokenToEthSwapInput( + ...updatedMethodArgs, + transactionParams + ); + case 'tokenToEthSwapOutput': + return exchange.tokenToEthSwapOutput( + ...updatedMethodArgs, + transactionParams + ); + case 'tokenToTokenSwapInput': + return exchange.tokenToTokenSwapInput( + ...updatedMethodArgs, + transactionParams + ); + case 'tokenToTokenSwapOutput': + return exchange.tokenToTokenSwapOutput( + ...updatedMethodArgs, + transactionParams + ); + default: + return null; } }; diff --git a/src/handlers/web3.js b/src/handlers/web3.js index a09bd8ee8ad..2fed1b85df8 100644 --- a/src/handlers/web3.js +++ b/src/handlers/web3.js @@ -46,7 +46,7 @@ export const isHexStringIgnorePrefix = value => { }; export const addHexPrefix = value => - ((startsWith(value, '0x')) ? value : `0x${value}`); + startsWith(value, '0x') ? value : `0x${value}`; export const mnemonicToSeed = value => ethers.utils.HDNode.mnemonicToSeed(value); diff --git a/src/helpers/sortList.js b/src/helpers/sortList.js index 210a5fc9ff1..9c35f30db16 100644 --- a/src/helpers/sortList.js +++ b/src/helpers/sortList.js @@ -1,9 +1,4 @@ -import { - get, - isFunction, - isString, - toLower, -} from 'lodash'; +import { get, isFunction, isString, toLower } from 'lodash'; export const sortList = ( array = [], diff --git a/src/helpers/transactions.js b/src/helpers/transactions.js index c3680fd477e..92db511cf37 100644 --- a/src/helpers/transactions.js +++ b/src/helpers/transactions.js @@ -27,11 +27,7 @@ const groupTransactionByDate = ({ pending, minedAt }) => { return format(timestamp, `MMMM${isThisYear(timestamp) ? '' : ' YYYY'}`); }; -const buildTransactionsSections = ( - accountAddress, - requests, - transactions -) => { +const buildTransactionsSections = (accountAddress, requests, transactions) => { let sectionedTransactions = []; if (!isEmpty(transactions)) { @@ -59,10 +55,6 @@ const buildTransactionsSections = ( }; export const buildTransactionsSectionsSelector = createSelector( - [ - accountAddressSelector, - requestsSelector, - transactionsSelector, - ], + [accountAddressSelector, requestsSelector, transactionsSelector], buildTransactionsSections ); diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index cce1986889f..b26cdbe18b7 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -6,21 +6,19 @@ import { } from '../redux/uniswap'; const mapStateToProps = ({ - uniswap: { - allowances, - pendingApprovals, - tokenReserves, - }, + uniswap: { allowances, pendingApprovals, tokenReserves }, }) => ({ allowances, pendingApprovals, tokenReserves, }); -export default Component => ( - connect(mapStateToProps, { - uniswapGetTokenReserve, - uniswapUpdateAllowances, - uniswapUpdatePendingApprovals, - })(Component) -); +export default Component => + connect( + mapStateToProps, + { + uniswapGetTokenReserve, + uniswapUpdateAllowances, + uniswapUpdatePendingApprovals, + } + )(Component); diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index 6138e312bc8..ba75c84c740 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -18,9 +18,7 @@ export const parseAccountAssets = (data, uniqueTokens) => { }; }); - return assets.filter( - asset => !!Number(get(asset, 'balance.amount')), - ); + return assets.filter(asset => !!Number(get(asset, 'balance.amount'))); }; /** diff --git a/src/parsers/gas.js b/src/parsers/gas.js index 33374338c56..7237493163e 100644 --- a/src/parsers/gas.js +++ b/src/parsers/gas.js @@ -1,8 +1,4 @@ -import { - get, - map, - zipObject, -} from 'lodash'; +import { get, map, zipObject } from 'lodash'; import { getMinimalTimeUnitStringForMs } from '../helpers/time'; import { convertRawAmountToBalance, @@ -21,7 +17,12 @@ import { gasUtils } from '../utils'; */ export const getFallbackGasPrices = (short = true) => ({ [gasUtils.FAST]: defaultGasPriceFormat(gasUtils.FAST, '0.5', '200', short), - [gasUtils.NORMAL]: defaultGasPriceFormat(gasUtils.NORMAL, '2.5', '100', short), + [gasUtils.NORMAL]: defaultGasPriceFormat( + gasUtils.NORMAL, + '2.5', + '100', + short + ), [gasUtils.SLOW]: defaultGasPriceFormat(gasUtils.SLOW, '2.5', '100', short), }); @@ -33,12 +34,26 @@ export const getFallbackGasPrices = (short = true) => ({ export const parseGasPrices = (data, short = true) => !data ? getFallbackGasPrices() - : ({ - [gasUtils.FAST]: defaultGasPriceFormat(gasUtils.FAST, data.fastWait, data.fast, short), - [gasUtils.NORMAL]: defaultGasPriceFormat(gasUtils.NORMAL, data.avgWait, data.average, short), - [gasUtils.SLOW]: defaultGasPriceFormat(gasUtils.SLOW, data.safeLowWait, data.safeLow, short), - }) -); + : { + [gasUtils.FAST]: defaultGasPriceFormat( + gasUtils.FAST, + data.fastWait, + data.fast, + short + ), + [gasUtils.NORMAL]: defaultGasPriceFormat( + gasUtils.NORMAL, + data.avgWait, + data.average, + short + ), + [gasUtils.SLOW]: defaultGasPriceFormat( + gasUtils.SLOW, + data.safeLowWait, + data.safeLow, + short + ), + }; const defaultGasPriceFormat = (option, timeWait, value) => { const timeAmount = multiply(timeWait, timeUnits.ms.minute); @@ -64,7 +79,7 @@ const defaultGasPriceFormat = (option, timeWait, value) => { * @param {Number} gasLimit */ export const parseTxFees = (gasPrices, priceUnit, gasLimit, nativeCurrency) => { - const txFees = map(gasUtils.GasSpeedOrder, (speed) => { + const txFees = map(gasUtils.GasSpeedOrder, speed => { const gasPrice = get(gasPrices, `${speed}.value.amount`); return { txFee: getTxFee(gasPrice, gasLimit, priceUnit, nativeCurrency), @@ -81,18 +96,15 @@ const getTxFee = (gasPrice, gasLimit, priceUnit, nativeCurrency) => { amount, 18, priceUnit, - nativeCurrency, + nativeCurrency ), }, value: { amount, - display: convertRawAmountToBalance( - amount, - { - decimals: 18, - symbol: 'ETH', - }, - ), + display: convertRawAmountToBalance(amount, { + decimals: 18, + symbol: 'ETH', + }), }, }; }; diff --git a/src/parsers/newTransaction.js b/src/parsers/newTransaction.js index dd845b896ee..3f82473e31d 100644 --- a/src/parsers/newTransaction.js +++ b/src/parsers/newTransaction.js @@ -29,13 +29,7 @@ export const parseNewTransaction = async ( get(txDetails, 'asset.price.value', 0), nativeCurrency ); - let tx = pick(txDetails, [ - 'dappName', - 'from', - 'hash', - 'nonce', - 'to', - ]); + let tx = pick(txDetails, ['dappName', 'from', 'hash', 'nonce', 'to']); const nonce = tx.nonce || (tx.from ? await getTransactionCount(tx.from) : ''); tx = { ...tx, diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index e06539f7800..6758e8db742 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -20,17 +20,18 @@ import TransactionStatusTypes from '../helpers/transactionStatusTypes'; import { convertRawAmountToBalance, convertRawAmountToNativeDisplay, - subtract, } from '../helpers/utilities'; import { isLowerCaseMatch } from '../utils'; const DIRECTION_OUT = 'out'; const dataFromLastTxHash = (transactionData, transactions) => { - const lastSuccessfulTxn = find(transactions, (txn) => txn.hash && !txn.pending); + const lastSuccessfulTxn = find(transactions, txn => txn.hash && !txn.pending); const lastTxHash = lastSuccessfulTxn ? lastSuccessfulTxn.hash : ''; if (lastTxHash) { - const lastTxnHashIndex = findIndex(transactionData, (txn) => lastTxHash.startsWith(txn.hash)); + const lastTxnHashIndex = findIndex(transactionData, txn => + lastTxHash.startsWith(txn.hash) + ); if (lastTxnHashIndex > -1) { return slice(transactionData, 0, lastTxnHashIndex); } @@ -43,26 +44,53 @@ export default ( accountAddress, nativeCurrency, existingTransactions, - appended = false, + appended = false ) => { - const data = appended ? dataFromLastTxHash(transactionData, existingTransactions) : transactionData; - const parsedNewTransactions = flatten(data.map(txn => parseTransaction(txn, accountAddress, nativeCurrency))); - const [pendingTransactions, remainingTransactions] = partition(existingTransactions, (txn) => txn.pending); - const [approvalTransactions, parsedTransactions] = partition(parsedNewTransactions, txn => txn.type === 'authorize'); - const updatedPendingTransactions = dedupePendingTransactions(pendingTransactions, parsedTransactions); - const updatedResults = concat(updatedPendingTransactions, parsedTransactions, remainingTransactions); - const dedupedResults = uniqBy(updatedResults, (txn) => txn.hash); + const data = appended + ? dataFromLastTxHash(transactionData, existingTransactions) + : transactionData; + const parsedNewTransactions = flatten( + data.map(txn => parseTransaction(txn, accountAddress, nativeCurrency)) + ); + const [pendingTransactions, remainingTransactions] = partition( + existingTransactions, + txn => txn.pending + ); + const [approvalTransactions, parsedTransactions] = partition( + parsedNewTransactions, + txn => txn.type === 'authorize' + ); + const updatedPendingTransactions = dedupePendingTransactions( + pendingTransactions, + parsedTransactions + ); + const updatedResults = concat( + updatedPendingTransactions, + parsedTransactions, + remainingTransactions + ); + const dedupedResults = uniqBy(updatedResults, txn => txn.hash); return { approvalTransactions, dedupedResults }; }; -const transformUniswapRefund = (internalTransactions) => { - const [txnsOut, txnsIn] = partition(internalTransactions, txn => txn.direction === DIRECTION_OUT); - const isSuccessfulSwap = txnsOut.length === 1 && (txnsIn.length === 1 || txnsIn.length === 2); +const transformUniswapRefund = internalTransactions => { + const [txnsOut, txnsIn] = partition( + internalTransactions, + txn => txn.direction === DIRECTION_OUT + ); + const isSuccessfulSwap = + txnsOut.length === 1 && (txnsIn.length === 1 || txnsIn.length === 2); if (!isSuccessfulSwap) return internalTransactions; const txnOut = txnsOut[0]; - const txnIn = find(txnsIn, (txn) => txn.asset.asset_code !== txnOut.asset.asset_code); - const refund = find(txnsIn, (txn) => txn.asset.asset_code === txnOut.asset.asset_code); + const txnIn = find( + txnsIn, + txn => txn.asset.asset_code !== txnOut.asset.asset_code + ); + const refund = find( + txnsIn, + txn => txn.asset.asset_code === txnOut.asset.asset_code + ); let updatedOut = txnOut; if (refund && txnOut) { updatedOut = { @@ -81,23 +109,27 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { 'status', 'type', ]); - transaction.from = txn.address_from; // eslint-disable-line camelcase - transaction.minedAt = txn.mined_at; // eslint-disable-line camelcase + transaction.from = txn.address_from; + transaction.minedAt = txn.mined_at; transaction.pending = false; - transaction.to = txn.address_to; // eslint-disable-line camelcase + transaction.to = txn.address_to; const changes = get(txn, 'changes', []); let internalTransactions = changes; if (isEmpty(changes) && txn.type === 'authorize') { const assetInternalTransaction = { - address_from: transaction.from, // eslint-disable-line camelcase - address_to: transaction.to, // eslint-disable-line camelcase + address_from: transaction.from, + address_to: transaction.to, asset: get(txn, 'meta.asset'), spender: get(txn, 'meta.spender'), }; internalTransactions = [assetInternalTransaction]; } // logic below: prevent sending yourself money to be seen as a trade - if (changes.length === 2 && get(changes, '[0].asset.asset_code') === get(changes, '[1].asset.asset_code')) { + if ( + changes.length === 2 && + get(changes, '[0].asset.asset_code') === + get(changes, '[1].asset.asset_code') + ) { internalTransactions = [changes[0]]; } // logic below: prevent sending a WalletConnect 0 amount to be seen as a Cancel @@ -137,7 +169,7 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { internalTxn.address_from, transaction.pending, transaction.status, - internalTxn.address_to, + internalTxn.address_to ); return { @@ -158,23 +190,24 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { const dedupePendingTransactions = (pendingTransactions, parsedTransactions) => { let updatedPendingTransactions = pendingTransactions; if (pendingTransactions.length) { - updatedPendingTransactions = filter(updatedPendingTransactions, (pendingTxn) => { - const matchingElement = find(parsedTransactions, (txn) => txn.hash - && (startsWith(toLower(txn.hash), toLower(pendingTxn.hash)) - || (txn.nonce && (txn.nonce >= pendingTxn.nonce)))); - return !matchingElement; - }); + updatedPendingTransactions = filter( + updatedPendingTransactions, + pendingTxn => { + const matchingElement = find( + parsedTransactions, + txn => + txn.hash && + (startsWith(toLower(txn.hash), toLower(pendingTxn.hash)) || + (txn.nonce && txn.nonce >= pendingTxn.nonce)) + ); + return !matchingElement; + } + ); } return updatedPendingTransactions; }; -const getTransactionLabel = ( - accountAddress, - from, - pending, - status, - to, -) => { +const getTransactionLabel = (accountAddress, from, pending, status, to) => { const isFromAccount = isLowerCaseMatch(from, accountAddress); const isToAccount = isLowerCaseMatch(to, accountAddress); diff --git a/src/parsers/uniqueTokens.js b/src/parsers/uniqueTokens.js index 02241c17587..9080c0ebed2 100644 --- a/src/parsers/uniqueTokens.js +++ b/src/parsers/uniqueTokens.js @@ -1,11 +1,4 @@ -import { - filter, - find, - get, - map, - pick, - uniq, -} from 'lodash'; +import { filter, find, get, map, pick, uniq } from 'lodash'; /** * @desc parse unique tokens from opensea @@ -68,12 +61,20 @@ export const dedupeUniqueTokens = (assets, uniqueTokens) => { const uniqueTokenFamilies = getFamilies(uniqueTokens); let updatedAssets = assets; if (assets.length) { - updatedAssets = filter(updatedAssets, (asset) => { - const matchingElement = find(uniqueTokenFamilies, (uniqueTokenFamily) => uniqueTokenFamily === get(asset, 'asset.asset_code')); + updatedAssets = filter(updatedAssets, asset => { + const matchingElement = find( + uniqueTokenFamilies, + uniqueTokenFamily => + uniqueTokenFamily === get(asset, 'asset.asset_code') + ); return !matchingElement; }); } return updatedAssets; }; -export const dedupeAssetsWithFamilies = (assets, families) => filter(assets, (asset) => !find(families, (family) => family === get(asset, 'address'))); +export const dedupeAssetsWithFamilies = (assets, families) => + filter( + assets, + asset => !find(families, family => family === get(asset, 'address')) + ); diff --git a/src/redux/data.js b/src/redux/data.js index 399b00cf9a3..ec047a59c81 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -1,12 +1,4 @@ -import { - concat, - get, - includes, - isNil, - map, - remove, - uniqBy, -} from 'lodash'; +import { concat, get, includes, isNil, map, remove, uniqBy } from 'lodash'; import { getAssets, getLocalTransactions, @@ -77,7 +69,7 @@ export const dataClearState = () => (dispatch, getState) => { dispatch({ type: DATA_CLEAR_STATE }); }; -export const dataUpdateAssets = (assets) => (dispatch, getState) => { +export const dataUpdateAssets = assets => (dispatch, getState) => { const { accountAddress, network } = getState().settings; if (assets.length) { saveAssets(accountAddress, assets, network); @@ -98,8 +90,10 @@ const checkMeta = message => (dispatch, getState) => { ); }; -export const transactionsReceived = (message, appended = false) => (dispatch, getState) => { - console.log('txns received', message); +export const transactionsReceived = (message, appended = false) => ( + dispatch, + getState +) => { const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; const transactionData = get(message, 'payload.transactions', []); @@ -112,7 +106,7 @@ export const transactionsReceived = (message, appended = false) => (dispatch, ge accountAddress, nativeCurrency, transactions, - appended, + appended ); dispatch(uniswapRemovePendingApproval(approvalTransactions)); saveLocalTransactions(accountAddress, dedupedResults, network); diff --git a/src/redux/gas.js b/src/redux/gas.js index f5a44ee6472..41b8db5899b 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -122,7 +122,9 @@ export const gasUpdateGasPriceOption = newGasPriceOption => ( }); }; -export const gasUpdateDefaultGasLimit = (defaultGasLimit = ethUnits.basic_tx) => dispatch => { +export const gasUpdateDefaultGasLimit = ( + defaultGasLimit = ethUnits.basic_tx +) => dispatch => { dispatch({ payload: defaultGasLimit, type: GAS_UPDATE_DEFAULT_GAS_LIMIT, @@ -131,17 +133,18 @@ export const gasUpdateDefaultGasLimit = (defaultGasLimit = ethUnits.basic_tx) => }; export const gasUpdateTxFee = gasLimit => (dispatch, getState) => { - const { - defaultGasLimit, - gasPrices, - selectedGasPriceOption, - } = getState().gas; + const { defaultGasLimit, gasPrices, selectedGasPriceOption } = getState().gas; const _gasLimit = gasLimit || defaultGasLimit; if (isEmpty(gasPrices)) return; const { assets } = getState().data; const { nativeCurrency } = getState().settings; const ethPriceUnit = getEthPriceUnit(assets); - const txFees = parseTxFees(gasPrices, ethPriceUnit, _gasLimit, nativeCurrency); + const txFees = parseTxFees( + gasPrices, + ethPriceUnit, + _gasLimit, + nativeCurrency + ); const results = getSelectedGasPrice( assets, gasPrices, @@ -208,57 +211,57 @@ const INITIAL_STATE = { export default (state = INITIAL_STATE, action) => { switch (action.type) { - case GAS_UPDATE_DEFAULT_GAS_LIMIT: - return { - ...state, - defaultGasLimit: action.payload, - }; - case GAS_PRICES_DEFAULT: - return { - ...state, - fetchingGasPrices: true, - gasPrices: action.payload.gasPrices, - selectedGasPrice: action.payload.selectedGasPrice, - txFees: action.payload.txFees, - }; - case GAS_PRICES_SUCCESS: - return { - ...state, - fetchingGasPrices: false, - gasPrices: action.payload, - }; - case GAS_PRICES_FAILURE: - return { - ...state, - fetchingGasPrices: false, - gasPrices: action.payload, - }; - case GAS_UPDATE_TX_FEE: - return { - ...state, - gasLimit: action.payload.gasLimit, - isSufficientGas: action.payload.isSufficientGas, - selectedGasPrice: action.payload.selectedGasPrice, - txFees: action.payload.txFees, - }; - case GAS_UPDATE_GAS_PRICE_OPTION: - return { - ...state, - isSufficientGas: action.payload.isSufficientGas, - selectedGasPrice: action.payload.selectedGasPrice, - selectedGasPriceOption: action.payload.selectedGasPriceOption, - }; - case GAS_RESET_FIELDS: { - return { - ...INITIAL_STATE, - fetchingGasPrices: state.fetchingGasPrices, - gasPrices: state.gasPrices, - selectedGasPrice: action.payload.selectedGasPrice, - selectedGasPriceOption: state.selectedGasPriceOption, - txFees: action.payload.txFees, - }; - } - default: - return state; + case GAS_UPDATE_DEFAULT_GAS_LIMIT: + return { + ...state, + defaultGasLimit: action.payload, + }; + case GAS_PRICES_DEFAULT: + return { + ...state, + fetchingGasPrices: true, + gasPrices: action.payload.gasPrices, + selectedGasPrice: action.payload.selectedGasPrice, + txFees: action.payload.txFees, + }; + case GAS_PRICES_SUCCESS: + return { + ...state, + fetchingGasPrices: false, + gasPrices: action.payload, + }; + case GAS_PRICES_FAILURE: + return { + ...state, + fetchingGasPrices: false, + gasPrices: action.payload, + }; + case GAS_UPDATE_TX_FEE: + return { + ...state, + gasLimit: action.payload.gasLimit, + isSufficientGas: action.payload.isSufficientGas, + selectedGasPrice: action.payload.selectedGasPrice, + txFees: action.payload.txFees, + }; + case GAS_UPDATE_GAS_PRICE_OPTION: + return { + ...state, + isSufficientGas: action.payload.isSufficientGas, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: action.payload.selectedGasPriceOption, + }; + case GAS_RESET_FIELDS: { + return { + ...INITIAL_STATE, + fetchingGasPrices: state.fetchingGasPrices, + gasPrices: state.gasPrices, + selectedGasPrice: action.payload.selectedGasPrice, + selectedGasPriceOption: state.selectedGasPriceOption, + txFees: action.payload.txFees, + }; + } + default: + return state; } }; diff --git a/src/redux/uniqueTokens.js b/src/redux/uniqueTokens.js index e3d415cba33..7bbb0ecbd84 100644 --- a/src/redux/uniqueTokens.js +++ b/src/redux/uniqueTokens.js @@ -63,7 +63,10 @@ export const uniqueTokensRefreshState = () => (dispatch, getState) => const newFamilies = getFamilies(uniqueTokens); const incomingFamilies = without(newFamilies, ...existingFamilies); if (incomingFamilies.length) { - const dedupedAssets = dedupeAssetsWithFamilies(assets, incomingFamilies); + const dedupedAssets = dedupeAssetsWithFamilies( + assets, + incomingFamilies + ); dispatch(dataUpdateAssets(dedupedAssets)); } saveUniqueTokens(accountAddress, uniqueTokens, network); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 0d51401a79e..7bc86d651da 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -20,11 +20,7 @@ import { removeAccountLocal, saveAccountLocal, } from '../handlers/localstorage/common'; -import { - getLiquidityInfo, - getReserve, - getReserves, -} from '../handlers/uniswap'; +import { getLiquidityInfo, getReserve, getReserves } from '../handlers/uniswap'; import TransactionStatusTypes from '../helpers/transactionStatusTypes'; import { uniswapAssetsClean } from '../references'; import { contractUtils, promiseUtils } from '../utils'; @@ -45,7 +41,8 @@ const UNISWAP_GET_TOKEN_RESERVES_SUCCESS = const UNISWAP_GET_TOKEN_RESERVES_FAILURE = 'uniswap/UNISWAP_GET_TOKEN_RESERVES_FAILURE'; -const UNISWAP_UPDATE_PENDING_APPROVALS = 'uniswap/UNISWAP_UPDATE_PENDING_APPROVALS'; +const UNISWAP_UPDATE_PENDING_APPROVALS = + 'uniswap/UNISWAP_UPDATE_PENDING_APPROVALS'; const UNISWAP_UPDATE_ASSETS = 'uniswap/UNISWAP_UPDATE_ASSETS'; const UNISWAP_UPDATE_ALLOWANCES = 'uniswap/UNISWAP_UPDATE_ALLOWANCES'; const UNISWAP_UPDATE_LIQUIDITY_TOKENS = @@ -100,7 +97,7 @@ export const uniswapLoadState = () => async (dispatch, getState) => { PENDING_APPROVALS, accountAddress, network, - {}, + {} ); dispatch({ payload: { @@ -201,7 +198,7 @@ export const uniswapUpdatePendingApprovals = ( tokenAddress, txHash, creationTimestamp, - estimatedTimeInMs, + estimatedTimeInMs ) => (dispatch, getState) => { const { accountAddress, network } = getState().settings; const { pendingApprovals } = getState().uniswap; @@ -217,51 +214,87 @@ export const uniswapUpdatePendingApprovals = ( payload: updatedPendingApprovals, type: UNISWAP_UPDATE_PENDING_APPROVALS, }); - saveAccountLocal(PENDING_APPROVALS, updatedPendingApprovals, accountAddress, network); + saveAccountLocal( + PENDING_APPROVALS, + updatedPendingApprovals, + accountAddress, + network + ); }; - -const updateAllowancesForSuccessfulTransactions = (assetAddresses) => (dispatch, getState) => { +const updateAllowancesForSuccessfulTransactions = assetAddresses => ( + dispatch, + getState +) => { if (isEmpty(assetAddresses)) return; const { accountAddress } = getState().settings; - promiseUtils.PromiseAllWithFails(map(assetAddresses, async (assetAddress) => { - const asset = uniswapAssetsRawLoweredKeys[assetAddress]; - return contractUtils.getAllowance( - accountAddress, - asset, - asset.exchangeAddress, - ); - })).then(allowances => { - const tokenAddressAllowances = fromPairs(zip(assetAddresses, allowances)); - dispatch(uniswapUpdateAllowances(tokenAddressAllowances)); - }).catch(error => { - // TODO error handling - }); + promiseUtils + .PromiseAllWithFails( + map(assetAddresses, async assetAddress => { + const asset = uniswapAssetsClean[assetAddress]; + return contractUtils.getAllowance( + accountAddress, + asset, + asset.exchangeAddress + ); + }) + ) + .then(allowances => { + const tokenAddressAllowances = fromPairs(zip(assetAddresses, allowances)); + dispatch(uniswapUpdateAllowances(tokenAddressAllowances)); + }) + .catch(() => {}); }; -export const uniswapRemovePendingApproval = (transactions) => (dispatch, getState) => { +export const uniswapRemovePendingApproval = transactions => ( + dispatch, + getState +) => { const newTransactions = map(transactions, txn => ({ ...txn, hash: toLower(txn.hash).split('-')[0], })); const { pendingApprovals } = getState().uniswap; const loweredTxHashes = map(newTransactions, txn => txn.hash); - const invertedPendingApprovals = mapValues(invertBy(pendingApprovals, value => value.hash), value => get(value, '[0]')); - const updatedAddresses = compact(map(loweredTxHashes, hash => invertedPendingApprovals[hash])); + const invertedPendingApprovals = mapValues( + invertBy(pendingApprovals, value => value.hash), + value => get(value, '[0]') + ); + const updatedAddresses = compact( + map(loweredTxHashes, hash => invertedPendingApprovals[hash]) + ); if (isEmpty(updatedAddresses)) return; const updatedPendingApprovals = omit(pendingApprovals, ...updatedAddresses); dispatch({ payload: updatedPendingApprovals, type: UNISWAP_UPDATE_PENDING_APPROVALS, }); - const successfulApprovalHashes = map(reject(newTransactions, txn => txn.status === TransactionStatusTypes.failed), txn => toLower(txn.hash)); - const successfullyApprovedAddresses = compact(map(successfulApprovalHashes, hash => invertedPendingApprovals[hash])); - dispatch(updateAllowancesForSuccessfulTransactions(successfullyApprovedAddresses)); + const successfulApprovalHashes = map( + reject( + newTransactions, + txn => txn.status === TransactionStatusTypes.failed + ), + txn => toLower(txn.hash) + ); + const successfullyApprovedAddresses = compact( + map(successfulApprovalHashes, hash => invertedPendingApprovals[hash]) + ); + dispatch( + updateAllowancesForSuccessfulTransactions(successfullyApprovedAddresses) + ); const { accountAddress, network } = getState().settings; - saveAccountLocal(PENDING_APPROVALS, updatedPendingApprovals, accountAddress, network); + saveAccountLocal( + PENDING_APPROVALS, + updatedPendingApprovals, + accountAddress, + network + ); }; -export const uniswapUpdateAllowances = (tokenAddressAllowances) => (dispatch, getState) => { +export const uniswapUpdateAllowances = tokenAddressAllowances => ( + dispatch, + getState +) => { const { accountAddress, network } = getState().settings; const { allowances } = getState().uniswap; const updatedAllowances = { @@ -390,49 +423,49 @@ export const INITIAL_UNISWAP_STATE = { export default (state = INITIAL_UNISWAP_STATE, action) => produce(state, draft => { switch (action.type) { - case UNISWAP_LOAD_REQUEST: - draft.loadingUniswap = true; - break; - case UNISWAP_LOAD_SUCCESS: - draft.allowances = action.payload.allowances; - draft.liquidityTokens = action.payload.liquidityTokens; - draft.loadingUniswap = false; - draft.pendingApprovals = action.payload.pendingApprovals; - draft.tokenReserves = action.payload.tokenReserves; - draft.uniswap = action.payload.uniswap; - draft.uniswapAssets = action.payload.uniswapAssets; - break; - case UNISWAP_LOAD_FAILURE: - draft.loadingUniswap = false; - break; - case UNISWAP_UPDATE_REQUEST: - draft.fetchingUniswap = true; - break; - case UNISWAP_UPDATE_SUCCESS: - draft.fetchingUniswap = false; - draft.uniswap = action.payload; - break; - case UNISWAP_UPDATE_FAILURE: - draft.fetchingUniswap = false; - break; - case UNISWAP_UPDATE_LIQUIDITY_TOKENS: - draft.liquidityTokens = action.payload; - break; - case UNISWAP_UPDATE_PENDING_APPROVALS: - draft.pendingApprovals = action.payload; - break; - case UNISWAP_UPDATE_ALLOWANCES: - draft.allowances = action.payload; - break; - case UNISWAP_UPDATE_ASSETS: - draft.uniswapAssets = action.payload; - break; - case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: - draft.tokenReserves = action.payload; - break; - case UNISWAP_CLEAR_STATE: - return INITIAL_UNISWAP_STATE; - default: - break; + case UNISWAP_LOAD_REQUEST: + draft.loadingUniswap = true; + break; + case UNISWAP_LOAD_SUCCESS: + draft.allowances = action.payload.allowances; + draft.liquidityTokens = action.payload.liquidityTokens; + draft.loadingUniswap = false; + draft.pendingApprovals = action.payload.pendingApprovals; + draft.tokenReserves = action.payload.tokenReserves; + draft.uniswap = action.payload.uniswap; + draft.uniswapAssets = action.payload.uniswapAssets; + break; + case UNISWAP_LOAD_FAILURE: + draft.loadingUniswap = false; + break; + case UNISWAP_UPDATE_REQUEST: + draft.fetchingUniswap = true; + break; + case UNISWAP_UPDATE_SUCCESS: + draft.fetchingUniswap = false; + draft.uniswap = action.payload; + break; + case UNISWAP_UPDATE_FAILURE: + draft.fetchingUniswap = false; + break; + case UNISWAP_UPDATE_LIQUIDITY_TOKENS: + draft.liquidityTokens = action.payload; + break; + case UNISWAP_UPDATE_PENDING_APPROVALS: + draft.pendingApprovals = action.payload; + break; + case UNISWAP_UPDATE_ALLOWANCES: + draft.allowances = action.payload; + break; + case UNISWAP_UPDATE_ASSETS: + draft.uniswapAssets = action.payload; + break; + case UNISWAP_GET_TOKEN_RESERVES_SUCCESS: + draft.tokenReserves = action.payload; + break; + case UNISWAP_CLEAR_STATE: + return INITIAL_UNISWAP_STATE; + default: + break; } -}); + }); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index f542232ed37..96f0bc75be5 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -135,7 +135,7 @@ class ExchangeModal extends PureComponent { componentDidMount = () => { this.props.gasUpdateDefaultGasLimit(ethUnits.basic_swap); - } + }; componentDidUpdate = (prevProps, prevState) => { const { @@ -193,20 +193,24 @@ class ExchangeModal extends PureComponent { ); const isNewAmount = - (this.state.inputAsExactAmount - && (isNewNativeAmount || isNewInputAmount)) - || (!this.state.inputAsExactAmount && isNewOutputAmount); + (this.state.inputAsExactAmount && + (isNewNativeAmount || isNewInputAmount)) || + (!this.state.inputAsExactAmount && isNewOutputAmount); const isNewCurrency = isNewInputCurrency || isNewOutputCurrency; const input = toLower(get(this.state.inputCurrency, 'address')); - const removedFromPending = (!get(pendingApprovals, `[${input}]`, null) - && get(prevProps, `pendingApprovals[${input}]`, null)); + const removedFromPending = + !get(pendingApprovals, `[${input}]`, null) && + get(prevProps, `pendingApprovals[${input}]`, null); if (isNewAmount || isNewCurrency) { this.getMarketDetails(); LayoutAnimation.easeInEaseOut(); } - if (removedFromPending || isNewValueForPath(this.state, prevState, 'inputCurrency.address')) { + if ( + removedFromPending || + isNewValueForPath(this.state, prevState, 'inputCurrency.address') + ) { this.getCurrencyAllowance(); } }; @@ -279,8 +283,12 @@ class ExchangeModal extends PureComponent { ); gasUpdateTxFee(gasLimit); return this.setState({ - approvalCreationTimestamp: isUnlockingAsset ? pendingApproval.creationTimestamp : null, - approvalEstimatedTimeInMs: isUnlockingAsset ? pendingApproval.estimatedTimeInMs : null, + approvalCreationTimestamp: isUnlockingAsset + ? pendingApproval.creationTimestamp + : null, + approvalEstimatedTimeInMs: isUnlockingAsset + ? pendingApproval.estimatedTimeInMs + : null, isAssetApproved, isUnlockingAsset, }); @@ -452,7 +460,11 @@ class ExchangeModal extends PureComponent { get(outputCurrency, 'price.value') ); - this.setOutputAmount(rawUpdatedAmount, updatedAmountDisplay, inputAsExactAmount); + this.setOutputAmount( + rawUpdatedAmount, + updatedAmountDisplay, + inputAsExactAmount + ); } } @@ -471,11 +483,18 @@ class ExchangeModal extends PureComponent { get(inputCurrency, 'price.value') ); - this.setInputAmount(rawUpdatedAmount, updatedAmountDisplay, inputAsExactAmount); + this.setInputAmount( + rawUpdatedAmount, + updatedAmountDisplay, + inputAsExactAmount + ); } } if (isAssetApproved) { - const gasLimit = await estimateSwapGasLimit(accountAddress, tradeDetails); + const gasLimit = await estimateSwapGasLimit( + accountAddress, + tradeDetails + ); gasUpdateTxFee(gasLimit); } } catch (error) { @@ -575,14 +594,17 @@ class ExchangeModal extends PureComponent { inputCurrency.address, inputCurrency.exchangeAddress, gasLimit, - get(selectedGasPrice, 'value.amount'), + get(selectedGasPrice, 'value.amount') + ); + const approvalEstimatedTimeInMs = get( + selectedGasPrice, + 'estimatedTime.amount' ); - const approvalEstimatedTimeInMs = get(selectedGasPrice, 'estimatedTime.amount'); uniswapUpdatePendingApprovals( inputCurrency.address, hash, approvalCreationTimestamp, - approvalEstimatedTimeInMs, + approvalEstimatedTimeInMs ); this.setState({ approvalCreationTimestamp, @@ -597,7 +619,7 @@ class ExchangeModal extends PureComponent { isUnlockingAsset: false, }); } - } + }; navigateToSelectInputCurrency = () => { this.props.navigation.navigate('CurrencySelectScreen', { @@ -651,7 +673,7 @@ class ExchangeModal extends PureComponent { } }; - setNativeAmount = nativeAmount => { + setNativeAmount = nativeAmount => this.setState(({ inputCurrency }) => { let inputAmount = null; let inputAmountDisplay = null; @@ -672,16 +694,14 @@ class ExchangeModal extends PureComponent { nativeAmount, }; }); - }; - setOutputAmount = (outputAmount, amountDisplay, inputAsExactAmount = false) => { - this.setState(({ outputCurrency }) => ({ + setOutputAmount = (outputAmount, amountDisplay, inputAsExactAmount = false) => + this.setState({ inputAsExactAmount, outputAmount, outputAmountDisplay: amountDisplay !== undefined ? amountDisplay : outputAmount, - })); - }; + }); setOutputCurrency = (outputCurrency, force) => { const { allAssets } = this.props; diff --git a/src/utils/contract.js b/src/utils/contract.js index 72a5187d14a..c28581917f2 100644 --- a/src/utils/contract.js +++ b/src/utils/contract.js @@ -6,7 +6,10 @@ import erc20ABI from '../references/erc20-abi.json'; const estimateApproveWithExchange = async (spender, exchange) => { try { - const gasLimit = await exchange.estimate.approve(spender, ethers.constants.MaxUint256); + const gasLimit = await exchange.estimate.approve( + spender, + ethers.constants.MaxUint256 + ); return gasLimit ? gasLimit.toString() : null; } catch (error) { console.log('error estimating approval', error); @@ -30,7 +33,7 @@ const approve = async (tokenAddress, spender, gasLimit, gasPrice) => { { gasLimit: gasLimit ? toHex(gasLimit) : undefined, gasPrice: gasPrice ? toHex(gasPrice) : undefined, - }, + } ); return { approval, diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index d62e2481784..83feeacbeef 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -1,9 +1,4 @@ -import { - find, - get, - replace, - toLower, -} from 'lodash'; +import { find, get, replace, toLower } from 'lodash'; import chains from '../references/chains.json'; import { add, diff --git a/src/utils/gas.js b/src/utils/gas.js index ee8081d2d42..9ad5e261d07 100644 --- a/src/utils/gas.js +++ b/src/utils/gas.js @@ -49,7 +49,7 @@ const showTransactionSpeedOptions = ( }; const formatGasSpeedItems = (gasPrices, txFees) => { - const gasItems = map(GasSpeedOrder, (speed) => { + const gasItems = map(GasSpeedOrder, speed => { const cost = get(txFees, `[${speed}].txFee.native.value.display`); const gwei = get(gasPrices, `[${speed}].value.display`); const time = get(gasPrices, `[${speed}].estimatedTime.display`); diff --git a/yarn.lock b/yarn.lock index 89072ab21ca..c8b0e05b54d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -697,9 +697,9 @@ integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.129.tgz#bc93d04d3f0e8b7d33dbe7b47a81081f02af5a0e" - integrity sha512-ob+olQe+i7Gvq10nZyDa3XFGCdVc7ojG1VsfwwFdxt8/li2cv74fFueR4rjTpgKBhJuPM2bwTeHq6sGLsVxetw== + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.130.tgz#e052b859f17534e51a587a64612206d7b80b7be7" + integrity sha512-ahf8Q/TxDR0toGiWr27kvdmBPnpHgdyUkR29H+x8oMxXFbjJ7lRhvSFCHP6WJ2UOJWhPSr6glPnnYkoJg2mFfQ== dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" "@ethersproject/bytes" ">=5.0.0-beta.129" @@ -709,9 +709,9 @@ bn.js "^4.4.0" "@ethersproject/bignumber@>=5.0.0-beta.130": - version "5.0.0-beta.131" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.131.tgz#153b3676fcc6127e6275aa3ee95c7de6f7279673" - integrity sha512-4Uvz6XjfUkd6rUEXhQ1h9EB1CtmDKEmkKytCCM1iDHZw3fOs5rYnxKv53e6bxdGlSR5+/QBHH4vNB6vFHdJsDA== + version "5.0.0-beta.132" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.132.tgz#61b7d87e3dd7d7fff0fb3286017a46d041a0302b" + integrity sha512-DiKfTzpu6myNluDjrRvVBIIwVtEVGC7AFMpIh2hze8C2vJx2Dzykj1bP/iguedLQC26xceXDqdUHQNWNLejGQg== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/logger" ">=5.0.0-beta.129" @@ -719,23 +719,23 @@ bn.js "^4.4.0" "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0-beta.126": - version "5.0.0-beta.130" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.130.tgz#48239f29f03f39bc18f5923a839a91f3d2d61267" - integrity sha512-udO4csx8EvRbbu1QlSOMzYXBwAVAMlDlEf057J97cXPyDimglznjDwMSJI89dQKl8gg6UPgBZIxVQGI5tTYmqg== + version "5.0.0-beta.131" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.131.tgz#aa4e98cafed24efba2f80be74e6dd6ecfba852eb" + integrity sha512-FkgX8AlH1OOhRiEbpZL6OLkO8J4bVOw3CTjjvW4yb7UU3j91duffDu/ulLjjIMe8DZ98AiGc4NQ+WwRKzh/Hiw== dependencies: "@ethersproject/logger" ">=5.0.0-beta.129" "@ethersproject/constants@>=5.0.0-beta.128": - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.129.tgz#83780862a357280876ec3f43aaaea27bbcab82c2" - integrity sha512-qOlJi9t/F7vOXjLRC3vfuOTr/ej+JXucJM76YZ8+X19e2VKjmPaMtbq0pj6pjOiePAWOjrgUJYp8njW2kdYUCg== + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.130.tgz#378f0a549beb63885510d90ec118e38964b7b539" + integrity sha512-ZO4b+jJ5o58/77d9jVNH0LVJdIeo2nKBdxaESxQ8Kgp7sPd5FsUiznPdWEu33frAQMUZ16ieSylv+vEqEzBh1g== dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" "@ethersproject/keccak256@>=5.0.0-beta.127": - version "5.0.0-beta.128" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.128.tgz#5635a9f386de3692e17b2fa550807a30f9da78b0" - integrity sha512-dWp669s9B1+DyUSDSjxtU29+g270qQzBVAfJ0O6GbAnyuWFoyLfU4eeD/4GDGHI6g94iHXNt8yAQNE9wocB+MQ== + version "5.0.0-beta.129" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.129.tgz#c8c22d96aa60e6fd72cffa7bc5e5621c6ebb7e21" + integrity sha512-kj4waDagZuRF34eMKjagRIRS/G2utQAMi1kCl8jy6BET0pCalD9/URGYZRDe5xRsUjjGPn58x+yoj+Qxw7r6cQ== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" js-sha3 "0.5.7" @@ -753,16 +753,16 @@ "@ethersproject/logger" ">=5.0.0-beta.129" "@ethersproject/rlp@>=5.0.0-beta.126": - version "5.0.0-beta.127" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.127.tgz#b9b9ab962f7392ced7c5c220d3d617f5e9df5953" - integrity sha512-kODY7Wzp6iPN82g4M56TWRsts6YAyyK2ekHr8gwAB9bg58fYqCL9e4EFT8m7/Gn9GtbrwQy6OSCurgBYyxVGjA== + version "5.0.0-beta.128" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.128.tgz#f86fc0616a4893168ec38e7920361f67f53c0ab9" + integrity sha512-MJJSsEeTRV85LCqnHuMav5uzAj7cFJ6c3ZRlKv66Ty7RD62hFj1tA1Fp5Rkokli/ePf92jALPT+XxOAUWmfUTA== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": - version "5.0.0-beta.131" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.131.tgz#98137914ff94a95858e88ad26187e266b354124b" - integrity sha512-TEUr1U1XWTPGEehAitqkG7SMgVspsAtB1+ESXdniznaYaMoP/D3W3lsDuFdvIIPWlAb97ra1w2pnCKxVcMmc4A== + version "5.0.0-beta.132" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.132.tgz#26bea757aced75affde6d25c4940245ba7693854" + integrity sha512-vGlHQnY7gP6ABD5+BHdyVf+ohgUQC4c17k2jNHgpkMHC2dZ1tydCBQGtzLpnuU6jzA75ESFl4WvIKA7Cq9fh2A== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/constants" ">=5.0.0-beta.128" @@ -779,9 +779,9 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x": - version "8.2.4" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020" - integrity sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow== + version "8.2.5" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.5.tgz#b307d3f1aced22e05bd6a2403c302eaebb577da3" + integrity sha512-rmGFzok1zR3xZKd5m3ihWdqafXFxvPHoQ/78+AG5URKbEbJiwBBfRgzbu+07W5f3+07JRshw6QqGbVmCp8ntig== "@hapi/joi@^15.0.3": version "15.1.1" @@ -1318,28 +1318,14 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": -<<<<<<< HEAD - version "12.7.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.7.tgz#f9bd8c00fa9e1a8129af910fc829f6139c397d6c" - integrity sha512-4jUncNe2tj1nmrO/34PsRpZqYVnRV1svbU78cKhuQKkMntKB/AmdLyGgswcZKjFHEHGpiY8pVD8CuVI55nP54w== -======= version "12.7.8" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.8.tgz#cb1bf6800238898bc2ff6ffa5702c3cadd350708" integrity sha512-FMdVn84tJJdV+xe+53sYiZS4R5yn1mAIxfj+DVoNiQjTYz1+OYmjwEZr1ev9nU0axXwda0QDbYl06QHanRVH3A== ->>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation "@types/node@^10.3.2": version "10.14.19" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.19.tgz#f52742c7834a815dedf66edfc8a51547e2a67342" integrity sha512-j6Sqt38ssdMKutXBUuAcmWF8QtHW1Fwz/mz4Y+Wd9mzpBiVFirjpNQf363hG5itkG+yGaD+oiLyb50HxJ36l9Q== -<<<<<<< HEAD - -"@types/node@^8.0.7": - version "8.10.54" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.54.tgz#1c88eb253ac1210f1a5876953fb70f7cc4928402" - integrity sha512-kaYyLYf6ICn6/isAyD4K1MyWWd5Q3JgH6bnMN089LUx88+s4W8GvK9Q6JMBVu5vsFFp7pMdSxdKmlBXwH/VFRg== -======= ->>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2819,9 +2805,9 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: delayed-stream "~1.0.0" commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + version "2.20.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.1.tgz#3863ce3ca92d0831dcf2a102f5fb4b5926afd0f9" + integrity sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg== commander@~2.13.0: version "2.13.0" @@ -2900,14 +2886,6 @@ configstore@^3.0.0: write-file-atomic "^2.0.0" xdg-basedir "^3.0.0" -<<<<<<< HEAD -======= -confusing-browser-globals@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" - integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== - ->>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation connect@^3.6.5: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -3539,15 +3517,9 @@ ejs@^2.7.1: integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.247: -<<<<<<< HEAD - version "1.3.266" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.266.tgz#a33fb529c75f8d133e75ea7cbedb73a62f2158d2" - integrity sha512-UTuTZ4v8T0gLPHI7U75PXLQePWI65MTS3mckRrnLCkNljHvsutbYs+hn2Ua/RFul3Jt/L3Ht2rLP+dU/AlBfrQ== -======= version "1.3.267" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.267.tgz#7745ff9d447fd2a9802e1c6dfa518631e0cf5357" integrity sha512-9Q2ixAJC+oHjWNtJV0MQ4vJMCWSowIrC6V6vcr+bwPddTDHj2ddv9xxXCzf4jT/fy6HP7maPoW0gifXkRxCttQ== ->>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation elliptic@6.3.3: version "6.3.3" @@ -4844,15 +4816,9 @@ hammerjs@^2.0.8: integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= handlebars@^4.1.2: -<<<<<<< HEAD - version "4.3.1" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.1.tgz#6febc1890851f62a8932d495cc88d29390fa850d" - integrity sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA== -======= - version "4.3.3" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.3.tgz#56dd05fe33d6bd8a7d797351c39a0cdcfd576be5" - integrity sha512-VupOxR91xcGojfINrzMqrvlyYbBs39sXIrWa7YdaQWeBudOlvKEGvCczMfJPgnuwHE/zyH1M6J+IUP6cgDVyxg== ->>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation + version "4.3.4" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.4.tgz#aab065294c27ad16ff4e711240a7288d2753306d" + integrity sha512-vvpo6mpK4ScNC1DbGRZ2d5BznS6ht0r1hi20RivsibMc6jNvFAeZQ6qk5VNspo6SOwVOJQbjHyBCpuS7BzA1pw== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -7149,12 +7115,6 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -<<<<<<< HEAD -minipass@^2.2.1, minipass@^2.6.0, minipass@^2.8.6: - version "2.8.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.8.6.tgz#620d889ace26356391d010ecb9458749df9b6db5" - integrity sha512-lFG7d6g3+/UaFDCOtqPiKAC9zngWWsQZl1g5q6gaONqrjq61SX2xFqXMleQiFVyDpYwa018E9hmlAFY22PCb+A== -======= minipass@^2.6.0, minipass@^2.8.6: version "2.8.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.8.6.tgz#620d889ace26356391d010ecb9458749df9b6db5" @@ -7167,7 +7127,6 @@ minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== ->>>>>>> b922b759... catching up with mike swap changes and updates to gas speed rotation dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -8670,9 +8629,9 @@ react-display-name@^0.2.4: integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" - integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw== + version "16.10.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.1.tgz#0612786bf19df406502d935494f0450b40b8294f" + integrity sha512-BXUMf9sIOPXXZWqr7+c5SeOKJykyVr2u0UDzEf4LNGc6taGkQe1A9DFD07umCIXz45RLr9oAAwZbAJ0Pkknfaw== react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: version "3.0.4" From 94406fa01056fbd371b945a98f608d59ed34cec1 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 3 Sep 2019 16:50:17 -0400 Subject: [PATCH 355/636] support for deeplinking --- src/App.js | 74 ++++---- src/hoc/index.js | 1 + src/hoc/withDeepLink.js | 125 ++++++++++++++ src/parsers/requests.js | 149 ++++++++++++++++ src/redux/requests.js | 145 +--------------- src/redux/walletconnect.js | 15 +- src/screens/TransactionConfirmationScreen.js | 38 ++--- .../TransactionConfirmationScreenWithData.js | 159 ++++++++++-------- src/utils/index.js | 3 + src/utils/parseObjectToUrlQueryString.js | 10 ++ src/utils/parseQueryParams.js | 1 - src/utils/signingMethods.js | 31 ++++ 12 files changed, 476 insertions(+), 275 deletions(-) create mode 100644 src/hoc/withDeepLink.js create mode 100644 src/parsers/requests.js create mode 100644 src/utils/parseObjectToUrlQueryString.js create mode 100644 src/utils/signingMethods.js diff --git a/src/App.js b/src/App.js index 5ce1e538b82..bf88f0117cb 100644 --- a/src/App.js +++ b/src/App.js @@ -17,6 +17,7 @@ import { compose, withProps } from 'recompact'; import { FlexItem } from './components/layout'; import OfflineBadge from './components/OfflineBadge'; import { + withDeepLink, withWalletConnectConnections, withWalletConnectOnSessionRequest, } from './hoc'; @@ -36,6 +37,7 @@ useScreens(false); class App extends Component { static propTypes = { + addDeepLinkRequest: PropTypes.func, appInitTimestamp: PropTypes.number, requestsForTopic: PropTypes.func, walletConnectClearTimestamp: PropTypes.func, @@ -102,16 +104,50 @@ class App extends Component { } handleOpenLinkingURL = ({ url }) => { + const { addDeepLinkRequest, walletConnectOnSessionRequest } = this.props; Linking.canOpenURL(url).then(supported => { if (supported) { - const { uri, redirectUrl } = parseQueryParams(url); - - const redirect = () => Linking.openURL(redirectUrl); - this.props.walletConnectOnSessionRequest(uri, redirect); + const { type, ...remainingParams } = parseQueryParams(url); + if (type && type === 'walletconnect') { + const { uri, redirectUrl } = remainingParams; + const redirect = () => Linking.openURL(redirectUrl); + walletConnectOnSessionRequest(uri, redirect); + } else { + addDeepLinkRequest(remainingParams); + } } }); }; + onPushNotificationOpened = (topic, autoOpened = false, fromLocal = false) => { + const { appInitTimestamp, requestsForTopic } = this.props; + const requests = requestsForTopic(topic); + + if (requests && requests.length === 1) { + const request = requests[0]; + + const transactionTimestamp = get(request, 'displayDetails.timestampInMs'); + const isNewTransaction = + appInitTimestamp && transactionTimestamp > appInitTimestamp; + + if (!autoOpened || isNewTransaction) { + return Navigation.handleAction({ + params: { autoOpened, transactionDetails: request }, + routeName: 'ConfirmRequest', + }); + } + } + + if (fromLocal) { + return Navigation.handleAction({ + params: { autoOpened, transactionDetails: last(requests) }, + routeName: 'ConfirmRequest', + }); + } + + return Navigation.handleAction({ routeName: 'ProfileScreen' }); + }; + handleInitializeAnalytics = async () => { const storedIdentifier = await keychain.loadString( 'analyticsUserIdentifier' @@ -145,35 +181,6 @@ class App extends Component { this.setState({ appState: nextAppState }); }; - onPushNotificationOpened = (topic, autoOpened = false, fromLocal = false) => { - const { appInitTimestamp, requestsForTopic } = this.props; - const requests = requestsForTopic(topic); - - if (requests && requests.length === 1) { - const request = requests[0]; - - const transactionTimestamp = get(request, 'displayDetails.timestampInMs'); - const isNewTransaction = - appInitTimestamp && transactionTimestamp > appInitTimestamp; - - if (!autoOpened || isNewTransaction) { - return Navigation.handleAction({ - params: { autoOpened, transactionDetails: request }, - routeName: 'ConfirmRequest', - }); - } - } - - if (fromLocal) { - return Navigation.handleAction({ - params: { autoOpened, transactionDetails: last(requests) }, - routeName: 'ConfirmRequest', - }); - } - - return Navigation.handleAction({ routeName: 'ProfileScreen' }); - }; - handleNavigatorRef = navigatorRef => Navigation.setTopLevelNavigator(navigatorRef); @@ -189,6 +196,7 @@ class App extends Component { const AppWithRedux = compose( withProps({ store }), + withDeepLink, withWalletConnectConnections, withWalletConnectOnSessionRequest, connect( diff --git a/src/hoc/index.js b/src/hoc/index.js index d500c33f624..0113e758fc0 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -9,6 +9,7 @@ export { } from './withBlockedHorizontalSwipe'; export { default as withBlurTransitionProps } from './withBlurTransitionProps'; export { default as withDataInit } from './withDataInit'; +export { default as withDeepLink } from './withDeepLink'; export { default as withFabSelection } from './withFabSelection'; export { default as withFabSendAction } from './withFabSendAction'; export { default as withGas } from './withGas'; diff --git a/src/hoc/withDeepLink.js b/src/hoc/withDeepLink.js new file mode 100644 index 00000000000..e2d799b756d --- /dev/null +++ b/src/hoc/withDeepLink.js @@ -0,0 +1,125 @@ +import { Linking } from 'react-native'; +import { connect } from 'react-redux'; +import { compose, withHandlers } from 'recompact'; +import { getRequestDisplayDetails } from '../parsers/requests'; +// eslint-disable-next-line import/default +import parseObjectToUrlQueryString from '../utils'; +import { Navigation } from '../navigation'; +import withAccountSettings from './withAccountSettings'; + +const mapStateToProps = ({ + data: { assets }, + settings: { accountAddress, nativeCurrency }, +}) => ({ + accountAddress, + assets, + nativeCurrency, +}); + +const parseResultsForRedirect = (results, redirectUrl) => { + const queryString = parseObjectToUrlQueryString(results); + const updatedRedirectUrl = `${redirectUrl}?${queryString}`; + return Linking.openURL(updatedRedirectUrl); +}; + +export default Component => + compose( + connect(mapStateToProps), + withAccountSettings, + withHandlers({ + addDeepLinkRequest: ({ + accountAddress, + assets, + nativeCurrency, + }) => uriParams => { + const { + dappName, + imageUrl, + method, + redirectUrl, + ...remainingParams + } = uriParams; + let payload = {}; + let redirect = results => parseResultsForRedirect(results, redirectUrl); + switch (method) { + case 'connect_sign': { + const { message } = remainingParams; + const params = [accountAddress, message]; + payload = { + method: 'eth_sign', + params, + }; + redirect = results => { + const updatedResults = { + ...results, + address: accountAddress, + message, + }; + return parseResultsForRedirect(updatedResults, redirectUrl); + }; + break; + } + case 'eth_sign': { + const { message } = remainingParams; + const params = [accountAddress, message]; + payload = { + method, + params, + }; + break; + } + case 'eth_sendTransaction': { + const { data, to, value } = remainingParams; + const transaction = { + data, + from: accountAddress, + to, + value, + }; + const params = [transaction]; + payload = { + method, + params, + }; + break; + } + case 'eth_signTransaction': { + const { data, to, value } = remainingParams; + const transaction = { + data, + from: accountAddress, + to, + value, + }; + const params = [transaction]; + payload = { + method, + params, + }; + break; + } + default: + break; + } + const displayDetails = getRequestDisplayDetails( + payload, + assets, + nativeCurrency + ); + const request = { + dappName, + displayDetails, + imageUrl, + payload, + }; + return Navigation.handleAction({ + params: { + autoOpened: true, + callback: redirect, + transactionDetails: request, + }, + routeName: 'ConfirmRequest', + }); + }, + }) + )(Component); diff --git a/src/parsers/requests.js b/src/parsers/requests.js new file mode 100644 index 00000000000..ebede937a82 --- /dev/null +++ b/src/parsers/requests.js @@ -0,0 +1,149 @@ +import { convertHexToUtf8 } from '@walletconnect/utils'; +import BigNumber from 'bignumber.js'; +import { get } from 'lodash'; +import { + convertAmountAndPriceToNativeDisplay, + convertHexToString, + convertRawAmountToDecimalFormat, + fromWei, +} from '../helpers/utilities'; +import smartContractMethods from '../references/smartcontract-methods.json'; +import { ethereumUtils } from '../utils'; +import { + PERSONAL_SIGN, + SEND_TRANSACTION, + SIGN, + SIGN_TRANSACTION, + SIGN_TYPED, + SIGN_TYPED_V3, +} from '../utils/signingMethods'; + +export const getRequestDisplayDetails = (payload, assets, nativeCurrency) => { + let timestampInMs = Date.now(); + if (payload.id) { + timestampInMs = getTimestampFromPayload(payload); + } + if ( + payload.method === SEND_TRANSACTION || + payload.method === SIGN_TRANSACTION + ) { + const transaction = get(payload, 'params[0]', null); + return getTransactionDisplayDetails( + transaction, + assets, + nativeCurrency, + timestampInMs + ); + } + if (payload.method === SIGN) { + const message = get(payload, 'params[1]'); + const result = getMessageDisplayDetails(message, timestampInMs); + return result; + } + if (payload.method === PERSONAL_SIGN) { + let message = ''; + try { + message = convertHexToUtf8(get(payload, 'params[0]')); + } catch (error) { + message = get(payload, 'params[0]'); + } + return getMessageDisplayDetails(message, timestampInMs); + } + if (payload.method === SIGN_TYPED || payload.method === SIGN_TYPED_V3) { + const request = get(payload, 'params[1]', null); + const jsonRequest = JSON.stringify(request.message); + return getMessageDisplayDetails(jsonRequest, timestampInMs); + } + return {}; +}; + +const getMessageDisplayDetails = (message, timestampInMs) => ({ + request: message, + timestampInMs, +}); + +const getTransactionDisplayDetails = ( + transaction, + assets, + nativeCurrency, + timestampInMs +) => { + const tokenTransferHash = smartContractMethods.token_transfer.hash; + if (transaction.data === '0x') { + const value = fromWei(convertHexToString(transaction.value)); + const asset = ethereumUtils.getAsset(assets); + const priceUnit = get(asset, 'price.value', 0); + const { amount, display } = convertAmountAndPriceToNativeDisplay( + value, + priceUnit, + nativeCurrency + ); + return { + request: { + asset, + from: transaction.from, + gasLimit: BigNumber(convertHexToString(transaction.gasLimit)), + gasPrice: BigNumber(convertHexToString(transaction.gasPrice)), + nativeAmount: amount, + nativeAmountDisplay: display, + nonce: Number(convertHexToString(transaction.nonce)), + to: transaction.to, + value, + }, + timestampInMs, + }; + } + if (transaction.data.startsWith(tokenTransferHash)) { + const contractAddress = transaction.to; + const asset = ethereumUtils.getAsset(assets, contractAddress); + const dataPayload = transaction.data.replace(tokenTransferHash, ''); + const toAddress = `0x${dataPayload.slice(0, 64).replace(/^0+/, '')}`; + const amount = `0x${dataPayload.slice(64, 128).replace(/^0+/, '')}`; + const value = convertRawAmountToDecimalFormat( + convertHexToString(amount), + asset.decimals + ); + const priceUnit = get(asset, 'price.value', 0); + const native = convertAmountAndPriceToNativeDisplay( + value, + priceUnit, + nativeCurrency + ); + return { + request: { + asset, + from: transaction.from, + gasLimit: BigNumber(convertHexToString(transaction.gasLimit)), + gasPrice: BigNumber(convertHexToString(transaction.gasPrice)), + nativeAmount: native.amount, + nativeAmountDisplay: native.display, + nonce: Number(convertHexToString(transaction.nonce)), + to: toAddress, + value, + }, + timestampInMs, + }; + } + if (transaction.data) { + const value = transaction.value + ? fromWei(convertHexToString(transaction.value)) + : 0; + return { + request: { + data: transaction.data, + from: transaction.from, + gasLimit: BigNumber(convertHexToString(transaction.gasLimit)), + gasPrice: BigNumber(convertHexToString(transaction.gasPrice)), + nonce: Number(convertHexToString(transaction.nonce)), + to: transaction.to, + value, + }, + timestampInMs, + }; + } + + return null; +}; + +const getTimestampFromPayload = payload => + parseInt(payload.id.toString().slice(0, -3), 10); diff --git a/src/redux/requests.js b/src/redux/requests.js index 837d29ca9a3..c09493dad13 100644 --- a/src/redux/requests.js +++ b/src/redux/requests.js @@ -1,5 +1,3 @@ -import { convertHexToUtf8 } from '@walletconnect/utils'; -import BigNumber from 'bignumber.js'; import { filter, get, omit, values } from 'lodash'; import { getLocalRequests, @@ -7,14 +5,7 @@ import { removeLocalRequests, saveLocalRequests, } from '../handlers/localstorage/walletconnect'; -import { - convertAmountAndPriceToNativeDisplay, - convertHexToString, - convertRawAmountToDecimalFormat, - fromWei, -} from '../helpers/utilities'; -import smartContractMethods from '../references/smartcontract-methods.json'; -import { ethereumUtils } from '../utils'; +import { getRequestDisplayDetails } from '../parsers/requests'; // -- Constants --------------------------------------- // const REQUESTS_UPDATE_REQUESTS_TO_APPROVE = @@ -31,140 +22,6 @@ export const requestsLoadState = () => async (dispatch, getState) => { } catch (error) {} }; -const getTimestampFromPayload = payload => - parseInt(payload.id.toString().slice(0, -3), 10); - -const getRequestDisplayDetails = (payload, assets, nativeCurrency) => { - const timestampInMs = getTimestampFromPayload(payload); - if (payload.method === 'eth_sendTransaction') { - const transaction = get(payload, 'params[0]', null); - return getTransactionDisplayDetails( - transaction, - assets, - nativeCurrency, - timestampInMs - ); - } - if (payload.method === 'eth_sign') { - const message = get(payload, 'params[1]'); - return getMessageDisplayDetails(message, timestampInMs); - } - if (payload.method === 'personal_sign') { - let message = ''; - try { - message = convertHexToUtf8(get(payload, 'params[0]')); - } catch (error) { - message = get(payload, 'params[0]'); - } - return getMessageDisplayDetails(message, timestampInMs, 'messagePersonal'); - } - if ( - payload.method === 'eth_signTypedData' || - payload.method === 'eth_signTypedData_v3' - ) { - const request = get(payload, 'params[1]', null); - const jsonRequest = JSON.stringify(request.message); - return getMessageDisplayDetails(jsonRequest, timestampInMs); - } - return {}; -}; - -const getMessageDisplayDetails = ( - message, - timestampInMs, - type = 'message' -) => ({ - payload: message, - timestampInMs, - type, -}); - -const getTransactionDisplayDetails = ( - transaction, - assets, - nativeCurrency, - timestampInMs -) => { - const tokenTransferHash = smartContractMethods.token_transfer.hash; - if (transaction.data === '0x') { - const value = fromWei(convertHexToString(transaction.value)); - const asset = ethereumUtils.getAsset(assets); - const priceUnit = get(asset, 'price.value', 0); - const { amount, display } = convertAmountAndPriceToNativeDisplay( - value, - priceUnit, - nativeCurrency - ); - return { - payload: { - asset, - from: transaction.from, - gasLimit: BigNumber(convertHexToString(transaction.gasLimit)), - gasPrice: BigNumber(convertHexToString(transaction.gasPrice)), - nativeAmount: amount, - nativeAmountDisplay: display, - nonce: Number(convertHexToString(transaction.nonce)), - to: transaction.to, - value, - }, - timestampInMs, - type: 'transaction', - }; - } - if (transaction.data.startsWith(tokenTransferHash)) { - const contractAddress = transaction.to; - const asset = ethereumUtils.getAsset(assets, contractAddress); - const dataPayload = transaction.data.replace(tokenTransferHash, ''); - const toAddress = `0x${dataPayload.slice(0, 64).replace(/^0+/, '')}`; - const amount = `0x${dataPayload.slice(64, 128).replace(/^0+/, '')}`; - const value = convertRawAmountToDecimalFormat( - convertHexToString(amount), - asset.decimals - ); - const priceUnit = get(asset, 'price.value', 0); - const native = convertAmountAndPriceToNativeDisplay( - value, - priceUnit, - nativeCurrency - ); - return { - payload: { - asset, - from: transaction.from, - gasLimit: BigNumber(convertHexToString(transaction.gasLimit)), - gasPrice: BigNumber(convertHexToString(transaction.gasPrice)), - nativeAmount: native.amount, - nativeAmountDisplay: native.display, - nonce: Number(convertHexToString(transaction.nonce)), - to: toAddress, - value, - }, - timestampInMs, - type: 'transaction', - }; - } - if (transaction.data) { - const value = transaction.value - ? fromWei(convertHexToString(transaction.value)) - : 0; - return { - payload: { - data: transaction.data, - from: transaction.from, - gasLimit: BigNumber(convertHexToString(transaction.gasLimit)), - gasPrice: BigNumber(convertHexToString(transaction.gasPrice)), - nonce: Number(convertHexToString(transaction.nonce)), - to: transaction.to, - value, - }, - timestampInMs, - type: 'default', - }; - } - - return null; -}; - export const addRequestToApprove = ( clientId, peerId, diff --git a/src/redux/walletconnect.js b/src/redux/walletconnect.js index 691d3978930..512972a196f 100644 --- a/src/redux/walletconnect.js +++ b/src/redux/walletconnect.js @@ -1,8 +1,8 @@ import analytics from '@segment/analytics-react-native'; +import WalletConnect from '@walletconnect/react-native'; +import lang from 'i18n-js'; import { forEach, mapValues, omitBy, pickBy, values } from 'lodash'; import { Alert } from 'react-native'; -import lang from 'i18n-js'; -import WalletConnect from '@walletconnect/react-native'; import { getAllValidWalletConnectSessions, saveWalletConnectSession, @@ -14,6 +14,7 @@ import { getFCMToken, checkPushNotificationPermissions, } from '../model/firebase'; +import { isSigningMethod } from '../utils/signingMethods'; import { addRequestToApprove } from './requests'; // -- Constants --------------------------------------- // @@ -98,20 +99,12 @@ export const walletConnectOnSessionRequest = ( } }; -const signingMethods = [ - 'eth_sendTransaction', - 'eth_signTransaction', - 'personal_sign', - 'eth_sign', - 'eth_signTypedData', -]; - const listenOnNewMessages = walletConnector => dispatch => { walletConnector.on('call_request', (error, payload) => { if (error) throw error; const { clientId, peerId, peerMeta } = walletConnector; const requestId = payload.id; - if (!signingMethods.includes(payload.method)) { + if (!isSigningMethod(payload.method)) { sendRpcCall(payload) .then(result => { walletConnector.approveRequest({ diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 38274a28e10..460101f8610 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -15,6 +15,11 @@ import { } from '../components/transaction'; import { Text } from '../components/text'; import { colors, position } from '../styles'; +import { + isMessageDisplayType, + isTransactionDisplayType, + SEND_TRANSACTION, +} from '../utils/signingMethods'; const CancelButtonContainer = styled.View` bottom: 22; @@ -42,10 +47,10 @@ export default class TransactionConfirmationScreen extends PureComponent { static propTypes = { dappName: PropTypes.string, imageUrl: PropTypes.string, + method: PropTypes.string, onCancel: PropTypes.func, onConfirm: PropTypes.func, request: PropTypes.object, - requestType: PropTypes.string, }; state = { @@ -86,7 +91,7 @@ export default class TransactionConfirmationScreen extends PureComponent { }; onLongPressSend = async () => { - const { onConfirm, requestType } = this.props; + const { onConfirm } = this.props; const { sendLongPressProgress } = this.state; Animated.timing(sendLongPressProgress, { @@ -94,27 +99,22 @@ export default class TransactionConfirmationScreen extends PureComponent { toValue: 0, }).start(); - await onConfirm(requestType); + await onConfirm(); }; - renderSendButton = () => { - const { requestType } = this.props; - const isMessage = - requestType === 'message' || requestType === 'messagePersonal'; - - return ( - - ); - }; + renderSendButton = () => ( + + {`Hold to ${this.props.method === SEND_TRANSACTION ? 'Send' : 'Sign'}`} + + ); renderTransactionSection = () => { - const { request, requestType } = this.props; + const { request, method } = this.props; - if (requestType === 'message' || requestType === 'messagePersonal') { + if (isMessageDisplayType(method)) { return ( { - if (requestType === 'message' || requestType === 'messagePersonal') { - return this.handleSignMessage(requestType); + handleConfirm = async () => { + const { + transactionDetails: { + payload: { method }, + }, + } = this.props.navigation.state.params; + if (isMessageDisplayType(method)) { + return this.handleSignMessage(); } return this.handleConfirmTransaction(); }; handleConfirmTransaction = async () => { - const { transactionDetails } = this.props.navigation.state.params; + const { + callback, + transactionDetails: { + dappName, + displayDetails, + payload, + peerId, + requestId, + }, + } = this.props.navigation.state.params; - const txPayload = get(transactionDetails, 'payload.params[0]'); + const txPayload = get(payload, 'params[0]'); let { gasLimit } = txPayload; if (isNil(gasLimit)) { @@ -67,91 +87,97 @@ class TransactionConfirmationScreenWithData extends PureComponent { }); if (transactionHash) { + if (callback) { + // TODO JIN what about for sign txn (no txn hash) + callback({ hash: transactionHash }); + } this.props.updateTransactionCountNonce(maxTxnCount + 1); const txDetails = { - amount: get(transactionDetails, 'displayDetails.payload.value'), - asset: get(transactionDetails, 'displayDetails.payload.asset'), - dappName: get(transactionDetails, 'dappName'), - from: get(transactionDetails, 'displayDetails.payload.from'), - gasLimit: get(transactionDetails, 'displayDetails.payload.gasLimit'), - gasPrice: get(transactionDetails, 'displayDetails.payload.gasPrice'), + amount: get(displayDetails, 'request.value'), + asset: get(displayDetails, 'request.asset'), + dappName, + from: get(displayDetails, 'request.from'), + gasLimit: get(displayDetails, 'request.gasLimit'), + gasPrice: get(displayDetails, 'request.gasPrice'), hash: transactionHash, - nonce: get(transactionDetails, 'displayDetails.payload.nonce'), - to: get(transactionDetails, 'displayDetails.payload.to'), + nonce: get(displayDetails, 'request.nonce'), + to: get(displayDetails, 'request.to'), }; this.props.dataAddNewTransaction(txDetails); - this.props.removeRequest(transactionDetails.requestId); - try { + analytics.track('Approved WalletConnect transaction request'); + if (requestId) { + this.props.removeRequest(requestId); await this.props.walletConnectSendStatus( - transactionDetails.peerId, - transactionDetails.requestId, + peerId, + requestId, transactionHash ); - // eslint-disable-next-line no-empty - } catch (error) {} - analytics.track('Approved WalletConnect transaction request'); + } this.closeScreen(); } else { await this.handleCancelRequest(); } }; - handleSignMessage = async requestType => { - const { transactionDetails } = this.props.navigation.state.params; + handleSignMessage = async () => { + const { + callback, + transactionDetails: { payload, peerId, requestId }, + } = this.props.navigation.state.params; let message = null; let flatFormatSignature = null; - if (requestType === 'message') { - message = get(transactionDetails, 'payload.params[1]'); - flatFormatSignature = await signMessage(message); - } else if (requestType === 'messagePersonal') { - message = get(transactionDetails, 'payload.params[0]'); + const method = get(payload, 'method'); + if (isSignFirstParamType(method)) { + message = get(payload, 'params[0]'); flatFormatSignature = await signPersonalMessage(message); + } else if (isSignSecondParamType(method)) { + message = get(payload, 'params[1]'); + flatFormatSignature = await signMessage(message); } if (flatFormatSignature) { - this.props.removeRequest(transactionDetails.requestId); - await this.props.walletConnectSendStatus( - transactionDetails.peerId, - transactionDetails.requestId, - flatFormatSignature - ); + if (callback) { + callback({ signature: flatFormatSignature }); + } analytics.track('Approved WalletConnect signature request'); + if (requestId) { + this.props.removeRequest(requestId); + await this.props.walletConnectSendStatus( + peerId, + requestId, + flatFormatSignature + ); + } this.closeScreen(); } else { await this.handleCancelRequest(); } }; - sendFailedTransactionStatus = async () => { - try { - this.closeScreen(); - const { transactionDetails } = this.props.navigation.state.params; - await this.props.walletConnectSendStatus( - transactionDetails.peerId, - transactionDetails.requestId, - null - ); - } catch (error) { - this.closeScreen(); - Alert.alert(lang.t('wallet.transaction.alert.cancelled_transaction')); - } - }; - handleCancelRequest = async () => { try { - await this.sendFailedTransactionStatus(); - const { transactionDetails } = this.props.navigation.state.params; + this.closeScreen(); const { - requestId, - displayDetails: { requestType }, - } = transactionDetails; - this.props.removeRequest(requestId); + callback, + transactionDetails: { + payload: { method }, + peerId, + requestId, + }, + } = this.props.navigation.state.params; + if (callback) { + callback({ error: 'Error' }); + } + if (requestId) { + await this.props.walletConnectSendStatus(peerId, requestId, null); + this.props.removeRequest(requestId); + } const rejectionType = - requestType === 'message' ? 'signature' : 'transaction'; + method === SEND_TRANSACTION ? 'transaction' : 'signature'; analytics.track(`Rejected WalletConnect ${rejectionType} request`); } catch (error) { this.closeScreen(); - Alert.alert('Failed to send rejected transaction status'); + Alert.alert(lang.t('wallet.transaction.alert.cancelled_transaction')); } }; @@ -164,21 +190,20 @@ class TransactionConfirmationScreenWithData extends PureComponent { transactionDetails: { dappName, imageUrl, - displayDetails: { type, payload }, + displayDetails: { request }, + payload: { method }, }, } = this.props.navigation.state.params; return ( - <> - - + ); }; } diff --git a/src/utils/index.js b/src/utils/index.js index 35f3aeda708..f1c1cd05a42 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -9,6 +9,9 @@ export { default as gasUtils } from './gas'; export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForPath } from './isNewValueForPath'; +export { + default as parseObjectToUrlQueryString, +} from './parseObjectToUrlQueryString'; export { default as parseQueryParams } from './parseQueryParams'; export { default as promiseUtils } from './promise'; export { default as reduceArrayToObject } from './reduceArrayToObject'; diff --git a/src/utils/parseObjectToUrlQueryString.js b/src/utils/parseObjectToUrlQueryString.js new file mode 100644 index 00000000000..937bd3344dd --- /dev/null +++ b/src/utils/parseObjectToUrlQueryString.js @@ -0,0 +1,10 @@ +import { keys } from 'lodash'; + +export default params => + keys(params) + .map(key => { + const encodedKey = encodeURIComponent(key); + const encodedValue = encodeURIComponent(params[key]); + return `${encodedKey}=${encodedValue}`; + }) + .join('&'); diff --git a/src/utils/parseQueryParams.js b/src/utils/parseQueryParams.js index 190da5efd3b..d2fffb2705e 100644 --- a/src/utils/parseQueryParams.js +++ b/src/utils/parseQueryParams.js @@ -15,6 +15,5 @@ export default queryString => { ); } } - return result; }; diff --git a/src/utils/signingMethods.js b/src/utils/signingMethods.js new file mode 100644 index 00000000000..c3ca0d31772 --- /dev/null +++ b/src/utils/signingMethods.js @@ -0,0 +1,31 @@ +import { concat, includes } from 'lodash'; + +export const PERSONAL_SIGN = 'personal_sign'; +export const SEND_TRANSACTION = 'eth_sendTransaction'; +export const SIGN = 'eth_sign'; +export const SIGN_TRANSACTION = 'eth_signTransaction'; +export const SIGN_TYPED = 'eth_signTypedData'; +export const SIGN_TYPED_V3 = 'eth_signTypedData_v3'; + +const displayTypes = { + message: [PERSONAL_SIGN, SIGN, SIGN_TYPED, SIGN_TYPED_V3], + transaction: [SEND_TRANSACTION, SIGN_TRANSACTION], +}; +const firstParamSigning = [PERSONAL_SIGN]; +const secondParamSigning = [SIGN, SIGN_TYPED, SIGN_TYPED_V3]; + +const allTypes = concat(displayTypes.message, ...displayTypes.transaction); + +export const isSigningMethod = method => includes(allTypes, method); + +export const isMessageDisplayType = method => + includes(displayTypes.message, method); + +export const isTransactionDisplayType = method => + includes(displayTypes.transaction, method); + +export const isSignSecondParamType = method => + includes(secondParamSigning, method); + +export const isSignFirstParamType = method => + includes(firstParamSigning, method); From bb0b9b87764fcf530ab7e4ae2148a3e7a5438daf Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 4 Sep 2019 12:48:39 -0400 Subject: [PATCH 356/636] add deeplink responses and remove unused screenprops --- CHANGELOG.md | 4 ++++ ios/Rainbow/Info.plist | 2 +- package.json | 4 ++-- src/hoc/withDeepLink.js | 16 +++++++++---- src/screens/ImportSeedPhraseSheet.js | 1 - src/screens/Routes.js | 5 ++-- .../TransactionConfirmationScreenWithData.js | 7 +++--- yarn.lock | 23 +++++++++++++++++++ 8 files changed, 48 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73e70494029..c27cb67ddf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ### Removed +## [1.1.5-2](https://github.com/rainbow-me/rainbow/releases/tag/v1.1.5-2) +### Changed +* Bugfix for transaction history with null symbol + ## [1.1.4-1](https://github.com/rainbow-me/rainbow/releases/tag/v1.1.4-1) ### Added * Support for importing private key and seed key diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index fdd8318f7d2..c45d53f2a59 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -34,7 +34,7 @@ CFBundleVersion - 1 + 2 CodePushDeploymentKey $(CODEPUSH_KEY) ITSAppUsesNonExemptEncryption diff --git a/package.json b/package.json index 6640e9bce95..0b188a4d381 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.1.5-1", + "version": "1.1.5-2", "private": true, "scripts": { "clean": "react-native-clean-project", @@ -247,4 +247,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/src/hoc/withDeepLink.js b/src/hoc/withDeepLink.js index e2d799b756d..118bdab57d5 100644 --- a/src/hoc/withDeepLink.js +++ b/src/hoc/withDeepLink.js @@ -42,30 +42,38 @@ export default Component => let payload = {}; let redirect = results => parseResultsForRedirect(results, redirectUrl); switch (method) { - case 'connect_sign': { + case 'eth_sign': { const { message } = remainingParams; const params = [accountAddress, message]; payload = { - method: 'eth_sign', + method, params, }; redirect = results => { const updatedResults = { ...results, address: accountAddress, - message, + msg: message, }; return parseResultsForRedirect(updatedResults, redirectUrl); }; break; } - case 'eth_sign': { + case 'personal_sign': { const { message } = remainingParams; const params = [accountAddress, message]; payload = { method, params, }; + redirect = results => { + const updatedResults = { + ...results, + address: accountAddress, + msg: message, + }; + return parseResultsForRedirect(updatedResults, redirectUrl); + }; break; } case 'eth_sendTransaction': { diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index adbe38486ae..6e9f186eb2f 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -116,7 +116,6 @@ ImportSeedPhraseSheet.propTypes = { onInputChange: PropTypes.func, onPasteSeedPhrase: PropTypes.func, onPressEnterKey: PropTypes.func, - screenProps: PropTypes.shape({ handleWalletConfig: PropTypes.func }), seedPhrase: PropTypes.string, }; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index c9e6963036c..56d46cfab0e 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -181,7 +181,7 @@ const MainNavigator = createStackNavigator( const AppContainer = createAppContainer(MainNavigator); -const AppContainerWithAnalytics = ({ ref, screenProps }) => ( +const AppContainerWithAnalytics = React.forwardRef((props, ref) => ( { const { params, routeName } = Navigation.getActiveRoute(currentState); @@ -229,8 +229,7 @@ const AppContainerWithAnalytics = ({ ref, screenProps }) => ( } }} ref={ref} - screenProps={screenProps} /> -); +)); export default React.memo(AppContainerWithAnalytics); diff --git a/src/screens/TransactionConfirmationScreenWithData.js b/src/screens/TransactionConfirmationScreenWithData.js index ef20f20cce7..ce62ff8884d 100644 --- a/src/screens/TransactionConfirmationScreenWithData.js +++ b/src/screens/TransactionConfirmationScreenWithData.js @@ -136,9 +136,6 @@ class TransactionConfirmationScreenWithData extends PureComponent { } if (flatFormatSignature) { - if (callback) { - callback({ signature: flatFormatSignature }); - } analytics.track('Approved WalletConnect signature request'); if (requestId) { this.props.removeRequest(requestId); @@ -148,6 +145,9 @@ class TransactionConfirmationScreenWithData extends PureComponent { flatFormatSignature ); } + if (callback) { + callback({ sig: flatFormatSignature }); + } this.closeScreen(); } else { await this.handleCancelRequest(); @@ -176,6 +176,7 @@ class TransactionConfirmationScreenWithData extends PureComponent { method === SEND_TRANSACTION ? 'transaction' : 'signature'; analytics.track(`Rejected WalletConnect ${rejectionType} request`); } catch (error) { + console.log('error while handling cancel request', error); this.closeScreen(); Alert.alert(lang.t('wallet.transaction.alert.cancelled_transaction')); } diff --git a/yarn.lock b/yarn.lock index 61b2347e4b2..583bd4d483e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1450,10 +1450,22 @@ resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.36.tgz#43985f3e1d5c994f1f264eb5ef5eb9661a285975" integrity sha512-QcKGR68KlcN78HYF98RaQnTOgeqB2Vo//0ye9dyJCCmB4ziaxQyvXI7zkrtAl/FNjYPggo+7MGYszel1ggPQxQ== +<<<<<<< HEAD "@walletconnect/utils@^1.0.0-beta.36": version "1.0.0-beta.36" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.36.tgz#34c9def70f9db1ffcdd8e5fc94d9ce30dc716b8a" integrity sha512-SlAqiWJLs/EG+eqxqWO/zOZRz06GYBKGlfK5OX203UjOl6Ps8WLN/D7l8llX97TdGzcGw5+b9Wq+kKuWR2HFQA== +======= +"@walletconnect/types@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.35.tgz#02577da82a85361c68518350fe6139dee4a43445" + integrity sha512-xlcSt0ZdEkiYmCpuO6cleLk1MmjyMPCCT5o1/z0zcRV15uDxfb+N9J/S2uVZBoLtnBtUK1m+11sRF3KrIo9FgQ== + +"@walletconnect/utils@^1.0.0-beta.31": + version "1.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.31.tgz#a73ea81325750208b5298680bf3f82208f0d4f37" + integrity sha512-cTZu+EzoEdvbkT36o+4VqBsD7ro5pXrOu9sswgcWkZ2xVFfRSnNctJkUdeK3JOu1wPnG25/QaRr3fQx4ZoIBrQ== +>>>>>>> 179f29ae... add deeplink responses dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" @@ -1461,6 +1473,17 @@ "@walletconnect/types" "^1.0.0-beta.36" bignumber.js "^8.1.1" +"@walletconnect/utils@^1.0.0-beta.35": + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.35.tgz#6c8c86cb7da9aa94f5d460cf81d1ef73ebf3a0fb" + integrity sha512-ru+IOU3vr9/BJvv3Vjgxnn0t5EW3zLzQinWBBR91GXvIfOCMn5uqhgtZ//pgVqaDi/EyHQXtUe4ZvPfqO5Zulw== + dependencies: + "@ethersproject/address" "^5.0.0-beta.125" + "@ethersproject/bytes" "^5.0.0-beta.126" + "@ethersproject/strings" "^5.0.0-beta.125" + "@walletconnect/types" "^1.0.0-beta.35" + bignumber.js "^8.1.1" + "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" From f239751fcc15d9131bc94bfb7871e72f202a5495 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 4 Sep 2019 13:40:09 -0400 Subject: [PATCH 357/636] add query param separator check in redirect url response --- src/hoc/withDeepLink.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hoc/withDeepLink.js b/src/hoc/withDeepLink.js index 118bdab57d5..1ce85b33710 100644 --- a/src/hoc/withDeepLink.js +++ b/src/hoc/withDeepLink.js @@ -18,7 +18,8 @@ const mapStateToProps = ({ const parseResultsForRedirect = (results, redirectUrl) => { const queryString = parseObjectToUrlQueryString(results); - const updatedRedirectUrl = `${redirectUrl}?${queryString}`; + const querySeparator = redirectUrl.includes('?') ? '&' : '?'; + const updatedRedirectUrl = `${redirectUrl}${querySeparator}${queryString}`; return Linking.openURL(updatedRedirectUrl); }; From c6dc7d20bcff03f292d1451713ded0284ea62586 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 4 Sep 2019 14:02:17 -0400 Subject: [PATCH 358/636] fix header on txn confirm screen --- src/screens/TransactionConfirmationScreen.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 460101f8610..5fa0d82d3a3 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -111,6 +111,13 @@ export default class TransactionConfirmationScreen extends PureComponent { ); + requestHeader = () => { + const { method } = this.props; + return isMessageDisplayType(method) + ? lang.t('wallet.message_signing.request') + : lang.t('wallet.transaction.request'); + }; + renderTransactionSection = () => { const { request, method } = this.props; @@ -164,7 +171,7 @@ export default class TransactionConfirmationScreen extends PureComponent { {this.props.dappName} - {lang.t('wallet.transaction.request')} + {this.requestHeader()} diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index e8290dccd6c..cbd532bbd3a 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -1,16 +1,5 @@ import analytics from '@segment/analytics-react-native'; -import { - get, - indexOf, - isEmpty, - isFunction, - isString, - map, - property, - sortBy, - upperFirst, - toLower, -} from 'lodash'; +import { get, isEmpty, isString, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { Keyboard, KeyboardAvoidingView } from 'react-native'; @@ -34,8 +23,7 @@ import { withUniqueTokens, } from '../hoc'; import { borders, colors } from '../styles'; -import { deviceUtils, isNewValueForPath } from '../utils'; -import { showActionSheetWithOptions } from '../utils/actionsheet'; +import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; import { getLocalContacts } from '../handlers/localstorage/contacts'; const statusBarHeight = getStatusBarHeight(true); @@ -52,32 +40,13 @@ const SheetContainer = styled(Column)` top: ${statusBarHeight}; `; -const formatGasSpeedItem = (value, key) => { - const cost = get(value, 'txFee.native.value.display'); - const gwei = get(value, 'value.display'); - const time = get(value, 'estimatedTime.display'); - - return { - gweiValue: gwei, - label: `${upperFirst(key)}: ${cost} ~${time.slice(0, -1)}`, - value: key, - }; -}; - -const labelOrder = ['slow', 'average', 'fast']; - -const formatGasSpeedItems = gasPrices => { - const gasItems = map(gasPrices, formatGasSpeedItem); - return sortBy(gasItems, ({ value }) => indexOf(labelOrder, value)); -}; - class SendSheet extends Component { static propTypes = { allAssets: PropTypes.array, assetAmount: PropTypes.string, fetchData: PropTypes.func, - gasPrice: PropTypes.object, gasPrices: PropTypes.object, + gasUpdateGasPriceOption: PropTypes.func, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, @@ -86,11 +55,11 @@ class SendSheet extends Component { onSubmit: PropTypes.func, recipient: PropTypes.string, selected: PropTypes.object, + selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), sendClearFields: PropTypes.func, sendMaxBalance: PropTypes.func, sendUpdateAssetAmount: PropTypes.func, - sendUpdateGasPrice: PropTypes.func, sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, sendUpdateSelected: PropTypes.func, @@ -194,29 +163,12 @@ class SendSheet extends Component { }; onPressTransactionSpeed = onSuccess => { - const { gasPrices, sendUpdateGasPrice } = this.props; - - const options = [{ label: 'Cancel' }, ...formatGasSpeedItems(gasPrices)]; - - showActionSheetWithOptions( - { - cancelButtonIndex: 0, - options: options.map(property('label')), - }, - buttonIndex => { - if (buttonIndex > 0) { - const selectedGasPriceItem = options[buttonIndex]; - - sendUpdateGasPrice(selectedGasPriceItem.value); - analytics.track('Updated Gas Price', { - gasPrice: selectedGasPriceItem.gweiValue, - }); - } - - if (isFunction(onSuccess)) { - onSuccess(); - } - } + const { gasPrices, gasUpdateGasPriceOption, txFees } = this.props; + gasUtils.showTransactionSpeedOptions( + gasPrices, + txFees, + gasUpdateGasPriceOption, + onSuccess ); }; @@ -269,11 +221,11 @@ class SendSheet extends Component { const { allAssets, fetchData, - gasPrice, isValidAddress, nativeCurrencySymbol, recipient, selected, + selectedGasPrice, sendableUniqueTokens, sendUpdateRecipient, ...props @@ -329,7 +281,7 @@ class SendSheet extends Component { txSpeedRenderer={ isIphoneX() && ( From b33264d3cbf6b32355214b01680a698306c774bb Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 1 Nov 2019 17:04:09 -0400 Subject: [PATCH 452/636] fix: removal of pending unlock transactions once they are confirmed --- src/components/coin-row/ExchangeCoinRow.js | 14 +++++++++----- src/parsers/transactions.js | 8 ++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index c813bb38b25..2689700568d 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -10,11 +10,15 @@ import BottomRowText from './BottomRowText'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; -const BottomRow = ({ balance, native, showBalance, symbol }) => ( - - {showBalance ? `${balance.display} ≈ ${native.balance.display}` : symbol} - -); +const BottomRow = ({ balance, native, showBalance, symbol }) => { + let text = symbol; + if (showBalance && native) { + text = `${balance.display} ≈ ${native.balance.display}`; + } else if (showBalance) { + text = `${balance.display}`; + } + return {text}; +}; const balanceShape = { balance: PropTypes.shape({ display: PropTypes.string }), diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index 6a2c01b3e42..9841b16a788 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -134,6 +134,14 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { }; internalTransactions = [assetInternalTransaction]; } + if (isEmpty(changes) && txn.type === 'authorize') { + const approveInternalTransaction = { + address_from: transaction.from, + address_to: transaction.to, + asset: get(txn, 'meta.asset'), + }; + internalTransactions = [approveInternalTransaction]; + } // logic below: prevent sending yourself money to be seen as a trade if ( changes.length === 2 && From 728870e4ad35d48eeeff3e1e3081b6ed6c84cf4d Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 2 Nov 2019 17:27:19 -0400 Subject: [PATCH 453/636] Fix: convert slippage bips to percentage format Changes made: - Updated slippage warning thresholds to use bips for clarity - Fix slippage bips to percentage format before being displayed - Use execution rate slippage instead of market rate slippage Market rate slippage is the slippage between the pre and post trade market rates. (Market rates only take into account the input / output token reserves.) Execution rate slippage is the slippage between the pre-trade market rate and the execution rate. (Execution rates take into account the actual trade itself as well as fees.) The main difference between these two slippage rate is the fee. --- src/components/exchange/SlippageWarning.js | 52 +++++++++++----------- src/helpers/__tests__/utilities.test.js | 51 ++++++++++++++++++++- src/helpers/utilities.js | 39 ++++++++-------- src/screens/ExchangeModal.js | 2 +- 4 files changed, 99 insertions(+), 45 deletions(-) diff --git a/src/components/exchange/SlippageWarning.js b/src/components/exchange/SlippageWarning.js index 97301ce4bff..dfc3d5bb7d3 100644 --- a/src/components/exchange/SlippageWarning.js +++ b/src/components/exchange/SlippageWarning.js @@ -3,13 +3,14 @@ import PropTypes from 'prop-types'; import React from 'react'; import { compose, onlyUpdateForKeys, withProps } from 'recompact'; import styled from 'styled-components/primitives'; +import { convertBipsToPercentage } from '../../helpers/utilities'; import { colors, padding } from '../../styles'; import { Icon } from '../icons'; import { Row, RowWithMargins } from '../layout'; import { Text } from '../text'; -export const SlippageWarningTheshold = 5; -const SevereSlippageThreshold = SlippageWarningTheshold * 2; +export const SlippageWarningThresholdInBips = 500; +const SevereSlippageThresholdInBips = SlippageWarningThresholdInBips * 2; const Container = styled(Row).attrs({ align: 'center', @@ -21,7 +22,7 @@ const Container = styled(Row).attrs({ `; const formatSlippage = slippage => - slippage ? parseFloat(slippage).toFixed(1) : 0; + slippage ? convertBipsToPercentage(slippage, 1) : 0; const renderSlippageText = displayValue => ( @@ -32,42 +33,43 @@ const renderSlippageText = displayValue => ( const enhance = compose( onlyUpdateForKeys(['slippage']), withProps(({ slippage }) => { - const fixedSlippage = formatSlippage(slippage); - const isSevere = fixedSlippage > SevereSlippageThreshold; + const isSevere = slippage >= SevereSlippageThresholdInBips; return { isSevere, severityColor: isSevere ? colors.brightRed : colors.brightOrange, - slippage: fixedSlippage, + showWarning: slippage >= SlippageWarningThresholdInBips, }; }) ); -const SlippageWarning = enhance(({ isSevere, severityColor, slippage }) => - slippage < SlippageWarningTheshold ? null : ( - - - - - - - {isSevere ? 'Please swap less' : 'Consider swapping less'} - - - ) +const SlippageWarning = enhance( + ({ isSevere, severityColor, showWarning, slippage }) => + showWarning ? ( + + + + + + + {isSevere ? 'Please swap less' : 'Consider swapping less'} + + + ) : null ); SlippageWarning.propTypes = { isSevere: PropTypes.bool, onPress: PropTypes.func, severityColor: PropTypes.string, + showWarning: PropTypes.bool, slippage: PropTypes.string, }; diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js index 8e093a8e750..a522fe3c991 100644 --- a/src/helpers/__tests__/utilities.test.js +++ b/src/helpers/__tests__/utilities.test.js @@ -1,4 +1,53 @@ -import { updatePrecisionToDisplay } from '../utilities'; +import { + convertBipsToPercentage, + handleSignificantDecimals, + updatePrecisionToDisplay, +} from '../utilities'; + +it('handleSignificantDecimals greater than 1, decimals 2', () => { + const result = handleSignificantDecimals('5.123', 2); + expect(result).toBe('5.12'); +}); + +it('handleSignificantDecimals greater than 1, decimals 18', () => { + const result = handleSignificantDecimals('5.1234', 18); + expect(result).toBe('5.123'); +}); + +it('handleSignificantDecimals greater than 1, decimals 18, long trail', () => { + const result = handleSignificantDecimals('5.00001234', 18); + expect(result).toBe('5.00'); +}); + +it('handleSignificantDecimals less than 1 and few decimals', () => { + const result = handleSignificantDecimals('0.012344', 2); + expect(result).toBe('0.0123'); +}); + +it('handleSignificantDecimals less than 1 and many decimals', () => { + const result = handleSignificantDecimals('0.00000000123', 18); + expect(result).toBe('0.00'); +}); + +it('convertBipsToPercentage, 2 decimal places', () => { + const result = convertBipsToPercentage('1', 2); + expect(result).toBe('0.01'); +}); + +it('convertBipsToPercentage, 1 decimal place', () => { + const result = convertBipsToPercentage('1', 1); + expect(result).toBe('0.0'); +}); + +it('convertBipsToPercentage, 10 bips to 1 decimal', () => { + const result = convertBipsToPercentage('10', 1); + expect(result).toBe('0.1'); +}); + +it('convertBipsToPercentage', () => { + const result = convertBipsToPercentage('12.34567', 2); + expect(result).toBe('0.12'); +}); it('updatePrecisionToDisplay1', () => { const result = updatePrecisionToDisplay('0.00000000123', '0.1234987234'); diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index d08b0d42931..45d4d6891f5 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -183,20 +183,6 @@ export const convertAmountFromNativeValue = (value, priceUnit) => .dividedBy(BigNumber(priceUnit)) .toFixed(); -/** - * @desc handle signficant decimals in display format - * @param {String|Number} value - * @param {Number} decimals - * @param {Number} buffer - * @return {String} - */ -export const handleSignificantDecimals = (value, decimals, buffer) => { - const result = significantDecimals(value, decimals, buffer); - return BigNumber(`${result}`).dp() <= 2 - ? BigNumber(`${result}`).toFormat(2) - : BigNumber(`${result}`).toFormat(); -}; - /** * @desc convert from string to number * @param {String} value @@ -220,7 +206,7 @@ export const smallerThan = (numberOne, numberTwo) => * @param {Number} buffer * @return {String} */ -export const significantDecimals = (value, decimals, buffer) => { +export const handleSignificantDecimals = (value, decimals, buffer) => { if ( !BigNumber(`${decimals}`).isInteger() || (buffer && !BigNumber(`${buffer}`).isInteger()) @@ -242,7 +228,9 @@ export const significantDecimals = (value, decimals, buffer) => { } let result = BigNumber(`${value}`).toFixed(decimals); result = BigNumber(`${result}`).toFixed(); - return result; + return BigNumber(`${result}`).dp() <= 2 + ? BigNumber(`${result}`).toFormat(2) + : BigNumber(`${result}`).toFormat(); }; /** @@ -340,11 +328,26 @@ export const convertAmountToBalanceDisplay = (value, asset, buffer) => { * @param {Number} buffer * @return {String} */ -export const convertAmountToPercentageDisplay = (value, buffer) => { - const display = handleSignificantDecimals(value, 2, buffer); +export const convertAmountToPercentageDisplay = ( + value, + decimals = 2, + buffer +) => { + const display = handleSignificantDecimals(value, decimals, buffer); return `${display}%`; }; +/** + * @desc convert from bips amount to percentage format + * @param {BigNumber} value in bips + * @param {Number} decimals + * @return {String} + */ +export const convertBipsToPercentage = (value, decimals = 2) => + BigNumber(`${value}`) + .shiftedBy(-2) + .toFixed(decimals); + /** * @desc convert from amount value to display formatted string * @param {BigNumber} value diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 6a55d3ee486..1beb18c6fe2 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -386,7 +386,7 @@ class ExchangeModal extends React.Component { ); } - const slippage = get(tradeDetails, 'marketRateSlippage', 0).toString(); + const slippage = get(tradeDetails, 'executionRateSlippage', 0).toFixed(); this.setState({ inputExecutionRate, From 9e27d77e1c3bb319d6d6150b78f15ea7a9a3e36d Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 28 Oct 2019 18:57:42 -0400 Subject: [PATCH 454/636] Revert "React native 0.61 bump (#195)" This reverts commit d64d0950484d017260c11f92c8fe902e239c39e7. --- .flowconfig | 78 ++++--- .gitignore | 1 - .prettierrc.js | 6 - ios/Podfile | 15 +- ios/Podfile.lock | 355 +++++++++----------------------- package.json | 17 +- yarn.lock | 522 ++++++++++------------------------------------- 7 files changed, 254 insertions(+), 740 deletions(-) delete mode 100644 .prettierrc.js diff --git a/.flowconfig b/.flowconfig index 9edb1be387b..7ad43751ac2 100644 --- a/.flowconfig +++ b/.flowconfig @@ -5,71 +5,63 @@ ; Ignore "BUCK" generated dirs /\.buckd/ -; Ignore polyfills -node_modules/react-native/Libraries/polyfills/.* +; Ignore unexpected extra "@providesModule" +.*/node_modules/.*/node_modules/fbjs/.* -; These should not be required directly -; require from fbjs/lib instead: require('fbjs/lib/warning') -node_modules/warning/.* +; Ignore duplicate module providers +; For RN Apps installed via npm, "Libraries" folder is inside +; "node_modules/react-native" but in the source repo it is in the root +.*/Libraries/react-native/React.js -; Flow doesn't support platforms -.*/Libraries/Utilities/LoadingView.js +; Ignore polyfills +.*/Libraries/polyfills/.* -[untyped] -.*/node_modules/@react-native-community/cli/.*/.* +; Ignore metro +.*/node_modules/metro/.* [include] [libs] node_modules/react-native/Libraries/react-native/react-native-interface.js node_modules/react-native/flow/ +node_modules/react-native/flow-github/ [options] emoji=true -esproposal.optional_chaining=enable -esproposal.nullish_coalescing=enable - -module.file_ext=.js -module.file_ext=.json -module.file_ext=.ios.js +module.system=haste +module.system.haste.use_name_reducers=true +# get basename +module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' +# strip .js or .js.flow suffix +module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' +# strip .ios suffix +module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' +module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' +module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' +module.system.haste.paths.blacklist=.*/__tests__/.* +module.system.haste.paths.blacklist=.*/__mocks__/.* +module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* +module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* munge_underscores=true -module.name_mapper='^react-native$' -> '/node_modules/react-native/Libraries/react-native/react-native-implementation' -module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' -module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' +module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' + +module.file_ext=.js +module.file_ext=.jsx +module.file_ext=.json +module.file_ext=.native.js suppress_type=$FlowIssue suppress_type=$FlowFixMe suppress_type=$FlowFixMeProps suppress_type=$FlowFixMeState -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError -[lints] -sketchy-null-number=warn -sketchy-null-mixed=warn -sketchy-number=warn -untyped-type-import=warn -nonstrict-import=warn -deprecated-type=warn -unsafe-getters-setters=warn -inexact-spread=warn -unnecessary-invariant=warn -signature-verification-failure=warn -deprecated-utility=error - -[strict] -deprecated-type -nonstrict-import -sketchy-null -unclear-type -unsafe-getters-setters -untyped-import -untyped-type-import - [version] -^0.105.0 \ No newline at end of file +^0.92.0 diff --git a/.gitignore b/.gitignore index 8dc0a7d6a8a..f13d7e7ba74 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ yarn-error.log buck-out/ \.buckd/ *.keystore -!debug.keystore # fastlane # diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index e516059d776..00000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - bracketSpacing: true, - jsxBracketSameLine: false, - singleQuote: true, - trailingComma: 'all', -}; \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index 4b33fb4594c..8d155b79d1a 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -13,14 +13,9 @@ target 'Rainbow' do pod 'Firebase/Messaging', '~> 5.3.0' # Core React - pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" - pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" - pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" - pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" pod 'React', :path => '../node_modules/react-native/' - pod 'React-Core', :path => '../node_modules/react-native/' - pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' - pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' + pod 'React-Core', :path => '../node_modules/react-native/React' + pod 'React-DevSupport', :path => '../node_modules/react-native/React' pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' @@ -30,7 +25,7 @@ target 'Rainbow' do pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' - pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' + pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' @@ -38,9 +33,7 @@ target 'Rainbow' do pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' # React Third Party - required - pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" - pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" - pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' + pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4d8463b2e8b..e8580d2108c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -7,14 +7,6 @@ PODS: - Fabric (~> 1.7.13) - DoubleConversion (1.1.6) - Fabric (1.7.13) - - FBLazyVector (0.61.2) - - FBReactNativeSpec (0.61.2): - - Folly (= 2018.10.22.00) - - RCTRequired (= 0.61.2) - - RCTTypeSafety (= 0.61.2) - - React-Core (= 0.61.2) - - React-jsi (= 0.61.2) - - ReactCommon/turbomodule/core (= 0.61.2) - Firebase/Core (5.3.0): - Firebase/CoreOnly - FirebaseAnalytics (= 5.0.1) @@ -62,175 +54,57 @@ PODS: - libwebp/mux (1.0.3): - libwebp/demux - libwebp/webp (1.0.3) - - nanopb (0.3.904): - - nanopb/decode (= 0.3.904) - - nanopb/encode (= 0.3.904) - - nanopb/decode (0.3.904) - - nanopb/encode (0.3.904) + - nanopb (0.3.9011): + - nanopb/decode (= 0.3.9011) + - nanopb/encode (= 0.3.9011) + - nanopb/decode (0.3.9011) + - nanopb/encode (0.3.9011) - Protobuf (3.10.0) - - RCTRequired (0.61.2) - - RCTTypeSafety (0.61.2): - - FBLazyVector (= 0.61.2) - - Folly (= 2018.10.22.00) - - RCTRequired (= 0.61.2) - - React-Core (= 0.61.2) - - React (0.61.2): - - React-Core (= 0.61.2) - - React-Core/DevSupport (= 0.61.2) - - React-Core/RCTWebSocket (= 0.61.2) - - React-RCTActionSheet (= 0.61.2) - - React-RCTAnimation (= 0.61.2) - - React-RCTBlob (= 0.61.2) - - React-RCTImage (= 0.61.2) - - React-RCTLinking (= 0.61.2) - - React-RCTNetwork (= 0.61.2) - - React-RCTSettings (= 0.61.2) - - React-RCTText (= 0.61.2) - - React-RCTVibration (= 0.61.2) - - React-Core (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/CoreModulesHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/Default (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/DevSupport (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default (= 0.61.2) - - React-Core/RCTWebSocket (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - React-jsinspector (= 0.61.2) - - Yoga - - React-Core/RCTActionSheetHeaders (0.61.2): + - React (0.60.5): + - React-Core (= 0.60.5) + - React-DevSupport (= 0.60.5) + - React-RCTActionSheet (= 0.60.5) + - React-RCTAnimation (= 0.60.5) + - React-RCTBlob (= 0.60.5) + - React-RCTImage (= 0.60.5) + - React-RCTLinking (= 0.60.5) + - React-RCTNetwork (= 0.60.5) + - React-RCTSettings (= 0.60.5) + - React-RCTText (= 0.60.5) + - React-RCTVibration (= 0.60.5) + - React-RCTWebSocket (= 0.60.5) + - React-Core (0.60.5): - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTAnimationHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTBlobHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTImageHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTLinkingHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTNetworkHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTSettingsHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTTextHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTVibrationHeaders (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-Core/RCTWebSocket (0.61.2): - - Folly (= 2018.10.22.00) - - glog - - React-Core/Default (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - Yoga - - React-CoreModules (0.61.2): - - FBReactNativeSpec (= 0.61.2) - - Folly (= 2018.10.22.00) - - RCTTypeSafety (= 0.61.2) - - React-Core/CoreModulesHeaders (= 0.61.2) - - React-RCTImage (= 0.61.2) - - ReactCommon/turbomodule/core (= 0.61.2) - - React-cxxreact (0.61.2): + - React-cxxreact (= 0.60.5) + - React-jsiexecutor (= 0.60.5) + - yoga (= 0.60.5.React) + - React-cxxreact (0.60.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsinspector (= 0.61.2) - - React-jsi (0.61.2): + - React-jsinspector (= 0.60.5) + - React-DevSupport (0.60.5): + - React-Core (= 0.60.5) + - React-RCTWebSocket (= 0.60.5) + - React-jsi (0.60.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsi/Default (= 0.61.2) - - React-jsi/Default (0.61.2): + - React-jsi/Default (= 0.60.5) + - React-jsi/Default (0.60.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsiexecutor (0.61.2): + - React-jsiexecutor (0.60.5): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsinspector (0.61.2) + - React-cxxreact (= 0.60.5) + - React-jsi (= 0.60.5) + - React-jsinspector (0.60.5) - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -247,41 +121,29 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React-RCTActionSheet (0.61.2): - - React-Core/RCTActionSheetHeaders (= 0.61.2) - - React-RCTAnimation (0.61.2): - - React-Core/RCTAnimationHeaders (= 0.61.2) - - React-RCTBlob (0.61.2): - - React-Core/RCTBlobHeaders (= 0.61.2) - - React-Core/RCTWebSocket (= 0.61.2) - - React-jsi (= 0.61.2) - - React-RCTNetwork (= 0.61.2) - - React-RCTImage (0.61.2): - - React-Core/RCTImageHeaders (= 0.61.2) - - React-RCTNetwork (= 0.61.2) - - React-RCTLinking (0.61.2): - - React-Core/RCTLinkingHeaders (= 0.61.2) - - React-RCTNetwork (0.61.2): - - React-Core/RCTNetworkHeaders (= 0.61.2) - - React-RCTSettings (0.61.2): - - React-Core/RCTSettingsHeaders (= 0.61.2) - - React-RCTText (0.61.2): - - React-Core/RCTTextHeaders (= 0.61.2) - - React-RCTVibration (0.61.2): - - React-Core/RCTVibrationHeaders (= 0.61.2) - - ReactCommon/jscallinvoker (0.61.2): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-cxxreact (= 0.61.2) - - ReactCommon/turbomodule/core (0.61.2): - - DoubleConversion - - Folly (= 2018.10.22.00) - - glog - - React-Core (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - ReactCommon/jscallinvoker (= 0.61.2) + - React-RCTActionSheet (0.60.5): + - React-Core (= 0.60.5) + - React-RCTAnimation (0.60.5): + - React-Core (= 0.60.5) + - React-RCTBlob (0.60.5): + - React-Core (= 0.60.5) + - React-RCTNetwork (= 0.60.5) + - React-RCTWebSocket (= 0.60.5) + - React-RCTImage (0.60.5): + - React-Core (= 0.60.5) + - React-RCTNetwork (= 0.60.5) + - React-RCTLinking (0.60.5): + - React-Core (= 0.60.5) + - React-RCTNetwork (0.60.5): + - React-Core (= 0.60.5) + - React-RCTSettings (0.60.5): + - React-Core (= 0.60.5) + - React-RCTText (0.60.5): + - React-Core (= 0.60.5) + - React-RCTVibration (0.60.5): + - React-Core (= 0.60.5) + - React-RCTWebSocket (0.60.5): + - React-Core (= 0.60.5) - RNAnalytics (1.1.0): - Analytics - React @@ -305,35 +167,29 @@ PODS: - React - RNStoreReview (0.1.5): - React - - SDWebImage (5.2.3): - - SDWebImage/Core (= 5.2.3) - - SDWebImage/Core (5.2.3) + - SDWebImage (5.2.5): + - SDWebImage/Core (= 5.2.5) + - SDWebImage/Core (5.2.5) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) - - Yoga (1.14.0) + - yoga (0.60.5.React) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) - Crashlytics (~> 3.10.7) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - Fabric (~> 1.7.11) - - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) - Firebase/Core (~> 5.3.0) - Firebase/Messaging (~> 5.3.0) - FLAnimatedImage - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - libwebp - - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - React (from `../node_modules/react-native/`) - - React-Core (from `../node_modules/react-native/`) - - React-Core/DevSupport (from `../node_modules/react-native/`) - - React-Core/RCTWebSocket (from `../node_modules/react-native/`) - - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) + - React-Core (from `../node_modules/react-native/React`) - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) + - React-DevSupport (from `../node_modules/react-native/React`) - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) @@ -351,8 +207,7 @@ DEPENDENCIES: - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) - - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -363,10 +218,10 @@ DEPENDENCIES: - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNStoreReview (from `../node_modules/react-native-store-review/ios`) - - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) + - yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - trunk: + https://github.com/cocoapods/specs.git: - Analytics - boost-for-react-native - Crashlytics @@ -389,26 +244,18 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-linear-gradient" DoubleConversion: :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" - FBLazyVector: - :path: "../node_modules/react-native/Libraries/FBLazyVector" - FBReactNativeSpec: - :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" Folly: :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" - RCTRequired: - :path: "../node_modules/react-native/Libraries/RCTRequired" - RCTTypeSafety: - :path: "../node_modules/react-native/Libraries/TypeSafety" React: :path: "../node_modules/react-native/" React-Core: - :path: "../node_modules/react-native/" - React-CoreModules: - :path: "../node_modules/react-native/React/CoreModules" + :path: "../node_modules/react-native/React" React-cxxreact: :path: "../node_modules/react-native/ReactCommon/cxxreact" + React-DevSupport: + :path: "../node_modules/react-native/React" React-jsi: :path: "../node_modules/react-native/ReactCommon/jsi" React-jsiexecutor: @@ -443,8 +290,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Text" React-RCTVibration: :path: "../node_modules/react-native/Libraries/Vibration" - ReactCommon: - :path: "../node_modules/react-native/ReactCommon" + React-RCTWebSocket: + :path: "../node_modules/react-native/Libraries/WebSocket" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -465,7 +312,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-screens" RNStoreReview: :path: "../node_modules/react-native-store-review/ios" - Yoga: + yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: @@ -475,44 +322,40 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 68b6a76960fbd8ecd9fb7ce0aadd3329c3340a99 - FBReactNativeSpec: 5a764c60abdc3336a213e5310c40b74741f32839 - Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa - FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 - FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 - FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 - FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb + Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 + FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d + FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 + FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 + FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: 800648f8b3127618c1b59c7f97684427630c5ea3 libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e - nanopb: 06f6030d554e6473f5e172460173fcf80f5548f4 + nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: c639d59ed389cfb1f1203f65c2ea946d8ec586e2 - RCTTypeSafety: dc23fb655d6c77667c78e327bf661bc11e3b8aec - React: 7e586e5d7bec12b91c1a096826b0fc9ab1da7865 - React-Core: 8ddb9770b4a30a6ab4a754e6ed5ec76454e3d699 - React-CoreModules: b3d9eece8ad7df36c917a41f05c1168c52fe0b34 - React-cxxreact: 1f972757c0bd08d962ef78068e06613c27489a3f - React-jsi: 32285a21b1b24c36060493ed3057a34677d58d09 - React-jsiexecutor: 8909917ff7d8f21a57e443a866fd8d4560e50c65 - React-jsinspector: 111d7d342b07a904c400592e02a2b958f1098b60 + React: 53c53c4d99097af47cf60594b8706b4e3321e722 + React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64 + React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395 + React-DevSupport: 197fb409737cff2c4f9986e77c220d7452cb9f9f + React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 + React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 + React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-netinfo: 6bb847e64f45a2d69c6173741111cfd95c669301 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 89b037c0fb7d2671607cb645760164e7e0c013f6 - React-RCTAnimation: e3cefa93c38c004c318f7ec04b883eb14b8b8235 - React-RCTBlob: d26ac0e313fbf14e7203473fd593ccaaeee8329e - React-RCTImage: 4bdd9588783fa9e48ef669ccd4f747224e208edf - React-RCTLinking: 65f0088ff463babd3d5d567964a65b74141eff3b - React-RCTNetwork: 0c1a73576c1cfeafe68396556de1b17d93c0c595 - React-RCTSettings: 4194f1f0edbddf3fd44d1714dc6578bb20379b60 - React-RCTText: e3ef6191cdb627855ff7fe8fa0c1e14094967fb8 - React-RCTVibration: fb54c732fd20405a76598e431aa2f8c2bf527de9 - ReactCommon: 5848032ed2f274fcb40f6b9ec24067787c42d479 + React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 + React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e + React-RCTBlob: 5e2b55f76e9a1c7ae52b826923502ddc3238df24 + React-RCTImage: f5f1c50922164e89bdda67bcd0153952a5cfe719 + React-RCTLinking: d0ecbd791e9ddddc41fa1f66b0255de90e8ee1e9 + React-RCTNetwork: e26946300b0ab7bb6c4a6348090e93fa21f33a9d + React-RCTSettings: d0d37cb521b7470c998595a44f05847777cc3f42 + React-RCTText: b074d89033583d4f2eb5faf7ea2db3a13c7553a2 + React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0 + React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 @@ -523,10 +366,10 @@ SPEC CHECKSUMS: RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - SDWebImage: 46a7f73228f84ce80990c786e4372cf4db5875ce + SDWebImage: 4eabf2fa6695c95c47724214417a9c036c965e4a SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 - Yoga: 14927e37bd25376d216b150ab2a561773d57911f + yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 -PODFILE CHECKSUM: a039fce385962c5aff74e63f1df4ed5302b9aa01 +PODFILE CHECKSUM: 33865f4d2b0b4f3f246921d3679430cd55088e21 -COCOAPODS: 1.8.4 +COCOAPODS: 1.6.1 diff --git a/package.json b/package.json index 7b648e42586..602d54dea18 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "1.1.6-3", "private": true, "scripts": { - "android": "react-native run-android", "clean": "react-native-clean-project", "start": "react-native start", "test": "jest test.js", @@ -71,7 +70,7 @@ "querystring-es3": "^0.2.1", "react": "16.9.0", "react-coin-icon": "^0.1.9", - "react-native": "0.61.2", + "react-native": "0.60.5", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", @@ -106,7 +105,7 @@ "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "9.10.1", + "react-native-svg": "9.13.2", "react-native-tcp": "^3.3.0", "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", "react-native-tooltip": "^5.2.0", @@ -142,26 +141,26 @@ "vm-browserify": "0.0.4" }, "devDependencies": { - "@babel/core": "^7.6.2", - "@babel/runtime": "^7.6.2", + "@babel/core": "^7.5.5", + "@babel/runtime": "^7.5.5", "@react-native-community/cli": "2.9.0", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^10.0.2", - "babel-jest": "^24.9.0", + "babel-jest": "^24.8.0", "babel-plugin-date-fns": "^0.2.1", "babel-plugin-lodash": "^3.3.4", "babel-plugin-rewire": "^1.2.0", "babel-plugin-styled-components": "^1.10.6", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", - "eslint": "^6.5.1", + "eslint": "6.1.0", "eslint-config-satya164": "^2.4.1", - "jest": "^24.9.0", + "jest": "^24.8.0", "metro-react-native-babel-preset": "^0.56.0", "mocha": "^6.1.4", "react-native-bundle-visualizer": "^2.0.1", "react-native-clean-project": "^3.1.0", - "react-test-renderer": "16.9.0", + "react-test-renderer": "16.8.3", "schedule": "0.5.0" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index d2bb655b109..af709ef2f88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.6.2": +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": version "7.6.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.4.tgz#6ebd9fe00925f6c3e177bb726a188b5f578088ff" integrity sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ== @@ -607,7 +607,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.6.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": version "7.6.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f" integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA== @@ -779,9 +779,9 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.4.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.4.0.tgz#3f2153d9eea8942dfe217e1642a420f1fe4087f3" - integrity sha512-JLK+vNrtZSQy1PiAAvtaPGiZhFQo+BLywJkD4EHG8vCzlW9w7Y9yfb2be1GFKnZKczLgzHBpgMOBUZs1qBNB5g== + version "8.5.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" + integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw== "@hapi/joi@^15.0.3": version "15.1.1" @@ -995,7 +995,7 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.9.0": +"@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== @@ -1008,20 +1008,7 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-android@^3.0.0-alpha.1", "@react-native-community/cli-platform-android@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.0-alpha.7.tgz#03c3671ab72b62a8742aa71b66cb8d594171891f" - integrity sha512-Ot/4K841f3vJZM5K7Za/bYgGeXUJyBsZZuoFvnEMAmR/tS6QCrsv8NQ7f/E3HmxvWaSEVNiiF8NiW2+qo6YDxg== - dependencies: - "@react-native-community/cli-tools" "^3.0.0-alpha.7" - chalk "^2.4.2" - execa "^1.0.0" - jetifier "^1.6.2" - logkitty "^0.6.0" - slash "^3.0.0" - xmldoc "^1.1.2" - -"@react-native-community/cli-platform-ios@^2.9.0": +"@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== @@ -1030,16 +1017,6 @@ chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-platform-ios@^3.0.0-alpha.1", "@react-native-community/cli-platform-ios@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0-alpha.7.tgz#21be15fc3b8117e0e62caf1e754f2760d78cfa93" - integrity sha512-6qM5LpzhCEhkb9MC+nxrOHX2TxoN4qm8+Vg9byIW/wExl8dWCTneRUbQ5qFlkkMksS2U63LiRVSCXK08d6x5bA== - dependencies: - "@react-native-community/cli-tools" "^3.0.0-alpha.7" - chalk "^2.4.2" - js-yaml "^3.13.1" - xcode "^2.0.0" - "@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" @@ -1050,22 +1027,7 @@ mime "^2.4.1" node-fetch "^2.5.0" -"@react-native-community/cli-tools@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0-alpha.7.tgz#1018283598e3f2ddc785d1381ca8692ec51735a5" - integrity sha512-x4XdeMtAx7RC1YP5cqLWIggXOuzuANItWi8BD8R/ak6GWMRd3X5L2HFuLa6GDXgkWSXtoUvqOilJplhVhLRrmQ== - dependencies: - chalk "^2.4.2" - lodash "^4.17.5" - mime "^2.4.1" - node-fetch "^2.5.0" - -"@react-native-community/cli-types@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0-alpha.7.tgz#b4c19fd71824400a57c7f6758fa1f7b15eece32d" - integrity sha512-anT+l41FK7EJXOlOx8ZzIgskDuslT5A5NkMg2Kt3YzAxf8wrCBbOo5/CjnuW6pi9fvjGgB810Yw3tFSl4yZY4A== - -"@react-native-community/cli@2.9.0": +"@react-native-community/cli@2.9.0", "@react-native-community/cli@^2.6.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw== @@ -1104,55 +1066,6 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^3.0.0-alpha.1": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.0-alpha.7.tgz#df8cb6a878d106da36e4f994f9d8c3541c3834ee" - integrity sha512-gmAnmH9sqReBEvfZxk0A3gw0Ddb6UNHYvbjjyM+qgH2TbEAWCfLHLqiHNSCYxfO3hkDyz4mj/cvtb8ahFjTdIw== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^3.0.0-alpha.7" - "@react-native-community/cli-platform-ios" "^3.0.0-alpha.7" - "@react-native-community/cli-tools" "^3.0.0-alpha.7" - "@react-native-community/cli-types" "^3.0.0-alpha.7" - "@types/mkdirp" "^0.5.2" - "@types/node-notifier" "^5.4.0" - "@types/semver" "^6.0.2" - "@types/ws" "^6.0.3" - chalk "^2.4.2" - command-exists "^1.2.8" - commander "^2.19.0" - compression "^1.7.1" - connect "^3.6.5" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - envinfo "^7.1.0" - errorhandler "^1.5.0" - execa "^1.0.0" - find-up "^4.1.0" - fs-extra "^7.0.1" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.56.0" - metro-config "^0.56.0" - metro-core "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-notifier "^5.2.1" - open "^6.2.0" - ora "^3.4.0" - plist "^3.0.0" - semver "^6.3.0" - serve-static "^1.13.1" - shell-quote "1.6.1" - strip-ansi "^5.2.0" - sudo-prompt "^9.0.0" - wcwidth "^1.0.1" - ws "^1.1.0" - "@react-native-community/masked-view@^0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.1.tgz#dbcfc5ec08efbb02d4142dd9426c8d7a396829d7" @@ -1404,20 +1317,6 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/node-notifier@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-5.4.0.tgz#4e66c85eb41cce8387b4cd9c6c67852be41a99db" - integrity sha512-M1XvCG6Rwej6+W0+kWultE46YS7erOy+W7suRmXtKwLGT3ytj6YEe9lqo47nRfL1xILzg9xJpKeNczIsWR8ymw== - dependencies: - "@types/node" "*" - "@types/node@*": version "12.12.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.3.tgz#ebfe83507ac506bc3486314a8aa395be66af8d23" @@ -1438,11 +1337,6 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== -"@types/semver@^6.0.2": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.0.tgz#d688d574400d96c5b0114968705366f431831e1a" - integrity sha512-1OzrNb4RuAzIT7wHSsgZRlMBlNsJl+do6UblR7JMW4oB7bbR+uBEYtUh7gEc/jM84GGilh68lSOokyM/zNUlBA== - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -1470,13 +1364,6 @@ "@types/unist" "*" "@types/vfile-message" "*" -"@types/ws@^6.0.3": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.3.tgz#b772375ba59d79066561c8d87500144d674ba6b3" - integrity sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w== - dependencies: - "@types/node" "*" - "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -1734,18 +1621,11 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0: +ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== -ansi-escapes@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" - integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== - dependencies: - type-fest "^0.5.2" - ansi-fragments@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansi-fragments/-/ansi-fragments-0.2.1.tgz#24409c56c4cc37817c3d7caa99d8969e2de5a05e" @@ -2062,7 +1942,7 @@ babel-eslint@^10.0.1, babel-eslint@^10.0.2: eslint-visitor-keys "^1.0.0" resolve "^1.12.0" -babel-jest@^24.9.0: +babel-jest@^24.8.0, babel-jest@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== @@ -2769,13 +2649,6 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - cli-spinners@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" @@ -2931,11 +2804,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -command-exists@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" - integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== - commander@^2.19.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -3189,7 +3057,7 @@ css-select-base-adapter@^0.1.1: resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== -css-select@^2.0.0: +css-select@^2.0.0, css-select@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== @@ -3208,7 +3076,7 @@ css-to-react-native@^2.2.2: css-color-keywords "^1.0.0" postcss-value-parser "^3.3.0" -css-tree@1.0.0-alpha.37: +css-tree@1.0.0-alpha.37, css-tree@^1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== @@ -3988,7 +3856,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.3.1, eslint-utils@^1.4.3: +eslint-utils@^1.3.1: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -4000,10 +3868,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.5.1: - version "6.6.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" - integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== +eslint@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" + integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4012,9 +3880,9 @@ eslint@^6.5.1: debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^6.0.0" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -4024,7 +3892,7 @@ eslint@^6.5.1: ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" + inquirer "^6.4.1" is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" @@ -4043,7 +3911,7 @@ eslint@^6.5.1: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: +espree@^6.0.0: version "6.1.2" resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d" integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA== @@ -4425,13 +4293,6 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -figures@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.1.0.tgz#4b198dd07d8d71530642864af2d45dd9e459c4ec" - integrity sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" @@ -4497,7 +4358,7 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^4.0.0, find-up@^4.1.0: +find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -5073,10 +4934,10 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-engine@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" - integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== +hermesvm@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.1.tgz#bd1df92b4dc504e261c23df34864daf24b844d03" + integrity sha512-EosSDeUqTTGvlc9vQiy5Y/9GBlucEyo6lYuxg/FnukHCD/CP3NYeDAGV54TyZ19FgSqMEoPgOH9cyxvv8epQ1g== hmac-drbg@^1.0.0: version "1.0.1" @@ -5377,22 +5238,22 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" - integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== +inquirer@^6.4.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: - ansi-escapes "^4.2.1" + ansi-escapes "^3.2.0" chalk "^2.4.2" - cli-cursor "^3.1.0" + cli-cursor "^2.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" run-async "^2.2.0" rxjs "^6.4.0" - string-width "^4.1.0" + string-width "^2.1.0" strip-ansi "^5.1.0" through "^2.3.6" @@ -6173,7 +6034,7 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest@^24.9.0: +jest@^24.8.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== @@ -6209,7 +6070,7 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsc-android@^245459.0.0: +jsc-android@245459.0.0: version "245459.0.0" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== @@ -6607,7 +6468,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -6859,24 +6720,6 @@ metro-babel-register@0.54.1: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-register@0.56.3, metro-babel-register@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.3.tgz#d0cfb38adf45cb35965649ede794f2308562e20f" - integrity sha512-ILCRtNFdW6vzqmLAG2MYWdTSE1vCAZqDKNggiNhlfViuoxmWAIL0vOqixl1CHZF5z4t55+fk46A0jSN7UgPyVw== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - metro-babel-transformer@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" @@ -6884,14 +6727,6 @@ metro-babel-transformer@0.54.1: dependencies: "@babel/core" "^7.0.0" -metro-babel-transformer@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz#6559c3a8565238a704a181353cef59fdb974e6db" - integrity sha512-N5/ftb3rBkt6uKlgYAv+lwtzYc4dK0tBpfZ8pjec3kcypGuGTuf4LTHEh65EuzySreLngYI0bQzoFSn3G3DYsw== - dependencies: - "@babel/core" "^7.0.0" - metro-source-map "0.56.3" - metro-babel7-plugin-react-transform@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" @@ -6909,16 +6744,6 @@ metro-cache@0.54.1: mkdirp "^0.5.1" rimraf "^2.5.4" -metro-cache@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.3.tgz#1b0759bc45291cc3ffc77736c09dcfbd322edb8b" - integrity sha512-SsryVe/TVkt2IkEGnYhB3gQlg9iMlu8WJikQHcCEjMfPEnSIzmeymrX73fwQNPnTnN7F3E0HVjH6Wvq6fh0mcA== - dependencies: - jest-serializer "^24.4.0" - metro-core "0.56.3" - mkdirp "^0.5.1" - rimraf "^2.5.4" - metro-config@0.54.1, metro-config@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd" @@ -6931,18 +6756,6 @@ metro-config@0.54.1, metro-config@^0.54.1: metro-core "0.54.1" pretty-format "^24.7.0" -metro-config@0.56.3, metro-config@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.3.tgz#b16e600817c58c768946f24b039d2a1ba6a67651" - integrity sha512-C3ZLA5y5gW5auDSQN5dsCTduJg7LXEiX/tLAADOkgXWVImr5P74x9Wt8y1MMWrKx6p+4p5RMDyEwWDMXJt/DwA== - dependencies: - cosmiconfig "^5.0.5" - jest-validate "^24.7.0" - metro "0.56.3" - metro-cache "0.56.3" - metro-core "0.56.3" - pretty-format "^24.7.0" - metro-core@0.54.1, metro-core@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b" @@ -6953,16 +6766,6 @@ metro-core@0.54.1, metro-core@^0.54.1: metro-resolver "0.54.1" wordwrap "^1.0.0" -metro-core@0.56.3, metro-core@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.3.tgz#34bb3a92621fd9b1ed3e6a01c6a4324fbb1201d9" - integrity sha512-OAaHP3mBdlACMZRwDJzZzYC0o2S3qfb4BBK75L8H4Ds+y3QUSrjsDEpHACcpaMTOds8rBvjzn+jjB5tqNoHfBA== - dependencies: - jest-haste-map "^24.7.1" - lodash.throttle "^4.1.1" - metro-resolver "0.56.3" - wordwrap "^1.0.0" - metro-inspector-proxy@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.54.1.tgz#0ef48ee3feb11c6da47aa100151a9bf2a7c358ee" @@ -6974,17 +6777,6 @@ metro-inspector-proxy@0.54.1: ws "^1.1.5" yargs "^9.0.0" -metro-inspector-proxy@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.3.tgz#48046f9e3f7153be2409e0bee9252dede932ac39" - integrity sha512-7WtHinw+VJcunQ3q8El1MqqzYSRvXEjW5QE13VYwcLtnay3pvcqACeiQmGbWI0IqxB1+QH8tf3nkA7z7pQ7Vpw== - dependencies: - connect "^3.6.5" - debug "^2.2.0" - rxjs "^5.4.3" - ws "^1.1.5" - yargs "^9.0.0" - metro-minify-uglify@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3" @@ -6992,13 +6784,6 @@ metro-minify-uglify@0.54.1: dependencies: uglify-es "^3.1.9" -metro-minify-uglify@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.3.tgz#763b26895f79d0589d3391dc94083d348cf9c2be" - integrity sha512-b9ljyeUpkJWVlFy8M/i4aNbvEBI0zN9vJh1jfU7yx+k9dX7FulLnpGmAQxxQdEszcM//sJrsKNS1oLYBxr0NMQ== - dependencies: - uglify-es "^3.1.9" - metro-react-native-babel-preset@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" @@ -7041,7 +6826,7 @@ metro-react-native-babel-preset@0.54.1: metro-babel7-plugin-react-transform "0.54.1" react-transform-hmr "^1.0.4" -metro-react-native-babel-preset@0.56.3, metro-react-native-babel-preset@^0.56.0: +metro-react-native-babel-preset@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz#5a1097c2f94e8ee0797a8ba2ab8f86d096f4c093" integrity sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow== @@ -7082,7 +6867,7 @@ metro-react-native-babel-preset@0.56.3, metro-react-native-babel-preset@^0.56.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@^0.54.1: +metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== @@ -7092,17 +6877,6 @@ metro-react-native-babel-transformer@^0.54.1: metro-babel-transformer "0.54.1" metro-react-native-babel-preset "0.54.1" -metro-react-native-babel-transformer@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" - integrity sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "0.56.3" - metro-react-native-babel-preset "0.56.3" - metro-source-map "0.56.3" - metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -7110,13 +6884,6 @@ metro-resolver@0.54.1: dependencies: absolute-path "^0.0.0" -metro-resolver@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.3.tgz#f18978b919a5ecc67028732609a564880715ef75" - integrity sha512-VvMl4xUp0fy76WiP3YDtzMmrn6tN/jwxOBqlTy9MjN6R9sUXrGyO5thwn/uKQqp5vwBTuJev7nZL7OKzwludKA== - dependencies: - absolute-path "^0.0.0" - metro-source-map@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5" @@ -7126,26 +6893,25 @@ metro-source-map@0.54.1: "@babel/types" "^7.0.0" source-map "^0.5.6" -metro-source-map@0.56.3, metro-source-map@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.3.tgz#0cadc9f9eca9ece224a6fd28b9e4fa3a9834e24c" - integrity sha512-CheqWbJZSM0zjcNBqELUiocwH3XArrOk6alhVuzJ2gV/WTMBQFwP0TtQssSMwjnouMHNEzY8RxErXKXBk/zJmQ== +metro-source-map@0.55.0, metro-source-map@^0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540" + integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw== dependencies: "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" invariant "^2.2.4" - metro-symbolicate "0.56.3" - ob1 "0.56.3" + metro-symbolicate "0.55.0" + ob1 "0.55.0" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz#20f9dc52fab3209903715716402692b3ac16831c" - integrity sha512-fSQtjjy4eiJDThSl9eloxMElhrs+5PQB+DKKzmTFXT8e2GDga+pa1xTBFRUACMO8BXGuWmxR7SnGDw0wo5Ngrw== +metro-symbolicate@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1" + integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg== dependencies: - invariant "^2.2.4" - metro-source-map "0.56.3" + metro-source-map "0.55.0" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" @@ -7209,65 +6975,6 @@ metro@0.54.1, metro@^0.54.1: xpipe "^1.0.5" yargs "^9.0.0" -metro@0.56.3, metro@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.3.tgz#3a38706bf6b1200421e871a4c53ddc2f359f65a9" - integrity sha512-mxHpvBGWanZ46wAEZVLinNO5IYMcFbTdMZIRhC7r+rvoSK6r9iPj95AujBfzLXMAl36RI2O3D7yp5hOYif/gEQ== - dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.1.2" - buffer-crc32 "^0.2.13" - chalk "^2.4.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" - invariant "^2.2.4" - jest-haste-map "^24.7.1" - jest-worker "^24.6.0" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-babel-register "0.56.3" - metro-babel-transformer "0.56.3" - metro-cache "0.56.3" - metro-config "0.56.3" - metro-core "0.56.3" - metro-inspector-proxy "0.56.3" - metro-minify-uglify "0.56.3" - metro-react-native-babel-preset "0.56.3" - metro-resolver "0.56.3" - metro-source-map "0.56.3" - metro-symbolicate "0.56.3" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" - source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.5" - xpipe "^1.0.5" - yargs "^9.0.0" - micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7512,11 +7219,6 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - mv@~2: version "2.1.1" resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" @@ -7793,10 +7495,10 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -ob1@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.3.tgz#5829e446587c9bf89c22ece4f3757b29f2ccfd18" - integrity sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ== +ob1@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd" + integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw== object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -8403,9 +8105,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.0.7" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" - integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177" + integrity sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw== pify@^2.0.0: version "2.3.0" @@ -8901,7 +8603,7 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.3: +react-devtools-core@^3.6.1: version "3.6.3" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== @@ -8914,7 +8616,7 @@ react-display-name@^0.2.4: resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.4.tgz#e2a670b81d79a2204335510c01246f4c92ff12cf" integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: version "16.11.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== @@ -9021,10 +8723,10 @@ react-native-firebase@^4.3.8: postinstall-build "^5.0.1" prop-types "^15.6.1" -react-native-gesture-handler@^1.4.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.0.tgz#df7dc5285c152e0656db70f55200fa632c4f45af" - integrity sha512-YUOXHsGLajK1cFReQ4Xh0H9GUTxDW9cUZEVu1q+dVqur2urSKi63KklAFB2l8Neob9nl1E/w0c5hGcBP9FMCIA== +react-native-gesture-handler@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" + integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -9175,10 +8877,13 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -react-native-svg@9.10.1: - version "9.10.1" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.10.1.tgz#055f457c427acedb01d2b758b6c1f423e8a3a607" - integrity sha512-im9LHke7pFRqQPf4qlSEti7QtcDHHeacRkI6xJspw1aka/n0LJxxBBkg7w7/Pmz5hDkzf7fRzyQi/TexB2sHnQ== +react-native-svg@9.13.2: + version "9.13.2" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.2.tgz#72a2e089f69af99c491586a95baf71009c263a51" + integrity sha512-l73+7X4mDYQBHilJ0UzFph4QmuvkngtJrfUiyLZwNLzX4T6gjyjAC2im+JNHhY7i4tU4k+I74YSCFiC7OB85Pw== + dependencies: + css-select "^2.0.2" + css-tree "^1.0.0-alpha.37" react-native-tab-view@^2.9.0: version "2.10.0" @@ -9227,15 +8932,15 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.61.2: - version "0.61.2" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.2.tgz#987b91b063557f8ebec803fdfea2044a24bdbe4d" - integrity sha512-hhd8bYbkkZYHoOndxUwbjJ6Yd9HFn5PvwqqS41uJ1xADdw44rx/svuwmJNA1RKF7jH74uR2jpBViWYGd36zGyg== +react-native@0.60.5: + version "0.60.5" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.5.tgz#3c1d9c06a0fbab9807220b6acac09488d39186ee" + integrity sha512-cZwI0XzzihACN+7an1Dy46A83FRaAe2Xyd7laCalFFAppZIYeMVphZQWrVljJk5kIZBNtYG35TY1VsghQ0Oc2Q== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" + "@react-native-community/cli" "^2.6.0" + "@react-native-community/cli-platform-android" "^2.6.0" + "@react-native-community/cli-platform-ios" "^2.4.1" abort-controller "^3.0.0" art "^0.10.0" base64-js "^1.1.2" @@ -9245,20 +8950,19 @@ react-native@0.61.2: event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermes-engine "^0.2.1" + hermesvm "^0.1.0" invariant "^2.2.4" - jsc-android "^245459.0.0" - metro-babel-register "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" - metro-source-map "^0.56.0" + jsc-android "245459.0.0" + metro-babel-register "0.54.1" + metro-react-native-babel-transformer "0.54.1" + metro-source-map "^0.55.0" nullthrows "^1.1.0" pretty-format "^24.7.0" promise "^7.1.1" prop-types "^15.7.2" - react-devtools-core "^3.6.3" - react-refresh "^0.4.0" + react-devtools-core "^3.6.1" regenerator-runtime "^0.13.2" - scheduler "0.15.0" + scheduler "0.14.0" stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" @@ -9335,15 +9039,15 @@ react-style-proptype@^3.2.2: dependencies: prop-types "^15.5.4" -react-test-renderer@16.9.0: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.9.0.tgz#7ed657a374af47af88f66f33a3ef99c9610c8ae9" - integrity sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ== +react-test-renderer@16.8.3: + version "16.8.3" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.3.tgz#230006af264cc46aeef94392e04747c21839e05e" + integrity sha512-rjJGYebduKNZH0k1bUivVrRLX04JfIQ0FKJLPK10TAb06XWhfi4gTobooF9K/DEFNW98iGac3OSxkfIJUN9Mdg== dependencies: object-assign "^4.1.1" prop-types "^15.6.2" - react-is "^16.9.0" - scheduler "^0.15.0" + react-is "^16.8.3" + scheduler "^0.13.3" react-timer-mixin@^0.13.4: version "0.13.4" @@ -9840,14 +9544,6 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -10033,10 +9729,18 @@ schedule@0.5.0: dependencies: object-assign "^4.1.1" -scheduler@0.15.0, scheduler@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e" - integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg== +scheduler@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b" + integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +scheduler@^0.13.3: + version "0.13.6" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" + integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -10786,11 +10490,6 @@ stylis@^3.5.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== -sudo-prompt@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a" - integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ== - sugarss@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" @@ -11193,11 +10892,6 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" - integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== - type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" @@ -11566,9 +11260,9 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.1.tgz#e051f3bb2de5d23995763deac108622a5e93604a" - integrity sha512-IWJreQ9HtBSyveqaC3UUEArUqCnt5zYLgHewSJ0CvxlIJfvY7yD8GDbLuLxGeHMWwSudYlODit1IfwNzvjZjEg== + version "3.4.3" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.3.tgz#e0792619ec3f8730194c93ef74474d4429606cd6" + integrity sha512-SRIy75K4/6H1vmMYVsxYwynFUNMOEzIhTy+Pm6D24JHTquwMe7rx/35X75u2sw65e46ZP67izyrJ6ahaAi8UjQ== dependencies: jsonc-parser "^2.2.0" vscode-languageserver-types "^3.15.0-next.5" From 1ed395deb961c163af895f059c25e01b25585f69 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 1 Nov 2019 11:01:56 -0400 Subject: [PATCH 455/636] fix gesture handler version to v1.4.1 exactly The later versions of the react-native-gesture-handler are breaking. Fixing the version to v1.4.1 for now until fixes to the package are made. --- ios/Rainbow.xcodeproj/project.pbxproj | 76 +++++++++++++-------------- package.json | 2 +- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index ba3472ce3fc..83707a60db0 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -28,8 +28,6 @@ 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */; }; 23320186D7F747FEB02451C6 /* SF-Pro-Text-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */; }; 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B86CB964E3AA47029988138C /* libRNKeychain.a */; }; - 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; }; - 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24979E7B20F84004007EB0DA /* FirebaseInstanceID.framework */; }; 24979E8920F84250007EB0DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24979E7720F84004007EB0DA /* GoogleService-Info.plist */; }; 26095B12C30047F89592D463 /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */; }; @@ -41,6 +39,9 @@ 396C4BA42EEC4D0985CEBB42 /* SF-Pro-Text-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */; }; 3C363E14D5DE4A028E43EA38 /* SF-Pro-Display-UltralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */; }; 3C41C1415A994234A0FF2589 /* SF-Pro-Text-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */; }; + 3CD599AF236B351D007DD55E /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CD599AE236B351D007DD55E /* InputMask.framework */; }; + 3CD599B0236B351D007DD55E /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3CD599AE236B351D007DD55E /* InputMask.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 3CD599B1236B3520007DD55E /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CD599AD236B3513007DD55E /* libRNTextInputMask.a */; }; 4013198EBD3D4D6F8052D25E /* SF-Pro-Display-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */; }; 41804DE52CE94296995264E0 /* SF-Pro-Text-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */; }; 424410A1E84845328C5A0CAB /* Graphik-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */; }; @@ -89,7 +90,6 @@ ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A014AE1645874354A732EB35 /* libToolTipMenu.a */; }; F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D1A86E696CA24D4F9D3F7F0F /* libz.tbd */; }; F4E8A17A670147F4A5EC177E /* libRNGestureHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A7E5E09E14B4EA4B52CC6EE /* libRNGestureHandler.a */; }; - F643BEEE1F9445C7932B2A75 /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */; }; F9EB9219ED9A4C72826A5908 /* Graphik-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */; }; F9EF1D44351840B8A380BD3E /* SF-Pro-Display-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */; }; FBDF4EF177284CF4826D7BF9 /* SF-Pro-Display-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D7BFD847B72D414D9BE734A0 /* SF-Pro-Display-HeavyItalic.otf */; }; @@ -446,6 +446,13 @@ remoteGlobalIDString = 47413E2820DBB5D000CCDA85; remoteInfo = "SRSRadialGradien-tvOS"; }; + 3CD599AC236B3513007DD55E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RNTextInputMask; + }; 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -551,13 +558,6 @@ remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteInfo = RCTText; }; - AA24D00F235EB5550082BA9B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNTextInputMask; - }; ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; @@ -574,7 +574,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */, + 3CD599B0236B351D007DD55E /* InputMask.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -613,7 +613,6 @@ 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ToolTipMenu.xcodeproj; path = "../node_modules/react-native-tooltip/ToolTipMenu.xcodeproj"; sourceTree = ""; }; 22E39434CDDE4C54848FBFD5 /* libCodePush.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libCodePush.a; sourceTree = ""; }; 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Text-Heavy.otf"; sourceTree = ""; }; - 24122D53232F2B3200BA0B17 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24979E3620F84003007EB0DA /* Protobuf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Protobuf.framework; path = Frameworks/Protobuf.framework; sourceTree = ""; }; 24979E7420F84004007EB0DA /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 24979E7520F84004007EB0DA /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/FirebaseCore.framework; sourceTree = ""; }; @@ -647,6 +646,8 @@ 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Rainbow.entitlements; path = Rainbow/Rainbow.entitlements; sourceTree = ""; }; 3C39C266218BBE66004C763F /* FastImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FastImage.xcodeproj; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = ""; }; 3CC4B790228B298400D827EB /* libSDWebImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSDWebImage.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; + 3CD599AE236B351D007DD55E /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D5210FEA8F00672599 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D7210FEACE00672599 /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ThinItalic.otf"; path = "../src/assets/fonts/Graphik-ThinItalic.otf"; sourceTree = ""; }; @@ -697,7 +698,6 @@ AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Semibold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Semibold.otf"; sourceTree = ""; }; ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFIRMessaging.xcodeproj; path = "../node_modules/react-native-fcm/ios/RNFIRMessaging.xcodeproj"; sourceTree = ""; }; - B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; B0C692B061D7430D8194DC98 /* ToolTipMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ToolTipMenuTests.xctest; sourceTree = ""; }; B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNTextInputMask.a; sourceTree = ""; }; B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Semibold.otf"; path = "../src/assets/fonts/SFMono-Semibold.otf"; sourceTree = ""; }; @@ -753,9 +753,11 @@ 4433A04AF3E942A2894B3933 /* libRNOS.a in Frameworks */, 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */, 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */, + 3CD599AF236B351D007DD55E /* InputMask.framework in Frameworks */, 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */, 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */, 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */, + 3CD599B1236B3520007DD55E /* libRNTextInputMask.a in Frameworks */, 91959ACCE81B4C128AAC8154 /* libRNSVG.a in Frameworks */, 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */, ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */, @@ -768,8 +770,6 @@ 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */, - 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */, - F643BEEE1F9445C7932B2A75 /* libRNTextInputMask.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1088,6 +1088,7 @@ children = ( 3CC4B790228B298400D827EB /* libSDWebImage.a */, 24A867FF226181F9005DCF78 /* libFirebaseInstanceID.a */, + 3CD599AE236B351D007DD55E /* InputMask.framework */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, 3CE850D7210FEACE00672599 /* libnanopb.a */, @@ -1120,6 +1121,14 @@ name = Products; sourceTree = ""; }; + 3CD599A8236B3513007DD55E /* Products */ = { + isa = PBXGroup; + children = ( + 3CD599AD236B3513007DD55E /* libRNTextInputMask.a */, + ); + name = Products; + sourceTree = ""; + }; 5E91572E1DD0AC6500FF2AA8 /* Products */ = { isa = PBXGroup; children = ( @@ -1141,6 +1150,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */, 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */, 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */, 3C39C266218BBE66004C763F /* FastImage.xcodeproj */, @@ -1173,7 +1183,6 @@ 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */, 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */, 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */, - B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1190,7 +1199,6 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( - 24122D53232F2B3200BA0B17 /* InputMask.framework */, 13B07FAE1A68108700A75B9A /* Rainbow */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* RainbowTests */, @@ -1214,14 +1222,6 @@ name = Products; sourceTree = ""; }; - AA24D00C235EB5550082BA9B /* Products */ = { - isa = PBXGroup; - children = ( - AA24D010235EB5550082BA9B /* libRNTextInputMask.a */, - ); - name = Products; - sourceTree = ""; - }; ADBDB9201DFEBF0600ED6528 /* Products */ = { isa = PBXGroup; children = ( @@ -1492,8 +1492,8 @@ ProjectRef = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; }, { - ProductGroup = AA24D00C235EB5550082BA9B /* Products */; - ProjectRef = B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */; + ProductGroup = 3CD599A8236B3513007DD55E /* Products */; + ProjectRef = 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */; }, { ProductGroup = 24979D5020F83E3E007EB0DA /* Products */; @@ -1872,6 +1872,13 @@ remoteRef = 3CD4E8CC216989E8000FA5BD /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 3CD599AD236B3513007DD55E /* libRNTextInputMask.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNTextInputMask.a; + remoteRef = 3CD599AC236B3513007DD55E /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1977,13 +1984,6 @@ remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - AA24D010235EB5550082BA9B /* libRNTextInputMask.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNTextInputMask.a; - remoteRef = AA24D00F235EB5550082BA9B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -2269,7 +2269,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; @@ -2330,7 +2330,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L74NQAQB8H; @@ -2427,7 +2427,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L74NQAQB8H; @@ -2571,7 +2571,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = ""; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L74NQAQB8H; diff --git a/package.json b/package.json index 602d54dea18..4aa2a8f825a 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-firebase": "^4.3.8", - "react-native-gesture-handler": "^1.4.1", + "react-native-gesture-handler": "1.4.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", "react-native-ios11-devicecheck": "^0.0.3", From fbb1ad24324689761db61d22b697f98e67b4ee8e Mon Sep 17 00:00:00 2001 From: Jordan Marsaw <37964165+blokboy@users.noreply.github.com> Date: Mon, 4 Nov 2019 17:39:03 -0500 Subject: [PATCH 456/636] Refactor search.js to remove loops --- src/utils/search.js | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/utils/search.js b/src/utils/search.js index 7fa3f8e841c..6980cff3650 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -1,26 +1,9 @@ -import { startsWith, toLower } from 'lodash'; +import matchSorter from 'match-sorter'; export const filterList = ( list, - searchPhrase, - searchParameter = false, - separator = ' ' + searchQuery, + searchListByKey ) => { - const filteredList = []; - if (list && searchPhrase.length > 0) { - for (let i = 0; i < list.length; i++) { - const searchedItem = searchParameter ? list[i][searchParameter] : list[i]; - const splitedWordList = (searchedItem || '').split(separator); - splitedWordList.push(searchedItem); - for (let j = 0; j < splitedWordList.length; j++) { - if (startsWith(toLower(splitedWordList[j]), toLower(searchPhrase))) { - filteredList.push(list[i]); - break; - } - } - } - } else { - return list; - } - return filteredList; + return matchSorter(list, searchQuery, { keys: searchListByKey ? [searchListByKey] : null }) }; From bc6bdee146dfcdd1ebd62851c6c34ccf8397b957 Mon Sep 17 00:00:00 2001 From: Jordan Marsaw <37964165+blokboy@users.noreply.github.com> Date: Mon, 4 Nov 2019 17:42:52 -0500 Subject: [PATCH 457/636] Fix ES-Lint related issues --- src/utils/search.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/utils/search.js b/src/utils/search.js index 6980cff3650..b2f124fd13c 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -1,9 +1,7 @@ import matchSorter from 'match-sorter'; -export const filterList = ( - list, - searchQuery, - searchListByKey -) => { - return matchSorter(list, searchQuery, { keys: searchListByKey ? [searchListByKey] : null }) +export const filterList = (list, searchQuery, searchListByKey) => { + return matchSorter(list, searchQuery, { + keys: searchListByKey ? [searchListByKey] : null, + }); }; From e8cc16646bb0bf466b6f2006415203984a5ed666 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 4 Nov 2019 17:57:26 -0500 Subject: [PATCH 458/636] add match-sorter to package.json --- package.json | 1 + yarn.lock | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/package.json b/package.json index 4aa2a8f825a..76588845e78 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "immer": "^3.1.3", "inherits": "^2.0.3", "lodash": "^4.17.15", + "match-sorter": "^4.0.2", "nanoid": "^2.0.3", "parse-ms": "^2.1.0", "patch-package": "^6.2.0", diff --git a/yarn.lock b/yarn.lock index af709ef2f88..f180dcfcfa1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6602,6 +6602,14 @@ markdown-table@^1.1.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== +match-sorter@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-4.0.2.tgz#1b451e8bc7112e5a41ebe3a977b7e19f167c3215" + integrity sha512-5EcCLEmPgfvq2hg1DAgAG7zqqS9bnZmRXzLR3md0xRi3Q1oGnnze6HuY+4bDRtm+X2lTsVZL8oG9FOkALFT4vw== + dependencies: + "@babel/runtime" "^7.5.5" + remove-accents "0.4.2" + mathml-tag-names@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc" @@ -9407,6 +9415,11 @@ remark@^10.0.1: remark-stringify "^6.0.0" unified "^7.0.0" +remove-accents@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" + integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" From 059433bef0b9a3f07bab39f60464ee7841386a99 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 24 Oct 2019 01:50:45 -0400 Subject: [PATCH 459/636] Fix shimmer effect in CurrencySelectModal --- src/components/asset-list/EmptyAssetList.js | 23 ++--- .../exchange/CurrencySelectModalHeader.js | 58 +++++++++++++ .../exchange/CurrencySelectionList.js | 84 +++++++++++++++++++ src/components/exchange/ExchangeSearch.js | 2 + src/components/exchange/index.js | 4 + src/screens/CurrencySelectModal.js | 84 +++++-------------- 6 files changed, 179 insertions(+), 76 deletions(-) create mode 100644 src/components/exchange/CurrencySelectModalHeader.js create mode 100644 src/components/exchange/CurrencySelectionList.js diff --git a/src/components/asset-list/EmptyAssetList.js b/src/components/asset-list/EmptyAssetList.js index 87356881e30..dc01efa7f54 100644 --- a/src/components/asset-list/EmptyAssetList.js +++ b/src/components/asset-list/EmptyAssetList.js @@ -1,4 +1,5 @@ import lang from 'i18n-js'; +import stylePropType from 'react-style-proptype'; import { times } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; @@ -11,26 +12,25 @@ import AssetListItemSkeleton from './AssetListItemSkeleton'; const InterstitialOffset = AssetListHeader.height + FabWrapper.bottomPosition; -const renderSkeleton = (index, isWalletEthZero) => ( - -); - const EmptyAssetList = ({ hideHeader, isWalletEthZero, skeletonCount, + style, ...props }) => ( - + {hideHeader && } - {times(skeletonCount, index => renderSkeleton(index, isWalletEthZero))} + {times(skeletonCount, index => ( + + ))} {isWalletEthZero && ( @@ -43,6 +43,7 @@ EmptyAssetList.propTypes = { hideHeader: PropTypes.bool, isWalletEthZero: PropTypes.bool, skeletonCount: PropTypes.number, + style: stylePropType, }; EmptyAssetList.defaultProps = { diff --git a/src/components/exchange/CurrencySelectModalHeader.js b/src/components/exchange/CurrencySelectModalHeader.js new file mode 100644 index 00000000000..be6ba663fdd --- /dev/null +++ b/src/components/exchange/CurrencySelectModalHeader.js @@ -0,0 +1,58 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { hoistStatics, onlyUpdateForKeys, withProps } from 'recompact'; +import styled from 'styled-components/primitives'; +import { borders, colors } from '../../styles'; +import { BackButton } from '../header'; +import { Centered } from '../layout'; +import { TruncatedText } from '../text'; + +const BackButtonWrapper = styled(Centered)` + bottom: 0; + left: 0; + position: absolute; + top: 0; +`; + +const HeaderHeight = 60; +const HeaderContainer = styled(Centered).attrs({ flex: 0 })` + ${borders.buildRadius('top', 12)}; + background-color: ${colors.white}; + height: ${HeaderHeight}; + width: 100%; +`; + +const HeaderTitle = withProps({ + height: 21, + letterSpacing: 'tighter', + lineHeight: 'loose', + size: 'large', + weight: 'bold', +})(TruncatedText); + +const CurrencySelectModalHeader = ({ onPressBack, title }) => ( + + + + + {title} + +); + +CurrencySelectModalHeader.propTypes = { + onPressBack: PropTypes.func, + title: PropTypes.string, +}; + +CurrencySelectModalHeader.height = HeaderHeight; + +export default hoistStatics(onlyUpdateForKeys(['title']))( + CurrencySelectModalHeader +); diff --git a/src/components/exchange/CurrencySelectionList.js b/src/components/exchange/CurrencySelectionList.js new file mode 100644 index 00000000000..3b9fa6b2d67 --- /dev/null +++ b/src/components/exchange/CurrencySelectionList.js @@ -0,0 +1,84 @@ +import PropTypes from 'prop-types'; +import React, { useEffect, useState } from 'react'; +import { View } from 'react-native'; +import { withNeverRerender } from '../../hoc'; +import { exchangeModalBorderRadius } from '../../screens/ExchangeModal'; +import { colors, position } from '../../styles'; +import { EmptyAssetList } from '../asset-list'; +import { Centered, ColumnWithMargins } from '../layout'; +import { Emoji, Text } from '../text'; +import CurrencySelectModalHeader from './CurrencySelectModalHeader'; +import ExchangeAssetList from './ExchangeAssetList'; +import ExchangeSearch from './ExchangeSearch'; + +const NoResultMessageOffset = + CurrencySelectModalHeader.height + ExchangeSearch.height; + +const NoResultMessage = withNeverRerender(() => ( + + + + + + Nothing here! + + +)); + +const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { + const showNoResults = listItems.length === 0; + + const [showSkeleton, setShowSkeleton] = useState(true); + useEffect(() => { + if (showSkeleton && !showList) { + setShowSkeleton(true); + } + }, [showList, showSkeleton]); + + return ( + + {showList && ( + + {showNoResults ? ( + + ) : ( + setShowSkeleton(false)} + key={`ExchangeAssetListCurrencySelectionModal-${type}`} + renderItem={renderItem} + scrollIndicatorInsets={{ + bottom: exchangeModalBorderRadius, + }} + /> + )} + + )} + {(showSkeleton || !showList) && ( + + )} + + ); +}; + +CurrencySelectionList.propTypes = { + listItems: PropTypes.array, + renderItem: PropTypes.func, + showList: PropTypes.bool, + type: PropTypes.string, +}; + +export default React.memo(CurrencySelectionList); diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 9f1d0f83d50..9ed309cb946 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -27,6 +27,8 @@ export default class ExchangeSearch extends PureComponent { searchQuery: PropTypes.string, }; + static height = ExchangeSearchHeight; + clearInput = () => { if (this.inputRef && this.inputRef.current) { this.inputRef.current.clear(); diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js index 4a6d2a08909..58edba5318d 100644 --- a/src/components/exchange/index.js +++ b/src/components/exchange/index.js @@ -1,4 +1,8 @@ export { default as ConfirmExchangeButton } from './ConfirmExchangeButton'; +export { default as CurrencySelectionList } from './CurrencySelectionList'; +export { + default as CurrencySelectModalHeader, +} from './CurrencySelectModalHeader'; export { default as ExchangeAssetList } from './ExchangeAssetList'; export { default as ExchangeInput } from './ExchangeInput'; export { default as ExchangeInputField } from './ExchangeInputField'; diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index aebcebb40b2..b99fb68038c 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -3,51 +3,25 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; -import { compose, mapProps, withProps } from 'recompact'; -import styled from 'styled-components/primitives'; +import { compose, mapProps } from 'recompact'; import { withUniswapAssets } from '../hoc'; -import { borders, colors, position } from '../styles'; +import { position } from '../styles'; import { isNewValueForPath } from '../utils'; import { filterList } from '../utils/search'; import { interpolate } from '../components/animations'; -import { EmptyAssetList } from '../components/asset-list'; import { ExchangeCoinRow } from '../components/coin-row'; -import { ExchangeAssetList, ExchangeSearch } from '../components/exchange'; -import GestureBlocker from '../components/GestureBlocker'; -import { BackButton } from '../components/header'; import { - Centered, - Column, - FlexItem, - KeyboardFixedOpenLayout, -} from '../components/layout'; + CurrencySelectionList, + CurrencySelectModalHeader, + ExchangeSearch, +} from '../components/exchange'; +import GestureBlocker from '../components/GestureBlocker'; +import { Column, KeyboardFixedOpenLayout } from '../components/layout'; import { Modal } from '../components/modal'; -import { TruncatedText } from '../components/text'; import { exchangeModalBorderRadius } from './ExchangeModal'; const EMPTY_ARRAY = []; -const BackButtonWrapper = styled(Centered)` - left: 0; - margin-left: 15; - position: absolute; -`; - -const HeaderContainer = styled(Centered).attrs({ flex: 0 })` - ${borders.buildRadius('top', 12)}; - background-color: ${colors.white}; - height: 60; - width: 100%; -`; - -const HeaderTitle = withProps({ - height: 21, - letterSpacing: 'tighter', - lineHeight: 'loose', - size: 'large', - weight: 'bold', -})(TruncatedText); - const appendAssetWithSearchableKey = asset => ({ ...asset, uniqueId: `${asset.name} ${asset.symbol}`, @@ -176,8 +150,6 @@ class CurrencySelectModal extends Component { const listItems = filterList(assets, searchQuery, 'uniqueId'); - const isLoading = !isFocused || listItems.length === 0; - return ( - - - - - {headerTitle} - + - - {isFocused ? ( - - ) : null} - - + From 87c6547ab31d103fe36ff3c10eab83f83335db54 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 4 Nov 2019 15:14:59 -0500 Subject: [PATCH 460/636] Improve loading shimmer effect in Swap flow Fixes RAI-22 https://linear.app/issue/RAI-22 --- .../exchange/CurrencySelectionList.js | 41 ++++++++++++++----- src/components/exchange/ExchangeAssetList.js | 24 +++++++---- src/components/exchange/ExchangeSearch.js | 2 +- src/components/inputs/ClearInputDecorator.js | 14 +++---- src/screens/CurrencySelectModal.js | 4 +- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/src/components/exchange/CurrencySelectionList.js b/src/components/exchange/CurrencySelectionList.js index 3b9fa6b2d67..cfa9ff43dc9 100644 --- a/src/components/exchange/CurrencySelectionList.js +++ b/src/components/exchange/CurrencySelectionList.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; -import React, { useEffect, useState } from 'react'; -import { View } from 'react-native'; +import React, { useEffect, useRef, useState } from 'react'; +import { Transition, Transitioning } from 'react-native-reanimated'; import { withNeverRerender } from '../../hoc'; import { exchangeModalBorderRadius } from '../../screens/ExchangeModal'; import { colors, position } from '../../styles'; @@ -11,14 +11,11 @@ import CurrencySelectModalHeader from './CurrencySelectModalHeader'; import ExchangeAssetList from './ExchangeAssetList'; import ExchangeSearch from './ExchangeSearch'; -const NoResultMessageOffset = - CurrencySelectModalHeader.height + ExchangeSearch.height; - const NoResultMessage = withNeverRerender(() => ( @@ -33,18 +30,40 @@ const NoResultMessage = withNeverRerender(() => ( )); +const skeletonTransition = ( + + + + + +); + const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { + const skeletonTransitionRef = useRef(); + const [showSkeleton, setShowSkeleton] = useState(true); + const showNoResults = listItems.length === 0; - const [showSkeleton, setShowSkeleton] = useState(true); + const onListMount = () => { + if (showSkeleton && showList) { + skeletonTransitionRef.current.animateNextTransition(); + setShowSkeleton(false); + } + }; + useEffect(() => { - if (showSkeleton && !showList) { + if (!showSkeleton && !showList) { setShowSkeleton(true); } }, [showList, showSkeleton]); return ( - + {showList && ( {showNoResults ? ( @@ -52,7 +71,7 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { ) : ( setShowSkeleton(false)} + onMount={onListMount} key={`ExchangeAssetListCurrencySelectionModal-${type}`} renderItem={renderItem} scrollIndicatorInsets={{ @@ -70,7 +89,7 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { pointerEvents="none" /> )} - + ); }; diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index f483361a52e..309de5a7839 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -45,6 +45,7 @@ const setLayoutForType = (type, dim) => { export default class ExchangeAssetList extends PureComponent { static propTypes = { items: PropTypes.arrayOf(PropTypes.object), + onMount: PropTypes.func, renderItem: PropTypes.func, }; @@ -77,25 +78,34 @@ export default class ExchangeAssetList extends PureComponent { getStableId = index => get(this.state, `dataProvider._data[${index}].uniqueId`); - updateList = () => { - this.setState(prevState => ({ - dataProvider: prevState.dataProvider.cloneWithRows(this.props.items), - })); + handleMount = () => { + if (this.props.onMount) { + this.props.onMount(); + } }; renderRow = (type, data) => this.props.renderItem(data); rlvRef = React.createRef(); + updateList = () => { + this.setState(prevState => ({ + dataProvider: prevState.dataProvider.cloneWithRows(this.props.items), + })); + }; + render = () => ( - + ( - + @@ -53,20 +53,20 @@ const ClearInputDecorator = ({ inputHeight, isVisible, onPress }) => { ref.current.animateNextTransition(); } + const paddingLeft = inputHeight / 2; + const paddingRight = inputHeight / 4; + return ( - + {isVisible && ( - + { + handleChangeSearchQuery = searchQuery => { this.setState({ searchQuery }); }; @@ -180,7 +180,7 @@ class CurrencySelectModal extends Component { /> From df4a0eb567258114100b858e43c67f7140f16470 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 4 Nov 2019 15:58:10 -0500 Subject: [PATCH 461/636] Clear search state between swap modals Fixes RAI-25 https://linear.app/issue/RAI-25 --- src/screens/CurrencySelectModal.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 92caba74ef9..a34342125d4 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -103,6 +103,8 @@ class CurrencySelectModal extends Component { navigation.navigate('MainExchangeScreen'); }; + handleDidBlur = () => this.handleChangeSearchQuery(''); + handleWillBlur = () => this.dangerouslySetIsGestureBlocked(false); handleWillFocus = () => { @@ -170,6 +172,7 @@ class CurrencySelectModal extends Component { > From ed4c27fedeab0d3f29e220af44b73a6d22ade2b3 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 5 Nov 2019 14:40:38 -0500 Subject: [PATCH 462/636] Revert "Merge pull request #206 from rainbow-me/jin-revert-61-bump" This reverts commit c043ea4e6409b55c81dbbe04b87de67cf80f9a12, reversing changes made to 0b4b626e13f1c42b18e363ca12111b81815c1510. --- .flowconfig | 78 ++-- .gitignore | 1 + .prettierrc.js | 6 + ios/Podfile | 15 +- ios/Podfile.lock | 355 +++++++++++++----- ios/Rainbow.xcodeproj/project.pbxproj | 76 ++-- package.json | 19 +- yarn.lock | 522 ++++++++++++++++++++------ 8 files changed, 779 insertions(+), 293 deletions(-) create mode 100644 .prettierrc.js diff --git a/.flowconfig b/.flowconfig index 7ad43751ac2..9edb1be387b 100644 --- a/.flowconfig +++ b/.flowconfig @@ -5,63 +5,71 @@ ; Ignore "BUCK" generated dirs /\.buckd/ -; Ignore unexpected extra "@providesModule" -.*/node_modules/.*/node_modules/fbjs/.* +; Ignore polyfills +node_modules/react-native/Libraries/polyfills/.* -; Ignore duplicate module providers -; For RN Apps installed via npm, "Libraries" folder is inside -; "node_modules/react-native" but in the source repo it is in the root -.*/Libraries/react-native/React.js +; These should not be required directly +; require from fbjs/lib instead: require('fbjs/lib/warning') +node_modules/warning/.* -; Ignore polyfills -.*/Libraries/polyfills/.* +; Flow doesn't support platforms +.*/Libraries/Utilities/LoadingView.js -; Ignore metro -.*/node_modules/metro/.* +[untyped] +.*/node_modules/@react-native-community/cli/.*/.* [include] [libs] node_modules/react-native/Libraries/react-native/react-native-interface.js node_modules/react-native/flow/ -node_modules/react-native/flow-github/ [options] emoji=true -module.system=haste -module.system.haste.use_name_reducers=true -# get basename -module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' -# strip .js or .js.flow suffix -module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' -# strip .ios suffix -module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' -module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' -module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' -module.system.haste.paths.blacklist=.*/__tests__/.* -module.system.haste.paths.blacklist=.*/__mocks__/.* -module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* -module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* - -munge_underscores=true - -module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable module.file_ext=.js -module.file_ext=.jsx module.file_ext=.json -module.file_ext=.native.js +module.file_ext=.ios.js + +munge_underscores=true + +module.name_mapper='^react-native$' -> '/node_modules/react-native/Libraries/react-native/react-native-implementation' +module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' +module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' suppress_type=$FlowIssue suppress_type=$FlowFixMe suppress_type=$FlowFixMeProps suppress_type=$FlowFixMeState -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ -suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError +[lints] +sketchy-null-number=warn +sketchy-null-mixed=warn +sketchy-number=warn +untyped-type-import=warn +nonstrict-import=warn +deprecated-type=warn +unsafe-getters-setters=warn +inexact-spread=warn +unnecessary-invariant=warn +signature-verification-failure=warn +deprecated-utility=error + +[strict] +deprecated-type +nonstrict-import +sketchy-null +unclear-type +unsafe-getters-setters +untyped-import +untyped-type-import + [version] -^0.92.0 +^0.105.0 \ No newline at end of file diff --git a/.gitignore b/.gitignore index f13d7e7ba74..8dc0a7d6a8a 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ yarn-error.log buck-out/ \.buckd/ *.keystore +!debug.keystore # fastlane # diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000000..e516059d776 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + bracketSpacing: true, + jsxBracketSameLine: false, + singleQuote: true, + trailingComma: 'all', +}; \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index 8d155b79d1a..4b33fb4594c 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -13,9 +13,14 @@ target 'Rainbow' do pod 'Firebase/Messaging', '~> 5.3.0' # Core React + pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" + pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" + pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" + pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" pod 'React', :path => '../node_modules/react-native/' - pod 'React-Core', :path => '../node_modules/react-native/React' - pod 'React-DevSupport', :path => '../node_modules/react-native/React' + pod 'React-Core', :path => '../node_modules/react-native/' + pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' + pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' @@ -25,7 +30,7 @@ target 'Rainbow' do pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' - pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' + pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' @@ -33,7 +38,9 @@ target 'Rainbow' do pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' # React Third Party - required - pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' + pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" + pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" + pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e8580d2108c..4d8463b2e8b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -7,6 +7,14 @@ PODS: - Fabric (~> 1.7.13) - DoubleConversion (1.1.6) - Fabric (1.7.13) + - FBLazyVector (0.61.2) + - FBReactNativeSpec (0.61.2): + - Folly (= 2018.10.22.00) + - RCTRequired (= 0.61.2) + - RCTTypeSafety (= 0.61.2) + - React-Core (= 0.61.2) + - React-jsi (= 0.61.2) + - ReactCommon/turbomodule/core (= 0.61.2) - Firebase/Core (5.3.0): - Firebase/CoreOnly - FirebaseAnalytics (= 5.0.1) @@ -54,57 +62,175 @@ PODS: - libwebp/mux (1.0.3): - libwebp/demux - libwebp/webp (1.0.3) - - nanopb (0.3.9011): - - nanopb/decode (= 0.3.9011) - - nanopb/encode (= 0.3.9011) - - nanopb/decode (0.3.9011) - - nanopb/encode (0.3.9011) + - nanopb (0.3.904): + - nanopb/decode (= 0.3.904) + - nanopb/encode (= 0.3.904) + - nanopb/decode (0.3.904) + - nanopb/encode (0.3.904) - Protobuf (3.10.0) - - React (0.60.5): - - React-Core (= 0.60.5) - - React-DevSupport (= 0.60.5) - - React-RCTActionSheet (= 0.60.5) - - React-RCTAnimation (= 0.60.5) - - React-RCTBlob (= 0.60.5) - - React-RCTImage (= 0.60.5) - - React-RCTLinking (= 0.60.5) - - React-RCTNetwork (= 0.60.5) - - React-RCTSettings (= 0.60.5) - - React-RCTText (= 0.60.5) - - React-RCTVibration (= 0.60.5) - - React-RCTWebSocket (= 0.60.5) - - React-Core (0.60.5): + - RCTRequired (0.61.2) + - RCTTypeSafety (0.61.2): + - FBLazyVector (= 0.61.2) + - Folly (= 2018.10.22.00) + - RCTRequired (= 0.61.2) + - React-Core (= 0.61.2) + - React (0.61.2): + - React-Core (= 0.61.2) + - React-Core/DevSupport (= 0.61.2) + - React-Core/RCTWebSocket (= 0.61.2) + - React-RCTActionSheet (= 0.61.2) + - React-RCTAnimation (= 0.61.2) + - React-RCTBlob (= 0.61.2) + - React-RCTImage (= 0.61.2) + - React-RCTLinking (= 0.61.2) + - React-RCTNetwork (= 0.61.2) + - React-RCTSettings (= 0.61.2) + - React-RCTText (= 0.61.2) + - React-RCTVibration (= 0.61.2) + - React-Core (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.61.2) + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/CoreModulesHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/Default (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/DevSupport (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.61.2) + - React-Core/RCTWebSocket (= 0.61.2) + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - React-jsinspector (= 0.61.2) + - Yoga + - React-Core/RCTActionSheetHeaders (0.61.2): - Folly (= 2018.10.22.00) - - React-cxxreact (= 0.60.5) - - React-jsiexecutor (= 0.60.5) - - yoga (= 0.60.5.React) - - React-cxxreact (0.60.5): + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTAnimationHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTBlobHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTImageHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTLinkingHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTNetworkHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTSettingsHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTTextHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTVibrationHeaders (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-Core/RCTWebSocket (0.61.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.61.2) + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsiexecutor (= 0.61.2) + - Yoga + - React-CoreModules (0.61.2): + - FBReactNativeSpec (= 0.61.2) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.61.2) + - React-Core/CoreModulesHeaders (= 0.61.2) + - React-RCTImage (= 0.61.2) + - ReactCommon/turbomodule/core (= 0.61.2) + - React-cxxreact (0.61.2): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsinspector (= 0.60.5) - - React-DevSupport (0.60.5): - - React-Core (= 0.60.5) - - React-RCTWebSocket (= 0.60.5) - - React-jsi (0.60.5): + - React-jsinspector (= 0.61.2) + - React-jsi (0.61.2): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsi/Default (= 0.60.5) - - React-jsi/Default (0.60.5): + - React-jsi/Default (= 0.61.2) + - React-jsi/Default (0.61.2): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsiexecutor (0.60.5): + - React-jsiexecutor (0.61.2): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.60.5) - - React-jsi (= 0.60.5) - - React-jsinspector (0.60.5) + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - React-jsinspector (0.61.2) - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -121,29 +247,41 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React-RCTActionSheet (0.60.5): - - React-Core (= 0.60.5) - - React-RCTAnimation (0.60.5): - - React-Core (= 0.60.5) - - React-RCTBlob (0.60.5): - - React-Core (= 0.60.5) - - React-RCTNetwork (= 0.60.5) - - React-RCTWebSocket (= 0.60.5) - - React-RCTImage (0.60.5): - - React-Core (= 0.60.5) - - React-RCTNetwork (= 0.60.5) - - React-RCTLinking (0.60.5): - - React-Core (= 0.60.5) - - React-RCTNetwork (0.60.5): - - React-Core (= 0.60.5) - - React-RCTSettings (0.60.5): - - React-Core (= 0.60.5) - - React-RCTText (0.60.5): - - React-Core (= 0.60.5) - - React-RCTVibration (0.60.5): - - React-Core (= 0.60.5) - - React-RCTWebSocket (0.60.5): - - React-Core (= 0.60.5) + - React-RCTActionSheet (0.61.2): + - React-Core/RCTActionSheetHeaders (= 0.61.2) + - React-RCTAnimation (0.61.2): + - React-Core/RCTAnimationHeaders (= 0.61.2) + - React-RCTBlob (0.61.2): + - React-Core/RCTBlobHeaders (= 0.61.2) + - React-Core/RCTWebSocket (= 0.61.2) + - React-jsi (= 0.61.2) + - React-RCTNetwork (= 0.61.2) + - React-RCTImage (0.61.2): + - React-Core/RCTImageHeaders (= 0.61.2) + - React-RCTNetwork (= 0.61.2) + - React-RCTLinking (0.61.2): + - React-Core/RCTLinkingHeaders (= 0.61.2) + - React-RCTNetwork (0.61.2): + - React-Core/RCTNetworkHeaders (= 0.61.2) + - React-RCTSettings (0.61.2): + - React-Core/RCTSettingsHeaders (= 0.61.2) + - React-RCTText (0.61.2): + - React-Core/RCTTextHeaders (= 0.61.2) + - React-RCTVibration (0.61.2): + - React-Core/RCTVibrationHeaders (= 0.61.2) + - ReactCommon/jscallinvoker (0.61.2): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.61.2) + - ReactCommon/turbomodule/core (0.61.2): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-Core (= 0.61.2) + - React-cxxreact (= 0.61.2) + - React-jsi (= 0.61.2) + - ReactCommon/jscallinvoker (= 0.61.2) - RNAnalytics (1.1.0): - Analytics - React @@ -167,29 +305,35 @@ PODS: - React - RNStoreReview (0.1.5): - React - - SDWebImage (5.2.5): - - SDWebImage/Core (= 5.2.5) - - SDWebImage/Core (5.2.5) + - SDWebImage (5.2.3): + - SDWebImage/Core (= 5.2.3) + - SDWebImage/Core (5.2.3) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) - - yoga (0.60.5.React) + - Yoga (1.14.0) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) - Crashlytics (~> 3.10.7) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - Fabric (~> 1.7.11) + - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) + - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) - Firebase/Core (~> 5.3.0) - Firebase/Messaging (~> 5.3.0) - FLAnimatedImage - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - libwebp + - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) + - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - React (from `../node_modules/react-native/`) - - React-Core (from `../node_modules/react-native/React`) + - React-Core (from `../node_modules/react-native/`) + - React-Core/DevSupport (from `../node_modules/react-native/`) + - React-Core/RCTWebSocket (from `../node_modules/react-native/`) + - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) - - React-DevSupport (from `../node_modules/react-native/React`) - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) @@ -207,7 +351,8 @@ DEPENDENCIES: - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - - React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`) + - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) + - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -218,10 +363,10 @@ DEPENDENCIES: - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNStoreReview (from `../node_modules/react-native-store-review/ios`) - - yoga (from `../node_modules/react-native/ReactCommon/yoga`) + - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - https://github.com/cocoapods/specs.git: + trunk: - Analytics - boost-for-react-native - Crashlytics @@ -244,18 +389,26 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-linear-gradient" DoubleConversion: :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" + FBLazyVector: + :path: "../node_modules/react-native/Libraries/FBLazyVector" + FBReactNativeSpec: + :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" Folly: :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + RCTRequired: + :path: "../node_modules/react-native/Libraries/RCTRequired" + RCTTypeSafety: + :path: "../node_modules/react-native/Libraries/TypeSafety" React: :path: "../node_modules/react-native/" React-Core: - :path: "../node_modules/react-native/React" + :path: "../node_modules/react-native/" + React-CoreModules: + :path: "../node_modules/react-native/React/CoreModules" React-cxxreact: :path: "../node_modules/react-native/ReactCommon/cxxreact" - React-DevSupport: - :path: "../node_modules/react-native/React" React-jsi: :path: "../node_modules/react-native/ReactCommon/jsi" React-jsiexecutor: @@ -290,8 +443,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Text" React-RCTVibration: :path: "../node_modules/react-native/Libraries/Vibration" - React-RCTWebSocket: - :path: "../node_modules/react-native/Libraries/WebSocket" + ReactCommon: + :path: "../node_modules/react-native/ReactCommon" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -312,7 +465,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-screens" RNStoreReview: :path: "../node_modules/react-native-store-review/ios" - yoga: + Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: @@ -322,40 +475,44 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - Firebase: 76ec2a7cde90fb4037793f83aeeca48451543487 - FirebaseAnalytics: b8bce8d5c40173328b8a4300da18c5c7e0a1908d - FirebaseCore: 31d258ec80ea97e1e8e40ce00a7ba7297afb45c2 - FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9 - FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51 + FBLazyVector: 68b6a76960fbd8ecd9fb7ce0aadd3329c3340a99 + FBReactNativeSpec: 5a764c60abdc3336a213e5310c40b74741f32839 + Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa + FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 + FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 + FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 + FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleToolboxForMac: 800648f8b3127618c1b59c7f97684427630c5ea3 libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e - nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd + nanopb: 06f6030d554e6473f5e172460173fcf80f5548f4 Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - React: 53c53c4d99097af47cf60594b8706b4e3321e722 - React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64 - React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395 - React-DevSupport: 197fb409737cff2c4f9986e77c220d7452cb9f9f - React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2 - React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30 - React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4 + RCTRequired: c639d59ed389cfb1f1203f65c2ea946d8ec586e2 + RCTTypeSafety: dc23fb655d6c77667c78e327bf661bc11e3b8aec + React: 7e586e5d7bec12b91c1a096826b0fc9ab1da7865 + React-Core: 8ddb9770b4a30a6ab4a754e6ed5ec76454e3d699 + React-CoreModules: b3d9eece8ad7df36c917a41f05c1168c52fe0b34 + React-cxxreact: 1f972757c0bd08d962ef78068e06613c27489a3f + React-jsi: 32285a21b1b24c36060493ed3057a34677d58d09 + React-jsiexecutor: 8909917ff7d8f21a57e443a866fd8d4560e50c65 + React-jsinspector: 111d7d342b07a904c400592e02a2b958f1098b60 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-netinfo: 6bb847e64f45a2d69c6173741111cfd95c669301 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90 - React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e - React-RCTBlob: 5e2b55f76e9a1c7ae52b826923502ddc3238df24 - React-RCTImage: f5f1c50922164e89bdda67bcd0153952a5cfe719 - React-RCTLinking: d0ecbd791e9ddddc41fa1f66b0255de90e8ee1e9 - React-RCTNetwork: e26946300b0ab7bb6c4a6348090e93fa21f33a9d - React-RCTSettings: d0d37cb521b7470c998595a44f05847777cc3f42 - React-RCTText: b074d89033583d4f2eb5faf7ea2db3a13c7553a2 - React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0 - React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4 + React-RCTActionSheet: 89b037c0fb7d2671607cb645760164e7e0c013f6 + React-RCTAnimation: e3cefa93c38c004c318f7ec04b883eb14b8b8235 + React-RCTBlob: d26ac0e313fbf14e7203473fd593ccaaeee8329e + React-RCTImage: 4bdd9588783fa9e48ef669ccd4f747224e208edf + React-RCTLinking: 65f0088ff463babd3d5d567964a65b74141eff3b + React-RCTNetwork: 0c1a73576c1cfeafe68396556de1b17d93c0c595 + React-RCTSettings: 4194f1f0edbddf3fd44d1714dc6578bb20379b60 + React-RCTText: e3ef6191cdb627855ff7fe8fa0c1e14094967fb8 + React-RCTVibration: fb54c732fd20405a76598e431aa2f8c2bf527de9 + ReactCommon: 5848032ed2f274fcb40f6b9ec24067787c42d479 RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 @@ -366,10 +523,10 @@ SPEC CHECKSUMS: RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - SDWebImage: 4eabf2fa6695c95c47724214417a9c036c965e4a + SDWebImage: 46a7f73228f84ce80990c786e4372cf4db5875ce SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 - yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 + Yoga: 14927e37bd25376d216b150ab2a561773d57911f -PODFILE CHECKSUM: 33865f4d2b0b4f3f246921d3679430cd55088e21 +PODFILE CHECKSUM: a039fce385962c5aff74e63f1df4ed5302b9aa01 -COCOAPODS: 1.6.1 +COCOAPODS: 1.8.4 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 83707a60db0..ba3472ce3fc 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */; }; 23320186D7F747FEB02451C6 /* SF-Pro-Text-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */; }; 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B86CB964E3AA47029988138C /* libRNKeychain.a */; }; + 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; }; + 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24979E7B20F84004007EB0DA /* FirebaseInstanceID.framework */; }; 24979E8920F84250007EB0DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24979E7720F84004007EB0DA /* GoogleService-Info.plist */; }; 26095B12C30047F89592D463 /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */; }; @@ -39,9 +41,6 @@ 396C4BA42EEC4D0985CEBB42 /* SF-Pro-Text-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */; }; 3C363E14D5DE4A028E43EA38 /* SF-Pro-Display-UltralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */; }; 3C41C1415A994234A0FF2589 /* SF-Pro-Text-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */; }; - 3CD599AF236B351D007DD55E /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CD599AE236B351D007DD55E /* InputMask.framework */; }; - 3CD599B0236B351D007DD55E /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3CD599AE236B351D007DD55E /* InputMask.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3CD599B1236B3520007DD55E /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CD599AD236B3513007DD55E /* libRNTextInputMask.a */; }; 4013198EBD3D4D6F8052D25E /* SF-Pro-Display-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */; }; 41804DE52CE94296995264E0 /* SF-Pro-Text-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */; }; 424410A1E84845328C5A0CAB /* Graphik-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */; }; @@ -90,6 +89,7 @@ ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A014AE1645874354A732EB35 /* libToolTipMenu.a */; }; F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D1A86E696CA24D4F9D3F7F0F /* libz.tbd */; }; F4E8A17A670147F4A5EC177E /* libRNGestureHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A7E5E09E14B4EA4B52CC6EE /* libRNGestureHandler.a */; }; + F643BEEE1F9445C7932B2A75 /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */; }; F9EB9219ED9A4C72826A5908 /* Graphik-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */; }; F9EF1D44351840B8A380BD3E /* SF-Pro-Display-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */; }; FBDF4EF177284CF4826D7BF9 /* SF-Pro-Display-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D7BFD847B72D414D9BE734A0 /* SF-Pro-Display-HeavyItalic.otf */; }; @@ -446,13 +446,6 @@ remoteGlobalIDString = 47413E2820DBB5D000CCDA85; remoteInfo = "SRSRadialGradien-tvOS"; }; - 3CD599AC236B3513007DD55E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNTextInputMask; - }; 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; @@ -558,6 +551,13 @@ remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteInfo = RCTText; }; + AA24D00F235EB5550082BA9B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RNTextInputMask; + }; ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; @@ -574,7 +574,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3CD599B0236B351D007DD55E /* InputMask.framework in Embed Frameworks */, + 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -613,6 +613,7 @@ 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ToolTipMenu.xcodeproj; path = "../node_modules/react-native-tooltip/ToolTipMenu.xcodeproj"; sourceTree = ""; }; 22E39434CDDE4C54848FBFD5 /* libCodePush.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libCodePush.a; sourceTree = ""; }; 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Text-Heavy.otf"; sourceTree = ""; }; + 24122D53232F2B3200BA0B17 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24979E3620F84003007EB0DA /* Protobuf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Protobuf.framework; path = Frameworks/Protobuf.framework; sourceTree = ""; }; 24979E7420F84004007EB0DA /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 24979E7520F84004007EB0DA /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/FirebaseCore.framework; sourceTree = ""; }; @@ -646,8 +647,6 @@ 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Rainbow.entitlements; path = Rainbow/Rainbow.entitlements; sourceTree = ""; }; 3C39C266218BBE66004C763F /* FastImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FastImage.xcodeproj; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = ""; }; 3CC4B790228B298400D827EB /* libSDWebImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSDWebImage.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; - 3CD599AE236B351D007DD55E /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D5210FEA8F00672599 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D7210FEACE00672599 /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ThinItalic.otf"; path = "../src/assets/fonts/Graphik-ThinItalic.otf"; sourceTree = ""; }; @@ -698,6 +697,7 @@ AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Semibold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Semibold.otf"; sourceTree = ""; }; ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFIRMessaging.xcodeproj; path = "../node_modules/react-native-fcm/ios/RNFIRMessaging.xcodeproj"; sourceTree = ""; }; + B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; B0C692B061D7430D8194DC98 /* ToolTipMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ToolTipMenuTests.xctest; sourceTree = ""; }; B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNTextInputMask.a; sourceTree = ""; }; B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Semibold.otf"; path = "../src/assets/fonts/SFMono-Semibold.otf"; sourceTree = ""; }; @@ -753,11 +753,9 @@ 4433A04AF3E942A2894B3933 /* libRNOS.a in Frameworks */, 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */, 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */, - 3CD599AF236B351D007DD55E /* InputMask.framework in Frameworks */, 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */, 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */, 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */, - 3CD599B1236B3520007DD55E /* libRNTextInputMask.a in Frameworks */, 91959ACCE81B4C128AAC8154 /* libRNSVG.a in Frameworks */, 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */, ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */, @@ -770,6 +768,8 @@ 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */, + 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */, + F643BEEE1F9445C7932B2A75 /* libRNTextInputMask.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1088,7 +1088,6 @@ children = ( 3CC4B790228B298400D827EB /* libSDWebImage.a */, 24A867FF226181F9005DCF78 /* libFirebaseInstanceID.a */, - 3CD599AE236B351D007DD55E /* InputMask.framework */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, 3CE850D7210FEACE00672599 /* libnanopb.a */, @@ -1121,14 +1120,6 @@ name = Products; sourceTree = ""; }; - 3CD599A8236B3513007DD55E /* Products */ = { - isa = PBXGroup; - children = ( - 3CD599AD236B3513007DD55E /* libRNTextInputMask.a */, - ); - name = Products; - sourceTree = ""; - }; 5E91572E1DD0AC6500FF2AA8 /* Products */ = { isa = PBXGroup; children = ( @@ -1150,7 +1141,6 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */, 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */, 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */, 3C39C266218BBE66004C763F /* FastImage.xcodeproj */, @@ -1183,6 +1173,7 @@ 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */, 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */, 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */, + B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1199,6 +1190,7 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( + 24122D53232F2B3200BA0B17 /* InputMask.framework */, 13B07FAE1A68108700A75B9A /* Rainbow */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* RainbowTests */, @@ -1222,6 +1214,14 @@ name = Products; sourceTree = ""; }; + AA24D00C235EB5550082BA9B /* Products */ = { + isa = PBXGroup; + children = ( + AA24D010235EB5550082BA9B /* libRNTextInputMask.a */, + ); + name = Products; + sourceTree = ""; + }; ADBDB9201DFEBF0600ED6528 /* Products */ = { isa = PBXGroup; children = ( @@ -1492,8 +1492,8 @@ ProjectRef = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; }, { - ProductGroup = 3CD599A8236B3513007DD55E /* Products */; - ProjectRef = 3CD599A7236B3513007DD55E /* RNTextInputMask.xcodeproj */; + ProductGroup = AA24D00C235EB5550082BA9B /* Products */; + ProjectRef = B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */; }, { ProductGroup = 24979D5020F83E3E007EB0DA /* Products */; @@ -1872,13 +1872,6 @@ remoteRef = 3CD4E8CC216989E8000FA5BD /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 3CD599AD236B3513007DD55E /* libRNTextInputMask.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNTextInputMask.a; - remoteRef = 3CD599AC236B3513007DD55E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1984,6 +1977,13 @@ remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + AA24D010235EB5550082BA9B /* libRNTextInputMask.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNTextInputMask.a; + remoteRef = AA24D00F235EB5550082BA9B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -2269,7 +2269,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; @@ -2330,7 +2330,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L74NQAQB8H; @@ -2427,7 +2427,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L74NQAQB8H; @@ -2571,7 +2571,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODEPUSH_KEY = ""; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L74NQAQB8H; diff --git a/package.json b/package.json index 76588845e78..5b394b1e121 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "1.1.6-3", "private": true, "scripts": { + "android": "react-native run-android", "clean": "react-native-clean-project", "start": "react-native start", "test": "jest test.js", @@ -71,7 +72,7 @@ "querystring-es3": "^0.2.1", "react": "16.9.0", "react-coin-icon": "^0.1.9", - "react-native": "0.60.5", + "react-native": "0.61.2", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", @@ -82,7 +83,7 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-firebase": "^4.3.8", - "react-native-gesture-handler": "1.4.1", + "react-native-gesture-handler": "^1.4.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", "react-native-ios11-devicecheck": "^0.0.3", @@ -106,7 +107,7 @@ "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "9.13.2", + "react-native-svg": "9.10.1", "react-native-tcp": "^3.3.0", "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", "react-native-tooltip": "^5.2.0", @@ -142,26 +143,26 @@ "vm-browserify": "0.0.4" }, "devDependencies": { - "@babel/core": "^7.5.5", - "@babel/runtime": "^7.5.5", + "@babel/core": "^7.6.2", + "@babel/runtime": "^7.6.2", "@react-native-community/cli": "2.9.0", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^10.0.2", - "babel-jest": "^24.8.0", + "babel-jest": "^24.9.0", "babel-plugin-date-fns": "^0.2.1", "babel-plugin-lodash": "^3.3.4", "babel-plugin-rewire": "^1.2.0", "babel-plugin-styled-components": "^1.10.6", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", - "eslint": "6.1.0", + "eslint": "^6.5.1", "eslint-config-satya164": "^2.4.1", - "jest": "^24.8.0", + "jest": "^24.9.0", "metro-react-native-babel-preset": "^0.56.0", "mocha": "^6.1.4", "react-native-bundle-visualizer": "^2.0.1", "react-native-clean-project": "^3.1.0", - "react-test-renderer": "16.8.3", + "react-test-renderer": "16.9.0", "schedule": "0.5.0" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index f180dcfcfa1..4fde35d8159 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.5.5": +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.6.2": version "7.6.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.4.tgz#6ebd9fe00925f6c3e177bb726a188b5f578088ff" integrity sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ== @@ -607,7 +607,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.6.2": version "7.6.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f" integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA== @@ -779,9 +779,9 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.5.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" - integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw== + version "8.4.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.4.0.tgz#3f2153d9eea8942dfe217e1642a420f1fe4087f3" + integrity sha512-JLK+vNrtZSQy1PiAAvtaPGiZhFQo+BLywJkD4EHG8vCzlW9w7Y9yfb2be1GFKnZKczLgzHBpgMOBUZs1qBNB5g== "@hapi/joi@^15.0.3": version "15.1.1" @@ -995,7 +995,7 @@ dependencies: prop-types "^15.5.10" -"@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": +"@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== @@ -1008,7 +1008,20 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0": +"@react-native-community/cli-platform-android@^3.0.0-alpha.1", "@react-native-community/cli-platform-android@^3.0.0-alpha.7": + version "3.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.0-alpha.7.tgz#03c3671ab72b62a8742aa71b66cb8d594171891f" + integrity sha512-Ot/4K841f3vJZM5K7Za/bYgGeXUJyBsZZuoFvnEMAmR/tS6QCrsv8NQ7f/E3HmxvWaSEVNiiF8NiW2+qo6YDxg== + dependencies: + "@react-native-community/cli-tools" "^3.0.0-alpha.7" + chalk "^2.4.2" + execa "^1.0.0" + jetifier "^1.6.2" + logkitty "^0.6.0" + slash "^3.0.0" + xmldoc "^1.1.2" + +"@react-native-community/cli-platform-ios@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== @@ -1017,6 +1030,16 @@ chalk "^2.4.2" xcode "^2.0.0" +"@react-native-community/cli-platform-ios@^3.0.0-alpha.1", "@react-native-community/cli-platform-ios@^3.0.0-alpha.7": + version "3.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0-alpha.7.tgz#21be15fc3b8117e0e62caf1e754f2760d78cfa93" + integrity sha512-6qM5LpzhCEhkb9MC+nxrOHX2TxoN4qm8+Vg9byIW/wExl8dWCTneRUbQ5qFlkkMksS2U63LiRVSCXK08d6x5bA== + dependencies: + "@react-native-community/cli-tools" "^3.0.0-alpha.7" + chalk "^2.4.2" + js-yaml "^3.13.1" + xcode "^2.0.0" + "@react-native-community/cli-tools@^2.8.3": version "2.8.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" @@ -1027,7 +1050,22 @@ mime "^2.4.1" node-fetch "^2.5.0" -"@react-native-community/cli@2.9.0", "@react-native-community/cli@^2.6.0": +"@react-native-community/cli-tools@^3.0.0-alpha.7": + version "3.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0-alpha.7.tgz#1018283598e3f2ddc785d1381ca8692ec51735a5" + integrity sha512-x4XdeMtAx7RC1YP5cqLWIggXOuzuANItWi8BD8R/ak6GWMRd3X5L2HFuLa6GDXgkWSXtoUvqOilJplhVhLRrmQ== + dependencies: + chalk "^2.4.2" + lodash "^4.17.5" + mime "^2.4.1" + node-fetch "^2.5.0" + +"@react-native-community/cli-types@^3.0.0-alpha.7": + version "3.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0-alpha.7.tgz#b4c19fd71824400a57c7f6758fa1f7b15eece32d" + integrity sha512-anT+l41FK7EJXOlOx8ZzIgskDuslT5A5NkMg2Kt3YzAxf8wrCBbOo5/CjnuW6pi9fvjGgB810Yw3tFSl4yZY4A== + +"@react-native-community/cli@2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw== @@ -1066,6 +1104,55 @@ shell-quote "1.6.1" ws "^1.1.0" +"@react-native-community/cli@^3.0.0-alpha.1": + version "3.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.0-alpha.7.tgz#df8cb6a878d106da36e4f994f9d8c3541c3834ee" + integrity sha512-gmAnmH9sqReBEvfZxk0A3gw0Ddb6UNHYvbjjyM+qgH2TbEAWCfLHLqiHNSCYxfO3hkDyz4mj/cvtb8ahFjTdIw== + dependencies: + "@hapi/joi" "^15.0.3" + "@react-native-community/cli-platform-android" "^3.0.0-alpha.7" + "@react-native-community/cli-platform-ios" "^3.0.0-alpha.7" + "@react-native-community/cli-tools" "^3.0.0-alpha.7" + "@react-native-community/cli-types" "^3.0.0-alpha.7" + "@types/mkdirp" "^0.5.2" + "@types/node-notifier" "^5.4.0" + "@types/semver" "^6.0.2" + "@types/ws" "^6.0.3" + chalk "^2.4.2" + command-exists "^1.2.8" + commander "^2.19.0" + compression "^1.7.1" + connect "^3.6.5" + cosmiconfig "^5.1.0" + deepmerge "^3.2.0" + envinfo "^7.1.0" + errorhandler "^1.5.0" + execa "^1.0.0" + find-up "^4.1.0" + fs-extra "^7.0.1" + glob "^7.1.1" + graceful-fs "^4.1.3" + inquirer "^3.0.6" + lodash "^4.17.5" + metro "^0.56.0" + metro-config "^0.56.0" + metro-core "^0.56.0" + metro-react-native-babel-transformer "^0.56.0" + minimist "^1.2.0" + mkdirp "^0.5.1" + morgan "^1.9.0" + node-notifier "^5.2.1" + open "^6.2.0" + ora "^3.4.0" + plist "^3.0.0" + semver "^6.3.0" + serve-static "^1.13.1" + shell-quote "1.6.1" + strip-ansi "^5.2.0" + sudo-prompt "^9.0.0" + wcwidth "^1.0.1" + ws "^1.1.0" + "@react-native-community/masked-view@^0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.1.tgz#dbcfc5ec08efbb02d4142dd9426c8d7a396829d7" @@ -1317,6 +1404,20 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/node-notifier@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-5.4.0.tgz#4e66c85eb41cce8387b4cd9c6c67852be41a99db" + integrity sha512-M1XvCG6Rwej6+W0+kWultE46YS7erOy+W7suRmXtKwLGT3ytj6YEe9lqo47nRfL1xILzg9xJpKeNczIsWR8ymw== + dependencies: + "@types/node" "*" + "@types/node@*": version "12.12.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.3.tgz#ebfe83507ac506bc3486314a8aa395be66af8d23" @@ -1337,6 +1438,11 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/semver@^6.0.2": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.0.tgz#d688d574400d96c5b0114968705366f431831e1a" + integrity sha512-1OzrNb4RuAzIT7wHSsgZRlMBlNsJl+do6UblR7JMW4oB7bbR+uBEYtUh7gEc/jM84GGilh68lSOokyM/zNUlBA== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -1364,6 +1470,13 @@ "@types/unist" "*" "@types/vfile-message" "*" +"@types/ws@^6.0.3": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.3.tgz#b772375ba59d79066561c8d87500144d674ba6b3" + integrity sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -1621,11 +1734,18 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-escapes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" + integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== + dependencies: + type-fest "^0.5.2" + ansi-fragments@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansi-fragments/-/ansi-fragments-0.2.1.tgz#24409c56c4cc37817c3d7caa99d8969e2de5a05e" @@ -1942,7 +2062,7 @@ babel-eslint@^10.0.1, babel-eslint@^10.0.2: eslint-visitor-keys "^1.0.0" resolve "^1.12.0" -babel-jest@^24.8.0, babel-jest@^24.9.0: +babel-jest@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== @@ -2649,6 +2769,13 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + cli-spinners@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" @@ -2804,6 +2931,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +command-exists@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" + integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== + commander@^2.19.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -3057,7 +3189,7 @@ css-select-base-adapter@^0.1.1: resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== -css-select@^2.0.0, css-select@^2.0.2: +css-select@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== @@ -3076,7 +3208,7 @@ css-to-react-native@^2.2.2: css-color-keywords "^1.0.0" postcss-value-parser "^3.3.0" -css-tree@1.0.0-alpha.37, css-tree@^1.0.0-alpha.37: +css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== @@ -3856,7 +3988,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.3.1: +eslint-utils@^1.3.1, eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -3868,10 +4000,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" - integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== +eslint@^6.5.1: + version "6.6.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" + integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -3880,9 +4012,9 @@ eslint@6.1.0: debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^6.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -3892,7 +4024,7 @@ eslint@6.1.0: ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.4.1" + inquirer "^7.0.0" is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" @@ -3911,7 +4043,7 @@ eslint@6.1.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.0.0: +espree@^6.1.2: version "6.1.2" resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d" integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA== @@ -4293,6 +4425,13 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +figures@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.1.0.tgz#4b198dd07d8d71530642864af2d45dd9e459c4ec" + integrity sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" @@ -4358,7 +4497,7 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^4.0.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -4934,10 +5073,10 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermesvm@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.1.tgz#bd1df92b4dc504e261c23df34864daf24b844d03" - integrity sha512-EosSDeUqTTGvlc9vQiy5Y/9GBlucEyo6lYuxg/FnukHCD/CP3NYeDAGV54TyZ19FgSqMEoPgOH9cyxvv8epQ1g== +hermes-engine@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" + integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== hmac-drbg@^1.0.0: version "1.0.1" @@ -5238,22 +5377,22 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^6.4.1: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== +inquirer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" + integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== dependencies: - ansi-escapes "^3.2.0" + ansi-escapes "^4.2.1" chalk "^2.4.2" - cli-cursor "^2.1.0" + cli-cursor "^3.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" run-async "^2.2.0" rxjs "^6.4.0" - string-width "^2.1.0" + string-width "^4.1.0" strip-ansi "^5.1.0" through "^2.3.6" @@ -6034,7 +6173,7 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest@^24.8.0: +jest@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== @@ -6070,7 +6209,7 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsc-android@245459.0.0: +jsc-android@^245459.0.0: version "245459.0.0" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== @@ -6468,7 +6607,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -6728,6 +6867,24 @@ metro-babel-register@0.54.1: core-js "^2.2.2" escape-string-regexp "^1.0.5" +metro-babel-register@0.56.3, metro-babel-register@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.3.tgz#d0cfb38adf45cb35965649ede794f2308562e20f" + integrity sha512-ILCRtNFdW6vzqmLAG2MYWdTSE1vCAZqDKNggiNhlfViuoxmWAIL0vOqixl1CHZF5z4t55+fk46A0jSN7UgPyVw== + dependencies: + "@babel/core" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/register" "^7.0.0" + core-js "^2.2.2" + escape-string-regexp "^1.0.5" + metro-babel-transformer@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" @@ -6735,6 +6892,14 @@ metro-babel-transformer@0.54.1: dependencies: "@babel/core" "^7.0.0" +metro-babel-transformer@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz#6559c3a8565238a704a181353cef59fdb974e6db" + integrity sha512-N5/ftb3rBkt6uKlgYAv+lwtzYc4dK0tBpfZ8pjec3kcypGuGTuf4LTHEh65EuzySreLngYI0bQzoFSn3G3DYsw== + dependencies: + "@babel/core" "^7.0.0" + metro-source-map "0.56.3" + metro-babel7-plugin-react-transform@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" @@ -6752,6 +6917,16 @@ metro-cache@0.54.1: mkdirp "^0.5.1" rimraf "^2.5.4" +metro-cache@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.3.tgz#1b0759bc45291cc3ffc77736c09dcfbd322edb8b" + integrity sha512-SsryVe/TVkt2IkEGnYhB3gQlg9iMlu8WJikQHcCEjMfPEnSIzmeymrX73fwQNPnTnN7F3E0HVjH6Wvq6fh0mcA== + dependencies: + jest-serializer "^24.4.0" + metro-core "0.56.3" + mkdirp "^0.5.1" + rimraf "^2.5.4" + metro-config@0.54.1, metro-config@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd" @@ -6764,6 +6939,18 @@ metro-config@0.54.1, metro-config@^0.54.1: metro-core "0.54.1" pretty-format "^24.7.0" +metro-config@0.56.3, metro-config@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.3.tgz#b16e600817c58c768946f24b039d2a1ba6a67651" + integrity sha512-C3ZLA5y5gW5auDSQN5dsCTduJg7LXEiX/tLAADOkgXWVImr5P74x9Wt8y1MMWrKx6p+4p5RMDyEwWDMXJt/DwA== + dependencies: + cosmiconfig "^5.0.5" + jest-validate "^24.7.0" + metro "0.56.3" + metro-cache "0.56.3" + metro-core "0.56.3" + pretty-format "^24.7.0" + metro-core@0.54.1, metro-core@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b" @@ -6774,6 +6961,16 @@ metro-core@0.54.1, metro-core@^0.54.1: metro-resolver "0.54.1" wordwrap "^1.0.0" +metro-core@0.56.3, metro-core@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.3.tgz#34bb3a92621fd9b1ed3e6a01c6a4324fbb1201d9" + integrity sha512-OAaHP3mBdlACMZRwDJzZzYC0o2S3qfb4BBK75L8H4Ds+y3QUSrjsDEpHACcpaMTOds8rBvjzn+jjB5tqNoHfBA== + dependencies: + jest-haste-map "^24.7.1" + lodash.throttle "^4.1.1" + metro-resolver "0.56.3" + wordwrap "^1.0.0" + metro-inspector-proxy@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.54.1.tgz#0ef48ee3feb11c6da47aa100151a9bf2a7c358ee" @@ -6785,6 +6982,17 @@ metro-inspector-proxy@0.54.1: ws "^1.1.5" yargs "^9.0.0" +metro-inspector-proxy@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.3.tgz#48046f9e3f7153be2409e0bee9252dede932ac39" + integrity sha512-7WtHinw+VJcunQ3q8El1MqqzYSRvXEjW5QE13VYwcLtnay3pvcqACeiQmGbWI0IqxB1+QH8tf3nkA7z7pQ7Vpw== + dependencies: + connect "^3.6.5" + debug "^2.2.0" + rxjs "^5.4.3" + ws "^1.1.5" + yargs "^9.0.0" + metro-minify-uglify@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3" @@ -6792,6 +7000,13 @@ metro-minify-uglify@0.54.1: dependencies: uglify-es "^3.1.9" +metro-minify-uglify@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.3.tgz#763b26895f79d0589d3391dc94083d348cf9c2be" + integrity sha512-b9ljyeUpkJWVlFy8M/i4aNbvEBI0zN9vJh1jfU7yx+k9dX7FulLnpGmAQxxQdEszcM//sJrsKNS1oLYBxr0NMQ== + dependencies: + uglify-es "^3.1.9" + metro-react-native-babel-preset@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" @@ -6834,7 +7049,7 @@ metro-react-native-babel-preset@0.54.1: metro-babel7-plugin-react-transform "0.54.1" react-transform-hmr "^1.0.4" -metro-react-native-babel-preset@^0.56.0: +metro-react-native-babel-preset@0.56.3, metro-react-native-babel-preset@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz#5a1097c2f94e8ee0797a8ba2ab8f86d096f4c093" integrity sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow== @@ -6875,7 +7090,7 @@ metro-react-native-babel-preset@^0.56.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1: +metro-react-native-babel-transformer@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== @@ -6885,6 +7100,17 @@ metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transforme metro-babel-transformer "0.54.1" metro-react-native-babel-preset "0.54.1" +metro-react-native-babel-transformer@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" + integrity sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.1.2" + metro-babel-transformer "0.56.3" + metro-react-native-babel-preset "0.56.3" + metro-source-map "0.56.3" + metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -6892,6 +7118,13 @@ metro-resolver@0.54.1: dependencies: absolute-path "^0.0.0" +metro-resolver@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.3.tgz#f18978b919a5ecc67028732609a564880715ef75" + integrity sha512-VvMl4xUp0fy76WiP3YDtzMmrn6tN/jwxOBqlTy9MjN6R9sUXrGyO5thwn/uKQqp5vwBTuJev7nZL7OKzwludKA== + dependencies: + absolute-path "^0.0.0" + metro-source-map@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5" @@ -6901,25 +7134,26 @@ metro-source-map@0.54.1: "@babel/types" "^7.0.0" source-map "^0.5.6" -metro-source-map@0.55.0, metro-source-map@^0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540" - integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw== +metro-source-map@0.56.3, metro-source-map@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.3.tgz#0cadc9f9eca9ece224a6fd28b9e4fa3a9834e24c" + integrity sha512-CheqWbJZSM0zjcNBqELUiocwH3XArrOk6alhVuzJ2gV/WTMBQFwP0TtQssSMwjnouMHNEzY8RxErXKXBk/zJmQ== dependencies: "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" invariant "^2.2.4" - metro-symbolicate "0.55.0" - ob1 "0.55.0" + metro-symbolicate "0.56.3" + ob1 "0.56.3" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1" - integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg== +metro-symbolicate@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz#20f9dc52fab3209903715716402692b3ac16831c" + integrity sha512-fSQtjjy4eiJDThSl9eloxMElhrs+5PQB+DKKzmTFXT8e2GDga+pa1xTBFRUACMO8BXGuWmxR7SnGDw0wo5Ngrw== dependencies: - metro-source-map "0.55.0" + invariant "^2.2.4" + metro-source-map "0.56.3" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" @@ -6983,6 +7217,65 @@ metro@0.54.1, metro@^0.54.1: xpipe "^1.0.5" yargs "^9.0.0" +metro@0.56.3, metro@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.3.tgz#3a38706bf6b1200421e871a4c53ddc2f359f65a9" + integrity sha512-mxHpvBGWanZ46wAEZVLinNO5IYMcFbTdMZIRhC7r+rvoSK6r9iPj95AujBfzLXMAl36RI2O3D7yp5hOYif/gEQ== + dependencies: + "@babel/core" "^7.0.0" + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/plugin-external-helpers" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + absolute-path "^0.0.0" + async "^2.4.0" + babel-preset-fbjs "^3.1.2" + buffer-crc32 "^0.2.13" + chalk "^2.4.1" + concat-stream "^1.6.0" + connect "^3.6.5" + debug "^2.2.0" + denodeify "^1.2.1" + eventemitter3 "^3.0.0" + fbjs "^1.0.0" + fs-extra "^1.0.0" + graceful-fs "^4.1.3" + image-size "^0.6.0" + invariant "^2.2.4" + jest-haste-map "^24.7.1" + jest-worker "^24.6.0" + json-stable-stringify "^1.0.1" + lodash.throttle "^4.1.1" + merge-stream "^1.0.1" + metro-babel-register "0.56.3" + metro-babel-transformer "0.56.3" + metro-cache "0.56.3" + metro-config "0.56.3" + metro-core "0.56.3" + metro-inspector-proxy "0.56.3" + metro-minify-uglify "0.56.3" + metro-react-native-babel-preset "0.56.3" + metro-resolver "0.56.3" + metro-source-map "0.56.3" + metro-symbolicate "0.56.3" + mime-types "2.1.11" + mkdirp "^0.5.1" + node-fetch "^2.2.0" + nullthrows "^1.1.0" + resolve "^1.5.0" + rimraf "^2.5.4" + serialize-error "^2.1.0" + source-map "^0.5.6" + temp "0.8.3" + throat "^4.1.0" + wordwrap "^1.0.0" + write-file-atomic "^1.2.0" + ws "^1.1.5" + xpipe "^1.0.5" + yargs "^9.0.0" + micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7227,6 +7520,11 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + mv@~2: version "2.1.1" resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" @@ -7503,10 +7801,10 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -ob1@0.55.0: - version "0.55.0" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd" - integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw== +ob1@0.56.3: + version "0.56.3" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.3.tgz#5829e446587c9bf89c22ece4f3757b29f2ccfd18" + integrity sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ== object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -8113,9 +8411,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177" - integrity sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" + integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== pify@^2.0.0: version "2.3.0" @@ -8611,7 +8909,7 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.1: +react-devtools-core@^3.6.3: version "3.6.3" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== @@ -8624,7 +8922,7 @@ react-display-name@^0.2.4: resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.4.tgz#e2a670b81d79a2204335510c01246f4c92ff12cf" integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: version "16.11.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== @@ -8731,10 +9029,10 @@ react-native-firebase@^4.3.8: postinstall-build "^5.0.1" prop-types "^15.6.1" -react-native-gesture-handler@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" - integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== +react-native-gesture-handler@^1.4.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.0.tgz#df7dc5285c152e0656db70f55200fa632c4f45af" + integrity sha512-YUOXHsGLajK1cFReQ4Xh0H9GUTxDW9cUZEVu1q+dVqur2urSKi63KklAFB2l8Neob9nl1E/w0c5hGcBP9FMCIA== dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -8885,13 +9183,10 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -react-native-svg@9.13.2: - version "9.13.2" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.2.tgz#72a2e089f69af99c491586a95baf71009c263a51" - integrity sha512-l73+7X4mDYQBHilJ0UzFph4QmuvkngtJrfUiyLZwNLzX4T6gjyjAC2im+JNHhY7i4tU4k+I74YSCFiC7OB85Pw== - dependencies: - css-select "^2.0.2" - css-tree "^1.0.0-alpha.37" +react-native-svg@9.10.1: + version "9.10.1" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.10.1.tgz#055f457c427acedb01d2b758b6c1f423e8a3a607" + integrity sha512-im9LHke7pFRqQPf4qlSEti7QtcDHHeacRkI6xJspw1aka/n0LJxxBBkg7w7/Pmz5hDkzf7fRzyQi/TexB2sHnQ== react-native-tab-view@^2.9.0: version "2.10.0" @@ -8940,15 +9235,15 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.60.5: - version "0.60.5" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.5.tgz#3c1d9c06a0fbab9807220b6acac09488d39186ee" - integrity sha512-cZwI0XzzihACN+7an1Dy46A83FRaAe2Xyd7laCalFFAppZIYeMVphZQWrVljJk5kIZBNtYG35TY1VsghQ0Oc2Q== +react-native@0.61.2: + version "0.61.2" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.2.tgz#987b91b063557f8ebec803fdfea2044a24bdbe4d" + integrity sha512-hhd8bYbkkZYHoOndxUwbjJ6Yd9HFn5PvwqqS41uJ1xADdw44rx/svuwmJNA1RKF7jH74uR2jpBViWYGd36zGyg== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^2.6.0" - "@react-native-community/cli-platform-android" "^2.6.0" - "@react-native-community/cli-platform-ios" "^2.4.1" + "@react-native-community/cli" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" abort-controller "^3.0.0" art "^0.10.0" base64-js "^1.1.2" @@ -8958,19 +9253,20 @@ react-native@0.60.5: event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermesvm "^0.1.0" + hermes-engine "^0.2.1" invariant "^2.2.4" - jsc-android "245459.0.0" - metro-babel-register "0.54.1" - metro-react-native-babel-transformer "0.54.1" - metro-source-map "^0.55.0" + jsc-android "^245459.0.0" + metro-babel-register "^0.56.0" + metro-react-native-babel-transformer "^0.56.0" + metro-source-map "^0.56.0" nullthrows "^1.1.0" pretty-format "^24.7.0" promise "^7.1.1" prop-types "^15.7.2" - react-devtools-core "^3.6.1" + react-devtools-core "^3.6.3" + react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.14.0" + scheduler "0.15.0" stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" @@ -9047,15 +9343,15 @@ react-style-proptype@^3.2.2: dependencies: prop-types "^15.5.4" -react-test-renderer@16.8.3: - version "16.8.3" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.3.tgz#230006af264cc46aeef94392e04747c21839e05e" - integrity sha512-rjJGYebduKNZH0k1bUivVrRLX04JfIQ0FKJLPK10TAb06XWhfi4gTobooF9K/DEFNW98iGac3OSxkfIJUN9Mdg== +react-test-renderer@16.9.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.9.0.tgz#7ed657a374af47af88f66f33a3ef99c9610c8ae9" + integrity sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ== dependencies: object-assign "^4.1.1" prop-types "^15.6.2" - react-is "^16.8.3" - scheduler "^0.13.3" + react-is "^16.9.0" + scheduler "^0.15.0" react-timer-mixin@^0.13.4: version "0.13.4" @@ -9557,6 +9853,14 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -9742,18 +10046,10 @@ schedule@0.5.0: dependencies: object-assign "^4.1.1" -scheduler@0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b" - integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -scheduler@^0.13.3: - version "0.13.6" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" - integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== +scheduler@0.15.0, scheduler@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e" + integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -10503,6 +10799,11 @@ stylis@^3.5.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== +sudo-prompt@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a" + integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ== + sugarss@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" @@ -10905,6 +11206,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== + type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" @@ -11273,9 +11579,9 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.3.tgz#e0792619ec3f8730194c93ef74474d4429606cd6" - integrity sha512-SRIy75K4/6H1vmMYVsxYwynFUNMOEzIhTy+Pm6D24JHTquwMe7rx/35X75u2sw65e46ZP67izyrJ6ahaAi8UjQ== + version "3.4.1" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.1.tgz#e051f3bb2de5d23995763deac108622a5e93604a" + integrity sha512-IWJreQ9HtBSyveqaC3UUEArUqCnt5zYLgHewSJ0CvxlIJfvY7yD8GDbLuLxGeHMWwSudYlODit1IfwNzvjZjEg== dependencies: jsonc-parser "^2.2.0" vscode-languageserver-types "^3.15.0-next.5" From 400efe14eb4a9179afbb6e6c6d48787b4528c83d Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 5 Nov 2019 16:05:56 -0500 Subject: [PATCH 463/636] Use autolinking for RN 61 upgrade --- android/app/build.gradle | 16 - .../java/com/rainbow/MainApplication.java | 33 +- android/settings.gradle | 32 - config/test/jest-setup.js | 12 +- ios/Podfile | 34 +- ios/Podfile.lock | 249 +- ios/Rainbow.xcodeproj/project.pbxproj | 2138 ++--------------- .../xcshareddata/xcschemes/Rainbow.xcscheme | 6 +- .../xcshareddata/WorkspaceSettings.xcsettings | 10 + ios/Rainbow/Info.plist | 314 +-- package.json | 10 +- yarn.lock | 674 +++--- 12 files changed, 908 insertions(+), 2620 deletions(-) create mode 100644 ios/Rainbow.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/android/app/build.gradle b/android/app/build.gradle index 4760302c632..74c2077ff23 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -156,35 +156,19 @@ dependencies { implementation project(':react-native-text-input-mask') implementation project(':react-native-safe-area-context') implementation project(':@segment_analytics-react-native') - implementation project(':react-native-firebase') implementation project(':@staltz_react-native-tcp') implementation project(':@react-native-community_blur') implementation project(':@react-native-community_netinfo') implementation project(':@react-native-community_masked-view') - implementation project(':@react-native-community_async-storage') implementation project(':react-native-camera') compile project(':react-native-device-info') compile project(':react-native-screens') compile project(':react-native-version-number') compile project(':react-native-matomo') - compile project(':react-native-fast-image') compile project(':react-native-blur') compile project(':react-native-languages') compile project(':react-native-reanimated') - compile project(':react-native-gesture-handler') compile project(':react-native-code-push') - compile project(':react-native-haptic-feedback') - compile project(':react-native-udp') - compile project(':react-native-touch-id') - compile project(':react-native-tcp') - compile project(':react-native-svg') - compile project(':react-native-splash-screen') - compile project(':react-native-randombytes') - compile project(':react-native-radial-gradient') - compile project(':react-native-os') - compile project(':react-native-mail') - compile project(':react-native-linear-gradient') - compile project(':react-native-keychain') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" compile "com.facebook.react:react-native:+" // From node_modules diff --git a/android/app/src/main/java/com/rainbow/MainApplication.java b/android/app/src/main/java/com/rainbow/MainApplication.java index 783b10508e3..10969facca4 100644 --- a/android/app/src/main/java/com/rainbow/MainApplication.java +++ b/android/app/src/main/java/com/rainbow/MainApplication.java @@ -8,34 +8,19 @@ import org.reactnative.maskedview.RNCMaskedViewPackage; import com.RNTextInputMask.RNTextInputMaskPackage; import com.segment.analytics.reactnative.core.RNAnalyticsPackage; -import io.invertase.firebase.RNFirebasePackage; import react-native-tcp.TcpSocketsModule; import com.cmcewen.blurview.BlurViewPackage; import com.reactnativecommunity.netinfo.NetInfoPackage; -import com.reactnativecommunity.asyncstorage.AsyncStoragePackage; import org.reactnative.camera.RNCameraPackage; import com.learnium.RNDeviceInfo.RNDeviceInfo; import com.swmansion.rnscreens.RNScreensPackage; import com.apsl.versionnumber.RNVersionNumberPackage; import de.bonify.reactnativepiwik.PiwikPackage; -import com.dylanvann.fastimage.FastImageViewPackage; import com.cmcewen.blurview.BlurViewPackage; import com.reactcommunity.rnlanguages.RNLanguagesPackage; import com.swmansion.reanimated.ReanimatedPackage; -import com.swmansion.gesturehandler.react.RNGestureHandlerPackage; import com.microsoft.codepush.react.CodePush; import com.reactlibrary.RNReactNativeHapticFeedbackPackage; -import com.tradle.react.UdpSocketsModule; -import com.rnfingerprint.FingerprintAuthPackage; -import com.peel.react.TcpSocketsModule; -import com.horcrux.svg.SvgPackage; -import org.devio.rn.splashscreen.SplashScreenReactPackage; -import com.bitgo.randombytes.RandomBytesPackage; -import com.surajit.rnrg.RNRadialGradientPackage; -import com.peel.react.rnos.RNOSModule; -import com.chirag.RNMail.RNMail; -import com.BV.LinearGradient.LinearGradientPackage; -import com.oblador.keychain.KeychainPackage; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; @@ -67,34 +52,18 @@ protected List getPackages() { new RNCMaskedViewPackage(), new RNTextInputMaskPackage(), new RNAnalyticsPackage(), - new RNFirebasePackage(), - new TcpSocketsModule(), new BlurViewPackage(), new NetInfoPackage(), - new AsyncStoragePackage(), new RNCameraPackage(), new RNDeviceInfo(), new RNScreensPackage(), new RNVersionNumberPackage(), new PiwikPackage(), - new FastImageViewPackage(), new BlurViewPackage(), new RNLanguagesPackage(), new ReanimatedPackage(), - new RNGestureHandlerPackage(), new CodePush(BuildConfig.CODEPUSH_KEY, getApplicationContext(), BuildConfig.DEBUG), - new RNReactNativeHapticFeedbackPackage(), - new UdpSocketsModule(), - new FingerprintAuthPackage(), - new TcpSocketsModule(), - new SvgPackage(), - new SplashScreenReactPackage(), - new RandomBytesPackage(), - new RNRadialGradientPackage(), - new RNOSModule(), - new RNMail(), - new LinearGradientPackage(), - new KeychainPackage() + new TcpSocketsModule() ); } diff --git a/android/settings.gradle b/android/settings.gradle index 3a4776811f5..51255462cdc 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -9,16 +9,12 @@ include ':react-native-text-input-mask' project(':react-native-text-input-mask').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-text-input-mask/android') include ':@segment_analytics-react-native' project(':@segment_analytics-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/@segment/analytics-react-native/android') -include ':react-native-firebase' -project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android') include ':@staltz_react-native-tcp' project(':@staltz_react-native-tcp').projectDir = new File(rootProject.projectDir, '../node_modules/@staltz/react-native-tcp/android') include ':@react-native-community_blur' project(':@react-native-community_blur').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/blur/android') include ':@react-native-community_netinfo' project(':@react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android') -include ':@react-native-community_async-storage' -project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android') include ':react-native-camera' project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android') include ':react-native-device-info' @@ -29,41 +25,13 @@ include ':react-native-version-number' project(':react-native-version-number').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-version-number/android') include ':react-native-matomo' project(':react-native-matomo').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-matomo/android') -include ':react-native-fast-image' -project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android') include ':react-native-blur' project(':react-native-blur').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-blur/android') include ':react-native-languages' project(':react-native-languages').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-languages/android') include ':react-native-reanimated' project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-reanimated/android') -include ':react-native-gesture-handler' -project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android') include ':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app') -include ':react-native-haptic-feedback' -project(':react-native-haptic-feedback').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-haptic-feedback/android') -include ':react-native-udp' -project(':react-native-udp').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-udp/android') -include ':react-native-touch-id' -project(':react-native-touch-id').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-touch-id/android') -include ':react-native-tcp' -project(':react-native-tcp').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-tcp/android') -include ':react-native-svg' -project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android') -include ':react-native-splash-screen' -project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android') -include ':react-native-randombytes' -project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android') -include ':react-native-radial-gradient' -project(':react-native-radial-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-radial-gradient/android') -include ':react-native-os' -project(':react-native-os').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-os/android') -include ':react-native-mail' -project(':react-native-mail').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mail/android') -include ':react-native-linear-gradient' -project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android') -include ':react-native-keychain' -project(':react-native-keychain').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keychain/android') include ':app' diff --git a/config/test/jest-setup.js b/config/test/jest-setup.js index ab0b4caaa14..8f7c8040669 100644 --- a/config/test/jest-setup.js +++ b/config/test/jest-setup.js @@ -1,5 +1,9 @@ /* eslint-disable no-undef */ -import { NativeModules } from 'react-native'; +jest.mock('@segment/analytics-react-native', () => ({ + identify: () => null, + reset: () => null, + setup: () => null, +})); jest.autoMockOff(); jest.mock('react-native-keychain', () => ({ @@ -7,9 +11,3 @@ jest.mock('react-native-keychain', () => ({ resetGenericPassword: jest.fn(), setGenericPassword: jest.fn(), })); - -NativeModules.RNAnalytics = {}; - -const mockAnalytics = jest.genMockFromModule('@segment/analytics-react-native'); - -jest.mock('@segment/analytics-react-native', () => mockAnalytics); diff --git a/ios/Podfile b/ios/Podfile index 4b33fb4594c..353cbb9e74f 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,4 +1,5 @@ -platform :ios, '9.0' +platform :ios, '10.0' +require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' # Prevent Cocoapods from collecting stats, which adds time to each pod installation ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -9,14 +10,15 @@ target 'Rainbow' do pod 'Crashlytics', '~> 3.10.7' # Firebase - pod 'Firebase/Core', '~> 5.3.0' - pod 'Firebase/Messaging', '~> 5.3.0' + pod 'Firebase/Core', '~> 6.2.0' + pod 'Firebase/Messaging', '~> 6.2.0' # Core React pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" - pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" + pod 'RCTTypeSafety', :path => + "../node_modules/react-native/Libraries/TypeSafety" pod 'React', :path => '../node_modules/react-native/' pod 'React-Core', :path => '../node_modules/react-native/' pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' @@ -44,31 +46,11 @@ target 'Rainbow' do pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' - - # React-Native-Community packages - pod 'react-native-blur', :path => '../node_modules/@react-native-community/blur' - pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo' - pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-community/async-storage' - - # Third Party packages - pod 'react-native-camera', :path => '../node_modules/react-native-camera' - pod 'RNFastImage', :path => '../node_modules/react-native-fast-image' - pod 'react-native-version-number', :path => '../node_modules/react-native-version-number' - - pod 'BVLinearGradient', :path => '../node_modules/react-native-linear-gradient' - pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info' - pod 'RNIOS11DeviceCheck', :path => '../node_modules/react-native-ios11-devicecheck/ios' - pod 'RNLanguages', :path => '../node_modules/react-native-languages' - pod 'RNReanimated', :path => '../node_modules/react-native-reanimated' - pod 'RNScreens', :path => '../node_modules/react-native-screens' - pod 'RNStoreReview', :path => '../node_modules/react-native-store-review/ios' - pod 'FLAnimatedImage' pod 'libwebp' - pod 'RNAnalytics', :path => '../node_modules/@segment/analytics-react-native' + pod 'CodePush', :path => '../node_modules/react-native-code-push' - pod 'RNCMaskedView', :path => '../node_modules/@react-native-community/masked-view' + use_native_modules! - pod 'react-native-safe-area-context', :path => '../node_modules/react-native-safe-area-context' end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4d8463b2e8b..e41644cede6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,8 +1,14 @@ PODS: - Analytics (3.7.0) + - Base64 (1.1.2) - boost-for-react-native (1.63.0) - BVLinearGradient (2.5.6): - React + - CodePush (5.7.0): + - Base64 (~> 1.1) + - JWT (~> 3.0.0-beta.7) + - React + - SSZipArchive (~> 2.1) - Crashlytics (3.10.9): - Fabric (~> 1.7.13) - DoubleConversion (1.1.6) @@ -15,27 +21,39 @@ PODS: - React-Core (= 0.61.2) - React-jsi (= 0.61.2) - ReactCommon/turbomodule/core (= 0.61.2) - - Firebase/Core (5.3.0): + - Firebase/Core (6.2.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 5.0.1) - - Firebase/CoreOnly (5.3.0): - - FirebaseCore (= 5.0.4) - - Firebase/Messaging (5.3.0): + - FirebaseAnalytics (= 6.0.1) + - Firebase/CoreOnly (6.2.0): + - FirebaseCore (= 6.0.2) + - Firebase/Messaging (6.2.0): - Firebase/CoreOnly - - FirebaseMessaging (= 3.0.2) - - FirebaseAnalytics (5.0.1): - - FirebaseCore (~> 5.0) - - FirebaseInstanceID (~> 3.0) - - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" + - FirebaseMessaging (~> 4.0.2) + - FirebaseAnalytics (6.0.1): + - FirebaseCore (~> 6.0) + - FirebaseInstanceID (~> 4.1) + - GoogleAppMeasurement (= 6.0.1) + - GoogleUtilities/AppDelegateSwizzler (~> 6.0) + - GoogleUtilities/MethodSwizzler (~> 6.0) + - GoogleUtilities/Network (~> 6.0) + - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (~> 0.3) - - FirebaseCore (5.0.4): - - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" - - FirebaseInstanceID (3.1.1): - - FirebaseCore (~> 5.0) - - FirebaseMessaging (3.0.2): - - FirebaseCore (~> 5.0) - - FirebaseInstanceID (~> 3.0) - - GoogleToolboxForMac/Logger (~> 2.1) + - FirebaseAnalyticsInterop (1.4.0) + - FirebaseCore (6.0.2): + - GoogleUtilities/Environment (~> 6.0) + - GoogleUtilities/Logger (~> 6.0) + - FirebaseInstanceID (4.2.6): + - FirebaseCore (~> 6.0) + - GoogleUtilities/Environment (~> 6.0) + - GoogleUtilities/UserDefaults (~> 6.0) + - FirebaseMessaging (4.0.2): + - FirebaseAnalyticsInterop (~> 1.1) + - FirebaseCore (~> 6.0) + - FirebaseInstanceID (~> 4.1) + - GoogleUtilities/AppDelegateSwizzler (~> 6.2) + - GoogleUtilities/Environment (~> 6.2) + - GoogleUtilities/Reachability (~> 6.2) + - GoogleUtilities/UserDefaults (~> 6.2) - Protobuf (~> 3.1) - FLAnimatedImage (1.0.12) - Folly (2018.10.22.00): @@ -48,11 +66,32 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - GoogleToolboxForMac/Defines (2.2.2) - - GoogleToolboxForMac/Logger (2.2.2): - - GoogleToolboxForMac/Defines (= 2.2.2) - - "GoogleToolboxForMac/NSData+zlib (2.2.2)": - - GoogleToolboxForMac/Defines (= 2.2.2) + - GoogleAppMeasurement (6.0.1): + - GoogleUtilities/AppDelegateSwizzler (~> 6.0) + - GoogleUtilities/MethodSwizzler (~> 6.0) + - GoogleUtilities/Network (~> 6.0) + - "GoogleUtilities/NSData+zlib (~> 6.0)" + - nanopb (~> 0.3) + - GoogleUtilities/AppDelegateSwizzler (6.3.1): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (6.3.1) + - GoogleUtilities/Logger (6.3.1): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (6.3.1): + - GoogleUtilities/Logger + - GoogleUtilities/Network (6.3.1): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (6.3.1)" + - GoogleUtilities/Reachability (6.3.1): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (6.3.1): + - GoogleUtilities/Logger + - JWT (3.0.0-beta.12): + - Base64 (~> 1.1.2) - libwebp (1.0.3): - libwebp/demux (= 1.0.3) - libwebp/mux (= 1.0.3) @@ -62,11 +101,11 @@ PODS: - libwebp/mux (1.0.3): - libwebp/demux - libwebp/webp (1.0.3) - - nanopb (0.3.904): - - nanopb/decode (= 0.3.904) - - nanopb/encode (= 0.3.904) - - nanopb/decode (0.3.904) - - nanopb/encode (0.3.904) + - nanopb (0.3.9011): + - nanopb/decode (= 0.3.9011) + - nanopb/encode (= 0.3.9011) + - nanopb/decode (0.3.9011) + - nanopb/encode (0.3.9011) - Protobuf (3.10.0) - RCTRequired (0.61.2) - RCTTypeSafety (0.61.2): @@ -241,10 +280,18 @@ PODS: - React - react-native-camera/RN (2.11.2): - React - - react-native-netinfo (4.4.0): + - react-native-mail (3.0.7): + - React + - react-native-netinfo (4.6.0): + - React + - react-native-randombytes (3.5.3): - React - react-native-safe-area-context (0.5.0): - React + - react-native-splash-screen (3.2.0): + - React + - react-native-udp (2.6.1): + - React - react-native-version-number (0.3.6): - React - React-RCTActionSheet (0.61.2): @@ -282,12 +329,14 @@ PODS: - React-cxxreact (= 0.61.2) - React-jsi (= 0.61.2) - ReactCommon/jscallinvoker (= 0.61.2) + - ReactNativePermissions (1.2.1): + - React - RNAnalytics (1.1.0): - Analytics - React - RNCAsyncStorage (1.6.2): - React - - RNCMaskedView (0.1.1): + - RNCMaskedView (0.1.4): - React - RNDeviceInfo (2.3.2): - React @@ -295,33 +344,60 @@ PODS: - React - SDWebImage (~> 5.0) - SDWebImageWebPCoder (~> 0.2.3) - - RNIOS11DeviceCheck (0.0.3): + - RNFirebase (5.5.6): + - Firebase/Core + - React + - RNFirebase/Crashlytics (= 5.5.6) + - RNFirebase/Crashlytics (5.5.6): + - Crashlytics + - Fabric + - Firebase/Core + - React + - RNGestureHandler (1.5.0): + - React + - RNKeychain (3.1.3): - React - RNLanguages (3.0.2): - React + - RNOS (1.1.0): + - React + - RNReactNativeHapticFeedback (1.8.2): + - React - RNReanimated (1.3.0): - React - RNScreens (1.0.0-alpha.23): - React - RNStoreReview (0.1.5): - React - - SDWebImage (5.2.3): - - SDWebImage/Core (= 5.2.3) - - SDWebImage/Core (5.2.3) + - RNSVG (9.10.1): + - React + - SDWebImage (5.2.5): + - SDWebImage/Core (= 5.2.5) + - SDWebImage/Core (5.2.5) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) + - SRSRadialGradient (1.0.0): + - React + - SSZipArchive (2.2.2) + - TcpSockets (3.3.2): + - React + - ToolTipMenu (5.2.1): + - React + - TouchID (4.4.1): + - React - Yoga (1.14.0) DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) + - CodePush (from `../node_modules/react-native-code-push`) - Crashlytics (~> 3.10.7) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - Fabric (~> 1.7.11) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) - - Firebase/Core (~> 5.3.0) - - Firebase/Messaging (~> 5.3.0) + - Firebase/Core (~> 6.2.0) + - Firebase/Messaging (~> 6.2.0) - FLAnimatedImage - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) @@ -339,8 +415,12 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-camera (from `../node_modules/react-native-camera`) + - react-native-mail (from `../node_modules/react-native-mail`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" + - react-native-randombytes (from `../node_modules/react-native-randombytes`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) + - react-native-splash-screen (from `../node_modules/react-native-splash-screen`) + - react-native-udp (from `../node_modules/react-native-udp`) - react-native-version-number (from `../node_modules/react-native-version-number`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -353,40 +433,57 @@ DEPENDENCIES: - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - ReactNativePermissions (from `../node_modules/react-native-permissions`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNFastImage (from `../node_modules/react-native-fast-image`) - - RNIOS11DeviceCheck (from `../node_modules/react-native-ios11-devicecheck/ios`) + - RNFirebase (from `../node_modules/react-native-firebase/ios`) + - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNKeychain (from `../node_modules/react-native-keychain`) - RNLanguages (from `../node_modules/react-native-languages`) + - RNOS (from `../node_modules/react-native-os`) + - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNStoreReview (from `../node_modules/react-native-store-review/ios`) + - RNSVG (from `../node_modules/react-native-svg`) + - SRSRadialGradient (from `../node_modules/react-native-radial-gradient/ios`) + - TcpSockets (from `../node_modules/react-native-tcp`) + - ToolTipMenu (from `../node_modules/react-native-tooltip`) + - TouchID (from `../node_modules/react-native-touch-id`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: trunk: - Analytics + - Base64 - boost-for-react-native - Crashlytics - Fabric - Firebase - FirebaseAnalytics + - FirebaseAnalyticsInterop - FirebaseCore - FirebaseInstanceID - FirebaseMessaging - FLAnimatedImage - - GoogleToolboxForMac + - GoogleAppMeasurement + - GoogleUtilities + - JWT - libwebp - nanopb - Protobuf - SDWebImage - SDWebImageWebPCoder + - SSZipArchive EXTERNAL SOURCES: BVLinearGradient: :path: "../node_modules/react-native-linear-gradient" + CodePush: + :path: "../node_modules/react-native-code-push" DoubleConversion: :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" FBLazyVector: @@ -419,10 +516,18 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/blur" react-native-camera: :path: "../node_modules/react-native-camera" + react-native-mail: + :path: "../node_modules/react-native-mail" react-native-netinfo: :path: "../node_modules/@react-native-community/netinfo" + react-native-randombytes: + :path: "../node_modules/react-native-randombytes" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" + react-native-splash-screen: + :path: "../node_modules/react-native-splash-screen" + react-native-udp: + :path: "../node_modules/react-native-udp" react-native-version-number: :path: "../node_modules/react-native-version-number" React-RCTActionSheet: @@ -445,6 +550,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Vibration" ReactCommon: :path: "../node_modules/react-native/ReactCommon" + ReactNativePermissions: + :path: "../node_modules/react-native-permissions" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -455,39 +562,62 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-device-info" RNFastImage: :path: "../node_modules/react-native-fast-image" - RNIOS11DeviceCheck: - :path: "../node_modules/react-native-ios11-devicecheck/ios" + RNFirebase: + :path: "../node_modules/react-native-firebase/ios" + RNGestureHandler: + :path: "../node_modules/react-native-gesture-handler" + RNKeychain: + :path: "../node_modules/react-native-keychain" RNLanguages: :path: "../node_modules/react-native-languages" + RNOS: + :path: "../node_modules/react-native-os" + RNReactNativeHapticFeedback: + :path: "../node_modules/react-native-haptic-feedback" RNReanimated: :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" RNStoreReview: :path: "../node_modules/react-native-store-review/ios" + RNSVG: + :path: "../node_modules/react-native-svg" + SRSRadialGradient: + :path: "../node_modules/react-native-radial-gradient/ios" + TcpSockets: + :path: "../node_modules/react-native-tcp" + ToolTipMenu: + :path: "../node_modules/react-native-tooltip" + TouchID: + :path: "../node_modules/react-native-touch-id" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: Analytics: 77fd5fb102a4a5eedafa2c2b0245ceb7b7c15e45 + Base64: cecfb41a004124895a7bcee567a89bae5a89d49b boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 + CodePush: d2e54ad42df82a8db65b2d23d8191b950ba945e1 Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 FBLazyVector: 68b6a76960fbd8ecd9fb7ce0aadd3329c3340a99 FBReactNativeSpec: 5a764c60abdc3336a213e5310c40b74741f32839 - Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa - FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2 - FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0 - FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6 - FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb + Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e + FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 + FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 + FirebaseCore: b0f0262acebfa540e5f97b3832dbb13186980822 + FirebaseInstanceID: d0eafcd8bdbd3447cd694594734078c3e3e77d8b + FirebaseMessaging: 20b6626c41be7840aed7a3dd9a14003efae3d588 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - GoogleToolboxForMac: 800648f8b3127618c1b59c7f97684427630c5ea3 + GoogleAppMeasurement: 51d8d9ea48f0ca44484d29cfbdef976fbd4fc336 + GoogleUtilities: f895fde57977df4e0233edda0dbeac490e3703b6 + JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e - nanopb: 06f6030d554e6473f5e172460173fcf80f5548f4 + nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b RCTRequired: c639d59ed389cfb1f1203f65c2ea946d8ec586e2 RCTTypeSafety: dc23fb655d6c77667c78e327bf661bc11e3b8aec @@ -500,8 +630,12 @@ SPEC CHECKSUMS: React-jsinspector: 111d7d342b07a904c400592e02a2b958f1098b60 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e - react-native-netinfo: 6bb847e64f45a2d69c6173741111cfd95c669301 + react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 + react-native-netinfo: fa32a5bb986924e9be82a261c262039042dde81e + react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d + react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 + react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f React-RCTActionSheet: 89b037c0fb7d2671607cb645760164e7e0c013f6 React-RCTAnimation: e3cefa93c38c004c318f7ec04b883eb14b8b8235 @@ -513,20 +647,31 @@ SPEC CHECKSUMS: React-RCTText: e3ef6191cdb627855ff7fe8fa0c1e14094967fb8 React-RCTVibration: fb54c732fd20405a76598e431aa2f8c2bf527de9 ReactCommon: 5848032ed2f274fcb40f6b9ec24067787c42d479 + ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f - RNCMaskedView: b79e193409a90bf6b5170d421684f437ff4e2278 + RNCMaskedView: 58f45cb9a3161160d992f98541ab3739883dcb41 RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 - RNIOS11DeviceCheck: a4a545fdd08230a17a8ce7608e95038ee23a32aa + RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 + RNGestureHandler: a4ddde1ffc6e590c8127b8b7eabfdade45475c74 + RNKeychain: c658833a9cb2cbcba6423bdd6e16cce59e27da0e RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e + RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a + RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - SDWebImage: 46a7f73228f84ce80990c786e4372cf4db5875ce + RNSVG: b5c2b84eba69007aa744d12f6f564c1d98d352d8 + SDWebImage: 4eabf2fa6695c95c47724214417a9c036c965e4a SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 + SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec + SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 + TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 + ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 + TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 Yoga: 14927e37bd25376d216b150ab2a561773d57911f -PODFILE CHECKSUM: a039fce385962c5aff74e63f1df4ed5302b9aa01 +PODFILE CHECKSUM: 94f1de4711040f874d0ddbdd66a5eb381627c8ed COCOAPODS: 1.8.4 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index ba3472ce3fc..96740298191 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -7,30 +7,22 @@ objects = { /* Begin PBXBuildFile section */ - 00E356F31AD99517003FC87E /* RainbowTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RainbowTests.m */; }; 03252948A60F4C4C87E4FD9E /* SF-Pro-Display-Ultralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */; }; 06B78001D9F2456D9C2D4A86 /* Graphik-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */; }; - 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */; }; 0AB30EE90F554EE59F57DFC1 /* SF-Pro-Display-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */; }; + 0E56AA9A8843EB50FA4BDD4F /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */; }; 0F4372360E744AF4B37EB905 /* Graphik-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D755E71324B04FEE9C691D14 /* libRNFirebase.a */; }; 16934DFE7F154B06ADAD8A0B /* SF-Pro-Display-ThinItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */; }; 184EB33331FB47F2960D2507 /* SF-Pro-Display-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */; }; - 1A048DFD2F724753902EA40B /* libRNReactNativeHapticFeedback.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D13995EB48584C438A10A161 /* libRNReactNativeHapticFeedback.a */; }; 1AE1684BFC3E487F99128043 /* SF-Pro-Display-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9165B952731E4502857CC0B4 /* SF-Pro-Display-Regular.otf */; }; 1B1113DAF261410889D80146 /* SF-Pro-Display-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */; }; 216C17A836F44ACE8D79ACC7 /* SF-Pro-Display-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */; }; - 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */; }; 23320186D7F747FEB02451C6 /* SF-Pro-Text-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */; }; - 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B86CB964E3AA47029988138C /* libRNKeychain.a */; }; 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; }; - 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24979E7B20F84004007EB0DA /* FirebaseInstanceID.framework */; }; 24979E8920F84250007EB0DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24979E7720F84004007EB0DA /* GoogleService-Info.plist */; }; 26095B12C30047F89592D463 /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */; }; 2D7BB74FB1A44EE2A2426373 /* SF-Pro-Text-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = E672AB1C5404435897615660 /* SF-Pro-Text-Light.otf */; }; @@ -41,32 +33,24 @@ 396C4BA42EEC4D0985CEBB42 /* SF-Pro-Text-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */; }; 3C363E14D5DE4A028E43EA38 /* SF-Pro-Display-UltralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */; }; 3C41C1415A994234A0FF2589 /* SF-Pro-Text-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */; }; + 3D5D4DF2FD7C44EE962100E3 /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0642ECCC7CB044FDB5A3CC32 /* libRNTextInputMask.a */; }; 4013198EBD3D4D6F8052D25E /* SF-Pro-Display-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */; }; 41804DE52CE94296995264E0 /* SF-Pro-Text-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */; }; 424410A1E84845328C5A0CAB /* Graphik-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */; }; 431D3F0FC92B45A7A0B2476B /* Graphik-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 88A5866DBF924C149CA0C6F4 /* Graphik-Semibold.otf */; }; - 4433A04AF3E942A2894B3933 /* libRNOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CCCB016071412E994DFF61 /* libRNOS.a */; }; - 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C1324455238847F2AD5C08B4 /* libBVLinearGradient.a */; }; - 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */; }; 549287401A7648CCB32F36E0 /* SF-Pro-Display-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */; }; 5D1949044DCB413FBE7AE82E /* SFMono-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */; }; 5F34DEED060F41878C4C5A59 /* SFMono-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */; }; 66620AB752074CB6938E956A /* Graphik-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */; }; 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; - 6E37C5716EC449C1B63D0E06 /* libTouchID.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E0A11D8843045ECB80C6AB8 /* libTouchID.a */; }; 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; - 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; - 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */; }; 872630C5E4CA448D8DDC783E /* Graphik-Extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */; }; 8B7F7FDAB33B4D119E087D57 /* Graphik-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */; }; 8FB4C0E7FE3240F2B2D23CE2 /* SFMono-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8789D635428240B5ABF282EE /* SFMono-Bold.otf */; }; - 91959ACCE81B4C128AAC8154 /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B98C0A69B3614C65B194BC68 /* libRNSVG.a */; }; 9274E6415DE5403A855B59A4 /* Graphik-SuperItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 51E41940863B4B88BDEF48D7 /* Graphik-SuperItalic.otf */; }; 92D7BFC8AFDA4E649EA6FF08 /* SFMono-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */; }; - 94822FBFCA7246168685FA85 /* libRNMail.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45B0EAA273D24F15B885A97D /* libRNMail.a */; }; 96E52368EDC94B9B80D1F29C /* SF-Pro-Text-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */; }; - 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EA95F99E656542F790F685B6 /* libSplashScreen.a */; }; 9E8553031AD44F52A814F2AB /* SF-Pro-Display-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */; }; AE47B46652EA48AFB68E7832 /* SF-Pro-Text-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */; }; AFCABA638327463693E67FD4 /* SF-Pro-Text-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */; }; @@ -80,501 +64,33 @@ C66451ECC2944B439E123CF2 /* SF-Pro-Display-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */; }; CAD3BF43528D47159190E17B /* SF-Pro-Display-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */; }; CB988C526B0C48FC9750A038 /* SF-Pro-Display-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */; }; - D77132C4B96040C39FED1AD5 /* libUdpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5AC94663BD4242A29273D66F /* libUdpSockets.a */; }; + D6A5F5CB2369A22A009BEF29 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; DBBDEB86E54044EE8712C882 /* Graphik-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEC826911B5641B8AF788BB3 /* Graphik-BlackItalic.otf */; }; E98BBF45029948B38545996F /* Graphik-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = E6F010E529544E518E1792C7 /* Graphik-Bold.otf */; }; - EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 91A43F69E797469687978D51 /* libRNStoreReview.a */; }; - ECF14FECD39C459D86EDCB82 /* libCodePush.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E39434CDDE4C54848FBFD5 /* libCodePush.a */; }; ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; }; - ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A014AE1645874354A732EB35 /* libToolTipMenu.a */; }; - F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D1A86E696CA24D4F9D3F7F0F /* libz.tbd */; }; - F4E8A17A670147F4A5EC177E /* libRNGestureHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A7E5E09E14B4EA4B52CC6EE /* libRNGestureHandler.a */; }; - F643BEEE1F9445C7932B2A75 /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */; }; F9EB9219ED9A4C72826A5908 /* Graphik-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */; }; F9EF1D44351840B8A380BD3E /* SF-Pro-Display-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */; }; FBDF4EF177284CF4826D7BF9 /* SF-Pro-Display-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D7BFD847B72D414D9BE734A0 /* SF-Pro-Display-HeavyItalic.otf */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { + D6A5F5F12369A413009BEF29 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTActionSheet; - }; - 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5115D1A9E6B3D00147676; - remoteInfo = RCTImage; - }; - 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B511DB1A9E6C8500147676; - remoteInfo = RCTNetwork; - }; - 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; - remoteInfo = RCTVibration; - }; - 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13B07F861A680F5B00A75B9A; - remoteInfo = Rainbow; - }; - 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTSettings; - }; - 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3C86DF461ADF2C930047B81A; - remoteInfo = RCTWebSocket; - }; - 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; - remoteInfo = React; - }; - 243A893D225F092800A13C7E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 171CDF49E32841EDA7D557DB /* RNGestureHandler.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B5C32A36220C603B000FFB8D; - remoteInfo = "RNGestureHandler-tvOS"; - }; - 24402FE722D6D3800045D406 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3C39C266218BBE66004C763F /* FastImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = FD751C4D229EB44C002BE1F4; - remoteInfo = "FastImage-tvOS"; - }; - 244C64092108794F007A5856 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 1A7B7E90124047F8A3CA4B84 /* RNReactNativeHapticFeedback.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNReactNativeHapticFeedback; - }; - 247947BA22568EAA006BBF56 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EDEBC6D6214B3E7000DD5AC8; - remoteInfo = jsi; - }; - 247947BC22568EAA006BBF56 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EDEBC73B214B45A300DD5AC8; - remoteInfo = jsiexecutor; - }; - 247947BE22568EAA006BBF56 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = ED296FB6214C9A0900B7C4FE; - remoteInfo = "jsi-tvOS"; - }; - 247947C022568EAA006BBF56 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = ED296FEE214C9CF800B7C4FE; - remoteInfo = "jsiexecutor-tvOS"; - }; - 2481F3202261753900D0349A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C779B11FB4664662AD0EBEA6 /* RNFirebase.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNFirebase; - }; - 2488BC2C22E97316006847C7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNStoreReview; - }; - 24979D5C20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = BVLinearGradient; - }; - 24979D5E20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 64AA15081EF7F30100718508; - remoteInfo = "BVLinearGradient-tvOS"; - }; - 24979D6720F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 02CF70769C034001B5CBC1EF /* ReactNativePermissions.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 9D23B34F1C767B80008B4819; - remoteInfo = ReactNativePermissions; - }; - 24979D6D20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNFIRMessaging; - }; - 24979D7120F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 50B1B80F51614673AFD8A804 /* RNKeychain.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 5D82366F1B0CE05B005A9EF3; - remoteInfo = RNKeychain; - }; - 24979D7320F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 50B1B80F51614673AFD8A804 /* RNKeychain.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 6478985F1F38BF9100DA1C12; - remoteInfo = "RNKeychain-tvOS"; - }; - 24979D7720F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 46FEDE7F1AFF192F00D3261C; - remoteInfo = RNMail; - }; - 24979D7920F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 46FEDE8A1AFF192F00D3261C; - remoteInfo = RNMailTests; - }; - 24979D7C20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNOS; - }; - 24979D8020F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 73EEC9391BFE4B1D00D468EB; - remoteInfo = RNRandomBytes; - }; - 24979D8220F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 163CDE4E2087CAD3001065FB; - remoteInfo = "RNRandomBytes-tvOS"; - }; - 24979D8920F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 0CF68AC11AF0540F00FF9E5C; - remoteInfo = RNSVG; - }; - 24979D8B20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 94DDAC5C1F3D024300EED511; - remoteInfo = "RNSVG-tvOS"; - }; - 24979D8E20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 2DB932A7706945C787DE22A6 /* SplashScreen.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D7682761D8E76B80014119E; - remoteInfo = SplashScreen; - }; - 24979D9120F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 137BEEE47D2E4F7AB452C0BD /* SRSRadialGradient.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = SRSRadialGradient; - }; - 24979D9420F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 35B7B17127FD476C81EA97E3 /* TcpSockets.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = TcpSockets; - }; - 24979D9820F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 4681C0211B05271A004D67D4; - remoteInfo = ToolTipMenu; - }; - 24979D9A20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 4681C02C1B05271A004D67D4; - remoteInfo = ToolTipMenuTests; - }; - 24979D9D20F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = TouchID; - }; - 24979DA020F83E3E007EB0DA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = UdpSockets; - }; - 249E5FD822613ABC0095F6B7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 249E5FA722613ABC0095F6B7 /* RNCAsyncStorage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNCAsyncStorage; - }; - 24D171E1212F57110090F180 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 171CDF49E32841EDA7D557DB /* RNGestureHandler.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNGestureHandler; - }; - 2C867629211152560067D47A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = CodePush; - }; - 2C86762B211152560067D47A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F886647B1F4ADB500036D01B; - remoteInfo = "CodePush-tvOS"; - }; - 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = ADD01A681E09402E00F6D226; - remoteInfo = "RCTBlob-tvOS"; - }; - 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EBF21BDC1FC498900052F4D5; - remoteInfo = jsinspector; - }; - 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5; - remoteInfo = "jsinspector-tvOS"; - }; - 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7; - remoteInfo = "third-party"; - }; - 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D383D3C1EBD27B6005632C8; - remoteInfo = "third-party-tvOS"; - }; - 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 139D7E881E25C6D100323FB7; - remoteInfo = "double-conversion"; - }; - 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D383D621EBD27B9005632C8; - remoteInfo = "double-conversion-tvOS"; - }; - 3C39C26F218BBE66004C763F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3C39C266218BBE66004C763F /* FastImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A287971D1DE0C0A60081BDFA; - remoteInfo = FastImage; - }; - 3CD4E8CC216989E8000FA5BD /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 137BEEE47D2E4F7AB452C0BD /* SRSRadialGradient.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 47413E2820DBB5D000CCDA85; - remoteInfo = "SRSRadialGradien-tvOS"; - }; - 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A283A1D9B042B00D4039D; - remoteInfo = "RCTImage-tvOS"; - }; - 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28471D9B043800D4039D; - remoteInfo = "RCTLinking-tvOS"; - }; - 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28541D9B044C00D4039D; - remoteInfo = "RCTNetwork-tvOS"; - }; - 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28611D9B046600D4039D; - remoteInfo = "RCTSettings-tvOS"; - }; - 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A287B1D9B048500D4039D; - remoteInfo = "RCTText-tvOS"; - }; - 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28881D9B049200D4039D; - remoteInfo = "RCTWebSocket-tvOS"; - }; - 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28131D9B038B00D4039D; - remoteInfo = "React-tvOS"; - }; - 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3C059A1DE3340900C268FA; - remoteInfo = yoga; - }; - 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3C06751DE3340C00C268FA; - remoteInfo = "yoga-tvOS"; - }; - 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4; - remoteInfo = cxxreact; - }; - 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4; - remoteInfo = "cxxreact-tvOS"; - }; - 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTAnimation; - }; - 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28201D9B03D100D4039D; - remoteInfo = "RCTAnimation-tvOS"; - }; - 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTLinking; - }; - 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5119B1A9E6C1200147676; - remoteInfo = RCTText; - }; - AA24D00F235EB5550082BA9B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */; + containerPortal = 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */; proxyType = 2; remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RNTextInputMask; }; - ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 358F4ED71D1E81A9004DF814; - remoteInfo = RCTBlob; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 24122D56232F2B3300BA0B17 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; dstPath = ""; dstSubfolderSpec = 10; files = ( - 24122D55232F2B3200BA0B17 /* InputMask.framework in Embed Frameworks */, + D6A5F5CB2369A22A009BEF29 /* InputMask.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -583,19 +99,10 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; - 00E356EE1AD99517003FC87E /* RainbowTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RainbowTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* RainbowTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RainbowTests.m; sourceTree = ""; }; - 02CF70769C034001B5CBC1EF /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = ""; }; + 0642ECCC7CB044FDB5A3CC32 /* libRNTextInputMask.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNTextInputMask.a; sourceTree = ""; }; 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Heavy.otf"; path = "../src/assets/fonts/SFMono-Heavy.otf"; sourceTree = ""; }; - 0E0889DFA1224AA48F1A5301 /* libRNRandomBytes-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNRandomBytes-tvOS.a"; sourceTree = ""; }; - 137BEEE47D2E4F7AB452C0BD /* SRSRadialGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = SRSRadialGradient.xcodeproj; path = "../node_modules/react-native-radial-gradient/ios/SRSRadialGradient.xcodeproj"; sourceTree = ""; }; - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* Rainbow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rainbow.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Rainbow/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Rainbow/AppDelegate.m; sourceTree = ""; }; @@ -603,15 +110,10 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Rainbow/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Rainbow/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Rainbow/main.m; sourceTree = ""; }; - 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 15B240C971E54630F3158955 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; - 171CDF49E32841EDA7D557DB /* RNGestureHandler.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNGestureHandler.xcodeproj; path = "../node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj"; sourceTree = ""; }; 1736F851327A41C3815212E7 /* SF-Pro-Text-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-BoldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-BoldItalic.otf"; sourceTree = ""; }; 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-RegularItalic.otf"; path = "../src/assets/fonts/Graphik-RegularItalic.otf"; sourceTree = ""; }; - 1A7B7E90124047F8A3CA4B84 /* RNReactNativeHapticFeedback.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNReactNativeHapticFeedback.xcodeproj; path = "../node_modules/react-native-haptic-feedback/ios/RNReactNativeHapticFeedback.xcodeproj"; sourceTree = ""; }; 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-HeavyItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-HeavyItalic.otf"; sourceTree = ""; }; - 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ToolTipMenu.xcodeproj; path = "../node_modules/react-native-tooltip/ToolTipMenu.xcodeproj"; sourceTree = ""; }; - 22E39434CDDE4C54848FBFD5 /* libCodePush.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libCodePush.a; sourceTree = ""; }; 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Text-Heavy.otf"; sourceTree = ""; }; 24122D53232F2B3200BA0B17 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24979E3620F84003007EB0DA /* Protobuf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Protobuf.framework; path = Frameworks/Protobuf.framework; sourceTree = ""; }; @@ -626,94 +128,60 @@ 24979E7C20F84004007EB0DA /* FirebaseCoreDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCoreDiagnostics.framework; path = Frameworks/FirebaseCoreDiagnostics.framework; sourceTree = ""; }; 24979E7D20F84005007EB0DA /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = module.modulemap; path = Frameworks/module.modulemap; sourceTree = ""; }; 24979E7E20F84005007EB0DA /* nanopb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = nanopb.framework; path = Frameworks/nanopb.framework; sourceTree = ""; }; - 249E5FA722613ABC0095F6B7 /* RNCAsyncStorage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNCAsyncStorage.xcodeproj; path = "../node_modules/@react-native-community/async-storage/ios/RNCAsyncStorage.xcodeproj"; sourceTree = ""; }; 24A867FF226181F9005DCF78 /* libFirebaseInstanceID.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libFirebaseInstanceID.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 25992DBB7F97481A95784B0F /* RNMailTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = RNMailTests.xctest; sourceTree = ""; }; 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ExtralightItalic.otf"; path = "../src/assets/fonts/Graphik-ExtralightItalic.otf"; sourceTree = ""; }; - 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNRandomBytes.xcodeproj; path = "../node_modules/react-native-randombytes/RNRandomBytes.xcodeproj"; sourceTree = ""; }; 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Display-Medium.otf"; sourceTree = ""; }; 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Light.otf"; path = "../src/assets/fonts/SFMono-Light.otf"; sourceTree = ""; }; 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-MediumItalic.otf"; path = "../src/assets/fonts/Graphik-MediumItalic.otf"; sourceTree = ""; }; - 2DB932A7706945C787DE22A6 /* SplashScreen.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = SplashScreen.xcodeproj; path = "../node_modules/react-native-splash-screen/ios/SplashScreen.xcodeproj"; sourceTree = ""; }; - 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSRSRadialGradient.a; sourceTree = ""; }; - 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNStoreReview.xcodeproj; path = "../node_modules/react-native-store-review/ios/RNStoreReview.xcodeproj"; sourceTree = ""; }; 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-MediumItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-MediumItalic.otf"; sourceTree = ""; }; 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Ultralight.otf"; path = "../src/assets/fonts/SF-Pro-Display-Ultralight.otf"; sourceTree = ""; }; 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Text-Medium.otf"; sourceTree = ""; }; - 35B7B17127FD476C81EA97E3 /* TcpSockets.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = TcpSockets.xcodeproj; path = "../node_modules/react-native-tcp/ios/TcpSockets.xcodeproj"; sourceTree = ""; }; - 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSVG.xcodeproj; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = ""; }; - 3A7E5E09E14B4EA4B52CC6EE /* libRNGestureHandler.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNGestureHandler.a; sourceTree = ""; }; 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Rainbow.entitlements; path = Rainbow/Rainbow.entitlements; sourceTree = ""; }; - 3C39C266218BBE66004C763F /* FastImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FastImage.xcodeproj; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = ""; }; 3CC4B790228B298400D827EB /* libSDWebImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSDWebImage.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D5210FEA8F00672599 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D7210FEACE00672599 /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-ThinItalic.otf"; path = "../src/assets/fonts/Graphik-ThinItalic.otf"; sourceTree = ""; }; - 45B0EAA273D24F15B885A97D /* libRNMail.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNMail.a; sourceTree = ""; }; - 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = UdpSockets.xcodeproj; path = "../node_modules/react-native-udp/ios/UdpSockets.xcodeproj"; sourceTree = ""; }; - 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = CodePush.xcodeproj; path = "../node_modules/react-native-code-push/ios/CodePush.xcodeproj"; sourceTree = ""; }; - 50B1B80F51614673AFD8A804 /* RNKeychain.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNKeychain.xcodeproj; path = "../node_modules/react-native-keychain/RNKeychain.xcodeproj"; sourceTree = ""; }; - 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = ""; }; 51E41940863B4B88BDEF48D7 /* Graphik-SuperItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-SuperItalic.otf"; path = "../src/assets/fonts/Graphik-SuperItalic.otf"; sourceTree = ""; }; 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Semibold.otf"; path = "../src/assets/fonts/SF-Pro-Display-Semibold.otf"; sourceTree = ""; }; - 5AC94663BD4242A29273D66F /* libUdpSockets.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libUdpSockets.a; sourceTree = ""; }; - 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; + 6613987F23689A430097D1D5 /* libReact-Core.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libReact-Core.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6613988123689A430097D1D5 /* libReact-CoreModules.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libReact-CoreModules.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6613988323689A430097D1D5 /* libReact-cxxreact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libReact-cxxreact.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6613988523689A430097D1D5 /* libReact-jsi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libReact-jsi.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 66139B432368A9AE0097D1D5 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libRNFirebase.a; sourceTree = BUILT_PRODUCTS_DIR; }; 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Thin.otf"; path = "../src/assets/fonts/SF-Pro-Display-Thin.otf"; sourceTree = ""; }; 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Medium.otf"; path = "../src/assets/fonts/SFMono-Medium.otf"; sourceTree = ""; }; 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; - 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTcpSockets.a; sourceTree = ""; }; 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-RegularItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-RegularItalic.otf"; sourceTree = ""; }; 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Black.otf"; path = "../src/assets/fonts/Graphik-Black.otf"; sourceTree = ""; }; - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; - 7A19C32218BC469EA9228F2E /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNSVG-tvOS.a"; sourceTree = ""; }; 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Light.otf"; path = "../src/assets/fonts/Graphik-Light.otf"; sourceTree = ""; }; 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Super.otf"; path = "../src/assets/fonts/Graphik-Super.otf"; sourceTree = ""; }; 7CEEDA7A68C24426BBAA8D77 /* Graphik-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-BoldItalic.otf"; path = "../src/assets/fonts/Graphik-BoldItalic.otf"; sourceTree = ""; }; - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; + 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-BoldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-BoldItalic.otf"; sourceTree = ""; }; 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-SemiboldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-SemiboldItalic.otf"; sourceTree = ""; }; 8789D635428240B5ABF282EE /* SFMono-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Bold.otf"; path = "../src/assets/fonts/SFMono-Bold.otf"; sourceTree = ""; }; 88A5866DBF924C149CA0C6F4 /* Graphik-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Semibold.otf"; path = "../src/assets/fonts/Graphik-Semibold.otf"; sourceTree = ""; }; - 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = BVLinearGradient.xcodeproj; path = "../node_modules/react-native-linear-gradient/BVLinearGradient.xcodeproj"; sourceTree = ""; }; - 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNRandomBytes.a; sourceTree = ""; }; 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Display-Heavy.otf"; sourceTree = ""; }; 9165B952731E4502857CC0B4 /* SF-Pro-Display-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Regular.otf"; path = "../src/assets/fonts/SF-Pro-Display-Regular.otf"; sourceTree = ""; }; - 91A43F69E797469687978D51 /* libRNStoreReview.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNStoreReview.a; sourceTree = ""; }; 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Extralight.otf"; path = "../src/assets/fonts/Graphik-Extralight.otf"; sourceTree = ""; }; 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Regular.otf"; path = "../src/assets/fonts/SF-Pro-Text-Regular.otf"; sourceTree = ""; }; 95F2888C850F40C8A26E083B /* SFMono-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Regular.otf"; path = "../src/assets/fonts/SFMono-Regular.otf"; sourceTree = ""; }; - 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = TouchID.xcodeproj; path = "../node_modules/react-native-touch-id/TouchID.xcodeproj"; sourceTree = ""; }; - 96CCCB016071412E994DFF61 /* libRNOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNOS.a; sourceTree = ""; }; 9DEADFA4826D4D0BAA950D21 /* libRNFIRMessaging.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFIRMessaging.a; sourceTree = ""; }; 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Light.otf"; path = "../src/assets/fonts/SF-Pro-Display-Light.otf"; sourceTree = ""; }; - 9E0A11D8843045ECB80C6AB8 /* libTouchID.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTouchID.a; sourceTree = ""; }; - A014AE1645874354A732EB35 /* libToolTipMenu.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libToolTipMenu.a; sourceTree = ""; }; A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Regular.otf"; path = "../src/assets/fonts/Graphik-Regular.otf"; sourceTree = ""; }; A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-SemiboldItalic.otf"; path = "../src/assets/fonts/Graphik-SemiboldItalic.otf"; sourceTree = ""; }; A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-BlackItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-BlackItalic.otf"; sourceTree = ""; }; AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Semibold.otf"; path = "../src/assets/fonts/SF-Pro-Text-Semibold.otf"; sourceTree = ""; }; - ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; - AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFIRMessaging.xcodeproj; path = "../node_modules/react-native-fcm/ios/RNFIRMessaging.xcodeproj"; sourceTree = ""; }; - B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; B0C692B061D7430D8194DC98 /* ToolTipMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ToolTipMenuTests.xctest; sourceTree = ""; }; - B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNTextInputMask.a; sourceTree = ""; }; B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Semibold.otf"; path = "../src/assets/fonts/SFMono-Semibold.otf"; sourceTree = ""; }; - B86CB964E3AA47029988138C /* libRNKeychain.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNKeychain.a; sourceTree = ""; }; - B98C0A69B3614C65B194BC68 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = ""; }; BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Bold.otf"; path = "../src/assets/fonts/SF-Pro-Display-Bold.otf"; sourceTree = ""; }; - BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNMail.xcodeproj; path = "../node_modules/react-native-mail/RNMail.xcodeproj"; sourceTree = ""; }; BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Black.otf"; path = "../src/assets/fonts/SF-Pro-Display-Black.otf"; sourceTree = ""; }; - BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNOS.xcodeproj; path = "../node_modules/react-native-os/ios/RNOS.xcodeproj"; sourceTree = ""; }; - C1324455238847F2AD5C08B4 /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = ""; }; C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-ThinItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-ThinItalic.otf"; sourceTree = ""; }; - C779B11FB4664662AD0EBEA6 /* RNFirebase.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFirebase.xcodeproj; path = "../node_modules/react-native-firebase/ios/RNFirebase.xcodeproj"; sourceTree = ""; }; CEC826911B5641B8AF788BB3 /* Graphik-BlackItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-BlackItalic.otf"; path = "../src/assets/fonts/Graphik-BlackItalic.otf"; sourceTree = ""; }; - D13995EB48584C438A10A161 /* libRNReactNativeHapticFeedback.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNReactNativeHapticFeedback.a; sourceTree = ""; }; D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-LightItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-LightItalic.otf"; sourceTree = ""; }; - D1A86E696CA24D4F9D3F7F0F /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; D518658CFF8B491991A06426 /* SF-Pro-Text-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-MediumItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-MediumItalic.otf"; sourceTree = ""; }; D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-LightItalic.otf"; path = "../src/assets/fonts/Graphik-LightItalic.otf"; sourceTree = ""; }; D755E71324B04FEE9C691D14 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFirebase.a; sourceTree = ""; }; @@ -725,7 +193,6 @@ E6F010E529544E518E1792C7 /* Graphik-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Bold.otf"; path = "../src/assets/fonts/Graphik-Bold.otf"; sourceTree = ""; }; E8E3CE2A4AD34CB991CD61EE /* SF-Pro-Display-LightItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-LightItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-LightItalic.otf"; sourceTree = ""; }; E93A96605FE51CFC31676801 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; - EA95F99E656542F790F685B6 /* libSplashScreen.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSplashScreen.a; sourceTree = ""; }; EB48DC1D46D449759B9C61D4 /* Graphik-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Thin.otf"; path = "../src/assets/fonts/Graphik-Thin.otf"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; @@ -734,82 +201,20 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 00E356EB1AD99517003FC87E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, - 2340D4240F794E6DACB53521 /* libRNKeychain.a in Frameworks */, - 45C6CAEFC1A04F3FB291BE53 /* libBVLinearGradient.a in Frameworks */, - 94822FBFCA7246168685FA85 /* libRNMail.a in Frameworks */, - 4433A04AF3E942A2894B3933 /* libRNOS.a in Frameworks */, - 24979E8620F84005007EB0DA /* FirebaseInstanceID.framework in Frameworks */, - 4AF3A1B2CEC540D7A1AF957C /* libReactNativePermissions.a in Frameworks */, - 7F911FD5E35D4FD99D48A61D /* libSRSRadialGradient.a in Frameworks */, - 22DD8F08F32047C280DFA368 /* libRNRandomBytes.a in Frameworks */, - 978F83D3C5E4491F9D9AC2C1 /* libSplashScreen.a in Frameworks */, - 91959ACCE81B4C128AAC8154 /* libRNSVG.a in Frameworks */, - 07F258CE8EB84A8A949D4580 /* libTcpSockets.a in Frameworks */, - ED8A2571BF074F6DB6D09045 /* libToolTipMenu.a in Frameworks */, - 6E37C5716EC449C1B63D0E06 /* libTouchID.a in Frameworks */, - D77132C4B96040C39FED1AD5 /* libUdpSockets.a in Frameworks */, - 1A048DFD2F724753902EA40B /* libRNReactNativeHapticFeedback.a in Frameworks */, - F4E8A17A670147F4A5EC177E /* libRNGestureHandler.a in Frameworks */, - ECF14FECD39C459D86EDCB82 /* libCodePush.a in Frameworks */, - F35098D973414A09939FB3F8 /* libz.tbd in Frameworks */, - 154AA73429B14ED4BC8E0C72 /* libRNFirebase.a in Frameworks */, - EA8076A8481B4CB4BBA566EF /* libRNStoreReview.a in Frameworks */, - 74FFC957AC7B953D0FDCB6DB /* libPods-Rainbow.a in Frameworks */, 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */, - F643BEEE1F9445C7932B2A75 /* libRNTextInputMask.a in Frameworks */, + 0E56AA9A8843EB50FA4BDD4F /* libPods-Rainbow.a in Frameworks */, + 3D5D4DF2FD7C44EE962100E3 /* libRNTextInputMask.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 00C302A81ABCB8CE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302BC1ABCB91800DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, - 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302D41ABCB9D200DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, - 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302E01ABCB9EE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, - ); - name = Products; - sourceTree = ""; - }; 00E356EF1AD99517003FC87E /* RainbowTests */ = { isa = PBXGroup; children = ( @@ -827,265 +232,40 @@ name = "Supporting Files"; sourceTree = ""; }; - 139105B71AF99BAD00B5F7CC /* Products */ = { + 13B07FAE1A68108700A75B9A /* Rainbow */ = { isa = PBXGroup; children = ( - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, - 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */, + 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */, + 008F07F21AC5B25A0029DE68 /* main.jsbundle */, + 13B07FAF1A68108700A75B9A /* AppDelegate.h */, + 13B07FB01A68108700A75B9A /* AppDelegate.m */, + 13B07FB51A68108700A75B9A /* Images.xcassets */, + 13B07FB61A68108700A75B9A /* Info.plist */, + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, + 13B07FB71A68108700A75B9A /* main.m */, ); - name = Products; - sourceTree = ""; - }; - 139FDEE71B06529A00C62182 /* Products */ = { - isa = PBXGroup; - children = ( - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, - 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 13B07FAE1A68108700A75B9A /* Rainbow */ = { - isa = PBXGroup; - children = ( - 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */, - 008F07F21AC5B25A0029DE68 /* main.jsbundle */, - 13B07FAF1A68108700A75B9A /* AppDelegate.h */, - 13B07FB01A68108700A75B9A /* AppDelegate.m */, - 13B07FB51A68108700A75B9A /* Images.xcassets */, - 13B07FB61A68108700A75B9A /* Info.plist */, - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, - 13B07FB71A68108700A75B9A /* main.m */, - ); - name = Rainbow; - sourceTree = ""; - }; - 146834001AC3E56700842450 /* Products */ = { - isa = PBXGroup; - children = ( - 146834041AC3E56700842450 /* libReact.a */, - 3DAD3EA31DF850E9000B6D8A /* libReact.a */, - 3DAD3EA51DF850E9000B6D8A /* libyoga.a */, - 3DAD3EA71DF850E9000B6D8A /* libyoga.a */, - 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */, - 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */, - 2DF0FFDF2056DD460020B375 /* libjsinspector.a */, - 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */, - 2DF0FFE32056DD460020B375 /* libthird-party.a */, - 2DF0FFE52056DD460020B375 /* libthird-party.a */, - 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */, - 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */, - 247947BB22568EAA006BBF56 /* libjsi.a */, - 247947BD22568EAA006BBF56 /* libjsiexecutor.a */, - 247947BF22568EAA006BBF56 /* libjsi-tvOS.a */, - 247947C122568EAA006BBF56 /* libjsiexecutor-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 244C64062108794F007A5856 /* Products */ = { - isa = PBXGroup; - children = ( - 244C640A2108794F007A5856 /* libRNReactNativeHapticFeedback.a */, - ); - name = Products; - sourceTree = ""; - }; - 2481F31D2261753900D0349A /* Products */ = { - isa = PBXGroup; - children = ( - 2481F3212261753900D0349A /* libRNFirebase.a */, - ); - name = Products; - sourceTree = ""; - }; - 2488BC2922E97315006847C7 /* Products */ = { - isa = PBXGroup; - children = ( - 2488BC2D22E97316006847C7 /* libRNStoreReview.a */, - ); - name = Products; + name = Rainbow; sourceTree = ""; }; 24979D1220F83E3D007EB0DA /* Recovered References */ = { isa = PBXGroup; children = ( 9DEADFA4826D4D0BAA950D21 /* libRNFIRMessaging.a */, - B86CB964E3AA47029988138C /* libRNKeychain.a */, - C1324455238847F2AD5C08B4 /* libBVLinearGradient.a */, - 45B0EAA273D24F15B885A97D /* libRNMail.a */, - 25992DBB7F97481A95784B0F /* RNMailTests.xctest */, - 96CCCB016071412E994DFF61 /* libRNOS.a */, - 51A0A7CFC45344D49BFF6CB9 /* libReactNativePermissions.a */, - 2FA917DDE3314475BABEC117 /* libSRSRadialGradient.a */, - 8C38066021DF4A73845E4A0F /* libRNRandomBytes.a */, - EA95F99E656542F790F685B6 /* libSplashScreen.a */, - B98C0A69B3614C65B194BC68 /* libRNSVG.a */, - 6747DC29E9EE446C8C2F7B76 /* libTcpSockets.a */, - A014AE1645874354A732EB35 /* libToolTipMenu.a */, B0C692B061D7430D8194DC98 /* ToolTipMenuTests.xctest */, - 9E0A11D8843045ECB80C6AB8 /* libTouchID.a */, - 5AC94663BD4242A29273D66F /* libUdpSockets.a */, - 0E0889DFA1224AA48F1A5301 /* libRNRandomBytes-tvOS.a */, - 7A19C32218BC469EA9228F2E /* libRNSVG-tvOS.a */, - D13995EB48584C438A10A161 /* libRNReactNativeHapticFeedback.a */, - 3A7E5E09E14B4EA4B52CC6EE /* libRNGestureHandler.a */, - 22E39434CDDE4C54848FBFD5 /* libCodePush.a */, D755E71324B04FEE9C691D14 /* libRNFirebase.a */, - 91A43F69E797469687978D51 /* libRNStoreReview.a */, - B0FE4F98AAFC420AAF52EFF0 /* libRNTextInputMask.a */, + 0642ECCC7CB044FDB5A3CC32 /* libRNTextInputMask.a */, ); name = "Recovered References"; sourceTree = ""; }; - 24979D3820F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D9520F83E3E007EB0DA /* libTcpSockets.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D3A20F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D9E20F83E3E007EB0DA /* libTouchID.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D3E20F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D6E20F83E3E007EB0DA /* libRNFIRMessaging.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4020F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D7220F83E3E007EB0DA /* libRNKeychain.a */, - 24979D7420F83E3E007EB0DA /* libRNKeychain.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4220F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D5D20F83E3E007EB0DA /* libBVLinearGradient.a */, - 24979D5F20F83E3E007EB0DA /* libBVLinearGradient.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4420F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D7820F83E3E007EB0DA /* libRNMail.a */, - 24979D7A20F83E3E007EB0DA /* RNMailTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4820F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D7D20F83E3E007EB0DA /* libRNOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4A20F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D6820F83E3E007EB0DA /* libReactNativePermissions.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4C20F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D9220F83E3E007EB0DA /* libSRSRadialGradient.a */, - 3CD4E8CD216989E8000FA5BD /* libSRSRadialGradien-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D4E20F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D8120F83E3E007EB0DA /* libRNRandomBytes.a */, - 24979D8320F83E3E007EB0DA /* libRNRandomBytes-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D5020F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D8F20F83E3E007EB0DA /* libSplashScreen.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D5420F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D8A20F83E3E007EB0DA /* libRNSVG.a */, - 24979D8C20F83E3E007EB0DA /* libRNSVG-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 24979D5620F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979D9920F83E3E007EB0DA /* libToolTipMenu.a */, - 24979D9B20F83E3E007EB0DA /* ToolTipMenuTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 24979D5820F83E3E007EB0DA /* Products */ = { - isa = PBXGroup; - children = ( - 24979DA120F83E3E007EB0DA /* libUdpSockets.a */, - ); - name = Products; - sourceTree = ""; - }; - 249E5FA822613ABC0095F6B7 /* Products */ = { - isa = PBXGroup; - children = ( - 249E5FD922613ABC0095F6B7 /* libRNCAsyncStorage.a */, - ); - name = Products; - sourceTree = ""; - }; - 24D171DE212F57100090F180 /* Products */ = { - isa = PBXGroup; - children = ( - 24D171E2212F57110090F180 /* libRNGestureHandler.a */, - 243A893E225F092800A13C7E /* libRNGestureHandler-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 2C867625211152550067D47A /* Products */ = { - isa = PBXGroup; - children = ( - 2C86762A211152560067D47A /* libCodePush.a */, - 2C86762C211152560067D47A /* libCodePush.a */, - ); - name = Products; - sourceTree = ""; - }; 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { isa = PBXGroup; children = ( + 66139B432368A9AE0097D1D5 /* libRNFirebase.a */, + 6613987F23689A430097D1D5 /* libReact-Core.a */, + 6613988123689A430097D1D5 /* libReact-CoreModules.a */, + 6613988323689A430097D1D5 /* libReact-cxxreact.a */, + 6613988523689A430097D1D5 /* libReact-jsi.a */, 3CC4B790228B298400D827EB /* libSDWebImage.a */, 24A867FF226181F9005DCF78 /* libFirebaseInstanceID.a */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */, @@ -1105,88 +285,19 @@ 24979E7E20F84005007EB0DA /* nanopb.framework */, 24979E3620F84003007EB0DA /* Protobuf.framework */, 2D16E6891FA4F8E400B85C8A /* libReact.a */, - D1A86E696CA24D4F9D3F7F0F /* libz.tbd */, 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */, ); name = Frameworks; sourceTree = ""; }; - 3C39C267218BBE66004C763F /* Products */ = { - isa = PBXGroup; - children = ( - 3C39C270218BBE66004C763F /* libFastImage.a */, - 24402FE822D6D3800045D406 /* libFastImage-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 5E91572E1DD0AC6500FF2AA8 /* Products */ = { - isa = PBXGroup; - children = ( - 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */, - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */, - ); - name = Products; - sourceTree = ""; - }; - 78C398B11ACF4ADC00677621 /* Products */ = { - isa = PBXGroup; - children = ( - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, - 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */, - 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */, - 3C39C266218BBE66004C763F /* FastImage.xcodeproj */, - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, - 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, - ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */, - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, - 146833FF1AC3E56700842450 /* React.xcodeproj */, - 02CF70769C034001B5CBC1EF /* ReactNativePermissions.xcodeproj */, - 249E5FA722613ABC0095F6B7 /* RNCAsyncStorage.xcodeproj */, - C779B11FB4664662AD0EBEA6 /* RNFirebase.xcodeproj */, - AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */, - 171CDF49E32841EDA7D557DB /* RNGestureHandler.xcodeproj */, - 50B1B80F51614673AFD8A804 /* RNKeychain.xcodeproj */, - BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */, - BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */, - 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */, - 1A7B7E90124047F8A3CA4B84 /* RNReactNativeHapticFeedback.xcodeproj */, - 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */, - 2DB932A7706945C787DE22A6 /* SplashScreen.xcodeproj */, - 137BEEE47D2E4F7AB452C0BD /* SRSRadialGradient.xcodeproj */, - 35B7B17127FD476C81EA97E3 /* TcpSockets.xcodeproj */, - 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */, - 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */, - 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */, - 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */, - B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */, + 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */, ); name = Libraries; sourceTree = ""; }; - 832341B11AAA6A8300B99B32 /* Products */ = { - isa = PBXGroup; - children = ( - 832341B51AAA6A8300B99B32 /* libRCTText.a */, - 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( @@ -1209,24 +320,6 @@ isa = PBXGroup; children = ( 13B07F961A680F5B00A75B9A /* Rainbow.app */, - 00E356EE1AD99517003FC87E /* RainbowTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - AA24D00C235EB5550082BA9B /* Products */ = { - isa = PBXGroup; - children = ( - AA24D010235EB5550082BA9B /* libRNTextInputMask.a */, - ); - name = Products; - sourceTree = ""; - }; - ADBDB9201DFEBF0600ED6528 /* Products */ = { - isa = PBXGroup; - children = ( - ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */, - 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */, ); name = Products; sourceTree = ""; @@ -1242,765 +335,158 @@ path = Pods; sourceTree = ""; }; + D6A5F5EE2369A413009BEF29 /* Products */ = { + isa = PBXGroup; + children = ( + D6A5F5F22369A413009BEF29 /* libRNTextInputMask.a */, + ); + name = Products; + sourceTree = ""; + }; DCAC1D8CC45E468FBB7E1395 /* Resources */ = { isa = PBXGroup; children = ( 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */, CEC826911B5641B8AF788BB3 /* Graphik-BlackItalic.otf */, E6F010E529544E518E1792C7 /* Graphik-Bold.otf */, - 7CEEDA7A68C24426BBAA8D77 /* Graphik-BoldItalic.otf */, - 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */, - 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */, - 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */, - D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */, - DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */, - 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */, - A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */, - 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */, - 88A5866DBF924C149CA0C6F4 /* Graphik-Semibold.otf */, - A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */, - 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */, - 51E41940863B4B88BDEF48D7 /* Graphik-SuperItalic.otf */, - EB48DC1D46D449759B9C61D4 /* Graphik-Thin.otf */, - 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */, - BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */, - A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */, - BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */, - 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */, - 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */, - D7BFD847B72D414D9BE734A0 /* SF-Pro-Display-HeavyItalic.otf */, - 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */, - E8E3CE2A4AD34CB991CD61EE /* SF-Pro-Display-LightItalic.otf */, - 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */, - 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */, - 9165B952731E4502857CC0B4 /* SF-Pro-Display-Regular.otf */, - D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */, - 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */, - 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */, - 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */, - C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */, - 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */, - DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */, - F62BBE10D6534F74B2180711 /* SF-Pro-Text-Bold.otf */, - 1736F851327A41C3815212E7 /* SF-Pro-Text-BoldItalic.otf */, - 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */, - 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */, - E672AB1C5404435897615660 /* SF-Pro-Text-Light.otf */, - D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */, - 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */, - D518658CFF8B491991A06426 /* SF-Pro-Text-MediumItalic.otf */, - 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */, - 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */, - AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */, - FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */, - 8789D635428240B5ABF282EE /* SFMono-Bold.otf */, - 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */, - 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */, - 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */, - 95F2888C850F40C8A26E083B /* SFMono-Regular.otf */, - B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */, - ); - name = Resources; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* RainbowTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RainbowTests" */; - buildPhases = ( - 00E356EA1AD99517003FC87E /* Sources */, - 00E356EB1AD99517003FC87E /* Frameworks */, - 00E356EC1AD99517003FC87E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 00E356F51AD99517003FC87E /* PBXTargetDependency */, - ); - name = RainbowTests; - productName = RainbowTests; - productReference = 00E356EE1AD99517003FC87E /* RainbowTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 13B07F861A680F5B00A75B9A /* Rainbow */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Rainbow" */; - buildPhases = ( - B448B1B66A188D3AC6DA3639 /* [CP] Check Pods Manifest.lock */, - 13B07F871A680F5B00A75B9A /* Sources */, - 13B07F8C1A680F5B00A75B9A /* Frameworks */, - 13B07F8E1A680F5B00A75B9A /* Resources */, - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 3CF823D3218F310D0024B77B /* ShellScript */, - 24122D56232F2B3300BA0B17 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Rainbow; - productName = "Hello World"; - productReference = 13B07F961A680F5B00A75B9A /* Rainbow.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 83CBB9F71A601CBA00E9B192 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 610; - ORGANIZATIONNAME = Facebook; - TargetAttributes = { - 00E356ED1AD99517003FC87E = { - CreatedOnToolsVersion = 6.2; - DevelopmentTeam = L74NQAQB8H; - ProvisioningStyle = Automatic; - TestTargetID = 13B07F861A680F5B00A75B9A; - }; - 13B07F861A680F5B00A75B9A = { - DevelopmentTeam = L74NQAQB8H; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Push = { - enabled = 1; - }; - com.apple.SafariKeychain = { - enabled = 1; - }; - }; - }; - }; - }; - buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Rainbow" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - Base, - ); - mainGroup = 83CBB9F61A601CBA00E9B192; - productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 24979D4220F83E3E007EB0DA /* Products */; - ProjectRef = 8AC83A50CE8F4EE782376063 /* BVLinearGradient.xcodeproj */; - }, - { - ProductGroup = 2C867625211152550067D47A /* Products */; - ProjectRef = 4A9E14039D3A4590A2F32D92 /* CodePush.xcodeproj */; - }, - { - ProductGroup = 3C39C267218BBE66004C763F /* Products */; - ProjectRef = 3C39C266218BBE66004C763F /* FastImage.xcodeproj */; - }, - { - ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; - ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - }, - { - ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */; - ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; - }, - { - ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */; - ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; - }, - { - ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; - ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - }, - { - ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; - ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - }, - { - ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; - ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - }, - { - ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; - ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - }, - { - ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; - ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - }, - { - ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; - ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - }, - { - ProductGroup = 139FDEE71B06529A00C62182 /* Products */; - ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - }, - { - ProductGroup = 146834001AC3E56700842450 /* Products */; - ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; - }, - { - ProductGroup = 24979D4A20F83E3E007EB0DA /* Products */; - ProjectRef = 02CF70769C034001B5CBC1EF /* ReactNativePermissions.xcodeproj */; - }, - { - ProductGroup = 249E5FA822613ABC0095F6B7 /* Products */; - ProjectRef = 249E5FA722613ABC0095F6B7 /* RNCAsyncStorage.xcodeproj */; - }, - { - ProductGroup = 2481F31D2261753900D0349A /* Products */; - ProjectRef = C779B11FB4664662AD0EBEA6 /* RNFirebase.xcodeproj */; - }, - { - ProductGroup = 24979D3E20F83E3E007EB0DA /* Products */; - ProjectRef = AEED489341644A6888669239 /* RNFIRMessaging.xcodeproj */; - }, - { - ProductGroup = 24D171DE212F57100090F180 /* Products */; - ProjectRef = 171CDF49E32841EDA7D557DB /* RNGestureHandler.xcodeproj */; - }, - { - ProductGroup = 24979D4020F83E3E007EB0DA /* Products */; - ProjectRef = 50B1B80F51614673AFD8A804 /* RNKeychain.xcodeproj */; - }, - { - ProductGroup = 24979D4420F83E3E007EB0DA /* Products */; - ProjectRef = BC297F456F414298BFBB0C30 /* RNMail.xcodeproj */; - }, - { - ProductGroup = 24979D4820F83E3E007EB0DA /* Products */; - ProjectRef = BEE6BF249EAB410AB20BBB98 /* RNOS.xcodeproj */; - }, - { - ProductGroup = 24979D4E20F83E3E007EB0DA /* Products */; - ProjectRef = 28B88B43D75F4B529A711317 /* RNRandomBytes.xcodeproj */; - }, - { - ProductGroup = 244C64062108794F007A5856 /* Products */; - ProjectRef = 1A7B7E90124047F8A3CA4B84 /* RNReactNativeHapticFeedback.xcodeproj */; - }, - { - ProductGroup = 2488BC2922E97315006847C7 /* Products */; - ProjectRef = 3182AEA93A7847CCB729F641 /* RNStoreReview.xcodeproj */; - }, - { - ProductGroup = 24979D5420F83E3E007EB0DA /* Products */; - ProjectRef = 3A545B8C781B47AC8A7CD956 /* RNSVG.xcodeproj */; - }, - { - ProductGroup = AA24D00C235EB5550082BA9B /* Products */; - ProjectRef = B076AB5B2A73409A8213C549 /* RNTextInputMask.xcodeproj */; - }, - { - ProductGroup = 24979D5020F83E3E007EB0DA /* Products */; - ProjectRef = 2DB932A7706945C787DE22A6 /* SplashScreen.xcodeproj */; - }, - { - ProductGroup = 24979D4C20F83E3E007EB0DA /* Products */; - ProjectRef = 137BEEE47D2E4F7AB452C0BD /* SRSRadialGradient.xcodeproj */; - }, - { - ProductGroup = 24979D3820F83E3E007EB0DA /* Products */; - ProjectRef = 35B7B17127FD476C81EA97E3 /* TcpSockets.xcodeproj */; - }, - { - ProductGroup = 24979D5620F83E3E007EB0DA /* Products */; - ProjectRef = 22B35A6AE60F41D093A35939 /* ToolTipMenu.xcodeproj */; - }, - { - ProductGroup = 24979D3A20F83E3E007EB0DA /* Products */; - ProjectRef = 969D4F061E6A446F9EEE2F02 /* TouchID.xcodeproj */; - }, - { - ProductGroup = 24979D5820F83E3E007EB0DA /* Products */; - ProjectRef = 46EFC4C16BAF4873BE45393E /* UdpSockets.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 13B07F861A680F5B00A75B9A /* Rainbow */, - 00E356ED1AD99517003FC87E /* RainbowTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTActionSheet.a; - remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTImage.a; - remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTNetwork.a; - remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTVibration.a; - remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTSettings.a; - remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTWebSocket.a; - remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 146834041AC3E56700842450 /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 243A893E225F092800A13C7E /* libRNGestureHandler-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRNGestureHandler-tvOS.a"; - remoteRef = 243A893D225F092800A13C7E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24402FE822D6D3800045D406 /* libFastImage-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libFastImage-tvOS.a"; - remoteRef = 24402FE722D6D3800045D406 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 244C640A2108794F007A5856 /* libRNReactNativeHapticFeedback.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNReactNativeHapticFeedback.a; - remoteRef = 244C64092108794F007A5856 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 247947BB22568EAA006BBF56 /* libjsi.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjsi.a; - remoteRef = 247947BA22568EAA006BBF56 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 247947BD22568EAA006BBF56 /* libjsiexecutor.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjsiexecutor.a; - remoteRef = 247947BC22568EAA006BBF56 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 247947BF22568EAA006BBF56 /* libjsi-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libjsi-tvOS.a"; - remoteRef = 247947BE22568EAA006BBF56 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 247947C122568EAA006BBF56 /* libjsiexecutor-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libjsiexecutor-tvOS.a"; - remoteRef = 247947C022568EAA006BBF56 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2481F3212261753900D0349A /* libRNFirebase.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNFirebase.a; - remoteRef = 2481F3202261753900D0349A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2488BC2D22E97316006847C7 /* libRNStoreReview.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNStoreReview.a; - remoteRef = 2488BC2C22E97316006847C7 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D5D20F83E3E007EB0DA /* libBVLinearGradient.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libBVLinearGradient.a; - remoteRef = 24979D5C20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D5F20F83E3E007EB0DA /* libBVLinearGradient.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libBVLinearGradient.a; - remoteRef = 24979D5E20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D6820F83E3E007EB0DA /* libReactNativePermissions.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReactNativePermissions.a; - remoteRef = 24979D6720F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D6E20F83E3E007EB0DA /* libRNFIRMessaging.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNFIRMessaging.a; - remoteRef = 24979D6D20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D7220F83E3E007EB0DA /* libRNKeychain.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNKeychain.a; - remoteRef = 24979D7120F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D7420F83E3E007EB0DA /* libRNKeychain.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNKeychain.a; - remoteRef = 24979D7320F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D7820F83E3E007EB0DA /* libRNMail.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNMail.a; - remoteRef = 24979D7720F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D7A20F83E3E007EB0DA /* RNMailTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = RNMailTests.xctest; - remoteRef = 24979D7920F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D7D20F83E3E007EB0DA /* libRNOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNOS.a; - remoteRef = 24979D7C20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D8120F83E3E007EB0DA /* libRNRandomBytes.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNRandomBytes.a; - remoteRef = 24979D8020F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D8320F83E3E007EB0DA /* libRNRandomBytes-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRNRandomBytes-tvOS.a"; - remoteRef = 24979D8220F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D8A20F83E3E007EB0DA /* libRNSVG.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNSVG.a; - remoteRef = 24979D8920F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D8C20F83E3E007EB0DA /* libRNSVG-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRNSVG-tvOS.a"; - remoteRef = 24979D8B20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D8F20F83E3E007EB0DA /* libSplashScreen.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSplashScreen.a; - remoteRef = 24979D8E20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D9220F83E3E007EB0DA /* libSRSRadialGradient.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSRSRadialGradient.a; - remoteRef = 24979D9120F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D9520F83E3E007EB0DA /* libTcpSockets.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libTcpSockets.a; - remoteRef = 24979D9420F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D9920F83E3E007EB0DA /* libToolTipMenu.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libToolTipMenu.a; - remoteRef = 24979D9820F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D9B20F83E3E007EB0DA /* ToolTipMenuTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = ToolTipMenuTests.xctest; - remoteRef = 24979D9A20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979D9E20F83E3E007EB0DA /* libTouchID.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libTouchID.a; - remoteRef = 24979D9D20F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24979DA120F83E3E007EB0DA /* libUdpSockets.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libUdpSockets.a; - remoteRef = 24979DA020F83E3E007EB0DA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 249E5FD922613ABC0095F6B7 /* libRNCAsyncStorage.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNCAsyncStorage.a; - remoteRef = 249E5FD822613ABC0095F6B7 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 24D171E2212F57110090F180 /* libRNGestureHandler.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNGestureHandler.a; - remoteRef = 24D171E1212F57110090F180 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2C86762A211152560067D47A /* libCodePush.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libCodePush.a; - remoteRef = 2C867629211152560067D47A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2C86762C211152560067D47A /* libCodePush.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libCodePush.a; - remoteRef = 2C86762B211152560067D47A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTBlob-tvOS.a"; - remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjsinspector.a; - remoteRef = 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libjsinspector-tvOS.a"; - remoteRef = 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE32056DD460020B375 /* libthird-party.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libthird-party.a"; - remoteRef = 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE52056DD460020B375 /* libthird-party.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libthird-party.a"; - remoteRef = 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libdouble-conversion.a"; - remoteRef = 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libdouble-conversion.a"; - remoteRef = 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3C39C270218BBE66004C763F /* libFastImage.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libFastImage.a; - remoteRef = 3C39C26F218BBE66004C763F /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3CD4E8CD216989E8000FA5BD /* libSRSRadialGradien-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libSRSRadialGradien-tvOS.a"; - remoteRef = 3CD4E8CC216989E8000FA5BD /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTImage-tvOS.a"; - remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTLinking-tvOS.a"; - remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTNetwork-tvOS.a"; - remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTSettings-tvOS.a"; - remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTText-tvOS.a"; - remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTWebSocket-tvOS.a"; - remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA31DF850E9000B6D8A /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libyoga.a; - remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libyoga.a; - remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcxxreact.a; - remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcxxreact.a; - remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTAnimation.a; - remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTAnimation.a; - remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; + 7CEEDA7A68C24426BBAA8D77 /* Graphik-BoldItalic.otf */, + 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */, + 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */, + 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */, + D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */, + DE019D6BCA1A4FF9B7F1E98A /* Graphik-Medium.otf */, + 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */, + A6EEFE6EA9354456B0DB4520 /* Graphik-Regular.otf */, + 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */, + 88A5866DBF924C149CA0C6F4 /* Graphik-Semibold.otf */, + A7F0978B24BA4EC283C580D9 /* Graphik-SemiboldItalic.otf */, + 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */, + 51E41940863B4B88BDEF48D7 /* Graphik-SuperItalic.otf */, + EB48DC1D46D449759B9C61D4 /* Graphik-Thin.otf */, + 3EA8003C5E2D46E38184714B /* Graphik-ThinItalic.otf */, + BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */, + A8AE8DE50B9544B6BC186E6C /* SF-Pro-Display-BlackItalic.otf */, + BA31E8CEDBCC417CA50BC57B /* SF-Pro-Display-Bold.otf */, + 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */, + 8D37634EBB294EC79081DFD2 /* SF-Pro-Display-Heavy.otf */, + D7BFD847B72D414D9BE734A0 /* SF-Pro-Display-HeavyItalic.otf */, + 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */, + E8E3CE2A4AD34CB991CD61EE /* SF-Pro-Display-LightItalic.otf */, + 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */, + 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */, + 9165B952731E4502857CC0B4 /* SF-Pro-Display-Regular.otf */, + D880F2D2B7704793A8D141DC /* SF-Pro-Display-RegularItalic.otf */, + 5842861A013B4B379705CC5A /* SF-Pro-Display-Semibold.otf */, + 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */, + 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */, + C1DB5F252E324925B4145360 /* SF-Pro-Display-ThinItalic.otf */, + 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */, + DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */, + F62BBE10D6534F74B2180711 /* SF-Pro-Text-Bold.otf */, + 1736F851327A41C3815212E7 /* SF-Pro-Text-BoldItalic.otf */, + 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */, + 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */, + E672AB1C5404435897615660 /* SF-Pro-Text-Light.otf */, + D1641F1A96C841C085169B2E /* SF-Pro-Text-LightItalic.otf */, + 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */, + D518658CFF8B491991A06426 /* SF-Pro-Text-MediumItalic.otf */, + 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */, + 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */, + AA6B0A8BE2484F46980BE9AC /* SF-Pro-Text-Semibold.otf */, + FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */, + 8789D635428240B5ABF282EE /* SFMono-Bold.otf */, + 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */, + 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */, + 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */, + 95F2888C850F40C8A26E083B /* SFMono-Regular.otf */, + B1089F835D6A4F578009B47F /* SFMono-Semibold.otf */, + ); + name = Resources; + sourceTree = ""; }; - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTLinking.a; - remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 13B07F861A680F5B00A75B9A /* Rainbow */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Rainbow" */; + buildPhases = ( + B448B1B66A188D3AC6DA3639 /* [CP] Check Pods Manifest.lock */, + 13B07F871A680F5B00A75B9A /* Sources */, + 13B07F8C1A680F5B00A75B9A /* Frameworks */, + 13B07F8E1A680F5B00A75B9A /* Resources */, + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, + 3CF823D3218F310D0024B77B /* ShellScript */, + 24122D56232F2B3300BA0B17 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Rainbow; + productName = "Hello World"; + productReference = 13B07F961A680F5B00A75B9A /* Rainbow.app */; + productType = "com.apple.product-type.application"; }; - 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTText.a; - remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 83CBB9F71A601CBA00E9B192 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 610; + ORGANIZATIONNAME = Facebook; + TargetAttributes = { + 13B07F861A680F5B00A75B9A = { + DevelopmentTeam = L74NQAQB8H; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Push = { + enabled = 1; + }; + com.apple.SafariKeychain = { + enabled = 1; + }; + }; + }; + }; + }; + buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Rainbow" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + Base, + ); + mainGroup = 83CBB9F61A601CBA00E9B192; + productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = D6A5F5EE2369A413009BEF29 /* Products */; + ProjectRef = 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 13B07F861A680F5B00A75B9A /* Rainbow */, + ); }; - AA24D010235EB5550082BA9B /* libRNTextInputMask.a */ = { +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + D6A5F5F22369A413009BEF29 /* libRNTextInputMask.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libRNTextInputMask.a; - remoteRef = AA24D00F235EB5550082BA9B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTBlob.a; - remoteRef = ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */; + remoteRef = D6A5F5F12369A413009BEF29 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ - 00E356EC1AD99517003FC87E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 13B07F8E1A680F5B00A75B9A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2121,14 +607,6 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 00E356EA1AD99517003FC87E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 00E356F31AD99517003FC87E /* RainbowTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 13B07F871A680F5B00A75B9A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2140,14 +618,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13B07F861A680F5B00A75B9A /* Rainbow */; - targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin PBXVariantGroup section */ 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { isa = PBXVariantGroup; @@ -2161,107 +631,6 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 00E356F61AD99517003FC87E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = L74NQAQB8H; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../node_modules/react-native-fcm/ios", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", - "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", - "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", - "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", - "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", - ); - INFOPLIST_FILE = RainbowTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Rainbow.app/Rainbow"; - }; - name = Debug; - }; - 00E356F71AD99517003FC87E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEVELOPMENT_TEAM = L74NQAQB8H; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../node_modules/react-native-fcm/ios", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", - "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", - "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", - "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", - "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", - ); - INFOPLIST_FILE = RainbowTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Rainbow.app/Rainbow"; - }; - name = Release; - }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */; @@ -2281,26 +650,11 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", "$(SRCROOT)/../node_modules/react-native-code-push/ios/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; @@ -2308,6 +662,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", + "\"$(SRCROOT)/Rainbow\"", ); OTHER_LDFLAGS = ( "$(inherited)", @@ -2341,26 +696,11 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", "$(SRCROOT)/../node_modules/react-native-code-push/ios/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; @@ -2368,6 +708,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", + "\"$(SRCROOT)/Rainbow\"", ); OTHER_LDFLAGS = ( "$(inherited)", @@ -2438,24 +779,10 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", "$(SRCROOT)/../node_modules/react-native-code-push/ios/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; @@ -2463,6 +790,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", + "\"$(SRCROOT)/Rainbow\"", ); OTHER_LDFLAGS = ( "$(inherited)", @@ -2477,54 +805,6 @@ }; name = Staging; }; - 2C6A799921127ED9003AFB37 /* Staging */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEVELOPMENT_TEAM = L74NQAQB8H; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../node_modules/react-native-fcm/ios", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", - "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", - "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", - "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", - ); - INFOPLIST_FILE = RainbowTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Rainbow.app/Rainbow"; - }; - name = Staging; - }; 2C87B7992197FA1900682EC4 /* LocalRelease */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2582,25 +862,10 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", "$(SRCROOT)/../node_modules/react-native-code-push/ios/**", "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; @@ -2608,6 +873,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", + "\"$(SRCROOT)/Rainbow\"", ); OTHER_LDFLAGS = ( "$(inherited)", @@ -2622,55 +888,6 @@ }; name = LocalRelease; }; - 2C87B79B2197FA1900682EC4 /* LocalRelease */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEVELOPMENT_TEAM = L74NQAQB8H; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../node_modules/react-native-fcm/ios", - "$(SRCROOT)/../node_modules/react-native-keychain/RNKeychainManager", - "$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient", - "$(SRCROOT)/../node_modules/react-native-mail/RNMail", - "$(SRCROOT)/../node_modules/react-native-os/ios", - "$(SRCROOT)/../node_modules/react-native-permissions/ios/**", - "$(SRCROOT)/../node_modules/react-native-radial-gradient/ios", - "$(SRCROOT)/../node_modules/react-native-randombytes", - "$(SRCROOT)/../node_modules/react-native-splash-screen/ios", - "$(SRCROOT)/../node_modules/react-native-svg/ios/**", - "$(SRCROOT)/../node_modules/react-native-tcp/ios/**", - "$(SRCROOT)/../node_modules/react-native-tooltip/ToolTipMenu", - "$(SRCROOT)/../node_modules/react-native-touch-id", - "$(SRCROOT)/../node_modules/react-native-udp/ios/**", - "$(SRCROOT)/../node_modules/react-native-haptic-feedback/ios", - "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", - "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", - "$(SRCROOT)/../node_modules/@ledgerhq/react-native-passcode-auth", - "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$(SRCROOT)/../node_modules/react-native-store-review/ios", - "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", - ); - INFOPLIST_FILE = RainbowTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/$(TARGET_NAME)\"", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Rainbow.app/Rainbow"; - }; - name = LocalRelease; - }; 83CBBA201A601CBA00E9B192 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2752,17 +969,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RainbowTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00E356F61AD99517003FC87E /* Debug */, - 00E356F71AD99517003FC87E /* Release */, - 2C87B79B2197FA1900682EC4 /* LocalRelease */, - 2C6A799921127ED9003AFB37 /* Staging */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Rainbow" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 10146fdb417..324638f15cb 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -14,10 +14,10 @@ buildForAnalyzing = "YES"> + ReferencedContainer = "container:Pods/Pods.xcodeproj"> + + + + BuildSystemType + Original + PreviewsEnabled + + + diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index df8934a4eb2..82aa74ff0ed 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -1,161 +1,161 @@ - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - Rainbow - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.1.5 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - rainbow - CFBundleURLSchemes - - rainbow - - - - CFBundleVersion - 3 - CodePushDeploymentKey - $(CODEPUSH_KEY) - ITSAppUsesNonExemptEncryption - - LSApplicationQueriesSchemes - - itms - itms-apps - twitter - - LSRequiresIPhoneOS - - NSAppTransportSecurity - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - - NSAppleMusicUsageDescription - Rainbow - NSBluetoothPeripheralUsageDescription - Rainbow - NSCalendarsUsageDescription - Rainbow - NSCameraUsageDescription - Used to scan QR codes - NSFaceIDUsageDescription - Used to sign transactions - NSLocationAlwaysUsageDescription - Rainbow - NSLocationWhenInUseUsageDescription - Rainbow - NSMicrophoneUsageDescription - Rainbow - NSMotionUsageDescription - Rainbow - NSSpeechRecognitionUsageDescription - Rainbow - UIAppFonts - - Graphik-Black.otf - Graphik-BlackItalic.otf - Graphik-Bold.otf - Graphik-BoldItalic.otf - Graphik-Extralight.otf - Graphik-ExtralightItalic.otf - Graphik-Light.otf - Graphik-LightItalic.otf - Graphik-Medium.otf - Graphik-MediumItalic.otf - Graphik-Regular.otf - Graphik-RegularItalic.otf - Graphik-Semibold.otf - Graphik-SemiboldItalic.otf - Graphik-Super.otf - Graphik-SuperItalic.otf - Graphik-Thin.otf - Graphik-ThinItalic.otf - SF-Pro-Display-Black.otf - SF-Pro-Display-BlackItalic.otf - SF-Pro-Display-Bold.otf - SF-Pro-Display-BoldItalic.otf - SF-Pro-Display-Heavy.otf - SF-Pro-Display-HeavyItalic.otf - SF-Pro-Display-Light.otf - SF-Pro-Display-LightItalic.otf - SF-Pro-Display-Medium.otf - SF-Pro-Display-MediumItalic.otf - SF-Pro-Display-Regular.otf - SF-Pro-Display-RegularItalic.otf - SF-Pro-Display-Semibold.otf - SF-Pro-Display-SemiboldItalic.otf - SF-Pro-Display-Thin.otf - SF-Pro-Display-ThinItalic.otf - SF-Pro-Display-Ultralight.otf - SF-Pro-Display-UltralightItalic.otf - SF-Pro-Text-Bold.otf - SF-Pro-Text-BoldItalic.otf - SF-Pro-Text-Heavy.otf - SF-Pro-Text-HeavyItalic.otf - SF-Pro-Text-Light.otf - SF-Pro-Text-LightItalic.otf - SF-Pro-Text-Medium.otf - SF-Pro-Text-MediumItalic.otf - SF-Pro-Text-Regular.otf - SF-Pro-Text-RegularItalic.otf - SF-Pro-Text-Semibold.otf - SF-Pro-Text-SemiboldItalic.otf - SFMono-Bold.otf - SFMono-Heavy.otf - SFMono-Light.otf - SFMono-Medium.otf - SFMono-Regular.otf - SFMono-Semibold.otf - - UIBackgroundModes - - remote-notification - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UIStatusBarStyle - UIStatusBarStyleDarkContent - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UIUserInterfaceStyle - Light - UIViewControllerBasedStatusBarAppearance - - + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + Rainbow + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.1.5 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + rainbow + CFBundleURLSchemes + + rainbow + + + + CFBundleVersion + 3 + CodePushDeploymentKey + $(CODEPUSH_KEY) + ITSAppUsesNonExemptEncryption + + LSApplicationQueriesSchemes + + itms + itms-apps + twitter + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSAppleMusicUsageDescription + Rainbow + NSBluetoothPeripheralUsageDescription + Rainbow + NSCalendarsUsageDescription + Rainbow + NSCameraUsageDescription + Used to scan QR codes + NSFaceIDUsageDescription + Used to sign transactions + NSLocationAlwaysUsageDescription + Rainbow + NSLocationWhenInUseUsageDescription + Rainbow + NSMicrophoneUsageDescription + Rainbow + NSMotionUsageDescription + Rainbow + NSSpeechRecognitionUsageDescription + Rainbow + UIAppFonts + + Graphik-Black.otf + Graphik-BlackItalic.otf + Graphik-Bold.otf + Graphik-BoldItalic.otf + Graphik-Extralight.otf + Graphik-ExtralightItalic.otf + Graphik-Light.otf + Graphik-LightItalic.otf + Graphik-Medium.otf + Graphik-MediumItalic.otf + Graphik-Regular.otf + Graphik-RegularItalic.otf + Graphik-Semibold.otf + Graphik-SemiboldItalic.otf + Graphik-Super.otf + Graphik-SuperItalic.otf + Graphik-Thin.otf + Graphik-ThinItalic.otf + SF-Pro-Display-Black.otf + SF-Pro-Display-BlackItalic.otf + SF-Pro-Display-Bold.otf + SF-Pro-Display-BoldItalic.otf + SF-Pro-Display-Heavy.otf + SF-Pro-Display-HeavyItalic.otf + SF-Pro-Display-Light.otf + SF-Pro-Display-LightItalic.otf + SF-Pro-Display-Medium.otf + SF-Pro-Display-MediumItalic.otf + SF-Pro-Display-Regular.otf + SF-Pro-Display-RegularItalic.otf + SF-Pro-Display-Semibold.otf + SF-Pro-Display-SemiboldItalic.otf + SF-Pro-Display-Thin.otf + SF-Pro-Display-ThinItalic.otf + SF-Pro-Display-Ultralight.otf + SF-Pro-Display-UltralightItalic.otf + SF-Pro-Text-Bold.otf + SF-Pro-Text-BoldItalic.otf + SF-Pro-Text-Heavy.otf + SF-Pro-Text-HeavyItalic.otf + SF-Pro-Text-Light.otf + SF-Pro-Text-LightItalic.otf + SF-Pro-Text-Medium.otf + SF-Pro-Text-MediumItalic.otf + SF-Pro-Text-Regular.otf + SF-Pro-Text-RegularItalic.otf + SF-Pro-Text-Semibold.otf + SF-Pro-Text-SemiboldItalic.otf + SFMono-Bold.otf + SFMono-Heavy.otf + SFMono-Light.otf + SFMono-Medium.otf + SFMono-Regular.otf + SFMono-Semibold.otf + + UIBackgroundModes + + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleDarkContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UIUserInterfaceStyle + Light + UIViewControllerBasedStatusBarAppearance + + diff --git a/package.json b/package.json index 5b394b1e121..afba5ccbe9e 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", - "react-native-firebase": "^4.3.8", + "react-native-firebase": "~5.5.5", "react-native-gesture-handler": "^1.4.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", @@ -93,8 +93,8 @@ "react-native-level-fs": "^3.0.1", "react-native-linear-gradient": "^2.5.6", "react-native-mail": "^3.0.6", - "react-native-os": "^1.2.2", - "react-native-permissions": "^1.1.1", + "react-native-os": "icxcat/react-native-os#master", + "react-native-permissions": "^1.2.1", "react-native-qrcode-scanner": "mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e", "react-native-qrcode-svg": "git+https://github.com/mikedemarais/react-native-qrcode-svg.git", "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", @@ -110,12 +110,12 @@ "react-native-svg": "9.10.1", "react-native-tcp": "^3.3.0", "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", - "react-native-tooltip": "^5.2.0", + "react-native-tooltip": "marcosrdz/react-native-tooltip#master", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.7", - "react-navigation-stack": "2.0.0-alpha.34", + "react-navigation-stack": "2.0.0-alpha.35", "react-navigation-tabs": "2.5.5", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", diff --git a/yarn.lock b/yarn.lock index 4fde35d8159..262a787befe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,17 +10,17 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.6.2": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.4.tgz#6ebd9fe00925f6c3e177bb726a188b5f578088ff" - integrity sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.0.tgz#461d2948b1a7113088baf999499bcbd39a7faa3b" + integrity sha512-Bb1NjZCaiwTQC/ARL+MwDpgocdnwWDCaugvkGt6cxfBzQa8Whv1JybBoUEiBDKl8Ni3H3c7Fykwk7QChUsHRlg== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.4" - "@babel/helpers" "^7.6.2" - "@babel/parser" "^7.6.4" - "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.3" - "@babel/types" "^7.6.3" + "@babel/generator" "^7.7.0" + "@babel/helpers" "^7.7.0" + "@babel/parser" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -29,132 +29,140 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.6.3", "@babel/generator@^7.6.4": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.4.tgz#a4f8437287bf9671b07f483b76e3bb731bc97671" - integrity sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.0.tgz#c6d4d1f7a0d6e139cbd01aca73170b0bff5425b4" + integrity sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw== dependencies: - "@babel/types" "^7.6.3" + "@babel/types" "^7.7.0" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== +"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz#efc54032d43891fe267679e63f6860aa7dbf4a5e" + integrity sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" "@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz#32dd9551d6ed3a5fc2edc50d6912852aa18274d9" + integrity sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw== dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-explode-assignable-expression" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/helper-builder-react-jsx@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" - integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== +"@babel/helper-builder-react-jsx@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.0.tgz#c6b8254d305bacd62beb648e4dea7d3ed79f352d" + integrity sha512-LSln3cexwInTMYYoFeVLKnYPPMfWNJ8PubTBs3hkh7wCu9iBaqq1OOyW+xGmEdLxT1nhsl+9SJ+h2oUDYz0l2A== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.7.0" esutils "^2.0.0" "@babel/helper-call-delegate@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" - integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== - dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz#df8942452c2c1a217335ca7e393b9afc67f668dc" + integrity sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw== + dependencies: + "@babel/helper-hoist-variables" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-create-class-features-plugin@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz#bcdc223abbfdd386f94196ae2544987f8df775e8" + integrity sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA== + dependencies: + "@babel/helper-function-name" "^7.7.0" + "@babel/helper-member-expression-to-functions" "^7.7.0" + "@babel/helper-optimise-call-expression" "^7.7.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" -"@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" - integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== +"@babel/helper-create-regexp-features-plugin@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.0.tgz#2e8badfe201cfafb5d930f46cf1e0b6f1cdcab23" + integrity sha512-ZhagAAVGD3L6MPM9/zZi7RRteonfBFLVUz3kjsnYsMAtr9hOJCKI9BAKIMpqn3NyWicPieoX779UL+7/3BEAOA== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.6.0" -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== +"@babel/helper-define-map@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz#60b0e9fd60def9de5054c38afde8c8ee409c7529" + integrity sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" + "@babel/helper-function-name" "^7.7.0" + "@babel/types" "^7.7.0" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== +"@babel/helper-explode-assignable-expression@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz#db2a6705555ae1f9f33b4b8212a546bc7f9dc3ef" + integrity sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg== dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== +"@babel/helper-function-name@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz#44a5ad151cfff8ed2599c91682dda2ec2c8430a3" + integrity sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q== dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-get-function-arity" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== +"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz#c604886bc97287a1d1398092bc666bc3d7d7aa2d" + integrity sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== +"@babel/helper-hoist-variables@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz#b4552e4cfe5577d7de7b183e193e84e4ec538c81" + integrity sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ== dependencies: - "@babel/types" "^7.4.4" + "@babel/types" "^7.7.0" -"@babel/helper-member-expression-to-functions@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" - integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== +"@babel/helper-member-expression-to-functions@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz#472b93003a57071f95a541ea6c2b098398bcad8a" + integrity sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA== dependencies: - "@babel/types" "^7.5.5" + "@babel/types" "^7.7.0" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz#99c095889466e5f7b6d66d98dffc58baaf42654d" + integrity sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" -"@babel/helper-module-transforms@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" - integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== +"@babel/helper-module-transforms@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz#154a69f0c5b8fd4d39e49750ff7ac4faa3f36786" + integrity sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/template" "^7.4.4" - "@babel/types" "^7.5.5" + "@babel/helper-module-imports" "^7.7.0" + "@babel/helper-simple-access" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/types" "^7.7.0" lodash "^4.17.13" -"@babel/helper-optimise-call-expression@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== +"@babel/helper-optimise-call-expression@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz#4f66a216116a66164135dc618c5d8b7a959f9365" + integrity sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.7.0" "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" @@ -168,60 +176,60 @@ dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-replace-supers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" - integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - -"@babel/helper-simple-access@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== - dependencies: - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" - integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== - dependencies: - "@babel/types" "^7.4.4" - -"@babel/helper-wrap-function@^7.1.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" - -"@babel/helpers@^7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.2.tgz#681ffe489ea4dcc55f23ce469e58e59c1c045153" - integrity sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA== - dependencies: - "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.2" - "@babel/types" "^7.6.0" +"@babel/helper-remap-async-to-generator@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz#4d69ec653e8bff5bce62f5d33fc1508f223c75a7" + integrity sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.0" + "@babel/helper-wrap-function" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz#d5365c8667fe7cbd13b8ddddceb9bd7f2b387512" + integrity sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.7.0" + "@babel/helper-optimise-call-expression" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-simple-access@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz#97a8b6c52105d76031b86237dc1852b44837243d" + integrity sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g== + dependencies: + "@babel/template" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helper-split-export-declaration@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz#1365e74ea6c614deeb56ebffabd71006a0eb2300" + integrity sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA== + dependencies: + "@babel/types" "^7.7.0" + +"@babel/helper-wrap-function@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz#15af3d3e98f8417a60554acbb6c14e75e0b33b74" + integrity sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w== + dependencies: + "@babel/helper-function-name" "^7.7.0" + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + +"@babel/helpers@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.0.tgz#359bb5ac3b4726f7c1fde0ec75f64b3f4275d60b" + integrity sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g== + dependencies: + "@babel/template" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" "@babel/highlight@^7.0.0": version "7.5.0" @@ -232,10 +240,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0", "@babel/parser@^7.6.3", "@babel/parser@^7.6.4": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.4.tgz#cb9b36a7482110282d5cb6dd424ec9262b473d81" - integrity sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.0.tgz#232618f6e8947bc54b407fa1f1c91a22758e7159" + integrity sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -245,11 +253,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" - integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz#ac54e728ecf81d90e8f4d2a9c05a890457107917" + integrity sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A== dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.5" + "@babel/helper-create-class-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": @@ -314,9 +322,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" - integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.0.tgz#5c9465bcd26354d5215294ea90ab1c706a571386" + integrity sha512-vQMV07p+L+jZeUnvX3pEJ9EiXGCjB5CTTvsirFD9rpEuATnoAvLBLoYbw1v5tyn3d2XxSuvEKi8cV3KqYUa0vQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -370,13 +378,13 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz#e2b84f11952cf5913fe3438b7d2585042772f492" + integrity sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw== dependencies: - "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-module-imports" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-remap-async-to-generator" "^7.7.0" "@babel/plugin-transform-block-scoped-functions@^7.0.0": version "7.2.0" @@ -394,17 +402,17 @@ lodash "^4.17.13" "@babel/plugin-transform-classes@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz#b411ecc1b8822d24b81e5d184f24149136eddd4a" + integrity sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.0" + "@babel/helper-define-map" "^7.7.0" + "@babel/helper-function-name" "^7.7.0" + "@babel/helper-optimise-call-expression" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-replace-supers" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0": @@ -445,11 +453,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-function-name@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz#0fa786f1eef52e3b7d4fc02e54b2129de8a04c2a" + integrity sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA== dependencies: - "@babel/helper-function-name" "^7.1.0" + "@babel/helper-function-name" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-literals@^7.0.0": @@ -467,13 +475,13 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz#39dfe957de4420445f1fcf88b68a2e4aa4515486" - integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz#3e5ffb4fd8c947feede69cbe24c9554ab4113fe3" + integrity sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg== dependencies: - "@babel/helper-module-transforms" "^7.4.4" + "@babel/helper-module-transforms" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-simple-access" "^7.7.0" babel-plugin-dynamic-import-node "^2.3.0" "@babel/plugin-transform-object-assign@^7.0.0": @@ -523,18 +531,18 @@ "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" - integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.0.tgz#834b0723ba78cd4d24d7d629300c2270f516d0b7" + integrity sha512-mXhBtyVB1Ujfy+0L6934jeJcSXj/VCg6whZzEcgiiZHNS0PGC7vUCsZDQCxxztkpIdF+dY1fUMcjAgEOC3ZOMQ== dependencies: - "@babel/helper-builder-react-jsx" "^7.3.0" + "@babel/helper-builder-react-jsx" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-regenerator@^7.0.0": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz#f1b20b535e7716b622c99e989259d7dd942dd9cc" + integrity sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg== dependencies: regenerator-transform "^0.14.0" @@ -579,69 +587,68 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz#dddb50cf3b8b2ef70b22e5326e9a91f05a1db13b" - integrity sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.0.tgz#182be03fa8bd2ffd0629791a1eaa4373b7589d38" + integrity sha512-y3KYbcfKe+8ziRXiGhhnGrVysDBo5+aJdB+x8sanM0K41cnmK7Q5vBlQLMbOnW/HPjLG9bg7dLgYDQZZG9T09g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.6.0" + "@babel/helper-create-class-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" "@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz#b692aad888a7e8d8b1b214be6b9dc03d5031f698" - integrity sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz#743d9bcc44080e3cc7d49259a066efa30f9187a3" + integrity sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.6.0" "@babel/register@^7.0.0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.2.tgz#25765a922202cb06f8bdac5a3b1e70cd6bf3dd45" - integrity sha512-xgZk2LRZvt6i2SAUWxc7ellk4+OYRgS3Zpsnr13nMS1Qo25w21Uu8o6vTOAqNaxiqrnv30KTYzh9YWY2k21CeQ== + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.0.tgz#4e23ecf840296ef79c605baaa5c89e1a2426314b" + integrity sha512-HV3GJzTvSoyOMWGYn2TAh6uL6g+gqKTgEZ99Q3+X9UURT1VPT/WcU46R61XftIc5rXytcOHZ4Z0doDlsjPomIg== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.13" - mkdirp "^0.5.1" + make-dir "^2.1.0" pirates "^4.0.0" - source-map-support "^0.5.9" + source-map-support "^0.5.16" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.6.2": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f" - integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2": + version "7.7.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.1.tgz#b223497bbfbcbbb38116673904debc71470ca528" + integrity sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ== dependencies: regenerator-runtime "^0.13.2" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" - integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== +"@babel/template@^7.0.0", "@babel/template@^7.4.0", "@babel/template@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.0.tgz#4fadc1b8e734d97f56de39c77de76f2562e597d0" + integrity sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.6.0" - "@babel/types" "^7.6.0" + "@babel/parser" "^7.7.0" + "@babel/types" "^7.7.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.2", "@babel/traverse@^7.6.3": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.3.tgz#66d7dba146b086703c0fb10dd588b7364cec47f9" - integrity sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.0.tgz#9f5744346b8d10097fd2ec2eeffcaf19813cbfaf" + integrity sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.3" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.6.3" - "@babel/types" "^7.6.3" + "@babel/generator" "^7.7.0" + "@babel/helper-function-name" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/parser" "^7.7.0" + "@babel/types" "^7.7.0" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0", "@babel/types@^7.6.3": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09" - integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.7.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.1.tgz#8b08ea368f2baff236613512cf67109e76285827" + integrity sha512-kN/XdANDab9x1z5gcjDc9ePpxexkt+1EQ2MQUiM4XnMvQfvp87/+6kY4Ko2maLXH+tei/DgJ/ybFITeqqRwDiA== dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -670,9 +677,9 @@ "@emotion/memoize" "0.7.1" "@emotion/is-prop-valid@^0.8.1": - version "0.8.4" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.4.tgz#cf1dcfc1812c226f05e1ba53592eb6b51e734990" - integrity sha512-QBW8h6wVQgeQ55F52rNaprEJxtVR+/ScOP8/V1ScSpPzKqHdFB9QVqby0Z50sqS8mcaeIl5vR1vQpKwJbIS6NQ== + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz#2dda0791f0eafa12b7a0a5b39858405cc7bde983" + integrity sha512-6ZODuZSFofbxSbcxwsFz+6ioPjb0ISJRRPLZ+WIbjcU2IMU0Io+RGQjjaTgOvNQl007KICBm7zXQaYQEC1r6Bg== dependencies: "@emotion/memoize" "0.7.3" @@ -779,9 +786,9 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.4.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.4.0.tgz#3f2153d9eea8942dfe217e1642a420f1fe4087f3" - integrity sha512-JLK+vNrtZSQy1PiAAvtaPGiZhFQo+BLywJkD4EHG8vCzlW9w7Y9yfb2be1GFKnZKczLgzHBpgMOBUZs1qBNB5g== + version "8.5.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" + integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw== "@hapi/joi@^15.0.3": version "15.1.1" @@ -1154,14 +1161,14 @@ ws "^1.1.0" "@react-native-community/masked-view@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.1.tgz#dbcfc5ec08efbb02d4142dd9426c8d7a396829d7" - integrity sha512-EyJVSbarZkOPYq+zCZLx9apMcpwkX9HvH6R+6CeVL29q88kEFemnLO/IhmE4YX/0MfalsduI8eTi7fuQh/5VeA== + version "0.1.4" + resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.4.tgz#e0f8952a30014922929d7742a0809bc108e66549" + integrity sha512-bP6FWEa1qaRJb1aKA9ni/2/D8NoBZU54oFyEeGnxkax80No4YCHFGmRW8xcFwgZ2TXWuRSoI1xpGzuWfspHs/g== "@react-native-community/netinfo@^4.1.4": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.4.0.tgz#a18eb9ba082b6aca6add004b4a918250ad7d13bc" - integrity sha512-qqNWMOsrDjj/daqV21ID2T8mNUjZD4pdx3PuWyE65gzKh2w+oMnzKb+J0NbLyZPn3wwLwU1+Cpf58A0ff5szjQ== + version "4.6.0" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.0.tgz#fc0b79a226da78371158f885a2f798ff07c926be" + integrity sha512-wz39BUpExDU1kTpLlBkDwwb0Efg+uuwixToosTSarZgpzG/CmcRvWdD786TMiE5tLDd+Mpi2xh3w4FrVM8zjoA== "@react-navigation/core@^3.5.1": version "3.5.1" @@ -1419,14 +1426,14 @@ "@types/node" "*" "@types/node@*": - version "12.12.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.3.tgz#ebfe83507ac506bc3486314a8aa395be66af8d23" - integrity sha512-opgSsy+cEF9N8MgaVPnWVtdJ3o4mV2aMHvDq7thkQUFt0EuOHJon4rQpJfhjmNHB+ikl0Cd6WhWIErOyQ+f7tw== + version "12.12.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.5.tgz#66103d2eddc543d44a04394abb7be52506d7f290" + integrity sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A== "@types/node@^10.3.2": - version "10.17.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.2.tgz#41b5afbcde1a5a805302a4da3cf399499f1bbf64" - integrity sha512-sAh60KDol+MpwOr1RTK0+HgBEYejKsxdpmrOS1Wts5bI03dLzq8F7T0sRXDKeaEK8iWDlGfdzxrzg6vx/c5pNA== + version "10.17.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.3.tgz#65a8d9a6a0f6af55595a2d0020617959130d6495" + integrity sha512-QZ9CjUB3QoA3f2afw3utKlfRPhpmufB7jC2+oDhLWnXqoyx333fhKSQDLQu2EK7OE0a15X67eYiRAaJsHXrpMA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2015,16 +2022,16 @@ atob@^2.1.1: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.5.1: - version "9.7.0" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.0.tgz#905ec19e50f04545fe9ff131182cc9ab25246901" - integrity sha512-j2IRvaCfrUxIiZun9ba4mhJ2omhw4OY88/yVzLO+lHhGBumAAK72PgM6gkbSN8iregPOn1ZlxGkmZh2CQ7X4AQ== + version "9.7.1" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.1.tgz#9ffc44c55f5ca89253d9bb7186cefb01ef57747f" + integrity sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw== dependencies: browserslist "^4.7.2" - caniuse-lite "^1.0.30001004" + caniuse-lite "^1.0.30001006" chalk "^2.4.2" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^7.0.19" + postcss "^7.0.21" postcss-value-parser "^4.0.2" aws-sign2@~0.7.0: @@ -2488,12 +2495,30 @@ btoa@^1.2.1: resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= -buffer-from@^1.0.0: +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0, buffer-from@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -2512,7 +2537,7 @@ buffer@^4.9.1: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.0.0: +buffer@^5.0.0, buffer@^5.4.3: version "5.4.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== @@ -2621,10 +2646,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001004: - version "1.0.30001006" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001006.tgz#5b6e8288792cfa275f007b2819a00ccad7112655" - integrity sha512-MXnUVX27aGs/QINz+QG1sWSLDr3P1A3Hq5EUWoIt0T7K24DuvMxZEnh3Y5aHlJW6Bz2aApJdSewdYLd8zQnUuw== +caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006: + version "1.0.30001008" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz#b8841b1df78a9f5ed9702537ef592f1f8772c0d9" + integrity sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw== capture-exit@^2.0.0: version "2.0.0" @@ -3643,9 +3668,9 @@ ejs@^2.7.1: integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.295: - version "1.3.296" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.296.tgz#a1d4322d742317945285d3ba88966561b67f3ac8" - integrity sha512-s5hv+TSJSVRsxH190De66YHb50pBGTweT9XGWYu/LMR20KX6TsjFzObo36CjVAzM+PUeeKSBRtm/mISlCzeojQ== + version "1.3.303" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.303.tgz#3059bcc39c1c3b492ca381d577b6a49b5050085e" + integrity sha512-xDFPmMjJ0gQBsVwspB0bjcbFn3MVcvU0sxXYmh1UMbZ6rDogQVM3vSyOvTO4rym1KlnJIU6nqzK3qs0yKudmjw== elliptic@6.3.3: version "6.3.3" @@ -7792,9 +7817,9 @@ number-is-nan@^1.0.0: integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= nwsapi@^2.0.7: - version "2.1.4" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" - integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== oauth-sign@~0.9.0: version "0.9.0" @@ -7968,7 +7993,7 @@ open@^6.2.0, open@^6.4.0: dependencies: is-wsl "^1.1.0" -opencollective-postinstall@^2.0.2: +opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== @@ -8411,9 +8436,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.0.7" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" - integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177" + integrity sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw== pify@^2.0.0: version "2.3.0" @@ -8616,7 +8641,7 @@ postcss-value-parser@^4.0.2: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.19, postcss@^7.0.2, postcss@^7.0.7: +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.7: version "7.0.21" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== @@ -8625,11 +8650,6 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.1 source-map "^0.6.1" supports-color "^6.1.0" -postinstall-build@^5.0.1: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7" - integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg== - postinstall-postinstall@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.0.0.tgz#7ba6711b4420575c4f561638836a81faad47f43f" @@ -8812,10 +8832,13 @@ q@^1.1.2, q@^1.4.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qrcode@^1.2.0: - version "1.4.2" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.2.tgz#e7c82a60140916d666541043bd2b0b72ee4e38a6" - integrity sha512-eR6RgxFYPDFH+zFLTJKtoNP/RlsHANQb52AUmQ2bGDPMuUw7jJb0F+DNEgx7qQGIElrbFxWYMc0/B91zLZPF9Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83" + integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== dependencies: + buffer "^5.4.3" + buffer-alloc "^1.2.0" + buffer-from "^1.1.1" dijkstrajs "^1.0.1" isarray "^2.0.1" pngjs "^3.3.0" @@ -8957,9 +8980,9 @@ react-native-camera@^2.11.0: prop-types "^15.6.2" react-native-circular-progress@^1.1.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/react-native-circular-progress/-/react-native-circular-progress-1.3.3.tgz#89d23d10f227d695fcc662c6400f6f5e9c0a6aa2" - integrity sha512-YfBziScKafqxOt9dN1vssCAm8sMrfmDqGROc8PoOFbY0rV6ueQPdW+dzkxXR2/POaLuzqvUcXB8HPc4Y9TiXlQ== + version "1.3.4" + resolved "https://registry.yarnpkg.com/react-native-circular-progress/-/react-native-circular-progress-1.3.4.tgz#91b8aed6ff5ecb8841d2a5a9089af41a5d962087" + integrity sha512-gch73x1qcx7vQewXdY7GdDgvgFSXZHVJ7hp4lXpOWT4Vo7ZnSAeeXYW11sMg2VkFpfA2gu6F+JRQLefDpMzcWQ== dependencies: prop-types "^15.7.2" @@ -9020,14 +9043,13 @@ react-native-fast-image@andrewschenk-linx/react-native-fast-image#fix-ios-xcode- version "7.0.2" resolved "https://codeload.github.com/andrewschenk-linx/react-native-fast-image/tar.gz/d19ae11a6469de94cb49211d00a7bc002ea76ff8" -react-native-firebase@^4.3.8: - version "4.3.8" - resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-4.3.8.tgz#a425b260aca0b97cde023dd2556fc18d16a3b7b3" - integrity sha512-lQuRrcnRd6Y3Drk8X66GYodfqPhWqy82+3S0rjOCoB3LhapnYXpi6QCqKJwkdBsy49zTyVsuH9cmMgQyejYW+w== +react-native-firebase@~5.5.5: + version "5.5.6" + resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-5.5.6.tgz#17b34ec0d5dc39afaaf0e159fd160f6339e0f707" + integrity sha512-AdbpGwKEEiMFgaRar9WOPc8Li4sfxR//WOyNQzxYsQ1fpARC908j7feqy2gu73SLqk4wzIrnlfJWakOe0/Bclg== dependencies: - opencollective "^1.0.3" - postinstall-build "^5.0.1" - prop-types "^15.6.1" + opencollective-postinstall "^2.0.0" + prop-types "^15.7.2" react-native-gesture-handler@^1.4.1: version "1.5.0" @@ -9089,12 +9111,11 @@ react-native-mail@^3.0.6: resolved "https://registry.yarnpkg.com/react-native-mail/-/react-native-mail-3.0.7.tgz#07e6aca43f6f1f85f3e58e96e7fcd16b31a927b8" integrity sha512-FHe4kKJKAGuCPPWcDwaRSjdUhEE4IWIsVtTZ05dgD/MgOm00isYmM20zuJHla7oiHVQ2HmzGji76g6IuhIrCjw== -react-native-os@^1.2.2: - version "1.2.5" - resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.5.tgz#4b10b010b8734bb300e8c0017f01bc67cad98e7a" - integrity sha512-cueg5nhzqA9vGwRXzX5/f/95JdhWjy7pNf9r5XW9YEfVf0C36CHzz5LNLrZQqJukmCWoeOEBDmtvllfpXVIpcA== +react-native-os@icxcat/react-native-os#master: + version "1.1.0" + resolved "https://codeload.github.com/icxcat/react-native-os/tar.gz/1efb92b990fb4c02475fcc98a8260c3991c59b2d" -react-native-permissions@^1.1.1: +react-native-permissions@^1.1.1, react-native-permissions@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.2.1.tgz#cb1f6e53b8992b3912de5a4cfc1553ac2e82d0f6" integrity sha512-6NOGsA7EsuKT9hfULccQfMrsGmRhBkmN6Uv8nz2QObjEG87XtroQtw4Qi1+tAjIkSHawCeAMJp+SCtiXSGUD5Q== @@ -9209,10 +9230,9 @@ react-native-text-input-mask@react-native-community/react-native-text-input-mask version "1.0.6" resolved "https://codeload.github.com/react-native-community/react-native-text-input-mask/tar.gz/abf0e7f538036bbc5719024fbd67a1efd756c4b9" -react-native-tooltip@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-native-tooltip/-/react-native-tooltip-5.2.0.tgz#4358ea1e9bdcb49dad28bf5881440b0182927422" - integrity sha512-3mbPGd/VDfb3dUZmdmgg4eE8idJU4OyYM9ItGifnofz+Cz50Aua+sVGo2Ecc7zHV0S+kM0mOyLL758hhTz2gDw== +react-native-tooltip@marcosrdz/react-native-tooltip#master: + version "5.2.1" + resolved "https://codeload.github.com/marcosrdz/react-native-tooltip/tar.gz/e0e88d212b5b7f350e5eabba87f588a32e0f2590" react-native-touch-id@^4.4.1: version "4.4.1" @@ -9270,10 +9290,10 @@ react-native@0.61.2: stacktrace-parser "^0.1.3" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.34: - version "2.0.0-alpha.34" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.34.tgz#1d5bddfdc9ce8cabb8e3749ad6257850657bc480" - integrity sha512-lqpDgMkGmwjIOJ+3jTDJUDksDQmG1DfYp4KdGAk5qN+ZyWjvbbKXhKvSLn8kX03egQFU6tMWnNAsI7duWiAG9A== +react-navigation-stack@2.0.0-alpha.35: + version "2.0.0-alpha.35" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.35.tgz#4d98790f9edf87d40052f41f8b24f00f9008a383" + integrity sha512-D6Dts3KSg/8blKkwsHbjKUNVGwrtJKN0PXW2PveuN7ySuVnyMRpEUxhMVsO7jznVf1hpk7R+fsBDGKAkNcHiBA== react-navigation-tabs@2.5.5: version "2.5.5" @@ -9736,19 +9756,19 @@ replace-ext@1.0.0: resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= -request-promise-core@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" - integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== dependencies: - lodash "^4.17.11" + lodash "^4.17.15" request-promise-native@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" - integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== dependencies: - request-promise-core "1.1.2" + request-promise-core "1.1.3" stealthy-require "^1.1.1" tough-cookie "^2.3.3" @@ -10394,7 +10414,7 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.6, source-map-support@^0.5.9: +source-map-support@^0.5.16, source-map-support@^0.5.6: version "0.5.16" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== @@ -11240,9 +11260,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.5.tgz#b0ee796d2ae7e25672e04f65629b997cd4b30bd6" - integrity sha512-7L3W+Npia1OCr5Blp4/Vw83tK1mu5gnoIURtT1fUVfQ3Kf8WStWV6NJz0fdoBJZls0KlweruRTLVe6XLafmy5g== + version "3.6.7" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.7.tgz#15f49211df6b8a01ee91322bbe46fa33223175dc" + integrity sha512-4sXQDzmdnoXiO+xvmTzQsfIiwrjUCSA95rSP4SEd8tDb51W2TiDOlL76Hl+Kw0Ie42PSItCW8/t6pBNCF2R48A== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -11579,19 +11599,25 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.1.tgz#e051f3bb2de5d23995763deac108622a5e93604a" - integrity sha512-IWJreQ9HtBSyveqaC3UUEArUqCnt5zYLgHewSJ0CvxlIJfvY7yD8GDbLuLxGeHMWwSudYlODit1IfwNzvjZjEg== + version "3.4.6" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.6.tgz#5a859ed0e46d37f83726b875691a3a0152c7ea49" + integrity sha512-FHuGne8eOJ88yHGNmm/6Kamyj4N03m6dJXq0UXdIY1GpYrulJBDxYnSDD5WaOnMLDtoGFlrE8I1Fq3n+gnfnLQ== dependencies: jsonc-parser "^2.2.0" - vscode-languageserver-types "^3.15.0-next.5" + vscode-languageserver-textdocument "^1.0.0-next.3" + vscode-languageserver-types "^3.15.0-next.6" vscode-nls "^4.1.1" vscode-uri "^2.1.0" -vscode-languageserver-types@^3.15.0-next.5: - version "3.15.0-next.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.5.tgz#863d711bf47b338ff5e63ae19fb20d4fcd4d713b" - integrity sha512-7hrELhTeWieUgex3+6692KjCkcmO/+V/bFItM5MHGcBotzwmjEuXjapLLYTYhIspuJ1ibRSik5MhX5YwLpsPiw== +vscode-languageserver-textdocument@^1.0.0-next.3: + version "1.0.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.3.tgz#653bf15b0eb11d87eceba1360fa0bd240a98d61b" + integrity sha512-uAz2tOpYJI27Q3xJYlVwj5QAgA32gkJLi5Th5nP2uIj5EtQ6ZwBrA7Hqgy85evprLGinsdJddkPgBYEFka1v7w== + +vscode-languageserver-types@^3.15.0-next.6: + version "3.15.0-next.6" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.6.tgz#7a990d00c39ad4e744335afb4cc422a3e687ff25" + integrity sha512-+4jfvmZ26oFMSX6EgPRB75PWHoT8pzyWuSSWk0erC4hTzmJq2gWxVLh20bZutZjMmiivawvPshtM3XZhX2SttA== vscode-nls@^4.1.1: version "4.1.1" From 30e5ec101ab19728036626bc5a375b4d3728e27f Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz <42337257+wojtus7@users.noreply.github.com> Date: Wed, 6 Nov 2019 16:18:56 +0100 Subject: [PATCH 464/636] Contact modal fixes (#196) This PR resolve the following issues: Contact modal no longer affect send sheet status bar color or background When you close the contact modal, if the input was previously focused in the send flow, it refocuses --- src/components/contacts/SwipeableContactRow.js | 10 ++++++++-- src/components/expanded-state/AddContactState.js | 7 +++++++ src/components/fields/AddressField.js | 1 + src/components/inputs/Input.js | 2 ++ src/components/send/SendContactList.js | 1 + src/components/send/SendHeader.js | 12 ++++++++++-- src/navigation/transitions/effects.js | 16 ++++++++++++++++ src/screens/Routes.js | 5 +++++ src/screens/SendSheet.js | 6 ++++++ 9 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index 6ebad6fc47f..190fcf442a1 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -69,6 +69,7 @@ export default class SwipeableContactRow extends PureComponent { }; swipeableRef = undefined; + isFocused = false; close = () => this.swipeableRef.close(); @@ -84,14 +85,16 @@ export default class SwipeableContactRow extends PureComponent { handleEditContact = () => { const { address, color, navigation, nickname, onChange } = this.props; + const refocusCallback = this.isFocused && this.props.inputRef.focus; this.close(); - navigation.navigate('ExpandedAssetScreen', { + navigation.navigate('OverlayExpandedAssetScreen', { address, asset: [], color, contact: { address, color, nickname }, onCloseModal: onChange, + onRefocusInput: refocusCallback, type: 'contact', }); }; @@ -100,7 +103,10 @@ export default class SwipeableContactRow extends PureComponent { handlePress = () => this.props.onPress(this.props.address); - handlePressStart = () => this.props.onTouch(this.props.address); + handlePressStart = () => { + this.props.onTouch(this.props.address); + this.isFocused = this.props.inputRef.isFocused(); + }; handleRef = ref => { this.swipeableRef = ref; diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 4e4d905d25e..1bfc7868866 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -40,6 +40,7 @@ class AddContactState extends PureComponent { contact: PropTypes.object, navigation: PropTypes.object, onCloseModal: PropTypes.func, + onRefocusInput: PropTypes.func, onUnmountModal: PropTypes.func, }; @@ -54,6 +55,12 @@ class AddContactState extends PureComponent { } }; + componentWillUnmount = () => { + if (this.props.onRefocusInput) { + this.props.onRefocusInput(); + } + }; + inputRef = undefined; handleAddContact = async () => { diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 8c6381dd8f8..4fb85f96fca 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -102,6 +102,7 @@ export default withNavigation( handleInputRef = ref => { this.inputRef = ref; + this.props.inputRef(ref); }; onChange = ({ nativeEvent: { text } }) => { diff --git a/src/components/inputs/Input.js b/src/components/inputs/Input.js index 21111a34e1b..971567d6b74 100644 --- a/src/components/inputs/Input.js +++ b/src/components/inputs/Input.js @@ -25,6 +25,8 @@ export default class Input extends PureComponent { focus = event => this.ref.current.focus(event); + isFocused = () => this.ref.current.isFocused(); + ref = React.createRef(); render = () => { diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index fdf27925246..7c9ae6035cb 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -143,6 +143,7 @@ class SendContactList extends Component { onChange={this.props.onUpdateContacts} onPress={this.props.onPressContact} onTouch={this.closeAllDifferentContacts} + inputRef={this.props.inputRef} {...item} /> ); diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 8c293073554..1f1e8ce7b70 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -1,10 +1,10 @@ import { find, get, isEmpty, isNumber } from 'lodash'; import PropTypes from 'prop-types'; import React, { Fragment, PureComponent } from 'react'; +import styled from 'styled-components/primitives'; import { Keyboard, Clipboard } from 'react-native'; import { withNavigation } from 'react-navigation'; import { compose, withProps } from 'recompact'; -import styled from 'styled-components/primitives'; import { deleteLocalContact } from '../../handlers/localstorage/contacts'; import { withNeverRerender } from '../../hoc'; import { colors, padding } from '../../styles'; @@ -110,6 +110,7 @@ class SendHeader extends PureComponent { navigateToContact = (contact = {}) => { const { navigation, onUpdateContacts, recipient } = this.props; + const refocusCallback = this.input.isFocused() && this.input.focus; let color = get(contact, 'color'); if (!isNumber(color)) { @@ -117,12 +118,13 @@ class SendHeader extends PureComponent { } Keyboard.dismiss(); - navigation.navigate('ExpandedAssetScreen', { + navigation.navigate('OverlayExpandedAssetScreen', { address: recipient, asset: [], color, contact: isEmpty(contact) ? false : contact, onCloseModal: onUpdateContacts, + onRefocusInput: refocusCallback, type: 'contact', }); }; @@ -130,6 +132,11 @@ class SendHeader extends PureComponent { openActionSheet = () => openContactActionSheet(this.handleContactActionSheetSelection); + handleRef = ref => { + this.input = ref; + this.props.inputRef(ref); + }; + render = () => { const { contact, @@ -152,6 +159,7 @@ class SendHeader extends PureComponent { currentContact={contact} name={contact.nickname} onChange={onChangeAddressInput} + inputRef={this.handleRef} /> {isValidAddress && ( @@ -113,6 +114,10 @@ const MainNavigator = createStackNavigator( }, screen: ImportSeedPhraseSheetWithData, }, + OverlayExpandedAssetScreen: { + navigationOptions: overlayExpandedPreset, + screen: ExpandedAssetScreenWithData, + }, ReceiveModal: { navigationOptions: { ...expandedPreset, diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index cbd532bbd3a..263aa549771 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -217,6 +217,10 @@ class SendSheet extends Component { this.props.sendUpdateRecipient(event); }; + handleRef = ref => { + this.input = ref; + }; + render() { const { allAssets, @@ -246,6 +250,7 @@ class SendSheet extends Component { onPressPaste={sendUpdateRecipient} onUpdateContacts={this.onUpdateContacts} recipient={recipient} + inputRef={this.handleRef} /> {showEmptyState && ( )} {showAssetList && ( From 1a20501862277ccd2a3ebada1794d02b5115efbc Mon Sep 17 00:00:00 2001 From: osdnk Date: Wed, 6 Nov 2019 17:00:35 +0100 Subject: [PATCH 465/636] Bump RN to use master --- ios/Podfile | 2 +- ios/Podfile.lock | 340 +++++++++++++++++++++++++---------------------- package.json | 2 +- yarn.lock | 165 +++++++++++++++++------ 4 files changed, 311 insertions(+), 198 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 353cbb9e74f..596af8baa72 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -40,7 +40,7 @@ target 'Rainbow' do pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' # React Third Party - required - pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" + pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon" pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e41644cede6..b96d2e05990 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,14 +13,14 @@ PODS: - Fabric (~> 1.7.13) - DoubleConversion (1.1.6) - Fabric (1.7.13) - - FBLazyVector (0.61.2) - - FBReactNativeSpec (0.61.2): + - FBLazyVector (1000.0.0) + - FBReactNativeSpec (1000.0.0): - Folly (= 2018.10.22.00) - - RCTRequired (= 0.61.2) - - RCTTypeSafety (= 0.61.2) - - React-Core (= 0.61.2) - - React-jsi (= 0.61.2) - - ReactCommon/turbomodule/core (= 0.61.2) + - RCTRequired (= 1000.0.0) + - RCTTypeSafety (= 1000.0.0) + - React-Core (= 1000.0.0) + - React-jsi (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) - Firebase/Core (6.2.0): - Firebase/CoreOnly - FirebaseAnalytics (= 6.0.1) @@ -107,169 +107,169 @@ PODS: - nanopb/decode (0.3.9011) - nanopb/encode (0.3.9011) - Protobuf (3.10.0) - - RCTRequired (0.61.2) - - RCTTypeSafety (0.61.2): - - FBLazyVector (= 0.61.2) + - RCTRequired (1000.0.0) + - RCTTypeSafety (1000.0.0): + - FBLazyVector (= 1000.0.0) - Folly (= 2018.10.22.00) - - RCTRequired (= 0.61.2) - - React-Core (= 0.61.2) - - React (0.61.2): - - React-Core (= 0.61.2) - - React-Core/DevSupport (= 0.61.2) - - React-Core/RCTWebSocket (= 0.61.2) - - React-RCTActionSheet (= 0.61.2) - - React-RCTAnimation (= 0.61.2) - - React-RCTBlob (= 0.61.2) - - React-RCTImage (= 0.61.2) - - React-RCTLinking (= 0.61.2) - - React-RCTNetwork (= 0.61.2) - - React-RCTSettings (= 0.61.2) - - React-RCTText (= 0.61.2) - - React-RCTVibration (= 0.61.2) - - React-Core (0.61.2): + - RCTRequired (= 1000.0.0) + - React-Core (= 1000.0.0) + - React (1000.0.0): + - React-Core (= 1000.0.0) + - React-Core/DevSupport (= 1000.0.0) + - React-Core/RCTWebSocket (= 1000.0.0) + - React-RCTActionSheet (= 1000.0.0) + - React-RCTAnimation (= 1000.0.0) + - React-RCTBlob (= 1000.0.0) + - React-RCTImage (= 1000.0.0) + - React-RCTLinking (= 1000.0.0) + - React-RCTNetwork (= 1000.0.0) + - React-RCTSettings (= 1000.0.0) + - React-RCTText (= 1000.0.0) + - React-RCTVibration (= 1000.0.0) + - React-Core (1000.0.0): - Folly (= 2018.10.22.00) - glog - - React-Core/Default (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-Core/Default (= 1000.0.0) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/CoreModulesHeaders (0.61.2): + - React-Core/CoreModulesHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/Default (0.61.2): + - React-Core/Default (1000.0.0): - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/DevSupport (0.61.2): + - React-Core/DevSupport (1000.0.0): - Folly (= 2018.10.22.00) - glog - - React-Core/Default (= 0.61.2) - - React-Core/RCTWebSocket (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) - - React-jsinspector (= 0.61.2) + - React-Core/Default (= 1000.0.0) + - React-Core/RCTWebSocket (= 1000.0.0) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) + - React-jsinspector (= 1000.0.0) - Yoga - - React-Core/RCTActionSheetHeaders (0.61.2): + - React-Core/RCTActionSheetHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTAnimationHeaders (0.61.2): + - React-Core/RCTAnimationHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTBlobHeaders (0.61.2): + - React-Core/RCTBlobHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTImageHeaders (0.61.2): + - React-Core/RCTImageHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTLinkingHeaders (0.61.2): + - React-Core/RCTLinkingHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTNetworkHeaders (0.61.2): + - React-Core/RCTNetworkHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTSettingsHeaders (0.61.2): + - React-Core/RCTSettingsHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTTextHeaders (0.61.2): + - React-Core/RCTTextHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTVibrationHeaders (0.61.2): + - React-Core/RCTVibrationHeaders (1000.0.0): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-Core/RCTWebSocket (0.61.2): + - React-Core/RCTWebSocket (1000.0.0): - Folly (= 2018.10.22.00) - glog - - React-Core/Default (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsiexecutor (= 0.61.2) + - React-Core/Default (= 1000.0.0) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsiexecutor (= 1000.0.0) - Yoga - - React-CoreModules (0.61.2): - - FBReactNativeSpec (= 0.61.2) + - React-CoreModules (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) - - RCTTypeSafety (= 0.61.2) - - React-Core/CoreModulesHeaders (= 0.61.2) - - React-RCTImage (= 0.61.2) - - ReactCommon/turbomodule/core (= 0.61.2) - - React-cxxreact (0.61.2): + - RCTTypeSafety (= 1000.0.0) + - React-Core/CoreModulesHeaders (= 1000.0.0) + - React-RCTImage (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - React-cxxreact (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsinspector (= 0.61.2) - - React-jsi (0.61.2): + - React-jsinspector (= 1000.0.0) + - React-jsi (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsi/Default (= 0.61.2) - - React-jsi/Default (0.61.2): + - React-jsi/Default (= 1000.0.0) + - React-jsi/Default (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsiexecutor (0.61.2): + - React-jsiexecutor (1000.0.0): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - React-jsinspector (0.61.2) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - react-native-camera (2.11.2): @@ -294,41 +294,63 @@ PODS: - React - react-native-version-number (0.3.6): - React - - React-RCTActionSheet (0.61.2): - - React-Core/RCTActionSheetHeaders (= 0.61.2) - - React-RCTAnimation (0.61.2): - - React-Core/RCTAnimationHeaders (= 0.61.2) - - React-RCTBlob (0.61.2): - - React-Core/RCTBlobHeaders (= 0.61.2) - - React-Core/RCTWebSocket (= 0.61.2) - - React-jsi (= 0.61.2) - - React-RCTNetwork (= 0.61.2) - - React-RCTImage (0.61.2): - - React-Core/RCTImageHeaders (= 0.61.2) - - React-RCTNetwork (= 0.61.2) - - React-RCTLinking (0.61.2): - - React-Core/RCTLinkingHeaders (= 0.61.2) - - React-RCTNetwork (0.61.2): - - React-Core/RCTNetworkHeaders (= 0.61.2) - - React-RCTSettings (0.61.2): - - React-Core/RCTSettingsHeaders (= 0.61.2) - - React-RCTText (0.61.2): - - React-Core/RCTTextHeaders (= 0.61.2) - - React-RCTVibration (0.61.2): - - React-Core/RCTVibrationHeaders (= 0.61.2) - - ReactCommon/jscallinvoker (0.61.2): + - React-RCTActionSheet (1000.0.0): + - React-Core/RCTActionSheetHeaders (= 1000.0.0) + - React-RCTAnimation (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 1000.0.0) + - React-Core/RCTAnimationHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - React-RCTBlob (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - Folly (= 2018.10.22.00) + - React-Core/RCTBlobHeaders (= 1000.0.0) + - React-Core/RCTWebSocket (= 1000.0.0) + - React-jsi (= 1000.0.0) + - React-RCTNetwork (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - React-RCTImage (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 1000.0.0) + - React-Core/RCTImageHeaders (= 1000.0.0) + - React-RCTNetwork (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - React-RCTLinking (1000.0.0): + - React-Core/RCTLinkingHeaders (= 1000.0.0) + - React-RCTNetwork (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 1000.0.0) + - React-Core/RCTNetworkHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - React-RCTSettings (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 1000.0.0) + - React-Core/RCTSettingsHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - React-RCTText (1000.0.0): + - React-Core/RCTTextHeaders (= 1000.0.0) + - React-RCTVibration (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - Folly (= 2018.10.22.00) + - React-Core/RCTVibrationHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) + - ReactCommon/callinvoker (1000.0.0): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.2) - - ReactCommon/turbomodule/core (0.61.2): + - React-cxxreact (= 1000.0.0) + - ReactCommon/turbomodule/core (1000.0.0): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-Core (= 0.61.2) - - React-cxxreact (= 0.61.2) - - React-jsi (= 0.61.2) - - ReactCommon/jscallinvoker (= 0.61.2) + - React-Core (= 1000.0.0) + - React-cxxreact (= 1000.0.0) + - React-jsi (= 1000.0.0) + - ReactCommon/callinvoker (= 1000.0.0) - ReactNativePermissions (1.2.1): - React - RNAnalytics (1.1.0): @@ -344,11 +366,11 @@ PODS: - React - SDWebImage (~> 5.0) - SDWebImageWebPCoder (~> 0.2.3) - - RNFirebase (5.5.6): + - RNFirebase (4.3.8): - Firebase/Core - React - - RNFirebase/Crashlytics (= 5.5.6) - - RNFirebase/Crashlytics (5.5.6): + - RNFirebase/Crashlytics (= 4.3.8) + - RNFirebase/Crashlytics (4.3.8): - Crashlytics - Fabric - Firebase/Core @@ -431,7 +453,7 @@ DEPENDENCIES: - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) + - ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - ReactNativePermissions (from `../node_modules/react-native-permissions`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" @@ -602,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 68b6a76960fbd8ecd9fb7ce0aadd3329c3340a99 - FBReactNativeSpec: 5a764c60abdc3336a213e5310c40b74741f32839 + FBLazyVector: dfe368ae424994e0abbae8a0a245dac1bbe17dce + FBReactNativeSpec: c3eda39edb0f2a64f72b4f283dc7fa526cbebcdb Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -619,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: c639d59ed389cfb1f1203f65c2ea946d8ec586e2 - RCTTypeSafety: dc23fb655d6c77667c78e327bf661bc11e3b8aec - React: 7e586e5d7bec12b91c1a096826b0fc9ab1da7865 - React-Core: 8ddb9770b4a30a6ab4a754e6ed5ec76454e3d699 - React-CoreModules: b3d9eece8ad7df36c917a41f05c1168c52fe0b34 - React-cxxreact: 1f972757c0bd08d962ef78068e06613c27489a3f - React-jsi: 32285a21b1b24c36060493ed3057a34677d58d09 - React-jsiexecutor: 8909917ff7d8f21a57e443a866fd8d4560e50c65 - React-jsinspector: 111d7d342b07a904c400592e02a2b958f1098b60 + RCTRequired: e441b20a74068b2cf816e16c7093063fc0db4683 + RCTTypeSafety: 85890ca3d09dd0524b1502e23d36de98670c1595 + React: dedffea26228e361142276950101d28f5188ae06 + React-Core: 00d71ce2782d220edcfae727b4a7d916bc920ee4 + React-CoreModules: 3cf2528b378534350d875fe15722109e02953ad7 + React-cxxreact: 88ad047aa86d3bf9efaecbb695a54d8958fae8a0 + React-jsi: 9896ba8305509502f02b4b0da6d9e21b78c70540 + React-jsiexecutor: 63762417eb9b5f588b3cd94338cd38ad52b39031 + React-jsinspector: 46d483d40b81a594091826e42f686b818037a03c react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -637,23 +659,23 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 89b037c0fb7d2671607cb645760164e7e0c013f6 - React-RCTAnimation: e3cefa93c38c004c318f7ec04b883eb14b8b8235 - React-RCTBlob: d26ac0e313fbf14e7203473fd593ccaaeee8329e - React-RCTImage: 4bdd9588783fa9e48ef669ccd4f747224e208edf - React-RCTLinking: 65f0088ff463babd3d5d567964a65b74141eff3b - React-RCTNetwork: 0c1a73576c1cfeafe68396556de1b17d93c0c595 - React-RCTSettings: 4194f1f0edbddf3fd44d1714dc6578bb20379b60 - React-RCTText: e3ef6191cdb627855ff7fe8fa0c1e14094967fb8 - React-RCTVibration: fb54c732fd20405a76598e431aa2f8c2bf527de9 - ReactCommon: 5848032ed2f274fcb40f6b9ec24067787c42d479 + React-RCTActionSheet: d2be7e6079f09a5c73165ffab06820fe94e29107 + React-RCTAnimation: 64d9fec78fb5e0c6bc0ca72c27bffeb39dddd20e + React-RCTBlob: 53e3d825b47c2326de2d1a7b3eceb99b149918d2 + React-RCTImage: 43a717dcc465499ba47310b92539583910a6cc97 + React-RCTLinking: d0bab900790673b3caa8044304f2ed7641c75c27 + React-RCTNetwork: ec61297b59c47a296b925066570cb63e57db39fa + React-RCTSettings: 1a1b54acd4505ab050fa37bd2dfca239c871711a + React-RCTText: de3a79e40844aec13e94dcd0ede9b2bbfced32d6 + React-RCTVibration: dc613323cdb9f950a6b97b483a161f2f2f0611fc + ReactCommon: 1394d3805a63a123df135d0590cfd1a71dd01ae6 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: 58f45cb9a3161160d992f98541ab3739883dcb41 RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 - RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 + RNFirebase: 11e0ebecabffa7e6af836b955baed5d7bd02331e RNGestureHandler: a4ddde1ffc6e590c8127b8b7eabfdade45475c74 RNKeychain: c658833a9cb2cbcba6423bdd6e16cce59e27da0e RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e @@ -668,10 +690,10 @@ SPEC CHECKSUMS: SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 - ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 + ToolTipMenu: ad9f45c5ef375418275c81a667c2805bcac8692a TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 14927e37bd25376d216b150ab2a561773d57911f + Yoga: 289aa548e3ecd0c35b75517bfc64918a451c765a -PODFILE CHECKSUM: 94f1de4711040f874d0ddbdd66a5eb381627c8ed +PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 COCOAPODS: 1.8.4 diff --git a/package.json b/package.json index afba5ccbe9e..a040268bfd0 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "querystring-es3": "^0.2.1", "react": "16.9.0", "react-coin-icon": "^0.1.9", - "react-native": "0.61.2", + "react-native": "facebook/react-native", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", "react-native-circular-progress": "^1.1.0", diff --git a/yarn.lock b/yarn.lock index 262a787befe..3fe34c55095 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1934,11 +1934,6 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -art@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2" - integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ== - asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -1988,7 +1983,7 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-limiter@~1.0.0: +async-limiter@^1.0.0, async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== @@ -3277,6 +3272,14 @@ d64@^1.0.0: resolved "https://registry.yarnpkg.com/d64/-/d64-1.0.0.tgz#4002a87e850cbfc9f9d9706b60fca613a3336e90" integrity sha1-QAKofoUMv8n52XBrYPymE6MzbpA= +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3814,6 +3817,24 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.52" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.52.tgz#bb21777e919a04263736ded120a9d665f10ea63f" + integrity sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.2" + next-tick "~1.0.0" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -3826,6 +3847,14 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" +es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -3992,6 +4021,13 @@ eslint-plugin-react@^7.12.4: prop-types "^15.7.2" resolve "^1.12.0" +eslint-plugin-relay@1.3.12: + version "1.3.12" + resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.3.12.tgz#1e7d936386650ccc7709c8f6eeb0210e0e226527" + integrity sha512-276RrlyF0112Mz8PbaDvYKmqBGYEm0WBCfMNunnm6jHQ0aClUbPUmNctJXpFjfurcZfNEOz22Nx3VUMVDIGIkw== + dependencies: + graphql "^14.0.0" + eslint-rule-composer@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" @@ -4255,6 +4291,13 @@ expect@^24.9.0: jest-message-util "^24.9.0" jest-regex-util "^24.9.0" +ext@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.1.2.tgz#d1d216c83641bb4cb7684622b063cff44a19ce35" + integrity sha512-/KLjJdTNyDepCihrk4HQt57nAE1IRCEo5jUt+WgWGCr1oARhibDvmI2DMcSNWood1T9AUWwq+jaV1wvRqaXfnA== + dependencies: + type "^2.0.0" + extend-shallow@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" @@ -4958,6 +5001,13 @@ grapheme-splitter@^1.0.4: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphql@^14.0.0: + version "14.5.8" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.5.8.tgz#504f3d3114cb9a0a3f359bbbcf38d9e5bf6a6b3c" + integrity sha512-MMwmi0zlVLQKLdGiMfWkgQD7dY/TUKt4L+zgJ/aR0Howebod3aNgP5JkgvAULiR2HPVZaP2VEElqtdidHweLkg== + dependencies: + iterall "^1.2.2" + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -5852,6 +5902,11 @@ istanbul-reports@^2.2.6: dependencies: handlebars "^4.1.2" +iterall@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== + jest-changed-files@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" @@ -6892,7 +6947,7 @@ metro-babel-register@0.54.1: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-register@0.56.3, metro-babel-register@^0.56.0: +metro-babel-register@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.3.tgz#d0cfb38adf45cb35965649ede794f2308562e20f" integrity sha512-ILCRtNFdW6vzqmLAG2MYWdTSE1vCAZqDKNggiNhlfViuoxmWAIL0vOqixl1CHZF5z4t55+fk46A0jSN7UgPyVw== @@ -7115,17 +7170,7 @@ metro-react-native-babel-preset@0.56.3, metro-react-native-babel-preset@^0.56.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" - integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "0.54.1" - metro-react-native-babel-preset "0.54.1" - -metro-react-native-babel-transformer@^0.56.0: +metro-react-native-babel-transformer@0.56.3, metro-react-native-babel-transformer@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" integrity sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw== @@ -7136,6 +7181,16 @@ metro-react-native-babel-transformer@^0.56.0: metro-react-native-babel-preset "0.56.3" metro-source-map "0.56.3" +metro-react-native-babel-transformer@^0.54.1: + version "0.54.1" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" + integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.1.2" + metro-babel-transformer "0.54.1" + metro-react-native-babel-preset "0.54.1" + metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -7159,7 +7214,7 @@ metro-source-map@0.54.1: "@babel/types" "^7.0.0" source-map "^0.5.6" -metro-source-map@0.56.3, metro-source-map@^0.56.0: +metro-source-map@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.3.tgz#0cadc9f9eca9ece224a6fd28b9e4fa3a9834e24c" integrity sha512-CheqWbJZSM0zjcNBqELUiocwH3XArrOk6alhVuzJ2gV/WTMBQFwP0TtQssSMwjnouMHNEzY8RxErXKXBk/zJmQ== @@ -7620,6 +7675,11 @@ netmask@^1.0.6: resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -7801,7 +7861,7 @@ nth-check@^1.0.2: dependencies: boolbase "~1.0.0" -nullthrows@^1.1.0: +nullthrows@^1.1.0, nullthrows@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== @@ -8932,13 +8992,14 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@^3.6.3: - version "3.6.3" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" - integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== +react-devtools-core@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.2.0.tgz#d8c445809dd9fc331f619e0a1f61a7accf432080" + integrity sha512-e3EcP63jYypZLPxxfEoYTk0L53wtphIxQD6/wVXQ9uBbYNqCd3/O9dbeBtC3v1VpZj/IcelTj6yisAdrfgxgWg== dependencies: + es6-symbol "^3" shell-quote "^1.6.1" - ws "^3.3.1" + ws "^7" react-display-name@^0.2.4: version "0.2.4" @@ -9255,39 +9316,39 @@ react-native-version-number@^0.3.6: resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.6.tgz#dd8b1435fc217df0a166d7e4a61fdc993f3e7437" integrity sha512-TdyXiK90NiwmSbmAUlUBOV6WI1QGoqtvZZzI5zQY4fKl67B3ZrZn/h+Wy/OYIKKFMfePSiyfeIs8LtHGOZ/NgA== -react-native@0.61.2: - version "0.61.2" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.2.tgz#987b91b063557f8ebec803fdfea2044a24bdbe4d" - integrity sha512-hhd8bYbkkZYHoOndxUwbjJ6Yd9HFn5PvwqqS41uJ1xADdw44rx/svuwmJNA1RKF7jH74uR2jpBViWYGd36zGyg== +react-native@facebook/react-native: + version "1000.0.0" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/e99b926d27fffe8d069f9af75b976845cc3ad43f" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" abort-controller "^3.0.0" - art "^0.10.0" base64-js "^1.1.2" connect "^3.6.5" create-react-class "^15.6.3" escape-string-regexp "^1.0.5" + eslint-plugin-relay "1.3.12" event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" hermes-engine "^0.2.1" invariant "^2.2.4" jsc-android "^245459.0.0" - metro-babel-register "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" - metro-source-map "^0.56.0" - nullthrows "^1.1.0" + metro-babel-register "0.56.3" + metro-react-native-babel-transformer "0.56.3" + metro-source-map "0.56.3" + nullthrows "^1.1.1" pretty-format "^24.7.0" promise "^7.1.1" prop-types "^15.7.2" - react-devtools-core "^3.6.3" + react-devtools-core "^4.0.6" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.15.0" + scheduler "0.16.2" stacktrace-parser "^0.1.3" + use-subscription "^1.0.0" whatwg-fetch "^3.0.0" react-navigation-stack@2.0.0-alpha.35: @@ -10066,7 +10127,15 @@ schedule@0.5.0: dependencies: object-assign "^4.1.1" -scheduler@0.15.0, scheduler@^0.15.0: +scheduler@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" + integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +scheduler@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e" integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg== @@ -11241,6 +11310,16 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -11470,6 +11549,11 @@ use-memo-one@^1.1.1: resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.1.tgz#39e6f08fe27e422a7d7b234b5f9056af313bd22c" integrity sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ== +use-subscription@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.2.0.tgz#2a6789ef2cb9c5d78990a728a28630673e82f709" + integrity sha512-gbBH3zEoZycCJBisWzRkZ9IjwlWys2udleYkkNYTZYLhKRwLQbzh2ZbHXzKDvgFyim0WN/ROpp2Z1AF8wiT7zA== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -11820,6 +11904,13 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" +ws@^7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.0.tgz#422eda8c02a4b5dba7744ba66eebbd84bcef0ec7" + integrity sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg== + dependencies: + async-limiter "^1.0.0" + ws@~6.1.0: version "6.1.4" resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" From da6bc7c61cacf2e436f25d89ddd33212144c0448 Mon Sep 17 00:00:00 2001 From: osdnk Date: Wed, 6 Nov 2019 17:17:49 +0100 Subject: [PATCH 466/636] Bump firebase --- ios/Podfile.lock | 52 ++++++++++++++++++++++++------------------------ package.json | 4 ++-- yarn.lock | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b96d2e05990..95b150a3701 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -366,11 +366,11 @@ PODS: - React - SDWebImage (~> 5.0) - SDWebImageWebPCoder (~> 0.2.3) - - RNFirebase (4.3.8): + - RNFirebase (5.5.6): - Firebase/Core - React - - RNFirebase/Crashlytics (= 4.3.8) - - RNFirebase/Crashlytics (4.3.8): + - RNFirebase/Crashlytics (= 5.5.6) + - RNFirebase/Crashlytics (5.5.6): - Crashlytics - Fabric - Firebase/Core @@ -624,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: dfe368ae424994e0abbae8a0a245dac1bbe17dce - FBReactNativeSpec: c3eda39edb0f2a64f72b4f283dc7fa526cbebcdb + FBLazyVector: 4997cd4c86871321e90543c08ad25bf336b15dc0 + FBReactNativeSpec: 1efbf5ca49a44dd65d1aaffbbab5ff235c14b48f Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: e441b20a74068b2cf816e16c7093063fc0db4683 - RCTTypeSafety: 85890ca3d09dd0524b1502e23d36de98670c1595 - React: dedffea26228e361142276950101d28f5188ae06 - React-Core: 00d71ce2782d220edcfae727b4a7d916bc920ee4 - React-CoreModules: 3cf2528b378534350d875fe15722109e02953ad7 - React-cxxreact: 88ad047aa86d3bf9efaecbb695a54d8958fae8a0 - React-jsi: 9896ba8305509502f02b4b0da6d9e21b78c70540 - React-jsiexecutor: 63762417eb9b5f588b3cd94338cd38ad52b39031 - React-jsinspector: 46d483d40b81a594091826e42f686b818037a03c + RCTRequired: f4f98e40b90a111dc90bc19f693ed75a7dbabf0b + RCTTypeSafety: c1d11ad48020264d74cef722487d1bc48d185966 + React: b3c2a3a18bcb0fdd7aabb7cabec6f6567e5feb46 + React-Core: 5ab72d5415ade84499d4e84ef2bad9db54058895 + React-CoreModules: 6aa3f7f827fd5ec3606005ee3686c5e1245d5be5 + React-cxxreact: d6a11e3d6907006cda0a735bc758786c00362f33 + React-jsi: c58aa0a6c19d04c84889370b463bd79b2cc59bbc + React-jsiexecutor: b33ef6612c1e265b28ee60472331da937a9ae4d1 + React-jsinspector: efc495d68e86b8e2cef988bb3bbc9ab967579ee2 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -659,23 +659,23 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: d2be7e6079f09a5c73165ffab06820fe94e29107 - React-RCTAnimation: 64d9fec78fb5e0c6bc0ca72c27bffeb39dddd20e - React-RCTBlob: 53e3d825b47c2326de2d1a7b3eceb99b149918d2 - React-RCTImage: 43a717dcc465499ba47310b92539583910a6cc97 - React-RCTLinking: d0bab900790673b3caa8044304f2ed7641c75c27 - React-RCTNetwork: ec61297b59c47a296b925066570cb63e57db39fa - React-RCTSettings: 1a1b54acd4505ab050fa37bd2dfca239c871711a - React-RCTText: de3a79e40844aec13e94dcd0ede9b2bbfced32d6 - React-RCTVibration: dc613323cdb9f950a6b97b483a161f2f2f0611fc - ReactCommon: 1394d3805a63a123df135d0590cfd1a71dd01ae6 + React-RCTActionSheet: 56947603c6a4edaeb5e2c624094acd046b03ad33 + React-RCTAnimation: d3085d62d3b5f4608e2da0aab3bedfbe465c93bf + React-RCTBlob: 92dd323fd2d9337913aa25ece1bc80f86ce2f827 + React-RCTImage: 34df8b073a3686040c5a687b3239470bd451e314 + React-RCTLinking: 81d736708bbaa6c235a0316ee7bd0b2f21f1d0c3 + React-RCTNetwork: 6ebcc9c9e85543c95cc951e8af1b9f2761ff3779 + React-RCTSettings: 2626520ca210cbea8782f79dc1eb702dfae125df + React-RCTText: 8c0a6e89a7516ddcde04f7d2d1d31f9cd18ed13a + React-RCTVibration: 0a7f770f2586bc11409775357698295484685444 + ReactCommon: bd329d75c40bafa6a3262bf9c25b288334b85016 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: 58f45cb9a3161160d992f98541ab3739883dcb41 RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 - RNFirebase: 11e0ebecabffa7e6af836b955baed5d7bd02331e + RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 RNGestureHandler: a4ddde1ffc6e590c8127b8b7eabfdade45475c74 RNKeychain: c658833a9cb2cbcba6423bdd6e16cce59e27da0e RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e @@ -692,7 +692,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: ad9f45c5ef375418275c81a667c2805bcac8692a TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 289aa548e3ecd0c35b75517bfc64918a451c765a + Yoga: cf77b922ab94b28544e8d9b431697f6df735f5e5 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/package.json b/package.json index a040268bfd0..e8361f9fdd8 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", - "react-native-firebase": "~5.5.5", + "react-native-firebase": "^5.5.6", "react-native-gesture-handler": "^1.4.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", @@ -249,4 +249,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 3fe34c55095..77e5023e148 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9104,7 +9104,7 @@ react-native-fast-image@andrewschenk-linx/react-native-fast-image#fix-ios-xcode- version "7.0.2" resolved "https://codeload.github.com/andrewschenk-linx/react-native-fast-image/tar.gz/d19ae11a6469de94cb49211d00a7bc002ea76ff8" -react-native-firebase@~5.5.5: +react-native-firebase@5.5.6: version "5.5.6" resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-5.5.6.tgz#17b34ec0d5dc39afaaf0e159fd160f6339e0f707" integrity sha512-AdbpGwKEEiMFgaRar9WOPc8Li4sfxR//WOyNQzxYsQ1fpARC908j7feqy2gu73SLqk4wzIrnlfJWakOe0/Bclg== From a68af4563f873c18f14be789134c7eabe2d1c64a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 5 Nov 2019 22:19:33 -0500 Subject: [PATCH 467/636] Fix wrong gasPrice displaying on first load --- src/components/gas/GasSpeedButton.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/gas/GasSpeedButton.js b/src/components/gas/GasSpeedButton.js index c220e8c9c05..359b3fbe4fc 100644 --- a/src/components/gas/GasSpeedButton.js +++ b/src/components/gas/GasSpeedButton.js @@ -62,9 +62,9 @@ class GasSpeedButton extends PureComponent { analytics.track('Updated Gas Price', { gasPrice: nextSpeedGweiValue }); }; - formatAnimatedGasPrice = gasPrice => { - const price = parseFloat(gasPrice || '0.00').toFixed(3); - return `${this.props.nativeCurrencySymbol}${price}`; + formatAnimatedGasPrice = animatedPrice => { + const formattedPrice = parseFloat(animatedPrice).toFixed(3); + return `${this.props.nativeCurrencySymbol}${formattedPrice}`; }; formatAnimatedEstimatedTime = estimatedTime => { @@ -117,10 +117,12 @@ export default compose( '' ).split(' '); + const gasPrice = get(selectedGasPrice, 'txFee.native.value.amount'); + return { estimatedTimeUnit: estimatedTime[1] || 'min', estimatedTimeValue: estimatedTime[0] || 0, - price: get(selectedGasPrice, 'txFee.native.value.amount', '0.00'), + price: isNaN(gasPrice) ? '0.00' : gasPrice, ...props, }; }), From 380e81d66d0c9debaa9641363405cc50fd1e4290 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 5 Nov 2019 22:26:40 -0500 Subject: [PATCH 468/636] Create compareObjectAtPaths utility to simplify shouldComponentUpdate code --- package.json | 1 + src/utils/compareObjectsAtPaths.js | 6 ++++++ src/utils/index.js | 1 + yarn.lock | 9 +++++++++ 4 files changed, 17 insertions(+) create mode 100644 src/utils/compareObjectsAtPaths.js diff --git a/package.json b/package.json index e8361f9fdd8..32386b25498 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "querystring-es3": "^0.2.1", "react": "16.9.0", "react-coin-icon": "^0.1.9", + "react-fast-compare": "^2.0.4", "react-native": "facebook/react-native", "react-native-actionsheet": "^2.4.2", "react-native-camera": "^2.11.0", diff --git a/src/utils/compareObjectsAtPaths.js b/src/utils/compareObjectsAtPaths.js new file mode 100644 index 00000000000..d4b5b67aeb1 --- /dev/null +++ b/src/utils/compareObjectsAtPaths.js @@ -0,0 +1,6 @@ +import { pick } from 'lodash'; +import isEqual from 'react-fast-compare'; + +export default function compareObjectsAtPaths(a, b, paths) { + return !isEqual(pick(a, paths), pick(b, paths)); +} diff --git a/src/utils/index.js b/src/utils/index.js index f1c1cd05a42..f6813765d4a 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,5 +1,6 @@ export { default as abbreviations } from './abbreviations'; export { default as addressUtils } from './address'; +export { default as compareObjectsAtPaths } from './compareObjectsAtPaths'; export { default as contractUtils } from './contract'; export { default as deviceUtils } from './deviceUtils'; export { default as dimensionsPropType } from './dimensionsPropType'; diff --git a/yarn.lock b/yarn.lock index 77e5023e148..83094c0f9ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9006,7 +9006,16 @@ react-display-name@^0.2.4: resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.4.tgz#e2a670b81d79a2204335510c01246f4c92ff12cf" integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== +<<<<<<< HEAD react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: +======= +react-fast-compare@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: +>>>>>>> e28d005a... Create compareObjectAtPaths utility to simplify shouldComponentUpdate code version "16.11.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== From 13546a42c28fa7ad46f6ffe80c8a1b2b83ff429a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 5 Nov 2019 22:28:31 -0500 Subject: [PATCH 469/636] =?UTF-8?q?Simplify=20ExchangeInputField=E2=80=99s?= =?UTF-8?q?=20sCU=20definition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/exchange/ExchangeInputField.js | 52 ++++--------------- 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 0692c18282d..a66bcd62f8f 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; import { colors } from '../../styles'; -import { isNewValueForPath } from '../../utils'; +import { compareObjectsAtPaths } from '../../utils'; import { ButtonPressAnimation } from '../animations'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; @@ -34,47 +34,15 @@ export default class ExchangeInputField extends Component { setNativeAmount: PropTypes.func, }; - shouldComponentUpdate = nextProps => { - const isNewAssetApproved = isNewValueForPath( - this.props, - nextProps, - 'isAssetApproved' - ); - const isNewInputAmount = isNewValueForPath( - this.props, - nextProps, - 'inputAmount' - ); - const isNewInputCurrency = isNewValueForPath( - this.props, - nextProps, - 'inputCurrencySymbol' - ); - const isNewNativeAmount = isNewValueForPath( - this.props, - nextProps, - 'nativeAmount' - ); - const isNewNativeCurrency = isNewValueForPath( - this.props, - nextProps, - 'nativeCurrency' - ); - const isNewUnlockingAsset = isNewValueForPath( - this.props, - nextProps, - 'isUnlockingAsset' - ); - - return ( - isNewAssetApproved || - isNewInputAmount || - isNewInputCurrency || - isNewNativeAmount || - isNewNativeCurrency || - isNewUnlockingAsset - ); - }; + shouldComponentUpdate = nextProps => + compareObjectsAtPaths(this.props, nextProps, [ + 'inputAmount', + 'inputCurrencySymbol', + 'isAssetApproved', + 'isUnlockingAsset', + 'nativeAmount', + 'nativeCurrency', + ]); inputFieldRef = undefined; From d100bfc6f52214e1b2412808e5754c183f4c351b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 5 Nov 2019 22:29:44 -0500 Subject: [PATCH 470/636] =?UTF-8?q?Simplify=20CurrencySelectModal=E2=80=99?= =?UTF-8?q?s=20sCU=20definition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/screens/CurrencySelectModal.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index a34342125d4..29e5c697d11 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -65,17 +65,14 @@ class CurrencySelectModal extends Component { const currentAssetsUniqueId = buildUniqueIdForListData(currentAssets); const nextAssetsUniqueId = buildUniqueIdForListData(nextAssets); - const isNewAssets = currentAssetsUniqueId !== nextAssetsUniqueId; - const isNewFocus = isNewValueForPath(this.props, nextProps, 'isFocused'); - const isNewSearchQuery = isNewValueForPath( - this.state, - nextState, - 'searchQuery' - ); - const isNewType = isNewValueForPath(this.props, nextProps, 'type'); - return isNewAssets || isNewFocus || isNewSearchQuery || isNewType; + return ( + isNewAssets || + isNewValueForPath(this.props, nextProps, 'isFocused') || + isNewValueForPath(this.props, nextProps, 'type') || + isNewValueForPath(this.state, nextState, 'searchQuery') + ); }; dangerouslySetIsGestureBlocked = isGestureBlocked => { From e838383ce1761acdc9180d695300268804af33ab Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 5 Nov 2019 22:32:05 -0500 Subject: [PATCH 471/636] Autocapitalize ExchangeSearch input text --- src/components/exchange/ExchangeSearch.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 6f6c38b8134..0af357ab38b 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -50,6 +50,7 @@ export default class ExchangeSearch extends PureComponent { Date: Mon, 4 Nov 2019 19:51:11 -0500 Subject: [PATCH 472/636] Update or clear Swap inputs depending on new chosen currency Fixes RAI-26 https://linear.app/issue/RAI-26 Fixes RAI-54 https://linear.app/issue/RAI-54 --- ios/Podfile.lock | 8 +- package.json | 2 +- src/screens/ExchangeModal.js | 139 +++++++++++++++++++---------------- yarn.lock | 46 ++++++------ 4 files changed, 104 insertions(+), 91 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 95b150a3701..eeb8682431d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -42,7 +42,7 @@ PODS: - FirebaseCore (6.0.2): - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/Logger (~> 6.0) - - FirebaseInstanceID (4.2.6): + - FirebaseInstanceID (4.2.7): - FirebaseCore (~> 6.0) - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/UserDefaults (~> 6.0) @@ -630,7 +630,7 @@ SPEC CHECKSUMS: FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 FirebaseCore: b0f0262acebfa540e5f97b3832dbb13186980822 - FirebaseInstanceID: d0eafcd8bdbd3447cd694594734078c3e3e77d8b + FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e FirebaseMessaging: 20b6626c41be7840aed7a3dd9a14003efae3d588 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 @@ -694,6 +694,10 @@ SPEC CHECKSUMS: TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 Yoga: cf77b922ab94b28544e8d9b431697f6df735f5e5 +<<<<<<< HEAD PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 +======= +PODFILE CHECKSUM: e87657d72331258847a818082180e92c3f95b480 +>>>>>>> f3b87a7f... Update or clear Swap inputs depending on new chosen currency COCOAPODS: 1.8.4 diff --git a/package.json b/package.json index 32386b25498..2433791a268 100644 --- a/package.json +++ b/package.json @@ -250,4 +250,4 @@ "vm": "vm-browserify", "tls": false } -} +} \ No newline at end of file diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 3b63e923368..a6c420475bd 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -9,7 +9,7 @@ import { import BigNumber from 'bignumber.js'; import { get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; +import React, { Component, Fragment } from 'react'; import { LayoutAnimation, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { withNavigationFocus, NavigationEvents } from 'react-navigation'; @@ -53,6 +53,7 @@ import { } from '../hoc'; import { colors, padding, position } from '../styles'; import { + compareObjectsAtPaths, contractUtils, ethereumUtils, gasUtils, @@ -66,17 +67,14 @@ const AnimatedFloatingPanels = Animated.createAnimatedComponent( toClass(FloatingPanels) ); -const isSameAsset = (firstAsset, secondAsset) => { - if (!firstAsset || !secondAsset) { - return false; - } - - const firstAddress = toLower(get(firstAsset, 'address', '')); - const secondAddress = toLower(get(secondAsset, 'address', '')); - return firstAddress === secondAddress; +const isSameAsset = (a, b) => { + if (!a || !b) return false; + const assetA = toLower(get(a, 'address', '')); + const assetB = toLower(get(b, 'address', '')); + return assetA === assetB; }; -class ExchangeModal extends React.Component { +class ExchangeModal extends Component { static propTypes = { accountAddress: PropTypes.string, allAssets: PropTypes.array, @@ -125,55 +123,79 @@ class ExchangeModal extends React.Component { tradeDetails: null, }; + shouldComponentUpdate = (nextProps, nextState) => { + const isNewProps = compareObjectsAtPaths(this.props, nextProps, [ + 'inputReserve.token.address', + 'outputReserve.token.address', + ]); + + const isNewState = compareObjectsAtPaths(this.state, nextState, [ + 'approvalCreationTimestamp', + 'approvalEstimatedTimeInMs', + 'inputAmount', + 'inputCurrency.uniqueId', + 'isAssetApproved', + 'isUnlockingAsset', + 'nativeAmount', + 'outputAmount', + 'outputCurrency.uniqueId', + 'slippage', + ]); + + return nextProps.isFocused ? isNewProps || isNewState : false; + }; + componentDidUpdate = (prevProps, prevState) => { if (prevProps.isTransitioning && !this.props.isTransitioning) { this.props.navigation.emit('refocus'); } - const isNewInputAmount = isNewValueForPath( - this.state, - prevState, - 'inputAmount' - ); - const isNewOutputAmount = isNewValueForPath( + + const isNewAmountOrCurrency = compareObjectsAtPaths(this.state, prevState, [ + 'inputAmount', + 'inputCurrency.uniqueId', + 'outputAmount', + 'outputCurrency.uniqueId', + ]); + + let isNewNativeAmount = isNewValueForPath( this.state, prevState, - 'outputAmount' + 'nativeAmount' ); - const isNewNativeAmount = + + if (isNewNativeAmount) { // Only consider 'new' if the native input isnt focused, // otherwise itll fight with the user's keystrokes - isNewValueForPath(this.state, prevState, 'nativeAmount') && - this.nativeFieldRef.isFocused(); + isNewNativeAmount = this.nativeFieldRef.isFocused(); + } - const isNewInputCurrency = isNewValueForPath( - this.state, - prevState, - 'inputCurrency.uniqueId' - ); - const isNewOutputCurrency = isNewValueForPath( - this.state, - prevState, - 'outputCurrency.uniqueId' + const isNewOutputReserveCurrency = isNewValueForPath( + this.props, + prevProps, + 'outputReserve.token.address' ); - const isNewAmount = - (this.state.inputAsExactAmount && - (isNewNativeAmount || isNewInputAmount)) || - (!this.state.inputAsExactAmount && isNewOutputAmount); - const isNewCurrency = isNewInputCurrency || isNewOutputCurrency; + if ( + isNewAmountOrCurrency || + isNewNativeAmount || + isNewOutputReserveCurrency + ) { + LayoutAnimation.easeInEaseOut(); + this.getMarketDetails(isNewOutputReserveCurrency); + } + + const inputCurrencyAddressPath = 'inputCurrency.address'; + const inputCurrencyAddress = toLower( + get(this.state, inputCurrencyAddressPath) + ); - const input = toLower(get(this.state.inputCurrency, 'address')); const removedFromPending = - !get(this.props, `pendingApprovals[${input}]`, null) && - get(prevProps, `pendingApprovals[${input}]`, null); + !get(this.props, `pendingApprovals[${inputCurrencyAddress}]`, null) && + get(prevProps, `pendingApprovals[${inputCurrencyAddress}]`, null); - if (isNewAmount || isNewCurrency) { - this.getMarketDetails(); - LayoutAnimation.easeInEaseOut(); - } if ( removedFromPending || - isNewValueForPath(this.state, prevState, 'inputCurrency.address') + isNewValueForPath(this.props, prevProps, inputCurrencyAddressPath) ) { this.getCurrencyAllowance(); } @@ -267,7 +289,7 @@ class ExchangeModal extends React.Component { } }; - getMarketDetails = async () => { + getMarketDetails = async isNewOutputCurrency => { const { accountAddress, chainId, @@ -416,7 +438,7 @@ class ExchangeModal extends React.Component { this.clearForm(); } - if (inputAsExactAmount && !this.outputFieldRef.isFocused()) { + if (inputAsExactAmount || (isNewOutputCurrency && inputAsExactAmount)) { if (isInputEmpty || isInputZero) { this.setOutputAmount(); } else { @@ -469,6 +491,7 @@ class ExchangeModal extends React.Component { }); } } + if (isAssetApproved) { const gasLimit = await estimateSwapGasLimit( accountAddress, @@ -482,22 +505,6 @@ class ExchangeModal extends React.Component { } }; - getReserveData = async tokenAddress => { - if (tokenAddress === 'eth') return null; - - const { tokenReserves, uniswapGetTokenReserve } = this.props; - - let reserve = tokenReserves[tokenAddress.toLowerCase()]; - if (!reserve) { - reserve = await uniswapGetTokenReserve(tokenAddress); - } - return reserve; - }; - - handleBlurField = ({ currentTarget }) => { - console.log('blur', currentTarget); - }; - handleFocusField = ({ currentTarget }) => { this.lastFocusedInput = currentTarget; }; @@ -634,6 +641,10 @@ class ExchangeModal extends React.Component { setInputCurrency = (inputCurrency, force) => { const { outputCurrency } = this.state; + if (!isSameAsset(inputCurrency, this.state.inputCurrency)) { + this.clearForm(); + } + this.setState({ inputCurrency }); if (!force) { @@ -685,13 +696,15 @@ class ExchangeModal extends React.Component { const { allAssets } = this.props; const { inputCurrency } = this.state; + if (!force) { + this.props.uniswapUpdateOutputCurrency(outputCurrency); + } + this.setState({ + inputAsExactAmount: true, outputCurrency, showConfirmButton: !!outputCurrency, }); - if (!force) { - this.props.uniswapUpdateOutputCurrency(outputCurrency); - } if (!force && isSameAsset(inputCurrency, outputCurrency)) { const outputAddress = toLower(outputCurrency.address); diff --git a/yarn.lock b/yarn.lock index 83094c0f9ca..f8193a65c4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1426,14 +1426,14 @@ "@types/node" "*" "@types/node@*": - version "12.12.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.5.tgz#66103d2eddc543d44a04394abb7be52506d7f290" - integrity sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A== + version "12.12.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.6.tgz#a47240c10d86a9a57bb0c633f0b2e0aea9ce9253" + integrity sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA== "@types/node@^10.3.2": - version "10.17.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.3.tgz#65a8d9a6a0f6af55595a2d0020617959130d6495" - integrity sha512-QZ9CjUB3QoA3f2afw3utKlfRPhpmufB7jC2+oDhLWnXqoyx333fhKSQDLQu2EK7OE0a15X67eYiRAaJsHXrpMA== + version "10.17.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.4.tgz#8993a4fe3c4022fda66bf4ea660d615fc5659c6f" + integrity sha512-F2pgg+LcIr/elguz+x+fdBX5KeZXGUOp7TV8M0TVIrDezYLFRNt8oMTyps0VQ1kj5WGGoR18RdxnRDHXrIFHMQ== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -3069,9 +3069,9 @@ contains-path@^0.1.0: integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" @@ -3671,9 +3671,9 @@ ejs@^2.7.1: integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.295: - version "1.3.303" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.303.tgz#3059bcc39c1c3b492ca381d577b6a49b5050085e" - integrity sha512-xDFPmMjJ0gQBsVwspB0bjcbFn3MVcvU0sxXYmh1UMbZ6rDogQVM3vSyOvTO4rym1KlnJIU6nqzK3qs0yKudmjw== + version "1.3.304" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.304.tgz#49b47d961f8143116174c2f70fbfee3aabf43015" + integrity sha512-a5mqa13jCdBc+Crgk3Gyr7vpXCiFWfFq23YDCEmrPYeiDOQKZDVE6EX/Q4Xdv97n3XkcjiSBDOY0IS19yP2yeA== elliptic@6.3.3: version "6.3.3" @@ -9006,16 +9006,12 @@ react-display-name@^0.2.4: resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.4.tgz#e2a670b81d79a2204335510c01246f4c92ff12cf" integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== -<<<<<<< HEAD -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: -======= react-fast-compare@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: ->>>>>>> e28d005a... Create compareObjectAtPaths utility to simplify shouldComponentUpdate code +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: version "16.11.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== @@ -11692,20 +11688,20 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.6" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.6.tgz#5a859ed0e46d37f83726b875691a3a0152c7ea49" - integrity sha512-FHuGne8eOJ88yHGNmm/6Kamyj4N03m6dJXq0UXdIY1GpYrulJBDxYnSDD5WaOnMLDtoGFlrE8I1Fq3n+gnfnLQ== + version "3.4.7" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.7.tgz#8d85f3c1d46a1e58e9867d747552fb8c83d934fd" + integrity sha512-y3MN2+/yph3yoIHGmHu4ScYpm285L58XVvfGkd49xTQzLja4apxSbwzsYcP9QsqS0W7KuvoyiPhqksiudoMwjg== dependencies: jsonc-parser "^2.2.0" - vscode-languageserver-textdocument "^1.0.0-next.3" + vscode-languageserver-textdocument "^1.0.0-next.4" vscode-languageserver-types "^3.15.0-next.6" vscode-nls "^4.1.1" vscode-uri "^2.1.0" -vscode-languageserver-textdocument@^1.0.0-next.3: - version "1.0.0-next.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.3.tgz#653bf15b0eb11d87eceba1360fa0bd240a98d61b" - integrity sha512-uAz2tOpYJI27Q3xJYlVwj5QAgA32gkJLi5Th5nP2uIj5EtQ6ZwBrA7Hqgy85evprLGinsdJddkPgBYEFka1v7w== +vscode-languageserver-textdocument@^1.0.0-next.4: + version "1.0.0-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.4.tgz#8f7afdfe3e81411f57baaa29bb3214d1907160cd" + integrity sha512-LJ5WfoBO54nqinjlLJKnjoo2Im4bIvPJ8bFT7R0C84ZI36iK8M29ddslfe5jUeWNSTtCda7YuKdKsDIq38HpgA== vscode-languageserver-types@^3.15.0-next.6: version "3.15.0-next.6" From 9e9b59b9ac713c7022c23a6d7ab4ec5d424a0cb1 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 03:22:15 -0500 Subject: [PATCH 473/636] improve walletscreen sCU --- src/screens/WalletScreen.js | 67 +++++++------------------------------ 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 38d67714f08..179991f2bfc 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -34,7 +34,7 @@ import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; -import { isNewValueForPath } from '../utils'; +import { compareObjectsAtPaths } from '../utils'; class WalletScreen extends Component { static propTypes = { @@ -42,7 +42,6 @@ class WalletScreen extends Component { allAssetsCount: PropTypes.number, assets: PropTypes.array, assetsTotal: PropTypes.object, - blurIntensity: PropTypes.object, initializeWallet: PropTypes.func, isEmpty: PropTypes.bool.isRequired, isFocused: PropTypes.bool, @@ -66,60 +65,20 @@ class WalletScreen extends Component { }; shouldComponentUpdate = nextProps => { - const isNewBlurIntensity = isNewValueForPath( - this.props, - nextProps, - 'blurIntensity' - ); - const isNewCurrency = isNewValueForPath( - this.props, - nextProps, - 'nativeCurrency' - ); - const isNewFetchingAssets = isNewValueForPath( - this.props, - nextProps, - 'fetchingAssets' - ); - const isNewFetchingUniqueTokens = isNewValueForPath( - this.props, - nextProps, - 'fetchingUniqueTokens' - ); - const isNewIsWalletEmpty = isNewValueForPath( - this.props, - nextProps, - 'isEmpty' - ); - const isNewIsWalletEthZero = isNewValueForPath( - this.props, - nextProps, - 'isWalletEthZero' - ); - const isNewLanguage = isNewValueForPath(this.props, nextProps, 'language'); - const isNewSections = isNewValueForPath(this.props, nextProps, 'sections'); + const shouldUpdate = compareObjectsAtPaths(this.props, nextProps, [ + 'fetchingAssets', + 'fetchingUniqueTokens', + 'isEmpty', + 'isWalletEthZero', + 'language', + 'nativeCurrency', + 'sections', + ]); - const isNewTransitionProps = isNewValueForPath( - this.props, - nextProps, - 'transitionProps' - ); - - if (!nextProps.isFocused) { - return isNewBlurIntensity || isNewTransitionProps; - } + console.log('nextProps', nextProps); + console.log('shouldUpdate', shouldUpdate); - return ( - isNewFetchingAssets || - isNewFetchingUniqueTokens || - isNewIsWalletEmpty || - isNewIsWalletEthZero || - isNewLanguage || - isNewCurrency || - isNewBlurIntensity || - isNewSections || - isNewTransitionProps - ); + return shouldUpdate; }; setInitialStatesForOpenAssets = async () => { From e25a649f31f4acc6fa98d615728449e32f1259c4 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 19:07:05 -0500 Subject: [PATCH 474/636] bump lock files after rebase --- ios/Podfile.lock | 54 ++++++++--------- yarn.lock | 155 ++++++++++++++++++++++++----------------------- 2 files changed, 105 insertions(+), 104 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index eeb8682431d..1a0ddfcaa79 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -358,7 +358,7 @@ PODS: - React - RNCAsyncStorage (1.6.2): - React - - RNCMaskedView (0.1.4): + - RNCMaskedView (0.1.5): - React - RNDeviceInfo (2.3.2): - React @@ -624,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 4997cd4c86871321e90543c08ad25bf336b15dc0 - FBReactNativeSpec: 1efbf5ca49a44dd65d1aaffbbab5ff235c14b48f + FBLazyVector: e74f526a074b06a86745c93f853d025f32962829 + FBReactNativeSpec: 7e9c3640035bbcb5b766b5ac5be585bb3bc0ddc9 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: f4f98e40b90a111dc90bc19f693ed75a7dbabf0b - RCTTypeSafety: c1d11ad48020264d74cef722487d1bc48d185966 - React: b3c2a3a18bcb0fdd7aabb7cabec6f6567e5feb46 - React-Core: 5ab72d5415ade84499d4e84ef2bad9db54058895 - React-CoreModules: 6aa3f7f827fd5ec3606005ee3686c5e1245d5be5 - React-cxxreact: d6a11e3d6907006cda0a735bc758786c00362f33 - React-jsi: c58aa0a6c19d04c84889370b463bd79b2cc59bbc - React-jsiexecutor: b33ef6612c1e265b28ee60472331da937a9ae4d1 - React-jsinspector: efc495d68e86b8e2cef988bb3bbc9ab967579ee2 + RCTRequired: e07e94a77b9df606f736440754173024d03c3cdd + RCTTypeSafety: e1702d2523892617bd93c2dd016fff3556379084 + React: fb9d2c4dad053590fee17959504136f6d75b7c71 + React-Core: 08128bafbabbc2706278b82a828d4d63f3178c0a + React-CoreModules: 2582fc278afb16068de16cf16e7b39749482b605 + React-cxxreact: 1214ba1e57d7f6dfcf39a2a38a02611443ee5416 + React-jsi: 23923fb832c01e6f5652757e15e5cf1b88a7e961 + React-jsiexecutor: 732c2b6b9b7ff31a386e91c1a84d9d2fc945e1ea + React-jsinspector: 1c06737e9ba1f55cfb72cd32072c849e67ed7216 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -659,20 +659,20 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 56947603c6a4edaeb5e2c624094acd046b03ad33 - React-RCTAnimation: d3085d62d3b5f4608e2da0aab3bedfbe465c93bf - React-RCTBlob: 92dd323fd2d9337913aa25ece1bc80f86ce2f827 - React-RCTImage: 34df8b073a3686040c5a687b3239470bd451e314 - React-RCTLinking: 81d736708bbaa6c235a0316ee7bd0b2f21f1d0c3 - React-RCTNetwork: 6ebcc9c9e85543c95cc951e8af1b9f2761ff3779 - React-RCTSettings: 2626520ca210cbea8782f79dc1eb702dfae125df - React-RCTText: 8c0a6e89a7516ddcde04f7d2d1d31f9cd18ed13a - React-RCTVibration: 0a7f770f2586bc11409775357698295484685444 - ReactCommon: bd329d75c40bafa6a3262bf9c25b288334b85016 + React-RCTActionSheet: 656fa18d132e3ecbda8fe65c0580e0b88bc40816 + React-RCTAnimation: 812c33d4de7dd1d9c76097e0bf461c2fb60f0677 + React-RCTBlob: 45f5811c9310779d4597b89b6e6b140063f17245 + React-RCTImage: 922254fde24d3bed938d7b6b263a947479f4eea8 + React-RCTLinking: 374b21bafa74a6264691a6e95a2e4b3648668b09 + React-RCTNetwork: 2e9acea301b97f19423c06a2b7d4f12a6ed09220 + React-RCTSettings: e2b74046208f6554c5855d409adcae5d363bfb25 + React-RCTText: 3c26ff3b26253114540fe20b2ac8ee3c961b8882 + React-RCTVibration: 6defa525322047b4fb8f9ccfc3679e60e4070a0c + ReactCommon: b010d47dbf91d58171b63f9b2fb6609dde87f510 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f - RNCMaskedView: 58f45cb9a3161160d992f98541ab3739883dcb41 + RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 @@ -690,14 +690,10 @@ SPEC CHECKSUMS: SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 - ToolTipMenu: ad9f45c5ef375418275c81a667c2805bcac8692a + ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: cf77b922ab94b28544e8d9b431697f6df735f5e5 + Yoga: 85076db2046b2b95464aceeee981bd4b834c670e -<<<<<<< HEAD PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 -======= -PODFILE CHECKSUM: e87657d72331258847a818082180e92c3f95b480 ->>>>>>> f3b87a7f... Update or clear Swap inputs depending on new chosen currency COCOAPODS: 1.8.4 diff --git a/yarn.lock b/yarn.lock index f8193a65c4e..6693cd287f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,18 +10,18 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.6.2": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.0.tgz#461d2948b1a7113088baf999499bcbd39a7faa3b" - integrity sha512-Bb1NjZCaiwTQC/ARL+MwDpgocdnwWDCaugvkGt6cxfBzQa8Whv1JybBoUEiBDKl8Ni3H3c7Fykwk7QChUsHRlg== + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" + integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.0" + "@babel/generator" "^7.7.2" "@babel/helpers" "^7.7.0" - "@babel/parser" "^7.7.0" + "@babel/parser" "^7.7.2" "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - convert-source-map "^1.1.0" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.7.2" + convert-source-map "^1.7.0" debug "^4.1.0" json5 "^2.1.0" lodash "^4.17.13" @@ -29,12 +29,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.0.tgz#c6d4d1f7a0d6e139cbd01aca73170b0bff5425b4" - integrity sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.2.tgz#2f4852d04131a5e17ea4f6645488b5da66ebf3af" + integrity sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.2" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -84,9 +84,9 @@ "@babel/helper-split-export-declaration" "^7.7.0" "@babel/helper-create-regexp-features-plugin@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.0.tgz#2e8badfe201cfafb5d930f46cf1e0b6f1cdcab23" - integrity sha512-ZhagAAVGD3L6MPM9/zZi7RRteonfBFLVUz3kjsnYsMAtr9hOJCKI9BAKIMpqn3NyWicPieoX779UL+7/3BEAOA== + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz#6f20443778c8fce2af2ff4206284afc0ced65db6" + integrity sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ== dependencies: "@babel/helper-regex" "^7.4.4" regexpu-core "^4.6.0" @@ -240,10 +240,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.0.tgz#232618f6e8947bc54b407fa1f1c91a22758e7159" - integrity sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.2.tgz#ea8334dc77416bfd9473eb470fd00d8245b3943b" + integrity sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -587,9 +587,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.0.tgz#182be03fa8bd2ffd0629791a1eaa4373b7589d38" - integrity sha512-y3KYbcfKe+8ziRXiGhhnGrVysDBo5+aJdB+x8sanM0K41cnmK7Q5vBlQLMbOnW/HPjLG9bg7dLgYDQZZG9T09g== + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.2.tgz#eb9f14c516b5d36f4d6f3a9d7badae6d0fc313d4" + integrity sha512-UWhDaJRqdPUtdK1s0sKYdoRuqK0NepjZto2UZltvuCgMoMZmdjhgz5hcRokie/3aYEaSz3xvusyoayVaq4PjRg== dependencies: "@babel/helper-create-class-features-plugin" "^7.7.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -615,9 +615,9 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2": - version "7.7.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.1.tgz#b223497bbfbcbbb38116673904debc71470ca528" - integrity sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ== + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" + integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== dependencies: regenerator-runtime "^0.13.2" @@ -630,25 +630,25 @@ "@babel/parser" "^7.7.0" "@babel/types" "^7.7.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.0.tgz#9f5744346b8d10097fd2ec2eeffcaf19813cbfaf" - integrity sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.2.tgz#ef0a65e07a2f3c550967366b3d9b62a2dcbeae09" + integrity sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.0" + "@babel/generator" "^7.7.2" "@babel/helper-function-name" "^7.7.0" "@babel/helper-split-export-declaration" "^7.7.0" - "@babel/parser" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/parser" "^7.7.2" + "@babel/types" "^7.7.2" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.7.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.1.tgz#8b08ea368f2baff236613512cf67109e76285827" - integrity sha512-kN/XdANDab9x1z5gcjDc9ePpxexkt+1EQ2MQUiM4XnMvQfvp87/+6kY4Ko2maLXH+tei/DgJ/ybFITeqqRwDiA== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7" + integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA== dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1161,9 +1161,9 @@ ws "^1.1.0" "@react-native-community/masked-view@^0.1.1": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.4.tgz#e0f8952a30014922929d7742a0809bc108e66549" - integrity sha512-bP6FWEa1qaRJb1aKA9ni/2/D8NoBZU54oFyEeGnxkax80No4YCHFGmRW8xcFwgZ2TXWuRSoI1xpGzuWfspHs/g== + version "0.1.5" + resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.5.tgz#25421be6cd943a4b1660b62cfbcd45be8891462c" + integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== "@react-native-community/netinfo@^4.1.4": version "4.6.0" @@ -3068,7 +3068,7 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0: +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -3312,9 +3312,9 @@ date-fns@^1.30.1: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.8.15: - version "1.8.16" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.16.tgz#2a3771de537255191b947957af2fd90012e71e64" - integrity sha512-XPmqzWz/EJiaRHjBqSJ2s6hE/BUoCIHKgdS2QPtTQtKcS9E4/Qn0WomoH1lXanWCzri+g7zPcuNV4aTZ8PMORQ== + version "1.8.17" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.17.tgz#53ec413f2a7b02afbea1846d61bb260fa8567cea" + integrity sha512-47VY/htqYqr9GHd7HW/h56PpQzRBSJcxIQFwqL3P20bMF/3az5c3PWdVY3LmPXFl6cQCYHL7c79b9ov+2bOBbw== debounce@^1.2.0: version "1.2.0" @@ -4413,7 +4413,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= -fast-levenshtein@~2.0.4: +fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -4901,9 +4901,9 @@ glob@^6.0.1: path-is-absolute "^1.0.0" glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" - integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ== + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -5493,7 +5493,7 @@ ip-regex@^1.0.3: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0= -ip@^1.1.5: +ip@1.1.5, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -8087,16 +8087,16 @@ optimist@^0.6.1: wordwrap "~0.0.2" optionator@^0.8.1, optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: deep-is "~0.1.3" - fast-levenshtein "~2.0.4" + fast-levenshtein "~2.0.6" levn "~0.3.0" prelude-ls "~1.1.2" type-check "~0.3.2" - wordwrap "~1.0.0" + word-wrap "~1.2.3" options@>=0.0.5: version "0.0.6" @@ -8496,9 +8496,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.0.tgz#0fd042f568d08b1ad9ff2d3ec0f0bfb3cb80e177" - integrity sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw== + version "2.1.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5" + integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA== pify@^2.0.0: version "2.3.0" @@ -9109,7 +9109,7 @@ react-native-fast-image@andrewschenk-linx/react-native-fast-image#fix-ios-xcode- version "7.0.2" resolved "https://codeload.github.com/andrewschenk-linx/react-native-fast-image/tar.gz/d19ae11a6469de94cb49211d00a7bc002ea76ff8" -react-native-firebase@5.5.6: +react-native-firebase@^5.5.6: version "5.5.6" resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-5.5.6.tgz#17b34ec0d5dc39afaaf0e159fd160f6339e0f707" integrity sha512-AdbpGwKEEiMFgaRar9WOPc8Li4sfxR//WOyNQzxYsQ1fpARC908j7feqy2gu73SLqk4wzIrnlfJWakOe0/Bclg== @@ -9323,7 +9323,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/e99b926d27fffe8d069f9af75b976845cc3ad43f" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/4d83a43f1ef92c6b759f567dcadf502b935b348c" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" @@ -10380,10 +10380,10 @@ slide@^1.1.5: resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= -smart-buffer@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d" - integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw== +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== snapdragon-node@^2.0.1: version "2.1.1" @@ -10453,12 +10453,12 @@ socks-proxy-agent@^4.0.1: socks "~2.3.2" socks@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e" - integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ== + version "2.3.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" + integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== dependencies: - ip "^1.1.5" - smart-buffer "4.0.2" + ip "1.1.5" + smart-buffer "^4.1.0" source-map-explorer@^2.1.0: version "2.1.0" @@ -11344,9 +11344,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.7" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.7.tgz#15f49211df6b8a01ee91322bbe46fa33223175dc" - integrity sha512-4sXQDzmdnoXiO+xvmTzQsfIiwrjUCSA95rSP4SEd8tDb51W2TiDOlL76Hl+Kw0Ie42PSItCW8/t6pBNCF2R48A== + version "3.6.8" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.8.tgz#5edcbcf9d49cbb0403dc49f856fe81530d65145e" + integrity sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -11704,9 +11704,9 @@ vscode-languageserver-textdocument@^1.0.0-next.4: integrity sha512-LJ5WfoBO54nqinjlLJKnjoo2Im4bIvPJ8bFT7R0C84ZI36iK8M29ddslfe5jUeWNSTtCda7YuKdKsDIq38HpgA== vscode-languageserver-types@^3.15.0-next.6: - version "3.15.0-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.6.tgz#7a990d00c39ad4e744335afb4cc422a3e687ff25" - integrity sha512-+4jfvmZ26oFMSX6EgPRB75PWHoT8pzyWuSSWk0erC4hTzmJq2gWxVLh20bZutZjMmiivawvPshtM3XZhX2SttA== + version "3.15.0-next.7" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.7.tgz#388727ecd0c42abc4b208ed9929c3e6e499949a3" + integrity sha512-G1MgJk+ujxwpfu0ZSvS3qevvvQ6Sb8m9VVlikGjG5E+/ZozPPO84azYgtUiRVAKTOXP0owxHxQhUh4BKktWwuQ== vscode-nls@^4.1.1: version "4.1.1" @@ -11819,7 +11819,12 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" -wordwrap@^1.0.0, wordwrap@~1.0.0: +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= From 29b42e667c7bbe332d9d50b0f180d09e8d327325 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 19:20:26 -0500 Subject: [PATCH 475/636] alphabetize recent Contacts modal fixes --- src/components/contacts/SwipeableContactRow.js | 2 +- src/components/send/SendContactList.js | 8 ++++---- src/screens/SendSheet.js | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index 190fcf442a1..e4c09706c7f 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -68,8 +68,8 @@ export default class SwipeableContactRow extends PureComponent { onTransitionEnd: PropTypes.func, }; - swipeableRef = undefined; isFocused = false; + swipeableRef = undefined; close = () => this.swipeableRef.close(); diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 7c9ae6035cb..a6de3c7394d 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -136,14 +136,14 @@ class SendContactList extends Component { renderItem = (type, item) => ( { - this.contacts[item.address] = component; - }} + inputRef={this.props.inputRef} navigation={this.props.navigation} onChange={this.props.onUpdateContacts} onPress={this.props.onPressContact} onTouch={this.closeAllDifferentContacts} - inputRef={this.props.inputRef} + ref={component => { + this.contacts[item.address] = component; + }} {...item} /> ); diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 263aa549771..7c86932fd1a 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -244,21 +244,21 @@ class SendSheet extends Component { {showEmptyState && ( )} {showAssetList && ( From df1c641d3e8e62262fe9c12240f97ca7c1842515 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 19:33:26 -0500 Subject: [PATCH 476/636] Cleanup FloatingActionButton sCU --- src/components/fab/FloatingActionButton.js | 10 ++++++---- src/screens/WalletScreen.js | 12 ++---------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/components/fab/FloatingActionButton.js b/src/components/fab/FloatingActionButton.js index 1187aefbb9b..b928cbf8382 100644 --- a/src/components/fab/FloatingActionButton.js +++ b/src/components/fab/FloatingActionButton.js @@ -5,7 +5,7 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import { ButtonPressAnimation } from '../animations'; import InnerBorder from '../InnerBorder'; import { borders, colors, position } from '../../styles'; -import { isNewValueForPath } from '../../utils'; +import { compareObjectsAtPaths } from '../../utils'; import { ShadowStack } from '../shadow-stack'; const FabSize = 56; @@ -34,9 +34,11 @@ export default class FloatingActionButton extends Component { }; shouldComponentUpdate = nextProps => - isNewValueForPath(this.props, nextProps, 'disabled') || - isNewValueForPath(this.props, nextProps, 'isFabSelectionValid') || - isNewValueForPath(this.props, nextProps, 'scaleTo'); + compareObjectsAtPaths(this.props, nextProps, [ + 'disabled', + 'isFabSelectionValid', + 'scaleTo', + ]); static size = FabSize; diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 179991f2bfc..7cd4550e39d 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -21,7 +21,6 @@ import buildWalletSectionsSelector from '../helpers/buildWalletSections'; import { withAccountData, withAccountSettings, - withBlurTransitionProps, withDataInit, withIsWalletEmpty, withIsWalletEthZero, @@ -64,8 +63,8 @@ class WalletScreen extends Component { } }; - shouldComponentUpdate = nextProps => { - const shouldUpdate = compareObjectsAtPaths(this.props, nextProps, [ + shouldComponentUpdate = nextProps => + compareObjectsAtPaths(this.props, nextProps, [ 'fetchingAssets', 'fetchingUniqueTokens', 'isEmpty', @@ -75,12 +74,6 @@ class WalletScreen extends Component { 'sections', ]); - console.log('nextProps', nextProps); - console.log('shouldUpdate', shouldUpdate); - - return shouldUpdate; - }; - setInitialStatesForOpenAssets = async () => { const { accountAddress, network } = this.props; const toggle = await getSmallBalanceToggle(accountAddress, network); @@ -141,7 +134,6 @@ export default compose( withSafeTimeout, withNavigation, withNavigationFocus, - withBlurTransitionProps, withIsWalletEmpty, withIsWalletEthZero, withStatusBarStyle('dark-content'), From 183b1b8c0ad51b0fcda3a1fc4f0337e61696815f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 19:34:11 -0500 Subject: [PATCH 477/636] upgrade to gesture-handler 1.5.0 --- index.js | 1 + ios/Podfile.lock | 44 ++++++++++++++++++++++---------------------- package.json | 2 +- yarn.lock | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/index.js b/index.js index f7619235702..58a904688a6 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ +import 'react-native-gesture-handler'; import './global'; import './shim'; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1a0ddfcaa79..7a68a99ab51 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -624,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: e74f526a074b06a86745c93f853d025f32962829 - FBReactNativeSpec: 7e9c3640035bbcb5b766b5ac5be585bb3bc0ddc9 + FBLazyVector: eb8f08b7d74893c0efd2c2929a7aacad332b4d93 + FBReactNativeSpec: 98ebcac12d15dd504e81bdc67576734cdeeaa3c1 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: e07e94a77b9df606f736440754173024d03c3cdd - RCTTypeSafety: e1702d2523892617bd93c2dd016fff3556379084 - React: fb9d2c4dad053590fee17959504136f6d75b7c71 - React-Core: 08128bafbabbc2706278b82a828d4d63f3178c0a - React-CoreModules: 2582fc278afb16068de16cf16e7b39749482b605 - React-cxxreact: 1214ba1e57d7f6dfcf39a2a38a02611443ee5416 - React-jsi: 23923fb832c01e6f5652757e15e5cf1b88a7e961 - React-jsiexecutor: 732c2b6b9b7ff31a386e91c1a84d9d2fc945e1ea - React-jsinspector: 1c06737e9ba1f55cfb72cd32072c849e67ed7216 + RCTRequired: dc4076e1979307be1ddf7a1573e8b76ea107e813 + RCTTypeSafety: cbd11418b5e738bb893d560a1d1d0a2abc43b7d3 + React: 309c7524464a8c8242824de7cbcc540c9ca8dbc6 + React-Core: 0d39da05c13082e15beaf6082241cd48be84c96b + React-CoreModules: a6b5e77af48fbd0b72e52393a24eae94c1e358ef + React-cxxreact: e30d772da5654aaff22887b57f16519286456911 + React-jsi: 8acba446a1c9941bae75625e1228df65d888742e + React-jsiexecutor: e119a409952bae53741f42d34152f43914161c76 + React-jsinspector: a716c0ca54969073372344fcf992ac70b6ec7447 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -659,16 +659,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 656fa18d132e3ecbda8fe65c0580e0b88bc40816 - React-RCTAnimation: 812c33d4de7dd1d9c76097e0bf461c2fb60f0677 - React-RCTBlob: 45f5811c9310779d4597b89b6e6b140063f17245 - React-RCTImage: 922254fde24d3bed938d7b6b263a947479f4eea8 - React-RCTLinking: 374b21bafa74a6264691a6e95a2e4b3648668b09 - React-RCTNetwork: 2e9acea301b97f19423c06a2b7d4f12a6ed09220 - React-RCTSettings: e2b74046208f6554c5855d409adcae5d363bfb25 - React-RCTText: 3c26ff3b26253114540fe20b2ac8ee3c961b8882 - React-RCTVibration: 6defa525322047b4fb8f9ccfc3679e60e4070a0c - ReactCommon: b010d47dbf91d58171b63f9b2fb6609dde87f510 + React-RCTActionSheet: 66d7e7ce73c2fb69b677ee151c2f9799958bbf90 + React-RCTAnimation: 7b7f243007e6b8cb7de33042f381f9686764e518 + React-RCTBlob: 9542277472ebc3bdbdfc7923fe002231d53544b8 + React-RCTImage: 06a9f6a71a9433d0e1bde8902b4d940d5845d98d + React-RCTLinking: b1f8d5d1867f090552e46a7e467c1669d4ea597c + React-RCTNetwork: 2a0faf1fe847e67414491e6fd94c0b0a7a14ab50 + React-RCTSettings: f3ca7b3db9e654dc4e06a50cf75372bc52720af6 + React-RCTText: cf8e9641e94de97e470ad438dee05eb56673df77 + React-RCTVibration: 5a8ef97610b01e2a66358897a9bad601447c3e6e + ReactCommon: 9822682c5da71de4acc5f51a301e71205e7b8caf ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -692,7 +692,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 85076db2046b2b95464aceeee981bd4b834c670e + Yoga: 26edd1529e7c934114e2ffa30d92bbe3c92d5d8b PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/package.json b/package.json index 2433791a268..18fc3d33a53 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-firebase": "^5.5.6", - "react-native-gesture-handler": "^1.4.1", + "react-native-gesture-handler": "1.5.0", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", "react-native-ios11-devicecheck": "^0.0.3", diff --git a/yarn.lock b/yarn.lock index 6693cd287f5..794a37295ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9117,7 +9117,7 @@ react-native-firebase@^5.5.6: opencollective-postinstall "^2.0.0" prop-types "^15.7.2" -react-native-gesture-handler@^1.4.1: +react-native-gesture-handler@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.0.tgz#df7dc5285c152e0656db70f55200fa632c4f45af" integrity sha512-YUOXHsGLajK1cFReQ4Xh0H9GUTxDW9cUZEVu1q+dVqur2urSKi63KklAFB2l8Neob9nl1E/w0c5hGcBP9FMCIA== From 435d5d98ec878bacf1e45ab9fc45e72af847bb68 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 6 Nov 2019 21:58:54 -0500 Subject: [PATCH 478/636] updating nvmrc to use v12.13.0 --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index afa7ccbea64..bce43c253fe 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v11.10.1 +v12.13.0 From 84acad0fb40ebc2a2078e0cd53a3d701017e1ef5 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 22:24:06 -0500 Subject: [PATCH 479/636] =?UTF-8?q?Changes=20after=20@jin=E2=80=99s=20code?= =?UTF-8?q?=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/exchange/ExchangeInputField.js | 4 +-- src/components/fab/FloatingActionButton.js | 4 +-- src/screens/ExchangeModal.js | 29 ++++++++++++------- src/screens/WalletScreen.js | 22 +++++++------- src/utils/index.js | 4 ++- ...AtPaths.js => isNewValueForObjectPaths.js} | 2 +- 6 files changed, 38 insertions(+), 27 deletions(-) rename src/utils/{compareObjectsAtPaths.js => isNewValueForObjectPaths.js} (66%) diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index a66bcd62f8f..625ebeb82c4 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { TouchableWithoutFeedback } from 'react-native'; import { colors } from '../../styles'; -import { compareObjectsAtPaths } from '../../utils'; +import { isNewValueForObjectPaths } from '../../utils'; import { ButtonPressAnimation } from '../animations'; import { CoolButton } from '../buttons'; import { CoinIcon } from '../coin-icon'; @@ -35,7 +35,7 @@ export default class ExchangeInputField extends Component { }; shouldComponentUpdate = nextProps => - compareObjectsAtPaths(this.props, nextProps, [ + isNewValueForObjectPaths(this.props, nextProps, [ 'inputAmount', 'inputCurrencySymbol', 'isAssetApproved', diff --git a/src/components/fab/FloatingActionButton.js b/src/components/fab/FloatingActionButton.js index b928cbf8382..2b41b34a90c 100644 --- a/src/components/fab/FloatingActionButton.js +++ b/src/components/fab/FloatingActionButton.js @@ -5,7 +5,7 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import { ButtonPressAnimation } from '../animations'; import InnerBorder from '../InnerBorder'; import { borders, colors, position } from '../../styles'; -import { compareObjectsAtPaths } from '../../utils'; +import { isNewValueForObjectPaths } from '../../utils'; import { ShadowStack } from '../shadow-stack'; const FabSize = 56; @@ -34,7 +34,7 @@ export default class FloatingActionButton extends Component { }; shouldComponentUpdate = nextProps => - compareObjectsAtPaths(this.props, nextProps, [ + isNewValueForObjectPaths(this.props, nextProps, [ 'disabled', 'isFabSelectionValid', 'scaleTo', diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a6c420475bd..7b6b034b6a8 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -53,7 +53,7 @@ import { } from '../hoc'; import { colors, padding, position } from '../styles'; import { - compareObjectsAtPaths, + isNewValueForObjectPaths, contractUtils, ethereumUtils, gasUtils, @@ -124,12 +124,12 @@ class ExchangeModal extends Component { }; shouldComponentUpdate = (nextProps, nextState) => { - const isNewProps = compareObjectsAtPaths(this.props, nextProps, [ + const isNewProps = isNewValueForObjectPaths(this.props, nextProps, [ 'inputReserve.token.address', 'outputReserve.token.address', ]); - const isNewState = compareObjectsAtPaths(this.state, nextState, [ + const isNewState = isNewValueForObjectPaths(this.state, nextState, [ 'approvalCreationTimestamp', 'approvalEstimatedTimeInMs', 'inputAmount', @@ -150,12 +150,16 @@ class ExchangeModal extends Component { this.props.navigation.emit('refocus'); } - const isNewAmountOrCurrency = compareObjectsAtPaths(this.state, prevState, [ - 'inputAmount', - 'inputCurrency.uniqueId', - 'outputAmount', - 'outputCurrency.uniqueId', - ]); + const isNewAmountOrCurrency = isNewValueForObjectPaths( + this.state, + prevState, + [ + 'inputAmount', + 'inputCurrency.uniqueId', + 'outputAmount', + 'outputCurrency.uniqueId', + ] + ); let isNewNativeAmount = isNewValueForPath( this.state, @@ -289,7 +293,7 @@ class ExchangeModal extends Component { } }; - getMarketDetails = async isNewOutputCurrency => { + getMarketDetails = async isNewOutputReserveCurrency => { const { accountAddress, chainId, @@ -438,7 +442,10 @@ class ExchangeModal extends Component { this.clearForm(); } - if (inputAsExactAmount || (isNewOutputCurrency && inputAsExactAmount)) { + if ( + inputAsExactAmount || + (isNewOutputReserveCurrency && inputAsExactAmount) + ) { if (isInputEmpty || isInputZero) { this.setOutputAmount(); } else { diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 7cd4550e39d..ae683a8f7c2 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -33,7 +33,7 @@ import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; import store from '../redux/store'; import { position } from '../styles'; -import { compareObjectsAtPaths } from '../utils'; +import { isNewValueForObjectPaths } from '../utils'; class WalletScreen extends Component { static propTypes = { @@ -64,15 +64,17 @@ class WalletScreen extends Component { }; shouldComponentUpdate = nextProps => - compareObjectsAtPaths(this.props, nextProps, [ - 'fetchingAssets', - 'fetchingUniqueTokens', - 'isEmpty', - 'isWalletEthZero', - 'language', - 'nativeCurrency', - 'sections', - ]); + !nextProps.isFocused + ? false + : isNewValueForObjectPaths(this.props, nextProps, [ + 'fetchingAssets', + 'fetchingUniqueTokens', + 'isEmpty', + 'isWalletEthZero', + 'language', + 'nativeCurrency', + 'sections', + ]); setInitialStatesForOpenAssets = async () => { const { accountAddress, network } = this.props; diff --git a/src/utils/index.js b/src/utils/index.js index f6813765d4a..e8f0af67d1f 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,6 +1,5 @@ export { default as abbreviations } from './abbreviations'; export { default as addressUtils } from './address'; -export { default as compareObjectsAtPaths } from './compareObjectsAtPaths'; export { default as contractUtils } from './contract'; export { default as deviceUtils } from './deviceUtils'; export { default as dimensionsPropType } from './dimensionsPropType'; @@ -9,6 +8,9 @@ export { default as ethereumUtils } from './ethereumUtils'; export { default as gasUtils } from './gas'; export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; +export { + default as isNewValueForObjectPaths, +} from './isNewValueForObjectPaths'; export { default as isNewValueForPath } from './isNewValueForPath'; export { default as parseObjectToUrlQueryString, diff --git a/src/utils/compareObjectsAtPaths.js b/src/utils/isNewValueForObjectPaths.js similarity index 66% rename from src/utils/compareObjectsAtPaths.js rename to src/utils/isNewValueForObjectPaths.js index d4b5b67aeb1..6b0d330e82c 100644 --- a/src/utils/compareObjectsAtPaths.js +++ b/src/utils/isNewValueForObjectPaths.js @@ -1,6 +1,6 @@ import { pick } from 'lodash'; import isEqual from 'react-fast-compare'; -export default function compareObjectsAtPaths(a, b, paths) { +export default function isNewValueForObjectPaths(a, b, paths) { return !isEqual(pick(a, paths), pick(b, paths)); } From c041b82b1c1a9709a3cac491643090664a58870a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 22:25:09 -0500 Subject: [PATCH 480/636] =?UTF-8?q?=F0=9F=98=AC=EF=B8=8F=20Downgrade=20ges?= =?UTF-8?q?ture-handler=20back=20to=201.4.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 48 ++++++++++++++++++++++++------------------------ package.json | 2 +- yarn.lock | 40 +++++++++++++++++++++++++++------------- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 7a68a99ab51..ddbbf73341c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -375,7 +375,7 @@ PODS: - Fabric - Firebase/Core - React - - RNGestureHandler (1.5.0): + - RNGestureHandler (1.4.1): - React - RNKeychain (3.1.3): - React @@ -624,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: eb8f08b7d74893c0efd2c2929a7aacad332b4d93 - FBReactNativeSpec: 98ebcac12d15dd504e81bdc67576734cdeeaa3c1 + FBLazyVector: 24f90ec1a12e2da15391635443e6f4d8ef78445e + FBReactNativeSpec: a237372e5011bed5a563be48ac41e25cbf9ddaee Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: dc4076e1979307be1ddf7a1573e8b76ea107e813 - RCTTypeSafety: cbd11418b5e738bb893d560a1d1d0a2abc43b7d3 - React: 309c7524464a8c8242824de7cbcc540c9ca8dbc6 - React-Core: 0d39da05c13082e15beaf6082241cd48be84c96b - React-CoreModules: a6b5e77af48fbd0b72e52393a24eae94c1e358ef - React-cxxreact: e30d772da5654aaff22887b57f16519286456911 - React-jsi: 8acba446a1c9941bae75625e1228df65d888742e - React-jsiexecutor: e119a409952bae53741f42d34152f43914161c76 - React-jsinspector: a716c0ca54969073372344fcf992ac70b6ec7447 + RCTRequired: 6dc9cc56c1615edf7ef3330f382c2f2bc48700b4 + RCTTypeSafety: 8a53912c3aece7df6c49d79c5812abc3c3a3c098 + React: ac0d09ac5b8aa118341d08f77f0fe9fe436e93b0 + React-Core: b902933e0269d144d5ac264b6ce1a5abd6650d06 + React-CoreModules: 30a8950c26338ec09dd5796363283aa71abda3f5 + React-cxxreact: f69cf4e46c0ce59ef2734c8785c1c6889ba3d723 + React-jsi: 75df71a8456575d9f50185c70b31c2a375978993 + React-jsiexecutor: 4882fb8a1c8b975f1c5865a9a15c2259844fa969 + React-jsinspector: 8b5b37766f75433fbca2507f5a6ca6b654f2d2fa react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -659,16 +659,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 66d7e7ce73c2fb69b677ee151c2f9799958bbf90 - React-RCTAnimation: 7b7f243007e6b8cb7de33042f381f9686764e518 - React-RCTBlob: 9542277472ebc3bdbdfc7923fe002231d53544b8 - React-RCTImage: 06a9f6a71a9433d0e1bde8902b4d940d5845d98d - React-RCTLinking: b1f8d5d1867f090552e46a7e467c1669d4ea597c - React-RCTNetwork: 2a0faf1fe847e67414491e6fd94c0b0a7a14ab50 - React-RCTSettings: f3ca7b3db9e654dc4e06a50cf75372bc52720af6 - React-RCTText: cf8e9641e94de97e470ad438dee05eb56673df77 - React-RCTVibration: 5a8ef97610b01e2a66358897a9bad601447c3e6e - ReactCommon: 9822682c5da71de4acc5f51a301e71205e7b8caf + React-RCTActionSheet: 0cad61e3404eb0e67a9c039c20df025e615d7634 + React-RCTAnimation: 5d298362d500674050b3dc7141617a84bd9ae04e + React-RCTBlob: c52de8cef82c1278d12ca16e23106e0fe4ca2aef + React-RCTImage: dbda9e3927bfbe1ca932c663deb0477f604cef16 + React-RCTLinking: 2a83dfbd5179439034db47e71c45bd5bd6f4d199 + React-RCTNetwork: 6c4650c30f6a3ba9019d10e054743bebde42eacb + React-RCTSettings: b0f6f83250f386dbbf4e509024d4fc5b252a380d + React-RCTText: 0433375b241a05c1f1bc0c56bea65d2098be628f + React-RCTVibration: 4e71dc6ae748dea87dcd5d73ea548b2acf60a2e2 + ReactCommon: eb23e7a6b5d2538652e6920f6bcf10702b6e377b ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -676,7 +676,7 @@ SPEC CHECKSUMS: RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 - RNGestureHandler: a4ddde1ffc6e590c8127b8b7eabfdade45475c74 + RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa RNKeychain: c658833a9cb2cbcba6423bdd6e16cce59e27da0e RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a @@ -692,7 +692,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 26edd1529e7c934114e2ffa30d92bbe3c92d5d8b + Yoga: 62ffa5a8eaf4777499dc0360620b109ef0f8b340 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/package.json b/package.json index 18fc3d33a53..a8817940267 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-firebase": "^5.5.6", - "react-native-gesture-handler": "1.5.0", + "react-native-gesture-handler": "1.4.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "^0.13.0", "react-native-ios11-devicecheck": "^0.0.3", diff --git a/yarn.lock b/yarn.lock index 794a37295ba..21ecdfd1449 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2288,7 +2288,7 @@ better-assert@~1.0.0: dependencies: callsite "1.0.0" -big-integer@^1.6.7: +big-integer@^1.6.44, big-integer@^1.6.7: version "1.6.47" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.47.tgz#e1e9320e26c4cc81f64fbf4b3bb20e025bf18e2d" integrity sha512-9t9f7X3as2XGX8b52GqG6ox0GvIdM86LyIXASJnDCFhYNgt+A+MByQZ3W2PyMRZjEvG5f8TEbSPfEotVuMJnQg== @@ -2350,6 +2350,13 @@ bplist-creator@0.0.7: dependencies: stream-buffers "~2.2.0" +bplist-creator@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.8.tgz#56b2a6e79e9aec3fc33bf831d09347d73794e79c" + integrity sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA== + dependencies: + stream-buffers "~2.2.0" + bplist-parser@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" @@ -2357,6 +2364,13 @@ bplist-parser@0.1.1: dependencies: big-integer "^1.6.7" +bplist-parser@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3671,9 +3685,9 @@ ejs@^2.7.1: integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.295: - version "1.3.304" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.304.tgz#49b47d961f8143116174c2f70fbfee3aabf43015" - integrity sha512-a5mqa13jCdBc+Crgk3Gyr7vpXCiFWfFq23YDCEmrPYeiDOQKZDVE6EX/Q4Xdv97n3XkcjiSBDOY0IS19yP2yeA== + version "1.3.305" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.305.tgz#64f38c2986277b15c7b2c81954171ed22bee249b" + integrity sha512-jBEhRZ3eeJWf3eAnGYB1vDy09uBQpZWshC5fxiiIRofA9L3vkpa3SxsXleVS2MvuYir15oTVxzWPsOwj7KBzUw== elliptic@6.3.3: version "6.3.3" @@ -9117,10 +9131,10 @@ react-native-firebase@^5.5.6: opencollective-postinstall "^2.0.0" prop-types "^15.7.2" -react-native-gesture-handler@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.0.tgz#df7dc5285c152e0656db70f55200fa632c4f45af" - integrity sha512-YUOXHsGLajK1cFReQ4Xh0H9GUTxDW9cUZEVu1q+dVqur2urSKi63KklAFB2l8Neob9nl1E/w0c5hGcBP9FMCIA== +react-native-gesture-handler@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" + integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -10338,12 +10352,12 @@ simple-plist@^0.2.1: plist "2.0.1" simple-plist@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.0.0.tgz#bed3085633b22f371e111f45d159a1ccf94b81eb" - integrity sha512-043L2rO80LVF7zfZ+fqhsEkoJFvW8o59rt/l4ctx1TJWoTx7/jkiS1R5TatD15Z1oYnuLJytzE7gcnnBuIPL2g== + version "1.1.0" + resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.1.0.tgz#8354ab63eb3922a054c78ce96c209c532e907a23" + integrity sha512-2i5Tc0BYAqppM7jVzmNrI+aEUntPolIq4fDgji6WuNNn1D/qYdn2KwoLhZdzQkE04lu9L5tUoeJsjuJAvd+lFg== dependencies: - bplist-creator "0.0.7" - bplist-parser "0.1.1" + bplist-creator "0.0.8" + bplist-parser "0.2.0" plist "^3.0.1" sisteransi@^1.0.3: From db3aaa54356d312a4c377cfc16c2bd790f3a9144 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 22:26:08 -0500 Subject: [PATCH 481/636] Delete outdated react-native patch file --- patches/react-native+0.60.5.patch | 175 ------------------------------ 1 file changed, 175 deletions(-) delete mode 100644 patches/react-native+0.60.5.patch diff --git a/patches/react-native+0.60.5.patch b/patches/react-native+0.60.5.patch deleted file mode 100644 index c5019731213..00000000000 --- a/patches/react-native+0.60.5.patch +++ /dev/null @@ -1,175 +0,0 @@ -diff --git a/node_modules/react-native/React/Modules/RCTStatusBarManager.m b/node_modules/react-native/React/Modules/RCTStatusBarManager.m -index 9b6f9d6..d15fd73 100644 ---- a/node_modules/react-native/React/Modules/RCTStatusBarManager.m -+++ b/node_modules/react-native/React/Modules/RCTStatusBarManager.m -@@ -14,17 +14,44 @@ - #if !TARGET_OS_TV - @implementation RCTConvert (UIStatusBar) - --RCT_ENUM_CONVERTER(UIStatusBarStyle, (@{ -- @"default": @(UIStatusBarStyleDefault), -- @"light-content": @(UIStatusBarStyleLightContent), -- @"dark-content": @(UIStatusBarStyleDefault), --}), UIStatusBarStyleDefault, integerValue); -- --RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ -- @"none": @(UIStatusBarAnimationNone), -- @"fade": @(UIStatusBarAnimationFade), -- @"slide": @(UIStatusBarAnimationSlide), --}), UIStatusBarAnimationNone, integerValue); -++ (UIStatusBarStyle)UIStatusBarStyle:(id)json RCT_DYNAMIC -+{ -+ static NSDictionary *mapping; -+ static dispatch_once_t onceToken; -+ dispatch_once(&onceToken, ^{ -+ if (@available(iOS 13.0, *)) { -+ mapping = @{ -+ @"default" : @(UIStatusBarStyleDefault), -+ @"light-content" : @(UIStatusBarStyleLightContent), -+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ -+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 -+ @"dark-content" : @(UIStatusBarStyleDarkContent) -+#else -+ @"dark-content": @(UIStatusBarStyleDefault) -+#endif -+ }; -+ -+ } else { -+ mapping = @{ -+ @"default" : @(UIStatusBarStyleDefault), -+ @"light-content" : @(UIStatusBarStyleLightContent), -+ @"dark-content" : @(UIStatusBarStyleDefault) -+ }; -+ } -+ }); -+ return _RCT_CAST( -+ type, [RCTConvertEnumValue("UIStatusBarStyle", mapping, @(UIStatusBarStyleDefault), json) integerValue]); -+} -+ -+RCT_ENUM_CONVERTER( -+ UIStatusBarAnimation, -+ (@{ -+ @"none" : @(UIStatusBarAnimationNone), -+ @"fade" : @(UIStatusBarAnimationFade), -+ @"slide" : @(UIStatusBarAnimationSlide), -+ }), -+ UIStatusBarAnimationNone, -+ integerValue); - - @end - #endif -@@ -36,8 +63,9 @@ static BOOL RCTViewControllerBasedStatusBarAppearance() - static BOOL value; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ -- value = [[[NSBundle mainBundle] objectForInfoDictionaryKey: -- @"UIViewControllerBasedStatusBarAppearance"] ?: @YES boolValue]; -+ value = -+ [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"] -+ ?: @YES boolValue]; - }); - - return value; -@@ -47,8 +75,7 @@ static BOOL RCTViewControllerBasedStatusBarAppearance() - - - (NSArray *)supportedEvents - { -- return @[@"statusBarFrameDidChange", -- @"statusBarFrameWillChange"]; -+ return @[ @"statusBarFrameDidChange", @"statusBarFrameWillChange" ]; - } - - #if !TARGET_OS_TV -@@ -56,8 +83,14 @@ static BOOL RCTViewControllerBasedStatusBarAppearance() - - (void)startObserving - { - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; -- [nc addObserver:self selector:@selector(applicationDidChangeStatusBarFrame:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; -- [nc addObserver:self selector:@selector(applicationWillChangeStatusBarFrame:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil]; -+ [nc addObserver:self -+ selector:@selector(applicationDidChangeStatusBarFrame:) -+ name:UIApplicationDidChangeStatusBarFrameNotification -+ object:nil]; -+ [nc addObserver:self -+ selector:@selector(applicationWillChangeStatusBarFrame:) -+ name:UIApplicationWillChangeStatusBarFrameNotification -+ object:nil]; - } - - - (void)stopObserving -@@ -74,11 +107,11 @@ - (void)emitEvent:(NSString *)eventName forNotification:(NSNotification *)notifi - { - CGRect frame = [notification.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue]; - NSDictionary *event = @{ -- @"frame": @{ -- @"x": @(frame.origin.x), -- @"y": @(frame.origin.y), -- @"width": @(frame.size.width), -- @"height": @(frame.size.height), -+ @"frame" : @{ -+ @"x" : @(frame.origin.x), -+ @"y" : @(frame.origin.y), -+ @"width" : @(frame.size.width), -+ @"height" : @(frame.size.height), - }, - }; - [self sendEventWithName:eventName body:event]; -@@ -94,15 +127,14 @@ - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification - [self emitEvent:@"statusBarFrameWillChange" forNotification:notification]; - } - --RCT_EXPORT_METHOD(getHeight:(RCTResponseSenderBlock)callback) -+RCT_EXPORT_METHOD(getHeight : (RCTResponseSenderBlock)callback) - { -- callback(@[@{ -- @"height": @(RCTSharedApplication().statusBarFrame.size.height), -- }]); -+ callback(@[ @{ -+ @"height" : @(RCTSharedApplication().statusBarFrame.size.height), -+ } ]); - } - --RCT_EXPORT_METHOD(setStyle:(UIStatusBarStyle)statusBarStyle -- animated:(BOOL)animated) -+RCT_EXPORT_METHOD(setStyle : (UIStatusBarStyle)statusBarStyle animated : (BOOL)animated) - { - if (RCTViewControllerBasedStatusBarAppearance()) { - RCTLogError(@"RCTStatusBarManager module requires that the \ -@@ -110,14 +142,12 @@ - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification - } else { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" -- [RCTSharedApplication() setStatusBarStyle:statusBarStyle -- animated:animated]; -+ [RCTSharedApplication() setStatusBarStyle:statusBarStyle animated:animated]; - } - #pragma clang diagnostic pop - } - --RCT_EXPORT_METHOD(setHidden:(BOOL)hidden -- withAnimation:(UIStatusBarAnimation)animation) -+RCT_EXPORT_METHOD(setHidden : (BOOL)hidden withAnimation : (UIStatusBarAnimation)animation) - { - if (RCTViewControllerBasedStatusBarAppearance()) { - RCTLogError(@"RCTStatusBarManager module requires that the \ -@@ -125,17 +155,16 @@ - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification - } else { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" -- [RCTSharedApplication() setStatusBarHidden:hidden -- withAnimation:animation]; -+ [RCTSharedApplication() setStatusBarHidden:hidden withAnimation:animation]; - #pragma clang diagnostic pop - } - } - --RCT_EXPORT_METHOD(setNetworkActivityIndicatorVisible:(BOOL)visible) -+RCT_EXPORT_METHOD(setNetworkActivityIndicatorVisible : (BOOL)visible) - { - RCTSharedApplication().networkActivityIndicatorVisible = visible; - } - --#endif //TARGET_OS_TV -+#endif // TARGET_OS_TV - - @end From d35b0d5446c414869f688032b3606aeb263e4612 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 6 Nov 2019 22:27:23 -0500 Subject: [PATCH 482/636] Allow leading decimals in swap inputs Fixes RAI-12 https://linear.app/issue/RAI-12 --- ios/Podfile.lock | 44 ++++++++++++------------ src/components/exchange/ExchangeInput.js | 11 ++++-- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ddbbf73341c..4a92e369342 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -624,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 24f90ec1a12e2da15391635443e6f4d8ef78445e - FBReactNativeSpec: a237372e5011bed5a563be48ac41e25cbf9ddaee + FBLazyVector: 9b38e9b284a4a7371d6a7eb7f561b1ca5b96823a + FBReactNativeSpec: 1645d04d7eb308d13322d1a3b7dc972f811b158c Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 6dc9cc56c1615edf7ef3330f382c2f2bc48700b4 - RCTTypeSafety: 8a53912c3aece7df6c49d79c5812abc3c3a3c098 - React: ac0d09ac5b8aa118341d08f77f0fe9fe436e93b0 - React-Core: b902933e0269d144d5ac264b6ce1a5abd6650d06 - React-CoreModules: 30a8950c26338ec09dd5796363283aa71abda3f5 - React-cxxreact: f69cf4e46c0ce59ef2734c8785c1c6889ba3d723 - React-jsi: 75df71a8456575d9f50185c70b31c2a375978993 - React-jsiexecutor: 4882fb8a1c8b975f1c5865a9a15c2259844fa969 - React-jsinspector: 8b5b37766f75433fbca2507f5a6ca6b654f2d2fa + RCTRequired: 0d2ced92ba3315e0fad9ec10044297ac192751b9 + RCTTypeSafety: bf09a7a477297cc999611146120564b759f083e6 + React: 6bf780885ae68bdf7dab4bed6eb97a6b29299a81 + React-Core: 95082d89adf87c4c4200f0d12008c9b6fe1d1726 + React-CoreModules: 15ce069a8b2f3f31734baf8fecfd604e4703562b + React-cxxreact: 02ca09ae4e6ace75c8c985a397dce6ecc98974f8 + React-jsi: 0e6d81dcb35b667df0183f4653f79e6d599f0a76 + React-jsiexecutor: 62c3cb35bbb9263a070ef99803bd7d210dd05b06 + React-jsinspector: f16017328b003e8baef8b5c3481e6479e72aea50 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -659,16 +659,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 0cad61e3404eb0e67a9c039c20df025e615d7634 - React-RCTAnimation: 5d298362d500674050b3dc7141617a84bd9ae04e - React-RCTBlob: c52de8cef82c1278d12ca16e23106e0fe4ca2aef - React-RCTImage: dbda9e3927bfbe1ca932c663deb0477f604cef16 - React-RCTLinking: 2a83dfbd5179439034db47e71c45bd5bd6f4d199 - React-RCTNetwork: 6c4650c30f6a3ba9019d10e054743bebde42eacb - React-RCTSettings: b0f6f83250f386dbbf4e509024d4fc5b252a380d - React-RCTText: 0433375b241a05c1f1bc0c56bea65d2098be628f - React-RCTVibration: 4e71dc6ae748dea87dcd5d73ea548b2acf60a2e2 - ReactCommon: eb23e7a6b5d2538652e6920f6bcf10702b6e377b + React-RCTActionSheet: 3cffc9f5fcfdb95baa722c3e78efd2a4f2dd40f3 + React-RCTAnimation: 3c8f2f065030db5c43537dbd5f9239636737b849 + React-RCTBlob: cfb83cd5dcfa54e284d89cd1eacf86b58b342e4b + React-RCTImage: d69c65908081498af219c0f0eb5336d1a9e61d8a + React-RCTLinking: 79b6421689a291b7a456ca29660d027782fc15c3 + React-RCTNetwork: 0ba165f2bc06857513301c4288dbb21eb7749788 + React-RCTSettings: 84d22405b77980d386c59bd1590c6f0178afe566 + React-RCTText: 8f5833fcd29e64967182bd83ed18d4bd10895801 + React-RCTVibration: 66ba6784fa6e0947c85fa6622c31f8cd9e2e6c2b + ReactCommon: a67533cedebb16637db2a8420cf81be9a9625fcf ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -692,7 +692,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 62ffa5a8eaf4777499dc0360620b109ef0f8b340 + Yoga: dfba15033d50829ffbf6aa3a0b47212962ce386c PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 62b5c61f479..935e8e27685 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -28,10 +28,17 @@ export default class ExchangeInput extends PureComponent { mask: '[099999999999999999].[999999999999999999]', placeholder: '0', placeholderTextColor: colors.alpha(colors.blueGreyDark, 0.3), + value: '', }; handleChangeText = (formatted, extracted) => { - this.props.onChangeText(extracted ? formatted : ''); + let text = extracted ? formatted : ''; + + if (!text.length && !this.props.value) { + text = '0.'; + } + + this.props.onChangeText(text); }; render = () => { @@ -55,7 +62,7 @@ export default class ExchangeInput extends PureComponent { allowFontScaling={false} flex={1} keyboardAppearance="dark" - keyboardType="decimal-pad" + keyboardType="numeric" mask={mask} onChangeText={this.handleChangeText} placeholder={placeholder} From 72fecc0f4521f6f9d1ba47786b0927aea5318ac8 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 7 Nov 2019 03:33:28 -0500 Subject: [PATCH 483/636] Update react-native-tooltip patch --- ...ive-tooltip+5.2.0.patch => react-native-tooltip+5.2.1.patch} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename patches/{react-native-tooltip+5.2.0.patch => react-native-tooltip+5.2.1.patch} (94%) diff --git a/patches/react-native-tooltip+5.2.0.patch b/patches/react-native-tooltip+5.2.1.patch similarity index 94% rename from patches/react-native-tooltip+5.2.0.patch rename to patches/react-native-tooltip+5.2.1.patch index f97a6c35e86..4fd415b0e94 100644 --- a/patches/react-native-tooltip+5.2.0.patch +++ b/patches/react-native-tooltip+5.2.1.patch @@ -1,5 +1,5 @@ diff --git a/node_modules/react-native-tooltip/ToolTip.ios.js b/node_modules/react-native-tooltip/ToolTip.ios.js -index 83bfbfe..56bba0e 100644 +index c6754e2..021a675 100644 --- a/node_modules/react-native-tooltip/ToolTip.ios.js +++ b/node_modules/react-native-tooltip/ToolTip.ios.js @@ -65,7 +65,7 @@ export default class ToolTip extends PureComponent { From eefb0df9ace6b727424dd6b58755444f1ed26972 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 7 Nov 2019 03:37:04 -0500 Subject: [PATCH 484/636] Visual improvements --- src/components/buttons/CoolButton.js | 39 +++++++++---------- src/components/coin-row/ExchangeCoinRow.js | 9 ++++- .../exchange/CurrencySelectModalHeader.js | 12 +++--- src/components/exchange/ExchangeInputField.js | 17 ++++++-- .../exchange/ExchangeModalHeader.js | 10 ++++- .../exchange/ExchangeOutputField.js | 2 +- src/components/exchange/ExchangeSearch.js | 14 +++++-- src/components/header/BackButton.js | 2 +- src/components/header/Header.js | 2 +- src/components/icons/svg/CaretIcon.js | 8 ++-- src/components/inputs/ClearInputDecorator.js | 2 +- src/components/modal/ModalHeader.js | 2 + src/components/profile/ProfileMasthead.js | 1 - src/components/shadow-stack/ShadowStack.js | 6 +-- src/screens/ExchangeModal.js | 2 +- src/screens/WalletScreen.js | 2 +- 16 files changed, 79 insertions(+), 51 deletions(-) diff --git a/src/components/buttons/CoolButton.js b/src/components/buttons/CoolButton.js index 55673071dea..477c87e1984 100644 --- a/src/components/buttons/CoolButton.js +++ b/src/components/buttons/CoolButton.js @@ -1,25 +1,15 @@ -import React from 'react'; import PropTypes from 'prop-types'; -import { compose, onlyUpdateForKeys, withProps } from 'recompact'; -import { withNeverRerender } from '../../hoc'; +import React from 'react'; +import FastImage from 'react-native-fast-image'; +import { onlyUpdateForKeys, withProps } from 'recompact'; +import CaretImageSource from '../../assets/family-dropdown-arrow.png'; import { colors, margin, padding, position } from '../../styles'; import { ButtonPressAnimation } from '../animations'; -import { Icon } from '../icons'; import InnerBorder from '../InnerBorder'; import { Row, RowWithMargins } from '../layout'; import { ShadowStack } from '../shadow-stack'; import { Text } from '../text'; -const CoolCaretIcon = compose( - withNeverRerender, - withProps({ - color: 'white', - flex: 0, - name: 'caret', - size: 7.5, - }) -)(Icon); - const CoolLabel = withProps({ color: 'white', flex: 1, @@ -41,12 +31,21 @@ const CoolButton = enhance( /> {children} - + @@ -65,9 +64,9 @@ CoolButton.propTypes = { CoolButton.defaultProps = { borderRadius: 20, shadows: [ - [0, 0, 1, colors.dark, 0.01], - [0, 4, 12, colors.dark, 0.04], - [0, 8, 23, colors.dark, 0.05], + [0, 2, 5, colors.dark, 0.15], + [0, 6, 10, colors.dark, 0.14], + [0, 1, 18, colors.dark, 0.08], ], }; diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 2689700568d..16e27008473 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { connect } from 'react-redux'; +import { css } from 'styled-components/primitives'; import { uniswapUpdateFavorites } from '../../redux/uniswap'; import { colors, position } from '../../styles'; import { isNewValueForPath } from '../../utils'; @@ -10,6 +11,11 @@ import BottomRowText from './BottomRowText'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; +const containerStyles = css` + padding-left: 15; + padding-right: 0; +`; + const BottomRow = ({ balance, native, showBalance, symbol }) => { let text = symbol; if (showBalance && native) { @@ -94,7 +100,7 @@ class ExchangeCoinRow extends Component { @@ -105,6 +111,7 @@ class ExchangeCoinRow extends Component { scaleTo={0.69} style={{ ...position.centeredAsObject, + height: '100%', paddingHorizontal: 19, }} > diff --git a/src/components/exchange/CurrencySelectModalHeader.js b/src/components/exchange/CurrencySelectModalHeader.js index be6ba663fdd..0c81f4a3d4d 100644 --- a/src/components/exchange/CurrencySelectModalHeader.js +++ b/src/components/exchange/CurrencySelectModalHeader.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { hoistStatics, onlyUpdateForKeys, withProps } from 'recompact'; import styled from 'styled-components/primitives'; -import { borders, colors } from '../../styles'; +import { borders, colors, padding } from '../../styles'; import { BackButton } from '../header'; import { Centered } from '../layout'; import { TruncatedText } from '../text'; @@ -11,10 +11,10 @@ const BackButtonWrapper = styled(Centered)` bottom: 0; left: 0; position: absolute; - top: 0; + top: 5; `; -const HeaderHeight = 60; +const HeaderHeight = 59; const HeaderContainer = styled(Centered).attrs({ flex: 0 })` ${borders.buildRadius('top', 12)}; background-color: ${colors.white}; @@ -23,6 +23,7 @@ const HeaderContainer = styled(Centered).attrs({ flex: 0 })` `; const HeaderTitle = withProps({ + align: 'center', height: 21, letterSpacing: 'tighter', lineHeight: 'loose', @@ -38,11 +39,10 @@ const CurrencySelectModalHeader = ({ onPressBack, title }) => ( direction="left" height={HeaderHeight} onPress={onPressBack} - paddingLeft={25} - size="9" + paddingLeft={27} /> - {title} + {title} ); diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 625ebeb82c4..fa9fb2ef201 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -80,7 +80,7 @@ export default class ExchangeInputField extends Component { const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); return ( - + - - + + Max diff --git a/src/components/exchange/ExchangeModalHeader.js b/src/components/exchange/ExchangeModalHeader.js index 152a5e77b7a..85d23815791 100644 --- a/src/components/exchange/ExchangeModalHeader.js +++ b/src/components/exchange/ExchangeModalHeader.js @@ -6,9 +6,15 @@ import { SheetHandle } from '../sheet'; import { Text } from '../text'; const ExchangeModalHeader = () => ( - + - + Swap diff --git a/src/components/exchange/ExchangeOutputField.js b/src/components/exchange/ExchangeOutputField.js index 3f39e8a5a29..c552ba594c2 100644 --- a/src/components/exchange/ExchangeOutputField.js +++ b/src/components/exchange/ExchangeOutputField.js @@ -75,7 +75,7 @@ export default class ExchangeOutputField extends PureComponent { flex={0} width="100%" css={` - ${padding(25 + paddingValue, 0, 25)}; + ${padding(24 + paddingValue, 0, 26)}; background-color: ${colors.white}; overflow: hidden; border-bottom-left-radius: ${bottomRadius}px; diff --git a/src/components/exchange/ExchangeSearch.js b/src/components/exchange/ExchangeSearch.js index 0af357ab38b..67291382f7d 100644 --- a/src/components/exchange/ExchangeSearch.js +++ b/src/components/exchange/ExchangeSearch.js @@ -11,10 +11,10 @@ import { RowWithMargins } from '../layout'; const ExchangeSearchHeight = 40; const Container = styled(RowWithMargins).attrs({ - margin: 6.5, + margin: 7, })` - ${margin(0, 15, 10)}; - ${padding(9, 13, 10)}; + ${margin(0, 15, 4)}; + ${padding(0, 13, 0)}; background-color: ${colors.skeleton}; border-radius: ${ExchangeSearchHeight / 2}; height: ${ExchangeSearchHeight}; @@ -47,7 +47,12 @@ export default class ExchangeSearch extends PureComponent { render = () => ( - + (direction === 'left' ? 0 : 20)}; padding-right: ${({ direction }) => (direction === 'right' ? 0 : 20)}; `; diff --git a/src/components/header/Header.js b/src/components/header/Header.js index 1f40bc1d2ad..99e1bd3fb1d 100644 --- a/src/components/header/Header.js +++ b/src/components/header/Header.js @@ -4,7 +4,7 @@ import { padding } from '../../styles'; import { Row } from '../layout'; const StatusBarHeight = getStatusBarHeight(true); -const HeaderHeight = 52; +const HeaderHeight = 46; const HeaderHeightWithStatusBar = HeaderHeight + StatusBarHeight; // eslint-disable-next-line react/display-name diff --git a/src/components/icons/svg/CaretIcon.js b/src/components/icons/svg/CaretIcon.js index a028c75e33c..9197a58e211 100644 --- a/src/components/icons/svg/CaretIcon.js +++ b/src/components/icons/svg/CaretIcon.js @@ -9,12 +9,12 @@ import Svg from '../Svg'; const CaretIcon = ({ color, size, ...props }) => ( diff --git a/src/components/inputs/ClearInputDecorator.js b/src/components/inputs/ClearInputDecorator.js index a77d9a3b467..d132e7a859d 100644 --- a/src/components/inputs/ClearInputDecorator.js +++ b/src/components/inputs/ClearInputDecorator.js @@ -70,7 +70,7 @@ const ClearInputDecorator = ({ inputHeight, isVisible, onPress }) => { diff --git a/src/components/modal/ModalHeader.js b/src/components/modal/ModalHeader.js index 5bdc57e4a66..8b0ab077b8b 100644 --- a/src/components/modal/ModalHeader.js +++ b/src/components/modal/ModalHeader.js @@ -44,8 +44,10 @@ const ModalHeader = ({ )} diff --git a/src/components/profile/ProfileMasthead.js b/src/components/profile/ProfileMasthead.js index 1d125e90935..b4df4ac997d 100644 --- a/src/components/profile/ProfileMasthead.js +++ b/src/components/profile/ProfileMasthead.js @@ -28,7 +28,6 @@ const AddressAbbreviation = styled(TruncatedAddress).attrs({ const Container = styled(Centered).attrs({ direction: 'column' })` margin-bottom: 24; padding-bottom: 32; - padding-top: 3; `; const ProfileMasthead = ({ diff --git a/src/components/shadow-stack/ShadowStack.js b/src/components/shadow-stack/ShadowStack.js index e53b54be204..08532a045ab 100644 --- a/src/components/shadow-stack/ShadowStack.js +++ b/src/components/shadow-stack/ShadowStack.js @@ -8,8 +8,7 @@ import ShadowItem from './ShadowItem'; const ChildrenWrapper = styled.View` ${position.cover}; - background-color: ${({ backgroundColor }) => - backgroundColor || colors.transparent}; + background-color: ${colors.transparent}; border-radius: ${({ borderRadius }) => borderRadius}; overflow: hidden; `; @@ -17,8 +16,7 @@ const ChildrenWrapper = styled.View` const ShadowStackContainer = styled.View` ${({ height }) => (height ? `height: ${height};` : '')} ${({ width }) => (width ? `width: ${width};` : '')} - background-color: ${({ backgroundColor }) => - backgroundColor || colors.transparent}; + background-color: ${colors.transparent}; border-radius: ${({ borderRadius }) => borderRadius}; z-index: 1; `; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 7b6b034b6a8..82f0bf81fd2 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -802,7 +802,7 @@ class ExchangeModal extends Component { {isSufficientBalance && } {showConfirmButton && ( - + -
+
From e9914d9c1dc4c3bbc3a7bc766793686d500332c0 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 7 Nov 2019 15:28:01 -0500 Subject: [PATCH 485/636] Reduce padding below header buttons --- src/components/exchange/CurrencySelectModalHeader.js | 2 +- src/components/header/Header.js | 2 +- src/components/header/HeaderButton.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/exchange/CurrencySelectModalHeader.js b/src/components/exchange/CurrencySelectModalHeader.js index 0c81f4a3d4d..8e6e85213a7 100644 --- a/src/components/exchange/CurrencySelectModalHeader.js +++ b/src/components/exchange/CurrencySelectModalHeader.js @@ -11,7 +11,7 @@ const BackButtonWrapper = styled(Centered)` bottom: 0; left: 0; position: absolute; - top: 5; + top: 3; `; const HeaderHeight = 59; diff --git a/src/components/header/Header.js b/src/components/header/Header.js index 99e1bd3fb1d..57543ea8810 100644 --- a/src/components/header/Header.js +++ b/src/components/header/Header.js @@ -4,7 +4,7 @@ import { padding } from '../../styles'; import { Row } from '../layout'; const StatusBarHeight = getStatusBarHeight(true); -const HeaderHeight = 46; +const HeaderHeight = 44; const HeaderHeightWithStatusBar = HeaderHeight + StatusBarHeight; // eslint-disable-next-line react/display-name diff --git a/src/components/header/HeaderButton.js b/src/components/header/HeaderButton.js index 7251e0e6967..af7f7e56958 100644 --- a/src/components/header/HeaderButton.js +++ b/src/components/header/HeaderButton.js @@ -7,7 +7,7 @@ import { Flex } from '../layout'; const HeaderButton = ({ children, onPress, transformOrigin, ...props }) => ( - + {children} From ffa4cf99ddbe6f1f1c859b1c536b54cb7b75af40 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 9 Nov 2019 16:05:22 -0500 Subject: [PATCH 486/636] Rename updated input/output amount variables in swap --- src/screens/ExchangeModal.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 82f0bf81fd2..183e8ab089a 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -449,20 +449,20 @@ class ExchangeModal extends Component { if (isInputEmpty || isInputZero) { this.setOutputAmount(); } else { - const updatedAmount = get(tradeDetails, 'outputAmount.amount'); - const rawUpdatedAmount = convertRawAmountToDecimalFormat( - updatedAmount, + const updatedOutputAmount = get(tradeDetails, 'outputAmount.amount'); + const rawUpdatedOutputAmount = convertRawAmountToDecimalFormat( + updatedOutputAmount, outputDecimals ); - const updatedAmountDisplay = updatePrecisionToDisplay( - rawUpdatedAmount, + const updatedOutputAmountDisplay = updatePrecisionToDisplay( + rawUpdatedOutputAmount, get(outputCurrency, 'price.value') ); this.setOutputAmount( - rawUpdatedAmount, - updatedAmountDisplay, + rawUpdatedOutputAmount, + updatedOutputAmountDisplay, inputAsExactAmount ); } @@ -475,26 +475,26 @@ class ExchangeModal extends Component { isSufficientBalance: true, }); } else { - const updatedAmount = get(tradeDetails, 'inputAmount.amount'); - const rawUpdatedAmount = convertRawAmountToDecimalFormat( - updatedAmount, + const updatedInputAmount = get(tradeDetails, 'inputAmount.amount'); + const rawUpdatedInputAmount = convertRawAmountToDecimalFormat( + updatedInputAmount, inputDecimals ); - const updatedAmountDisplay = updatePrecisionToDisplay( - rawUpdatedAmount, + const updatedInputAmountDisplay = updatePrecisionToDisplay( + rawUpdatedInputAmount, get(inputCurrency, 'price.value') ); this.setInputAmount( - rawUpdatedAmount, - updatedAmountDisplay, + rawUpdatedInputAmount, + updatedInputAmountDisplay, inputAsExactAmount ); this.setState({ isSufficientBalance: - Number(inputBalance) >= Number(rawUpdatedAmount), + Number(inputBalance) >= Number(rawUpdatedInputAmount), }); } } From 875fed8cde52180b4ec8ca4008bbd3ab5ab8b7e7 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 9 Nov 2019 16:03:25 -0500 Subject: [PATCH 487/636] Fix: updatePrecisionToDisplay should round up input values and round down output values --- src/helpers/__tests__/utilities.test.js | 38 +++++++++++++++++++++++++ src/helpers/utilities.js | 29 ++++++++++++++----- src/screens/ExchangeModal.js | 9 ++++-- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js index a522fe3c991..a537bb289bd 100644 --- a/src/helpers/__tests__/utilities.test.js +++ b/src/helpers/__tests__/utilities.test.js @@ -54,6 +54,15 @@ it('updatePrecisionToDisplay1', () => { expect(result).toBe('0.000000001'); }); +it('updatePrecisionToDisplay1RoundUp', () => { + const result = updatePrecisionToDisplay( + '0.00000000123', + '0.1234987234', + true + ); + expect(result).toBe('0.000000002'); +}); + it('updatePrecisionToDisplay2', () => { const result = updatePrecisionToDisplay( '0.17987196800000002', @@ -62,22 +71,51 @@ it('updatePrecisionToDisplay2', () => { expect(result).toBe('0.179'); }); +it('updatePrecisionToDisplay2RoundUp', () => { + const result = updatePrecisionToDisplay( + '0.17987196800000002', + '0.1234987234', + true + ); + expect(result).toBe('0.18'); +}); + it('updatePrecisionToDisplay3', () => { const result = updatePrecisionToDisplay('0.123456789', '3.001'); expect(result).toBe('0.123'); }); +it('updatePrecisionToDisplay3RoundUp', () => { + const result = updatePrecisionToDisplay('0.123456789', '3.001', true); + expect(result).toBe('0.124'); +}); + it('updatePrecisionToDisplay4', () => { const result = updatePrecisionToDisplay('0.123456789', '32.0412'); expect(result).toBe('0.1234'); }); +it('updatePrecisionToDisplay4RoundUp', () => { + const result = updatePrecisionToDisplay('0.123456789', '32.0412', true); + expect(result).toBe('0.1235'); +}); + it('updatePrecisionToDisplay5', () => { const result = updatePrecisionToDisplay('0.123456789', '132.0051'); expect(result).toBe('0.12345'); }); +it('updatePrecisionToDisplay5RoundUp', () => { + const result = updatePrecisionToDisplay('0.123456789', '132.0051', true); + expect(result).toBe('0.12346'); +}); + it('updatePrecisionToDisplay6', () => { const result = updatePrecisionToDisplay('0.123456789', '1320.0112'); expect(result).toBe('0.123456'); }); + +it('updatePrecisionToDisplay6RoundUp', () => { + const result = updatePrecisionToDisplay('0.123456789', '1320.0112', true); + expect(result).toBe('0.123457'); +}); diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 45d4d6891f5..a18c73764b1 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -90,21 +90,36 @@ export const floorDivide = (numberOne, numberTwo) => */ export const countDecimalPlaces = value => BigNumber(`${value}`).dp(); -export const updatePrecisionToDisplay = (amount, nativePrice) => { +/** + * @desc update the amount to display precision + * equivalent to ~0.01 of the native price + * or use most significant decimal + * if the updated precision amounts to zero + * @param {String} amount + * @param {String} nativePrice + * @param {Boolean} use rounding up mode + * @return {String} updated amount + */ +export const updatePrecisionToDisplay = ( + amount, + nativePrice, + roundUp = false +) => { + const roundingMode = roundUp ? BigNumber.ROUND_UP : BigNumber.ROUND_DOWN; const bnAmount = BigNumber(`${amount}`); - const significantDigits = BigNumber(`${nativePrice}`) + const significantDigitsOfNativePriceInteger = BigNumber(`${nativePrice}`) .decimalPlaces(0, BigNumber.ROUND_DOWN) .sd(true); - const truncatedPrecision = BigNumber(significantDigits) + const truncatedPrecision = BigNumber(significantDigitsOfNativePriceInteger) .plus(2, 10) .toNumber(); - const result = bnAmount.decimalPlaces( + const truncatedAmount = bnAmount.decimalPlaces( truncatedPrecision, BigNumber.ROUND_DOWN ); - return result.isZero() - ? BigNumber(bnAmount.toPrecision(1, BigNumber.ROUND_DOWN)).toFixed() - : result.toFixed(); + return truncatedAmount.isZero() + ? BigNumber(bnAmount.toPrecision(1, roundingMode)).toFixed() + : bnAmount.decimalPlaces(truncatedPrecision, roundingMode).toFixed(); }; /** diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 183e8ab089a..38e5496e55d 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -405,7 +405,8 @@ class ExchangeModal extends Component { const outputPriceValue = get(outputCurrency, 'price.value', 0); outputExecutionRate = updatePrecisionToDisplay( get(tradeDetails, 'executionRate.rateInverted', BigNumber(0)), - outputPriceValue + outputPriceValue, + true ); outputNativePrice = convertAmountToNativeDisplay( @@ -483,7 +484,8 @@ class ExchangeModal extends Component { const updatedInputAmountDisplay = updatePrecisionToDisplay( rawUpdatedInputAmount, - get(inputCurrency, 'price.value') + get(inputCurrency, 'price.value'), + true ); this.setInputAmount( @@ -679,7 +681,8 @@ class ExchangeModal extends Component { inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); inputAmountDisplay = updatePrecisionToDisplay( inputAmount, - get(inputCurrency, 'price.value') + get(inputCurrency, 'price.value'), + true ); } From a967b0197631e3fc40887f9af0e8425cf034fe30 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 7 Nov 2019 13:14:29 -0500 Subject: [PATCH 488/636] rename uniswap prop to uniswapLiquidityTokenInfo for clarity --- ...st.js => withUniswapLiquidityTokenInfo.test.js} | 2 +- src/hoc/index.js | 4 ++-- ...quidity.js => withUniswapLiquidityTokenInfo.js} | 13 +++++++------ src/redux/uniswap.js | 14 +++++++++----- src/screens/WalletScreen.js | 4 ++-- 5 files changed, 21 insertions(+), 16 deletions(-) rename src/hoc/__tests__/{withUniswapLiquidity.test.js => withUniswapLiquidityTokenInfo.test.js} (86%) rename src/hoc/{withUniswapLiquidity.js => withUniswapLiquidityTokenInfo.js} (89%) diff --git a/src/hoc/__tests__/withUniswapLiquidity.test.js b/src/hoc/__tests__/withUniswapLiquidityTokenInfo.test.js similarity index 86% rename from src/hoc/__tests__/withUniswapLiquidity.test.js rename to src/hoc/__tests__/withUniswapLiquidityTokenInfo.test.js index b0b1258c3dd..2598921b69f 100644 --- a/src/hoc/__tests__/withUniswapLiquidity.test.js +++ b/src/hoc/__tests__/withUniswapLiquidityTokenInfo.test.js @@ -1,4 +1,4 @@ -import { transformPool } from '../withUniswapLiquidity'; +import { transformPool } from '../withUniswapLiquidityTokenInfo'; it('transformPool', async () => { const pool = { diff --git a/src/hoc/index.js b/src/hoc/index.js index b1360b876ad..b5f73fb42cb 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -46,9 +46,9 @@ export { default as withUniqueTokens } from './withUniqueTokens'; export { default as withUniswapAllowances } from './withUniswapAllowances'; export { default as withUniswapAssets } from './withUniswapAssets'; export { - default as withUniswapLiquidity, + default as withUniswapLiquidityTokenInfo, readableUniswapSelector, -} from './withUniswapLiquidity'; +} from './withUniswapLiquidityTokenInfo'; export { default as withWalletConnectConfirmationModal, } from './withWalletConnectConfirmationModal'; diff --git a/src/hoc/withUniswapLiquidity.js b/src/hoc/withUniswapLiquidityTokenInfo.js similarity index 89% rename from src/hoc/withUniswapLiquidity.js rename to src/hoc/withUniswapLiquidityTokenInfo.js index 7e0e2e35831..0ed070d61b1 100644 --- a/src/hoc/withUniswapLiquidity.js +++ b/src/hoc/withUniswapLiquidityTokenInfo.js @@ -20,14 +20,15 @@ import { import { ethereumUtils } from '../utils'; import withAccountSettings from './withAccountSettings'; -const mapStateToProps = ({ uniswap: { uniswap } }) => ({ - uniswap, +const mapStateToProps = ({ uniswap: { uniswapLiquidityTokenInfo } }) => ({ + uniswapLiquidityTokenInfo, }); const assetsSelector = state => state.assets; const nativeCurrencySelector = state => state.nativeCurrency; const nativeCurrencySymbolSelector = state => state.nativeCurrencySymbol; -const uniswapSelector = state => state.uniswap; +const uniswapLiquidityTokenInfoSelector = state => + state.uniswapLiquidityTokenInfo; export const transformPool = (liquidityPool, ethPrice, nativeCurrency) => { if (isEmpty(liquidityPool)) { @@ -74,12 +75,12 @@ const buildUniswapCards = ( nativeCurrency, nativeCurrencySymbol, assets, - uniswap + uniswapLiquidityTokenInfo ) => { const ethPrice = get(ethereumUtils.getAsset(assets), 'price.value', 0); const uniswapPools = compact( - map(values(uniswap), liquidityPool => + map(values(uniswapLiquidityTokenInfo), liquidityPool => transformPool(liquidityPool, ethPrice, nativeCurrency) ) ); @@ -108,7 +109,7 @@ export const readableUniswapSelector = createSelector( nativeCurrencySelector, nativeCurrencySymbolSelector, assetsSelector, - uniswapSelector, + uniswapLiquidityTokenInfoSelector, ], buildUniswapCards ); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 6ca8f5105a4..892a885314a 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -67,7 +67,10 @@ export const uniswapLoadState = () => async (dispatch, getState) => { const { accountAddress, network } = getState().settings; dispatch({ type: UNISWAP_LOAD_REQUEST }); try { - const uniswap = await getUniswapLiquidityInfo(accountAddress, network); + const uniswapLiquidityTokenInfo = await getUniswapLiquidityInfo( + accountAddress, + network + ); const favorites = await getUniswapFavorites(); const liquidityTokens = await getLiquidity(accountAddress, network); const allowances = await getAllowances(accountAddress, network); @@ -82,8 +85,8 @@ export const uniswapLoadState = () => async (dispatch, getState) => { favorites, liquidityTokens, pendingApprovals, - uniswap, uniswapAssets, + uniswapLiquidityTokenInfo, }, type: UNISWAP_LOAD_SUCCESS, }); @@ -362,8 +365,8 @@ export const INITIAL_UNISWAP_STATE = { outputCurrency: null, outputReserve: null, pendingApprovals: {}, - uniswap: {}, uniswapAssets: {}, + uniswapLiquidityTokenInfo: {}, }; export default (state = INITIAL_UNISWAP_STATE, action) => @@ -378,7 +381,8 @@ export default (state = INITIAL_UNISWAP_STATE, action) => draft.liquidityTokens = action.payload.liquidityTokens; draft.loadingUniswap = false; draft.pendingApprovals = action.payload.pendingApprovals; - draft.uniswap = action.payload.uniswap; + draft.uniswapLiquidityTokenInfo = + action.payload.uniswapLiquidityTokenInfo; draft.uniswapAssets = action.payload.uniswapAssets; break; case UNISWAP_UPDATE_FAVORITES: @@ -404,7 +408,7 @@ export default (state = INITIAL_UNISWAP_STATE, action) => break; case UNISWAP_UPDATE_SUCCESS: draft.fetchingUniswap = false; - draft.uniswap = action.payload; + draft.uniswapLiquidityTokenInfo = action.payload; break; case UNISWAP_UPDATE_FAILURE: draft.fetchingUniswap = false; diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 2f64c4118e4..57216d9b909 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -26,7 +26,7 @@ import { withIsWalletEthZero, withStatusBarStyle, withUniqueTokens, - withUniswapLiquidity, + withUniswapLiquidityTokenInfo, } from '../hoc'; import { setOpenSmallBalances } from '../redux/openBalances'; import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; @@ -132,7 +132,7 @@ export default compose( withUniqueTokens, withAccountSettings, withDataInit, - withUniswapLiquidity, + withUniswapLiquidityTokenInfo, withSafeTimeout, withNavigation, withNavigationFocus, From 933c29a7292c8c3baa47435aa7c9853737c7d5af Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 7 Nov 2019 18:56:14 -0500 Subject: [PATCH 489/636] rename uniswap pending approval function for clarity --- src/hoc/withUniswapAllowances.js | 4 ++-- src/redux/uniswap.js | 2 +- src/screens/ExchangeModal.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 6f150213f60..45558ddbd1c 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; import { + uniswapAddPendingApproval, uniswapClearCurrenciesAndReserves, uniswapUpdateAllowances, uniswapUpdateInputCurrency, uniswapUpdateOutputCurrency, - uniswapUpdatePendingApprovals, } from '../redux/uniswap'; const mapStateToProps = ({ @@ -27,10 +27,10 @@ export default Component => connect( mapStateToProps, { + uniswapAddPendingApproval, uniswapClearCurrenciesAndReserves, uniswapUpdateAllowances, uniswapUpdateInputCurrency, uniswapUpdateOutputCurrency, - uniswapUpdatePendingApprovals, } )(Component); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 892a885314a..c8ec6169869 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -139,7 +139,7 @@ export const uniswapClearState = () => (dispatch, getState) => { dispatch({ type: UNISWAP_CLEAR_STATE }); }; -export const uniswapUpdatePendingApprovals = ( +export const uniswapAddPendingApproval = ( tokenAddress, txHash, creationTimestamp, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 82f0bf81fd2..c9a7d0a0a46 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -95,8 +95,8 @@ class ExchangeModal extends Component { tokenReserves: PropTypes.object, tradeDetails: PropTypes.object, txFees: PropTypes.object, + uniswapAddPendingApproval: PropTypes.func, uniswapUpdateAllowances: PropTypes.func, - uniswapUpdatePendingApprovals: PropTypes.func, }; state = { @@ -559,7 +559,7 @@ class ExchangeModal extends Component { handleUnlockAsset = async () => { try { const { inputCurrency } = this.state; - const { gasLimit, gasPrices, uniswapUpdatePendingApprovals } = this.props; + const { gasLimit, gasPrices, uniswapAddPendingApproval } = this.props; const fastGasPrice = get(gasPrices, `[${gasUtils.FAST}]`); const { creationTimestamp: approvalCreationTimestamp, @@ -574,7 +574,7 @@ class ExchangeModal extends Component { fastGasPrice, 'estimatedTime.amount' ); - uniswapUpdatePendingApprovals( + uniswapAddPendingApproval( inputCurrency.address, hash, approvalCreationTimestamp, From ef7f01a8cdeda4151de6de4fe8871103f57c0680 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 7 Nov 2019 21:28:23 -0500 Subject: [PATCH 490/636] update state with uniswap liquidity token info from localstorage first --- src/redux/uniswap.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index c8ec6169869..86c6cb4e8f6 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -42,6 +42,9 @@ const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; const UNISWAP_LOAD_SUCCESS = 'uniswap/UNISWAP_LOAD_SUCCESS'; const UNISWAP_LOAD_FAILURE = 'uniswap/UNISWAP_LOAD_FAILURE'; +const UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS = + 'uniswap/UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS'; + const UNISWAP_UPDATE_REQUEST = 'uniswap/UNISWAP_UPDATE_REQUEST'; const UNISWAP_UPDATE_SUCCESS = 'uniswap/UNISWAP_UPDATE_SUCCESS'; const UNISWAP_UPDATE_FAILURE = 'uniswap/UNISWAP_UPDATE_FAILURE'; @@ -71,14 +74,18 @@ export const uniswapLoadState = () => async (dispatch, getState) => { accountAddress, network ); + dispatch({ + payload: uniswapLiquidityTokenInfo, + type: UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS, + }); + const allowances = await getAllowances(accountAddress, network); const favorites = await getUniswapFavorites(); const liquidityTokens = await getLiquidity(accountAddress, network); - const allowances = await getAllowances(accountAddress, network); - const uniswapAssets = await getUniswapAssets(accountAddress, network); const pendingApprovals = await getUniswapPendingApprovals( accountAddress, network ); + const uniswapAssets = await getUniswapAssets(accountAddress, network); dispatch({ payload: { allowances, @@ -86,7 +93,6 @@ export const uniswapLoadState = () => async (dispatch, getState) => { liquidityTokens, pendingApprovals, uniswapAssets, - uniswapLiquidityTokenInfo, }, type: UNISWAP_LOAD_SUCCESS, }); @@ -375,14 +381,15 @@ export default (state = INITIAL_UNISWAP_STATE, action) => case UNISWAP_LOAD_REQUEST: draft.loadingUniswap = true; break; + case UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS: + draft.uniswapLiquidityTokenInfo = action.payload; + break; case UNISWAP_LOAD_SUCCESS: draft.allowances = action.payload.allowances; draft.favorites = action.payload.favorites; draft.liquidityTokens = action.payload.liquidityTokens; draft.loadingUniswap = false; draft.pendingApprovals = action.payload.pendingApprovals; - draft.uniswapLiquidityTokenInfo = - action.payload.uniswapLiquidityTokenInfo; draft.uniswapAssets = action.payload.uniswapAssets; break; case UNISWAP_UPDATE_FAVORITES: From 4c56ac72fb647b3cdeb8ecedd2127c25a1ce347b Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 8 Nov 2019 04:09:25 -0500 Subject: [PATCH 491/636] Fix issues related to leading decimals + leading zeros --- ios/Podfile.lock | 44 ++--- src/components/coin-row/ExchangeCoinRow.js | 6 +- .../exchange/CurrencySelectionList.js | 14 +- src/components/exchange/ExchangeInput.js | 46 ++++- src/screens/ExchangeModal.js | 30 +-- yarn.lock | 183 +++++++++++++++--- 6 files changed, 238 insertions(+), 85 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4a92e369342..f8dbfb4728a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -624,8 +624,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 9b38e9b284a4a7371d6a7eb7f561b1ca5b96823a - FBReactNativeSpec: 1645d04d7eb308d13322d1a3b7dc972f811b158c + FBLazyVector: cba38f85f99345e0a5363c733fb899ac0374456e + FBReactNativeSpec: 454704730bc852f3df18aa3d737fae49c1b8c807 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,15 +641,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 0d2ced92ba3315e0fad9ec10044297ac192751b9 - RCTTypeSafety: bf09a7a477297cc999611146120564b759f083e6 - React: 6bf780885ae68bdf7dab4bed6eb97a6b29299a81 - React-Core: 95082d89adf87c4c4200f0d12008c9b6fe1d1726 - React-CoreModules: 15ce069a8b2f3f31734baf8fecfd604e4703562b - React-cxxreact: 02ca09ae4e6ace75c8c985a397dce6ecc98974f8 - React-jsi: 0e6d81dcb35b667df0183f4653f79e6d599f0a76 - React-jsiexecutor: 62c3cb35bbb9263a070ef99803bd7d210dd05b06 - React-jsinspector: f16017328b003e8baef8b5c3481e6479e72aea50 + RCTRequired: 1e96ef069b5ca9b5b50baf6d0af9048232b458ff + RCTTypeSafety: 4b2ca882920f75cd61b89db27bc010cdf6cce574 + React: 3053a3e7446830d7e34befa2aea3e316447dcbff + React-Core: b04f999a0c226801e3260e4fe5aca555cc4c3a2c + React-CoreModules: 808cbc2978af28e20c046b28aec7029f15d03300 + React-cxxreact: 24d49b79cbb4d915c8e163fc4c0bf15553166347 + React-jsi: 989c7df372bb2faad532bfeb76326ab301514dde + React-jsiexecutor: 163af49f01253cf3a15bec1b84172a60a8790dc2 + React-jsinspector: 0c2e65fb3ee2084961ebbb44f76dcd0bae778a19 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 @@ -659,16 +659,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 3cffc9f5fcfdb95baa722c3e78efd2a4f2dd40f3 - React-RCTAnimation: 3c8f2f065030db5c43537dbd5f9239636737b849 - React-RCTBlob: cfb83cd5dcfa54e284d89cd1eacf86b58b342e4b - React-RCTImage: d69c65908081498af219c0f0eb5336d1a9e61d8a - React-RCTLinking: 79b6421689a291b7a456ca29660d027782fc15c3 - React-RCTNetwork: 0ba165f2bc06857513301c4288dbb21eb7749788 - React-RCTSettings: 84d22405b77980d386c59bd1590c6f0178afe566 - React-RCTText: 8f5833fcd29e64967182bd83ed18d4bd10895801 - React-RCTVibration: 66ba6784fa6e0947c85fa6622c31f8cd9e2e6c2b - ReactCommon: a67533cedebb16637db2a8420cf81be9a9625fcf + React-RCTActionSheet: 2519e835f932cebdbf09d083f26da20ccee04c4d + React-RCTAnimation: 5532bd047009610ad5241901a12fdb04de63b928 + React-RCTBlob: 1442ce9a65a6183e61673a4f80ae82d23f097ba6 + React-RCTImage: bea88e624edf49dd6eb990aafd09659986faf859 + React-RCTLinking: 626f7b18df5dd23c8f97992cb419e3ed0123a8a6 + React-RCTNetwork: 118bbd48bdcdbfb7495d8ef6853c783ca9d5e2fa + React-RCTSettings: abad768c41c0d199dd2bbc0c82ec7b6fedfbe56d + React-RCTText: 169de4510d0741f73d73ee6d5c25194ffb4b08a7 + React-RCTVibration: a88813cd6826cd5722b5f769611e49490abc10e3 + ReactCommon: b87d3090701ca4b90139fd28ccbbc978157914a1 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -692,7 +692,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: dfba15033d50829ffbf6aa3a0b47212962ce386c + Yoga: 57c54b4bbd7f55a069f4a5eaaa55909f4e122af9 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 16e27008473..bde669de5be 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -70,10 +70,8 @@ class ExchangeCoinRow extends Component { }; handlePress = () => { - const { item, onPress } = this.props; - - if (onPress) { - onPress(item); + if (this.props.onPress) { + this.props.onPress(this.props.item); } }; diff --git a/src/components/exchange/CurrencySelectionList.js b/src/components/exchange/CurrencySelectionList.js index cfa9ff43dc9..8bec52a3a6c 100644 --- a/src/components/exchange/CurrencySelectionList.js +++ b/src/components/exchange/CurrencySelectionList.js @@ -44,13 +44,6 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { const showNoResults = listItems.length === 0; - const onListMount = () => { - if (showSkeleton && showList) { - skeletonTransitionRef.current.animateNextTransition(); - setShowSkeleton(false); - } - }; - useEffect(() => { if (!showSkeleton && !showList) { setShowSkeleton(true); @@ -71,8 +64,13 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { ) : ( { + if (showSkeleton && showList) { + skeletonTransitionRef.current.animateNextTransition(); + setShowSkeleton(false); + } + }} renderItem={renderItem} scrollIndicatorInsets={{ bottom: exchangeModalBorderRadius, diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index 935e8e27685..d02712b78b2 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -1,10 +1,11 @@ -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import TextInputMask from 'react-native-text-input-mask'; import stylePropType from 'react-style-proptype'; import { colors, fonts } from '../../styles'; +import { isNewValueForObjectPaths } from '../../utils'; -export default class ExchangeInput extends PureComponent { +export default class ExchangeInput extends Component { static propTypes = { color: PropTypes.string, disableTabularNums: PropTypes.bool, @@ -31,20 +32,50 @@ export default class ExchangeInput extends PureComponent { value: '', }; - handleChangeText = (formatted, extracted) => { - let text = extracted ? formatted : ''; + state = { touched: false }; - if (!text.length && !this.props.value) { + shouldComponentUpdate = (nextProps, nextState) => + nextState.touched !== this.state.touched || + isNewValueForObjectPaths(this.props, nextProps, [ + 'color', + 'editable', + 'placeholder', + 'placeholderTextColor', + 'value', + ]); + + handleBlur = () => { + const { value } = this.props; + + if (typeof value === 'string') { + const parts = value.split('.'); + if (parts[0].length > 1 && !Number(parts[0])) { + this.props.onChangeText(`0.${parts[1]}`); + } + } + }; + + handleChangeText = formatted => { + let text = formatted; + + if (this.state.touched && !text.length && !this.props.value) { text = '0.'; } this.props.onChangeText(text); }; + toggleTouched = () => { + if (!this.state.touched) { + this.setState({ touched: true }); + } + }; + render = () => { const { color, disableTabularNums, + editable, fontFamily, fontSize, fontWeight, @@ -60,10 +91,13 @@ export default class ExchangeInput extends PureComponent { Date: Fri, 8 Nov 2019 04:11:06 -0500 Subject: [PATCH 492/636] Fix slippage showing 100% even when inputs were 0 Fixes RAI-63 https://linear.app/issue/RAI-63 --- src/screens/ExchangeModal.js | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 466f51c4507..616e86d5b4b 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -36,6 +36,7 @@ import { convertAmountToNativeAmount, convertAmountToNativeDisplay, convertAmountToRawAmount, + convertNumberToString, convertRawAmountToDecimalFormat, greaterThan, subtract, @@ -135,6 +136,7 @@ class ExchangeModal extends Component { 'inputAmount', 'inputCurrency.uniqueId', 'isAssetApproved', + 'isSufficientBalance', 'isUnlockingAsset', 'nativeAmount', 'outputAmount', @@ -415,17 +417,22 @@ class ExchangeModal extends Component { ); } - const slippage = get(tradeDetails, 'executionRateSlippage', 0).toString(); + const slippage = convertNumberToString( + get(tradeDetails, 'executionRateSlippage', 0) + ); const inputBalance = ethereumUtils.getBalanceAmount( selectedGasPrice, inputCurrency ); + const isSufficientBalance = + !parseFloat(inputAmount) || + parseFloat(inputBalance) >= parseFloat(inputAmount); + this.setState({ inputExecutionRate, inputNativePrice, - isSufficientBalance: - !inputAmount || Number(inputBalance) >= Number(inputAmount), + isSufficientBalance, outputExecutionRate, outputNativePrice, slippage, @@ -498,7 +505,7 @@ class ExchangeModal extends Component { this.setState({ isSufficientBalance: - Number(inputBalance) >= Number(rawUpdatedInputAmount), + parseFloat(inputBalance) >= parseFloat(rawUpdatedInputAmount), }); } } @@ -736,6 +743,7 @@ class ExchangeModal extends Component { const { approvalCreationTimestamp, approvalEstimatedTimeInMs, + inputAmount, inputAmountDisplay, inputCurrency, // inputExecutionRate, @@ -744,6 +752,7 @@ class ExchangeModal extends Component { isSufficientBalance, isUnlockingAsset, nativeAmount, + outputAmount, outputAmountDisplay, outputCurrency, // outputExecutionRate, @@ -752,6 +761,9 @@ class ExchangeModal extends Component { slippage, } = this.state; + const isSlippageWarningVisible = + isSufficientBalance && !!inputAmount && !!outputAmount; + return ( @@ -804,7 +816,9 @@ class ExchangeModal extends Component { setOutputAmount={this.setOutputAmount} /> - {isSufficientBalance && } + {isSlippageWarningVisible && ( + + )} {showConfirmButton && ( From c42420a13002bb60c3a733668fa8bdb0a586a9d1 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 9 Nov 2019 01:00:28 -0500 Subject: [PATCH 493/636] add unisocks to token pair json --- src/references/token-overrides.json | 3 +++ src/references/uniswap-pairs.json | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 3618a1901ac..6b0f0161235 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -137,6 +137,9 @@ "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E": { "name": "TrueUSD" }, + "0x23B608675a2B2fB1890d3ABBd85c5775c51691d5": { + "name": "Unisocks Edition 0" + }, "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { "name": "Uniswap V1" }, diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index ba3997b2222..333c768b2b2 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -304,5 +304,11 @@ "symbol": "ZRX", "decimals": 18, "exchangeAddress": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" + }, + "0x23B608675a2B2fB1890d3ABBd85c5775c51691d5": { + "symbol": "SOCKS", + "name": "Unisocks Edition 0", + "decimals": 18, + "exchangeAddress": "0x22d8432cc7aA4f8712a655fC4cdfB1baEC29FCA9" } } From 40036cf6dd70bd171768c234121d3e98da688fca Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 00:14:38 -0500 Subject: [PATCH 494/636] =?UTF-8?q?Fix=20flashing=20=E2=80=980.=E2=80=99?= =?UTF-8?q?=20when=20swiping=20between=20swap=20UI=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes RAI-64 https://linear.app/issue/RAI-64 Fixes RAI-65 https://linear.app/issue/RAI-65 --- src/components/exchange/ExchangeInput.js | 57 +++++++++++++++---- .../exchange/ExchangeNativeField.js | 5 +- src/screens/ExchangeModal.js | 6 +- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/components/exchange/ExchangeInput.js b/src/components/exchange/ExchangeInput.js index d02712b78b2..0b6c7ffb419 100644 --- a/src/components/exchange/ExchangeInput.js +++ b/src/components/exchange/ExchangeInput.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import { InteractionManager } from 'react-native'; import TextInputMask from 'react-native-text-input-mask'; import stylePropType from 'react-style-proptype'; import { colors, fonts } from '../../styles'; @@ -13,7 +14,10 @@ export default class ExchangeInput extends Component { fontSize: PropTypes.string, fontWeight: PropTypes.string, mask: PropTypes.string, + onBlur: PropTypes.func, + onChange: PropTypes.func, onChangeText: PropTypes.func, + onFocus: PropTypes.func, placeholder: PropTypes.string, placeholderTextColor: PropTypes.string, refInput: PropTypes.func, @@ -32,10 +36,13 @@ export default class ExchangeInput extends Component { value: '', }; - state = { touched: false }; + state = { + isFocused: false, + isTouched: false, + }; shouldComponentUpdate = (nextProps, nextState) => - nextState.touched !== this.state.touched || + nextState.isTouched !== this.state.isTouched || isNewValueForObjectPaths(this.props, nextProps, [ 'color', 'editable', @@ -44,30 +51,57 @@ export default class ExchangeInput extends Component { 'value', ]); - handleBlur = () => { - const { value } = this.props; + handleBlur = event => { + const { onBlur, onChangeText, value } = this.props; if (typeof value === 'string') { const parts = value.split('.'); if (parts[0].length > 1 && !Number(parts[0])) { - this.props.onChangeText(`0.${parts[1]}`); + onChangeText(`0.${parts[1]}`); } } + + this.setState({ + isFocused: false, + isTouched: false, + }); + + if (onBlur) { + onBlur(event); + } + }; + + handleFocus = event => { + this.setState({ isFocused: true }); + if (this.props.onFocus) { + this.props.onFocus(event); + } }; handleChangeText = formatted => { + const { onChangeText, value } = this.props; let text = formatted; - if (this.state.touched && !text.length && !this.props.value) { + if (this.state.isTouched && !text.length && !value) { text = '0.'; } - this.props.onChangeText(text); + if (onChangeText) { + onChangeText(text); + } }; - toggleTouched = () => { - if (!this.state.touched) { - this.setState({ touched: true }); + handleChange = event => { + const { isFocused, isTouched } = this.state; + + if (isFocused && !isTouched) { + InteractionManager.runAfterInteractions(() => { + this.setState({ isTouched: true }); + }); + } + + if (this.props.onChange) { + this.props.onChange(event); } }; @@ -97,8 +131,9 @@ export default class ExchangeInput extends Component { keyboardType="decimal-pad" mask={mask} onBlur={this.handleBlur} - onChange={this.toggleTouched} + onChange={this.handleChange} onChangeText={this.handleChangeText} + onFocus={this.handleFocus} placeholder={placeholder} placeholderTextColor={placeholderTextColor} refInput={refInput} diff --git a/src/components/exchange/ExchangeNativeField.js b/src/components/exchange/ExchangeNativeField.js index 0645b5ec1ee..0da19c552f1 100644 --- a/src/components/exchange/ExchangeNativeField.js +++ b/src/components/exchange/ExchangeNativeField.js @@ -78,7 +78,10 @@ class ExchangeNativeField extends Component { const { isFocused } = this.state; - let opacity = nativeAmount ? 0.5 : 0.3; + const nativeAmountExists = + typeof nativeAmount === 'string' && nativeAmount.length > 0; + + let opacity = nativeAmountExists ? 0.5 : 0.3; if (isFocused) { opacity = 1; } diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 616e86d5b4b..2806d2d5f8a 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -144,7 +144,11 @@ class ExchangeModal extends Component { 'slippage', ]); - return nextProps.isFocused ? isNewProps || isNewState : false; + if (this.props.isFocused && nextProps.isFocused) { + return isNewProps || isNewState; + } + + return false; }; componentDidUpdate = (prevProps, prevState) => { From 3694c2bd6d7f6cb2a6718d4ae0f5d6bb833d0dfd Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 00:16:15 -0500 Subject: [PATCH 495/636] Improve "favorite star" touchable hitbox Fixes RAI-62 https://linear.app/issue/RAI-62 --- .../animations/ButtonPressAnimation.js | 4 +- .../coin-row/CoinRowFavoriteButton.js | 47 +++++++++++++++++++ src/components/coin-row/ExchangeCoinRow.js | 34 +++++--------- src/components/coin-row/index.js | 5 +- 4 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 src/components/coin-row/CoinRowFavoriteButton.js diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 551943f23e4..be4b31ebfda 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -1,6 +1,6 @@ import { omit, pick } from 'lodash'; import PropTypes from 'prop-types'; -import React, { Fragment, PureComponent } from 'react'; +import React, { Fragment, Component } from 'react'; import { InteractionManager } from 'react-native'; import { createNativeWrapper, @@ -65,7 +65,7 @@ const HapticFeedbackTypes = { selection: 'selection', }; -export default class ButtonPressAnimation extends PureComponent { +export default class ButtonPressAnimation extends Component { static propTypes = { activeOpacity: PropTypes.number, children: PropTypes.any, diff --git a/src/components/coin-row/CoinRowFavoriteButton.js b/src/components/coin-row/CoinRowFavoriteButton.js new file mode 100644 index 00000000000..dc1c4bf3d4c --- /dev/null +++ b/src/components/coin-row/CoinRowFavoriteButton.js @@ -0,0 +1,47 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import styled from 'styled-components/primitives'; +import { colors, padding, position } from '../../styles'; +import { ButtonPressAnimation } from '../animations'; +import { Icon } from '../icons'; +import { Centered } from '../layout'; +import CoinRow from './CoinRow'; + +const FavoriteButtonPadding = 19; +const FavoriteButtonWidth = FavoriteButtonPadding * 3; + +const Container = styled(Centered).attrs({ flex: 0 })` + ${padding(0, FavoriteButtonPadding)} + bottom: 0; + height: ${CoinRow.height} + position: absolute; + right: 0; + top: 0; + width: ${FavoriteButtonWidth}; +`; + +const CoinRowFavoriteButton = ({ isFavorited, onPress }) => ( + + + + + + + +); + +CoinRowFavoriteButton.propTypes = { + isFavorited: PropTypes.bool, + onPress: PropTypes.func, +}; + +export default React.memo(CoinRowFavoriteButton); diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index bde669de5be..e53b22da5ba 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -3,13 +3,12 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { css } from 'styled-components/primitives'; import { uniswapUpdateFavorites } from '../../redux/uniswap'; -import { colors, position } from '../../styles'; import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; -import { Icon } from '../icons'; import BottomRowText from './BottomRowText'; import CoinName from './CoinName'; import CoinRow from './CoinRow'; +import CoinRowFavoriteButton from './CoinRowFavoriteButton'; const containerStyles = css` padding-left: 15; @@ -85,13 +84,20 @@ class ExchangeCoinRow extends Component { }; render = () => { - const { item, showBalance, showFavoriteButton, ...props } = this.props; + const { + item, + showBalance, + showFavoriteButton, + uniqueId, + ...props + } = this.props; const { favorite } = this.state; return ( @@ -103,21 +109,10 @@ class ExchangeCoinRow extends Component { topRowRender={TopRow} > {showFavoriteButton && ( - - - + /> )}
@@ -125,7 +120,4 @@ class ExchangeCoinRow extends Component { }; } -export default connect( - null, - { uniswapUpdateFavorites } -)(ExchangeCoinRow); +export default connect(null, { uniswapUpdateFavorites })(ExchangeCoinRow); diff --git a/src/components/coin-row/index.js b/src/components/coin-row/index.js index 16e6b519574..4ff8f3a6049 100644 --- a/src/components/coin-row/index.js +++ b/src/components/coin-row/index.js @@ -1,10 +1,9 @@ export { default as BalanceCoinRow } from './BalanceCoinRow'; export { default as BottomRowText } from './BottomRowText'; export { default as CoinRow } from './CoinRow'; +export { default as CoinRowFavoriteButton } from './CoinRowFavoriteButton'; export { default as CollectiblesSendRow } from './CollectiblesSendRow'; -export { - default as ContractInteractionCoinRow, -} from './ContractInteractionCoinRow'; +export { default as ContractInteractionCoinRow } from './ContractInteractionCoinRow'; export { default as ExchangeCoinRow } from './ExchangeCoinRow'; export { default as RequestCoinRow } from './RequestCoinRow'; export { default as SendCoinRow } from './SendCoinRow'; From 9129c51cc3dfa2e15f23760939102f065c8da090 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 01:32:47 -0500 Subject: [PATCH 496/636] Appease the eslint/prettier overlords --- src/App.js | 9 ++-- src/components/Avatar.js | 5 +- src/components/SendComponentWithData.js | 34 ++++++------ .../HoldToAuthorizeButton.js | 5 +- .../buttons/hold-to-authorize/index.js | 4 +- src/components/coin-icon/CoinIcon.js | 5 +- .../coin-icon/RequestVendorLogoIcon.js | 10 +++- src/components/coin-row/CoinRow.js | 5 +- src/components/coin-row/RequestCoinRow.js | 37 +++++++------ src/components/contacts/index.js | 4 +- src/components/exchange/index.js | 4 +- src/components/expanded-state/index.js | 4 +- src/components/header/CameraHeaderButton.js | 5 +- src/components/qrcode-scanner/index.js | 4 +- .../token-family/TokenFamilyHeader.js | 5 +- src/components/transaction/index.js | 12 ++--- .../unique-token/UniqueTokenCard.js | 5 +- src/components/walletconnect-list/index.js | 8 +-- src/hoc/index.js | 36 ++++--------- src/hoc/withAccountAddress.js | 5 +- src/hoc/withAccountData.js | 5 +- src/hoc/withAccountSettings.js | 16 ++---- src/hoc/withActionSheetManager.js | 5 +- src/hoc/withDataInit.js | 53 +++++++++---------- src/hoc/withFabSelection.js | 13 ++--- src/hoc/withGas.js | 13 ++--- src/hoc/withImageDimensionsCache.js | 11 ++-- src/hoc/withIsWalletEmpty.js | 5 +- src/hoc/withIsWalletEthZero.js | 5 +- src/hoc/withIsWalletImporting.js | 5 +- src/hoc/withKeyboardHeight.js | 5 +- src/hoc/withMessageSigningScreen.js | 7 +-- src/hoc/withOpenBalances.js | 7 +-- src/hoc/withOpenFamilyTabs.js | 11 ++-- src/hoc/withOpenInvestmentCards.js | 11 ++-- src/hoc/withRequests.js | 10 +--- src/hoc/withTransactionConfirmationScreen.js | 15 +++--- src/hoc/withUniqueTokens.js | 5 +- src/hoc/withUniswapAllowances.js | 17 +++--- src/hoc/withWalletConnectConfirmationModal.js | 11 ++-- src/hoc/withWalletConnectConnections.js | 13 ++--- src/hoc/withWalletConnectOnSessionRequest.js | 5 +- src/screens/ExampleScreen.js | 5 +- src/utils/index.js | 8 +-- 44 files changed, 180 insertions(+), 287 deletions(-) diff --git a/src/App.js b/src/App.js index bf88f0117cb..51644cb50a0 100644 --- a/src/App.js +++ b/src/App.js @@ -199,12 +199,9 @@ const AppWithRedux = compose( withDeepLink, withWalletConnectConnections, withWalletConnectOnSessionRequest, - connect( - ({ walletconnect: { appInitTimestamp } }) => ({ appInitTimestamp }), - { - requestsForTopic, - } - ) + connect(({ walletconnect: { appInitTimestamp } }) => ({ appInitTimestamp }), { + requestsForTopic, + }) )(App); const AppWithCodePush = CodePush({ diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 94db9e5137b..0633d4dce6a 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -16,7 +16,10 @@ const Container = styled(Centered)` const Avatar = ({ size, source }) => ( {source ? ( diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index a4bffb61a77..f0d3aedfe56 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -262,13 +262,13 @@ export const withSendComponentWithData = (SendComponent, options) => { return ( { } return compose( - connect( - mapStateToProps, - { - sendClearFields, - sendMaxBalance, - sendModalInit, - sendToggleConfirmationView, - sendTransaction, - sendUpdateAssetAmount, - - sendUpdateNativeAmount, - sendUpdateRecipient, - sendUpdateSelected, - } - ), + connect(mapStateToProps, { + sendClearFields, + sendMaxBalance, + sendModalInit, + sendToggleConfirmationView, + sendTransaction, + sendUpdateAssetAmount, + sendUpdateNativeAmount, + sendUpdateRecipient, + sendUpdateSelected, + }), withGas, withAccountData, withUniqueTokens diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js index aec4146cc37..e937963a747 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js @@ -32,7 +32,10 @@ const ButtonShadows = { [0, 6, 10, colors.dark, 0.14], [0, 1, 18, colors.dark, 0.12], ], - disabled: [[0, 2, 6, colors.dark, 0.06], [0, 3, 9, colors.dark, 0.08]], + disabled: [ + [0, 2, 6, colors.dark, 0.06], + [0, 3, 9, colors.dark, 0.08], + ], }; const progressDurationMs = 500; // @christian approves diff --git a/src/components/buttons/hold-to-authorize/index.js b/src/components/buttons/hold-to-authorize/index.js index b9f164f13aa..ac8c7b825e6 100644 --- a/src/components/buttons/hold-to-authorize/index.js +++ b/src/components/buttons/hold-to-authorize/index.js @@ -1,5 +1,3 @@ export { default as HoldToAuthorizeButton } from './HoldToAuthorizeButton'; -export { - default as HoldToAuthorizeButtonIcon, -} from './HoldToAuthorizeButtonIcon'; +export { default as HoldToAuthorizeButtonIcon } from './HoldToAuthorizeButtonIcon'; export { default as UnlockingSpinner } from './UnlockingSpinner'; diff --git a/src/components/coin-icon/CoinIcon.js b/src/components/coin-icon/CoinIcon.js index 82af5e350da..9152d7bc087 100644 --- a/src/components/coin-icon/CoinIcon.js +++ b/src/components/coin-icon/CoinIcon.js @@ -29,7 +29,10 @@ const CoinIcon = enhance(({ bgColor, showShadow, size, symbol, ...props }) => {...props} {...borders.buildCircleAsObject(size)} backgroundColor={bgColor} - shadows={[[0, 4, 6, colors.dark, 0.04], [0, 1, 3, colors.dark, 0.08]]} + shadows={[ + [0, 4, 6, colors.dark, 0.04], + [0, 1, 3, colors.dark, 0.08], + ]} shouldRasterizeIOS > { }; export default compose( - connect( - null, - { removeExpiredRequest: removeRequest } - ), + connect(null, { removeExpiredRequest: removeRequest }), withNavigation, - withProps(({ item: { displayDetails: { timestampInMs } } }) => { - const createdAt = new Date(timestampInMs); - const expiresAt = addHours(createdAt, 1); - const percentElapsed = getPercentageOfTimeElapsed(createdAt, expiresAt); - - return { - createdAt, - expirationColor: - percentElapsed > 25 ? colors.primaryBlue : colors.orangeMedium, - expiresAt, - percentElapsed, - }; - }), + withProps( + ({ + item: { + displayDetails: { timestampInMs }, + }, + }) => { + const createdAt = new Date(timestampInMs); + const expiresAt = addHours(createdAt, 1); + const percentElapsed = getPercentageOfTimeElapsed(createdAt, expiresAt); + + return { + createdAt, + expirationColor: + percentElapsed > 25 ? colors.primaryBlue : colors.orangeMedium, + expiresAt, + percentElapsed, + }; + } + ), onlyUpdateForKeys(['expirationColor', 'expiresAt', 'percentElapsed']) )(RequestCoinRow); diff --git a/src/components/contacts/index.js b/src/components/contacts/index.js index 1751d092942..07180d5a091 100644 --- a/src/components/contacts/index.js +++ b/src/components/contacts/index.js @@ -1,6 +1,4 @@ export { default as ContactAvatar } from './ContactAvatar'; export { default as ContactRow } from './ContactRow'; -export { - default as showDeleteContactActionSheet, -} from './showDeleteContactActionSheet'; +export { default as showDeleteContactActionSheet } from './showDeleteContactActionSheet'; export { default as SwipeableContactRow } from './SwipeableContactRow'; diff --git a/src/components/exchange/index.js b/src/components/exchange/index.js index 58edba5318d..cfeb7fba930 100644 --- a/src/components/exchange/index.js +++ b/src/components/exchange/index.js @@ -1,8 +1,6 @@ export { default as ConfirmExchangeButton } from './ConfirmExchangeButton'; export { default as CurrencySelectionList } from './CurrencySelectionList'; -export { - default as CurrencySelectModalHeader, -} from './CurrencySelectModalHeader'; +export { default as CurrencySelectModalHeader } from './CurrencySelectModalHeader'; export { default as ExchangeAssetList } from './ExchangeAssetList'; export { default as ExchangeInput } from './ExchangeInput'; export { default as ExchangeInputField } from './ExchangeInputField'; diff --git a/src/components/expanded-state/index.js b/src/components/expanded-state/index.js index 48634a8c6cc..c8cff3f975e 100644 --- a/src/components/expanded-state/index.js +++ b/src/components/expanded-state/index.js @@ -2,7 +2,5 @@ export { default as FloatingPanel } from './FloatingPanel'; export { default as FloatingPanels } from './FloatingPanels'; export { default as InvestmentExpandedState } from './InvestmentExpandedState'; export { default as TokenExpandedState } from './TokenExpandedState'; -export { - default as UniqueTokenExpandedState, -} from './UniqueTokenExpandedState'; +export { default as UniqueTokenExpandedState } from './UniqueTokenExpandedState'; export { default as AddContactState } from './AddContactState'; diff --git a/src/components/header/CameraHeaderButton.js b/src/components/header/CameraHeaderButton.js index 8c49f6bc005..f7617d71265 100644 --- a/src/components/header/CameraHeaderButton.js +++ b/src/components/header/CameraHeaderButton.js @@ -17,7 +17,10 @@ const CameraHeaderButton = ({ onPress }) => ( {familyImage ? ( diff --git a/src/components/transaction/index.js b/src/components/transaction/index.js index c0d72ea5734..2d3279305fa 100644 --- a/src/components/transaction/index.js +++ b/src/components/transaction/index.js @@ -1,12 +1,6 @@ -export { - default as DefaultTransactionConfirmationSection, -} from './sections/DefaultTransactionConfirmationSection'; -export { - default as MessageSigningSection, -} from './sections/MessageSigningSection'; -export { - default as TransactionConfirmationSection, -} from './sections/TransactionConfirmationSection'; +export { default as DefaultTransactionConfirmationSection } from './sections/DefaultTransactionConfirmationSection'; +export { default as MessageSigningSection } from './sections/MessageSigningSection'; +export { default as TransactionConfirmationSection } from './sections/TransactionConfirmationSection'; export { default as TransactionMessage } from './TransactionMessage'; export { default as TransactionRow } from './TransactionRow'; export { default as TransactionSheet } from './TransactionSheet'; diff --git a/src/components/unique-token/UniqueTokenCard.js b/src/components/unique-token/UniqueTokenCard.js index d50bc824f99..f5c801bb9c0 100644 --- a/src/components/unique-token/UniqueTokenCard.js +++ b/src/components/unique-token/UniqueTokenCard.js @@ -85,7 +85,10 @@ UniqueTokenCard.propTypes = { }; UniqueTokenCard.defaultProps = { - shadows: [[0, 1, 3, colors.dark, 0.06], [0, 4, 6, colors.dark, 0.04]], + shadows: [ + [0, 1, 3, colors.dark, 0.06], + [0, 4, 6, colors.dark, 0.04], + ], }; export default compose( diff --git a/src/components/walletconnect-list/index.js b/src/components/walletconnect-list/index.js index cbef5d48ef9..bb140749d23 100644 --- a/src/components/walletconnect-list/index.js +++ b/src/components/walletconnect-list/index.js @@ -1,9 +1,5 @@ export { default as WalletConnectExplainer } from './WalletConnectExplainer'; -export { - default as WalletConnectExplainerItem, -} from './WalletConnectExplainerItem'; -export { - default as WalletConnectLearnMoreButton, -} from './WalletConnectLearnMoreButton'; +export { default as WalletConnectExplainerItem } from './WalletConnectExplainerItem'; +export { default as WalletConnectLearnMoreButton } from './WalletConnectLearnMoreButton'; export { default as WalletConnectList } from './WalletConnectList'; export { default as WalletConnectListItem } from './WalletConnectListItem'; diff --git a/src/hoc/index.js b/src/hoc/index.js index b5f73fb42cb..bef5076ea5e 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -4,9 +4,7 @@ export { default as withAccountSettings } from './withAccountSettings'; export { default as withAccountTransactions } from './withAccountTransactions'; export { default as withActionSheetManager } from './withActionSheetManager'; export { default as withAppState } from './withAppState'; -export { - default as withBlockedHorizontalSwipe, -} from './withBlockedHorizontalSwipe'; +export { default as withBlockedHorizontalSwipe } from './withBlockedHorizontalSwipe'; export { default as withBlurTransitionProps } from './withBlurTransitionProps'; export { default as withDataInit } from './withDataInit'; export { default as withDeepLink } from './withDeepLink'; @@ -14,33 +12,23 @@ export { default as withFabSelection } from './withFabSelection'; export { default as withFabSendAction } from './withFabSendAction'; export { default as withGas } from './withGas'; export { default as withHideSplashScreen } from './withHideSplashScreen'; -export { - default as withImageDimensionsCache, -} from './withImageDimensionsCache'; +export { default as withImageDimensionsCache } from './withImageDimensionsCache'; export { default as withIsWalletEmpty } from './withIsWalletEmpty'; export { default as withIsWalletEthZero } from './withIsWalletEthZero'; export { default as withIsWalletImporting } from './withIsWalletImporting'; export { default as withKeyboardHeight } from './withKeyboardHeight'; -export { - default as withMessageSigningScreen, -} from './withMessageSigningScreen'; +export { default as withMessageSigningScreen } from './withMessageSigningScreen'; export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; export { default as withOpenFamilyTabs } from './withOpenFamilyTabs'; export { default as withOpenInvestmentCards } from './withOpenInvestmentCards'; export { default as withOpenBalances } from './withOpenBalances'; export { default as withRequests } from './withRequests'; -export { - default as withRotationForDirection, -} from './withRotationForDirection'; -export { - default as withSafeAreaViewInsetValues, -} from './withSafeAreaViewInsetValues'; +export { default as withRotationForDirection } from './withRotationForDirection'; +export { default as withSafeAreaViewInsetValues } from './withSafeAreaViewInsetValues'; export { default as withSendFeedback } from './withSendFeedback'; export { default as withStatusBarStyle } from './withStatusBarStyle'; -export { - default as withTransactionConfirmationScreen, -} from './withTransactionConfirmationScreen'; +export { default as withTransactionConfirmationScreen } from './withTransactionConfirmationScreen'; export { default as withTransitionProps } from './withTransitionProps'; export { default as withUniqueTokens } from './withUniqueTokens'; export { default as withUniswapAllowances } from './withUniswapAllowances'; @@ -49,12 +37,6 @@ export { default as withUniswapLiquidityTokenInfo, readableUniswapSelector, } from './withUniswapLiquidityTokenInfo'; -export { - default as withWalletConnectConfirmationModal, -} from './withWalletConnectConfirmationModal'; -export { - default as withWalletConnectConnections, -} from './withWalletConnectConnections'; -export { - default as withWalletConnectOnSessionRequest, -} from './withWalletConnectOnSessionRequest'; +export { default as withWalletConnectConfirmationModal } from './withWalletConnectConfirmationModal'; +export { default as withWalletConnectConnections } from './withWalletConnectConnections'; +export { default as withWalletConnectOnSessionRequest } from './withWalletConnectOnSessionRequest'; diff --git a/src/hoc/withAccountAddress.js b/src/hoc/withAccountAddress.js index 570e8850079..1b018d3f3c2 100644 --- a/src/hoc/withAccountAddress.js +++ b/src/hoc/withAccountAddress.js @@ -17,9 +17,6 @@ const lowerAccountAddressSelector = createSelector( export default Component => compose( - connect( - mapStateToProps, - { settingsUpdateAccountAddress } - ), + connect(mapStateToProps, { settingsUpdateAccountAddress }), withProps(lowerAccountAddressSelector) )(Component); diff --git a/src/hoc/withAccountData.js b/src/hoc/withAccountData.js index 8ced359485d..1b1c0af2ab5 100644 --- a/src/hoc/withAccountData.js +++ b/src/hoc/withAccountData.js @@ -13,7 +13,4 @@ const mapStateToProps = ({ const sortAssets = state => sortAssetsByNativeAmountSelector(state); export default Component => - compose( - connect(mapStateToProps), - withProps(sortAssets) - )(Component); + compose(connect(mapStateToProps), withProps(sortAssets))(Component); diff --git a/src/hoc/withAccountSettings.js b/src/hoc/withAccountSettings.js index 76bf43ec609..d95c22d7f33 100644 --- a/src/hoc/withAccountSettings.js +++ b/src/hoc/withAccountSettings.js @@ -27,10 +27,7 @@ const withNativeCurrencySymbol = nativeCurrency => ({ nativeCurrencySymbol: supportedNativeCurrencies[nativeCurrency].symbol, }); -const withLanguageSelector = createSelector( - [languageSelector], - withLanguage -); +const withLanguageSelector = createSelector([languageSelector], withLanguage); const withNativeCurrencySelector = createSelector( [nativeCurrencySelector], @@ -39,13 +36,10 @@ const withNativeCurrencySelector = createSelector( export default Component => compose( - connect( - mapStateToProps, - { - settingsChangeLanguage, - settingsChangeNativeCurrency, - } - ), + connect(mapStateToProps, { + settingsChangeLanguage, + settingsChangeNativeCurrency, + }), withProps(withLanguageSelector), withProps(withNativeCurrencySelector) )(Component); diff --git a/src/hoc/withActionSheetManager.js b/src/hoc/withActionSheetManager.js index 67936d63dcc..1c67c847dc5 100644 --- a/src/hoc/withActionSheetManager.js +++ b/src/hoc/withActionSheetManager.js @@ -6,7 +6,4 @@ const mapStateToProps = ({ actionSheetManager: { isActionSheetOpen } }) => ({ }); export default Component => - connect( - mapStateToProps, - { setIsActionSheetOpen } - )(Component); + connect(mapStateToProps, { setIsActionSheetOpen })(Component); diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index b4cda99614c..fc09a63b796 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -41,34 +41,31 @@ import withHideSplashScreen from './withHideSplashScreen'; export default Component => compose( - connect( - null, - { - clearIsWalletEmpty, - clearOpenFamilyTab, - dataClearState, - dataLoadState, - explorerClearState, - explorerInit, - gasClearState, - gasPricesInit, - nonceClearState, - requestsClearState, - requestsLoadState, - setIsWalletEthZero, - settingsLoadState, - settingsUpdateAccountAddress, - uniqueTokensClearState, - uniqueTokensLoadState, - uniqueTokensRefreshState, - uniswapClearState, - uniswapLoadState, - uniswapUpdateState, - walletConnectClearState, - walletConnectLoadState, - web3ListenerInit, - } - ), + connect(null, { + clearIsWalletEmpty, + clearOpenFamilyTab, + dataClearState, + dataLoadState, + explorerClearState, + explorerInit, + gasClearState, + gasPricesInit, + nonceClearState, + requestsClearState, + requestsLoadState, + setIsWalletEthZero, + settingsLoadState, + settingsUpdateAccountAddress, + uniqueTokensClearState, + uniqueTokensLoadState, + uniqueTokensRefreshState, + uniswapClearState, + uniswapLoadState, + uniswapUpdateState, + walletConnectClearState, + walletConnectLoadState, + web3ListenerInit, + }), withHideSplashScreen, withHandlers({ checkEthBalance: ownProps => async walletAddress => { diff --git a/src/hoc/withFabSelection.js b/src/hoc/withFabSelection.js index f29b73a56ed..57deec92129 100644 --- a/src/hoc/withFabSelection.js +++ b/src/hoc/withFabSelection.js @@ -27,13 +27,10 @@ const withFabSelectionValidationSelector = createSelector( ); export default compose( - connect( - mapStateToProps, - { - setActionType, - setScrollingVelocity, - updateSelectedID, - } - ), + connect(mapStateToProps, { + setActionType, + setScrollingVelocity, + updateSelectedID, + }), withProps(withFabSelectionValidationSelector) ); diff --git a/src/hoc/withGas.js b/src/hoc/withGas.js index 3fb51f573fb..819c0c39c76 100644 --- a/src/hoc/withGas.js +++ b/src/hoc/withGas.js @@ -24,11 +24,8 @@ const mapStateToProps = ({ }); export default Component => - connect( - mapStateToProps, - { - gasUpdateDefaultGasLimit, - gasUpdateGasPriceOption, - gasUpdateTxFee, - } - )(Component); + connect(mapStateToProps, { + gasUpdateDefaultGasLimit, + gasUpdateGasPriceOption, + gasUpdateTxFee, + })(Component); diff --git a/src/hoc/withImageDimensionsCache.js b/src/hoc/withImageDimensionsCache.js index 71d28875d29..53346f2a9ea 100644 --- a/src/hoc/withImageDimensionsCache.js +++ b/src/hoc/withImageDimensionsCache.js @@ -9,10 +9,7 @@ const mapStateToProps = ({ imageDimensionsCache }) => ({ }); export default Component => - connect( - mapStateToProps, - { - pruneCache: pruneImageDimensionsCache, - updateCache: updateImageDimensionsCache, - } - )(Component); + connect(mapStateToProps, { + pruneCache: pruneImageDimensionsCache, + updateCache: updateImageDimensionsCache, + })(Component); diff --git a/src/hoc/withIsWalletEmpty.js b/src/hoc/withIsWalletEmpty.js index 19792316b27..d1679a587cd 100644 --- a/src/hoc/withIsWalletEmpty.js +++ b/src/hoc/withIsWalletEmpty.js @@ -4,7 +4,4 @@ import { setIsWalletEmpty } from '../redux/isWalletEmpty'; const mapStateToProps = ({ isWalletEmpty }) => isWalletEmpty; export default Component => - connect( - mapStateToProps, - { setIsWalletEmpty } - )(Component); + connect(mapStateToProps, { setIsWalletEmpty })(Component); diff --git a/src/hoc/withIsWalletEthZero.js b/src/hoc/withIsWalletEthZero.js index 4225c000111..0f48a4773d7 100644 --- a/src/hoc/withIsWalletEthZero.js +++ b/src/hoc/withIsWalletEthZero.js @@ -4,7 +4,4 @@ import { setIsWalletEthZero } from '../redux/isWalletEthZero'; const mapStateToProps = ({ isWalletEthZero }) => isWalletEthZero; export default Component => - connect( - mapStateToProps, - { setIsWalletEthZero } - )(Component); + connect(mapStateToProps, { setIsWalletEthZero })(Component); diff --git a/src/hoc/withIsWalletImporting.js b/src/hoc/withIsWalletImporting.js index cc0c97eefbd..a5370cb33ce 100644 --- a/src/hoc/withIsWalletImporting.js +++ b/src/hoc/withIsWalletImporting.js @@ -4,7 +4,4 @@ import { setIsWalletImporting } from '../redux/isWalletImporting'; const mapStateToProps = ({ isWalletImporting }) => isWalletImporting; export default Component => - connect( - mapStateToProps, - { setIsWalletImporting } - )(Component); + connect(mapStateToProps, { setIsWalletImporting })(Component); diff --git a/src/hoc/withKeyboardHeight.js b/src/hoc/withKeyboardHeight.js index 1fc944e9f14..c6751fc5bd2 100644 --- a/src/hoc/withKeyboardHeight.js +++ b/src/hoc/withKeyboardHeight.js @@ -3,7 +3,4 @@ import { setKeyboardHeight } from '../redux/keyboardHeight'; const mapStateToProps = ({ keyboardHeight }) => keyboardHeight; -export default connect( - mapStateToProps, - { setKeyboardHeight } -); +export default connect(mapStateToProps, { setKeyboardHeight }); diff --git a/src/hoc/withMessageSigningScreen.js b/src/hoc/withMessageSigningScreen.js index 1c188090333..1842ca51737 100644 --- a/src/hoc/withMessageSigningScreen.js +++ b/src/hoc/withMessageSigningScreen.js @@ -6,9 +6,4 @@ const mapStateToProps = ({ walletconnect: { walletConnectors } }) => ({ }); export default Component => - connect( - mapStateToProps, - { - removeRequest, - } - )(Component); + connect(mapStateToProps, { removeRequest })(Component); diff --git a/src/hoc/withOpenBalances.js b/src/hoc/withOpenBalances.js index 8d9c62fd15f..437a0d6ef8a 100644 --- a/src/hoc/withOpenBalances.js +++ b/src/hoc/withOpenBalances.js @@ -6,9 +6,4 @@ const mapStateToProps = ({ openBalances: { openSmallBalances } }) => ({ }); export default Component => - connect( - mapStateToProps, - { - setOpenSmallBalances, - } - )(Component); + connect(mapStateToProps, { setOpenSmallBalances })(Component); diff --git a/src/hoc/withOpenFamilyTabs.js b/src/hoc/withOpenFamilyTabs.js index 583a8428115..4c9551b8593 100644 --- a/src/hoc/withOpenFamilyTabs.js +++ b/src/hoc/withOpenFamilyTabs.js @@ -6,10 +6,7 @@ const mapStateToProps = ({ openFamilyTabs: { openFamilyTabs } }) => ({ }); export default Component => - connect( - mapStateToProps, - { - pushOpenFamilyTab, - setOpenFamilyTabs, - } - )(Component); + connect(mapStateToProps, { + pushOpenFamilyTab, + setOpenFamilyTabs, + })(Component); diff --git a/src/hoc/withOpenInvestmentCards.js b/src/hoc/withOpenInvestmentCards.js index 408582ebc0f..f6e87b4e48a 100644 --- a/src/hoc/withOpenInvestmentCards.js +++ b/src/hoc/withOpenInvestmentCards.js @@ -9,10 +9,7 @@ const mapStateToProps = ({ openInvestmentCards: { openInvestmentCards } }) => ({ }); export default Component => - connect( - mapStateToProps, - { - pushOpenInvestmentCard, - setOpenInvestmentCards, - } - )(Component); + connect(mapStateToProps, { + pushOpenInvestmentCard, + setOpenInvestmentCards, + })(Component); diff --git a/src/hoc/withRequests.js b/src/hoc/withRequests.js index 129c20c9bf8..e5627a228b9 100644 --- a/src/hoc/withRequests.js +++ b/src/hoc/withRequests.js @@ -20,13 +20,7 @@ const withRequests = requests => { }; }; -const withRequestsSelector = createSelector( - [requestsSelector], - withRequests -); +const withRequestsSelector = createSelector([requestsSelector], withRequests); export default Component => - compose( - connect(mapStateToProps), - withProps(withRequestsSelector) - )(Component); + compose(connect(mapStateToProps), withProps(withRequestsSelector))(Component); diff --git a/src/hoc/withTransactionConfirmationScreen.js b/src/hoc/withTransactionConfirmationScreen.js index 34c82553f65..ced2b7ce1d2 100644 --- a/src/hoc/withTransactionConfirmationScreen.js +++ b/src/hoc/withTransactionConfirmationScreen.js @@ -9,12 +9,9 @@ const mapStateToProps = ({ nonce: { transactionCountNonce } }) => ({ }); export default Component => - connect( - mapStateToProps, - { - dataAddNewTransaction, - removeRequest, - updateTransactionCountNonce, - walletConnectSendStatus, - } - )(Component); + connect(mapStateToProps, { + dataAddNewTransaction, + removeRequest, + updateTransactionCountNonce, + walletConnectSendStatus, + })(Component); diff --git a/src/hoc/withUniqueTokens.js b/src/hoc/withUniqueTokens.js index 667f73345c2..21d9a64b2f3 100644 --- a/src/hoc/withUniqueTokens.js +++ b/src/hoc/withUniqueTokens.js @@ -34,7 +34,4 @@ const sendableUniqueTokens = state => { }; export default Component => - compose( - connect(mapStateToProps), - withProps(sendableUniqueTokens) - )(Component); + compose(connect(mapStateToProps), withProps(sendableUniqueTokens))(Component); diff --git a/src/hoc/withUniswapAllowances.js b/src/hoc/withUniswapAllowances.js index 45558ddbd1c..7a6d85f61d1 100644 --- a/src/hoc/withUniswapAllowances.js +++ b/src/hoc/withUniswapAllowances.js @@ -24,13 +24,10 @@ const mapStateToProps = ({ }); export default Component => - connect( - mapStateToProps, - { - uniswapAddPendingApproval, - uniswapClearCurrenciesAndReserves, - uniswapUpdateAllowances, - uniswapUpdateInputCurrency, - uniswapUpdateOutputCurrency, - } - )(Component); + connect(mapStateToProps, { + uniswapAddPendingApproval, + uniswapClearCurrenciesAndReserves, + uniswapUpdateAllowances, + uniswapUpdateInputCurrency, + uniswapUpdateOutputCurrency, + })(Component); diff --git a/src/hoc/withWalletConnectConfirmationModal.js b/src/hoc/withWalletConnectConfirmationModal.js index bee7ac08123..45318e355ed 100644 --- a/src/hoc/withWalletConnectConfirmationModal.js +++ b/src/hoc/withWalletConnectConfirmationModal.js @@ -5,10 +5,7 @@ import { } from '../redux/walletconnect'; export default Component => - connect( - null, - { - walletConnectApproveSession, - walletConnectRejectSession, - } - )(Component); + connect(null, { + walletConnectApproveSession, + walletConnectRejectSession, + })(Component); diff --git a/src/hoc/withWalletConnectConnections.js b/src/hoc/withWalletConnectConnections.js index 8173a08fa75..c454eeeca51 100644 --- a/src/hoc/withWalletConnectConnections.js +++ b/src/hoc/withWalletConnectConnections.js @@ -47,13 +47,10 @@ const walletConnectSelector = createSelector( export default Component => compose( - connect( - mapStateToProps, - { - walletConnectClearTimestamp, - walletConnectDisconnectAllByDappName, - walletConnectUpdateTimestamp, - } - ), + connect(mapStateToProps, { + walletConnectClearTimestamp, + walletConnectDisconnectAllByDappName, + walletConnectUpdateTimestamp, + }), withProps(walletConnectSelector) )(Component); diff --git a/src/hoc/withWalletConnectOnSessionRequest.js b/src/hoc/withWalletConnectOnSessionRequest.js index 5730c99b34d..9b686564cb6 100644 --- a/src/hoc/withWalletConnectOnSessionRequest.js +++ b/src/hoc/withWalletConnectOnSessionRequest.js @@ -2,7 +2,4 @@ import { connect } from 'react-redux'; import { walletConnectOnSessionRequest } from '../redux/walletconnect'; export default Component => - connect( - null, - { walletConnectOnSessionRequest } - )(Component); + connect(null, { walletConnectOnSessionRequest })(Component); diff --git a/src/screens/ExampleScreen.js b/src/screens/ExampleScreen.js index 4f7777d8e0c..32e3ce9768d 100644 --- a/src/screens/ExampleScreen.js +++ b/src/screens/ExampleScreen.js @@ -38,7 +38,4 @@ class ExampleScreen extends PureComponent { ); } -export default compose( - withAccountData, - withDataInit -)(ExampleScreen); +export default compose(withAccountData, withDataInit)(ExampleScreen); diff --git a/src/utils/index.js b/src/utils/index.js index e8f0af67d1f..eae6f18f6bd 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -8,13 +8,9 @@ export { default as ethereumUtils } from './ethereumUtils'; export { default as gasUtils } from './gas'; export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; -export { - default as isNewValueForObjectPaths, -} from './isNewValueForObjectPaths'; +export { default as isNewValueForObjectPaths } from './isNewValueForObjectPaths'; export { default as isNewValueForPath } from './isNewValueForPath'; -export { - default as parseObjectToUrlQueryString, -} from './parseObjectToUrlQueryString'; +export { default as parseObjectToUrlQueryString } from './parseObjectToUrlQueryString'; export { default as parseQueryParams } from './parseQueryParams'; export { default as promiseUtils } from './promise'; export { default as reduceArrayToObject } from './reduceArrayToObject'; From d2b69c6a23cb57e8ccc47c9eb71a2fadabdd75d1 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 01:34:30 -0500 Subject: [PATCH 497/636] upgrade deps --- ios/Podfile.lock | 82 +++++++------- package.json | 54 ++++----- yarn.lock | 287 +++++++++++++++++++++++++---------------------- 3 files changed, 221 insertions(+), 202 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f8dbfb4728a..41f51a737b4 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -272,15 +272,15 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (2.11.2): + - react-native-camera (3.9.0): - React - - react-native-camera/RCT (= 2.11.2) - - react-native-camera/RN (= 2.11.2) - - react-native-camera/RCT (2.11.2): + - react-native-camera/RCT (= 3.9.0) + - react-native-camera/RN (= 3.9.0) + - react-native-camera/RCT (3.9.0): - React - - react-native-camera/RN (2.11.2): + - react-native-camera/RN (3.9.0): - React - - react-native-mail (3.0.7): + - react-native-mail (4.1.0): - React - react-native-netinfo (4.6.0): - React @@ -318,7 +318,9 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -351,8 +353,6 @@ PODS: - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/callinvoker (= 1000.0.0) - - ReactNativePermissions (1.2.1): - - React - RNAnalytics (1.1.0): - Analytics - React @@ -377,12 +377,14 @@ PODS: - React - RNGestureHandler (1.4.1): - React - - RNKeychain (3.1.3): + - RNKeychain (4.0.1): - React - RNLanguages (3.0.2): - React - RNOS (1.1.0): - React + - RNPermissions (2.0.3): + - React - RNReactNativeHapticFeedback (1.8.2): - React - RNReanimated (1.3.0): @@ -391,7 +393,7 @@ PODS: - React - RNStoreReview (0.1.5): - React - - RNSVG (9.10.1): + - RNSVG (9.13.3): - React - SDWebImage (5.2.5): - SDWebImage/Core (= 5.2.5) @@ -455,7 +457,6 @@ DEPENDENCIES: - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - - ReactNativePermissions (from `../node_modules/react-native-permissions`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -466,6 +467,7 @@ DEPENDENCIES: - RNKeychain (from `../node_modules/react-native-keychain`) - RNLanguages (from `../node_modules/react-native-languages`) - RNOS (from `../node_modules/react-native-os`) + - RNPermissions (from `../node_modules/react-native-permissions`) - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) @@ -572,8 +574,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Vibration" ReactCommon: :path: "../node_modules/react-native/ReactCommon" - ReactNativePermissions: - :path: "../node_modules/react-native-permissions" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -594,6 +594,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-languages" RNOS: :path: "../node_modules/react-native-os" + RNPermissions: + :path: "../node_modules/react-native-permissions" RNReactNativeHapticFeedback: :path: "../node_modules/react-native-haptic-feedback" RNReanimated: @@ -624,8 +626,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: cba38f85f99345e0a5363c733fb899ac0374456e - FBReactNativeSpec: 454704730bc852f3df18aa3d737fae49c1b8c807 + FBLazyVector: 5941a412090840d8454b63f5deddc334d3e66ec1 + FBReactNativeSpec: 4e760ee4050dfda7e234635346f0ee7ca47ada49 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -641,35 +643,34 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 1e96ef069b5ca9b5b50baf6d0af9048232b458ff - RCTTypeSafety: 4b2ca882920f75cd61b89db27bc010cdf6cce574 - React: 3053a3e7446830d7e34befa2aea3e316447dcbff - React-Core: b04f999a0c226801e3260e4fe5aca555cc4c3a2c - React-CoreModules: 808cbc2978af28e20c046b28aec7029f15d03300 - React-cxxreact: 24d49b79cbb4d915c8e163fc4c0bf15553166347 - React-jsi: 989c7df372bb2faad532bfeb76326ab301514dde - React-jsiexecutor: 163af49f01253cf3a15bec1b84172a60a8790dc2 - React-jsinspector: 0c2e65fb3ee2084961ebbb44f76dcd0bae778a19 + RCTRequired: 6cb19d0cdc3cdbd049f0f1d54d579ce45a2d18b3 + RCTTypeSafety: 72c13a219b3e3f767f17a0207ead9b91e34dda98 + React: e84718e1b6e37662a56676196e70cb548d5dc82d + React-Core: 410c225ed959c8b92bb0b6cf8e15269229e1bc4b + React-CoreModules: 178af3b46382139ec79adaab4d7df174aca8d708 + React-cxxreact: 9b691755a0958781dfef5c3e006c948eaa89896a + React-jsi: de7c2b3f5677ca946990fefae03b185b1b1a3cab + React-jsiexecutor: 6ba5c0957102f46bb59ae1da5aa0a39dc0471ea2 + React-jsinspector: 5f6f950665fe118bf09094c768f5e1585d6c9faf react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: b5e6e34586ca6f588b0c736dcabfe0aad5ce2f3e - react-native-mail: 021d8ee60e374609f5689ef354dc8e36839a9ba6 + react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 + react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 react-native-netinfo: fa32a5bb986924e9be82a261c262039042dde81e react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 2519e835f932cebdbf09d083f26da20ccee04c4d - React-RCTAnimation: 5532bd047009610ad5241901a12fdb04de63b928 - React-RCTBlob: 1442ce9a65a6183e61673a4f80ae82d23f097ba6 - React-RCTImage: bea88e624edf49dd6eb990aafd09659986faf859 - React-RCTLinking: 626f7b18df5dd23c8f97992cb419e3ed0123a8a6 - React-RCTNetwork: 118bbd48bdcdbfb7495d8ef6853c783ca9d5e2fa - React-RCTSettings: abad768c41c0d199dd2bbc0c82ec7b6fedfbe56d - React-RCTText: 169de4510d0741f73d73ee6d5c25194ffb4b08a7 - React-RCTVibration: a88813cd6826cd5722b5f769611e49490abc10e3 - ReactCommon: b87d3090701ca4b90139fd28ccbbc978157914a1 - ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e + React-RCTActionSheet: c8458a9d0d7068c89b080dceb703c62409362b9c + React-RCTAnimation: 683d473651a4fe92dcfcfbe46cd97e737a2d9524 + React-RCTBlob: aad21f3f52f00d666fd4bba5e61b499ea973c768 + React-RCTImage: 4860c2ee02200535ff6c4b98d2335d5caa0a5361 + React-RCTLinking: da8550a85c729b7254a424d9bd2713c41af2a7a4 + React-RCTNetwork: c1369c792662ef2bf6a9654dda5d6fed553eacbd + React-RCTSettings: 360a138e20baa5123c3707cc06252db6c01066ce + React-RCTText: 6667febb3da7f709cd0661d3c3c5e3f50207e6b0 + React-RCTVibration: adfe01cff28981427aef496b578d1d63372b9efd + ReactCommon: 3e28aaf6de1505111189685989f4a5ebe6cc409c RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 @@ -677,14 +678,15 @@ SPEC CHECKSUMS: RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa - RNKeychain: c658833a9cb2cbcba6423bdd6e16cce59e27da0e + RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a + RNPermissions: 9e437a90de84a5402ff689d4da233730b81556c2 RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - RNSVG: b5c2b84eba69007aa744d12f6f564c1d98d352d8 + RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c SDWebImage: 4eabf2fa6695c95c47724214417a9c036c965e4a SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec @@ -692,7 +694,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 57c54b4bbd7f55a069f4a5eaaa55909f4e122af9 + Yoga: 03905d5f074f7f0bdb2d13b164010826bbeeeae6 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/package.json b/package.json index a8817940267..1e818fd6fa9 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.6.2", "@react-native-community/blur": "^3.3.1", - "@react-native-community/masked-view": "^0.1.1", - "@react-native-community/netinfo": "^4.1.4", + "@react-native-community/masked-view": "^0.1.5", + "@react-native-community/netinfo": "^4.6.0", "@segment/analytics-react-native": "^1.0.1", "@staltz/react-native-tcp": "^3.3.1", "@tradle/react-native-http": "^2.0.1", @@ -39,7 +39,7 @@ "bignumber.js": "^9.0.0", "browserify-zlib": "^0.1.4", "buffer": "^4.9.1", - "chroma-js": "^1.3.7", + "chroma-js": "^2.1.0", "code-push": "^2.0.6", "console-browserify": "^1.1.0", "constants-browserify": "^1.0.0", @@ -48,7 +48,7 @@ "dns.js": "^1.0.1", "domain-browser": "^1.2.0", "eth-contract-metadata": "^1.9.3", - "ethers": "^4.0.37", + "ethers": "^4.0.39", "events": "^1.1.1", "global": "^4.3.2", "grapheme-splitter": "^1.0.4", @@ -56,11 +56,11 @@ "husky": "^2.4.0", "i18n-js": "^3.0.11", "i18next": "^17.0.3", - "immer": "^3.1.3", + "immer": "^5.0.0", "inherits": "^2.0.3", "lodash": "^4.17.15", "match-sorter": "^4.0.2", - "nanoid": "^2.0.3", + "nanoid": "^2.1.6", "parse-ms": "^2.1.0", "patch-package": "^6.2.0", "path-browserify": "0.0.0", @@ -70,15 +70,15 @@ "prop-types": "^15.7.2", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "react": "16.9.0", + "react": "16.11.0", "react-coin-icon": "^0.1.9", "react-fast-compare": "^2.0.4", "react-native": "facebook/react-native", "react-native-actionsheet": "^2.4.2", - "react-native-camera": "^2.11.0", - "react-native-circular-progress": "^1.1.0", + "react-native-camera": "^3.9.0", + "react-native-circular-progress": "^1.3.4", "react-native-code-push": "^5.6.0", - "react-native-crypto": "^2.1.2", + "react-native-crypto": "^2.2.0", "react-native-device-info": "^2.1.3", "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", @@ -86,16 +86,16 @@ "react-native-firebase": "^5.5.6", "react-native-gesture-handler": "1.4.1", "react-native-haptic-feedback": "^1.8.2", - "react-native-indicators": "^0.13.0", + "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", - "react-native-keychain": "^3.1.3", + "react-native-keychain": "4.0.1", "react-native-languages": "^3.0.0", "react-native-level-fs": "^3.0.1", "react-native-linear-gradient": "^2.5.6", - "react-native-mail": "^3.0.6", + "react-native-mail": "^4.1.0", "react-native-os": "icxcat/react-native-os#master", - "react-native-permissions": "^1.2.1", + "react-native-permissions": "^2.0.3", "react-native-qrcode-scanner": "mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e", "react-native-qrcode-svg": "git+https://github.com/mikedemarais/react-native-qrcode-svg.git", "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", @@ -108,16 +108,16 @@ "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "9.10.1", - "react-native-tcp": "^3.3.0", + "react-native-svg": "9.13.3", + "react-native-tcp": "^3.3.2", "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", "react-native-tooltip": "marcosrdz/react-native-tooltip#master", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", - "react-navigation": "4.0.7", - "react-navigation-stack": "2.0.0-alpha.35", - "react-navigation-tabs": "2.5.5", + "react-navigation": "4.0.10", + "react-navigation-stack": "2.0.0-alpha.36", + "react-navigation-tabs": "2.5.6", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", @@ -130,7 +130,7 @@ "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0", "reselect": "^4.0.0", - "rn-nodeify": "10.1.0", + "rn-nodeify": "10.2.0", "socket.io-client": "^2.2.0", "stream-browserify": "^1.0.0", "string_decoder": "^0.10.31", @@ -144,11 +144,11 @@ "vm-browserify": "0.0.4" }, "devDependencies": { - "@babel/core": "^7.6.2", - "@babel/runtime": "^7.6.2", + "@babel/core": "^7.7.2", + "@babel/runtime": "^7.7.2", "@react-native-community/cli": "2.9.0", "babel-core": "7.0.0-bridge.0", - "babel-eslint": "^10.0.2", + "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", "babel-plugin-date-fns": "^0.2.1", "babel-plugin-lodash": "^3.3.4", @@ -156,11 +156,11 @@ "babel-plugin-styled-components": "^1.10.6", "babel-plugin-transform-remove-console": "^6.9.4", "detox": "^12.8.0", - "eslint": "^6.5.1", + "eslint": "^6.6.0", "eslint-config-satya164": "^2.4.1", "jest": "^24.9.0", - "metro-react-native-babel-preset": "^0.56.0", - "mocha": "^6.1.4", + "metro-react-native-babel-preset": "^0.57.0", + "mocha": "^6.2.2", "react-native-bundle-visualizer": "^2.0.1", "react-native-clean-project": "^3.1.0", "react-test-renderer": "16.9.0", @@ -250,4 +250,4 @@ "vm": "vm-browserify", "tls": false } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 5bbfafae487..e7aa10d7d59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.6.2": +"@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== @@ -241,9 +241,9 @@ js-tokens "^4.0.0" "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.2.tgz#ea8334dc77416bfd9473eb470fd00d8245b3943b" - integrity sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w== + version "7.7.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.3.tgz#5fad457c2529de476a248f75b0f090b3060af043" + integrity sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A== "@babel/plugin-external-helpers@^7.0.0": version "7.2.0" @@ -614,7 +614,7 @@ pirates "^4.0.0" source-map-support "^0.5.16" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== @@ -1160,12 +1160,12 @@ wcwidth "^1.0.1" ws "^1.1.0" -"@react-native-community/masked-view@^0.1.1": +"@react-native-community/masked-view@^0.1.5": version "0.1.5" resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.5.tgz#25421be6cd943a4b1660b62cfbcd45be8891462c" integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== -"@react-native-community/netinfo@^4.1.4": +"@react-native-community/netinfo@^4.6.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.0.tgz#fc0b79a226da78371158f885a2f798ff07c926be" integrity sha512-wz39BUpExDU1kTpLlBkDwwb0Efg+uuwixToosTSarZgpzG/CmcRvWdD786TMiE5tLDd+Mpi2xh3w4FrVM8zjoA== @@ -1426,14 +1426,14 @@ "@types/node" "*" "@types/node@*": - version "12.12.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.6.tgz#a47240c10d86a9a57bb0c633f0b2e0aea9ce9253" - integrity sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA== + version "12.12.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11" + integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w== "@types/node@^10.3.2": - version "10.17.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.4.tgz#8993a4fe3c4022fda66bf4ea660d615fc5659c6f" - integrity sha512-F2pgg+LcIr/elguz+x+fdBX5KeZXGUOp7TV8M0TVIrDezYLFRNt8oMTyps0VQ1kj5WGGoR18RdxnRDHXrIFHMQ== + version "10.17.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.5.tgz#c1920150f7b90708a7d0f3add12a06bc9123c055" + integrity sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2051,7 +2051,7 @@ babel-core@7.0.0-bridge.0: resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== -babel-eslint@^10.0.1, babel-eslint@^10.0.2: +babel-eslint@^10.0.1, babel-eslint@^10.0.3: version "10.0.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== @@ -2288,9 +2288,9 @@ better-assert@~1.0.0: callsite "1.0.0" big-integer@^1.6.44, big-integer@^1.6.7: - version "1.6.47" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.47.tgz#e1e9320e26c4cc81f64fbf4b3bb20e025bf18e2d" - integrity sha512-9t9f7X3as2XGX8b52GqG6ox0GvIdM86LyIXASJnDCFhYNgt+A+MByQZ3W2PyMRZjEvG5f8TEbSPfEotVuMJnQg== + version "1.6.48" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" + integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== bignumber.js@^8.1.1: version "8.1.1" @@ -2537,9 +2537,9 @@ buffer-xor@^1.0.3: integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -2750,10 +2750,12 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== -chroma-js@^1.3.7: - version "1.4.1" - resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-1.4.1.tgz#eb2d9c4d1ff24616be84b35119f4d26f8205f134" - integrity sha512-jTwQiT859RTFN/vIf7s+Vl/Z2LcMrvMv3WUFmd/4u76AdlFC0NTNgqEEFPcRiHmAswPsMiQEDZLM8vX8qXpZNQ== +chroma-js@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.0.tgz#c0be48a21fe797ef8965608c1c4f911ef2da49d5" + integrity sha512-uiRdh4ZZy+UTPSrAdp8hqEdVb1EllLtTHOt5TMaOjJUvi+O54/83Fc5K2ld1P+TJX+dw5B+8/sCgzI6eaur/lg== + dependencies: + cross-env "^6.0.3" ci-info@^1.5.0: version "1.6.0" @@ -3170,6 +3172,13 @@ create-react-class@^15.6.3: loose-envify "^1.3.1" object-assign "^4.1.1" +cross-env@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941" + integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag== + dependencies: + cross-spawn "^7.0.0" + cross-spawn@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -3222,13 +3231,13 @@ css-select-base-adapter@^0.1.1: resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== -css-select@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" - integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== +css-select@^2.0.0, css-select@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== dependencies: boolbase "^1.0.0" - css-what "^2.1.2" + css-what "^3.2.1" domutils "^1.7.0" nth-check "^1.0.2" @@ -3241,7 +3250,7 @@ css-to-react-native@^2.2.2: css-color-keywords "^1.0.0" postcss-value-parser "^3.3.0" -css-tree@1.0.0-alpha.37: +css-tree@1.0.0-alpha.37, css-tree@^1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== @@ -3249,10 +3258,10 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-what@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== +css-what@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" + integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== csso@^4.0.2: version "4.0.2" @@ -3592,9 +3601,9 @@ doctrine@^3.0.0: esutils "^2.0.2" dom-serializer@0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb" - integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q== + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== dependencies: domelementtype "^2.0.1" entities "^2.0.0" @@ -3684,9 +3693,9 @@ ejs@^2.7.1: integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.295: - version "1.3.305" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.305.tgz#64f38c2986277b15c7b2c81954171ed22bee249b" - integrity sha512-jBEhRZ3eeJWf3eAnGYB1vDy09uBQpZWshC5fxiiIRofA9L3vkpa3SxsXleVS2MvuYir15oTVxzWPsOwj7KBzUw== + version "1.3.306" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz#e8265301d053d5f74e36cb876486830261fbe946" + integrity sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A== elliptic@6.3.3: version "6.3.3" @@ -3822,9 +3831,9 @@ es-abstract@^1.12.0, es-abstract@^1.15.0, es-abstract@^1.5.1, es-abstract@^1.7.0 string.prototype.trimright "^2.1.0" es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" @@ -4074,7 +4083,7 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.5.1: +eslint@^6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== @@ -4170,7 +4179,7 @@ eth-contract-metadata@^1.9.3: resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== -ethers@^4.0.28, ethers@^4.0.37: +ethers@^4.0.28, ethers@^4.0.39: version "4.0.39" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.39.tgz#5ce9dfffedb03936415743f63b37d96280886a47" integrity sha512-QVtC8TTUgTrnlQjQvdFJ7fkSWKwp8HVTbKRmrdbVryrPzJHMTf3WSeRNvLF2enGyAFtyHJyFNnjN0fSshcEr9w== @@ -5319,10 +5328,10 @@ image-size@^0.6.0: resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2" integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== -immer@^3.1.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" - integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== +immer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.0.tgz#07f462b7d95f7e86c214a861ecacd766d42b8c0a" + integrity sha512-G7gRqKbi9NE025XVyqyTV98dxUOtdKvu/P1QRaVZfA55aEcXgjbxPdm+TlWdcSMNPKijlaHNz61DGPyelouRlA== import-fresh@^2.0.0: version "2.0.0" @@ -6857,9 +6866,9 @@ md5.js@^1.3.4: safe-buffer "^5.1.2" mdast-util-compact@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz#98a25cc8a7865761a41477b3a87d1dcef0b1e79d" - integrity sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w== + version "1.0.4" + resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz#d531bb7667b5123abf20859be086c4d06c894593" + integrity sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg== dependencies: unist-util-visit "^1.1.0" @@ -7168,7 +7177,7 @@ metro-react-native-babel-preset@0.54.1: metro-babel7-plugin-react-transform "0.54.1" react-transform-hmr "^1.0.4" -metro-react-native-babel-preset@0.56.3, metro-react-native-babel-preset@^0.56.0: +metro-react-native-babel-preset@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz#5a1097c2f94e8ee0797a8ba2ab8f86d096f4c093" integrity sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow== @@ -7209,7 +7218,7 @@ metro-react-native-babel-preset@0.56.3, metro-react-native-babel-preset@^0.56.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-preset@0.57.0: +metro-react-native-babel-preset@0.57.0, metro-react-native-babel-preset@^0.57.0: version "0.57.0" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.57.0.tgz#bbbce26a20d9ca3fdc08f0df564bc982b82651b7" integrity sha512-pvLh1QOwdxsjgYE2a+4aTKs3LSF3+t4jscxHtkND6wsJnKVVspLt8FkDaORa6zr3Fq12tVpEt5NJMdgtWqBpaA== @@ -7645,7 +7654,7 @@ mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" -mocha@^6.1.4: +mocha@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.2.tgz#5d8987e28940caf8957a7d7664b910dc5b2fea20" integrity sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A== @@ -7734,7 +7743,7 @@ nan@^2.12.1, nan@^2.14.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== -nanoid@^2.0.3: +nanoid@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== @@ -8031,9 +8040,9 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-inspect@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" - integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== object-is@^1.0.1: version "1.0.1" @@ -8567,9 +8576,9 @@ path-parse@^1.0.5: integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" - integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== dependencies: isarray "0.0.1" @@ -8853,9 +8862,9 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier@^1.17.1: - version "1.18.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" - integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== pretty-format@^24.7.0, pretty-format@^24.9.0: version "24.9.0" @@ -8900,9 +8909,9 @@ promise@^7.1.1: asap "~2.0.3" prompts@^2.0.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35" - integrity sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw== + version "2.3.0" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.0.tgz#a444e968fa4cc7e86689a74050685ac8006c4cc4" + integrity sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg== dependencies: kleur "^3.0.3" sisteransi "^1.0.3" @@ -9025,9 +9034,9 @@ qrcode@^1.2.0: yargs "^13.2.4" qs@^6.7.0: - version "6.9.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409" - integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA== + version "6.9.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" + integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== qs@~6.5.2: version "6.5.2" @@ -9158,14 +9167,14 @@ react-native-bundle-visualizer@^2.0.1: rimraf "^3.0.0" source-map-explorer "^2.1.0" -react-native-camera@^2.11.0: - version "2.11.2" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-2.11.2.tgz#4936bb0a484e8ba7d0b3ecf28fa7c161833b1ac0" - integrity sha512-9Fw5zpOJqaZOa/n1SUG141sbD5b77/EWSv0VTBvP66SneN4tuuS4tYtM0YndqF+BRlyAggjYGJPDs3L7BMYsmQ== +react-native-camera@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.9.0.tgz#334d9d7be5476d673af4df954929958ecc36ed55" + integrity sha512-qUhog1yd7FQ9xRTxN1SP+T5f4uLuVY5eXx6mMlBCNsqvYSoKCWFHH1Kpil9fx7d2iOl/o09o/7kHNcSl9RkrkQ== dependencies: prop-types "^15.6.2" -react-native-circular-progress@^1.1.0: +react-native-circular-progress@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/react-native-circular-progress/-/react-native-circular-progress-1.3.4.tgz#91b8aed6ff5ecb8841d2a5a9089af41a5d962087" integrity sha512-gch73x1qcx7vQewXdY7GdDgvgFSXZHVJ7hp4lXpOWT4Vo7ZnSAeeXYW11sMg2VkFpfA2gu6F+JRQLefDpMzcWQ== @@ -9190,7 +9199,7 @@ react-native-code-push@^5.6.0: semver "^5.6.0" xcode "1.0.0" -react-native-crypto@^2.1.2: +react-native-crypto@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/react-native-crypto/-/react-native-crypto-2.2.0.tgz#c999ed7c96064f830e1f958687f53d0c44025770" integrity sha512-eZu9Y8pa8BN9FU2pIex7MLRAi+Cd1Y6bsxfiufKh7sfraAACJvjQTeW7/zcQAT93WMfM+D0OVk+bubvkrbrUkw== @@ -9252,10 +9261,10 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -react-native-indicators@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.13.0.tgz#001824bba194b1ca6e654d903beaf0168d4e6ac8" - integrity sha1-ABgku6GUscpuZU2QO+rwFo1Oasg= +react-native-indicators@0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" + integrity sha512-s23em477GHGxWeGczWrixScAZD6tQU4mx1fttlrwhEGKOxhBgp55Kh3RoD9Wj4yna4e5W35xQNoPqoJAT6QW5A== dependencies: prop-types "^15.5.10" @@ -9269,10 +9278,10 @@ react-native-iphone-x-helper@^1.2.1: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== -react-native-keychain@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-3.1.3.tgz#fce176e7b95243cecda1896a7e6bdfe0335d778a" - integrity sha512-eWUbjYJge4icX8FhWJk/OPlyGxPnW9bZDysBX3WwOG37iurdH692HKnM2Ih+S+0te65RytImvUrcVnHVBbumYg== +react-native-keychain@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.1.tgz#c332f5d9aaf597255ae6ea4ca7d5c84a24684a1d" + integrity sha512-AqQp4Hib9y5DP5es5umEAhxKG7L0bA8cHNFhvlqs6oUcbUoKtXmhLDo3wzvnCF+bm8DXpGhvkU6P0LkfO0AgPQ== react-native-languages@^3.0.0: version "3.0.2" @@ -9292,20 +9301,25 @@ react-native-linear-gradient@^2.5.6: resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz#96215cbc5ec7a01247a20890888aa75b834d44a0" integrity sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg== -react-native-mail@^3.0.6: - version "3.0.7" - resolved "https://registry.yarnpkg.com/react-native-mail/-/react-native-mail-3.0.7.tgz#07e6aca43f6f1f85f3e58e96e7fcd16b31a927b8" - integrity sha512-FHe4kKJKAGuCPPWcDwaRSjdUhEE4IWIsVtTZ05dgD/MgOm00isYmM20zuJHla7oiHVQ2HmzGji76g6IuhIrCjw== +react-native-mail@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/react-native-mail/-/react-native-mail-4.1.0.tgz#2ebe2df2211a84862a3aea77316736189e23435b" + integrity sha512-3IHQmUQJwFFV7HwDONeIEahhaEvK9u23liqIUQajPy7frk/AoIGhkdKf4FVSTeq+VlUx97qls4uNizP7hBXIIw== react-native-os@icxcat/react-native-os#master: version "1.1.0" resolved "https://codeload.github.com/icxcat/react-native-os/tar.gz/1efb92b990fb4c02475fcc98a8260c3991c59b2d" -react-native-permissions@^1.1.1, react-native-permissions@^1.2.1: +react-native-permissions@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.2.1.tgz#cb1f6e53b8992b3912de5a4cfc1553ac2e82d0f6" integrity sha512-6NOGsA7EsuKT9hfULccQfMrsGmRhBkmN6Uv8nz2QObjEG87XtroQtw4Qi1+tAjIkSHawCeAMJp+SCtiXSGUD5Q== +react-native-permissions@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-2.0.3.tgz#b6da83e5e313e41ba5f70ff2c4567291766b0140" + integrity sha512-8pd+UhyphAiFGzBil5d5pDxRf/rH+20SzDNu9cFnCtoD2MbYTVH7GjXsxaZ2lPsmwrqYYbF8FBfwmncKf/G1+Q== + react-native-qrcode-scanner@mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e: version "1.0.1" resolved "https://codeload.github.com/mikedemarais/react-native-qrcode-scanner/tar.gz/2ca70b8c64afb87e712aba578e11409c6406069e" @@ -9390,17 +9404,20 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -react-native-svg@9.10.1: - version "9.10.1" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.10.1.tgz#055f457c427acedb01d2b758b6c1f423e8a3a607" - integrity sha512-im9LHke7pFRqQPf4qlSEti7QtcDHHeacRkI6xJspw1aka/n0LJxxBBkg7w7/Pmz5hDkzf7fRzyQi/TexB2sHnQ== +react-native-svg@9.13.3: + version "9.13.3" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.3.tgz#6414b337d55af169ac2487ab70f3108404434446" + integrity sha512-H50b2m4jvrQ7KxKs8uYSuWecr6e5XC7BDfS7DaA96+0Owjh0C9DksI5l8SRyHnmE+emiYMPu6Qqfr9dCyKkaJQ== + dependencies: + css-select "^2.0.2" + css-tree "^1.0.0-alpha.37" react-native-tab-view@^2.9.0: version "2.10.0" resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.0.tgz#5e249e5650502010013449ffd4e5edc18a95364b" integrity sha512-qgexVz5eO4yaFjdkmn/sURXgVvaBo6pZD/q1eoca96SbPVbaH3WzVhF3bRUfeTHwZkXwznFTpS3JURqIFU8vQA== -react-native-tcp@^3.3.0: +react-native-tcp@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/react-native-tcp/-/react-native-tcp-3.3.2.tgz#b38c153039acac89294caa4991689c003ec62dce" integrity sha512-zjFmjAvYOsBkR1MF7htuPlk+uOzTykKaeu/eN+I7fkZ7UqBCW+9u/gJgWCv6Tjfn2tGgku6hsEWril4Oy3zJhg== @@ -9443,7 +9460,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/5db27077cb3a05a827da8a5d03d0dab751612f5a" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/58726cee8576af1beca23d02fb09c655ab3e1c84" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" @@ -9476,25 +9493,25 @@ react-native@facebook/react-native: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.35: - version "2.0.0-alpha.35" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.35.tgz#4d98790f9edf87d40052f41f8b24f00f9008a383" - integrity sha512-D6Dts3KSg/8blKkwsHbjKUNVGwrtJKN0PXW2PveuN7ySuVnyMRpEUxhMVsO7jznVf1hpk7R+fsBDGKAkNcHiBA== +react-navigation-stack@2.0.0-alpha.36: + version "2.0.0-alpha.36" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.36.tgz#b8b207a7523c7919f39713a652f178c161754a70" + integrity sha512-29X8H4Z55MXzf7YWANj7TsfB5tHizALF5VWu2kgTENobNJWbNSeiwemQqXhsp58YmaWTmKcE1GpfeW3tPEoEvA== -react-navigation-tabs@2.5.5: - version "2.5.5" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.5.tgz#f651355b140b35ef5753aac434da5e1943abdd26" - integrity sha512-oIL5V4agCxcqbWNZzF1h/cm1bxKXNUeGrWaRQEEnuN3TXTEj1SVRz33CnKYg30pVvgF5L2p28sOk15Z4Ao01NQ== +react-navigation-tabs@2.5.6: + version "2.5.6" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.6.tgz#51f1a39b6c9525e6b5fe035945c243c04e53242b" + integrity sha512-4WivEAsChJ+MuJ6JHxhAUMekHnVIt/zc4y/07KChXD5NBkSE0sk4vmMRndZQ6AP3n/ZihACcfigBAsMoqt0JXA== dependencies: hoist-non-react-statics "^3.3.0" react-lifecycles-compat "^3.0.4" react-native-safe-area-view "^0.14.6" react-native-tab-view "^2.9.0" -react-navigation@4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.0.7.tgz#cc7ce334fef009242494d623e50e9cf79eb63ddd" - integrity sha512-0tTWanq870Hyr1VGHuj98+myRHNQnKgpRgjgzhAwVuLShyPIB9OnoLGIwIcqEdxgxGo+JMFmIGg8KCr7xapfgg== +react-navigation@4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.0.10.tgz#ddf41134600689d6ba99e35dd22ba1f664f91e5c" + integrity sha512-7PqvmsdQ7HIyxPUMYbd9Uq//VoMdniEOLAOSvIhb/ExtbAt/1INSjUF+RiMWOMCWLTCNvNPRvTz7xy7qwWureg== dependencies: "@react-navigation/core" "^3.5.1" "@react-navigation/native" "^3.6.2" @@ -9572,10 +9589,10 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@16.9.0: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa" - integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w== +react@16.11.0: + version "16.11.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.11.0.tgz#d294545fe62299ccee83363599bf904e4a07fdbb" + integrity sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -10123,10 +10140,10 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rn-nodeify@10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.1.0.tgz#e36c4aa25d6bf1dbde7d9f733ab30168772d50c6" - integrity sha512-EW9I7OWt1aTShdJEnnS/qoEvfb2myLee6uWcAMxJWcisn3z3DxWTTLfm5bqwn/2eYjcs6j677JLY6nL02uMaaQ== +rn-nodeify@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/rn-nodeify/-/rn-nodeify-10.2.0.tgz#e68843bf280edf878b7615b255fb5e71cde9f8f6" + integrity sha512-mPNe2vNR14UTwAbpebI9fXn9HAU37vebyZDCqZOK6G5GBEUiMCANIVa7zgc9aJ1JeziLUGLR9c+H9/BSbVdd4Q== dependencies: "@yarnpkg/lockfile" "^1.0.0" deep-equal "^1.0.0" @@ -10467,9 +10484,9 @@ simple-plist@^1.0.0: plist "^3.0.1" sisteransi@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" - integrity sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg== + version "1.0.4" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" + integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== sjcl@^1.0.3: version "1.0.8" @@ -11561,9 +11578,9 @@ unique-string@^1.0.0: crypto-random-string "^1.0.0" unist-util-find-all-after@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-1.0.4.tgz#2eeaba818fd98492d69c44f9bee52c6a25282eef" - integrity sha512-CaxvMjTd+yF93BKLJvZnEfqdM7fgEACsIpQqz8vIj9CJnUb9VpyymFS3tg6TCtgrF7vfCJBF5jbT2Ox9CBRYRQ== + version "1.0.5" + resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz#5751a8608834f41d117ad9c577770c5f2f1b2899" + integrity sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw== dependencies: unist-util-is "^3.0.0" @@ -11573,9 +11590,9 @@ unist-util-is@^3.0.0: integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== unist-util-remove-position@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz#d91aa8b89b30cb38bad2924da11072faa64fd972" - integrity sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA== + version "1.1.4" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz#ec037348b6102c897703eee6d0294ca4755a2020" + integrity sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A== dependencies: unist-util-visit "^1.1.0" @@ -11585,9 +11602,9 @@ unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ== unist-util-stringify-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz#de2a2bc8d3febfa606652673a91455b6a36fb9f3" - integrity sha512-Zqlf6+FRI39Bah8Q6ZnNGrEHUhwJOkHde2MHVk96lLyftfJJckaPslKgzhVcviXj8KcE9UJM9F+a4JEiBUTYgA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz#5a3866e7138d55974b640ec69a94bc19e0f3fa12" + integrity sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA== dependencies: "@types/unist" "^2.0.2" @@ -11771,16 +11788,16 @@ verror@1.10.0: extsprintf "^1.2.0" vfile-location@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.5.tgz#c83eb02f8040228a8d2b3f10e485be3e3433e0a2" - integrity sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.6.tgz#8a274f39411b8719ea5728802e10d9e0dff1519e" + integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA== vfile-message@*: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.1.tgz#951881861c22fc1eb39f873c0b93e336a64e8f6d" - integrity sha512-KtasSV+uVU7RWhUn4Lw+wW1Zl/nW8JWx7JCPps10Y9JRRIDeDXf8wfBLoOSsJLyo27DqMyAi54C6Jf/d6Kr2Bw== + version "2.0.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.2.tgz#75ba05090ec758fa8420f2c11ce049bcddd8cf3e" + integrity sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA== dependencies: - "@types/unist" "^2.0.2" + "@types/unist" "^2.0.0" unist-util-stringify-position "^2.0.0" vfile-message@^1.0.0: From 5255b33d0cd65776e7b8b3091f9990d4d464a4a0 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 01:35:02 -0500 Subject: [PATCH 498/636] enable safari debugging --- ios/Rainbow/AppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Rainbow/AppDelegate.m b/ios/Rainbow/AppDelegate.m index da84b28a998..1ced4283042 100644 --- a/ios/Rainbow/AppDelegate.m +++ b/ios/Rainbow/AppDelegate.m @@ -48,7 +48,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; + return [NSURL URLWithString:[[[[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil] absoluteString] stringByAppendingString:@"&inlineSourceMap=true" ]]; #else return [CodePush bundleURL]; #endif From 40f011f80dcb78cc924a905b06a3d4f1cba75421 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 8 Nov 2019 20:52:08 +0100 Subject: [PATCH 499/636] fix refocus in send sheet and move open assets logic to wallet initialization --- src/components/SendComponentWithData.js | 2 +- .../animations/ButtonPressAnimation.js | 2 ++ .../contacts/SwipeableContactRow.js | 16 ++-------- src/components/fields/AddressField.js | 3 ++ src/components/fields/UnderlineField.js | 11 +++++++ src/components/send/SendContactList.js | 29 +++++++++++++++++-- src/components/send/SendHeader.js | 21 ++++++++++++-- src/components/text/ErrorText.js | 4 +-- src/hoc/withDataInit.js | 29 +++++++++++++++++-- src/hoc/withSelectedInput.js | 14 +++++++++ src/redux/reducers.js | 2 ++ src/redux/selectedInput.js | 24 +++++++++++++++ src/screens/SendSheet.js | 6 ---- src/screens/WalletScreen.js | 24 --------------- 14 files changed, 133 insertions(+), 54 deletions(-) create mode 100644 src/hoc/withSelectedInput.js create mode 100644 src/redux/selectedInput.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index f0d3aedfe56..b1e6e860db1 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -47,7 +47,7 @@ const mapStateToProps = ({ send, settings }) => ({ export const withSendComponentWithData = (SendComponent, options) => { class SendComponentWithData extends Component { static propTypes = { - accountType: PropTypes.string.isRequired, + accountType: PropTypes.string, address: PropTypes.string, assetAmount: PropTypes.string.isRequired, assets: PropTypes.array.isRequired, diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index be4b31ebfda..ca7cc2c34ed 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -150,6 +150,7 @@ export default class ButtonPressAnimation extends Component { }; createLongPressListener = () => { + this.longPressDetected = false; const { minLongPressDuration, onLongPress } = this.props; if (onLongPress) { this.longPressTimeout = setTimeout( @@ -176,6 +177,7 @@ export default class ButtonPressAnimation extends Component { handleDetectedLongPress = () => { this.longPressDetected = true; + clearTimeout(this.longPressTimeout); this.handleHaptic(); this.props.onLongPress(); }; diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index e4c09706c7f..440bc8bd7be 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -66,9 +66,9 @@ export default class SwipeableContactRow extends PureComponent { onPress: PropTypes.func, onTouch: PropTypes.func, onTransitionEnd: PropTypes.func, + selectedInputId: PropTypes.object, }; - isFocused = false; swipeableRef = undefined; close = () => this.swipeableRef.close(); @@ -84,19 +84,8 @@ export default class SwipeableContactRow extends PureComponent { }; handleEditContact = () => { - const { address, color, navigation, nickname, onChange } = this.props; - const refocusCallback = this.isFocused && this.props.inputRef.focus; - this.close(); - navigation.navigate('OverlayExpandedAssetScreen', { - address, - asset: [], - color, - contact: { address, color, nickname }, - onCloseModal: onChange, - onRefocusInput: refocusCallback, - type: 'contact', - }); + this.props.onSelectEdit(this.props); }; handleLongPress = () => this.swipeableRef.openRight(); @@ -105,7 +94,6 @@ export default class SwipeableContactRow extends PureComponent { handlePressStart = () => { this.props.onTouch(this.props.address); - this.isFocused = this.props.inputRef.isFocused(); }; handleRef = ref => { diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 4fb85f96fca..5f3bb476126 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -121,6 +121,9 @@ export default withNavigation( onBlur = () => { this.checkClipboard(this.state.address); + if (this.props.onBlur) { + this.props.onBlur(); + } }; checkClipboard = async address => { diff --git a/src/components/fields/UnderlineField.js b/src/components/fields/UnderlineField.js index d30492eee84..a1d966a9941 100644 --- a/src/components/fields/UnderlineField.js +++ b/src/components/fields/UnderlineField.js @@ -6,7 +6,9 @@ import Animated, { Easing } from 'react-native-reanimated'; import { colors, position } from '../../styles'; import { Button } from '../buttons'; import { Input } from '../inputs'; +import store from '../../redux/store'; import { Column, FlexItem, Row } from '../layout'; +import { setSelectedInputId } from '../../redux/selectedInput'; const Underline = styled(View)` ${position.cover}; @@ -78,6 +80,7 @@ export default class UnderlineField extends PureComponent { this.setState({ isFocused: false }); if (this.props.onBlur) this.props.onBlur(...props); + store.dispatch(setSelectedInputId(null)); }; onChange = event => { @@ -102,6 +105,13 @@ export default class UnderlineField extends PureComponent { this.setState({ isFocused: true }); if (this.props.onFocus) this.props.onFocus(...props); + if (this.input && this.input.isFocused()) { + store.dispatch(setSelectedInputId(this.input)); + } + }; + + handleRef = ref => { + this.input = ref; }; render() { @@ -126,6 +136,7 @@ export default class UnderlineField extends PureComponent { > { - if (this.touchedContact) { + if (this.touchedContact && this.contacts[this.touchedContact]) { this.contacts[this.touchedContact].close(); } this.touchedContact = address; @@ -134,6 +137,22 @@ class SendContactList extends Component { return false; }; + onSelectEdit = accountInfo => { + const { address, color, navigation, nickname, onChange } = accountInfo; + const refocusCallback = + this.props.selectedInputId && this.props.selectedInputId.focus; + + navigation.navigate('OverlayExpandedAssetScreen', { + address, + asset: [], + color, + contact: { address, color, nickname }, + onCloseModal: onChange, + onRefocusInput: refocusCallback, + type: 'contact', + }); + }; + renderItem = (type, item) => ( { this.contacts[item.address] = component; }} @@ -169,4 +189,7 @@ class SendContactList extends Component { ); } -export default withNavigation(SendContactList); +export default compose( + withSelectedInput, + withNavigation +)(SendContactList); diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 1f1e8ce7b70..48ca2054452 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -15,6 +15,9 @@ import { AddressField } from '../fields'; import { Icon } from '../icons'; import { Row } from '../layout'; import { Label } from '../text'; +import store from '../../redux/store'; +import withSelectedInput from '../../hoc/withSelectedInput'; +import { setSelectedInputId } from '../../redux/selectedInput'; const AddressInputContainer = styled(Row).attrs({ align: 'center' })` ${padding(19, 15)} @@ -87,6 +90,7 @@ class SendHeader extends PureComponent { onPressPaste: PropTypes.func, onUpdateContacts: PropTypes.func, recipient: PropTypes.string, + selectedInputId: PropTypes.object, }; handleConfirmDeleteContactSelection = async buttonIndex => { @@ -110,7 +114,9 @@ class SendHeader extends PureComponent { navigateToContact = (contact = {}) => { const { navigation, onUpdateContacts, recipient } = this.props; - const refocusCallback = this.input.isFocused() && this.input.focus; + const refocusCallback = + this.props.selectedInputId.isFocused() && + this.props.selectedInputId.focus; let color = get(contact, 'color'); if (!isNumber(color)) { @@ -134,7 +140,15 @@ class SendHeader extends PureComponent { handleRef = ref => { this.input = ref; - this.props.inputRef(ref); + }; + + onFocus = () => { + store.dispatch(setSelectedInputId(this.input)); + }; + + onBlur = () => { + console.log('blur'); + store.dispatch(setSelectedInputId(null)); }; render = () => { @@ -160,6 +174,8 @@ class SendHeader extends PureComponent { name={contact.nickname} onChange={onChangeAddressInput} inputRef={this.handleRef} + onFocus={this.onFocus} + onBlur={this.onBlur} /> {isValidAddress && ( ( - + {error} diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index fc09a63b796..a13641c0c4d 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -3,7 +3,12 @@ import { isNil } from 'lodash'; import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { compose, withHandlers } from 'recompact'; -import { getIsWalletEmpty } from '../handlers/localstorage/accountLocal'; +import { + getIsWalletEmpty, + getOpenFamilies, + getOpenInvestmentCards, + getSmallBalanceToggle, +} from '../handlers/localstorage/accountLocal'; import { hasEthBalance } from '../handlers/web3'; import { dataClearState, dataLoadState } from '../redux/data'; import { explorerClearState, explorerInit } from '../redux/explorer'; @@ -11,8 +16,9 @@ import { gasClearState, gasPricesInit } from '../redux/gas'; import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; -import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; +import { clearOpenFamilyTab, pushOpenFamilyTab } from '../redux/openFamilyTabs'; import { requestsLoadState, requestsClearState } from '../redux/requests'; + import { settingsLoadState, settingsUpdateAccountAddress, @@ -36,6 +42,10 @@ import { walletConnectLoadState, walletConnectClearState, } from '../redux/walletconnect'; +import { setOpenSmallBalances } from '../redux/openBalances'; + +import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; +import store from '../redux/store'; import { promiseUtils } from '../utils'; import withHideSplashScreen from './withHideSplashScreen'; @@ -136,6 +146,17 @@ export default Component => throw error; } }, + setInitialStatesForOpenAssets: () => async (walletAddress, network) => { + const toggle = await getSmallBalanceToggle(walletAddress, network); + const openInvestmentCards = await getOpenInvestmentCards( + walletAddress, + network + ); + const openFamilies = await getOpenFamilies(walletAddress, network); + await store.dispatch(setOpenSmallBalances(toggle)); + await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); + await store.dispatch(pushOpenFamilyTab(openFamilies)); + }, }), withHandlers({ initializeWallet: ownProps => async seedPhrase => { @@ -149,6 +170,10 @@ export default Component => ); return null; } + await ownProps.setInitialStatesForOpenAssets( + walletAddress, + ownProps.network + ); if (isImported) { await ownProps.clearAccountData(); } diff --git a/src/hoc/withSelectedInput.js b/src/hoc/withSelectedInput.js new file mode 100644 index 00000000000..0d5b3488cdd --- /dev/null +++ b/src/hoc/withSelectedInput.js @@ -0,0 +1,14 @@ +import { connect } from 'react-redux'; +import { setSelectedInputId } from '../redux/selectedInput'; + +const mapStateToProps = ({ selectedInput: { selectedInputId } }) => ({ + selectedInputId, +}); + +export default Component => + connect( + mapStateToProps, + { + setSelectedInputId, + } + )(Component); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index c4ac6f4faa8..5d51d9d7008 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -15,6 +15,7 @@ import openBalances from './openBalances'; import openFamilyTabs from './openFamilyTabs'; import openInvestmentCards from './openInvestmentCards'; import requests from './requests'; +import selectedInput from './selectedInput'; import selectedWithFab from './selectedWithFab'; import send from './send'; import settings from './settings'; @@ -38,6 +39,7 @@ export default combineReducers({ openFamilyTabs, openInvestmentCards, requests, + selectedInput, selectedWithFab, send, settings, diff --git a/src/redux/selectedInput.js b/src/redux/selectedInput.js new file mode 100644 index 00000000000..4f9306d9d84 --- /dev/null +++ b/src/redux/selectedInput.js @@ -0,0 +1,24 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_SELECTED_INPUT_ID = 'openBalances/SET_SELECTED_INPUT_ID'; + +export const setSelectedInputId = payload => dispatch => { + console.log(payload); + dispatch({ + payload, + type: SET_SELECTED_INPUT_ID, + }); +}; + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + selectedInputId: null, +}; + +export default (state = INITIAL_STATE, action) => + produce(state, draft => { + if (action.type === SET_SELECTED_INPUT_ID) { + draft.selectedInputId = action.payload; + } + }); diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 7c86932fd1a..cbd532bbd3a 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -217,10 +217,6 @@ class SendSheet extends Component { this.props.sendUpdateRecipient(event); }; - handleRef = ref => { - this.input = ref; - }; - render() { const { allAssets, @@ -244,7 +240,6 @@ class SendSheet extends Component { diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 57216d9b909..c1570e84065 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -12,11 +12,6 @@ import { ProfileHeaderButton, } from '../components/header'; import { Page } from '../components/layout'; -import { - getOpenFamilies, - getOpenInvestmentCards, - getSmallBalanceToggle, -} from '../handlers/localstorage/accountLocal'; import buildWalletSectionsSelector from '../helpers/buildWalletSections'; import { withAccountData, @@ -28,10 +23,6 @@ import { withUniqueTokens, withUniswapLiquidityTokenInfo, } from '../hoc'; -import { setOpenSmallBalances } from '../redux/openBalances'; -import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; -import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; -import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForObjectPaths } from '../utils'; @@ -57,7 +48,6 @@ class WalletScreen extends Component { componentDidMount = async () => { try { await this.props.initializeWallet(); - await this.setInitialStatesForOpenAssets(); } catch (error) { // TODO error state } @@ -76,20 +66,6 @@ class WalletScreen extends Component { 'sections', ]); - setInitialStatesForOpenAssets = async () => { - const { accountAddress, network } = this.props; - const toggle = await getSmallBalanceToggle(accountAddress, network); - const openInvestmentCards = await getOpenInvestmentCards( - accountAddress, - network - ); - const openFamilies = await getOpenFamilies(accountAddress, network); - await store.dispatch(setOpenSmallBalances(toggle)); - await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); - await store.dispatch(pushOpenFamilyTab(openFamilies)); - return true; - }; - render = () => { const { isEmpty, From 8634f321a73fb43e3df0ff45e6587595e0e321f3 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 8 Nov 2019 21:57:15 +0100 Subject: [PATCH 500/636] remove logs from send header and select input --- src/components/send/SendHeader.js | 1 - src/redux/selectedInput.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 48ca2054452..8397a659660 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -147,7 +147,6 @@ class SendHeader extends PureComponent { }; onBlur = () => { - console.log('blur'); store.dispatch(setSelectedInputId(null)); }; diff --git a/src/redux/selectedInput.js b/src/redux/selectedInput.js index 4f9306d9d84..0ed76ec4a49 100644 --- a/src/redux/selectedInput.js +++ b/src/redux/selectedInput.js @@ -4,7 +4,6 @@ import produce from 'immer'; const SET_SELECTED_INPUT_ID = 'openBalances/SET_SELECTED_INPUT_ID'; export const setSelectedInputId = payload => dispatch => { - console.log(payload); dispatch({ payload, type: SET_SELECTED_INPUT_ID, From b76b6ea266ecbf85ba3f0b53483ec8b04c02dc71 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 01:56:04 -0500 Subject: [PATCH 501/636] alphabetize wojtus7 code --- src/components/fields/UnderlineField.js | 6 +++--- src/components/send/SendContactList.js | 15 ++++++--------- src/components/send/SendHeader.js | 11 +++++------ src/hoc/withSelectedInput.js | 7 +------ 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/components/fields/UnderlineField.js b/src/components/fields/UnderlineField.js index a1d966a9941..08367f05d3e 100644 --- a/src/components/fields/UnderlineField.js +++ b/src/components/fields/UnderlineField.js @@ -3,12 +3,12 @@ import React, { PureComponent } from 'react'; import styled from 'styled-components/primitives'; import { View } from 'react-native'; import Animated, { Easing } from 'react-native-reanimated'; +import { setSelectedInputId } from '../../redux/selectedInput'; +import store from '../../redux/store'; import { colors, position } from '../../styles'; import { Button } from '../buttons'; import { Input } from '../inputs'; -import store from '../../redux/store'; import { Column, FlexItem, Row } from '../layout'; -import { setSelectedInputId } from '../../redux/selectedInput'; const Underline = styled(View)` ${position.cover}; @@ -136,7 +136,6 @@ export default class UnderlineField extends PureComponent { > diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 3bc23e67a7f..110fcf1f708 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -6,14 +6,14 @@ import { RecyclerListView, } from 'recyclerlistview'; import { withNavigation } from 'react-navigation'; +import { compose } from 'recompose'; +import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; +import withSelectedInput from '../../hoc/withSelectedInput'; +import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { deviceUtils } from '../../utils'; import { FlyInAnimation } from '../animations'; -import { sheetVerticalOffset } from '../../navigation/transitions/effects'; -import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; import { SwipeableContactRow } from '../contacts'; import SendEmptyState from './SendEmptyState'; -import withSelectedInput from '../../hoc/withSelectedInput'; -import { compose } from 'recompose'; const LastRowPadding = 12; const rowHeight = 62; @@ -159,8 +159,8 @@ class SendContactList extends Component { navigation={this.props.navigation} onChange={this.props.onUpdateContacts} onPress={this.props.onPressContact} - onTouch={this.closeAllDifferentContacts} onSelectEdit={this.onSelectEdit} + onTouch={this.closeAllDifferentContacts} ref={component => { this.contacts[item.address] = component; }} @@ -189,7 +189,4 @@ class SendContactList extends Component { ); } -export default compose( - withSelectedInput, - withNavigation -)(SendContactList); +export default compose(withSelectedInput, withNavigation)(SendContactList); diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 8397a659660..28c4e9f9e8e 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -6,7 +6,9 @@ import { Keyboard, Clipboard } from 'react-native'; import { withNavigation } from 'react-navigation'; import { compose, withProps } from 'recompact'; import { deleteLocalContact } from '../../handlers/localstorage/contacts'; -import { withNeverRerender } from '../../hoc'; +import { withNeverRerender, withSelectedInput } from '../../hoc'; +import { setSelectedInputId } from '../../redux/selectedInput'; +import store from '../../redux/store'; import { colors, padding } from '../../styles'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { AddContactButton, PasteAddressButton } from '../buttons'; @@ -15,9 +17,6 @@ import { AddressField } from '../fields'; import { Icon } from '../icons'; import { Row } from '../layout'; import { Label } from '../text'; -import store from '../../redux/store'; -import withSelectedInput from '../../hoc/withSelectedInput'; -import { setSelectedInputId } from '../../redux/selectedInput'; const AddressInputContainer = styled(Row).attrs({ align: 'center' })` ${padding(19, 15)} @@ -170,11 +169,11 @@ class SendHeader extends PureComponent { address={recipient} autoFocus currentContact={contact} + inputRef={this.handleRef} name={contact.nickname} + onBlur={this.onBlur} onChange={onChangeAddressInput} - inputRef={this.handleRef} onFocus={this.onFocus} - onBlur={this.onBlur} /> {isValidAddress && ( ({ }); export default Component => - connect( - mapStateToProps, - { - setSelectedInputId, - } - )(Component); + connect(mapStateToProps, { setSelectedInputId })(Component); From 7b42bdf1b49817954b95ebd76e4162bc1cb226f2 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 02:05:35 -0500 Subject: [PATCH 502/636] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 93dfaa6b1da..3322dab31d8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# Rainbow Wallet +# Rainbow +🌈️ — the pocket robot for your internet money. ⁖𝗣𝗼𝘄𝗲𝗿𝗲𝗱 𝗯𝘆 𝗘𝘁𝗵𝗲𝗿𝗲𝘂𝗺⁖ -A mobile wallet for open finance and the decentralized web. +📲️ [Available on the iOS App Store.](https://apps.apple.com/us/app/rainbow-ethereum-wallet/id1457119021) ## Requirements From e7c513e96dc581dd9685e4469aee70fbf7fa32a0 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 02:10:06 -0500 Subject: [PATCH 503/636] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3322dab31d8..ce375d0ebc7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ -# Rainbow -🌈️ — the pocket robot for your internet money. ⁖𝗣𝗼𝘄𝗲𝗿𝗲𝗱 𝗯𝘆 𝗘𝘁𝗵𝗲𝗿𝗲𝘂𝗺⁖ +![](https://pbs.twimg.com/profile_banners/1103191459409420288/1573207178/1500x500) +# 🌈️ Rainbow +— the pocket robot for your internet money. ⁖𝗣𝗼𝘄𝗲𝗿𝗲𝗱 𝗯𝘆 𝗘𝘁𝗵𝗲𝗿𝗲𝘂𝗺⁖ 📲️ [Available on the iOS App Store.](https://apps.apple.com/us/app/rainbow-ethereum-wallet/id1457119021) +🐦️ [Follow us on Twitter](https://twitter.com/rainbowdotme) + ## Requirements * A computer running macOS. From afc614dfd1536ec79aeb0ab33924b8e3fea08889 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 02:11:38 -0500 Subject: [PATCH 504/636] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce375d0ebc7..8d7a8f80dec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![](https://pbs.twimg.com/profile_banners/1103191459409420288/1573207178/1500x500) -# 🌈️ Rainbow -— the pocket robot for your internet money. ⁖𝗣𝗼𝘄𝗲𝗿𝗲𝗱 𝗯𝘆 𝗘𝘁𝗵𝗲𝗿𝗲𝘂𝗺⁖ +### 🌈️ Rainbow +> the pocket robot for your internet money ⁖𝗣𝗼𝘄𝗲𝗿𝗲𝗱 𝗯𝘆 𝗘𝘁𝗵𝗲𝗿𝗲𝘂𝗺⁖ 📲️ [Available on the iOS App Store.](https://apps.apple.com/us/app/rainbow-ethereum-wallet/id1457119021) From c32432b585c57878b4f07e01a725fc9a285b6515 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 02:13:21 -0500 Subject: [PATCH 505/636] Revert "Change wallet init and keyboard in send" --- src/components/SendComponentWithData.js | 2 +- .../animations/ButtonPressAnimation.js | 2 -- .../contacts/SwipeableContactRow.js | 16 ++++++++-- src/components/fields/AddressField.js | 3 -- src/components/fields/UnderlineField.js | 11 ------- src/components/send/SendContactList.js | 30 ++++--------------- src/components/send/SendHeader.js | 23 +++----------- src/components/text/ErrorText.js | 4 +-- src/hoc/withDataInit.js | 29 ++---------------- src/hoc/withSelectedInput.js | 9 ------ src/redux/reducers.js | 2 -- src/redux/selectedInput.js | 23 -------------- src/screens/SendSheet.js | 6 ++++ src/screens/WalletScreen.js | 24 +++++++++++++++ 14 files changed, 58 insertions(+), 126 deletions(-) delete mode 100644 src/hoc/withSelectedInput.js delete mode 100644 src/redux/selectedInput.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index b1e6e860db1..f0d3aedfe56 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -47,7 +47,7 @@ const mapStateToProps = ({ send, settings }) => ({ export const withSendComponentWithData = (SendComponent, options) => { class SendComponentWithData extends Component { static propTypes = { - accountType: PropTypes.string, + accountType: PropTypes.string.isRequired, address: PropTypes.string, assetAmount: PropTypes.string.isRequired, assets: PropTypes.array.isRequired, diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index ca7cc2c34ed..be4b31ebfda 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -150,7 +150,6 @@ export default class ButtonPressAnimation extends Component { }; createLongPressListener = () => { - this.longPressDetected = false; const { minLongPressDuration, onLongPress } = this.props; if (onLongPress) { this.longPressTimeout = setTimeout( @@ -177,7 +176,6 @@ export default class ButtonPressAnimation extends Component { handleDetectedLongPress = () => { this.longPressDetected = true; - clearTimeout(this.longPressTimeout); this.handleHaptic(); this.props.onLongPress(); }; diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index 440bc8bd7be..e4c09706c7f 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -66,9 +66,9 @@ export default class SwipeableContactRow extends PureComponent { onPress: PropTypes.func, onTouch: PropTypes.func, onTransitionEnd: PropTypes.func, - selectedInputId: PropTypes.object, }; + isFocused = false; swipeableRef = undefined; close = () => this.swipeableRef.close(); @@ -84,8 +84,19 @@ export default class SwipeableContactRow extends PureComponent { }; handleEditContact = () => { + const { address, color, navigation, nickname, onChange } = this.props; + const refocusCallback = this.isFocused && this.props.inputRef.focus; + this.close(); - this.props.onSelectEdit(this.props); + navigation.navigate('OverlayExpandedAssetScreen', { + address, + asset: [], + color, + contact: { address, color, nickname }, + onCloseModal: onChange, + onRefocusInput: refocusCallback, + type: 'contact', + }); }; handleLongPress = () => this.swipeableRef.openRight(); @@ -94,6 +105,7 @@ export default class SwipeableContactRow extends PureComponent { handlePressStart = () => { this.props.onTouch(this.props.address); + this.isFocused = this.props.inputRef.isFocused(); }; handleRef = ref => { diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 5f3bb476126..4fb85f96fca 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -121,9 +121,6 @@ export default withNavigation( onBlur = () => { this.checkClipboard(this.state.address); - if (this.props.onBlur) { - this.props.onBlur(); - } }; checkClipboard = async address => { diff --git a/src/components/fields/UnderlineField.js b/src/components/fields/UnderlineField.js index 08367f05d3e..d30492eee84 100644 --- a/src/components/fields/UnderlineField.js +++ b/src/components/fields/UnderlineField.js @@ -3,8 +3,6 @@ import React, { PureComponent } from 'react'; import styled from 'styled-components/primitives'; import { View } from 'react-native'; import Animated, { Easing } from 'react-native-reanimated'; -import { setSelectedInputId } from '../../redux/selectedInput'; -import store from '../../redux/store'; import { colors, position } from '../../styles'; import { Button } from '../buttons'; import { Input } from '../inputs'; @@ -80,7 +78,6 @@ export default class UnderlineField extends PureComponent { this.setState({ isFocused: false }); if (this.props.onBlur) this.props.onBlur(...props); - store.dispatch(setSelectedInputId(null)); }; onChange = event => { @@ -105,13 +102,6 @@ export default class UnderlineField extends PureComponent { this.setState({ isFocused: true }); if (this.props.onFocus) this.props.onFocus(...props); - if (this.input && this.input.isFocused()) { - store.dispatch(setSelectedInputId(this.input)); - } - }; - - handleRef = ref => { - this.input = ref; }; render() { @@ -145,7 +135,6 @@ export default class UnderlineField extends PureComponent { onChange={this.onChange} onFocus={this.onFocus} placeholder={placeholder} - ref={this.handleRef} size="h2" value={this.format(String(this.props.value || ''))} /> diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 110fcf1f708..a6de3c7394d 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -6,12 +6,10 @@ import { RecyclerListView, } from 'recyclerlistview'; import { withNavigation } from 'react-navigation'; -import { compose } from 'recompose'; -import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; -import withSelectedInput from '../../hoc/withSelectedInput'; -import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { deviceUtils } from '../../utils'; import { FlyInAnimation } from '../animations'; +import { sheetVerticalOffset } from '../../navigation/transitions/effects'; +import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; import { SwipeableContactRow } from '../contacts'; import SendEmptyState from './SendEmptyState'; @@ -29,8 +27,7 @@ class SendContactList extends Component { currentInput: PropTypes.string, navigation: PropTypes.object, onPressContact: PropTypes.func, - onUpdateContacts: PropTypes.func, - selectedInputId: PropTypes.object, + onUpdateContacts: PropTypes.array, }; constructor(args) { @@ -87,7 +84,7 @@ class SendContactList extends Component { }; closeAllDifferentContacts = address => { - if (this.touchedContact && this.contacts[this.touchedContact]) { + if (this.touchedContact) { this.contacts[this.touchedContact].close(); } this.touchedContact = address; @@ -137,29 +134,12 @@ class SendContactList extends Component { return false; }; - onSelectEdit = accountInfo => { - const { address, color, navigation, nickname, onChange } = accountInfo; - const refocusCallback = - this.props.selectedInputId && this.props.selectedInputId.focus; - - navigation.navigate('OverlayExpandedAssetScreen', { - address, - asset: [], - color, - contact: { address, color, nickname }, - onCloseModal: onChange, - onRefocusInput: refocusCallback, - type: 'contact', - }); - }; - renderItem = (type, item) => ( { this.contacts[item.address] = component; @@ -189,4 +169,4 @@ class SendContactList extends Component { ); } -export default compose(withSelectedInput, withNavigation)(SendContactList); +export default withNavigation(SendContactList); diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 28c4e9f9e8e..1f1e8ce7b70 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -6,9 +6,7 @@ import { Keyboard, Clipboard } from 'react-native'; import { withNavigation } from 'react-navigation'; import { compose, withProps } from 'recompact'; import { deleteLocalContact } from '../../handlers/localstorage/contacts'; -import { withNeverRerender, withSelectedInput } from '../../hoc'; -import { setSelectedInputId } from '../../redux/selectedInput'; -import store from '../../redux/store'; +import { withNeverRerender } from '../../hoc'; import { colors, padding } from '../../styles'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { AddContactButton, PasteAddressButton } from '../buttons'; @@ -89,7 +87,6 @@ class SendHeader extends PureComponent { onPressPaste: PropTypes.func, onUpdateContacts: PropTypes.func, recipient: PropTypes.string, - selectedInputId: PropTypes.object, }; handleConfirmDeleteContactSelection = async buttonIndex => { @@ -113,9 +110,7 @@ class SendHeader extends PureComponent { navigateToContact = (contact = {}) => { const { navigation, onUpdateContacts, recipient } = this.props; - const refocusCallback = - this.props.selectedInputId.isFocused() && - this.props.selectedInputId.focus; + const refocusCallback = this.input.isFocused() && this.input.focus; let color = get(contact, 'color'); if (!isNumber(color)) { @@ -139,14 +134,7 @@ class SendHeader extends PureComponent { handleRef = ref => { this.input = ref; - }; - - onFocus = () => { - store.dispatch(setSelectedInputId(this.input)); - }; - - onBlur = () => { - store.dispatch(setSelectedInputId(null)); + this.props.inputRef(ref); }; render = () => { @@ -169,11 +157,9 @@ class SendHeader extends PureComponent { address={recipient} autoFocus currentContact={contact} - inputRef={this.handleRef} name={contact.nickname} - onBlur={this.onBlur} onChange={onChangeAddressInput} - onFocus={this.onFocus} + inputRef={this.handleRef} /> {isValidAddress && ( ( - + {error} diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index a13641c0c4d..fc09a63b796 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -3,12 +3,7 @@ import { isNil } from 'lodash'; import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { compose, withHandlers } from 'recompact'; -import { - getIsWalletEmpty, - getOpenFamilies, - getOpenInvestmentCards, - getSmallBalanceToggle, -} from '../handlers/localstorage/accountLocal'; +import { getIsWalletEmpty } from '../handlers/localstorage/accountLocal'; import { hasEthBalance } from '../handlers/web3'; import { dataClearState, dataLoadState } from '../redux/data'; import { explorerClearState, explorerInit } from '../redux/explorer'; @@ -16,9 +11,8 @@ import { gasClearState, gasPricesInit } from '../redux/gas'; import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; -import { clearOpenFamilyTab, pushOpenFamilyTab } from '../redux/openFamilyTabs'; +import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; import { requestsLoadState, requestsClearState } from '../redux/requests'; - import { settingsLoadState, settingsUpdateAccountAddress, @@ -42,10 +36,6 @@ import { walletConnectLoadState, walletConnectClearState, } from '../redux/walletconnect'; -import { setOpenSmallBalances } from '../redux/openBalances'; - -import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; -import store from '../redux/store'; import { promiseUtils } from '../utils'; import withHideSplashScreen from './withHideSplashScreen'; @@ -146,17 +136,6 @@ export default Component => throw error; } }, - setInitialStatesForOpenAssets: () => async (walletAddress, network) => { - const toggle = await getSmallBalanceToggle(walletAddress, network); - const openInvestmentCards = await getOpenInvestmentCards( - walletAddress, - network - ); - const openFamilies = await getOpenFamilies(walletAddress, network); - await store.dispatch(setOpenSmallBalances(toggle)); - await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); - await store.dispatch(pushOpenFamilyTab(openFamilies)); - }, }), withHandlers({ initializeWallet: ownProps => async seedPhrase => { @@ -170,10 +149,6 @@ export default Component => ); return null; } - await ownProps.setInitialStatesForOpenAssets( - walletAddress, - ownProps.network - ); if (isImported) { await ownProps.clearAccountData(); } diff --git a/src/hoc/withSelectedInput.js b/src/hoc/withSelectedInput.js deleted file mode 100644 index f657b6a6c8a..00000000000 --- a/src/hoc/withSelectedInput.js +++ /dev/null @@ -1,9 +0,0 @@ -import { connect } from 'react-redux'; -import { setSelectedInputId } from '../redux/selectedInput'; - -const mapStateToProps = ({ selectedInput: { selectedInputId } }) => ({ - selectedInputId, -}); - -export default Component => - connect(mapStateToProps, { setSelectedInputId })(Component); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 5d51d9d7008..c4ac6f4faa8 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -15,7 +15,6 @@ import openBalances from './openBalances'; import openFamilyTabs from './openFamilyTabs'; import openInvestmentCards from './openInvestmentCards'; import requests from './requests'; -import selectedInput from './selectedInput'; import selectedWithFab from './selectedWithFab'; import send from './send'; import settings from './settings'; @@ -39,7 +38,6 @@ export default combineReducers({ openFamilyTabs, openInvestmentCards, requests, - selectedInput, selectedWithFab, send, settings, diff --git a/src/redux/selectedInput.js b/src/redux/selectedInput.js deleted file mode 100644 index 0ed76ec4a49..00000000000 --- a/src/redux/selectedInput.js +++ /dev/null @@ -1,23 +0,0 @@ -import produce from 'immer'; - -// -- Constants --------------------------------------- // -const SET_SELECTED_INPUT_ID = 'openBalances/SET_SELECTED_INPUT_ID'; - -export const setSelectedInputId = payload => dispatch => { - dispatch({ - payload, - type: SET_SELECTED_INPUT_ID, - }); -}; - -// -- Reducer ----------------------------------------- // -const INITIAL_STATE = { - selectedInputId: null, -}; - -export default (state = INITIAL_STATE, action) => - produce(state, draft => { - if (action.type === SET_SELECTED_INPUT_ID) { - draft.selectedInputId = action.payload; - } - }); diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index cbd532bbd3a..7c86932fd1a 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -217,6 +217,10 @@ class SendSheet extends Component { this.props.sendUpdateRecipient(event); }; + handleRef = ref => { + this.input = ref; + }; + render() { const { allAssets, @@ -240,6 +244,7 @@ class SendSheet extends Component { diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index c1570e84065..57216d9b909 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -12,6 +12,11 @@ import { ProfileHeaderButton, } from '../components/header'; import { Page } from '../components/layout'; +import { + getOpenFamilies, + getOpenInvestmentCards, + getSmallBalanceToggle, +} from '../handlers/localstorage/accountLocal'; import buildWalletSectionsSelector from '../helpers/buildWalletSections'; import { withAccountData, @@ -23,6 +28,10 @@ import { withUniqueTokens, withUniswapLiquidityTokenInfo, } from '../hoc'; +import { setOpenSmallBalances } from '../redux/openBalances'; +import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; +import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; +import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForObjectPaths } from '../utils'; @@ -48,6 +57,7 @@ class WalletScreen extends Component { componentDidMount = async () => { try { await this.props.initializeWallet(); + await this.setInitialStatesForOpenAssets(); } catch (error) { // TODO error state } @@ -66,6 +76,20 @@ class WalletScreen extends Component { 'sections', ]); + setInitialStatesForOpenAssets = async () => { + const { accountAddress, network } = this.props; + const toggle = await getSmallBalanceToggle(accountAddress, network); + const openInvestmentCards = await getOpenInvestmentCards( + accountAddress, + network + ); + const openFamilies = await getOpenFamilies(accountAddress, network); + await store.dispatch(setOpenSmallBalances(toggle)); + await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); + await store.dispatch(pushOpenFamilyTab(openFamilies)); + return true; + }; + render = () => { const { isEmpty, From 7b9825a0bedd9d09ca913d7882977c9419d33918 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 10 Nov 2019 02:50:12 -0500 Subject: [PATCH 506/636] calculate native price from market details of selected swap input --- src/redux/gas.js | 9 ++------- src/screens/ExchangeModal.js | 23 ++++++++++++++++++++--- src/utils/ethereumUtils.js | 22 ++++++++++++++-------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/redux/gas.js b/src/redux/gas.js index 4beb2e8aded..bab930fa30b 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -22,17 +22,12 @@ const GAS_UPDATE_GAS_PRICE_OPTION = 'gas/GAS_UPDATE_GAS_PRICE_OPTION'; // -- Actions --------------------------------------------------------------- // let getGasPricesInterval = null; -const getEthPriceUnit = assets => { - const ethAsset = ethereumUtils.getAsset(assets); - return get(ethAsset, 'price.value', 0); -}; - const getDefaultTxFees = () => (dispatch, getState) => { const { assets } = getState().data; const { gasLimit } = getState().gas; const { nativeCurrency } = getState().settings; const fallbackGasPrices = getFallbackGasPrices(); - const ethPriceUnit = getEthPriceUnit(assets); + const ethPriceUnit = ethereumUtils.getEthPriceUnit(assets); const txFees = parseTxFees( fallbackGasPrices, ethPriceUnit, @@ -140,7 +135,7 @@ export const gasUpdateTxFee = (gasLimit, overrideGasOption) => ( if (isEmpty(gasPrices)) return; const { assets } = getState().data; const { nativeCurrency } = getState().settings; - const ethPriceUnit = getEthPriceUnit(assets); + const ethPriceUnit = ethereumUtils.getEthPriceUnit(assets); const txFees = parseTxFees( gasPrices, ethPriceUnit, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 2806d2d5f8a..d04e917a8ae 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -1,4 +1,5 @@ import { + getMarketDetails as getUniswapMarketDetails, tradeEthForExactTokensWithData, tradeExactEthForTokensWithData, tradeExactTokensForEthWithData, @@ -38,6 +39,7 @@ import { convertAmountToRawAmount, convertNumberToString, convertRawAmountToDecimalFormat, + divide, greaterThan, subtract, updatePrecisionToDisplay, @@ -634,6 +636,15 @@ class ExchangeModal extends Component { }); }; + getMarketPrice = () => { + const { allAssets, inputReserve } = this.props; + if (!inputReserve) return 0; + const ethPrice = ethereumUtils.getEthPriceUnit(allAssets); + const inputMarketDetails = getUniswapMarketDetails(undefined, inputReserve); + const assetToEthPrice = get(inputMarketDetails, 'marketRate.rate'); + return divide(ethPrice, assetToEthPrice) || 0; + }; + setInputAmount = (inputAmount, amountDisplay, inputAsExactAmount = true) => { this.setState(({ inputCurrency }) => { const newState = { @@ -649,7 +660,10 @@ class ExchangeModal extends Component { const isInputZero = parseFloat(inputAmount) === 0; if (inputAmount && !isInputZero) { - const nativePrice = get(inputCurrency, 'native.price.amount', 0); + let nativePrice = get(inputCurrency, 'native.price.amount', null); + if (isNil(nativePrice)) { + nativePrice = this.getMarketPrice(); + } nativeAmount = convertAmountToNativeAmount(inputAmount, nativePrice); } @@ -690,11 +704,14 @@ class ExchangeModal extends Component { const isNativeZero = parseFloat(nativeAmount) === 0; if (nativeAmount && !isNativeZero) { - const nativePrice = get(inputCurrency, 'native.price.amount', 0); + let nativePrice = get(inputCurrency, 'native.price.amount', null); + if (isNil(nativePrice)) { + nativePrice = this.getMarketPrice(); + } inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); inputAmountDisplay = updatePrecisionToDisplay( inputAmount, - get(inputCurrency, 'price.value'), + nativePrice, true ); } diff --git a/src/utils/ethereumUtils.js b/src/utils/ethereumUtils.js index 83feeacbeef..f72c5957a84 100644 --- a/src/utils/ethereumUtils.js +++ b/src/utils/ethereumUtils.js @@ -8,7 +8,12 @@ import { subtract, } from '../helpers/utilities'; -export const getBalanceAmount = (selectedGasPrice, selected) => { +const getEthPriceUnit = assets => { + const ethAsset = getAsset(assets); + return get(ethAsset, 'price.value', 0); +}; + +const getBalanceAmount = (selectedGasPrice, selected) => { let amount = ''; if (selected.address === 'eth') { const balanceAmount = get(selected, 'balance.amount', 0); @@ -22,7 +27,7 @@ export const getBalanceAmount = (selectedGasPrice, selected) => { return amount; }; -export const getAsset = (assets, address = 'eth') => +const getAsset = (assets, address = 'eth') => find(assets, asset => asset.address === address); /** @@ -30,7 +35,7 @@ export const getAsset = (assets, address = 'eth') => * @param {String} hex * @return {String} */ -export const removeHexPrefix = hex => replace(toLower(hex), '0x', ''); +const removeHexPrefix = hex => replace(toLower(hex), '0x', ''); /** * @desc pad string to specific width and padding @@ -39,7 +44,7 @@ export const removeHexPrefix = hex => replace(toLower(hex), '0x', ''); * @param {String} z * @return {String} */ -export const padLeft = (n, width, z) => { +const padLeft = (n, width, z) => { z = z || '0'; n = n + ''; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; @@ -51,7 +56,7 @@ export const padLeft = (n, width, z) => { * @param {Array} arrVals * @return {String} */ -export const getDataString = (func, arrVals) => { +const getDataString = (func, arrVals) => { let val = ''; for (let i = 0; i < arrVals.length; i++) val += padLeft(arrVals[i], 64); const data = func + val; @@ -62,7 +67,7 @@ export const getDataString = (func, arrVals) => { * @desc get network string from chainId * @param {Number} chainId */ -export const getNetworkFromChainId = chainId => { +const getNetworkFromChainId = chainId => { const networkData = find(chains, ['chain_id', chainId]); return get(networkData, 'network', 'mainnet'); }; @@ -71,7 +76,7 @@ export const getNetworkFromChainId = chainId => { * @desc get chainId from network string * @param {String} network */ -export const getChainIdFromNetwork = network => { +const getChainIdFromNetwork = network => { const chainData = find(chains, ['network', network]); return get(chainData, 'chain_id', 1); }; @@ -83,7 +88,7 @@ export const getChainIdFromNetwork = network => { * @param {String} gasPrice * @return {Object} ethereum, balanceAmount, balance, requestedAmount, txFeeAmount, txFee, amountWithFees */ -export const transactionData = (assets, assetAmount, gasPrice) => { +const transactionData = (assets, assetAmount, gasPrice) => { const ethereum = getAsset(assets); const balance = get(ethereum, 'balance.amount', 0); const requestedAmount = convertNumberToString(assetAmount); @@ -104,6 +109,7 @@ export default { getBalanceAmount, getChainIdFromNetwork, getDataString, + getEthPriceUnit, getNetworkFromChainId, removeHexPrefix, transactionData, From 8b621b5d1c35ed115a310f37dcb2d80f6681ee6f Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 11 Nov 2019 17:11:03 -0500 Subject: [PATCH 507/636] Fix: remove the use of multiRemove for uniswap clear data multiRemove is only available directly on AsyncStorage, not through the react-native-storage package we are using. We will use multiGet/multiRemove once we move over to the AsyncStorage package directly. --- src/handlers/localstorage/uniswap.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/handlers/localstorage/uniswap.js b/src/handlers/localstorage/uniswap.js index 4a7e0c89666..539ad21d435 100644 --- a/src/handlers/localstorage/uniswap.js +++ b/src/handlers/localstorage/uniswap.js @@ -1,9 +1,10 @@ +import { forEach } from 'lodash'; import { getAccountLocal, getGlobal, - removeAccountLocalMulti, saveAccountLocal, saveGlobal, + removeAccountLocal, } from './common'; const ASSETS = 'uniswapassets'; @@ -66,4 +67,6 @@ export const saveUniswapPendingApprovals = ( ); export const removeUniswapStorage = (accountAddress, network) => - removeAccountLocalMulti(uniswapAccountLocalKeys, accountAddress, network); + forEach(uniswapAccountLocalKeys, key => + removeAccountLocal(key, accountAddress, network) + ); From acd5171a2d65fe78476ffda95c557ffdd3cf7547 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 11 Nov 2019 17:13:49 -0500 Subject: [PATCH 508/636] Fix: upperFirst network in Settings Section --- src/components/settings-menu/SettingsSection.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index 2f223d6fb84..23287408750 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -1,3 +1,4 @@ +import { upperFirst } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { InteractionManager, Linking, ScrollView } from 'react-native'; @@ -88,7 +89,7 @@ const SettingsSection = ({ onPress={onPressNetwork} label="Network" > - {network || ''} + {upperFirst(network) || ''} } From d935b806039640b892f7f25518e19b3c346d5a2a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 21:43:11 -0500 Subject: [PATCH 509/636] fix camera-related crash --- ios/Podfile.lock | 56 ++++++++++++++++++++++++------------------------ package.json | 2 +- yarn.lock | 29 +++++++++++++++---------- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 41f51a737b4..c2e36f92e95 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -353,6 +353,8 @@ PODS: - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/callinvoker (= 1000.0.0) + - ReactNativePermissions (1.2.1): + - React - RNAnalytics (1.1.0): - Analytics - React @@ -383,8 +385,6 @@ PODS: - React - RNOS (1.1.0): - React - - RNPermissions (2.0.3): - - React - RNReactNativeHapticFeedback (1.8.2): - React - RNReanimated (1.3.0): @@ -457,6 +457,7 @@ DEPENDENCIES: - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - ReactNativePermissions (from `../node_modules/react-native-permissions`) - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" @@ -467,7 +468,6 @@ DEPENDENCIES: - RNKeychain (from `../node_modules/react-native-keychain`) - RNLanguages (from `../node_modules/react-native-languages`) - RNOS (from `../node_modules/react-native-os`) - - RNPermissions (from `../node_modules/react-native-permissions`) - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) @@ -574,6 +574,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/Vibration" ReactCommon: :path: "../node_modules/react-native/ReactCommon" + ReactNativePermissions: + :path: "../node_modules/react-native-permissions" RNAnalytics: :path: "../node_modules/@segment/analytics-react-native" RNCAsyncStorage: @@ -594,8 +596,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-languages" RNOS: :path: "../node_modules/react-native-os" - RNPermissions: - :path: "../node_modules/react-native-permissions" RNReactNativeHapticFeedback: :path: "../node_modules/react-native-haptic-feedback" RNReanimated: @@ -626,8 +626,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 5941a412090840d8454b63f5deddc334d3e66ec1 - FBReactNativeSpec: 4e760ee4050dfda7e234635346f0ee7ca47ada49 + FBLazyVector: 6995a031cc53166998f5a5be8c911f80d15fc54e + FBReactNativeSpec: 5f0c1480e8927323e856974124ec92ac5e9c67a7 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -643,15 +643,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 6cb19d0cdc3cdbd049f0f1d54d579ce45a2d18b3 - RCTTypeSafety: 72c13a219b3e3f767f17a0207ead9b91e34dda98 - React: e84718e1b6e37662a56676196e70cb548d5dc82d - React-Core: 410c225ed959c8b92bb0b6cf8e15269229e1bc4b - React-CoreModules: 178af3b46382139ec79adaab4d7df174aca8d708 - React-cxxreact: 9b691755a0958781dfef5c3e006c948eaa89896a - React-jsi: de7c2b3f5677ca946990fefae03b185b1b1a3cab - React-jsiexecutor: 6ba5c0957102f46bb59ae1da5aa0a39dc0471ea2 - React-jsinspector: 5f6f950665fe118bf09094c768f5e1585d6c9faf + RCTRequired: 0eccd1d7eebe9f16145e7f569918341acf4e0ab0 + RCTTypeSafety: 28d458ca465f9cc7d9401117b734713c8ac189a4 + React: 3f401a1e658dc120e908c0f96a2f7421b68ea02f + React-Core: 6687c721b36d2b1c59d2a8ee499d195249ee4bae + React-CoreModules: 0766028fa3c745e766436c3934944d73d00061ee + React-cxxreact: d7a2f3c762e255722eedd10b208cabc177b83e77 + React-jsi: 5d7c0879254a55e1c1b2008ac1577dea095161ed + React-jsiexecutor: 99f48e5668bf945a7880fc517e417d4a17d24d3b + React-jsinspector: a9257fe5aa63fe1b96ea44c259f8ec649c70f821 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -661,16 +661,17 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: c8458a9d0d7068c89b080dceb703c62409362b9c - React-RCTAnimation: 683d473651a4fe92dcfcfbe46cd97e737a2d9524 - React-RCTBlob: aad21f3f52f00d666fd4bba5e61b499ea973c768 - React-RCTImage: 4860c2ee02200535ff6c4b98d2335d5caa0a5361 - React-RCTLinking: da8550a85c729b7254a424d9bd2713c41af2a7a4 - React-RCTNetwork: c1369c792662ef2bf6a9654dda5d6fed553eacbd - React-RCTSettings: 360a138e20baa5123c3707cc06252db6c01066ce - React-RCTText: 6667febb3da7f709cd0661d3c3c5e3f50207e6b0 - React-RCTVibration: adfe01cff28981427aef496b578d1d63372b9efd - ReactCommon: 3e28aaf6de1505111189685989f4a5ebe6cc409c + React-RCTActionSheet: 50b5633059b5d964c36943add7d6e3190a860c2f + React-RCTAnimation: c738d8c0a6aaf80d08a0008aaba1c87d88042163 + React-RCTBlob: 929b1c40f6d46420490540ccb8e95c927a217531 + React-RCTImage: 9b635cc4d0e383ccb34223e97c026494d24235e9 + React-RCTLinking: 0ebc9a563d4771589327c738844831b72e52fe00 + React-RCTNetwork: 2d95f47b05d4b7837a913c2a2836aee1c8b7aea8 + React-RCTSettings: 24862bf02e84c1a3dbefd1e9c848f42a15ec690e + React-RCTText: a59ddb090b3765bccfbb43b45971116ba4656fdc + React-RCTVibration: 5dac153fc3da212887788e64b88a25d6d13974b7 + ReactCommon: fb664367bd019d02b0d62f711f2a6846d16a390c + ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 @@ -681,7 +682,6 @@ SPEC CHECKSUMS: RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a - RNPermissions: 9e437a90de84a5402ff689d4da233730b81556c2 RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1 RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 @@ -694,7 +694,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 03905d5f074f7f0bdb2d13b164010826bbeeeae6 + Yoga: 92ba1a29b0219c5e5ea7fcddda1fdff473753f5f PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/package.json b/package.json index 1e818fd6fa9..b0802092899 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "react-native-linear-gradient": "^2.5.6", "react-native-mail": "^4.1.0", "react-native-os": "icxcat/react-native-os#master", - "react-native-permissions": "^2.0.3", + "react-native-permissions": "^1.2.1", "react-native-qrcode-scanner": "mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e", "react-native-qrcode-svg": "git+https://github.com/mikedemarais/react-native-qrcode-svg.git", "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", diff --git a/yarn.lock b/yarn.lock index e7aa10d7d59..14cd34c7bbf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1790,6 +1790,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -9310,16 +9315,11 @@ react-native-os@icxcat/react-native-os#master: version "1.1.0" resolved "https://codeload.github.com/icxcat/react-native-os/tar.gz/1efb92b990fb4c02475fcc98a8260c3991c59b2d" -react-native-permissions@^1.1.1: +react-native-permissions@^1.1.1, react-native-permissions@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-1.2.1.tgz#cb1f6e53b8992b3912de5a4cfc1553ac2e82d0f6" integrity sha512-6NOGsA7EsuKT9hfULccQfMrsGmRhBkmN6Uv8nz2QObjEG87XtroQtw4Qi1+tAjIkSHawCeAMJp+SCtiXSGUD5Q== -react-native-permissions@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-2.0.3.tgz#b6da83e5e313e41ba5f70ff2c4567291766b0140" - integrity sha512-8pd+UhyphAiFGzBil5d5pDxRf/rH+20SzDNu9cFnCtoD2MbYTVH7GjXsxaZ2lPsmwrqYYbF8FBfwmncKf/G1+Q== - react-native-qrcode-scanner@mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e: version "1.0.1" resolved "https://codeload.github.com/mikedemarais/react-native-qrcode-scanner/tar.gz/2ca70b8c64afb87e712aba578e11409c6406069e" @@ -9460,7 +9460,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/58726cee8576af1beca23d02fb09c655ab3e1c84" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/8c63dd3b1a9008798f7a4432b1e1aec2f54a7eba" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" @@ -10822,13 +10822,13 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string-width@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff" - integrity sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ== + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" - strip-ansi "^5.2.0" + strip-ansi "^6.0.0" string.prototype.trimleft@^2.1.0: version "2.1.0" @@ -10896,6 +10896,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" From 3ffb1fd0c4e0b4057fc90ef1e5de59ff95e1f896 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 23:44:10 -0500 Subject: [PATCH 510/636] Revert "Revert "Change wallet init and keyboard in send"" --- src/components/SendComponentWithData.js | 2 +- .../animations/ButtonPressAnimation.js | 2 ++ .../contacts/SwipeableContactRow.js | 16 ++-------- src/components/fields/AddressField.js | 3 ++ src/components/fields/UnderlineField.js | 11 +++++++ src/components/send/SendContactList.js | 30 +++++++++++++++---- src/components/send/SendHeader.js | 23 +++++++++++--- src/components/text/ErrorText.js | 4 +-- src/hoc/withDataInit.js | 29 ++++++++++++++++-- src/hoc/withSelectedInput.js | 9 ++++++ src/redux/reducers.js | 2 ++ src/redux/selectedInput.js | 23 ++++++++++++++ src/screens/SendSheet.js | 6 ---- src/screens/WalletScreen.js | 24 --------------- 14 files changed, 126 insertions(+), 58 deletions(-) create mode 100644 src/hoc/withSelectedInput.js create mode 100644 src/redux/selectedInput.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js index f0d3aedfe56..b1e6e860db1 100644 --- a/src/components/SendComponentWithData.js +++ b/src/components/SendComponentWithData.js @@ -47,7 +47,7 @@ const mapStateToProps = ({ send, settings }) => ({ export const withSendComponentWithData = (SendComponent, options) => { class SendComponentWithData extends Component { static propTypes = { - accountType: PropTypes.string.isRequired, + accountType: PropTypes.string, address: PropTypes.string, assetAmount: PropTypes.string.isRequired, assets: PropTypes.array.isRequired, diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index be4b31ebfda..ca7cc2c34ed 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -150,6 +150,7 @@ export default class ButtonPressAnimation extends Component { }; createLongPressListener = () => { + this.longPressDetected = false; const { minLongPressDuration, onLongPress } = this.props; if (onLongPress) { this.longPressTimeout = setTimeout( @@ -176,6 +177,7 @@ export default class ButtonPressAnimation extends Component { handleDetectedLongPress = () => { this.longPressDetected = true; + clearTimeout(this.longPressTimeout); this.handleHaptic(); this.props.onLongPress(); }; diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index e4c09706c7f..440bc8bd7be 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -66,9 +66,9 @@ export default class SwipeableContactRow extends PureComponent { onPress: PropTypes.func, onTouch: PropTypes.func, onTransitionEnd: PropTypes.func, + selectedInputId: PropTypes.object, }; - isFocused = false; swipeableRef = undefined; close = () => this.swipeableRef.close(); @@ -84,19 +84,8 @@ export default class SwipeableContactRow extends PureComponent { }; handleEditContact = () => { - const { address, color, navigation, nickname, onChange } = this.props; - const refocusCallback = this.isFocused && this.props.inputRef.focus; - this.close(); - navigation.navigate('OverlayExpandedAssetScreen', { - address, - asset: [], - color, - contact: { address, color, nickname }, - onCloseModal: onChange, - onRefocusInput: refocusCallback, - type: 'contact', - }); + this.props.onSelectEdit(this.props); }; handleLongPress = () => this.swipeableRef.openRight(); @@ -105,7 +94,6 @@ export default class SwipeableContactRow extends PureComponent { handlePressStart = () => { this.props.onTouch(this.props.address); - this.isFocused = this.props.inputRef.isFocused(); }; handleRef = ref => { diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 4fb85f96fca..5f3bb476126 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -121,6 +121,9 @@ export default withNavigation( onBlur = () => { this.checkClipboard(this.state.address); + if (this.props.onBlur) { + this.props.onBlur(); + } }; checkClipboard = async address => { diff --git a/src/components/fields/UnderlineField.js b/src/components/fields/UnderlineField.js index d30492eee84..08367f05d3e 100644 --- a/src/components/fields/UnderlineField.js +++ b/src/components/fields/UnderlineField.js @@ -3,6 +3,8 @@ import React, { PureComponent } from 'react'; import styled from 'styled-components/primitives'; import { View } from 'react-native'; import Animated, { Easing } from 'react-native-reanimated'; +import { setSelectedInputId } from '../../redux/selectedInput'; +import store from '../../redux/store'; import { colors, position } from '../../styles'; import { Button } from '../buttons'; import { Input } from '../inputs'; @@ -78,6 +80,7 @@ export default class UnderlineField extends PureComponent { this.setState({ isFocused: false }); if (this.props.onBlur) this.props.onBlur(...props); + store.dispatch(setSelectedInputId(null)); }; onChange = event => { @@ -102,6 +105,13 @@ export default class UnderlineField extends PureComponent { this.setState({ isFocused: true }); if (this.props.onFocus) this.props.onFocus(...props); + if (this.input && this.input.isFocused()) { + store.dispatch(setSelectedInputId(this.input)); + } + }; + + handleRef = ref => { + this.input = ref; }; render() { @@ -135,6 +145,7 @@ export default class UnderlineField extends PureComponent { onChange={this.onChange} onFocus={this.onFocus} placeholder={placeholder} + ref={this.handleRef} size="h2" value={this.format(String(this.props.value || ''))} /> diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index a6de3c7394d..110fcf1f708 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -6,10 +6,12 @@ import { RecyclerListView, } from 'recyclerlistview'; import { withNavigation } from 'react-navigation'; +import { compose } from 'recompose'; +import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; +import withSelectedInput from '../../hoc/withSelectedInput'; +import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { deviceUtils } from '../../utils'; import { FlyInAnimation } from '../animations'; -import { sheetVerticalOffset } from '../../navigation/transitions/effects'; -import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; import { SwipeableContactRow } from '../contacts'; import SendEmptyState from './SendEmptyState'; @@ -27,7 +29,8 @@ class SendContactList extends Component { currentInput: PropTypes.string, navigation: PropTypes.object, onPressContact: PropTypes.func, - onUpdateContacts: PropTypes.array, + onUpdateContacts: PropTypes.func, + selectedInputId: PropTypes.object, }; constructor(args) { @@ -84,7 +87,7 @@ class SendContactList extends Component { }; closeAllDifferentContacts = address => { - if (this.touchedContact) { + if (this.touchedContact && this.contacts[this.touchedContact]) { this.contacts[this.touchedContact].close(); } this.touchedContact = address; @@ -134,12 +137,29 @@ class SendContactList extends Component { return false; }; + onSelectEdit = accountInfo => { + const { address, color, navigation, nickname, onChange } = accountInfo; + const refocusCallback = + this.props.selectedInputId && this.props.selectedInputId.focus; + + navigation.navigate('OverlayExpandedAssetScreen', { + address, + asset: [], + color, + contact: { address, color, nickname }, + onCloseModal: onChange, + onRefocusInput: refocusCallback, + type: 'contact', + }); + }; + renderItem = (type, item) => ( { this.contacts[item.address] = component; @@ -169,4 +189,4 @@ class SendContactList extends Component { ); } -export default withNavigation(SendContactList); +export default compose(withSelectedInput, withNavigation)(SendContactList); diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 1f1e8ce7b70..28c4e9f9e8e 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -6,7 +6,9 @@ import { Keyboard, Clipboard } from 'react-native'; import { withNavigation } from 'react-navigation'; import { compose, withProps } from 'recompact'; import { deleteLocalContact } from '../../handlers/localstorage/contacts'; -import { withNeverRerender } from '../../hoc'; +import { withNeverRerender, withSelectedInput } from '../../hoc'; +import { setSelectedInputId } from '../../redux/selectedInput'; +import store from '../../redux/store'; import { colors, padding } from '../../styles'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { AddContactButton, PasteAddressButton } from '../buttons'; @@ -87,6 +89,7 @@ class SendHeader extends PureComponent { onPressPaste: PropTypes.func, onUpdateContacts: PropTypes.func, recipient: PropTypes.string, + selectedInputId: PropTypes.object, }; handleConfirmDeleteContactSelection = async buttonIndex => { @@ -110,7 +113,9 @@ class SendHeader extends PureComponent { navigateToContact = (contact = {}) => { const { navigation, onUpdateContacts, recipient } = this.props; - const refocusCallback = this.input.isFocused() && this.input.focus; + const refocusCallback = + this.props.selectedInputId.isFocused() && + this.props.selectedInputId.focus; let color = get(contact, 'color'); if (!isNumber(color)) { @@ -134,7 +139,14 @@ class SendHeader extends PureComponent { handleRef = ref => { this.input = ref; - this.props.inputRef(ref); + }; + + onFocus = () => { + store.dispatch(setSelectedInputId(this.input)); + }; + + onBlur = () => { + store.dispatch(setSelectedInputId(null)); }; render = () => { @@ -157,9 +169,11 @@ class SendHeader extends PureComponent { address={recipient} autoFocus currentContact={contact} + inputRef={this.handleRef} name={contact.nickname} + onBlur={this.onBlur} onChange={onChangeAddressInput} - inputRef={this.handleRef} + onFocus={this.onFocus} /> {isValidAddress && ( ( - + {error} diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index fc09a63b796..a13641c0c4d 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -3,7 +3,12 @@ import { isNil } from 'lodash'; import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { compose, withHandlers } from 'recompact'; -import { getIsWalletEmpty } from '../handlers/localstorage/accountLocal'; +import { + getIsWalletEmpty, + getOpenFamilies, + getOpenInvestmentCards, + getSmallBalanceToggle, +} from '../handlers/localstorage/accountLocal'; import { hasEthBalance } from '../handlers/web3'; import { dataClearState, dataLoadState } from '../redux/data'; import { explorerClearState, explorerInit } from '../redux/explorer'; @@ -11,8 +16,9 @@ import { gasClearState, gasPricesInit } from '../redux/gas'; import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; -import { clearOpenFamilyTab } from '../redux/openFamilyTabs'; +import { clearOpenFamilyTab, pushOpenFamilyTab } from '../redux/openFamilyTabs'; import { requestsLoadState, requestsClearState } from '../redux/requests'; + import { settingsLoadState, settingsUpdateAccountAddress, @@ -36,6 +42,10 @@ import { walletConnectLoadState, walletConnectClearState, } from '../redux/walletconnect'; +import { setOpenSmallBalances } from '../redux/openBalances'; + +import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; +import store from '../redux/store'; import { promiseUtils } from '../utils'; import withHideSplashScreen from './withHideSplashScreen'; @@ -136,6 +146,17 @@ export default Component => throw error; } }, + setInitialStatesForOpenAssets: () => async (walletAddress, network) => { + const toggle = await getSmallBalanceToggle(walletAddress, network); + const openInvestmentCards = await getOpenInvestmentCards( + walletAddress, + network + ); + const openFamilies = await getOpenFamilies(walletAddress, network); + await store.dispatch(setOpenSmallBalances(toggle)); + await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); + await store.dispatch(pushOpenFamilyTab(openFamilies)); + }, }), withHandlers({ initializeWallet: ownProps => async seedPhrase => { @@ -149,6 +170,10 @@ export default Component => ); return null; } + await ownProps.setInitialStatesForOpenAssets( + walletAddress, + ownProps.network + ); if (isImported) { await ownProps.clearAccountData(); } diff --git a/src/hoc/withSelectedInput.js b/src/hoc/withSelectedInput.js new file mode 100644 index 00000000000..f657b6a6c8a --- /dev/null +++ b/src/hoc/withSelectedInput.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import { setSelectedInputId } from '../redux/selectedInput'; + +const mapStateToProps = ({ selectedInput: { selectedInputId } }) => ({ + selectedInputId, +}); + +export default Component => + connect(mapStateToProps, { setSelectedInputId })(Component); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index c4ac6f4faa8..5d51d9d7008 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -15,6 +15,7 @@ import openBalances from './openBalances'; import openFamilyTabs from './openFamilyTabs'; import openInvestmentCards from './openInvestmentCards'; import requests from './requests'; +import selectedInput from './selectedInput'; import selectedWithFab from './selectedWithFab'; import send from './send'; import settings from './settings'; @@ -38,6 +39,7 @@ export default combineReducers({ openFamilyTabs, openInvestmentCards, requests, + selectedInput, selectedWithFab, send, settings, diff --git a/src/redux/selectedInput.js b/src/redux/selectedInput.js new file mode 100644 index 00000000000..0ed76ec4a49 --- /dev/null +++ b/src/redux/selectedInput.js @@ -0,0 +1,23 @@ +import produce from 'immer'; + +// -- Constants --------------------------------------- // +const SET_SELECTED_INPUT_ID = 'openBalances/SET_SELECTED_INPUT_ID'; + +export const setSelectedInputId = payload => dispatch => { + dispatch({ + payload, + type: SET_SELECTED_INPUT_ID, + }); +}; + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + selectedInputId: null, +}; + +export default (state = INITIAL_STATE, action) => + produce(state, draft => { + if (action.type === SET_SELECTED_INPUT_ID) { + draft.selectedInputId = action.payload; + } + }); diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 7c86932fd1a..cbd532bbd3a 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -217,10 +217,6 @@ class SendSheet extends Component { this.props.sendUpdateRecipient(event); }; - handleRef = ref => { - this.input = ref; - }; - render() { const { allAssets, @@ -244,7 +240,6 @@ class SendSheet extends Component { diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 57216d9b909..c1570e84065 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -12,11 +12,6 @@ import { ProfileHeaderButton, } from '../components/header'; import { Page } from '../components/layout'; -import { - getOpenFamilies, - getOpenInvestmentCards, - getSmallBalanceToggle, -} from '../handlers/localstorage/accountLocal'; import buildWalletSectionsSelector from '../helpers/buildWalletSections'; import { withAccountData, @@ -28,10 +23,6 @@ import { withUniqueTokens, withUniswapLiquidityTokenInfo, } from '../hoc'; -import { setOpenSmallBalances } from '../redux/openBalances'; -import { pushOpenFamilyTab } from '../redux/openFamilyTabs'; -import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; -import store from '../redux/store'; import { position } from '../styles'; import { isNewValueForObjectPaths } from '../utils'; @@ -57,7 +48,6 @@ class WalletScreen extends Component { componentDidMount = async () => { try { await this.props.initializeWallet(); - await this.setInitialStatesForOpenAssets(); } catch (error) { // TODO error state } @@ -76,20 +66,6 @@ class WalletScreen extends Component { 'sections', ]); - setInitialStatesForOpenAssets = async () => { - const { accountAddress, network } = this.props; - const toggle = await getSmallBalanceToggle(accountAddress, network); - const openInvestmentCards = await getOpenInvestmentCards( - accountAddress, - network - ); - const openFamilies = await getOpenFamilies(accountAddress, network); - await store.dispatch(setOpenSmallBalances(toggle)); - await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); - await store.dispatch(pushOpenFamilyTab(openFamilies)); - return true; - }; - render = () => { const { isEmpty, From fb76496de4f326e1163aaba838fe616cc2a3cf27 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 23:48:55 -0500 Subject: [PATCH 511/636] fix wojtec code --- src/components/send/SendContactList.js | 2 +- src/components/send/SendHeader.js | 11 +++-------- src/components/send/index.js | 2 ++ src/hoc/index.js | 1 + src/redux/selectedInput.js | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 110fcf1f708..4c4e19fc6ea 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -8,7 +8,7 @@ import { import { withNavigation } from 'react-navigation'; import { compose } from 'recompose'; import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; -import withSelectedInput from '../../hoc/withSelectedInput'; +import { withSelectedInput } from '../../hoc'; import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { deviceUtils } from '../../utils'; import { FlyInAnimation } from '../animations'; diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 28c4e9f9e8e..758f24d31ec 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -7,8 +7,6 @@ import { withNavigation } from 'react-navigation'; import { compose, withProps } from 'recompact'; import { deleteLocalContact } from '../../handlers/localstorage/contacts'; import { withNeverRerender, withSelectedInput } from '../../hoc'; -import { setSelectedInputId } from '../../redux/selectedInput'; -import store from '../../redux/store'; import { colors, padding } from '../../styles'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; import { AddContactButton, PasteAddressButton } from '../buttons'; @@ -90,6 +88,7 @@ class SendHeader extends PureComponent { onUpdateContacts: PropTypes.func, recipient: PropTypes.string, selectedInputId: PropTypes.object, + setSelectedInputId: PropTypes.func, }; handleConfirmDeleteContactSelection = async buttonIndex => { @@ -141,13 +140,9 @@ class SendHeader extends PureComponent { this.input = ref; }; - onFocus = () => { - store.dispatch(setSelectedInputId(this.input)); - }; + onFocus = () => this.props.setSelectedInputId(this.input); - onBlur = () => { - store.dispatch(setSelectedInputId(null)); - }; + onBlur = () => this.props.setSelectedInputId(null); render = () => { const { diff --git a/src/components/send/index.js b/src/components/send/index.js index 3d0e15d1b51..89c34394065 100644 --- a/src/components/send/index.js +++ b/src/components/send/index.js @@ -1,5 +1,7 @@ export { default as SendAssetForm } from './SendAssetForm'; +export { default as SendAssetFormCollectible } from './SendAssetFormCollectible'; export { default as SendAssetFormField } from './SendAssetFormField'; +export { default as SendAssetFormToken } from './SendAssetFormToken'; export { default as SendAssetList } from './SendAssetList'; export { default as SendButton } from './SendButton'; export { default as SendContactList } from './SendContactList'; diff --git a/src/hoc/index.js b/src/hoc/index.js index bef5076ea5e..5c77e3ca374 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -26,6 +26,7 @@ export { default as withOpenBalances } from './withOpenBalances'; export { default as withRequests } from './withRequests'; export { default as withRotationForDirection } from './withRotationForDirection'; export { default as withSafeAreaViewInsetValues } from './withSafeAreaViewInsetValues'; +export { default as withSelectedInput } from './withSelectedInput'; export { default as withSendFeedback } from './withSendFeedback'; export { default as withStatusBarStyle } from './withStatusBarStyle'; export { default as withTransactionConfirmationScreen } from './withTransactionConfirmationScreen'; diff --git a/src/redux/selectedInput.js b/src/redux/selectedInput.js index 0ed76ec4a49..821d17ecc68 100644 --- a/src/redux/selectedInput.js +++ b/src/redux/selectedInput.js @@ -1,7 +1,7 @@ import produce from 'immer'; // -- Constants --------------------------------------- // -const SET_SELECTED_INPUT_ID = 'openBalances/SET_SELECTED_INPUT_ID'; +const SET_SELECTED_INPUT_ID = 'selectedInput/SET_SELECTED_INPUT_ID'; export const setSelectedInputId = payload => dispatch => { dispatch({ From 479075b6946856405d31c0676f0199e0639c97f2 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 11 Nov 2019 23:49:15 -0500 Subject: [PATCH 512/636] bump lock files --- ios/Podfile.lock | 44 ++++++++++++++++++++++---------------------- yarn.lock | 18 +++++++++--------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c2e36f92e95..f19f7eff4c2 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -626,8 +626,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 6995a031cc53166998f5a5be8c911f80d15fc54e - FBReactNativeSpec: 5f0c1480e8927323e856974124ec92ac5e9c67a7 + FBLazyVector: 210b3eaff713673bf7d6bb43e41153ff91262431 + FBReactNativeSpec: b78f09a9b711428a445e77b633c96291005be7a1 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -643,15 +643,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 0eccd1d7eebe9f16145e7f569918341acf4e0ab0 - RCTTypeSafety: 28d458ca465f9cc7d9401117b734713c8ac189a4 - React: 3f401a1e658dc120e908c0f96a2f7421b68ea02f - React-Core: 6687c721b36d2b1c59d2a8ee499d195249ee4bae - React-CoreModules: 0766028fa3c745e766436c3934944d73d00061ee - React-cxxreact: d7a2f3c762e255722eedd10b208cabc177b83e77 - React-jsi: 5d7c0879254a55e1c1b2008ac1577dea095161ed - React-jsiexecutor: 99f48e5668bf945a7880fc517e417d4a17d24d3b - React-jsinspector: a9257fe5aa63fe1b96ea44c259f8ec649c70f821 + RCTRequired: ee4195302dc3f8a69dd0208deb1ac4521639f236 + RCTTypeSafety: 7fd7b22d06920927cf362b0cd45b3ae41c508728 + React: fb5f888af23fd5ea0b15beaa339a2aa48cd7505f + React-Core: 86ac27467597319d5e3845ee016b9d4fe6e2b9ee + React-CoreModules: b9211dff9f5b58e187a41aa57b8210ade6906846 + React-cxxreact: 815ae7adcaa6f83c9a14120202882b3e0fc551dc + React-jsi: 3df445e3ca2abf4176f11880c0cbbe3928215a08 + React-jsiexecutor: 7eb566c1d783a74a81f38148ed59b663c89a804c + React-jsinspector: 66138c3ee67dd1fdec84c58072b86430e2268b5f react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -661,16 +661,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 50b5633059b5d964c36943add7d6e3190a860c2f - React-RCTAnimation: c738d8c0a6aaf80d08a0008aaba1c87d88042163 - React-RCTBlob: 929b1c40f6d46420490540ccb8e95c927a217531 - React-RCTImage: 9b635cc4d0e383ccb34223e97c026494d24235e9 - React-RCTLinking: 0ebc9a563d4771589327c738844831b72e52fe00 - React-RCTNetwork: 2d95f47b05d4b7837a913c2a2836aee1c8b7aea8 - React-RCTSettings: 24862bf02e84c1a3dbefd1e9c848f42a15ec690e - React-RCTText: a59ddb090b3765bccfbb43b45971116ba4656fdc - React-RCTVibration: 5dac153fc3da212887788e64b88a25d6d13974b7 - ReactCommon: fb664367bd019d02b0d62f711f2a6846d16a390c + React-RCTActionSheet: a1ef62eebe8c9d61d00ccce86f4bdf050c80a0ef + React-RCTAnimation: 5442181d0b3100a53eb1135c318659b1baa03a25 + React-RCTBlob: 8e7beeb14dd9f4f25b10622cfb24f19cb123259d + React-RCTImage: 00f1c6e1c99f795dbc01425da43d8628f678b7ee + React-RCTLinking: 0d2288627f79fff0c4fd3cec800ae776b3e41197 + React-RCTNetwork: 666ce399bc8a36e65fc51bc8bee787b8f0e07f4b + React-RCTSettings: c6e57cdc13eb6b46adca74463f462e3f448b63ed + React-RCTText: 2118cedfd39f0f11b865ef7345b132e77d5526f6 + React-RCTVibration: 31dbba8d9e21ea73a34e0239b8b7fc0d3615df6f + ReactCommon: 7e9df6ab843723ae92083170f6221391626b7df8 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -694,7 +694,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 92ba1a29b0219c5e5ea7fcddda1fdff473753f5f + Yoga: a3c2c5dfb24cd30eb3207b2c1808901f287ed319 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/yarn.lock b/yarn.lock index 14cd34c7bbf..0d98da2402b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5175,10 +5175,10 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-engine@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" - integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== +hermes-engine@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.3.0.tgz#c03ded211102eef775045a5f55e286783db8ad48" + integrity sha512-Xl21n/FohkoeQyz/9AeisoePhXaLvXRyT41xkYHOrqoNr+pkLUGc1xIo486ctIxSp5SN4BkN6T3YFWOdD0ntaQ== hmac-drbg@^1.0.0: version "1.0.1" @@ -5288,9 +5288,9 @@ husky@^2.4.0: slash "^3.0.0" i18n-js@^3.0.11: - version "3.3.0" - resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.3.0.tgz#05512f7184b5117c087ab597be649720a834c068" - integrity sha512-+m8jh84IIWlFwEJgwrWCkeIwIES9ilJKBOj5qx8ZTLLmlPz7bjKnCdxf254wRf6M4pkQHtgXGT9r9lGk0e9aug== + version "3.5.0" + resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.0.tgz#e2c41e1f90405d691d33ddce260f3dff9743215e" + integrity sha512-XosH7plfEisWo5XEYxkdlwONsDVQ3sYI3ZoKXcjXdyq+9eVNIJg2h2oPsgadfqcXxpPHMVMNBgmiyW3aEJXg1g== i18next@^17.0.3: version "17.3.1" @@ -9460,7 +9460,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/8c63dd3b1a9008798f7a4432b1e1aec2f54a7eba" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/8e750d75eedfe4f9465c98b9a28d1b6279257dc0" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" @@ -9475,7 +9475,7 @@ react-native@facebook/react-native: event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermes-engine "^0.2.1" + hermes-engine "~0.3.0" invariant "^2.2.4" jsc-android "^245459.0.0" metro-babel-register "0.57.0" From 0712762455cda4879fe28656af09730c407ee652 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 12 Nov 2019 00:05:18 -0500 Subject: [PATCH 513/636] update ethereum utils tests --- src/utils/__tests__/ethereumUtils.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/__tests__/ethereumUtils.test.js b/src/utils/__tests__/ethereumUtils.test.js index 578be29045f..639c4002b75 100644 --- a/src/utils/__tests__/ethereumUtils.test.js +++ b/src/utils/__tests__/ethereumUtils.test.js @@ -1,4 +1,4 @@ -import { getBalanceAmount } from '../ethereumUtils'; +import ethereumUtils from '../ethereumUtils'; const gasPrice = { txFee: { @@ -13,7 +13,7 @@ it('getBalanceAmountEth', () => { address: 'eth', balance: { amount: '1' }, }; - const updatedBalance = getBalanceAmount(gasPrice, selected); + const updatedBalance = ethereumUtils.getBalanceAmount(gasPrice, selected); expect(updatedBalance).toBe('0.999999999999979'); }); @@ -22,7 +22,7 @@ it('getBalanceAmountInsufficientEth', () => { address: 'eth', balance: { amount: '0.00000000000000001' }, }; - const updatedBalance = getBalanceAmount(gasPrice, selected); + const updatedBalance = ethereumUtils.getBalanceAmount(gasPrice, selected); expect(updatedBalance).toBe('0'); }); @@ -31,6 +31,6 @@ it('getBalanceAmountToken', () => { address: '0x12345', balance: { amount: '1' }, }; - const updatedBalance = getBalanceAmount(gasPrice, selected); + const updatedBalance = ethereumUtils.getBalanceAmount(gasPrice, selected); expect(updatedBalance).toBe('1'); }); From ee6c4fb40c1de060be09e3c7c69fc154060bb64c Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 12 Nov 2019 00:14:59 -0500 Subject: [PATCH 514/636] Fix focus state on asset selection and get input currency from state instead of props --- src/screens/ExchangeModal.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index d04e917a8ae..c2f16147773 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -146,11 +146,7 @@ class ExchangeModal extends Component { 'slippage', ]); - if (this.props.isFocused && nextProps.isFocused) { - return isNewProps || isNewState; - } - - return false; + return isNewProps || isNewState; }; componentDidUpdate = (prevProps, prevState) => { @@ -207,7 +203,7 @@ class ExchangeModal extends Component { if ( removedFromPending || - isNewValueForPath(this.props, prevProps, inputCurrencyAddressPath) + isNewValueForPath(this.state, prevState, inputCurrencyAddressPath) ) { this.getCurrencyAllowance(); } From 8c9007c5e81e87746b9c90c1f15aa4374e7e2975 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 11 Nov 2019 18:43:14 -0500 Subject: [PATCH 515/636] consolidate wallet open state settings --- src/hoc/withDataInit.js | 48 +++------- src/hoc/withOpenBalances.js | 4 +- src/hoc/withOpenFamilyTabs.js | 7 +- src/hoc/withOpenInvestmentCards.js | 4 +- src/redux/openBalances.js | 26 ------ src/redux/openFamilyTabs.js | 48 ---------- src/redux/openInvestmentCards.js | 42 --------- src/redux/openStateSettings.js | 137 +++++++++++++++++++++++++++++ src/redux/reducers.js | 8 +- 9 files changed, 162 insertions(+), 162 deletions(-) delete mode 100644 src/redux/openBalances.js delete mode 100644 src/redux/openFamilyTabs.js delete mode 100644 src/redux/openInvestmentCards.js create mode 100644 src/redux/openStateSettings.js diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index a13641c0c4d..8d43fda89f6 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -3,22 +3,20 @@ import { isNil } from 'lodash'; import { Alert } from 'react-native'; import { connect } from 'react-redux'; import { compose, withHandlers } from 'recompact'; -import { - getIsWalletEmpty, - getOpenFamilies, - getOpenInvestmentCards, - getSmallBalanceToggle, -} from '../handlers/localstorage/accountLocal'; +import { getIsWalletEmpty } from '../handlers/localstorage/accountLocal'; import { hasEthBalance } from '../handlers/web3'; +import { walletInit } from '../model/wallet'; import { dataClearState, dataLoadState } from '../redux/data'; import { explorerClearState, explorerInit } from '../redux/explorer'; import { gasClearState, gasPricesInit } from '../redux/gas'; import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; -import { clearOpenFamilyTab, pushOpenFamilyTab } from '../redux/openFamilyTabs'; +import { + clearOpenStateSettings, + openStateSettingsLoadState, +} from '../redux/openStateSettings'; import { requestsLoadState, requestsClearState } from '../redux/requests'; - import { settingsLoadState, settingsUpdateAccountAddress, @@ -33,19 +31,14 @@ import { uniqueTokensLoadState, uniqueTokensRefreshState, } from '../redux/uniqueTokens'; -import { - web3ListenerClearState, - web3ListenerInit, -} from '../redux/web3listener'; -import { walletInit } from '../model/wallet'; import { walletConnectLoadState, walletConnectClearState, } from '../redux/walletconnect'; -import { setOpenSmallBalances } from '../redux/openBalances'; - -import { pushOpenInvestmentCard } from '../redux/openInvestmentCards'; -import store from '../redux/store'; +import { + web3ListenerClearState, + web3ListenerInit, +} from '../redux/web3listener'; import { promiseUtils } from '../utils'; import withHideSplashScreen from './withHideSplashScreen'; @@ -53,7 +46,7 @@ export default Component => compose( connect(null, { clearIsWalletEmpty, - clearOpenFamilyTab, + clearOpenStateSettings, dataClearState, dataLoadState, explorerClearState, @@ -61,6 +54,7 @@ export default Component => gasClearState, gasPricesInit, nonceClearState, + openStateSettingsLoadState, requestsClearState, requestsLoadState, setIsWalletEthZero, @@ -92,7 +86,7 @@ export default Component => const p1 = ownProps.dataClearState(); const p2 = ownProps.clearIsWalletEmpty(); const p3 = ownProps.uniqueTokensClearState(); - const p4 = ownProps.clearOpenFamilyTab(); + const p4 = ownProps.clearOpenStateSettings(); const p5 = ownProps.walletConnectClearState(); const p6 = ownProps.nonceClearState(); const p7 = ownProps.requestsClearState(); @@ -123,6 +117,7 @@ export default Component => } }, loadAccountData: ownProps => async () => { + await ownProps.openStateSettingsLoadState(); const p1 = ownProps.settingsLoadState(); const p2 = ownProps.dataLoadState(); const p3 = ownProps.uniqueTokensLoadState(); @@ -146,17 +141,6 @@ export default Component => throw error; } }, - setInitialStatesForOpenAssets: () => async (walletAddress, network) => { - const toggle = await getSmallBalanceToggle(walletAddress, network); - const openInvestmentCards = await getOpenInvestmentCards( - walletAddress, - network - ); - const openFamilies = await getOpenFamilies(walletAddress, network); - await store.dispatch(setOpenSmallBalances(toggle)); - await store.dispatch(pushOpenInvestmentCard(openInvestmentCards)); - await store.dispatch(pushOpenFamilyTab(openFamilies)); - }, }), withHandlers({ initializeWallet: ownProps => async seedPhrase => { @@ -170,10 +154,6 @@ export default Component => ); return null; } - await ownProps.setInitialStatesForOpenAssets( - walletAddress, - ownProps.network - ); if (isImported) { await ownProps.clearAccountData(); } diff --git a/src/hoc/withOpenBalances.js b/src/hoc/withOpenBalances.js index 437a0d6ef8a..ec47eba04bb 100644 --- a/src/hoc/withOpenBalances.js +++ b/src/hoc/withOpenBalances.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; -import { setOpenSmallBalances } from '../redux/openBalances'; +import { setOpenSmallBalances } from '../redux/openStateSettings'; -const mapStateToProps = ({ openBalances: { openSmallBalances } }) => ({ +const mapStateToProps = ({ openStateSettings: { openSmallBalances } }) => ({ openSmallBalances, }); diff --git a/src/hoc/withOpenFamilyTabs.js b/src/hoc/withOpenFamilyTabs.js index 4c9551b8593..7cf706bfde2 100644 --- a/src/hoc/withOpenFamilyTabs.js +++ b/src/hoc/withOpenFamilyTabs.js @@ -1,7 +1,10 @@ import { connect } from 'react-redux'; -import { pushOpenFamilyTab, setOpenFamilyTabs } from '../redux/openFamilyTabs'; +import { + pushOpenFamilyTab, + setOpenFamilyTabs, +} from '../redux/openStateSettings'; -const mapStateToProps = ({ openFamilyTabs: { openFamilyTabs } }) => ({ +const mapStateToProps = ({ openStateSettings: { openFamilyTabs } }) => ({ openFamilyTabs, }); diff --git a/src/hoc/withOpenInvestmentCards.js b/src/hoc/withOpenInvestmentCards.js index f6e87b4e48a..456a3f9e5c9 100644 --- a/src/hoc/withOpenInvestmentCards.js +++ b/src/hoc/withOpenInvestmentCards.js @@ -2,9 +2,9 @@ import { connect } from 'react-redux'; import { pushOpenInvestmentCard, setOpenInvestmentCards, -} from '../redux/openInvestmentCards'; +} from '../redux/openStateSettings'; -const mapStateToProps = ({ openInvestmentCards: { openInvestmentCards } }) => ({ +const mapStateToProps = ({ openStateSettings: { openInvestmentCards } }) => ({ openInvestmentCards, }); diff --git a/src/redux/openBalances.js b/src/redux/openBalances.js deleted file mode 100644 index 87f446b2212..00000000000 --- a/src/redux/openBalances.js +++ /dev/null @@ -1,26 +0,0 @@ -import produce from 'immer'; -import { saveSmallBalanceToggle } from '../handlers/localstorage/accountLocal'; - -// -- Constants --------------------------------------- // -const SET_OPEN_SMALL_BALANCES = 'openBalances/SET_OPEN_SMALL_BALANCES'; - -export const setOpenSmallBalances = payload => (dispatch, getState) => { - const { accountAddress, network } = getState().settings; - saveSmallBalanceToggle(payload, accountAddress, network); - dispatch({ - payload, - type: SET_OPEN_SMALL_BALANCES, - }); -}; - -// -- Reducer ----------------------------------------- // -const INITIAL_STATE = { - openSmallBalances: false, -}; - -export default (state = INITIAL_STATE, action) => - produce(state, draft => { - if (action.type === SET_OPEN_SMALL_BALANCES) { - draft.openSmallBalances = action.payload; - } - }); diff --git a/src/redux/openFamilyTabs.js b/src/redux/openFamilyTabs.js deleted file mode 100644 index 8ac00b1d18b..00000000000 --- a/src/redux/openFamilyTabs.js +++ /dev/null @@ -1,48 +0,0 @@ -import produce from 'immer'; -import { saveOpenFamilies } from '../handlers/localstorage/accountLocal'; - -// -- Constants --------------------------------------- // -const CLEAR_OPEN_FAMILY_TAB = 'openFamilyTabs/CLEAR_OPEN_FAMILY_TAB'; -const PUSH_OPEN_FAMILY_TAB = 'openFamilyTabs/PUSH_OPEN_FAMILY_TAB'; -const SET_OPEN_FAMILY_TABS = 'openFamilyTabs/SET_OPEN_FAMILY_TABS'; - -export const clearOpenFamilyTab = () => dispatch => - dispatch({ - type: CLEAR_OPEN_FAMILY_TAB, - }); - -export const pushOpenFamilyTab = payload => dispatch => - dispatch({ - payload, - type: PUSH_OPEN_FAMILY_TAB, - }); - -export const setOpenFamilyTabs = payload => (dispatch, getState) => { - const { accountAddress, network } = getState().settings; - const { openFamilyTabs } = getState().openFamilyTabs; - const updatedFamilyTabs = { - ...openFamilyTabs, - [payload.index]: payload.state, - }; - saveOpenFamilies(updatedFamilyTabs, accountAddress, network); - dispatch({ - payload: updatedFamilyTabs, - type: SET_OPEN_FAMILY_TABS, - }); -}; - -// -- Reducer ----------------------------------------- // -const INITIAL_STATE = { - openFamilyTabs: {}, -}; - -export default (state = INITIAL_STATE, action) => - produce(state, draft => { - if (action.type === SET_OPEN_FAMILY_TABS) { - draft.openFamilyTabs = action.payload; - } else if (action.type === PUSH_OPEN_FAMILY_TAB) { - draft.openFamilyTabs = action.payload; - } else if (action.type === CLEAR_OPEN_FAMILY_TAB) { - return INITIAL_STATE; - } - }); diff --git a/src/redux/openInvestmentCards.js b/src/redux/openInvestmentCards.js deleted file mode 100644 index 34ad62c0260..00000000000 --- a/src/redux/openInvestmentCards.js +++ /dev/null @@ -1,42 +0,0 @@ -import produce from 'immer'; -import { saveOpenInvestmentCards } from '../handlers/localstorage/accountLocal'; - -// -- Constants --------------------------------------- // -const SET_OPEN_INVESTMENT_CARDS = - 'openInvestmentCards/SET_OPEN_INVESTMENT_CARDS'; -const PUSH_OPEN_INVESTMENT_CARD = - 'openInvestmentCards/PUSH_OPEN_INVESTMENT_CARD'; - -export const setOpenInvestmentCards = payload => (dispatch, getState) => { - const { accountAddress, network } = getState().settings; - const { openInvestmentCards } = getState().openInvestmentCards; - const updatedOpenInvestmentCards = { - ...openInvestmentCards, - [payload.index]: payload.state, - }; - saveOpenInvestmentCards(updatedOpenInvestmentCards, accountAddress, network); - dispatch({ - payload: updatedOpenInvestmentCards, - type: SET_OPEN_INVESTMENT_CARDS, - }); -}; - -export const pushOpenInvestmentCard = payload => dispatch => - dispatch({ - payload, - type: PUSH_OPEN_INVESTMENT_CARD, - }); - -// -- Reducer ----------------------------------------- // -const INITIAL_STATE = { - openInvestmentCards: {}, -}; - -export default (state = INITIAL_STATE, action) => - produce(state, draft => { - if (action.type === SET_OPEN_INVESTMENT_CARDS) { - draft.openInvestmentCards = action.payload; - } else if (action.type === PUSH_OPEN_INVESTMENT_CARD) { - draft.openInvestmentCards = action.payload; - } - }); diff --git a/src/redux/openStateSettings.js b/src/redux/openStateSettings.js new file mode 100644 index 00000000000..6735da3f588 --- /dev/null +++ b/src/redux/openStateSettings.js @@ -0,0 +1,137 @@ +import produce from 'immer'; +import { + getOpenFamilies, + getOpenInvestmentCards, + getSmallBalanceToggle, + saveOpenFamilies, + saveOpenInvestmentCards, + saveSmallBalanceToggle, + removeOpenFamilies, + removeOpenInvestmentCards, + removeSmallBalanceToggle, +} from '../handlers/localstorage/accountLocal'; + +// -- Constants ------------------------------------------------------------- // +const OPEN_STATE_SETTINGS_LOAD_SUCCESS = + 'openStateSettings/OPEN_STATE_SETTINGS_LOAD_SUCCESS'; +const OPEN_STATE_SETTINGS_LOAD_FAILURE = + 'openStateSettings/OPEN_STATE_SETTINGS_LOAD_FAILURE'; +const CLEAR_OPEN_STATE_SETTINGS = 'openStateSettings/CLEAR_OPEN_STATE_SETTINGS'; +const PUSH_OPEN_FAMILY_TAB = 'openStateSettings/PUSH_OPEN_FAMILY_TAB'; +const SET_OPEN_FAMILY_TABS = 'openStateSettings/SET_OPEN_FAMILY_TABS'; +const SET_OPEN_SMALL_BALANCES = 'openStateSettings/SET_OPEN_SMALL_BALANCES'; +const SET_OPEN_INVESTMENT_CARDS = 'openStateSettings/SET_OPEN_INVESTMENT_CARDS'; +const PUSH_OPEN_INVESTMENT_CARD = 'openStateSettings/PUSH_OPEN_INVESTMENT_CARD'; + +// -- Actions --------------------------------------------------------------- // +export const openStateSettingsLoadState = () => async (dispatch, getState) => { + try { + const { accountAddress, network } = getState().settings; + const openSmallBalances = await getSmallBalanceToggle( + accountAddress, + network + ); + const openInvestmentCards = await getOpenInvestmentCards( + accountAddress, + network + ); + const openFamilyTabs = await getOpenFamilies(accountAddress, network); + dispatch({ + payload: { + openFamilyTabs, + openInvestmentCards, + openSmallBalances, + }, + type: OPEN_STATE_SETTINGS_LOAD_SUCCESS, + }); + } catch (error) { + dispatch({ type: OPEN_STATE_SETTINGS_LOAD_FAILURE }); + } +}; + +export const setOpenSmallBalances = payload => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + saveSmallBalanceToggle(payload, accountAddress, network); + dispatch({ + payload, + type: SET_OPEN_SMALL_BALANCES, + }); +}; + +export const pushOpenFamilyTab = payload => dispatch => + dispatch({ + payload, + type: PUSH_OPEN_FAMILY_TAB, + }); + +export const setOpenFamilyTabs = payload => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + const { openFamilyTabs } = getState().openStateSettings; + const updatedFamilyTabs = { + ...openFamilyTabs, + [payload.index]: payload.state, + }; + saveOpenFamilies(updatedFamilyTabs, accountAddress, network); + dispatch({ + payload: updatedFamilyTabs, + type: SET_OPEN_FAMILY_TABS, + }); +}; + +export const setOpenInvestmentCards = payload => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + const { openInvestmentCards } = getState().openStateSettings; + const updatedOpenInvestmentCards = { + ...openInvestmentCards, + [payload.index]: payload.state, + }; + saveOpenInvestmentCards(updatedOpenInvestmentCards, accountAddress, network); + dispatch({ + payload: updatedOpenInvestmentCards, + type: SET_OPEN_INVESTMENT_CARDS, + }); +}; + +export const pushOpenInvestmentCard = payload => dispatch => + dispatch({ + payload, + type: PUSH_OPEN_INVESTMENT_CARD, + }); + +export const clearOpenStateSettings = () => (dispatch, getState) => { + const { accountAddress, network } = getState().settings; + removeOpenFamilies(accountAddress, network); + removeOpenInvestmentCards(accountAddress, network); + removeSmallBalanceToggle(accountAddress, network); + dispatch({ + type: CLEAR_OPEN_STATE_SETTINGS, + }); +}; + +// -- Reducer --------------------------------------------------------------- // +export const INITIAL_STATE = { + openFamilyTabs: {}, + openInvestmentCards: {}, + openSmallBalances: false, +}; + +export default (state = INITIAL_STATE, action) => + produce(state, draft => { + if (action.type === OPEN_STATE_SETTINGS_LOAD_SUCCESS) { + draft.openFamilyTabs = action.payload.openFamilyTabs; + draft.openInvestmentCards = action.payload.openInvestmentCards; + draft.openSmallBalances = action.payload.openSmallBalances; + } else if (action.type === SET_OPEN_FAMILY_TABS) { + draft.openFamilyTabs = action.payload; + } else if (action.type === PUSH_OPEN_FAMILY_TAB) { + draft.openFamilyTabs = action.payload; + } else if (action.type === SET_OPEN_SMALL_BALANCES) { + draft.openSmallBalances = action.payload; + } else if (action.type === SET_OPEN_INVESTMENT_CARDS) { + draft.openInvestmentCards = action.payload; + } else if (action.type === PUSH_OPEN_INVESTMENT_CARD) { + draft.openInvestmentCards = action.payload; + } else if (action.type === CLEAR_OPEN_STATE_SETTINGS) { + return INITIAL_STATE; + } + }); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 5d51d9d7008..6450535b461 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -11,9 +11,7 @@ import isWalletImporting from './isWalletImporting'; import keyboardHeight from './keyboardHeight'; import navigation from './navigation'; import nonce from './nonce'; -import openBalances from './openBalances'; -import openFamilyTabs from './openFamilyTabs'; -import openInvestmentCards from './openInvestmentCards'; +import openStateSettings from './openStateSettings'; import requests from './requests'; import selectedInput from './selectedInput'; import selectedWithFab from './selectedWithFab'; @@ -35,9 +33,7 @@ export default combineReducers({ keyboardHeight, navigation, nonce, - openBalances, - openFamilyTabs, - openInvestmentCards, + openStateSettings, requests, selectedInput, selectedWithFab, From 5d638920437828eb25a628f865a0f115f9764933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Osadnik?= Date: Wed, 13 Nov 2019 12:18:03 +0100 Subject: [PATCH 516/636] Fix outstanding issues (#229) --- src/screens/ExchangeModal.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index c2f16147773..0841e2e4554 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -188,7 +188,6 @@ class ExchangeModal extends Component { isNewNativeAmount || isNewOutputReserveCurrency ) { - LayoutAnimation.easeInEaseOut(); this.getMarketDetails(isNewOutputReserveCurrency); } @@ -609,12 +608,9 @@ class ExchangeModal extends Component { }; handleKeyboardManagement = () => { - if (!this.lastFocusedInput) { - return this.inputFieldRef.focus(); - } - if (this.lastFocusedInput !== TextInput.State.currentlyFocusedField()) { - return TextInput.State.focusTextInput(this.lastFocusedInput); + TextInput.State.focusTextInput(this.lastFocusedInput); + this.lastFocusedInput = null; } }; From 0159cff24fa80897ff51491b8cadbf476cbfbc23 Mon Sep 17 00:00:00 2001 From: osdnk Date: Wed, 13 Nov 2019 13:10:52 +0100 Subject: [PATCH 517/636] Fix building in release mode --- ios/Rainbow.xcodeproj/project.pbxproj | 12 ++++++------ src/screens/ExchangeModal.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 96740298191..6c3d0491e35 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -22,7 +22,6 @@ 1B1113DAF261410889D80146 /* SF-Pro-Display-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2AEF0207B9724FE5A27519FF /* SF-Pro-Display-Medium.otf */; }; 216C17A836F44ACE8D79ACC7 /* SF-Pro-Display-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */; }; 23320186D7F747FEB02451C6 /* SF-Pro-Text-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */; }; - 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; }; 24979E8920F84250007EB0DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24979E7720F84004007EB0DA /* GoogleService-Info.plist */; }; 26095B12C30047F89592D463 /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */; }; 2D7BB74FB1A44EE2A2426373 /* SF-Pro-Text-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = E672AB1C5404435897615660 /* SF-Pro-Text-Light.otf */; }; @@ -42,6 +41,8 @@ 5D1949044DCB413FBE7AE82E /* SFMono-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */; }; 5F34DEED060F41878C4C5A59 /* SFMono-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */; }; 66620AB752074CB6938E956A /* Graphik-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */; }; + 66CA6CFE237C27E200C8E3D6 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66CA6CFD237C27E200C8E3D6 /* InputMask.framework */; }; + 66CA6CFF237C27E200C8E3D6 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66CA6CFD237C27E200C8E3D6 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; @@ -64,7 +65,6 @@ C66451ECC2944B439E123CF2 /* SF-Pro-Display-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */; }; CAD3BF43528D47159190E17B /* SF-Pro-Display-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */; }; CB988C526B0C48FC9750A038 /* SF-Pro-Display-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */; }; - D6A5F5CB2369A22A009BEF29 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 24122D53232F2B3200BA0B17 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; DBBDEB86E54044EE8712C882 /* Graphik-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEC826911B5641B8AF788BB3 /* Graphik-BlackItalic.otf */; }; E98BBF45029948B38545996F /* Graphik-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = E6F010E529544E518E1792C7 /* Graphik-Bold.otf */; }; ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; }; @@ -90,7 +90,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D6A5F5CB2369A22A009BEF29 /* InputMask.framework in Embed Frameworks */, + 66CA6CFF237C27E200C8E3D6 /* InputMask.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -115,7 +115,6 @@ 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-RegularItalic.otf"; path = "../src/assets/fonts/Graphik-RegularItalic.otf"; sourceTree = ""; }; 1DEDF110038147A598C9B152 /* SF-Pro-Text-HeavyItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-HeavyItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-HeavyItalic.otf"; sourceTree = ""; }; 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Heavy.otf"; path = "../src/assets/fonts/SF-Pro-Text-Heavy.otf"; sourceTree = ""; }; - 24122D53232F2B3200BA0B17 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24979E3620F84003007EB0DA /* Protobuf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Protobuf.framework; path = Frameworks/Protobuf.framework; sourceTree = ""; }; 24979E7420F84004007EB0DA /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 24979E7520F84004007EB0DA /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/FirebaseCore.framework; sourceTree = ""; }; @@ -152,6 +151,7 @@ 662C7FD632C1481AB5AB1DB7 /* SF-Pro-Display-Thin.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Thin.otf"; path = "../src/assets/fonts/SF-Pro-Display-Thin.otf"; sourceTree = ""; }; 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Medium.otf"; path = "../src/assets/fonts/SFMono-Medium.otf"; sourceTree = ""; }; 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; + 66CA6CFD237C27E200C8E3D6 /* InputMask.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InputMask.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 715DAAA3174542BAB93807A6 /* SF-Pro-Text-RegularItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-RegularItalic.otf"; path = "../src/assets/fonts/SF-Pro-Text-RegularItalic.otf"; sourceTree = ""; }; 7818F79CD3944D17AF4196A5 /* Graphik-Black.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Black.otf"; path = "../src/assets/fonts/Graphik-Black.otf"; sourceTree = ""; }; @@ -206,9 +206,9 @@ buildActionMask = 2147483647; files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, - 24122D54232F2B3200BA0B17 /* InputMask.framework in Frameworks */, 0E56AA9A8843EB50FA4BDD4F /* libPods-Rainbow.a in Frameworks */, 3D5D4DF2FD7C44EE962100E3 /* libRNTextInputMask.a in Frameworks */, + 66CA6CFE237C27E200C8E3D6 /* InputMask.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -263,6 +263,7 @@ children = ( 66139B432368A9AE0097D1D5 /* libRNFirebase.a */, 6613987F23689A430097D1D5 /* libReact-Core.a */, + 66CA6CFD237C27E200C8E3D6 /* InputMask.framework */, 6613988123689A430097D1D5 /* libReact-CoreModules.a */, 6613988323689A430097D1D5 /* libReact-cxxreact.a */, 6613988523689A430097D1D5 /* libReact-jsi.a */, @@ -301,7 +302,6 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( - 24122D53232F2B3200BA0B17 /* InputMask.framework */, 13B07FAE1A68108700A75B9A /* Rainbow */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* RainbowTests */, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 0841e2e4554..6a58126da64 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -11,7 +11,7 @@ import BigNumber from 'bignumber.js'; import { get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; -import { LayoutAnimation, TextInput } from 'react-native'; +import { TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; import { withNavigationFocus, NavigationEvents } from 'react-navigation'; import { compose, toClass, withProps } from 'recompact'; From b00b62b6c29ba5db63fcc18c259839adb9241f68 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 14 Nov 2019 22:44:35 -0500 Subject: [PATCH 518/636] Update swap token icons Fixes RAI-43 https://linear.app/issue/RAI-43 --- ios/Podfile.lock | 70 ++++++++++++++-------------- package.json | 2 +- src/components/coin-icon/CoinIcon.js | 19 +++++++- yarn.lock | 47 ++++++++----------- 4 files changed, 72 insertions(+), 66 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f19f7eff4c2..b2b7dd41620 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -72,23 +72,23 @@ PODS: - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (~> 0.3) - - GoogleUtilities/AppDelegateSwizzler (6.3.1): + - GoogleUtilities/AppDelegateSwizzler (6.3.2): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.3.1) - - GoogleUtilities/Logger (6.3.1): + - GoogleUtilities/Environment (6.3.2) + - GoogleUtilities/Logger (6.3.2): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.3.1): + - GoogleUtilities/MethodSwizzler (6.3.2): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.3.1): + - GoogleUtilities/Network (6.3.2): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.3.1)" - - GoogleUtilities/Reachability (6.3.1): + - "GoogleUtilities/NSData+zlib (6.3.2)" + - GoogleUtilities/Reachability (6.3.2): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.3.1): + - GoogleUtilities/UserDefaults (6.3.2): - GoogleUtilities/Logger - JWT (3.0.0-beta.12): - Base64 (~> 1.1.2) @@ -395,9 +395,9 @@ PODS: - React - RNSVG (9.13.3): - React - - SDWebImage (5.2.5): - - SDWebImage/Core (= 5.2.5) - - SDWebImage/Core (5.2.5) + - SDWebImage (5.3.1): + - SDWebImage/Core (= 5.3.1) + - SDWebImage/Core (5.3.1) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) @@ -626,8 +626,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 210b3eaff713673bf7d6bb43e41153ff91262431 - FBReactNativeSpec: b78f09a9b711428a445e77b633c96291005be7a1 + FBLazyVector: 3c557c904906a16efd29521a04b9c8686de38216 + FBReactNativeSpec: bb037bdd0a297cd978fd11975b8cda0221343096 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -638,20 +638,20 @@ SPEC CHECKSUMS: Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleAppMeasurement: 51d8d9ea48f0ca44484d29cfbdef976fbd4fc336 - GoogleUtilities: f895fde57977df4e0233edda0dbeac490e3703b6 + GoogleUtilities: 547a86735c6f0ee30ad17e94df4fc21f616b71cb JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: ee4195302dc3f8a69dd0208deb1ac4521639f236 - RCTTypeSafety: 7fd7b22d06920927cf362b0cd45b3ae41c508728 - React: fb5f888af23fd5ea0b15beaa339a2aa48cd7505f - React-Core: 86ac27467597319d5e3845ee016b9d4fe6e2b9ee - React-CoreModules: b9211dff9f5b58e187a41aa57b8210ade6906846 - React-cxxreact: 815ae7adcaa6f83c9a14120202882b3e0fc551dc - React-jsi: 3df445e3ca2abf4176f11880c0cbbe3928215a08 - React-jsiexecutor: 7eb566c1d783a74a81f38148ed59b663c89a804c - React-jsinspector: 66138c3ee67dd1fdec84c58072b86430e2268b5f + RCTRequired: 76dea74f39053c5ece421aa68faaed99a520c656 + RCTTypeSafety: fae97c41dc0718e0e8740e23bf85954f6fe76439 + React: 3e13f51327ef94d700388926efe74e5a14534f01 + React-Core: 011eb66a79cb131c892245abd3c6653786f83986 + React-CoreModules: 43f39f48f79c34224f34f9739690f714332920d2 + React-cxxreact: f6449f6c2cb07c16d95da7fbb95064102bf504c5 + React-jsi: 4cde0e89436d3180ce5c983265ded2fdc4e9fdee + React-jsiexecutor: 8540f256c210050c239b40a22d488bd7b0a7da83 + React-jsinspector: 13b657970778a2cf6f58ccc182a962f8ada9752c react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -661,16 +661,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: a1ef62eebe8c9d61d00ccce86f4bdf050c80a0ef - React-RCTAnimation: 5442181d0b3100a53eb1135c318659b1baa03a25 - React-RCTBlob: 8e7beeb14dd9f4f25b10622cfb24f19cb123259d - React-RCTImage: 00f1c6e1c99f795dbc01425da43d8628f678b7ee - React-RCTLinking: 0d2288627f79fff0c4fd3cec800ae776b3e41197 - React-RCTNetwork: 666ce399bc8a36e65fc51bc8bee787b8f0e07f4b - React-RCTSettings: c6e57cdc13eb6b46adca74463f462e3f448b63ed - React-RCTText: 2118cedfd39f0f11b865ef7345b132e77d5526f6 - React-RCTVibration: 31dbba8d9e21ea73a34e0239b8b7fc0d3615df6f - ReactCommon: 7e9df6ab843723ae92083170f6221391626b7df8 + React-RCTActionSheet: ad2d234b166eac167ea5a72b8520b2e75b969e4b + React-RCTAnimation: 6cc6b1474c06bbb5708d81d5aa7de8bf82d2e7c9 + React-RCTBlob: fcf733fa6359ec947e7aa03654eeb123e42dc3aa + React-RCTImage: 7471a0a6e56e9a073408de2c2840867ef9776b6a + React-RCTLinking: ca63cc48b51a3794422d136fa8884b951ff28c7f + React-RCTNetwork: fb1a0e9e2b06e7f9aeb514e9e603b0b4f24247bd + React-RCTSettings: d7c2320b334e47aad1f187c91efa17b11cf71253 + React-RCTText: 70172eebbfe602d187dacd4b2be3ba1f4ddd1426 + React-RCTVibration: 0e2697e1d9ecf96d37bb16979fe4f938e4b29c48 + ReactCommon: 60447eea63cfb8b0449773f141790b694312149c ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -687,14 +687,14 @@ SPEC CHECKSUMS: RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c - SDWebImage: 4eabf2fa6695c95c47724214417a9c036c965e4a + SDWebImage: 7137d57385fb632129838c1e6ab9528a22c666cc SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: a3c2c5dfb24cd30eb3207b2c1808901f287ed319 + Yoga: a2dc4dfcc1202c437e48b62cc35a782216508c76 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/package.json b/package.json index b0802092899..799ae8a3eae 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "punycode": "^1.4.1", "querystring-es3": "^0.2.1", "react": "16.11.0", - "react-coin-icon": "^0.1.9", + "react-coin-icon": "0.1.12", "react-fast-compare": "^2.0.4", "react-native": "facebook/react-native", "react-native-actionsheet": "^2.4.2", diff --git a/src/components/coin-icon/CoinIcon.js b/src/components/coin-icon/CoinIcon.js index 9152d7bc087..b207167117b 100644 --- a/src/components/coin-icon/CoinIcon.js +++ b/src/components/coin-icon/CoinIcon.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { css } from 'styled-components/primitives'; import ReactCoinIcon, { FallbackIcon } from 'react-coin-icon'; -import { onlyUpdateForKeys } from 'recompact'; +import { compose, withProps, onlyUpdateForKeys } from 'recompact'; import { borders, colors, fonts } from '../../styles'; import { ShadowStack } from '../shadow-stack'; @@ -21,7 +21,22 @@ const CoinIconFallback = fallbackProps => ( /> ); -const enhance = onlyUpdateForKeys(['bgColor', 'symbol']); +const enhance = compose( + onlyUpdateForKeys(['bgColor', 'symbol']), + withProps(({ symbol }) => { + let symbolOverride = symbol; + + if (symbol === 'POA20') { + symbolOverride = 'POA'; + } else if (typeof symbol === 'string' && symbol.includes('*')) { + symbolOverride = symbol.replace(/[*]/g, ''); + } + + return { + symbol: symbolOverride, + }; + }) +); const CoinIcon = enhance(({ bgColor, showShadow, size, symbol, ...props }) => showShadow ? ( diff --git a/yarn.lock b/yarn.lock index 0d98da2402b..5cab9f71867 100644 --- a/yarn.lock +++ b/yarn.lock @@ -669,13 +669,6 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@emotion/is-prop-valid@^0.7.3": - version "0.7.3" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz#a6bf4fa5387cbba59d44e698a4680f481a8da6cc" - integrity sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA== - dependencies: - "@emotion/memoize" "0.7.1" - "@emotion/is-prop-valid@^0.8.1": version "0.8.5" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz#2dda0791f0eafa12b7a0a5b39858405cc7bde983" @@ -683,11 +676,6 @@ dependencies: "@emotion/memoize" "0.7.3" -"@emotion/memoize@0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f" - integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg== - "@emotion/memoize@0.7.3": version "0.7.3" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78" @@ -9112,14 +9100,14 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-coin-icon@^0.1.9: - version "0.1.9" - resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.9.tgz#20d4ec2361ce74a756188df728d0f7b55f0f412b" - integrity sha512-M62K8YHDUh1byPqNs4SHYpHbW/6z13PC5NlqIIZ35lErYJzJwZmFJkkii+RsameLjiGaButGic/ydlEM4tEYNQ== +react-coin-icon@0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.12.tgz#27468537670ef374506f95e0e30d340e49ef1c8c" + integrity sha512-EkF3r35Si9cevjXyQcDJFkw1zK2h9ctSV5NiFyucdMsZLdd9DefnR2ji8BKVg/X0bOKsrRXhqa7b15SsXImLOw== dependencies: "@svgr/cli" "^4.3.0" lodash "^4.17.11" - styled-components "4.3.1" + styled-components "4.4.1" react-deep-force-update@^1.0.0: version "1.1.2" @@ -9146,9 +9134,9 @@ react-fast-compare@^2.0.4: integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: - version "16.11.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" - integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== + version "16.12.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" + integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: version "3.0.4" @@ -10938,13 +10926,14 @@ style-search@^0.1.0: resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI= -styled-components@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.3.1.tgz#18c3709f4ed9d582cd206b1acd8b758a211dd114" - integrity sha512-04XKQFFSEx3qTeN5I4kiSeajrwG6juDMw2+vUgvfxeXFegE40TuPKS4fFey8RJP1Ii1AoVQVUOglrdUUey0ZHw== +styled-components@4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.4.1.tgz#e0631e889f01db67df4de576fedaca463f05c2f2" + integrity sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g== dependencies: "@babel/helper-module-imports" "^7.0.0" - "@emotion/is-prop-valid" "^0.7.3" + "@babel/traverse" "^7.0.0" + "@emotion/is-prop-valid" "^0.8.1" "@emotion/unitless" "^0.7.0" babel-plugin-styled-components ">= 1" css-to-react-native "^2.2.2" @@ -11706,9 +11695,11 @@ use-memo-one@^1.1.1: integrity sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ== use-subscription@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.2.0.tgz#2a6789ef2cb9c5d78990a728a28630673e82f709" - integrity sha512-gbBH3zEoZycCJBisWzRkZ9IjwlWys2udleYkkNYTZYLhKRwLQbzh2ZbHXzKDvgFyim0WN/ROpp2Z1AF8wiT7zA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.3.0.tgz#3df13a798e826c8d462899423293289a3362e4e6" + integrity sha512-buZV7FUtnbOr+65dN7PHK7chHhQGfk/yjgqfpRLoWuHIAc4klAD/rdot2FsPNtFthN1ZydvA8tR/mWBMQ+/fDQ== + dependencies: + object-assign "^4.1.1" use@^3.1.0: version "3.1.1" From 0b808a4d25c349e87b342cf028629b6c1a34eb1c Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Thu, 14 Nov 2019 19:52:08 -0500 Subject: [PATCH 519/636] Fix stars showing up on unfavorited items Fixes RAI-69 https://linear.app/issue/RAI-69 --- ios/Podfile.lock | 44 ++-- src/components/coin-row/ExchangeCoinRow.js | 19 +- src/components/exchange/ExchangeAssetList.js | 5 +- src/screens/CurrencySelectModal.js | 8 + yarn.lock | 224 ++++++++++++------- 5 files changed, 183 insertions(+), 117 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b2b7dd41620..bb699f271e7 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -626,8 +626,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 3c557c904906a16efd29521a04b9c8686de38216 - FBReactNativeSpec: bb037bdd0a297cd978fd11975b8cda0221343096 + FBLazyVector: ecca54884bcbca6e0bf6aa4bb0609500fba2a454 + FBReactNativeSpec: 3ee351f778656ddd4ef4b419093f26d57561b5b6 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -643,15 +643,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 76dea74f39053c5ece421aa68faaed99a520c656 - RCTTypeSafety: fae97c41dc0718e0e8740e23bf85954f6fe76439 - React: 3e13f51327ef94d700388926efe74e5a14534f01 - React-Core: 011eb66a79cb131c892245abd3c6653786f83986 - React-CoreModules: 43f39f48f79c34224f34f9739690f714332920d2 - React-cxxreact: f6449f6c2cb07c16d95da7fbb95064102bf504c5 - React-jsi: 4cde0e89436d3180ce5c983265ded2fdc4e9fdee - React-jsiexecutor: 8540f256c210050c239b40a22d488bd7b0a7da83 - React-jsinspector: 13b657970778a2cf6f58ccc182a962f8ada9752c + RCTRequired: ed682a2cdbada65027cdce7342872ce7be2f148e + RCTTypeSafety: 9c323eae031754761a1dc916be0fb94cd8329b4f + React: 1526e91cf6dc1ff05e161f4a62ec6d3889cd93a5 + React-Core: 0117ccd0135b08ef1c56f61e7e94d49ac2f8cc7b + React-CoreModules: 8bc81b4dcf1b06cf8e767b677e0d310bdc3a9107 + React-cxxreact: b2ccf2c2933c908227a4db3a4119dbbda0298451 + React-jsi: 8e4c76f69519c8d46e5a3226c02bce233a78dadd + React-jsiexecutor: 09c4f112dc5eff1f573a28c5efc20ce7df180da1 + React-jsinspector: 9ad8aea3c889b71231586a8e8e379f48df4f45a8 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -661,16 +661,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: ad2d234b166eac167ea5a72b8520b2e75b969e4b - React-RCTAnimation: 6cc6b1474c06bbb5708d81d5aa7de8bf82d2e7c9 - React-RCTBlob: fcf733fa6359ec947e7aa03654eeb123e42dc3aa - React-RCTImage: 7471a0a6e56e9a073408de2c2840867ef9776b6a - React-RCTLinking: ca63cc48b51a3794422d136fa8884b951ff28c7f - React-RCTNetwork: fb1a0e9e2b06e7f9aeb514e9e603b0b4f24247bd - React-RCTSettings: d7c2320b334e47aad1f187c91efa17b11cf71253 - React-RCTText: 70172eebbfe602d187dacd4b2be3ba1f4ddd1426 - React-RCTVibration: 0e2697e1d9ecf96d37bb16979fe4f938e4b29c48 - ReactCommon: 60447eea63cfb8b0449773f141790b694312149c + React-RCTActionSheet: 35b3f73f7587592b438d6af1ee5af1e43af9c15b + React-RCTAnimation: 0c346a402613834c2d9793376ffe6c008ea7c2fa + React-RCTBlob: ec3861d7b98c10264a20acd0cfe49eb6eb15579b + React-RCTImage: 8efea8d879fb7df7f66d3c73ff3feea56f971d35 + React-RCTLinking: 4336a93575f08057563f534d0c1d38592d2c0bde + React-RCTNetwork: df79caf75da2b392cb0c8e6b086f642adca403bc + React-RCTSettings: 34cc2696bde255d3cb00ac79f8719a4ae3ff9775 + React-RCTText: 4e236748059b67d3abf84d1b70f79b6cf4a182c8 + React-RCTVibration: a63c67ec9eadeddec5e8371c56ac9071e9c93a4c + ReactCommon: 7bc590509e40483bd7bb975456060ab270f0d0bf ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -694,7 +694,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: a2dc4dfcc1202c437e48b62cc35a782216508c76 + Yoga: b225f4ec22178cb062530328d7733d1f20d5516b PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index e53b22da5ba..9d1e5c0d437 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -1,3 +1,4 @@ +import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { connect } from 'react-redux'; @@ -58,12 +59,16 @@ class ExchangeCoinRow extends Component { }; state = { - favorite: !!this.props.item.favorite, + localFavorite: false, }; shouldComponentUpdate = (nextProps, nextState) => { const isNewAsset = isNewValueForPath(this.props, nextProps, 'uniqueId'); - const isNewFavorite = isNewValueForPath(this.state, nextState, 'favorite'); + const isNewFavorite = isNewValueForPath( + this.state, + nextState, + 'localFavorite' + ); return isNewAsset || isNewFavorite; }; @@ -77,9 +82,9 @@ class ExchangeCoinRow extends Component { toggleFavorite = () => { const { item, uniswapUpdateFavorites } = this.props; this.setState(prevState => { - const favorite = !prevState.favorite; - uniswapUpdateFavorites(item.address, favorite); - return { favorite }; + const localFavorite = !prevState.localFavorite; + uniswapUpdateFavorites(item.address, localFavorite); + return { localFavorite }; }); }; @@ -91,7 +96,7 @@ class ExchangeCoinRow extends Component { uniqueId, ...props } = this.props; - const { favorite } = this.state; + const { localFavorite } = this.state; return ( {showFavoriteButton && ( )} diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index 309de5a7839..7ef48e4dac5 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -7,7 +7,7 @@ import { LayoutProvider, RecyclerListView, } from 'recyclerlistview'; -import { deviceUtils, isNewValueForPath } from '../../utils'; +import { deviceUtils, isNewValueForObjectPaths } from '../../utils'; import { colors } from '../../styles'; import { CoinRow } from '../coin-row'; @@ -30,7 +30,8 @@ const layoutItemAnimator = { const getLayoutTypeForIndex = () => ViewTypes.COIN_ROW; -const hasRowChanged = (r1, r2) => isNewValueForPath(r1, r2, 'uniqueId'); +const hasRowChanged = (r1, r2) => + isNewValueForObjectPaths(r1, r2, ['favorite', 'uniqueId']); const setLayoutForType = (type, dim) => { if (type === ViewTypes.COIN_ROW) { diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 29e5c697d11..611f831e44f 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -130,6 +130,7 @@ class CurrencySelectModal extends Component { render = () => { const { assetsAvailableOnUniswap, + favorites, isFocused, sortedUniswapAssets, transitionPosition, @@ -145,6 +146,13 @@ class CurrencySelectModal extends Component { assets = assetsAvailableOnUniswap; } else if (type === CurrencySelectionTypes.output) { headerTitle = 'Receive'; + + if (Array.isArray(favorites) && favorites.length) { + assets = assets.map(asset => ({ + ...asset, + favorite: favorites.includes(asset.address), + })); + } } const listItems = filterList(assets, searchQuery, 'uniqueId'); diff --git a/yarn.lock b/yarn.lock index 5cab9f71867..e168ece3dfe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1350,6 +1350,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -1530,37 +1535,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -"@walletconnect/core@^1.0.0-beta.38": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.38.tgz#4716cfa87a58b707b274dbbb0601868512207ab6" - integrity sha512-fJfiK2oAWlGCCh7ULjq7fVnGsnn7/TnLsQTAzt5TwmHQ0YsZ595UYnuux4rr93IyvjIIcKkI6WMQKvcw1t/y4A== +"@walletconnect/core@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.39.tgz#43d05dbabcaeea491c0ee213ed60d2236672010f" + integrity sha512-cJSQe2Ao4okSvohNjA7Bs7Z+0BAznfVVTWBECIX/bGoSFpkAWabGY2Pn2gIYhobQMLSFpE6ZlZ4QfvlPO8HyPw== dependencies: - "@walletconnect/types" "^1.0.0-beta.38" - "@walletconnect/utils" "^1.0.0-beta.38" + "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/utils" "^1.0.0-beta.39" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.38.tgz#cbba526ebfa2ba7ce0d5496e3f1556222fba1544" - integrity sha512-rQ0ZYfcA7R4i4px3EEjSzCyHa4IswVn8642/rLxJbdgd/xXV7qW1+wjYoOdLPyEGLGUX5ojIC0e6yba3Q3y2gA== + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.39.tgz#0db212eba9087055822a89bf73d1cebc5762639e" + integrity sha512-d/QAjL/Rp1lrJeblsHpl+Fa6HTz40A93X5l6oTV0YFAG7bZDPl+OogM337WnjZWfwcn1XaKXSwsmG1NXTQn4Yg== dependencies: - "@walletconnect/core" "^1.0.0-beta.38" - "@walletconnect/types" "^1.0.0-beta.38" - "@walletconnect/utils" "^1.0.0-beta.38" + "@walletconnect/core" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/utils" "^1.0.0-beta.39" -"@walletconnect/types@^1.0.0-beta.38": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.38.tgz#6f6e23511d6821723767df18be395e52f406e6a7" - integrity sha512-155J5SXBio6Vo2zDP3ijvSmfCIJS5jp7A0bIJ+z1RAG0yG+nevCW1yLTevyRNT8U7mJSjKI/HkmjzZuW1ATiLQ== +"@walletconnect/types@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.39.tgz#e84463f32d6c450376db3d0ce56f0ece6608bfa7" + integrity sha512-YO/g1HVnFxcMNiUI9LEWEDe5uVHw8D7JzJol+bT71iXymzolnsbG32OayCJM9nHqT48Rpz1EGIno8EjW9jH2OQ== -"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.38": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.38.tgz#6755367bc7d9f7811f87464f636aa4f41aded36e" - integrity sha512-4esXDexo8w8QDsw3Ng378pjK88EBMVmbeYYfdWmCazKHDNmActJkVYAQtIeHFOAOG2OAAZ6IYt6fWvuw8jaPbg== +"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.39.tgz#8909b9cffa3999b046ce32cbb21b8ddca97b9183" + integrity sha512-AOlhPkK+IUzGG5iDTupKdUwNW4on1aAj5NyLMMN1+htr06hqaCV8F9HeYibSen22wdSUuLXkIQNy3SR3LPcehA== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.38" + "@walletconnect/types" "^1.0.0-beta.39" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1574,9 +1579,9 @@ Base64@~0.2.0: integrity sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg= abab@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.2.tgz#a2fba1b122c69a85caa02d10f9270c7219709a9d" - integrity sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== abbrev@1: version "1.1.1" @@ -1795,6 +1800,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" + integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -2648,9 +2661,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006: - version "1.0.30001008" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz#b8841b1df78a9f5ed9702537ef592f1f8772c0d9" - integrity sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw== + version "1.0.30001010" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz#397a14034d384260453cc81994f494626d34b938" + integrity sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw== capture-exit@^2.0.0: version "2.0.0" @@ -2694,6 +2707,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" @@ -2932,11 +2953,23 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" @@ -3076,7 +3109,7 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -3383,9 +3416,9 @@ decode-uri-component@^0.2.0: integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-equal@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.0.tgz#3103cdf8ab6d32cf4a8df7865458f2b8d33f3745" - integrity sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== dependencies: is-arguments "^1.0.4" is-date-object "^1.0.1" @@ -3487,9 +3520,9 @@ depd@~1.1.2: integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -3680,10 +3713,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" - integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== +ejs@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.2.tgz#749037c4c09bd57626a6140afbe6b7e650661614" + integrity sha512-rHGwtpl67oih3xAHbZlpw5rQAt+YV1mSCu2fUZ9XNrfaGEhom7E+AUiMci+ByP4aSfuAWx7hE0BPuJLMrpXwOw== electron-to-chromium@^1.3.295: version "1.3.306" @@ -4168,9 +4201,9 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-contract-metadata@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" - integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== + version "1.10.0" + resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.10.0.tgz#a3a0c5e4afae7a3522269cac48ed65f82bae3370" + integrity sha512-HbSwC2IRjjWHkWZ8Ibfql6OjTihuoZknigF6nYmDNgTw+lWEau4mnSTO+0lU7VCn3+bxRYmdtNTWIwl3INzaUw== ethers@^4.0.28, ethers@^4.0.39: version "4.0.39" @@ -4915,7 +4948,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -5039,9 +5072,9 @@ hammerjs@^2.0.8: integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= handlebars@^4.1.2: - version "4.5.1" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.1.tgz#8a01c382c180272260d07f2d1aa3ae745715c7ba" - integrity sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA== + version "4.5.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.2.tgz#5a4eb92ab5962ca3415ac188c86dc7f784f76a0f" + integrity sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -5086,6 +5119,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -5183,9 +5221,9 @@ hoist-non-react-statics@^2.3.1: integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" - integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== + version "3.3.1" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#101685d3aff3b23ea213163f6e8e12f4f111e19f" + integrity sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw== dependencies: react-is "^16.7.0" @@ -5335,9 +5373,9 @@ import-fresh@^2.0.0: resolve-from "^3.0.0" import-fresh@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" - integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -5817,6 +5855,11 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +is-wsl@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" + integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + is@~0.2.6: version "0.2.7" resolved "https://registry.yarnpkg.com/is/-/is-0.2.7.tgz#3b34a2c48f359972f35042849193ae7264b63562" @@ -7508,12 +7551,7 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== - -"mime-db@>= 1.40.0 < 2": +mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": version "1.42.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== @@ -7531,11 +7569,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + version "2.1.25" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" + integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== dependencies: - mime-db "1.40.0" + mime-db "1.42.0" mime@1.6.0: version "1.6.0" @@ -7876,9 +7914,9 @@ node-pre-gyp@^0.12.0: tar "^4" node-releases@^1.1.38: - version "1.1.39" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.39.tgz#c1011f30343aff5b633153b10ff691d278d08e8d" - integrity sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA== + version "1.1.40" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.40.tgz#a94facfa8e2d612302601ca1361741d529c4515a" + integrity sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ== dependencies: semver "^6.3.0" @@ -8175,6 +8213,13 @@ open@^6.2.0, open@^6.4.0: dependencies: is-wsl "^1.1.0" +open@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.0.0.tgz#7e52999b14eb73f90f0f0807fe93897c4ae73ec9" + integrity sha512-K6EKzYqnwQzk+/dzJAQSBORub3xlBTxMz+ntpZpH/LyCa1o6KjXhuN+2npAaI9jaSmU3R1Q8NWf4KUWcyytGsQ== + dependencies: + is-wsl "^2.1.0" + opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" @@ -9037,9 +9082,9 @@ qs@~6.5.2: integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^6.4.2: - version "6.8.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.3.tgz#fd9fb7ffb068b79062b43383685611ee47777d4b" - integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ== + version "6.9.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.9.0.tgz#1c3b727c370cf00f177c99f328fda2108f8fa3dd" + integrity sha512-KG4bhCFYapExLsUHrFt+kQVEegF2agm4cpF/VNc6pZVthIfCc/GK8t8VyNIE3nyXG9DK3Tf2EGkxjR6/uRdYsA== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -9448,7 +9493,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/8e750d75eedfe4f9465c98b9a28d1b6279257dc0" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/ce226c1f283735456f0de67b4dc7ca2955efc671" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" @@ -10586,21 +10631,21 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.0.tgz#d80e2a7fef0f15b3c9c1f57bc22bd1aabfaf2309" - integrity sha512-VlOYrBo7gKT72E3IGMzK33ddEWIHGIdyraz8nmpxC7n0ZrzGWq08pWkB8FBxlJJCm9xmP3imlZ9ElUsGbKPpvQ== + version "2.1.1" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.1.tgz#7e7f833cbb7a807dc3a76608c0d581909353852c" + integrity sha512-GSHrlyGFhcXhjdWgM+ysY7d11eZMN2gvLsW56qFOdV3ZCsZCM/tl8tt3PXu5BUvllNKPRCGyv2mbWjbZrvEdmA== dependencies: btoa "^1.2.1" - chalk "^2.4.2" - convert-source-map "^1.6.0" - ejs "^2.7.1" + chalk "^3.0.0" + convert-source-map "^1.7.0" + ejs "^2.7.2" escape-html "^1.0.3" - glob "^7.1.4" + glob "^7.1.6" lodash "^4.17.15" - open "^6.4.0" + open "^7.0.0" source-map "^0.7.3" - temp "^0.9.0" - yargs "^14.0.0" + temp "^0.9.1" + yargs "^14.2.0" source-map-resolve@^0.5.0: version "0.5.2" @@ -11027,9 +11072,9 @@ stylis@^3.5.0: integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== sudo-prompt@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a" - integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ== + version "9.1.1" + resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0" + integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA== sugarss@^2.0.0: version "2.0.0" @@ -11089,6 +11134,13 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + svg-arc-to-cubic-bezier@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz#390c450035ae1c4a0104d90650304c3bc814abe6" @@ -11194,7 +11246,7 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" -temp@^0.9.0: +temp@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697" integrity sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA== @@ -11477,9 +11529,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.8" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.8.tgz#5edcbcf9d49cbb0403dc49f856fe81530d65145e" - integrity sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ== + version "3.6.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.9.tgz#85d353edb6ddfb62a9d798f36e91792249320611" + integrity sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -12276,7 +12328,7 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^14.0.0: +yargs@^14.2.0: version "14.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.0.tgz#f116a9242c4ed8668790b40759b4906c276e76c3" integrity sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg== From b442832caaf0606fb8af5d7864c7ea9a00c3356b Mon Sep 17 00:00:00 2001 From: osdnk Date: Fri, 15 Nov 2019 10:55:50 +0100 Subject: [PATCH 520/636] Fix stuttering of modal while opening --- src/components/exchange/ExchangeInputField.js | 1 - src/screens/ExchangeModal.js | 14 +++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index fa9fb2ef201..7ad2a19ded7 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -96,7 +96,6 @@ export default class ExchangeInputField extends Component { symbol={inputCurrencySymbol} /> { + clearTimeout(this.initialFocusTimeout); this.props.uniswapClearCurrenciesAndReserves(); }; @@ -776,7 +789,6 @@ class ExchangeModal extends Component { const isSlippageWarningVisible = isSufficientBalance && !!inputAmount && !!outputAmount; - return ( From 6f417fb89e825bb1183994a6b722f86e77f04294 Mon Sep 17 00:00:00 2001 From: osdnk Date: Fri, 15 Nov 2019 11:04:02 +0100 Subject: [PATCH 521/636] Use InteractionManager --- src/screens/ExchangeModal.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 5995538344e..fada15c1372 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -11,7 +11,7 @@ import BigNumber from 'bignumber.js'; import { get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; -import { TextInput } from 'react-native'; +import { TextInput, InteractionManager } from 'react-native'; import Animated from 'react-native-reanimated'; import { withNavigationFocus, NavigationEvents } from 'react-navigation'; import { compose, toClass, withProps } from 'recompact'; @@ -141,7 +141,9 @@ class ExchangeModal extends Component { nextProps.isTransitioning && this.lastFocusedInput === null ) { - this.initialFocusTimeout = setTimeout(this.inputFieldRef.focus, 300); + this.inputFocusInteractionHandle = InteractionManager.runAfterInteractions( + this.inputFieldRef.focus + ); } const isNewState = isNewValueForObjectPaths(this.state, nextState, [ @@ -221,7 +223,11 @@ class ExchangeModal extends Component { }; componentWillUnmount = () => { - clearTimeout(this.initialFocusTimeout); + if (this.inputFocusInteractionHandle) { + InteractionManager.clearInteractionHandle( + this.inputFocusInteractionHandle + ); + } this.props.uniswapClearCurrenciesAndReserves(); }; From 977a95a401553cd27750dd955c529a7cb885ceb2 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Fri, 15 Nov 2019 11:43:53 +0100 Subject: [PATCH 522/636] fix checking if selected input exist --- src/components/send/SendHeader.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 758f24d31ec..0442c946340 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -113,6 +113,7 @@ class SendHeader extends PureComponent { navigateToContact = (contact = {}) => { const { navigation, onUpdateContacts, recipient } = this.props; const refocusCallback = + this.props.selectedInputId && this.props.selectedInputId.isFocused() && this.props.selectedInputId.focus; From e04624814e48a382378780679bf99af47f4bb026 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 15 Nov 2019 20:14:54 -0500 Subject: [PATCH 523/636] Revert "Merge pull request #230 from rainbow-me/fix-favorite-stars" This reverts commit 6b8f65b1d3560fae7499d29070dc165d2053d1e4, reversing changes made to 3cee6490216dc38cb23a9b1c8bf59bab08f24c82. --- ios/Podfile.lock | 44 ++-- src/components/coin-row/ExchangeCoinRow.js | 19 +- src/components/exchange/ExchangeAssetList.js | 5 +- src/screens/CurrencySelectModal.js | 8 - yarn.lock | 224 +++++++------------ 5 files changed, 117 insertions(+), 183 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bb699f271e7..b2b7dd41620 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -626,8 +626,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: ecca54884bcbca6e0bf6aa4bb0609500fba2a454 - FBReactNativeSpec: 3ee351f778656ddd4ef4b419093f26d57561b5b6 + FBLazyVector: 3c557c904906a16efd29521a04b9c8686de38216 + FBReactNativeSpec: bb037bdd0a297cd978fd11975b8cda0221343096 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -643,15 +643,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: ed682a2cdbada65027cdce7342872ce7be2f148e - RCTTypeSafety: 9c323eae031754761a1dc916be0fb94cd8329b4f - React: 1526e91cf6dc1ff05e161f4a62ec6d3889cd93a5 - React-Core: 0117ccd0135b08ef1c56f61e7e94d49ac2f8cc7b - React-CoreModules: 8bc81b4dcf1b06cf8e767b677e0d310bdc3a9107 - React-cxxreact: b2ccf2c2933c908227a4db3a4119dbbda0298451 - React-jsi: 8e4c76f69519c8d46e5a3226c02bce233a78dadd - React-jsiexecutor: 09c4f112dc5eff1f573a28c5efc20ce7df180da1 - React-jsinspector: 9ad8aea3c889b71231586a8e8e379f48df4f45a8 + RCTRequired: 76dea74f39053c5ece421aa68faaed99a520c656 + RCTTypeSafety: fae97c41dc0718e0e8740e23bf85954f6fe76439 + React: 3e13f51327ef94d700388926efe74e5a14534f01 + React-Core: 011eb66a79cb131c892245abd3c6653786f83986 + React-CoreModules: 43f39f48f79c34224f34f9739690f714332920d2 + React-cxxreact: f6449f6c2cb07c16d95da7fbb95064102bf504c5 + React-jsi: 4cde0e89436d3180ce5c983265ded2fdc4e9fdee + React-jsiexecutor: 8540f256c210050c239b40a22d488bd7b0a7da83 + React-jsinspector: 13b657970778a2cf6f58ccc182a962f8ada9752c react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -661,16 +661,16 @@ SPEC CHECKSUMS: react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 35b3f73f7587592b438d6af1ee5af1e43af9c15b - React-RCTAnimation: 0c346a402613834c2d9793376ffe6c008ea7c2fa - React-RCTBlob: ec3861d7b98c10264a20acd0cfe49eb6eb15579b - React-RCTImage: 8efea8d879fb7df7f66d3c73ff3feea56f971d35 - React-RCTLinking: 4336a93575f08057563f534d0c1d38592d2c0bde - React-RCTNetwork: df79caf75da2b392cb0c8e6b086f642adca403bc - React-RCTSettings: 34cc2696bde255d3cb00ac79f8719a4ae3ff9775 - React-RCTText: 4e236748059b67d3abf84d1b70f79b6cf4a182c8 - React-RCTVibration: a63c67ec9eadeddec5e8371c56ac9071e9c93a4c - ReactCommon: 7bc590509e40483bd7bb975456060ab270f0d0bf + React-RCTActionSheet: ad2d234b166eac167ea5a72b8520b2e75b969e4b + React-RCTAnimation: 6cc6b1474c06bbb5708d81d5aa7de8bf82d2e7c9 + React-RCTBlob: fcf733fa6359ec947e7aa03654eeb123e42dc3aa + React-RCTImage: 7471a0a6e56e9a073408de2c2840867ef9776b6a + React-RCTLinking: ca63cc48b51a3794422d136fa8884b951ff28c7f + React-RCTNetwork: fb1a0e9e2b06e7f9aeb514e9e603b0b4f24247bd + React-RCTSettings: d7c2320b334e47aad1f187c91efa17b11cf71253 + React-RCTText: 70172eebbfe602d187dacd4b2be3ba1f4ddd1426 + React-RCTVibration: 0e2697e1d9ecf96d37bb16979fe4f938e4b29c48 + ReactCommon: 60447eea63cfb8b0449773f141790b694312149c ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -694,7 +694,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: b225f4ec22178cb062530328d7733d1f20d5516b + Yoga: a2dc4dfcc1202c437e48b62cc35a782216508c76 PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index 9d1e5c0d437..e53b22da5ba 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -1,4 +1,3 @@ -import { get } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { connect } from 'react-redux'; @@ -59,16 +58,12 @@ class ExchangeCoinRow extends Component { }; state = { - localFavorite: false, + favorite: !!this.props.item.favorite, }; shouldComponentUpdate = (nextProps, nextState) => { const isNewAsset = isNewValueForPath(this.props, nextProps, 'uniqueId'); - const isNewFavorite = isNewValueForPath( - this.state, - nextState, - 'localFavorite' - ); + const isNewFavorite = isNewValueForPath(this.state, nextState, 'favorite'); return isNewAsset || isNewFavorite; }; @@ -82,9 +77,9 @@ class ExchangeCoinRow extends Component { toggleFavorite = () => { const { item, uniswapUpdateFavorites } = this.props; this.setState(prevState => { - const localFavorite = !prevState.localFavorite; - uniswapUpdateFavorites(item.address, localFavorite); - return { localFavorite }; + const favorite = !prevState.favorite; + uniswapUpdateFavorites(item.address, favorite); + return { favorite }; }); }; @@ -96,7 +91,7 @@ class ExchangeCoinRow extends Component { uniqueId, ...props } = this.props; - const { localFavorite } = this.state; + const { favorite } = this.state; return ( {showFavoriteButton && ( )} diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index 7ef48e4dac5..309de5a7839 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -7,7 +7,7 @@ import { LayoutProvider, RecyclerListView, } from 'recyclerlistview'; -import { deviceUtils, isNewValueForObjectPaths } from '../../utils'; +import { deviceUtils, isNewValueForPath } from '../../utils'; import { colors } from '../../styles'; import { CoinRow } from '../coin-row'; @@ -30,8 +30,7 @@ const layoutItemAnimator = { const getLayoutTypeForIndex = () => ViewTypes.COIN_ROW; -const hasRowChanged = (r1, r2) => - isNewValueForObjectPaths(r1, r2, ['favorite', 'uniqueId']); +const hasRowChanged = (r1, r2) => isNewValueForPath(r1, r2, 'uniqueId'); const setLayoutForType = (type, dim) => { if (type === ViewTypes.COIN_ROW) { diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 611f831e44f..29e5c697d11 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -130,7 +130,6 @@ class CurrencySelectModal extends Component { render = () => { const { assetsAvailableOnUniswap, - favorites, isFocused, sortedUniswapAssets, transitionPosition, @@ -146,13 +145,6 @@ class CurrencySelectModal extends Component { assets = assetsAvailableOnUniswap; } else if (type === CurrencySelectionTypes.output) { headerTitle = 'Receive'; - - if (Array.isArray(favorites) && favorites.length) { - assets = assets.map(asset => ({ - ...asset, - favorite: favorites.includes(asset.address), - })); - } } const listItems = filterList(assets, searchQuery, 'uniqueId'); diff --git a/yarn.lock b/yarn.lock index e168ece3dfe..5cab9f71867 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1350,11 +1350,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -1535,37 +1530,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -"@walletconnect/core@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.39.tgz#43d05dbabcaeea491c0ee213ed60d2236672010f" - integrity sha512-cJSQe2Ao4okSvohNjA7Bs7Z+0BAznfVVTWBECIX/bGoSFpkAWabGY2Pn2gIYhobQMLSFpE6ZlZ4QfvlPO8HyPw== +"@walletconnect/core@^1.0.0-beta.38": + version "1.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.38.tgz#4716cfa87a58b707b274dbbb0601868512207ab6" + integrity sha512-fJfiK2oAWlGCCh7ULjq7fVnGsnn7/TnLsQTAzt5TwmHQ0YsZ595UYnuux4rr93IyvjIIcKkI6WMQKvcw1t/y4A== dependencies: - "@walletconnect/types" "^1.0.0-beta.39" - "@walletconnect/utils" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.38" + "@walletconnect/utils" "^1.0.0-beta.38" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.39.tgz#0db212eba9087055822a89bf73d1cebc5762639e" - integrity sha512-d/QAjL/Rp1lrJeblsHpl+Fa6HTz40A93X5l6oTV0YFAG7bZDPl+OogM337WnjZWfwcn1XaKXSwsmG1NXTQn4Yg== + version "1.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.38.tgz#cbba526ebfa2ba7ce0d5496e3f1556222fba1544" + integrity sha512-rQ0ZYfcA7R4i4px3EEjSzCyHa4IswVn8642/rLxJbdgd/xXV7qW1+wjYoOdLPyEGLGUX5ojIC0e6yba3Q3y2gA== dependencies: - "@walletconnect/core" "^1.0.0-beta.39" - "@walletconnect/types" "^1.0.0-beta.39" - "@walletconnect/utils" "^1.0.0-beta.39" + "@walletconnect/core" "^1.0.0-beta.38" + "@walletconnect/types" "^1.0.0-beta.38" + "@walletconnect/utils" "^1.0.0-beta.38" -"@walletconnect/types@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.39.tgz#e84463f32d6c450376db3d0ce56f0ece6608bfa7" - integrity sha512-YO/g1HVnFxcMNiUI9LEWEDe5uVHw8D7JzJol+bT71iXymzolnsbG32OayCJM9nHqT48Rpz1EGIno8EjW9jH2OQ== +"@walletconnect/types@^1.0.0-beta.38": + version "1.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.38.tgz#6f6e23511d6821723767df18be395e52f406e6a7" + integrity sha512-155J5SXBio6Vo2zDP3ijvSmfCIJS5jp7A0bIJ+z1RAG0yG+nevCW1yLTevyRNT8U7mJSjKI/HkmjzZuW1ATiLQ== -"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.39.tgz#8909b9cffa3999b046ce32cbb21b8ddca97b9183" - integrity sha512-AOlhPkK+IUzGG5iDTupKdUwNW4on1aAj5NyLMMN1+htr06hqaCV8F9HeYibSen22wdSUuLXkIQNy3SR3LPcehA== +"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.38": + version "1.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.38.tgz#6755367bc7d9f7811f87464f636aa4f41aded36e" + integrity sha512-4esXDexo8w8QDsw3Ng378pjK88EBMVmbeYYfdWmCazKHDNmActJkVYAQtIeHFOAOG2OAAZ6IYt6fWvuw8jaPbg== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.38" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1579,9 +1574,9 @@ Base64@~0.2.0: integrity sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg= abab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.2.tgz#a2fba1b122c69a85caa02d10f9270c7219709a9d" + integrity sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg== abbrev@1: version "1.1.1" @@ -1800,14 +1795,6 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" - integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -2661,9 +2648,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006: - version "1.0.30001010" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz#397a14034d384260453cc81994f494626d34b938" - integrity sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw== + version "1.0.30001008" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz#b8841b1df78a9f5ed9702537ef592f1f8772c0d9" + integrity sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw== capture-exit@^2.0.0: version "2.0.0" @@ -2707,14 +2694,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" @@ -2953,23 +2932,11 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" @@ -3109,7 +3076,7 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -convert-source-map@^1.4.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -3416,9 +3383,9 @@ decode-uri-component@^0.2.0: integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-equal@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + version "1.1.0" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.0.tgz#3103cdf8ab6d32cf4a8df7865458f2b8d33f3745" + integrity sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== dependencies: is-arguments "^1.0.4" is-date-object "^1.0.1" @@ -3520,9 +3487,9 @@ depd@~1.1.2: integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -3713,10 +3680,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.2.tgz#749037c4c09bd57626a6140afbe6b7e650661614" - integrity sha512-rHGwtpl67oih3xAHbZlpw5rQAt+YV1mSCu2fUZ9XNrfaGEhom7E+AUiMci+ByP4aSfuAWx7hE0BPuJLMrpXwOw== +ejs@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" + integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== electron-to-chromium@^1.3.295: version "1.3.306" @@ -4201,9 +4168,9 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-contract-metadata@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.10.0.tgz#a3a0c5e4afae7a3522269cac48ed65f82bae3370" - integrity sha512-HbSwC2IRjjWHkWZ8Ibfql6OjTihuoZknigF6nYmDNgTw+lWEau4mnSTO+0lU7VCn3+bxRYmdtNTWIwl3INzaUw== + version "1.9.3" + resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" + integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== ethers@^4.0.28, ethers@^4.0.39: version "4.0.39" @@ -4948,7 +4915,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -5072,9 +5039,9 @@ hammerjs@^2.0.8: integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= handlebars@^4.1.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.2.tgz#5a4eb92ab5962ca3415ac188c86dc7f784f76a0f" - integrity sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg== + version "4.5.1" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.1.tgz#8a01c382c180272260d07f2d1aa3ae745715c7ba" + integrity sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -5119,11 +5086,6 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -5221,9 +5183,9 @@ hoist-non-react-statics@^2.3.1: integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#101685d3aff3b23ea213163f6e8e12f4f111e19f" - integrity sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw== + version "3.3.0" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" + integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== dependencies: react-is "^16.7.0" @@ -5373,9 +5335,9 @@ import-fresh@^2.0.0: resolve-from "^3.0.0" import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" + integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -5855,11 +5817,6 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" - integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== - is@~0.2.6: version "0.2.7" resolved "https://registry.yarnpkg.com/is/-/is-0.2.7.tgz#3b34a2c48f359972f35042849193ae7264b63562" @@ -7551,7 +7508,12 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +"mime-db@>= 1.40.0 < 2": version "1.42.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== @@ -7569,11 +7531,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== dependencies: - mime-db "1.42.0" + mime-db "1.40.0" mime@1.6.0: version "1.6.0" @@ -7914,9 +7876,9 @@ node-pre-gyp@^0.12.0: tar "^4" node-releases@^1.1.38: - version "1.1.40" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.40.tgz#a94facfa8e2d612302601ca1361741d529c4515a" - integrity sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ== + version "1.1.39" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.39.tgz#c1011f30343aff5b633153b10ff691d278d08e8d" + integrity sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA== dependencies: semver "^6.3.0" @@ -8213,13 +8175,6 @@ open@^6.2.0, open@^6.4.0: dependencies: is-wsl "^1.1.0" -open@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/open/-/open-7.0.0.tgz#7e52999b14eb73f90f0f0807fe93897c4ae73ec9" - integrity sha512-K6EKzYqnwQzk+/dzJAQSBORub3xlBTxMz+ntpZpH/LyCa1o6KjXhuN+2npAaI9jaSmU3R1Q8NWf4KUWcyytGsQ== - dependencies: - is-wsl "^2.1.0" - opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" @@ -9082,9 +9037,9 @@ qs@~6.5.2: integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^6.4.2: - version "6.9.0" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.9.0.tgz#1c3b727c370cf00f177c99f328fda2108f8fa3dd" - integrity sha512-KG4bhCFYapExLsUHrFt+kQVEegF2agm4cpF/VNc6pZVthIfCc/GK8t8VyNIE3nyXG9DK3Tf2EGkxjR6/uRdYsA== + version "6.8.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.3.tgz#fd9fb7ffb068b79062b43383685611ee47777d4b" + integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -9493,7 +9448,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/ce226c1f283735456f0de67b4dc7ca2955efc671" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/8e750d75eedfe4f9465c98b9a28d1b6279257dc0" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0-alpha.1" @@ -10631,21 +10586,21 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.1.tgz#7e7f833cbb7a807dc3a76608c0d581909353852c" - integrity sha512-GSHrlyGFhcXhjdWgM+ysY7d11eZMN2gvLsW56qFOdV3ZCsZCM/tl8tt3PXu5BUvllNKPRCGyv2mbWjbZrvEdmA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.0.tgz#d80e2a7fef0f15b3c9c1f57bc22bd1aabfaf2309" + integrity sha512-VlOYrBo7gKT72E3IGMzK33ddEWIHGIdyraz8nmpxC7n0ZrzGWq08pWkB8FBxlJJCm9xmP3imlZ9ElUsGbKPpvQ== dependencies: btoa "^1.2.1" - chalk "^3.0.0" - convert-source-map "^1.7.0" - ejs "^2.7.2" + chalk "^2.4.2" + convert-source-map "^1.6.0" + ejs "^2.7.1" escape-html "^1.0.3" - glob "^7.1.6" + glob "^7.1.4" lodash "^4.17.15" - open "^7.0.0" + open "^6.4.0" source-map "^0.7.3" - temp "^0.9.1" - yargs "^14.2.0" + temp "^0.9.0" + yargs "^14.0.0" source-map-resolve@^0.5.0: version "0.5.2" @@ -11072,9 +11027,9 @@ stylis@^3.5.0: integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== sudo-prompt@^9.0.0: - version "9.1.1" - resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0" - integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA== + version "9.0.0" + resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a" + integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ== sugarss@^2.0.0: version "2.0.0" @@ -11134,13 +11089,6 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== - dependencies: - has-flag "^4.0.0" - svg-arc-to-cubic-bezier@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz#390c450035ae1c4a0104d90650304c3bc814abe6" @@ -11246,7 +11194,7 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" -temp@^0.9.1: +temp@^0.9.0: version "0.9.1" resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697" integrity sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA== @@ -11529,9 +11477,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.9.tgz#85d353edb6ddfb62a9d798f36e91792249320611" - integrity sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw== + version "3.6.8" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.8.tgz#5edcbcf9d49cbb0403dc49f856fe81530d65145e" + integrity sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -12328,7 +12276,7 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^14.2.0: +yargs@^14.0.0: version "14.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.0.tgz#f116a9242c4ed8668790b40759b4906c276e76c3" integrity sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg== From 72bc1592051426d374852b51c673c22157acb8d5 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 15 Nov 2019 21:40:25 -0500 Subject: [PATCH 524/636] move POA to token overrides list for symbols and remove any asterisks in asset symbols --- src/components/coin-icon/CoinIcon.js | 19 ++----------------- src/parsers/accounts.js | 5 ++++- src/references/token-overrides.json | 3 ++- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/components/coin-icon/CoinIcon.js b/src/components/coin-icon/CoinIcon.js index b207167117b..9152d7bc087 100644 --- a/src/components/coin-icon/CoinIcon.js +++ b/src/components/coin-icon/CoinIcon.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { css } from 'styled-components/primitives'; import ReactCoinIcon, { FallbackIcon } from 'react-coin-icon'; -import { compose, withProps, onlyUpdateForKeys } from 'recompact'; +import { onlyUpdateForKeys } from 'recompact'; import { borders, colors, fonts } from '../../styles'; import { ShadowStack } from '../shadow-stack'; @@ -21,22 +21,7 @@ const CoinIconFallback = fallbackProps => ( /> ); -const enhance = compose( - onlyUpdateForKeys(['bgColor', 'symbol']), - withProps(({ symbol }) => { - let symbolOverride = symbol; - - if (symbol === 'POA20') { - symbolOverride = 'POA'; - } else if (typeof symbol === 'string' && symbol.includes('*')) { - symbolOverride = symbol.replace(/[*]/g, ''); - } - - return { - symbol: symbolOverride, - }; - }) -); +const enhance = onlyUpdateForKeys(['bgColor', 'symbol']); const CoinIcon = enhance(({ bgColor, showShadow, size, symbol, ...props }) => showShadow ? ( diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index ba75c84c740..f9b2853a33f 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -29,7 +29,10 @@ export const parseAccountAssets = (data, uniqueTokens) => { export const parseAsset = assetData => { const address = get(assetData, 'asset_code', null); const name = get(assetData, 'name') || 'Unknown Token'; - const symbol = get(assetData, 'symbol') || '———'; + let symbol = get(assetData, 'symbol') || '———'; + if (symbol && symbol.includes('*')) { + symbol = symbol.replace(/[*]/g, ''); + } const asset = { address, decimals: get(assetData, 'decimals'), diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 6b0f0161235..261b3e7857d 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -90,7 +90,8 @@ "name": "Kleros" }, "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { - "name": "POA Network" + "name": "POA Network", + "symbol": "POA" }, "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6": { "name": "Raiden" From 8bad7515a2dde6639807510824bd227960e5fc75 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 17 Nov 2019 19:18:32 -0500 Subject: [PATCH 525/636] Fix: do not hide swap modal or send modal when canceling authentication New behavior: - Will not navigate away when authorization fails (either by failure or user cancel) - Fix for Hold to Send/Swap/Sign buttons to animate back from Authorizing state (for the Send, Swap, and WalletConnect flows) --- .../hold-to-authorize/HoldToAuthorizeButton.js | 14 ++++++++++++-- src/components/exchange/ConfirmExchangeButton.js | 3 +++ src/screens/ExchangeModal.js | 9 ++++++++- src/screens/TransactionConfirmationScreen.js | 16 ++++++++++++---- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js index e937963a747..55054e54c1b 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js @@ -99,8 +99,7 @@ export default class HoldToAuthorizeButton extends PureComponent { componentDidUpdate = () => { if (this.state.isAuthorizing && !this.props.isAuthorizing) { - // eslint-disable-next-line react/no-did-update-set-state - this.setState({ isAuthorizing: false }); + this.onFinishAuthorizing(); } }; @@ -110,6 +109,17 @@ export default class HoldToAuthorizeButton extends PureComponent { animation = new Value(0); + onFinishAuthorizing = () => { + const { disabled } = this.props; + if (!disabled) { + buildAnimation(this.animation, { + duration: calculateReverseDuration(this.animation), + isInteraction: true, + toValue: 0, + }).start(() => this.setState({ isAuthorizing: false })); + } + }; + onTapChange = ({ nativeEvent: { state } }) => { const { disabled, onPress } = this.props; diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 4a66026763b..111e9d12435 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -8,6 +8,7 @@ const ConfirmExchangeButton = ({ disabled, inputCurrencyName, isAssetApproved, + isAuthorizing, isSufficientBalance, isUnlockingAsset, onSubmit, @@ -33,6 +34,7 @@ const ConfirmExchangeButton = ({ disabledBackgroundColor={colors.grey20} flex={1} hideBiometricIcon={isUnlockingAsset || !isAssetApproved} + isAuthorizing={isAuthorizing} label={label} onLongPress={isAssetApproved ? onSubmit : null} onPress={isAssetApproved ? null : onUnlockAsset} @@ -57,6 +59,7 @@ ConfirmExchangeButton.propTypes = { disabled: PropTypes.bool, inputCurrencyName: PropTypes.string, isAssetApproved: PropTypes.bool, + isAuthorizing: PropTypes.bool, isSufficientBalance: PropTypes.bool, isUnlockingAsset: PropTypes.bool, onSubmit: PropTypes.func, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index fada15c1372..1aa69e76a1d 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -113,6 +113,7 @@ class ExchangeModal extends Component { inputExecutionRate: null, inputNativePrice: null, isAssetApproved: true, + isAuthorizing: false, isSufficientBalance: true, isUnlockingAsset: false, nativeAmount: null, @@ -152,6 +153,7 @@ class ExchangeModal extends Component { 'inputAmount', 'inputCurrency.uniqueId', 'isAssetApproved', + 'isAuthorizing', 'isSufficientBalance', 'isUnlockingAsset', 'nativeAmount', @@ -558,6 +560,7 @@ class ExchangeModal extends Component { }; handleSubmit = async () => { + this.setState({ isAuthorizing: true }); const { accountAddress, dataAddNewTransaction, @@ -570,6 +573,7 @@ class ExchangeModal extends Component { try { const gasPrice = get(selectedGasPrice, 'value.amount'); const txn = await executeSwap(tradeDetails, gasLimit, gasPrice); + this.setState({ isAuthorizing: false }); if (txn) { dataAddNewTransaction({ amount: inputAmount, @@ -579,9 +583,10 @@ class ExchangeModal extends Component { nonce: get(txn, 'nonce'), to: get(txn, 'to'), }); + navigation.navigate('ProfileScreen'); } - navigation.navigate('ProfileScreen'); } catch (error) { + this.setState({ isAuthorizing: false }); console.log('error submitting swap', error); navigation.navigate('WalletScreen'); } @@ -781,6 +786,7 @@ class ExchangeModal extends Component { // inputExecutionRate, // inputNativePrice, isAssetApproved, + isAuthorizing, isSufficientBalance, isUnlockingAsset, nativeAmount, @@ -858,6 +864,7 @@ class ExchangeModal extends Component { disabled={isAssetApproved && !Number(inputAmountDisplay)} inputCurrencyName={get(inputCurrency, 'symbol')} isAssetApproved={isAssetApproved} + isAuthorizing={isAuthorizing} isSufficientBalance={isSufficientBalance} isUnlockingAsset={isUnlockingAsset} onSubmit={this.handleSubmit} diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index e94289db037..319cf7a3d1a 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -55,6 +55,7 @@ export default class TransactionConfirmationScreen extends PureComponent { state = { biometryType: null, + isAuthorizing: false, sendLongPressProgress: new Animated.Value(0), }; @@ -94,21 +95,28 @@ export default class TransactionConfirmationScreen extends PureComponent { const { onConfirm } = this.props; const { sendLongPressProgress } = this.state; + this.setState({ isAuthorizing: true }); Animated.timing(sendLongPressProgress, { duration: (sendLongPressProgress._value / 100) * 800, toValue: 0, }).start(); - await onConfirm(); + try { + await onConfirm(); + this.setState({ isAuthorizing: false }); + } catch (error) { + this.setState({ isAuthorizing: false }); + } }; renderSendButton = () => ( - {`Hold to ${this.props.method === SEND_TRANSACTION ? 'Send' : 'Sign'}`} - + /> ); requestHeader = () => { From 5aaa251d5f672bcc1feb2d1fed1adb70fafad1df Mon Sep 17 00:00:00 2001 From: jinchung Date: Sun, 17 Nov 2019 15:45:43 -0500 Subject: [PATCH 526/636] Autolink RNTextInputMask without the use of !use_frameworks --- ios/Dummy.swift | 9 + ios/Podfile | 1 + ios/Podfile.lock | 62 ++-- ios/Rainbow-Bridging-Header.h | 4 + ios/Rainbow.xcodeproj/project.pbxproj | 80 ++---- package.json | 2 +- yarn.lock | 390 ++++++++++++++------------ 7 files changed, 281 insertions(+), 267 deletions(-) create mode 100644 ios/Dummy.swift create mode 100644 ios/Rainbow-Bridging-Header.h diff --git a/ios/Dummy.swift b/ios/Dummy.swift new file mode 100644 index 00000000000..8cf6d84f43f --- /dev/null +++ b/ios/Dummy.swift @@ -0,0 +1,9 @@ +// +// Dummy.swift +// Rainbow +// +// Created by Jin on 11/17/19. +// Copyright © 2019 Facebook. All rights reserved. +// + +import Foundation diff --git a/ios/Podfile b/ios/Podfile index 596af8baa72..914b1afcc56 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -49,6 +49,7 @@ target 'Rainbow' do pod 'FLAnimatedImage' pod 'libwebp' pod 'CodePush', :path => '../node_modules/react-native-code-push' + pod 'RNInputMask', :path => '../node_modules/react-native-text-input-mask/ios/InputMask' use_native_modules! diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b2b7dd41620..071cab5fd54 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -282,7 +282,7 @@ PODS: - React - react-native-mail (4.1.0): - React - - react-native-netinfo (4.6.0): + - react-native-netinfo (4.6.1): - React - react-native-randombytes (3.5.3): - React @@ -290,6 +290,9 @@ PODS: - React - react-native-splash-screen (3.2.0): - React + - react-native-text-input-mask (2.0.0): + - React + - RNInputMask - react-native-udp (2.6.1): - React - react-native-version-number (0.3.6): @@ -379,6 +382,7 @@ PODS: - React - RNGestureHandler (1.4.1): - React + - RNInputMask (4.1.0) - RNKeychain (4.0.1): - React - RNLanguages (3.0.2): @@ -444,6 +448,7 @@ DEPENDENCIES: - react-native-randombytes (from `../node_modules/react-native-randombytes`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-splash-screen (from `../node_modules/react-native-splash-screen`) + - react-native-text-input-mask (from `../node_modules/react-native-text-input-mask`) - react-native-udp (from `../node_modules/react-native-udp`) - react-native-version-number (from `../node_modules/react-native-version-number`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) @@ -465,6 +470,7 @@ DEPENDENCIES: - RNFastImage (from `../node_modules/react-native-fast-image`) - RNFirebase (from `../node_modules/react-native-firebase/ios`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNInputMask (from `../node_modules/react-native-text-input-mask/ios/InputMask`) - RNKeychain (from `../node_modules/react-native-keychain`) - RNLanguages (from `../node_modules/react-native-languages`) - RNOS (from `../node_modules/react-native-os`) @@ -550,6 +556,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-safe-area-context" react-native-splash-screen: :path: "../node_modules/react-native-splash-screen" + react-native-text-input-mask: + :path: "../node_modules/react-native-text-input-mask" react-native-udp: :path: "../node_modules/react-native-udp" react-native-version-number: @@ -590,6 +598,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-firebase/ios" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" + RNInputMask: + :path: "../node_modules/react-native-text-input-mask/ios/InputMask" RNKeychain: :path: "../node_modules/react-native-keychain" RNLanguages: @@ -626,8 +636,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 3c557c904906a16efd29521a04b9c8686de38216 - FBReactNativeSpec: bb037bdd0a297cd978fd11975b8cda0221343096 + FBLazyVector: 622571adc030d0593ff14b01a6a7a9381b5a8ec9 + FBReactNativeSpec: 51b297eb6a8f1f1af7ad995f7b50d463f9cbc8ac Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -643,34 +653,35 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 76dea74f39053c5ece421aa68faaed99a520c656 - RCTTypeSafety: fae97c41dc0718e0e8740e23bf85954f6fe76439 - React: 3e13f51327ef94d700388926efe74e5a14534f01 - React-Core: 011eb66a79cb131c892245abd3c6653786f83986 - React-CoreModules: 43f39f48f79c34224f34f9739690f714332920d2 - React-cxxreact: f6449f6c2cb07c16d95da7fbb95064102bf504c5 - React-jsi: 4cde0e89436d3180ce5c983265ded2fdc4e9fdee - React-jsiexecutor: 8540f256c210050c239b40a22d488bd7b0a7da83 - React-jsinspector: 13b657970778a2cf6f58ccc182a962f8ada9752c + RCTRequired: 2a7ef3e1905ee07fee04afa15899d1ac0d2bc4e2 + RCTTypeSafety: adcfc8e711634c0df8058465bd0fbcad56989697 + React: d53ebbfd6d3280ff687f1c4f7c54dac1d88a6652 + React-Core: 328e5d8eab893b47ff927c5a8788c894b6a54952 + React-CoreModules: 6dc8cae7c919d7c91e26a78ddc8bf7bd8d63ff25 + React-cxxreact: 107da773ef534e63b49bbe872b9a453c86595033 + React-jsi: 1457ea0c197731415c6d740bb8732cf599655afe + React-jsiexecutor: f6940db2473bca39a8842b49f06d2a69d124da23 + React-jsinspector: 604eb8729343ebf184f49297f29b732441e9647f react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 - react-native-netinfo: fa32a5bb986924e9be82a261c262039042dde81e + react-native-netinfo: a59d8426a8484f739fe3a95dd6ad5af1435db05f react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 + react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: ad2d234b166eac167ea5a72b8520b2e75b969e4b - React-RCTAnimation: 6cc6b1474c06bbb5708d81d5aa7de8bf82d2e7c9 - React-RCTBlob: fcf733fa6359ec947e7aa03654eeb123e42dc3aa - React-RCTImage: 7471a0a6e56e9a073408de2c2840867ef9776b6a - React-RCTLinking: ca63cc48b51a3794422d136fa8884b951ff28c7f - React-RCTNetwork: fb1a0e9e2b06e7f9aeb514e9e603b0b4f24247bd - React-RCTSettings: d7c2320b334e47aad1f187c91efa17b11cf71253 - React-RCTText: 70172eebbfe602d187dacd4b2be3ba1f4ddd1426 - React-RCTVibration: 0e2697e1d9ecf96d37bb16979fe4f938e4b29c48 - ReactCommon: 60447eea63cfb8b0449773f141790b694312149c + React-RCTActionSheet: 2ab0d8d31444de3efd22ddf62710084fdb5f6507 + React-RCTAnimation: e3646eaa461d5d185425466ea67bed3e0cb00826 + React-RCTBlob: e1d6ad0f23c7f7d3b7d275682e1a0a5ba2d99f3b + React-RCTImage: b97e9b849351326887f5cb13291ed6a843fc59a4 + React-RCTLinking: ea3b68257a6a398deb6873bfa34d2c8fd7b5a655 + React-RCTNetwork: 90483487d95bc1b857ba26f656671f5ee62e9b6c + React-RCTSettings: d8ad1a9ab6a11d0d57c5fa14f2eda76ec4ea0c17 + React-RCTText: 2ee0ca2a22aa068be44586ec81e8d87a3258b4ef + React-RCTVibration: ffb1b3ebe3ee57ea15f89bb1f629f76371e2367c + ReactCommon: 10c762da3c1f81ecf70d9cf3c535f082a92c36ca ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -679,6 +690,7 @@ SPEC CHECKSUMS: RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa + RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a @@ -694,8 +706,8 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: a2dc4dfcc1202c437e48b62cc35a782216508c76 + Yoga: 44c98065ff5af48e4443cf4a5d0ed95daf4f7824 -PODFILE CHECKSUM: c2dd20b4f67edce36459865856cb810e185bdcd4 +PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 COCOAPODS: 1.8.4 diff --git a/ios/Rainbow-Bridging-Header.h b/ios/Rainbow-Bridging-Header.h new file mode 100644 index 00000000000..1b2cb5d6d09 --- /dev/null +++ b/ios/Rainbow-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 6c3d0491e35..723df0deaf7 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -32,7 +32,7 @@ 396C4BA42EEC4D0985CEBB42 /* SF-Pro-Text-SemiboldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = FA887652F27F43869229AD50 /* SF-Pro-Text-SemiboldItalic.otf */; }; 3C363E14D5DE4A028E43EA38 /* SF-Pro-Display-UltralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = DCA738BE00E04734AEDA2F07 /* SF-Pro-Display-UltralightItalic.otf */; }; 3C41C1415A994234A0FF2589 /* SF-Pro-Text-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 233322FCDC624F6FA60C4B52 /* SF-Pro-Text-Heavy.otf */; }; - 3D5D4DF2FD7C44EE962100E3 /* libRNTextInputMask.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0642ECCC7CB044FDB5A3CC32 /* libRNTextInputMask.a */; }; + 3CBE29CD2381E43900BE05AC /* Dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBE29CC2381E43900BE05AC /* Dummy.swift */; }; 4013198EBD3D4D6F8052D25E /* SF-Pro-Display-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */; }; 41804DE52CE94296995264E0 /* SF-Pro-Text-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */; }; 424410A1E84845328C5A0CAB /* Graphik-RegularItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 182DC054E3584C83822F2A82 /* Graphik-RegularItalic.otf */; }; @@ -41,8 +41,6 @@ 5D1949044DCB413FBE7AE82E /* SFMono-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2C4A4A4FB3D84F14A48989D8 /* SFMono-Light.otf */; }; 5F34DEED060F41878C4C5A59 /* SFMono-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0A8698C728414E56A3FD89A6 /* SFMono-Heavy.otf */; }; 66620AB752074CB6938E956A /* Graphik-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2DA6F347A6B540399883FF91 /* Graphik-MediumItalic.otf */; }; - 66CA6CFE237C27E200C8E3D6 /* InputMask.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66CA6CFD237C27E200C8E3D6 /* InputMask.framework */; }; - 66CA6CFF237C27E200C8E3D6 /* InputMask.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66CA6CFD237C27E200C8E3D6 /* InputMask.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6928E7805EA5404480C48640 /* Graphik-LightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D551F7BECCAF4CE3BC8C0C3D /* Graphik-LightItalic.otf */; }; 7287CE1EC33B4913AEE1F4B6 /* SFMono-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 668A9E253DAF444A90ECB997 /* SFMono-Medium.otf */; }; 7E04FF8B32EC4F2BB6BF1403 /* Graphik-ExtralightItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 273D2D617F3F43E99F8F404B /* Graphik-ExtralightItalic.otf */; }; @@ -73,30 +71,6 @@ FBDF4EF177284CF4826D7BF9 /* SF-Pro-Display-HeavyItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D7BFD847B72D414D9BE734A0 /* SF-Pro-Display-HeavyItalic.otf */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - D6A5F5F12369A413009BEF29 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNTextInputMask; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 24122D56232F2B3300BA0B17 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 12; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 66CA6CFF237C27E200C8E3D6 /* InputMask.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -137,6 +111,8 @@ 35833023DB594F1AA6A72866 /* SF-Pro-Display-Ultralight.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Ultralight.otf"; path = "../src/assets/fonts/SF-Pro-Display-Ultralight.otf"; sourceTree = ""; }; 35A24AFF4AB449C287EE66A8 /* SF-Pro-Text-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Text-Medium.otf"; sourceTree = ""; }; 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Rainbow.entitlements; path = Rainbow/Rainbow.entitlements; sourceTree = ""; }; + 3CBE29CB2381E43800BE05AC /* Rainbow-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Rainbow-Bridging-Header.h"; sourceTree = ""; }; + 3CBE29CC2381E43900BE05AC /* Dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dummy.swift; sourceTree = ""; }; 3CC4B790228B298400D827EB /* libSDWebImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSDWebImage.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D5210FEA8F00672599 /* libGoogleToolboxForMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libGoogleToolboxForMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3CE850D7210FEACE00672599 /* libnanopb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libnanopb.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -158,7 +134,6 @@ 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Light.otf"; path = "../src/assets/fonts/Graphik-Light.otf"; sourceTree = ""; }; 7CD46377E5FC4E5EBFD57D71 /* Graphik-Super.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Super.otf"; path = "../src/assets/fonts/Graphik-Super.otf"; sourceTree = ""; }; 7CEEDA7A68C24426BBAA8D77 /* Graphik-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-BoldItalic.otf"; path = "../src/assets/fonts/Graphik-BoldItalic.otf"; sourceTree = ""; }; - 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTextInputMask.xcodeproj; path = "../node_modules/react-native-text-input-mask/ios/RNTextInputMask.xcodeproj"; sourceTree = ""; }; 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-BoldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-BoldItalic.otf"; sourceTree = ""; }; 86B30DBBDA594167BFE4747E /* SF-Pro-Display-SemiboldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-SemiboldItalic.otf"; path = "../src/assets/fonts/SF-Pro-Display-SemiboldItalic.otf"; sourceTree = ""; }; 8789D635428240B5ABF282EE /* SFMono-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Bold.otf"; path = "../src/assets/fonts/SFMono-Bold.otf"; sourceTree = ""; }; @@ -207,8 +182,6 @@ files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, 0E56AA9A8843EB50FA4BDD4F /* libPods-Rainbow.a in Frameworks */, - 3D5D4DF2FD7C44EE962100E3 /* libRNTextInputMask.a in Frameworks */, - 66CA6CFE237C27E200C8E3D6 /* InputMask.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -243,6 +216,8 @@ 13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 13B07FB71A68108700A75B9A /* main.m */, + 3CBE29CC2381E43900BE05AC /* Dummy.swift */, + 3CBE29CB2381E43800BE05AC /* Rainbow-Bridging-Header.h */, ); name = Rainbow; sourceTree = ""; @@ -294,7 +269,6 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -335,14 +309,6 @@ path = Pods; sourceTree = ""; }; - D6A5F5EE2369A413009BEF29 /* Products */ = { - isa = PBXGroup; - children = ( - D6A5F5F22369A413009BEF29 /* libRNTextInputMask.a */, - ); - name = Products; - sourceTree = ""; - }; DCAC1D8CC45E468FBB7E1395 /* Resources */ = { isa = PBXGroup; children = ( @@ -417,7 +383,6 @@ 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 3CF823D3218F310D0024B77B /* ShellScript */, - 24122D56232F2B3300BA0B17 /* Embed Frameworks */, ); buildRules = ( ); @@ -439,6 +404,7 @@ TargetAttributes = { 13B07F861A680F5B00A75B9A = { DevelopmentTeam = L74NQAQB8H; + LastSwiftMigration = 1120; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Push = { @@ -463,12 +429,6 @@ mainGroup = 83CBB9F61A601CBA00E9B192; productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; - projectReferences = ( - { - ProductGroup = D6A5F5EE2369A413009BEF29 /* Products */; - ProjectRef = 838BD591AFF847ABA0F42AAC /* RNTextInputMask.xcodeproj */; - }, - ); projectRoot = ""; targets = ( 13B07F861A680F5B00A75B9A /* Rainbow */, @@ -476,16 +436,6 @@ }; /* End PBXProject section */ -/* Begin PBXReferenceProxy section */ - D6A5F5F22369A413009BEF29 /* libRNTextInputMask.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRNTextInputMask.a; - remoteRef = D6A5F5F12369A413009BEF29 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - /* Begin PBXResourcesBuildPhase section */ 13B07F8E1A680F5B00A75B9A /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -612,6 +562,7 @@ buildActionMask = 2147483647; files = ( 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, + 3CBE29CD2381E43900BE05AC /* Dummy.swift in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -635,8 +586,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; @@ -673,6 +624,9 @@ PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -681,8 +635,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -719,6 +673,8 @@ PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; @@ -764,8 +720,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = E93A96605FE51CFC31676801 /* Pods-Rainbow.staging.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -801,6 +757,8 @@ PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Staging; @@ -847,8 +805,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 15B240C971E54630F3158955 /* Pods-Rainbow.localrelease.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = ""; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -884,6 +842,8 @@ PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = LocalRelease; diff --git a/package.json b/package.json index 799ae8a3eae..714fb1a07a6 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "react-native-store-review": "^0.1.5", "react-native-svg": "9.13.3", "react-native-tcp": "^3.3.2", - "react-native-text-input-mask": "react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9", + "react-native-text-input-mask": "waqas19921/react-native-text-input-mask", "react-native-tooltip": "marcosrdz/react-native-tooltip#master", "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", diff --git a/yarn.lock b/yarn.lock index 5cab9f71867..227a4c8455a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -764,9 +764,9 @@ "@ethersproject/logger" ">=5.0.0-beta.129" "@hapi/address@2.x.x": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.2.tgz#1c794cd6dbf2354d1eb1ef10e0303f573e1c7222" - integrity sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q== + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== "@hapi/bourne@1.x.x": version "1.3.2" @@ -990,6 +990,13 @@ dependencies: prop-types "^15.5.10" +"@react-native-community/cli-debugger-ui@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-3.0.0.tgz#d01d08d1e5ddc1633d82c7d84d48fff07bd39416" + integrity sha512-m3X+iWLsK/H7/b7PpbNO33eQayR/+M26la4ZbYe1KRke5Umg4PIWsvg21O8Tw4uJcY8LA5hsP+rBi/syBkBf0g== + dependencies: + serve-static "^1.13.1" + "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" @@ -1003,12 +1010,12 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-android@^3.0.0-alpha.1", "@react-native-community/cli-platform-android@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.0-alpha.7.tgz#03c3671ab72b62a8742aa71b66cb8d594171891f" - integrity sha512-Ot/4K841f3vJZM5K7Za/bYgGeXUJyBsZZuoFvnEMAmR/tS6QCrsv8NQ7f/E3HmxvWaSEVNiiF8NiW2+qo6YDxg== +"@react-native-community/cli-platform-android@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz#e652abce79a7c1e3a8280228123e99df2c4b97b6" + integrity sha512-rNO9DmRiVhB6aP2DVUjEJv7ecriTARDZND88ny3xNVUkrD1Y+zwF6aZu3eoT52VXOxLCSLiJzz19OiyGmfqxYg== dependencies: - "@react-native-community/cli-tools" "^3.0.0-alpha.7" + "@react-native-community/cli-tools" "^3.0.0" chalk "^2.4.2" execa "^1.0.0" jetifier "^1.6.2" @@ -1017,20 +1024,20 @@ xmldoc "^1.1.2" "@react-native-community/cli-platform-ios@^2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7" - integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg== + version "2.10.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.10.0.tgz#ee494d2f9a8f8727bd5eb3c446f22ebb5429b624" + integrity sha512-z5BQKyT/bgTSdHhvsFNf++6VP50vtOOaITnNKvw4954wURjv5JOQh1De3BngyaDOoGfV1mXkCxutqAXqSeuIjw== dependencies: "@react-native-community/cli-tools" "^2.8.3" chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-platform-ios@^3.0.0-alpha.1", "@react-native-community/cli-platform-ios@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0-alpha.7.tgz#21be15fc3b8117e0e62caf1e754f2760d78cfa93" - integrity sha512-6qM5LpzhCEhkb9MC+nxrOHX2TxoN4qm8+Vg9byIW/wExl8dWCTneRUbQ5qFlkkMksS2U63LiRVSCXK08d6x5bA== +"@react-native-community/cli-platform-ios@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz#3a48a449c0c33af3b0b3d19d3256de99388fe15f" + integrity sha512-QoNVlDj8eMXRZk9uktPFsctHurQpv9jKmiu6mQii4NEtT2npE7g1hbWpRNojutBsfgmCdQGDHd9uB54eeCnYgg== dependencies: - "@react-native-community/cli-tools" "^3.0.0-alpha.7" + "@react-native-community/cli-tools" "^3.0.0" chalk "^2.4.2" js-yaml "^3.13.1" xcode "^2.0.0" @@ -1045,20 +1052,20 @@ mime "^2.4.1" node-fetch "^2.5.0" -"@react-native-community/cli-tools@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0-alpha.7.tgz#1018283598e3f2ddc785d1381ca8692ec51735a5" - integrity sha512-x4XdeMtAx7RC1YP5cqLWIggXOuzuANItWi8BD8R/ak6GWMRd3X5L2HFuLa6GDXgkWSXtoUvqOilJplhVhLRrmQ== +"@react-native-community/cli-tools@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0.tgz#fe48b80822ed7e49b8af051f9fe41e22a2a710b1" + integrity sha512-8IhQKZdf3E4CR8T7HhkPGgorot/cLkRDgneJFDSWk/wCYZAuUh4NEAdumQV7N0jLSMWX7xxiWUPi94lOBxVY9g== dependencies: chalk "^2.4.2" lodash "^4.17.5" mime "^2.4.1" node-fetch "^2.5.0" -"@react-native-community/cli-types@^3.0.0-alpha.7": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0-alpha.7.tgz#b4c19fd71824400a57c7f6758fa1f7b15eece32d" - integrity sha512-anT+l41FK7EJXOlOx8ZzIgskDuslT5A5NkMg2Kt3YzAxf8wrCBbOo5/CjnuW6pi9fvjGgB810Yw3tFSl4yZY4A== +"@react-native-community/cli-types@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652" + integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg== "@react-native-community/cli@2.9.0": version "2.9.0" @@ -1099,20 +1106,15 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^3.0.0-alpha.1": - version "3.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.0-alpha.7.tgz#df8cb6a878d106da36e4f994f9d8c3541c3834ee" - integrity sha512-gmAnmH9sqReBEvfZxk0A3gw0Ddb6UNHYvbjjyM+qgH2TbEAWCfLHLqiHNSCYxfO3hkDyz4mj/cvtb8ahFjTdIw== +"@react-native-community/cli@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.1.tgz#d7dfec14c867a17793bb981dd90eef2d8fc7808a" + integrity sha512-fh7hZHNmGciBOIJHUdS4D6/7KaIlmdJLG0i/efxm7spuMI0uviWwz4IcjNRanFbAgYu3Yp4rfke+Gm/gcHSRaA== dependencies: "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^3.0.0-alpha.7" - "@react-native-community/cli-platform-ios" "^3.0.0-alpha.7" - "@react-native-community/cli-tools" "^3.0.0-alpha.7" - "@react-native-community/cli-types" "^3.0.0-alpha.7" - "@types/mkdirp" "^0.5.2" - "@types/node-notifier" "^5.4.0" - "@types/semver" "^6.0.2" - "@types/ws" "^6.0.3" + "@react-native-community/cli-debugger-ui" "^3.0.0" + "@react-native-community/cli-tools" "^3.0.0" + "@react-native-community/cli-types" "^3.0.0" chalk "^2.4.2" command-exists "^1.2.8" commander "^2.19.0" @@ -1154,9 +1156,9 @@ integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== "@react-native-community/netinfo@^4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.0.tgz#fc0b79a226da78371158f885a2f798ff07c926be" - integrity sha512-wz39BUpExDU1kTpLlBkDwwb0Efg+uuwixToosTSarZgpzG/CmcRvWdD786TMiE5tLDd+Mpi2xh3w4FrVM8zjoA== + version "4.6.1" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.1.tgz#09960b49217d555e54144f54e63485fe55d673ad" + integrity sha512-RIcrNzVnkes6/d5jFprce8i6ruUO9+/FVZZgejlu/TSnysyFXHNJKgcIqxbKx+7XfQxfjrCGeCvsfYxrFrU0zw== "@react-navigation/core@^3.5.1": version "3.5.1" @@ -1350,6 +1352,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -1399,24 +1406,10 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/node-notifier@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-5.4.0.tgz#4e66c85eb41cce8387b4cd9c6c67852be41a99db" - integrity sha512-M1XvCG6Rwej6+W0+kWultE46YS7erOy+W7suRmXtKwLGT3ytj6YEe9lqo47nRfL1xILzg9xJpKeNczIsWR8ymw== - dependencies: - "@types/node" "*" - "@types/node@*": - version "12.12.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11" - integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w== + version "12.12.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.8.tgz#dab418655af39ce2fa99286a0bed21ef8072ac9d" + integrity sha512-XLla8N+iyfjvsa0KKV+BP/iGSoTmwxsu5Ci5sM33z9TjohF72DEz95iNvD6pPmemvbQgxAv/909G73gUn8QR7w== "@types/node@^10.3.2": version "10.17.5" @@ -1433,11 +1426,6 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== -"@types/semver@^6.0.2": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.0.tgz#d688d574400d96c5b0114968705366f431831e1a" - integrity sha512-1OzrNb4RuAzIT7wHSsgZRlMBlNsJl+do6UblR7JMW4oB7bbR+uBEYtUh7gEc/jM84GGilh68lSOokyM/zNUlBA== - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -1464,13 +1452,6 @@ "@types/unist" "*" "@types/vfile-message" "*" -"@types/ws@^6.0.3": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.3.tgz#b772375ba59d79066561c8d87500144d674ba6b3" - integrity sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w== - dependencies: - "@types/node" "*" - "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -1530,37 +1511,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -"@walletconnect/core@^1.0.0-beta.38": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.38.tgz#4716cfa87a58b707b274dbbb0601868512207ab6" - integrity sha512-fJfiK2oAWlGCCh7ULjq7fVnGsnn7/TnLsQTAzt5TwmHQ0YsZ595UYnuux4rr93IyvjIIcKkI6WMQKvcw1t/y4A== +"@walletconnect/core@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.39.tgz#43d05dbabcaeea491c0ee213ed60d2236672010f" + integrity sha512-cJSQe2Ao4okSvohNjA7Bs7Z+0BAznfVVTWBECIX/bGoSFpkAWabGY2Pn2gIYhobQMLSFpE6ZlZ4QfvlPO8HyPw== dependencies: - "@walletconnect/types" "^1.0.0-beta.38" - "@walletconnect/utils" "^1.0.0-beta.38" + "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/utils" "^1.0.0-beta.39" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.38.tgz#cbba526ebfa2ba7ce0d5496e3f1556222fba1544" - integrity sha512-rQ0ZYfcA7R4i4px3EEjSzCyHa4IswVn8642/rLxJbdgd/xXV7qW1+wjYoOdLPyEGLGUX5ojIC0e6yba3Q3y2gA== + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.39.tgz#0db212eba9087055822a89bf73d1cebc5762639e" + integrity sha512-d/QAjL/Rp1lrJeblsHpl+Fa6HTz40A93X5l6oTV0YFAG7bZDPl+OogM337WnjZWfwcn1XaKXSwsmG1NXTQn4Yg== dependencies: - "@walletconnect/core" "^1.0.0-beta.38" - "@walletconnect/types" "^1.0.0-beta.38" - "@walletconnect/utils" "^1.0.0-beta.38" + "@walletconnect/core" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/utils" "^1.0.0-beta.39" -"@walletconnect/types@^1.0.0-beta.38": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.38.tgz#6f6e23511d6821723767df18be395e52f406e6a7" - integrity sha512-155J5SXBio6Vo2zDP3ijvSmfCIJS5jp7A0bIJ+z1RAG0yG+nevCW1yLTevyRNT8U7mJSjKI/HkmjzZuW1ATiLQ== +"@walletconnect/types@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.39.tgz#e84463f32d6c450376db3d0ce56f0ece6608bfa7" + integrity sha512-YO/g1HVnFxcMNiUI9LEWEDe5uVHw8D7JzJol+bT71iXymzolnsbG32OayCJM9nHqT48Rpz1EGIno8EjW9jH2OQ== -"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.38": - version "1.0.0-beta.38" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.38.tgz#6755367bc7d9f7811f87464f636aa4f41aded36e" - integrity sha512-4esXDexo8w8QDsw3Ng378pjK88EBMVmbeYYfdWmCazKHDNmActJkVYAQtIeHFOAOG2OAAZ6IYt6fWvuw8jaPbg== +"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.39.tgz#8909b9cffa3999b046ce32cbb21b8ddca97b9183" + integrity sha512-AOlhPkK+IUzGG5iDTupKdUwNW4on1aAj5NyLMMN1+htr06hqaCV8F9HeYibSen22wdSUuLXkIQNy3SR3LPcehA== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.38" + "@walletconnect/types" "^1.0.0-beta.39" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1574,9 +1555,9 @@ Base64@~0.2.0: integrity sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg= abab@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.2.tgz#a2fba1b122c69a85caa02d10f9270c7219709a9d" - integrity sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== abbrev@1: version "1.1.1" @@ -1734,11 +1715,11 @@ ansi-escapes@^3.0.0: integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-escapes@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.1.tgz#4dccdb846c3eee10f6d64dea66273eab90c37228" - integrity sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q== + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.0.tgz#a4ce2b33d6b214b7950d8595c212f12ac9cc569d" + integrity sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg== dependencies: - type-fest "^0.5.2" + type-fest "^0.8.1" ansi-fragments@^0.2.1: version "0.2.1" @@ -1795,6 +1776,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" + integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -2648,9 +2637,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006: - version "1.0.30001008" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz#b8841b1df78a9f5ed9702537ef592f1f8772c0d9" - integrity sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw== + version "1.0.30001010" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz#397a14034d384260453cc81994f494626d34b938" + integrity sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw== capture-exit@^2.0.0: version "2.0.0" @@ -2694,6 +2683,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" @@ -2932,11 +2929,23 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" @@ -3076,7 +3085,7 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -3383,9 +3392,9 @@ decode-uri-component@^0.2.0: integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-equal@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.0.tgz#3103cdf8ab6d32cf4a8df7865458f2b8d33f3745" - integrity sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== dependencies: is-arguments "^1.0.4" is-date-object "^1.0.1" @@ -3487,9 +3496,9 @@ depd@~1.1.2: integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -3680,10 +3689,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" - integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ== +ejs@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.2.tgz#749037c4c09bd57626a6140afbe6b7e650661614" + integrity sha512-rHGwtpl67oih3xAHbZlpw5rQAt+YV1mSCu2fUZ9XNrfaGEhom7E+AUiMci+ByP4aSfuAWx7hE0BPuJLMrpXwOw== electron-to-chromium@^1.3.295: version "1.3.306" @@ -4168,9 +4177,9 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-contract-metadata@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2" - integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw== + version "1.11.0" + resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.11.0.tgz#4d23a8208d5d53be9d4c0696ed8492b505c6bca1" + integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA== ethers@^4.0.28, ethers@^4.0.39: version "4.0.39" @@ -4915,7 +4924,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -5039,9 +5048,9 @@ hammerjs@^2.0.8: integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= handlebars@^4.1.2: - version "4.5.1" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.1.tgz#8a01c382c180272260d07f2d1aa3ae745715c7ba" - integrity sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA== + version "4.5.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" + integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -5086,10 +5095,15 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== has-unicode@^2.0.0: version "2.0.1" @@ -5183,9 +5197,9 @@ hoist-non-react-statics@^2.3.1: integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== hoist-non-react-statics@^3.0.1, hoist-non-react-statics@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" - integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== + version "3.3.1" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#101685d3aff3b23ea213163f6e8e12f4f111e19f" + integrity sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw== dependencies: react-is "^16.7.0" @@ -5335,9 +5349,9 @@ import-fresh@^2.0.0: resolve-from "^3.0.0" import-fresh@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" - integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -5817,6 +5831,11 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +is-wsl@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" + integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + is@~0.2.6: version "0.2.7" resolved "https://registry.yarnpkg.com/is/-/is-0.2.7.tgz#3b34a2c48f359972f35042849193ae7264b63562" @@ -7508,12 +7527,7 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== - -"mime-db@>= 1.40.0 < 2": +mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": version "1.42.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== @@ -7531,11 +7545,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + version "2.1.25" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" + integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== dependencies: - mime-db "1.40.0" + mime-db "1.42.0" mime@1.6.0: version "1.6.0" @@ -7737,9 +7751,9 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" - integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== + version "2.1.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.7.tgz#d775e3e7c6470bbaaae3da9a647a80e228e0abf7" + integrity sha512-fmS3qwDldm4bE01HCIRqNk+f255CNjnAoeV3Zzzv0KemObHKqYgirVaZA9DtKcjogicWjYcHkJs4D5A8CjnuVQ== nanomatch@^1.2.9: version "1.2.13" @@ -7876,9 +7890,9 @@ node-pre-gyp@^0.12.0: tar "^4" node-releases@^1.1.38: - version "1.1.39" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.39.tgz#c1011f30343aff5b633153b10ff691d278d08e8d" - integrity sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA== + version "1.1.40" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.40.tgz#a94facfa8e2d612302601ca1361741d529c4515a" + integrity sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ== dependencies: semver "^6.3.0" @@ -8175,6 +8189,13 @@ open@^6.2.0, open@^6.4.0: dependencies: is-wsl "^1.1.0" +open@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.0.0.tgz#7e52999b14eb73f90f0f0807fe93897c4ae73ec9" + integrity sha512-K6EKzYqnwQzk+/dzJAQSBORub3xlBTxMz+ntpZpH/LyCa1o6KjXhuN+2npAaI9jaSmU3R1Q8NWf4KUWcyytGsQ== + dependencies: + is-wsl "^2.1.0" + opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" @@ -9037,9 +9058,9 @@ qs@~6.5.2: integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^6.4.2: - version "6.8.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.3.tgz#fd9fb7ffb068b79062b43383685611ee47777d4b" - integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ== + version "6.9.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.9.0.tgz#1c3b727c370cf00f177c99f328fda2108f8fa3dd" + integrity sha512-KG4bhCFYapExLsUHrFt+kQVEegF2agm4cpF/VNc6pZVthIfCc/GK8t8VyNIE3nyXG9DK3Tf2EGkxjR6/uRdYsA== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -9401,9 +9422,9 @@ react-native-svg@9.13.3: css-tree "^1.0.0-alpha.37" react-native-tab-view@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.0.tgz#5e249e5650502010013449ffd4e5edc18a95364b" - integrity sha512-qgexVz5eO4yaFjdkmn/sURXgVvaBo6pZD/q1eoca96SbPVbaH3WzVhF3bRUfeTHwZkXwznFTpS3JURqIFU8vQA== + version "2.10.2" + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.2.tgz#35ae92f574f2220312138f479a99ad3cbf981b6f" + integrity sha512-DJMz7WDlQiykgvojaEPM5MKFNMlGC89SMhX++wkD6iJ4TK04NyUgvUKsZYuY7u6k0o0HtG7sNeexFsbxfwhrVg== react-native-tcp@^3.3.2: version "3.3.2" @@ -9417,9 +9438,9 @@ react-native-tcp@^3.3.2: process "^0.11.9" util "^0.10.3" -react-native-text-input-mask@react-native-community/react-native-text-input-mask#abf0e7f538036bbc5719024fbd67a1efd756c4b9: - version "1.0.6" - resolved "https://codeload.github.com/react-native-community/react-native-text-input-mask/tar.gz/abf0e7f538036bbc5719024fbd67a1efd756c4b9" +react-native-text-input-mask@waqas19921/react-native-text-input-mask: + version "2.0.0" + resolved "https://codeload.github.com/waqas19921/react-native-text-input-mask/tar.gz/10af70f94cb61b092abe3911708b1c10005b6b57" react-native-tooltip@marcosrdz/react-native-tooltip#master: version "5.2.1" @@ -9448,12 +9469,12 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/8e750d75eedfe4f9465c98b9a28d1b6279257dc0" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/8797a5cfcb8a3dbd233408fb4ac86d78239f5e3f" dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" + "@react-native-community/cli" "^3.0.0" + "@react-native-community/cli-platform-android" "^3.0.0" + "@react-native-community/cli-platform-ios" "^3.0.0" abort-controller "^3.0.0" base64-js "^1.1.2" connect "^3.6.5" @@ -10586,21 +10607,21 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.0.tgz#d80e2a7fef0f15b3c9c1f57bc22bd1aabfaf2309" - integrity sha512-VlOYrBo7gKT72E3IGMzK33ddEWIHGIdyraz8nmpxC7n0ZrzGWq08pWkB8FBxlJJCm9xmP3imlZ9ElUsGbKPpvQ== + version "2.1.1" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.1.tgz#7e7f833cbb7a807dc3a76608c0d581909353852c" + integrity sha512-GSHrlyGFhcXhjdWgM+ysY7d11eZMN2gvLsW56qFOdV3ZCsZCM/tl8tt3PXu5BUvllNKPRCGyv2mbWjbZrvEdmA== dependencies: btoa "^1.2.1" - chalk "^2.4.2" - convert-source-map "^1.6.0" - ejs "^2.7.1" + chalk "^3.0.0" + convert-source-map "^1.7.0" + ejs "^2.7.2" escape-html "^1.0.3" - glob "^7.1.4" + glob "^7.1.6" lodash "^4.17.15" - open "^6.4.0" + open "^7.0.0" source-map "^0.7.3" - temp "^0.9.0" - yargs "^14.0.0" + temp "^0.9.1" + yargs "^14.2.0" source-map-resolve@^0.5.0: version "0.5.2" @@ -11027,9 +11048,9 @@ stylis@^3.5.0: integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== sudo-prompt@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a" - integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ== + version "9.1.1" + resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0" + integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA== sugarss@^2.0.0: version "2.0.0" @@ -11089,6 +11110,13 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + svg-arc-to-cubic-bezier@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz#390c450035ae1c4a0104d90650304c3bc814abe6" @@ -11194,7 +11222,7 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" -temp@^0.9.0: +temp@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697" integrity sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA== @@ -11433,11 +11461,6 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" - integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== - type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" @@ -11448,6 +11471,11 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + type@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" @@ -11477,9 +11505,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.8" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.8.tgz#5edcbcf9d49cbb0403dc49f856fe81530d65145e" - integrity sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ== + version "3.6.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.9.tgz#85d353edb6ddfb62a9d798f36e91792249320611" + integrity sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -12276,10 +12304,10 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^14.0.0: - version "14.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.0.tgz#f116a9242c4ed8668790b40759b4906c276e76c3" - integrity sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg== +yargs@^14.2.0: + version "14.2.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.1.tgz#2bb87b57c12b9afea40bb4ed9745bb9eb5031a9b" + integrity sha512-rZ00XIuGAoI58F0weHyCP3PAN17wJqdN/pF8eMp+imuP+jSdMCD5t4bSf5d5FKPvEDrK9zYlnhO7bFYKQ5UYow== dependencies: cliui "^5.0.0" decamelize "^1.2.0" From faba3f8b159fee80a5a6be8edd6c02d60da1b017 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 18 Nov 2019 17:06:22 -0500 Subject: [PATCH 527/636] Fix: swap input / output currencies when selection causes match --- src/redux/uniswap.js | 4 ++-- src/screens/ExchangeModal.js | 42 ++++++++++++------------------------ 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 86c6cb4e8f6..572ac45d997 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -115,7 +115,7 @@ export const uniswapUpdateTokenReserves = ( }; export const uniswapUpdateInputCurrency = inputCurrency => async dispatch => { - const inputReserve = await getReserve(get(inputCurrency, 'address')); + const inputReserve = await getReserve(get(inputCurrency, 'address', null)); dispatch({ payload: { inputCurrency, @@ -126,7 +126,7 @@ export const uniswapUpdateInputCurrency = inputCurrency => async dispatch => { }; export const uniswapUpdateOutputCurrency = outputCurrency => async dispatch => { - const outputReserve = await getReserve(get(outputCurrency, 'address')); + const outputReserve = await getReserve(get(outputCurrency, 'address', null)); dispatch({ payload: { outputCurrency, diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index fada15c1372..fa24df65898 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -685,25 +685,18 @@ class ExchangeModal extends Component { }); }; - setInputCurrency = (inputCurrency, force) => { - const { outputCurrency } = this.state; + setInputCurrency = (inputCurrency, userSelected = true) => { + const { inputCurrency: previousInputCurrency, outputCurrency } = this.state; - if (!isSameAsset(inputCurrency, this.state.inputCurrency)) { + if (!isSameAsset(inputCurrency, previousInputCurrency)) { this.clearForm(); } this.setState({ inputCurrency }); + this.props.uniswapUpdateInputCurrency(inputCurrency); - if (!force) { - this.props.uniswapUpdateInputCurrency(inputCurrency); - } - - if (!force && isSameAsset(inputCurrency, outputCurrency)) { - if (!isNil(inputCurrency) && !isNil(outputCurrency)) { - this.setOutputCurrency(null, true); - } else { - this.setOutputCurrency(inputCurrency, true); - } + if (userSelected && isSameAsset(inputCurrency, outputCurrency)) { + this.setOutputCurrency(previousInputCurrency, false); } }; @@ -743,13 +736,13 @@ class ExchangeModal extends Component { amountDisplay !== undefined ? amountDisplay : outputAmount, }); - setOutputCurrency = (outputCurrency, force) => { - const { allAssets } = this.props; - const { inputCurrency } = this.state; + setOutputCurrency = (outputCurrency, userSelected = true) => { + const { + inputCurrency, + outputCurrency: previousOutputCurrency, + } = this.state; - if (!force) { - this.props.uniswapUpdateOutputCurrency(outputCurrency); - } + this.props.uniswapUpdateOutputCurrency(outputCurrency); this.setState({ inputAsExactAmount: true, @@ -757,15 +750,8 @@ class ExchangeModal extends Component { showConfirmButton: !!outputCurrency, }); - if (!force && isSameAsset(inputCurrency, outputCurrency)) { - const outputAddress = toLower(outputCurrency.address); - const asset = ethereumUtils.getAsset(allAssets, outputAddress); - - if (!isNil(asset) && !isNil(inputCurrency) && !isNil(outputCurrency)) { - this.setInputCurrency(null, true); - } else { - this.setInputCurrency(outputCurrency, true); - } + if (userSelected && isSameAsset(inputCurrency, outputCurrency)) { + this.setInputCurrency(previousOutputCurrency, false); } }; From 110566821074782b05ab0d32365e508762a0a7e5 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 18 Nov 2019 19:23:04 -0500 Subject: [PATCH 528/636] Fix: input focus after selecting currencies (https://linear.app/issue/RAI-73) - The initial focus of the input was not happening, causing issues with the keyboard transition - Added extra logic to handle the case when an asset and null are swapped during currency selection; the input focus should not be on the last focused at that point as it will be unselectable without a currency --- src/screens/ExchangeModal.js | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 23bde7617a8..8e2e5bc170e 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -77,6 +77,8 @@ const isSameAsset = (a, b) => { return assetA === assetB; }; +const getNativeTag = field => get(field, '_nativeTag'); + class ExchangeModal extends Component { static propTypes = { accountAddress: PropTypes.string, @@ -143,10 +145,9 @@ class ExchangeModal extends Component { this.lastFocusedInput === null ) { this.inputFocusInteractionHandle = InteractionManager.runAfterInteractions( - this.inputFieldRef.focus + this.focusInputField ); } - const isNewState = isNewValueForObjectPaths(this.state, nextState, [ 'approvalCreationTimestamp', 'approvalEstimatedTimeInMs', @@ -254,6 +255,12 @@ class ExchangeModal extends Component { if (this.outputFieldRef) this.outputFieldRef.clear(); }; + focusInputField = () => { + if (this.inputFieldRef) { + this.inputFieldRef.focus(); + } + }; + getCurrencyAllowance = async () => { const { accountAddress, @@ -631,9 +638,31 @@ class ExchangeModal extends Component { } }; + findNextFocused = () => { + const inputRefTag = getNativeTag(this.inputFieldRef); + const nativeInputRefTag = getNativeTag(this.nativeFieldRef); + const outputRefTag = getNativeTag(this.outputFieldRef); + + const lastFocusedIsInputType = + this.lastFocusedInput === inputRefTag || + this.lastFocusedInput === nativeInputRefTag; + + const lastFocusedIsOutputType = this.lastFocusedInput === outputRefTag; + + if (lastFocusedIsInputType && !this.state.inputCurrency) { + return outputRefTag; + } + + if (lastFocusedIsOutputType && !this.state.outputCurrency) { + return inputRefTag; + } + + return this.lastFocusedInput; + }; + handleKeyboardManagement = () => { if (this.lastFocusedInput !== TextInput.State.currentlyFocusedField()) { - TextInput.State.focusTextInput(this.lastFocusedInput); + TextInput.State.focusTextInput(this.findNextFocused()); this.lastFocusedInput = null; } }; From e1a6cffb1ffc87d4749089ec00b683ff79b85880 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 18 Nov 2019 21:24:37 -0500 Subject: [PATCH 529/636] Add countdown animation for unlocking spinner --- .../hold-to-authorize/UnlockingSpinner.js | 67 +++++++++++++------ 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/src/components/buttons/hold-to-authorize/UnlockingSpinner.js b/src/components/buttons/hold-to-authorize/UnlockingSpinner.js index 29b0ef97b46..3d2d91458b6 100644 --- a/src/components/buttons/hold-to-authorize/UnlockingSpinner.js +++ b/src/components/buttons/hold-to-authorize/UnlockingSpinner.js @@ -1,33 +1,58 @@ +import AnimateNumber from '@bankify/react-native-animate-number'; import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useCallback } from 'react'; import { colors } from '../../../styles'; import { ColumnWithMargins, RowWithMargins } from '../../layout'; import Spinner from '../../Spinner'; import { Text } from '../../text'; -const UnlockingSpinner = ({ timeRemaining }) => ( - - - - - Unlocking - - - {timeRemaining && ( - - {`~ ${timeRemaining} Remaining`} - - )} - +const renderCountdownText = animatedTimeRemaining => ( + + {`~ ${animatedTimeRemaining}s Remaining`} + ); +const UnlockingSpinner = ({ interval, timeRemaining }) => { + const formatter = useCallback( + animatedNumber => + Math.max(Math.ceil((timeRemaining - animatedNumber) / interval), 0), + [interval, timeRemaining] + ); + + return ( + + + + + Unlocking + + + {timeRemaining && ( + + )} + + ); +}; + UnlockingSpinner.propTypes = { - timeRemaining: PropTypes.string, + interval: PropTypes.number, + timeRemaining: PropTypes.number, +}; + +UnlockingSpinner.defaultProps = { + interval: 1000, }; export default React.memo(UnlockingSpinner); From 26421d5160aacdb40d9cacc0ea3af91169da3ce2 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 19 Nov 2019 19:21:35 +0100 Subject: [PATCH 530/636] add easing as prop, and make posiible to use values bigger than 1 --- .../animations/ButtonPressAnimation.js | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index ca7cc2c34ed..4a06415c2b4 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -28,6 +28,7 @@ const { createAnimatedComponent, divide, eq, + or, event, greaterThan, lessThan, @@ -225,7 +226,9 @@ export default class ButtonPressAnimation extends Component { offsetY = Math.floor(height / 2) * (transformOrigin === 'top' ? -1 : 1); } - const scaleDiff = 1 - (this.props.defaultScale - this.props.scaleTo) / 2; + const scaleDiff = + this.props.defaultScale - + (this.props.defaultScale - this.props.scaleTo) / 2; const opacity = scaleTo > defaultScale @@ -270,7 +273,16 @@ export default class ButtonPressAnimation extends Component { ]), cond(contains([FAILED, CANCELLED, END], this.gestureState), [ cond( - lessThan(this.scale, scaleDiff), + or( + and( + greaterThan(this.props.defaultScale, this.props.scaleTo), + lessThan(this.scale, scaleDiff) + ), + and( + lessThan(this.props.defaultScale, this.props.scaleTo), + greaterThan(this.scale, scaleDiff) + ) + ), block([stopClock(this.clock), set(this.shouldSpring, 0)]) ), call([], this.reset), @@ -288,26 +300,38 @@ export default class ButtonPressAnimation extends Component { ) ), cond( - and(greaterThan(this.scale, 0), eq(this.shouldSpring, 1)), + eq(this.shouldSpring, 1), set( this.scale, timing({ clock: this.clock, duration: this.props.duration, - easing: Easing.bezier(0.25, 0.46, 0.45, 0.94), + easing: this.props.easing, from: this.scale, to: this.props.scaleTo, }) ) ), cond( - and(lessThan(this.scale, 1), eq(this.shouldSpring, 0)), + and( + or( + and( + greaterThan(this.props.defaultScale, this.props.scaleTo), + lessThan(this.scale, this.props.defaultScale) + ), + and( + lessThan(this.props.defaultScale, this.props.scaleTo), + greaterThan(this.scale, this.props.defaultScale) + ) + ), + eq(this.shouldSpring, 0) + ), set( this.scale, timing({ clock: this.clockReversed, duration: this.props.duration, - easing: Easing.bezier(0.25, 0.46, 0.45, 0.94), + easing: this.props.easing, from: this.scale, to: this.props.defaultScale, }) From 7a6ee483af699cd2bc595c989452c4c0f0c12e10 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 19 Nov 2019 15:40:01 -0500 Subject: [PATCH 531/636] Fix: alphabetization of swap receive inputs --- src/hoc/withUniswapAssets.js | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 1531d93b9c7..708e7195bbd 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -2,11 +2,11 @@ import { concat, filter, get, - indexOf, + includes, map, partition, - property, sortBy, + toLower, values, } from 'lodash'; import { connect } from 'react-redux'; @@ -22,28 +22,30 @@ const uniswapFavoritesSelector = state => state.favorites; const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); +const includeExchangeAddress = asset => ({ + ...asset, + exchangeAddress: get(uniswapAssetsClean, `${asset.address}.exchangeAddress`), +}); + +const lowerAssetName = asset => toLower(asset.name); + +const includeFavorite = asset => ({ + ...asset, + favorite: true, +}); + const withAssetsAvailableOnUniswap = allAssets => { const availableAssets = filter(allAssets, filterUniswapAssetsByAvailability); - const assetsAvailableOnUniswap = map(availableAssets, asset => ({ - ...asset, - exchangeAddress: get( - uniswapAssetsClean, - `${asset.address}.exchangeAddress` - ), - })); + const assetsAvailableOnUniswap = map(availableAssets, includeExchangeAddress); return { assetsAvailableOnUniswap }; }; const withSortedUniswapAssets = (unsortedUniswapAssets, favorites) => { - const sortedAssets = sortBy(values(unsortedUniswapAssets), property('name')); - const [favoriteAssets, remainingAssets] = partition( - sortedAssets, - asset => indexOf(favorites, asset.address) > -1 + const sortedAssets = sortBy(values(unsortedUniswapAssets), lowerAssetName); + const [favoriteAssets, remainingAssets] = partition(sortedAssets, asset => + includes(favorites, asset.address) ); - const labeledFavorites = map(favoriteAssets, asset => ({ - ...asset, - favorite: true, - })); + const labeledFavorites = map(favoriteAssets, includeFavorite); return { sortedUniswapAssets: concat(labeledFavorites, remainingAssets), }; From faba58bd6f40b84caf07fb161a1488a48669bd1c Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 19 Nov 2019 15:23:11 -0500 Subject: [PATCH 532/636] ExchangeModal should update on pending approvals change Remove redundant approval amount checks --- src/hoc/withUniswapAssets.js | 7 ++- src/redux/uniswap.js | 84 ++++++------------------------------ src/screens/ExchangeModal.js | 3 +- 3 files changed, 21 insertions(+), 73 deletions(-) diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 708e7195bbd..679abe11ad5 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -22,9 +22,12 @@ const uniswapFavoritesSelector = state => state.favorites; const filterUniswapAssetsByAvailability = ({ address }) => uniswapAssetAddresses.includes(address); -const includeExchangeAddress = asset => ({ +export const includeExchangeAddress = asset => ({ ...asset, - exchangeAddress: get(uniswapAssetsClean, `${asset.address}.exchangeAddress`), + exchangeAddress: get( + uniswapAssetsClean, + `[${toLower(asset.address)}].exchangeAddress` + ), }); const lowerAssetName = asset => toLower(asset.name); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 572ac45d997..f7cc073ea0e 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -3,7 +3,6 @@ import { compact, concat, filter, - fromPairs, get, invertBy, isEmpty, @@ -11,11 +10,9 @@ import { map, mapValues, omit, - reject, toLower, uniq, without, - zip, } from 'lodash'; import { getAllowances, @@ -33,9 +30,7 @@ import { saveUniswapPendingApprovals, } from '../handlers/localstorage/uniswap'; import { getLiquidityInfo, getReserve } from '../handlers/uniswap'; -import TransactionStatusTypes from '../helpers/transactionStatusTypes'; -import { uniswapAssetsClean } from '../references'; -import { contractUtils, promiseUtils } from '../utils'; +import { includeExchangeAddress } from '../hoc/withUniswapAssets'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -66,6 +61,12 @@ const UNISWAP_UPDATE_LIQUIDITY_TOKENS = const UNISWAP_CLEAR_STATE = 'uniswap/UNISWAP_CLEAR_STATE'; // -- Actions --------------------------------------------------------------- // +const extractTransactionHash = txn => toLower(txn.hash).split('-')[0]; +const firstItem = value => get(value, '[0]'); +const lowerAddress = asset => toLower(asset.address); +const hasTokenQuantity = token => token.quantity > 0; +const getAssetCode = token => get(token, 'asset.asset_code'); + export const uniswapLoadState = () => async (dispatch, getState) => { const { accountAddress, network } = getState().settings; dispatch({ type: UNISWAP_LOAD_REQUEST }); @@ -168,43 +169,15 @@ export const uniswapAddPendingApproval = ( saveUniswapPendingApprovals(updatedPendingApprovals, accountAddress, network); }; -const updateAllowancesForSuccessfulTransactions = assetAddresses => ( - dispatch, - getState -) => { - if (isEmpty(assetAddresses)) return; - const { accountAddress } = getState().settings; - promiseUtils - .PromiseAllWithFails( - map(assetAddresses, async assetAddress => { - const asset = uniswapAssetsClean[assetAddress]; - return contractUtils.getAllowance( - accountAddress, - asset, - asset.exchangeAddress - ); - }) - ) - .then(allowances => { - const tokenAddressAllowances = fromPairs(zip(assetAddresses, allowances)); - dispatch(uniswapUpdateAllowances(tokenAddressAllowances)); - }) - .catch(() => {}); -}; - export const uniswapRemovePendingApproval = transactions => ( dispatch, getState ) => { - const newTransactions = map(transactions, txn => ({ - ...txn, - hash: toLower(txn.hash).split('-')[0], - })); + const loweredTxHashes = map(transactions, extractTransactionHash); const { pendingApprovals } = getState().uniswap; - const loweredTxHashes = map(newTransactions, txn => txn.hash); const invertedPendingApprovals = mapValues( invertBy(pendingApprovals, value => value.hash), - value => get(value, '[0]') + firstItem ); const updatedAddresses = compact( map(loweredTxHashes, hash => invertedPendingApprovals[hash]) @@ -215,19 +188,6 @@ export const uniswapRemovePendingApproval = transactions => ( payload: updatedPendingApprovals, type: UNISWAP_UPDATE_PENDING_APPROVALS, }); - const successfulApprovalHashes = map( - reject( - newTransactions, - txn => txn.status === TransactionStatusTypes.failed - ), - txn => toLower(txn.hash) - ); - const successfullyApprovedAddresses = compact( - map(successfulApprovalHashes, hash => invertedPendingApprovals[hash]) - ); - dispatch( - updateAllowancesForSuccessfulTransactions(successfullyApprovedAddresses) - ); const { accountAddress, network } = getState().settings; saveUniswapPendingApprovals(updatedPendingApprovals, accountAddress, network); }; @@ -267,19 +227,8 @@ export const uniswapUpdateAllowances = tokenAddressAllowances => ( export const uniswapUpdateAssets = assets => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - const uniswapAssetPrices = map(assets, asset => { - const loweredAddress = toLower(asset.address); - return { - ...asset, - exchangeAddress: get( - uniswapAssetsClean, - `[${loweredAddress}].exchangeAddress` - ), - }; - }); - const mappedAssets = keyBy(uniswapAssetPrices, asset => - toLower(asset.address) - ); + const uniswapAssetPrices = map(assets, includeExchangeAddress); + const mappedAssets = keyBy(uniswapAssetPrices, lowerAddress); dispatch({ payload: mappedAssets, type: UNISWAP_UPDATE_ASSETS, @@ -310,15 +259,12 @@ export const uniswapUpdateLiquidityTokens = ( liquidityTokens, appendOrChange ) => (dispatch, getState) => { - let updatedLiquidityTokens = filter( - liquidityTokens, - token => token.quantity > 0 - ); + let updatedLiquidityTokens = filter(liquidityTokens, hasTokenQuantity); if (appendOrChange) { const { liquidityTokens: existingLiquidityTokens } = getState().uniswap; updatedLiquidityTokens = uniq( concat(existingLiquidityTokens, ...updatedLiquidityTokens), - token => get(token, 'asset.asset_code') + getAssetCode ); } const { accountAddress, network } = getState().settings; @@ -341,9 +287,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => dispatch({ type: UNISWAP_UPDATE_REQUEST }); - const exchangeContracts = map(liquidityTokens, x => - get(x, 'asset.asset_code') - ); + const exchangeContracts = map(liquidityTokens, getAssetCode); return getLiquidityInfo(accountAddress, exchangeContracts) .then(liquidityInfo => { saveLiquidityInfo(liquidityInfo, accountAddress, network); diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 8e2e5bc170e..d203e86cbd0 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -133,6 +133,7 @@ class ExchangeModal extends Component { const isNewProps = isNewValueForObjectPaths(this.props, nextProps, [ 'inputReserve.token.address', 'outputReserve.token.address', + 'pendingApprovals', ]); // Code below is a workaround. We noticed that opening keyboard while animation @@ -286,7 +287,7 @@ class ExchangeModal extends Component { uniswapUpdateAllowances({ [toLower(inputAddress)]: allowance }); } const isAssetApproved = greaterThan(allowance, 0); - if (greaterThan(allowance, 0)) { + if (isAssetApproved) { return this.setState({ approvalCreationTimestamp: null, approvalEstimatedTimeInMs: null, From 64208128f80545b0d1e615fb82e3c2af97355874 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 20 Nov 2019 18:28:33 -0500 Subject: [PATCH 533/636] Create a contacts redux --- src/components/coin-row/TransactionCoinRow.js | 11 +-- .../contacts/SwipeableContactRow.js | 7 +- .../contacts/showDeleteContactActionSheet.js | 10 ++- .../expanded-state/AddContactState.js | 18 +++-- src/components/fields/AddressField.js | 1 - src/components/send/SendContactList.js | 76 ++++++----------- src/components/send/SendHeader.js | 18 ++--- src/handlers/localstorage/contacts.js | 81 ++----------------- src/helpers/emojiHandler.js | 9 --- src/hoc/index.js | 1 + src/hoc/withContacts.js | 29 +++++++ src/hoc/withDataInit.js | 5 +- src/redux/contacts.js | 74 +++++++++++++++++ src/redux/reducers.js | 2 + src/screens/ExpandedAssetScreen.js | 26 ------ src/screens/SendSheet.js | 33 ++++---- 16 files changed, 193 insertions(+), 208 deletions(-) create mode 100644 src/hoc/withContacts.js create mode 100644 src/redux/contacts.js diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 343aa2cbf4a..63dc13168bf 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -1,12 +1,12 @@ -import { compact, get } from 'lodash'; +import { compact, get, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { compose, mapProps, onlyUpdateForKeys, withHandlers } from 'recompact'; import { Linking } from 'react-native'; import { withNavigation } from 'react-navigation'; import { css } from 'styled-components/primitives'; -import { getSelectedLocalContact } from '../../handlers/localstorage/contacts'; import TransactionStatusTypes from '../../helpers/transactionStatusTypes'; +import { withContacts } from '../../hoc'; import { colors } from '../../styles'; import { abbreviations } from '../../utils'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; @@ -88,11 +88,12 @@ export default compose( pending, ...props, })), + withContacts, withNavigation, withHandlers({ - onPressTransaction: ({ hash, item, navigation }) => async () => { + onPressTransaction: ({ contacts, hash, item, navigation }) => async () => { const { from, to, status } = item; - const isSent = status === 'sent'; + const isSent = status === TransactionStatusTypes.sent; const headerInfo = { address: '', @@ -101,7 +102,7 @@ export default compose( }; const contactAddress = isSent ? to : from; - const contact = await getSelectedLocalContact(contactAddress); + const contact = contacts[toLower(contactAddress)]; let contactColor = 0; if (contact) { diff --git a/src/components/contacts/SwipeableContactRow.js b/src/components/contacts/SwipeableContactRow.js index 440bc8bd7be..ecd15707a12 100644 --- a/src/components/contacts/SwipeableContactRow.js +++ b/src/components/contacts/SwipeableContactRow.js @@ -62,10 +62,11 @@ export default class SwipeableContactRow extends PureComponent { color: PropTypes.number, navigation: PropTypes.object, nickname: PropTypes.string, - onChange: PropTypes.func, onPress: PropTypes.func, + onSelectEdit: PropTypes.func, onTouch: PropTypes.func, onTransitionEnd: PropTypes.func, + removeContact: PropTypes.func, selectedInputId: PropTypes.object, }; @@ -74,12 +75,12 @@ export default class SwipeableContactRow extends PureComponent { close = () => this.swipeableRef.close(); handleDeleteContact = async () => { - const { address, nickname, onChange } = this.props; + const { address, nickname, removeContact } = this.props; this.close(); showDeleteContactActionSheet({ address, nickname, - onDelete: onChange, + removeContact, }); }; diff --git a/src/components/contacts/showDeleteContactActionSheet.js b/src/components/contacts/showDeleteContactActionSheet.js index 23c9cd2ebce..5b667719c38 100644 --- a/src/components/contacts/showDeleteContactActionSheet.js +++ b/src/components/contacts/showDeleteContactActionSheet.js @@ -1,8 +1,12 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import { deleteLocalContact } from '../../handlers/localstorage/contacts'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; -const showDeleteContactActionSheet = ({ address, nickname, onDelete }) => +const showDeleteContactActionSheet = ({ + address, + nickname, + onDelete, + removeContact, +}) => showActionSheetWithOptions( { cancelButtonIndex: 1, @@ -13,7 +17,7 @@ const showDeleteContactActionSheet = ({ address, nickname, onDelete }) => }, async buttonIndex => { if (buttonIndex === 0) { - await deleteLocalContact(address); + removeContact(address); ReactNativeHapticFeedback.trigger('notificationSuccess'); onDelete(); } diff --git a/src/components/expanded-state/AddContactState.js b/src/components/expanded-state/AddContactState.js index 1bfc7868866..7c18e507572 100644 --- a/src/components/expanded-state/AddContactState.js +++ b/src/components/expanded-state/AddContactState.js @@ -3,8 +3,7 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { compose, onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components/primitives'; -import { addNewLocalContact } from '../../handlers/localstorage/contacts'; -import { withAccountData, withAccountSettings } from '../../hoc'; +import { withAccountData, withAccountSettings, withContacts } from '../../hoc'; import { colors, margin, padding } from '../../styles'; import { abbreviations, deviceUtils } from '../../utils'; import { ButtonPressAnimation } from '../animations'; @@ -38,10 +37,11 @@ class AddContactState extends PureComponent { address: PropTypes.string, color: PropTypes.number, contact: PropTypes.object, + contactsAddOrUpdate: PropTypes.func, navigation: PropTypes.object, onCloseModal: PropTypes.func, onRefocusInput: PropTypes.func, - onUnmountModal: PropTypes.func, + removeContact: PropTypes.func, }; state = { @@ -64,11 +64,16 @@ class AddContactState extends PureComponent { inputRef = undefined; handleAddContact = async () => { - const { address, navigation, onCloseModal } = this.props; + const { + address, + contactsAddOrUpdate, + navigation, + onCloseModal, + } = this.props; const { color, value } = this.state; if (value.length > 0) { - await addNewLocalContact(address, value, color); + contactsAddOrUpdate(address, value, color); if (onCloseModal) { onCloseModal(); } @@ -77,7 +82,6 @@ class AddContactState extends PureComponent { }; handleCancel = () => { - this.props.onUnmountModal('', 0, false); if (this.props.onCloseModal) { this.props.onCloseModal(); } @@ -110,6 +114,7 @@ class AddContactState extends PureComponent { address: this.props.address, nickname: this.state.value, onDelete: this.handleCancel, + removeContact: this.props.removeContact, }); handleFocusInput = () => { @@ -218,5 +223,6 @@ class AddContactState extends PureComponent { export default compose( withAccountData, withAccountSettings, + withContacts, onlyUpdateForKeys(['price', 'subtitle']) )(AddContactState); diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 5f3bb476126..7a99260c0b5 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -33,7 +33,6 @@ export default withNavigation( static propTypes = { address: PropTypes.string, autoFocus: PropTypes.bool, - contacts: PropTypes.array, currentContact: PropTypes.object, onChange: PropTypes.func.isRequired, }; diff --git a/src/components/send/SendContactList.js b/src/components/send/SendContactList.js index 4c4e19fc6ea..177e2327172 100644 --- a/src/components/send/SendContactList.js +++ b/src/components/send/SendContactList.js @@ -1,3 +1,4 @@ +import { toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { @@ -7,10 +8,10 @@ import { } from 'recyclerlistview'; import { withNavigation } from 'react-navigation'; import { compose } from 'recompose'; -import { removeFirstEmojiFromString } from '../../helpers/emojiHandler'; import { withSelectedInput } from '../../hoc'; import { sheetVerticalOffset } from '../../navigation/transitions/effects'; import { deviceUtils } from '../../utils'; +import { filterList } from '../../utils/search'; import { FlyInAnimation } from '../animations'; import { SwipeableContactRow } from '../contacts'; import SendEmptyState from './SendEmptyState'; @@ -29,7 +30,7 @@ class SendContactList extends Component { currentInput: PropTypes.string, navigation: PropTypes.object, onPressContact: PropTypes.func, - onUpdateContacts: PropTypes.func, + removeContact: PropTypes.func, selectedInputId: PropTypes.object, }; @@ -67,10 +68,8 @@ class SendContactList extends Component { } componentWillReceiveProps = props => { - let newAssets = Object.assign([], props.allAssets); - newAssets.reverse(); - newAssets = this.filterContactList( - newAssets, + const newAssets = filterList( + props.allAssets, props.currentInput, 'nickname' ); @@ -90,42 +89,10 @@ class SendContactList extends Component { if (this.touchedContact && this.contacts[this.touchedContact]) { this.contacts[this.touchedContact].close(); } - this.touchedContact = address; + this.touchedContact = toLower(address); this.recentlyRendered = false; }; - filterContactList = ( - list, - searchPhrase, - searchParameter = false, - separator = ' ' - ) => { - const filteredList = []; - if (list && searchPhrase.length > 0) { - for (let i = 0; i < list.length; i++) { - const searchedItem = searchParameter - ? list[i][searchParameter] - : list[i]; - const splitedWordList = searchedItem.split(separator); - splitedWordList.push(searchedItem); - splitedWordList.push(removeFirstEmojiFromString(searchedItem).join('')); - for (let j = 0; j < splitedWordList.length; j++) { - if ( - splitedWordList[j] - .toLowerCase() - .startsWith(searchPhrase.toLowerCase()) - ) { - filteredList.push(list[i]); - break; - } - } - } - } else { - return list; - } - return filteredList; - }; - handleScroll = (event, offsetX, offsetY) => { position = offsetY; }; @@ -153,20 +120,23 @@ class SendContactList extends Component { }); }; - renderItem = (type, item) => ( - { - this.contacts[item.address] = component; - }} - {...item} - /> - ); + renderItem = (type, item) => { + const { inputRef, navigation, onPressContact, removeContact } = this.props; + return ( + { + this.contacts[toLower(item.address)] = component; + }} + removeContact={removeContact} + {...item} + /> + ); + }; render = () => ( { let contact = DefaultContactItem; - if (recipient && contacts.length) { - const localContact = find(contacts, ({ address }) => address === recipient); - contact = localContact || DefaultContactItem; + if (recipient && !isEmpty(contacts)) { + contact = get(contacts, `${[toLower(recipient)]}`, DefaultContactItem); } return { contact }; @@ -85,16 +84,16 @@ class SendHeader extends PureComponent { navigation: PropTypes.any, onChangeAddressInput: PropTypes.func, onPressPaste: PropTypes.func, - onUpdateContacts: PropTypes.func, recipient: PropTypes.string, + removeContact: PropTypes.func, selectedInputId: PropTypes.object, setSelectedInputId: PropTypes.func, }; handleConfirmDeleteContactSelection = async buttonIndex => { + const { removeContact, recipient } = this.props; if (buttonIndex === 0) { - await deleteLocalContact(this.props.recipient); - this.props.onUpdateContacts(); + removeContact(recipient); } }; @@ -111,7 +110,7 @@ class SendHeader extends PureComponent { }; navigateToContact = (contact = {}) => { - const { navigation, onUpdateContacts, recipient } = this.props; + const { navigation, recipient } = this.props; const refocusCallback = this.props.selectedInputId && this.props.selectedInputId.isFocused() && @@ -128,7 +127,6 @@ class SendHeader extends PureComponent { asset: [], color, contact: isEmpty(contact) ? false : contact, - onCloseModal: onUpdateContacts, onRefocusInput: refocusCallback, type: 'contact', }); diff --git a/src/handlers/localstorage/contacts.js b/src/handlers/localstorage/contacts.js index b52b0d1a001..63fe9ef8282 100644 --- a/src/handlers/localstorage/contacts.js +++ b/src/handlers/localstorage/contacts.js @@ -1,86 +1,17 @@ -import { find, orderBy, toLower } from 'lodash'; -import { - removeFirstEmojiFromString, - makeSpaceAfterFirstEmoji, -} from '../../helpers/emojiHandler'; import { getGlobal, saveGlobal } from './common'; const LOCAL_CONTACTS = 'localContacts'; -/** - * @desc get local contacts - * @return {Table} - */ -export const getLocalContacts = () => getGlobal(LOCAL_CONTACTS, []); - -/** - * @desc get local contacts - * @return {Number} - */ -export const getNumberOfLocalContacts = async () => { - const contacts = await getLocalContacts(); - return contacts.length; -}; +const contactsVersion = '0.2.1'; /** - * @desc get local contacts - * @param {String} [address] + * @desc get contacts * @return {Object} */ -export const getSelectedLocalContact = async address => { - const contacts = await getLocalContacts(); - const localContact = find(contacts, contact => contact.address === address); - return localContact || false; -}; - -/** - * @desc add new contact to the local contacts - * @param {String} [address] - * @param {String} [nickname] - * @param {Number} [color] - * @return {Void} - */ -export const addNewLocalContact = async (address, nickname, color) => { - let contacts = await getLocalContacts(); - for (let i = 0; i < contacts.length; i++) { - if (contacts[i].address === address) { - contacts.splice(i, 1); - i--; - } - } - - contacts.push({ - address, - color, - nickname: makeSpaceAfterFirstEmoji(nickname), - }); - - const sortedContacts = orderBy( - contacts, - [ - contact => { - let newContact = toLower(contact.nickname); - newContact = removeFirstEmojiFromString(newContact); - return newContact; - }, - ], - ['desc'] - ); - await saveGlobal(LOCAL_CONTACTS, sortedContacts); -}; +export const getContacts = () => getGlobal(LOCAL_CONTACTS, [], contactsVersion); /** - * @desc delete contact from the local contacts - * @param {String} [address] - * @return {Void} + * @desc save contacts */ -export const deleteLocalContact = async address => { - const contacts = await getLocalContacts(); - for (let i = 0; i < contacts.length; i++) { - if (contacts[i].address === address) { - contacts.splice(i, 1); - i--; - } - } - await saveGlobal(LOCAL_CONTACTS, contacts); -}; +export const saveContacts = contacts => + saveGlobal(LOCAL_CONTACTS, contacts, contactsVersion); diff --git a/src/helpers/emojiHandler.js b/src/helpers/emojiHandler.js index 70f6e9a05fe..9cf4e9a55df 100644 --- a/src/helpers/emojiHandler.js +++ b/src/helpers/emojiHandler.js @@ -2,15 +2,6 @@ import GraphemeSplitter from 'grapheme-splitter'; const regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g; -export const makeSpaceAfterFirstEmoji = string => { - const grapheme = new GraphemeSplitter().splitGraphemes(string); - const first = grapheme[0]; - - return grapheme[1] !== ' ' && first.search(regex) > -1 - ? string.replace(first, `${first} `) - : string; -}; - export const removeFirstEmojiFromString = string => { const grapheme = new GraphemeSplitter().splitGraphemes(string); const first = grapheme[0]; diff --git a/src/hoc/index.js b/src/hoc/index.js index 5c77e3ca374..c7eab59d81e 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -6,6 +6,7 @@ export { default as withActionSheetManager } from './withActionSheetManager'; export { default as withAppState } from './withAppState'; export { default as withBlockedHorizontalSwipe } from './withBlockedHorizontalSwipe'; export { default as withBlurTransitionProps } from './withBlurTransitionProps'; +export { default as withContacts } from './withContacts'; export { default as withDataInit } from './withDataInit'; export { default as withDeepLink } from './withDeepLink'; export { default as withFabSelection } from './withFabSelection'; diff --git a/src/hoc/withContacts.js b/src/hoc/withContacts.js new file mode 100644 index 00000000000..3741713b630 --- /dev/null +++ b/src/hoc/withContacts.js @@ -0,0 +1,29 @@ +import { sortBy, values } from 'lodash'; +import { connect } from 'react-redux'; +import { compose, withProps } from 'recompact'; +import { createSelector } from 'reselect'; +import { contactsAddOrUpdate, removeContact } from '../redux/contacts'; + +const contactsSelector = state => state.contacts; + +const withSortedContacts = contacts => ({ + sortedContacts: sortBy(values(contacts), 'name'), +}); + +const withSortedContactsSelector = createSelector( + [contactsSelector], + withSortedContacts +); + +const mapStateToProps = ({ contacts: { contacts } }) => ({ + contacts, +}); + +export default Component => + compose( + connect(mapStateToProps, { + contactsAddOrUpdate, + removeContact, + }), + withProps(withSortedContactsSelector) + )(Component); diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 8d43fda89f6..a258c3732c4 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -12,6 +12,7 @@ import { gasClearState, gasPricesInit } from '../redux/gas'; import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; import { setIsWalletEthZero } from '../redux/isWalletEthZero'; import { nonceClearState } from '../redux/nonce'; +import { contactsLoadState } from '../redux/contacts'; import { clearOpenStateSettings, openStateSettingsLoadState, @@ -47,6 +48,7 @@ export default Component => connect(null, { clearIsWalletEmpty, clearOpenStateSettings, + contactsLoadState, dataClearState, dataLoadState, explorerClearState, @@ -124,7 +126,8 @@ export default Component => const p4 = ownProps.walletConnectLoadState(); const p5 = ownProps.uniswapLoadState(); const p6 = ownProps.requestsLoadState(); - return promiseUtils.PromiseAllWithFails([p1, p2, p3, p4, p5, p6]); + const p7 = ownProps.contactsLoadState(); + return promiseUtils.PromiseAllWithFails([p1, p2, p3, p4, p5, p6, p7]); }, refreshAccountData: ownProps => async () => { try { diff --git a/src/redux/contacts.js b/src/redux/contacts.js new file mode 100644 index 00000000000..5e972e0a7d2 --- /dev/null +++ b/src/redux/contacts.js @@ -0,0 +1,74 @@ +import { omit, toLower } from 'lodash'; +import { getContacts, saveContacts } from '../handlers/localstorage/contacts'; + +// -- Constants --------------------------------------- // +const CONTACTS_UPDATE = 'contacts/CONTACTS_UPDATE'; +const CONTACTS_LOAD = 'contacts/CONTACTS_LOAD'; +const CONTACTS_CLEAR_STATE = 'contacts/CONTACTS_CLEAR_STATE'; + +// -- Actions ---------------------------------------- // +export const contactsLoadState = () => async dispatch => { + try { + const contacts = await getContacts(); + dispatch({ + payload: contacts, + type: CONTACTS_LOAD, + }); + // eslint-disable-next-line no-empty + } catch (error) {} +}; + +export const contactsAddOrUpdate = (address, nickname, color) => ( + dispatch, + getState +) => { + const loweredAddress = toLower(address); + const { contacts } = getState().contacts; + const updatedContacts = { + ...contacts, + [loweredAddress]: { + address: loweredAddress, + color, + nickname, + }, + }; + saveContacts(updatedContacts); + dispatch({ + payload: updatedContacts, + type: CONTACTS_UPDATE, + }); +}; + +export const removeContact = address => (dispatch, getState) => { + const { contacts } = getState().contacts; + const updatedContacts = omit(contacts, toLower(address)); + saveContacts(updatedContacts); + dispatch({ + payload: updatedContacts, + type: CONTACTS_UPDATE, + }); +}; + +// -- Reducer ----------------------------------------- // +const INITIAL_STATE = { + contacts: {}, +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case CONTACTS_UPDATE: + return { ...state, contacts: action.payload }; + case CONTACTS_LOAD: + return { + ...state, + contacts: action.payload, + }; + case CONTACTS_CLEAR_STATE: + return { + ...state, + ...INITIAL_STATE, + }; + default: + return state; + } +}; diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 6450535b461..28a57b1bb20 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -1,6 +1,7 @@ import { combineReducers } from 'redux'; import actionSheetManager from './actionSheetManager'; +import contacts from './contacts'; import data from './data'; import explorer from './explorer'; import gas from './gas'; @@ -23,6 +24,7 @@ import walletconnect from './walletconnect'; export default combineReducers({ actionSheetManager, + contacts, data, explorer, gas, diff --git a/src/screens/ExpandedAssetScreen.js b/src/screens/ExpandedAssetScreen.js index 978b3bb2172..0998c985b4b 100644 --- a/src/screens/ExpandedAssetScreen.js +++ b/src/screens/ExpandedAssetScreen.js @@ -11,7 +11,6 @@ import { Centered } from '../components/layout'; import TouchableBackdrop from '../components/TouchableBackdrop'; import { padding } from '../styles'; import { deviceUtils, safeAreaInsetValues } from '../utils'; -import { addNewLocalContact } from '../handlers/localstorage/contacts'; const { bottom: safeAreaBottom, top: safeAreaTop } = safeAreaInsetValues; @@ -37,32 +36,8 @@ export default class ExpandedAssetScreen extends Component { containerPadding: 15, }; - state = { - color: 0, - shouldSave: false, - value: '', - }; - shouldComponentUpdate = () => false; - componentWillUnmount = async () => { - const { address, onCloseModal, type } = this.props; - const { color, shouldSave, value } = this.state; - - if (type === 'contact' && shouldSave && value.length > 0) { - await addNewLocalContact(address, value, color); - onCloseModal(); - } - }; - - setNewValuesToSave = (value, color, shouldSave = true) => { - this.setState({ - color, - shouldSave, - value, - }); - }; - render = () => ( {createElement(ScreenTypes[this.props.type], { ...this.props, - onUnmountModal: this.setNewValuesToSave, })} ); diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index cbd532bbd3a..11305645f7d 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -18,13 +18,13 @@ import { import { withAccountData, withAccountSettings, + withContacts, withDataInit, withTransitionProps, withUniqueTokens, } from '../hoc'; import { borders, colors } from '../styles'; import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; -import { getLocalContacts } from '../handlers/localstorage/contacts'; const statusBarHeight = getStatusBarHeight(true); @@ -44,6 +44,7 @@ class SendSheet extends Component { static propTypes = { allAssets: PropTypes.array, assetAmount: PropTypes.string, + contacts: PropTypes.object, fetchData: PropTypes.func, gasPrices: PropTypes.object, gasUpdateGasPriceOption: PropTypes.func, @@ -54,6 +55,7 @@ class SendSheet extends Component { navigation: PropTypes.object, onSubmit: PropTypes.func, recipient: PropTypes.string, + removeContact: PropTypes.func, selected: PropTypes.object, selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), @@ -63,6 +65,7 @@ class SendSheet extends Component { sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, sendUpdateSelected: PropTypes.func, + sortedContacts: PropTypes.array, }; static defaultProps = { @@ -72,7 +75,6 @@ class SendSheet extends Component { }; state = { - contacts: [], currentInput: '', isAuthorizing: false, }; @@ -84,11 +86,11 @@ class SendSheet extends Component { if (address) { sendUpdateRecipient(address); } - this.onUpdateContacts(); }; - componentDidUpdate(prevProps, prevState) { + componentDidUpdate(prevProps) { const { + contacts, isValidAddress, navigation, selected, @@ -112,15 +114,15 @@ class SendSheet extends Component { 'isValidAddress' ); const isNewContactList = isNewValueForPath( - this.state, - prevState, + this.props, + prevProps, 'contacts' ); if (isNewValidAddress || isNewSelected || isNewContactList) { let verticalGestureResponseDistance = 140; - if (!isValidAddress && this.state.contacts.length !== 0) { + if (!isValidAddress && !isEmpty(contacts)) { verticalGestureResponseDistance = 140; } else if (isValidAddress) { verticalGestureResponseDistance = isEmpty(selected) @@ -207,11 +209,6 @@ class SendSheet extends Component { }); }; - onUpdateContacts = async () => { - const contacts = await getLocalContacts(); - this.setState({ contacts }); - }; - onChangeInput = event => { this.setState({ currentInput: event }); this.props.sendUpdateRecipient(event); @@ -220,14 +217,17 @@ class SendSheet extends Component { render() { const { allAssets, + contacts, fetchData, isValidAddress, nativeCurrencySymbol, recipient, + removeContact, selected, selectedGasPrice, sendableUniqueTokens, sendUpdateRecipient, + sortedContacts, ...props } = this.props; const showEmptyState = !isValidAddress; @@ -239,20 +239,20 @@ class SendSheet extends Component { {showEmptyState && ( )} {showAssetList && ( @@ -298,6 +298,7 @@ class SendSheet extends Component { export default compose( withAccountData, + withContacts, withUniqueTokens, withAccountSettings, withDataInit, From 4b6b3c51435c14340133c5b63250e03ca4a75d5b Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 20 Nov 2019 19:20:19 -0500 Subject: [PATCH 534/636] Remove non-word character removal for send recipient Contact names can include additional characters (e.g, emojis) --- src/redux/send.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/redux/send.js b/src/redux/send.js index 0bc610ef03b..589f28b9cc8 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -114,13 +114,11 @@ export const sendToggleConfirmationView = boolean => (dispatch, getState) => { }); }; -export const sendUpdateRecipient = recipient => dispatch => { - const input = recipient.replace(/[^\w.]/g, ''); +export const sendUpdateRecipient = recipient => dispatch => dispatch({ - payload: input, + payload: recipient, type: SEND_UPDATE_RECIPIENT, }); -}; export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { const { nativeCurrency } = getState().settings; From 580d0cfa539535954ca6cd077f11f675e7941299 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 20 Nov 2019 22:23:00 -0500 Subject: [PATCH 535/636] Add contact info during transaction selector --- src/components/activity-list/ActivityList.js | 8 +++- .../activity-list/RecyclerActivityList.js | 1 + src/components/coin-row/TransactionCoinRow.js | 25 ++++++------ src/helpers/transactions.js | 38 ++++++++++++++++--- 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/components/activity-list/ActivityList.js b/src/components/activity-list/ActivityList.js index 348288daa9d..a36a52970b2 100644 --- a/src/components/activity-list/ActivityList.js +++ b/src/components/activity-list/ActivityList.js @@ -2,7 +2,11 @@ import PropTypes from 'prop-types'; import React from 'react'; import { compose, mapProps, onlyUpdateForKeys, withProps } from 'recompact'; import { buildTransactionsSectionsSelector } from '../../helpers/transactions'; -import { withAccountSettings, withAccountTransactions } from '../../hoc'; +import { + withAccountSettings, + withAccountTransactions, + withContacts, +} from '../../hoc'; import RecyclerActivityList from './RecyclerActivityList'; const ActivityList = ({ header, isEmpty, sections }) => ( @@ -28,6 +32,7 @@ ActivityList.propTypes = { export default compose( withAccountSettings, withAccountTransactions, + withContacts, withProps(buildTransactionsSectionsSelector), mapProps(({ nativeCurrency, requests, sections, ...props }) => { let pendingTransactionsCount = 0; @@ -46,6 +51,7 @@ export default compose( }; }), onlyUpdateForKeys([ + 'contacts', 'isEmpty', 'nativeCurrency', 'pendingTransactionsCount', diff --git a/src/components/activity-list/RecyclerActivityList.js b/src/components/activity-list/RecyclerActivityList.js index 7a11f93a82e..c098da593a9 100644 --- a/src/components/activity-list/RecyclerActivityList.js +++ b/src/components/activity-list/RecyclerActivityList.js @@ -71,6 +71,7 @@ const hasRowChanged = (r1, r2) => { return ( r1Key !== r2Key || + isNewValueForPath(r1, r2, 'contact') || isNewValueForPath(r1, r2, 'native.symbol') || isNewValueForPath(r1, r2, 'pending') ); diff --git a/src/components/coin-row/TransactionCoinRow.js b/src/components/coin-row/TransactionCoinRow.js index 63dc13168bf..1118e74593a 100644 --- a/src/components/coin-row/TransactionCoinRow.js +++ b/src/components/coin-row/TransactionCoinRow.js @@ -1,4 +1,4 @@ -import { compact, get, toLower } from 'lodash'; +import { compact, get } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { compose, mapProps, onlyUpdateForKeys, withHandlers } from 'recompact'; @@ -6,7 +6,6 @@ import { Linking } from 'react-native'; import { withNavigation } from 'react-navigation'; import { css } from 'styled-components/primitives'; import TransactionStatusTypes from '../../helpers/transactionStatusTypes'; -import { withContacts } from '../../hoc'; import { colors } from '../../styles'; import { abbreviations } from '../../utils'; import { showActionSheetWithOptions } from '../../utils/actionsheet'; @@ -81,20 +80,21 @@ const TransactionCoinRow = ({ item, onPressTransaction, ...props }) => ( TransactionCoinRow.propTypes = rowRenderPropTypes; export default compose( - mapProps(({ item: { hash, native, pending, ...item }, ...props }) => ({ - hash, - item, - native, - pending, - ...props, - })), - withContacts, + mapProps( + ({ item: { contact, hash, native, pending, ...item }, ...props }) => ({ + contact, + hash, + item, + native, + pending, + ...props, + }) + ), withNavigation, withHandlers({ - onPressTransaction: ({ contacts, hash, item, navigation }) => async () => { + onPressTransaction: ({ contact, hash, item, navigation }) => async () => { const { from, to, status } = item; const isSent = status === TransactionStatusTypes.sent; - const headerInfo = { address: '', divider: isSent ? 'to' : 'from', @@ -102,7 +102,6 @@ export default compose( }; const contactAddress = isSent ? to : from; - const contact = contacts[toLower(contactAddress)]; let contactColor = 0; if (contact) { diff --git a/src/helpers/transactions.js b/src/helpers/transactions.js index 92db511cf37..31edb274db8 100644 --- a/src/helpers/transactions.js +++ b/src/helpers/transactions.js @@ -5,10 +5,12 @@ import { isToday, isYesterday, } from 'date-fns'; -import { get, groupBy, isEmpty } from 'lodash'; +import { get, groupBy, isEmpty, map, toLower } from 'lodash'; import { createSelector } from 'reselect'; +import TransactionStatusTypes from '../helpers/transactionStatusTypes'; const accountAddressSelector = state => state.accountAddress; +const contactsSelector = state => state.contacts; const requestsSelector = state => state.requests; const transactionsSelector = state => state.transactions; @@ -27,11 +29,32 @@ const groupTransactionByDate = ({ pending, minedAt }) => { return format(timestamp, `MMMM${isThisYear(timestamp) ? '' : ' YYYY'}`); }; -const buildTransactionsSections = (accountAddress, requests, transactions) => { +const addContactInfo = contacts => txn => { + const { from, to, status } = txn; + const isSent = status === TransactionStatusTypes.sent; + const contactAddress = isSent ? to : from; + const contact = get(contacts, `${[toLower(contactAddress)]}`, null); + return { + ...txn, + contact, + }; +}; + +const buildTransactionsSections = ( + accountAddress, + contacts, + requests, + transactions +) => { let sectionedTransactions = []; - if (!isEmpty(transactions)) { - const transactionsByDate = groupBy(transactions, groupTransactionByDate); + const transactionsWithContacts = map(transactions, addContactInfo(contacts)); + + if (!isEmpty(transactionsWithContacts)) { + const transactionsByDate = groupBy( + transactionsWithContacts, + groupTransactionByDate + ); sectionedTransactions = Object.keys(transactionsByDate).map(section => ({ data: transactionsByDate[section], @@ -55,6 +78,11 @@ const buildTransactionsSections = (accountAddress, requests, transactions) => { }; export const buildTransactionsSectionsSelector = createSelector( - [accountAddressSelector, requestsSelector, transactionsSelector], + [ + accountAddressSelector, + contactsSelector, + requestsSelector, + transactionsSelector, + ], buildTransactionsSections ); From 22f1ced6171abf3e27cb1d5cbbd26023a301d8d2 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 21 Nov 2019 13:51:54 -0500 Subject: [PATCH 536/636] Sort token override lists alphabetically by name instead of symbol --- src/references/token-overrides.json | 94 ++++++------- src/references/uniswap-pairs.json | 202 ++++++++++++++-------------- 2 files changed, 148 insertions(+), 148 deletions(-) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 261b3e7857d..d622c7a23a0 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -2,27 +2,45 @@ "ETH": { "name": "Ethereum" }, + "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { + "name": "0x" + }, "0x960b236A07cf122663c4303350609A66A7B288C0": { "name": "Aragon" }, + "0x1985365e9f78359a9B6AD760e32412f4a445E862": { + "name": "Augur" + }, + "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { + "name": "Bancor" + }, "0x0D8775F648430679A709E98d2b0Cb6250d2887EF": { "name": "Basic Attention Token" }, "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { "name": "Bloom" }, - "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { - "name": "Bancor" + "0x514910771AF9Ca656af840dff83E8264EcF986CA": { + "name": "Chainlink" + }, + "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { + "name": "Civic" }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { "name": "Compound Dai" }, - "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { - "name": "Civic" + "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { + "name": "CryptoFranc" }, "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { "name": "Dai" }, + "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { + "name": "DAOstack" + }, + "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { + "name": "Decentraland" + }, "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { "name": "Digix Gold Token" }, @@ -32,9 +50,6 @@ "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b": { "name": "FunFair" }, - "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { - "name": "DAOstack" - }, "0x6810e776880C02933D47DB1b9fc05908e5386b96": { "name": "Gnosis" }, @@ -44,39 +59,42 @@ "0x12B19D3e2ccc14Da04FAe33e63652ce469b3F2FD": { "name": "Grid+" }, + "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { + "name": "Holo" + }, + "0x607F4C5BB672230e8672085532f7e901544a7375": { + "name": "iExec" + }, "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { "name": "Kin" }, + "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { + "name": "Kleros" + }, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { "name": "Kyber Network" }, - "0x514910771AF9Ca656af840dff83E8264EcF986CA": { - "name": "Chainlink" - }, - "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { - "name": "Loopring" - }, - "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { - "name": "Holo" + "0x58b6A8A3302369DAEc383334672404Ee733aB239": { + "name": "Livepeer" }, "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { "name": "LoomToken" }, - "0x58b6A8A3302369DAEc383334672404Ee733aB239": { - "name": "Livepeer" + "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { + "name": "Loopring" }, - "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { - "name": "Decentraland" + "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { + "name": "Maker" }, "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { "name": "Matic Network" }, - "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { - "name": "Maker" - }, "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { "name": "Melon" }, + "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { + "name": "Monolith" + }, "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206": { "name": "Nexo" }, @@ -86,9 +104,6 @@ "0x8E870D67F660D95d5be530380D0eC0bd388289E1": { "name": "Paxos Standard" }, - "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { - "name": "Kleros" - }, "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { "name": "POA Network", "symbol": "POA" @@ -99,39 +114,30 @@ "0x408e41876cCCDC0F92210600ef50372656052a38": { "name": "Republic" }, - "0x1985365e9f78359a9B6AD760e32412f4a445E862": { - "name": "Augur" - }, - "0x607F4C5BB672230e8672085532f7e901544a7375": { - "name": "iExec" - }, "0xB4EFd85c19999D84251304bDA99E90B92300Bd93": { "name": "Rocket Pool" }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT" }, - "0x42456D7084eacF4083f1140d3229471bbA2949A8": { - "name": "Synthetix ETH" + "0x42d6622deCe394b54999Fbd73D108123806f6a18": { + "name": "SpankChain" }, "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E": { "name": "Status" }, + "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { + "name": "Storj" + }, "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { "name": "Synthetix" }, - "0x42d6622deCe394b54999Fbd73D108123806f6a18": { - "name": "SpankChain" - }, - "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { - "name": "Storj" + "0x42456D7084eacF4083f1140d3229471bbA2949A8": { + "name": "Synthetix ETH" }, "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { "name": "Synthetix USD" }, - "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { - "name": "Monolith" - }, "0xdac17f958d2ee523a2206206994597c13d831ec7": { "name": "Tether" }, @@ -155,11 +161,5 @@ }, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": { "name": "Wrapped Ether" - }, - "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { - "name": "CryptoFranc" - }, - "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { - "name": "0x" } } diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index 333c768b2b2..69e01e570e4 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -5,12 +5,30 @@ "decimals": 18, "exchangeAddress": null }, + "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { + "name": "0x", + "symbol": "ZRX", + "decimals": 18, + "exchangeAddress": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" + }, "0x960b236A07cf122663c4303350609A66A7B288C0": { "name": "Aragon", "symbol": "ANT", "decimals": 18, "exchangeAddress": "0x077d52B047735976dfdA76feF74d4d988AC25196" }, + "0x1985365e9f78359a9B6AD760e32412f4a445E862": { + "name": "Augur", + "symbol": "REP", + "decimals": 18, + "exchangeAddress": "0x48B04d2A05B6B604d8d5223Fd1984f191DED51af" + }, + "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { + "name": "Bancor", + "symbol": "BNT", + "decimals": 18, + "exchangeAddress": "0x87d80DBD37E551F58680B4217b23aF6a752DA83F" + }, "0x0D8775F648430679A709E98d2b0Cb6250d2887EF": { "name": "Basic Attention Token", "symbol": "BAT", @@ -23,11 +41,17 @@ "decimals": 18, "exchangeAddress": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" }, - "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C": { - "name": "Bancor", - "symbol": "BNT", + "0x514910771AF9Ca656af840dff83E8264EcF986CA": { + "name": "Chainlink", + "symbol": "LINK", "decimals": 18, - "exchangeAddress": "0x87d80DBD37E551F58680B4217b23aF6a752DA83F" + "exchangeAddress": "0xF173214C720f58E03e194085B1DB28B50aCDeeaD" + }, + "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { + "name": "Civic", + "symbol": "CVC", + "decimals": 8, + "exchangeAddress": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { "name": "Compound Dai", @@ -35,11 +59,11 @@ "decimals": 8, "exchangeAddress": "0x45A2FDfED7F7a2c791fb1bdF6075b83faD821ddE" }, - "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { - "name": "Civic", - "symbol": "CVC", - "decimals": 8, - "exchangeAddress": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" + "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { + "name": "CryptoFranc", + "symbol": "XCHF", + "decimals": 18, + "exchangeAddress": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" }, "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { "name": "Dai", @@ -47,6 +71,18 @@ "decimals": 18, "exchangeAddress": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" }, + "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { + "name": "DAOstack", + "symbol": "GEN", + "decimals": 18, + "exchangeAddress": "0x26Cc0EAb6Cb650B0Db4D0d0dA8cB5BF69F4ad692" + }, + "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { + "name": "Decentraland", + "symbol": "MANA", + "decimals": 18, + "exchangeAddress": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" + }, "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { "name": "Digix Gold Token", "symbol": "DGX", @@ -65,12 +101,6 @@ "decimals": 8, "exchangeAddress": "0x60a87cC7Fca7E53867facB79DA73181B1bB4238B" }, - "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { - "name": "DAOstack", - "symbol": "GEN", - "decimals": 18, - "exchangeAddress": "0x26Cc0EAb6Cb650B0Db4D0d0dA8cB5BF69F4ad692" - }, "0x6810e776880C02933D47DB1b9fc05908e5386b96": { "name": "Gnosis", "symbol": "GNO", @@ -83,35 +113,41 @@ "decimals": 12, "exchangeAddress": "0x4B17685b330307C751B47f33890c8398dF4Fe407" }, + "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { + "name": "Holo", + "symbol": "HOT", + "decimals": 18, + "exchangeAddress": "0xd4777E164c6C683E10593E08760B803D58529a8E" + }, + "0x607F4C5BB672230e8672085532f7e901544a7375": { + "name": "iExec", + "symbol": "RLC", + "decimals": 9, + "exchangeAddress": "0xA825CAE02B310E9901b4776806CE25db520c8642" + }, "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { "name": "Kin", "symbol": "KIN", "decimals": 18, "exchangeAddress": "0xb7520a5F8c832c573d6BD0Df955fC5c9b72400F7" }, + "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { + "name": "Kleros", + "symbol": "PNK", + "decimals": 18, + "exchangeAddress": "0xF506828B166de88cA2EDb2A98D960aBba0D2402A" + }, "0xdd974D5C2e2928deA5F71b9825b8b646686BD200": { "name": "Kyber Network", "symbol": "KNC", "decimals": 18, "exchangeAddress": "0x49c4f9bc14884f6210F28342ceD592A633801a8b" }, - "0x514910771AF9Ca656af840dff83E8264EcF986CA": { - "name": "Chainlink", - "symbol": "LINK", - "decimals": 18, - "exchangeAddress": "0xF173214C720f58E03e194085B1DB28B50aCDeeaD" - }, - "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { - "name": "Loopring", - "symbol": "LRC", - "decimals": 18, - "exchangeAddress": "0xA539BAaa3aCA455c986bB1E25301CEF936CE1B65" - }, - "0x6c6EE5e31d828De241282B9606C8e98Ea48526E2": { - "name": "Holo", - "symbol": "HOT", + "0x58b6A8A3302369DAEc383334672404Ee733aB239": { + "name": "Livepeer", + "symbol": "LPT", "decimals": 18, - "exchangeAddress": "0xd4777E164c6C683E10593E08760B803D58529a8E" + "exchangeAddress": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" }, "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { "name": "LoomToken", @@ -119,17 +155,17 @@ "decimals": 18, "exchangeAddress": "0x417CB32bc991fBbDCaE230C7c4771CC0D69daA6b" }, - "0x58b6A8A3302369DAEc383334672404Ee733aB239": { - "name": "Livepeer", - "symbol": "LPT", + "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { + "name": "Loopring", + "symbol": "LRC", "decimals": 18, - "exchangeAddress": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" + "exchangeAddress": "0xA539BAaa3aCA455c986bB1E25301CEF936CE1B65" }, - "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { - "name": "Decentraland", - "symbol": "MANA", + "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { + "name": "Maker", + "symbol": "MKR", "decimals": 18, - "exchangeAddress": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" + "exchangeAddress": "0x2C4Bd064b998838076fa341A83d007FC2FA50957" }, "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0": { "name": "Matic Network", @@ -137,18 +173,18 @@ "decimals": 18, "exchangeAddress": "0x9a7A75E66B325a3BD46973B2b57c9b8d9D26a621" }, - "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2": { - "name": "Maker", - "symbol": "MKR", - "decimals": 18, - "exchangeAddress": "0x2C4Bd064b998838076fa341A83d007FC2FA50957" - }, "0xec67005c4E498Ec7f55E092bd1d35cbC47C91892": { "name": "Melon", "symbol": "MLN", "decimals": 18, "exchangeAddress": "0xA931F4eB165AC307fD7431b5EC6eADde53E14b0C" }, + "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { + "name": "Monolith", + "symbol": "TKN", + "decimals": 8, + "exchangeAddress": "0xb6cFBf322db47D39331E306005DC7E5e6549942B" + }, "0xB62132e35a6c13ee1EE0f84dC5d40bad8d815206": { "name": "Nexo", "symbol": "NEXO", @@ -167,12 +203,6 @@ "decimals": 18, "exchangeAddress": "0xC040d51b07Aea5d94a89Bc21E8078B77366Fc6C7" }, - "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { - "name": "Kleros", - "symbol": "PNK", - "decimals": 18, - "exchangeAddress": "0xF506828B166de88cA2EDb2A98D960aBba0D2402A" - }, "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { "name": "POA Network", "symbol": "POA20", @@ -191,18 +221,6 @@ "decimals": 18, "exchangeAddress": "0x43892992B0b102459E895B88601Bb2C76736942c" }, - "0x1985365e9f78359a9B6AD760e32412f4a445E862": { - "name": "Augur", - "symbol": "REP", - "decimals": 18, - "exchangeAddress": "0x48B04d2A05B6B604d8d5223Fd1984f191DED51af" - }, - "0x607F4C5BB672230e8672085532f7e901544a7375": { - "name": "iExec", - "symbol": "RLC", - "decimals": 9, - "exchangeAddress": "0xA825CAE02B310E9901b4776806CE25db520c8642" - }, "0xB4EFd85c19999D84251304bDA99E90B92300Bd93": { "name": "Rocket Pool", "symbol": "RPL", @@ -215,11 +233,11 @@ "decimals": 8, "exchangeAddress": "0xC0C59cDe851bfcbdddD3377EC10ea54A18Efb937" }, - "0x42456D7084eacF4083f1140d3229471bbA2949A8": { - "name": "Synthetix ETH", - "symbol": "sETH", + "0x42d6622deCe394b54999Fbd73D108123806f6a18": { + "name": "SpankChain", + "symbol": "SPANK", "decimals": 18, - "exchangeAddress": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" + "exchangeAddress": "0x4e395304655F0796bc3bc63709DB72173b9DdF98" }, "0x744d70FDBE2Ba4CF95131626614a1763DF805B9E": { "name": "Status", @@ -227,23 +245,23 @@ "decimals": 18, "exchangeAddress": "0x1aEC8F11A7E78dC22477e91Ed924Fab46e3A88Fd" }, + "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { + "name": "Storj", + "symbol": "STORJ", + "decimals": 8, + "exchangeAddress": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" + }, "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { "name": "Synthetix", "symbol": "SNX", "decimals": 18, "exchangeAddress": "0x9fAA0Cb10912DE7Ad1D86705C65de291a9088A61" }, - "0x42d6622deCe394b54999Fbd73D108123806f6a18": { - "name": "SpankChain", - "symbol": "SPANK", + "0x42456D7084eacF4083f1140d3229471bbA2949A8": { + "name": "Synthetix ETH", + "symbol": "sETH", "decimals": 18, - "exchangeAddress": "0x4e395304655F0796bc3bc63709DB72173b9DdF98" - }, - "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { - "name": "Storj", - "symbol": "STORJ", - "decimals": 8, - "exchangeAddress": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" + "exchangeAddress": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" }, "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { "name": "Synthetix USD", @@ -251,18 +269,18 @@ "decimals": 18, "exchangeAddress": "0xA1ECDcca26150cF69090280eE2EE32347C238c7b" }, - "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a": { - "name": "Monolith", - "symbol": "TKN", - "decimals": 8, - "exchangeAddress": "0xb6cFBf322db47D39331E306005DC7E5e6549942B" - }, "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E": { "name": "TrueUSD", "symbol": "TUSD", "decimals": 18, "exchangeAddress": "0x4F30E682D0541eAC91748bd38A648d759261b8f3" }, + "0x23B608675a2B2fB1890d3ABBd85c5775c51691d5": { + "symbol": "SOCKS", + "name": "Unisocks Edition 0", + "decimals": 18, + "exchangeAddress": "0x22d8432cc7aA4f8712a655fC4cdfB1baEC29FCA9" + }, "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { "name": "Uniswap V1", "symbol": "UNI-V1:DAI", @@ -292,23 +310,5 @@ "symbol": "WETH", "decimals": 18, "exchangeAddress": "0xA2881A90Bf33F03E7a3f803765Cd2ED5c8928dFb" - }, - "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { - "name": "CryptoFranc", - "symbol": "XCHF", - "decimals": 18, - "exchangeAddress": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" - }, - "0xE41d2489571d322189246DaFA5ebDe1F4699F498": { - "name": "0x", - "symbol": "ZRX", - "decimals": 18, - "exchangeAddress": "0xaE76c84C9262Cdb9abc0C2c8888e62Db8E22A0bF" - }, - "0x23B608675a2B2fB1890d3ABBd85c5775c51691d5": { - "symbol": "SOCKS", - "name": "Unisocks Edition 0", - "decimals": 18, - "exchangeAddress": "0x22d8432cc7aA4f8712a655fC4cdfB1baEC29FCA9" } } From 1c88a8d376f3fa893d19b670ac351d5754f033eb Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 21 Nov 2019 15:34:06 -0500 Subject: [PATCH 537/636] DAI -> SAI, Synthetix fixes, add bZx tokens, DGD, misc. improvements --- src/references/token-overrides.json | 32 +++++++++++++++------ src/references/uniswap-pairs.json | 44 ++++++++++++++++++++--------- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index d622c7a23a0..08e81905035 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -20,6 +20,12 @@ "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { "name": "Bloom" }, + "0x493c57c4763932315a328269e1adad09653b9081": { + "name": "bZx Dai" + }, + "0x14094949152eddbfcd073717200da82fed8dc960": { + "name": "bZx Sai" + }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { "name": "Chainlink" }, @@ -27,12 +33,13 @@ "name": "Civic" }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { - "name": "Compound Dai" + "name": "Compound Sai", + "symbol": "cSAI" }, "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { "name": "CryptoFranc" }, - "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { + "0x6b175474e89094c44da98b954eedeac495271d0f": { "name": "Dai" }, "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { @@ -41,8 +48,11 @@ "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942": { "name": "Decentraland" }, + "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a": { + "name": "DigixDAO" + }, "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { - "name": "Digix Gold Token" + "name": "Digix Gold" }, "0x4946Fcea7C692606e8908002e55A582af44AC121": { "name": "FOAM" @@ -78,7 +88,7 @@ "name": "Livepeer" }, "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { - "name": "LoomToken" + "name": "Loom" }, "0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD": { "name": "Loopring" @@ -106,7 +116,7 @@ }, "0x6758B7d441a9739b98552B373703d8d3d14f9e62": { "name": "POA Network", - "symbol": "POA" + "symbol": "POA20" }, "0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6": { "name": "Raiden" @@ -117,6 +127,9 @@ "0xB4EFd85c19999D84251304bDA99E90B92300Bd93": { "name": "Rocket Pool" }, + "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { + "name": "Sai" + }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT" }, @@ -129,13 +142,13 @@ "0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC": { "name": "Storj" }, - "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { + "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f": { "name": "Synthetix" }, - "0x42456D7084eacF4083f1140d3229471bbA2949A8": { + "0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb": { "name": "Synthetix ETH" }, - "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { + "0x57ab1ec28d129707052df4df418d58a2d46d5f51": { "name": "Synthetix USD" }, "0xdac17f958d2ee523a2206206994597c13d831ec7": { @@ -148,7 +161,8 @@ "name": "Unisocks Edition 0" }, "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { - "name": "Uniswap V1" + "name": "Uniswap V1", + "symbol": "UNI-V1:SAI" }, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": { "name": "USD Coin" diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index 69e01e570e4..ec15effabab 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -41,6 +41,12 @@ "decimals": 18, "exchangeAddress": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" }, + "0x14094949152eddbfcd073717200da82fed8dc960": { + "name": "bZx Sai", + "symbol": "ISAI", + "decimals": 18, + "exchangeAddress": "0x81eed7f1ecbd7fa9978fcc7584296fb0c215dc5c" + }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { "name": "Chainlink", "symbol": "LINK", @@ -54,8 +60,8 @@ "exchangeAddress": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { - "name": "Compound Dai", - "symbol": "cDAI", + "name": "Compound Sai", + "symbol": "cSAI", "decimals": 8, "exchangeAddress": "0x45A2FDfED7F7a2c791fb1bdF6075b83faD821ddE" }, @@ -65,11 +71,11 @@ "decimals": 18, "exchangeAddress": "0x8dE0d002DC83478f479dC31F76cB0a8aa7CcEa17" }, - "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { + "0x6b175474e89094c44da98b954eedeac495271d0f": { "name": "Dai", "symbol": "DAI", "decimals": 18, - "exchangeAddress": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" + "exchangeAddress": "0x2a1530c4c41db0b0b2bb646cb5eb1a67b7158667" }, "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf": { "name": "DAOstack", @@ -83,8 +89,14 @@ "decimals": 18, "exchangeAddress": "0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2" }, + "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a": { + "name": "DigixDAO", + "symbol": "DGD", + "decimals": 9, + "exchangeAddress": "0xd55c1ca9f5992a2e5e379dce49abf24294abe055" + }, "0x4f3AfEC4E5a3F2A6a1A411DEF7D7dFe50eE057bF": { - "name": "Digix Gold Token", + "name": "Digix Gold", "symbol": "DGX", "decimals": 9, "exchangeAddress": "0xb92dE8B30584392Af27726D5ce04Ef3c4e5c9924" @@ -150,7 +162,7 @@ "exchangeAddress": "0xc4a1C45D5546029Fd57128483aE65b56124BFA6A" }, "0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0": { - "name": "LoomToken", + "name": "Loom", "symbol": "LOOM", "decimals": 18, "exchangeAddress": "0x417CB32bc991fBbDCaE230C7c4771CC0D69daA6b" @@ -227,6 +239,12 @@ "decimals": 18, "exchangeAddress": "0x3Fb2F18065926DdB33E7571475c509541d15dA0e" }, + "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { + "name": "Sai", + "symbol": "SAI", + "decimals": 18, + "exchangeAddress": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" + }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT", "symbol": "SALT", @@ -251,23 +269,23 @@ "decimals": 8, "exchangeAddress": "0xA7298541E52f96d42382eCBe4f242cBcBC534d02" }, - "0x2Dea20405c52Fb477ecCa8Fe622661d316Ac5400": { + "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f": { "name": "Synthetix", "symbol": "SNX", "decimals": 18, - "exchangeAddress": "0x9fAA0Cb10912DE7Ad1D86705C65de291a9088A61" + "exchangeAddress": "0x3958b4ec427f8fa24eb60f42821760e88d485f7f" }, - "0x42456D7084eacF4083f1140d3229471bbA2949A8": { + "0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb": { "name": "Synthetix ETH", "symbol": "sETH", "decimals": 18, - "exchangeAddress": "0x4740C758859D4651061CC9CDEFdBa92BDc3a845d" + "exchangeAddress": "0xe9cf7887b93150d4f2da7dfc6d502b216438f244" }, - "0x0cbe2df57ca9191b64a7af3baa3f946fa7df2f25": { + "0x57ab1ec28d129707052df4df418d58a2d46d5f51": { "name": "Synthetix USD", "symbol": "sUSD", "decimals": 18, - "exchangeAddress": "0xA1ECDcca26150cF69090280eE2EE32347C238c7b" + "exchangeAddress": "0xb944d13b2f4047fc7bd3f7013bcf01b115fb260d" }, "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E": { "name": "TrueUSD", @@ -283,7 +301,7 @@ }, "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14": { "name": "Uniswap V1", - "symbol": "UNI-V1:DAI", + "symbol": "UNI-V1:SAI", "decimals": 18, "exchangeAddress": "0x601c32E0580D3aef9437dB52D09f5a5D7E60eC22" }, From 72264e23a3507af1c792693fdda5c34167ad1eeb Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 22 Nov 2019 11:37:58 -0500 Subject: [PATCH 538/636] Set the default gas limit for swap --- src/screens/ExchangeModal.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index d203e86cbd0..ac5918dae07 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -54,6 +54,7 @@ import { withUniswapAllowances, withUniswapAssets, } from '../hoc'; +import ethUnits from '../references/ethereum-units.json'; import { colors, padding, position } from '../styles'; import { isNewValueForObjectPaths, @@ -129,6 +130,10 @@ class ExchangeModal extends Component { tradeDetails: null, }; + componentDidMount() { + this.props.gasUpdateDefaultGasLimit(ethUnits.basic_swap); + } + shouldComponentUpdate = (nextProps, nextState) => { const isNewProps = isNewValueForObjectPaths(this.props, nextProps, [ 'inputReserve.token.address', From 087acf5238f13448ded62542faf6c90bdf50f810 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Fri, 22 Nov 2019 23:30:55 -0500 Subject: [PATCH 539/636] Rename bZx -> Fulcrum, add cUSDC, iUSDC --- src/references/token-overrides.json | 14 ++++++++++++-- src/references/uniswap-pairs.json | 10 ++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 08e81905035..3a8ce84d25e 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -21,10 +21,16 @@ "name": "Bloom" }, "0x493c57c4763932315a328269e1adad09653b9081": { - "name": "bZx Dai" + "name": "Fulcrum Dai", + "symbol": "iDAI" }, "0x14094949152eddbfcd073717200da82fed8dc960": { - "name": "bZx Sai" + "name": "Fulcrum Sai", + "symbol": "iSAI" + }, + "0xf013406a0b1d544238083df0b93ad0d2cbe0f65f": { + "name": "Fulcrum USD Coin", + "symbol": "iUSDC" }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { "name": "Chainlink" @@ -36,6 +42,10 @@ "name": "Compound Sai", "symbol": "cSAI" }, + "0x39aa39c021dfbae8fac545936693ac917d5e7563": { + "name": "Compound USD Coin", + "symbol": "cUSDC" + }, "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { "name": "CryptoFranc" }, diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index ec15effabab..65093f8e398 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -42,8 +42,8 @@ "exchangeAddress": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" }, "0x14094949152eddbfcd073717200da82fed8dc960": { - "name": "bZx Sai", - "symbol": "ISAI", + "name": "Fulcrum Sai", + "symbol": "iSAI", "decimals": 18, "exchangeAddress": "0x81eed7f1ecbd7fa9978fcc7584296fb0c215dc5c" }, @@ -65,6 +65,12 @@ "decimals": 8, "exchangeAddress": "0x45A2FDfED7F7a2c791fb1bdF6075b83faD821ddE" }, + "0x39aa39c021dfbae8fac545936693ac917d5e7563": { + "name": "Compound USD Coin", + "symbol": "cUSDC", + "decimals": 8, + "exchangeAddress": "0xb791c10824296881f91bdbc16367bbd9743fd99b" + }, "0xB4272071eCAdd69d933AdcD19cA99fe80664fc08": { "name": "CryptoFranc", "symbol": "XCHF", From 8b807266467904f9126b913a3c1c3c472d79b174 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 18 Nov 2019 18:11:04 -0500 Subject: [PATCH 540/636] Refactor ExchangeAssetList to use FlatList --- ios/Podfile.lock | 60 ++--- package.json | 6 +- .../coin-row/CoinRowFavoriteButton.js | 47 ++-- src/components/coin-row/ExchangeCoinRow.js | 132 ++++------ .../exchange/CurrencySelectionList.js | 36 ++- src/components/exchange/ExchangeAssetList.js | 159 ++++-------- src/hoc/withUniswapAssets.js | 3 +- src/hooks/index.js | 1 + src/hooks/useConstant.js | 11 + src/screens/CurrencySelectModal.js | 75 ++++-- yarn.lock | 236 +++++++++--------- 11 files changed, 358 insertions(+), 408 deletions(-) create mode 100644 src/hooks/index.js create mode 100644 src/hooks/useConstant.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 071cab5fd54..f264491825b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -272,13 +272,13 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.9.0): + - react-native-camera (3.11.1): - React - - react-native-camera/RCT (= 3.9.0) - - react-native-camera/RN (= 3.9.0) - - react-native-camera/RCT (3.9.0): + - react-native-camera/RCT (= 3.11.1) + - react-native-camera/RN (= 3.11.1) + - react-native-camera/RCT (3.11.1): - React - - react-native-camera/RN (3.9.0): + - react-native-camera/RN (3.11.1): - React - react-native-mail (4.1.0): - React @@ -380,7 +380,7 @@ PODS: - Fabric - Firebase/Core - React - - RNGestureHandler (1.4.1): + - RNGestureHandler (1.5.1): - React - RNInputMask (4.1.0) - RNKeychain (4.0.1): @@ -636,8 +636,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 622571adc030d0593ff14b01a6a7a9381b5a8ec9 - FBReactNativeSpec: 51b297eb6a8f1f1af7ad995f7b50d463f9cbc8ac + FBLazyVector: 2f46475005546a849f4536fb0d9bbc6c947b180a + FBReactNativeSpec: fa241922044c423c26f9577be1b5645712cad339 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -653,17 +653,17 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 2a7ef3e1905ee07fee04afa15899d1ac0d2bc4e2 - RCTTypeSafety: adcfc8e711634c0df8058465bd0fbcad56989697 - React: d53ebbfd6d3280ff687f1c4f7c54dac1d88a6652 - React-Core: 328e5d8eab893b47ff927c5a8788c894b6a54952 - React-CoreModules: 6dc8cae7c919d7c91e26a78ddc8bf7bd8d63ff25 - React-cxxreact: 107da773ef534e63b49bbe872b9a453c86595033 - React-jsi: 1457ea0c197731415c6d740bb8732cf599655afe - React-jsiexecutor: f6940db2473bca39a8842b49f06d2a69d124da23 - React-jsinspector: 604eb8729343ebf184f49297f29b732441e9647f + RCTRequired: 2b5646277a719d85c3d34612567fbfb1aadf9145 + RCTTypeSafety: ff6e3fec9f4af7fc6701114b37692b9006341a09 + React: 052db1fd4ac556dc1592417b2f609193da321474 + React-Core: e1f844506555a95e7a1040e41eeee769c106176b + React-CoreModules: 62ce394a4e1beaedd8555de319f9a20091131b70 + React-cxxreact: c84a96722f37ddd5aded39d348884df9836a7372 + React-jsi: a63afe42b704966ba3cc8b1cea48f3b122d34c4a + React-jsiexecutor: 20c480f3ea143218834c87c89a0efec93e902dca + React-jsinspector: 0e2b152e184ae4793bd15ff2db6cbf0216f2b975 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: c529629e3ecd017dcdacfd0355576ef489d9d198 + react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 react-native-netinfo: a59d8426a8484f739fe3a95dd6ad5af1435db05f react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 @@ -672,16 +672,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 2ab0d8d31444de3efd22ddf62710084fdb5f6507 - React-RCTAnimation: e3646eaa461d5d185425466ea67bed3e0cb00826 - React-RCTBlob: e1d6ad0f23c7f7d3b7d275682e1a0a5ba2d99f3b - React-RCTImage: b97e9b849351326887f5cb13291ed6a843fc59a4 - React-RCTLinking: ea3b68257a6a398deb6873bfa34d2c8fd7b5a655 - React-RCTNetwork: 90483487d95bc1b857ba26f656671f5ee62e9b6c - React-RCTSettings: d8ad1a9ab6a11d0d57c5fa14f2eda76ec4ea0c17 - React-RCTText: 2ee0ca2a22aa068be44586ec81e8d87a3258b4ef - React-RCTVibration: ffb1b3ebe3ee57ea15f89bb1f629f76371e2367c - ReactCommon: 10c762da3c1f81ecf70d9cf3c535f082a92c36ca + React-RCTActionSheet: 461bd041982eb739c1be94d9cfbf7818d1d05507 + React-RCTAnimation: 6b7b68991927e6ef83282a385bfe971f5fcd298c + React-RCTBlob: 9e7a1de1a9cfe750c0f3832a9b471a694f0ccb94 + React-RCTImage: 6a8489a99368f35b15755f805ec980e8d30741de + React-RCTLinking: f4621e7c7e0c892533ff0f6a7ed9a7ed5e4f55ca + React-RCTNetwork: 8a6b08e7bbd58fad2fb0661848011d9ccfcc14db + React-RCTSettings: 64f7701f3683abb3c6fced20a82d1e512c7e4e7e + React-RCTText: 6623e85ca666578e1744858d78b323291ced9ada + React-RCTVibration: c16066afc43000d7a2969adb27cb0f6e08d7cd08 + ReactCommon: ab029e0e08e9fc52630c3edc5b21c9c0648dcb9b ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -689,7 +689,7 @@ SPEC CHECKSUMS: RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 - RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa + RNGestureHandler: 7add966bb5d90ee8cf38d4341f87814474357972 RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e @@ -706,7 +706,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 44c98065ff5af48e4443cf4a5d0ed95daf4f7824 + Yoga: d827efa299f868ae67dea515f0727b7afaa4d2e1 PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 diff --git a/package.json b/package.json index 714fb1a07a6..5336e83dcc5 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "eth-contract-metadata": "^1.9.3", "ethers": "^4.0.39", "events": "^1.1.1", + "fuzzysearch": "^1.0.3", "global": "^4.3.2", "grapheme-splitter": "^1.0.4", "https-browserify": "0.0.1", @@ -84,7 +85,7 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-firebase": "^5.5.6", - "react-native-gesture-handler": "1.4.1", + "react-native-gesture-handler": "1.5.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", @@ -116,7 +117,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", - "react-navigation-stack": "2.0.0-alpha.36", + "react-navigation-stack": "2.0.0-alpha.37", "react-navigation-tabs": "2.5.6", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", @@ -140,6 +141,7 @@ "timers-browserify": "^1.4.2", "tty-browserify": "0.0.0", "url": "^0.10.3", + "use-debounce": "^3.1.0", "util": "^0.10.3", "vm-browserify": "0.0.4" }, diff --git a/src/components/coin-row/CoinRowFavoriteButton.js b/src/components/coin-row/CoinRowFavoriteButton.js index dc1c4bf3d4c..5ccce89eb76 100644 --- a/src/components/coin-row/CoinRowFavoriteButton.js +++ b/src/components/coin-row/CoinRowFavoriteButton.js @@ -1,8 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import styled from 'styled-components/primitives'; +import { BaseButton } from 'react-native-gesture-handler'; import { colors, padding, position } from '../../styles'; -import { ButtonPressAnimation } from '../animations'; import { Icon } from '../icons'; import { Centered } from '../layout'; import CoinRow from './CoinRow'; @@ -10,33 +9,25 @@ import CoinRow from './CoinRow'; const FavoriteButtonPadding = 19; const FavoriteButtonWidth = FavoriteButtonPadding * 3; -const Container = styled(Centered).attrs({ flex: 0 })` - ${padding(0, FavoriteButtonPadding)} - bottom: 0; - height: ${CoinRow.height} - position: absolute; - right: 0; - top: 0; - width: ${FavoriteButtonWidth}; -`; - const CoinRowFavoriteButton = ({ isFavorited, onPress }) => ( - - - - - - - + + + + + ); CoinRowFavoriteButton.propTypes = { diff --git a/src/components/coin-row/ExchangeCoinRow.js b/src/components/coin-row/ExchangeCoinRow.js index e53b22da5ba..d3daf0846e0 100644 --- a/src/components/coin-row/ExchangeCoinRow.js +++ b/src/components/coin-row/ExchangeCoinRow.js @@ -1,9 +1,7 @@ import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; +import React, { memo, useState } from 'react'; +import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import { css } from 'styled-components/primitives'; -import { uniswapUpdateFavorites } from '../../redux/uniswap'; -import { isNewValueForPath } from '../../utils'; import { ButtonPressAnimation } from '../animations'; import BottomRowText from './BottomRowText'; import CoinName from './CoinName'; @@ -42,82 +40,58 @@ TopRow.propTypes = { name: PropTypes.string, }; -class ExchangeCoinRow extends Component { - static propTypes = { - index: PropTypes.number, - item: PropTypes.shape({ - address: PropTypes.string, - favorite: PropTypes.bool, - symbol: PropTypes.string, - }), - onPress: PropTypes.func, - showBalance: PropTypes.bool, - showFavoriteButton: PropTypes.bool, - uniqueId: PropTypes.string, - uniswapUpdateFavorites: PropTypes.func, - }; +const ExchangeCoinRow = ({ + item, + onFavoriteAsset, + onPress, + showBalance, + showFavoriteButton, + ...props +}) => { + const [localFavorite, setLocalFavorite] = useState(!!item.favorite); - state = { - favorite: !!this.props.item.favorite, - }; - - shouldComponentUpdate = (nextProps, nextState) => { - const isNewAsset = isNewValueForPath(this.props, nextProps, 'uniqueId'); - const isNewFavorite = isNewValueForPath(this.state, nextState, 'favorite'); - - return isNewAsset || isNewFavorite; - }; - - handlePress = () => { - if (this.props.onPress) { - this.props.onPress(this.props.item); - } - }; - - toggleFavorite = () => { - const { item, uniswapUpdateFavorites } = this.props; - this.setState(prevState => { - const favorite = !prevState.favorite; - uniswapUpdateFavorites(item.address, favorite); - return { favorite }; - }); - }; + return ( + onPress(item)} + scaleTo={0.96} + > + + {showFavoriteButton && ( + { + const newLocalFavorite = !localFavorite; + setLocalFavorite(newLocalFavorite); + onFavoriteAsset(item.address, newLocalFavorite); + ReactNativeHapticFeedback.trigger('selection'); + }} + /> + )} + + + ); +}; - render = () => { - const { - item, - showBalance, - showFavoriteButton, - uniqueId, - ...props - } = this.props; - const { favorite } = this.state; +ExchangeCoinRow.propTypes = { + item: PropTypes.shape({ + address: PropTypes.string, + favorite: PropTypes.bool, + symbol: PropTypes.string, + }), + onFavoriteAsset: PropTypes.func, + onPress: PropTypes.func, + showBalance: PropTypes.bool, + showFavoriteButton: PropTypes.bool, +}; - return ( - - - {showFavoriteButton && ( - - )} - - - ); - }; -} +const neverRerender = () => true; -export default connect(null, { uniswapUpdateFavorites })(ExchangeCoinRow); +export default memo(ExchangeCoinRow, neverRerender); diff --git a/src/components/exchange/CurrencySelectionList.js b/src/components/exchange/CurrencySelectionList.js index 8bec52a3a6c..1f0abb6af30 100644 --- a/src/components/exchange/CurrencySelectionList.js +++ b/src/components/exchange/CurrencySelectionList.js @@ -1,8 +1,7 @@ import PropTypes from 'prop-types'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { memo, useEffect, useRef, useState } from 'react'; import { Transition, Transitioning } from 'react-native-reanimated'; import { withNeverRerender } from '../../hoc'; -import { exchangeModalBorderRadius } from '../../screens/ExchangeModal'; import { colors, position } from '../../styles'; import { EmptyAssetList } from '../asset-list'; import { Centered, ColumnWithMargins } from '../layout'; @@ -38,7 +37,7 @@ const skeletonTransition = ( ); -const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { +const CurrencySelectionList = ({ itemProps, listItems, showList }) => { const skeletonTransitionRef = useRef(); const [showSkeleton, setShowSkeleton] = useState(true); @@ -50,10 +49,16 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { } }, [showList, showSkeleton]); + const onListLayout = () => { + if (showSkeleton && showList) { + skeletonTransitionRef.current.animateNextTransition(); + setShowSkeleton(false); + } + }; + return ( @@ -63,18 +68,9 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { ) : ( { - if (showSkeleton && showList) { - skeletonTransitionRef.current.animateNextTransition(); - setShowSkeleton(false); - } - }} - renderItem={renderItem} - scrollIndicatorInsets={{ - bottom: exchangeModalBorderRadius, - }} + onLayout={onListLayout} /> )} @@ -83,7 +79,6 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { )} @@ -92,10 +87,13 @@ const CurrencySelectionList = ({ listItems, renderItem, showList, type }) => { }; CurrencySelectionList.propTypes = { + itemProps: PropTypes.object, listItems: PropTypes.array, - renderItem: PropTypes.func, showList: PropTypes.bool, - type: PropTypes.string, }; -export default React.memo(CurrencySelectionList); +const propsAreEqual = (prev, next) => + prev.listItems.length === next.listItems.length && + prev.showList === next.showList; + +export default memo(CurrencySelectionList, propsAreEqual); diff --git a/src/components/exchange/ExchangeAssetList.js b/src/components/exchange/ExchangeAssetList.js index 309de5a7839..cead37e5a70 100644 --- a/src/components/exchange/ExchangeAssetList.js +++ b/src/components/exchange/ExchangeAssetList.js @@ -1,123 +1,60 @@ -import { get } from 'lodash'; import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import { LayoutAnimation, View } from 'react-native'; -import { - DataProvider, - LayoutProvider, - RecyclerListView, -} from 'recyclerlistview'; -import { deviceUtils, isNewValueForPath } from '../../utils'; -import { colors } from '../../styles'; -import { CoinRow } from '../coin-row'; +import React, { useCallback } from 'react'; +import { FlatList } from 'react-native-gesture-handler'; +import { exchangeModalBorderRadius } from '../../screens/ExchangeModal'; +import { CoinRow, ExchangeCoinRow } from '../coin-row'; -const ViewTypes = { - COIN_ROW: 0, -}; +const getItemLayout = (_, index) => ({ + index, + length: CoinRow.height, + offset: CoinRow.height * index, +}); -const NOOP = () => undefined; +const keyExtractor = ({ uniqueId }) => `ExchangeAssetList-${uniqueId}`; -const layoutItemAnimator = { - animateDidMount: NOOP, - animateShift: () => - LayoutAnimation.configureNext( - LayoutAnimation.create(200, 'easeInEaseOut', 'opacity') - ), - animateWillMount: NOOP, - animateWillUnmount: NOOP, - animateWillUpdate: NOOP, +const contentContainerStyle = { + paddingBottom: exchangeModalBorderRadius, }; -const getLayoutTypeForIndex = () => ViewTypes.COIN_ROW; - -const hasRowChanged = (r1, r2) => isNewValueForPath(r1, r2, 'uniqueId'); - -const setLayoutForType = (type, dim) => { - if (type === ViewTypes.COIN_ROW) { - dim.width = deviceUtils.dimensions.width; - dim.height = CoinRow.height; - } else { - dim.width = 0; - dim.height = 0; - } +const scrollIndicatorInsets = { + bottom: exchangeModalBorderRadius, }; -export default class ExchangeAssetList extends PureComponent { - static propTypes = { - items: PropTypes.arrayOf(PropTypes.object), - onMount: PropTypes.func, - renderItem: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - dataProvider: new DataProvider(hasRowChanged, this.getStableId), - }; - - this.state.dataProvider._requiresDataChangeHandling = true; - - this.layoutProvider = new LayoutProvider( - getLayoutTypeForIndex, - setLayoutForType - ); - } - - componentDidMount = () => { - this.updateList(); - }; - - componentDidUpdate = prevProps => { - if (this.props.items.length !== prevProps.items.length) { - //this.rlvRef.current.forceRerender(); - this.updateList(); - } - }; - - getStableId = index => - get(this.state, `dataProvider._data[${index}].uniqueId`); - - handleMount = () => { - if (this.props.onMount) { - this.props.onMount(); - } - }; +const ExchangeAssetList = ({ itemProps, items, onLayout }) => { + const renderItemCallback = useCallback( + ({ item }) => , + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); - renderRow = (type, data) => this.props.renderItem(data); + return ( + + ); +}; - rlvRef = React.createRef(); +ExchangeAssetList.propTypes = { + itemProps: PropTypes.object, + items: PropTypes.array.isRequired, + onLayout: PropTypes.func, +}; - updateList = () => { - this.setState(prevState => ({ - dataProvider: prevState.dataProvider.cloneWithRows(this.props.items), - })); - }; +const propsAreEqual = (prev, next) => prev.items.length === next.items.length; - render = () => ( - - - - ); -} +export default React.memo(ExchangeAssetList, propsAreEqual); diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 679abe11ad5..1f8cec1b167 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -12,6 +12,7 @@ import { import { connect } from 'react-redux'; import { compose, withProps } from 'recompact'; import { createSelector } from 'reselect'; +import { uniswapUpdateFavorites } from '../redux/uniswap'; import { uniswapAssetAddresses, uniswapAssetsClean } from '../references'; import withAccountData from './withAccountData'; @@ -70,7 +71,7 @@ const mapStateToProps = ({ uniswap: { favorites, uniswapAssets } }) => ({ }); export default compose( - connect(mapStateToProps), + connect(mapStateToProps, { uniswapUpdateFavorites }), withAccountData, withProps(withSortedUniswapAssetsSelector), withProps(withAssetsAvailableOnUniswapSelector) diff --git a/src/hooks/index.js b/src/hooks/index.js new file mode 100644 index 00000000000..df52b2e2db8 --- /dev/null +++ b/src/hooks/index.js @@ -0,0 +1 @@ +export { default as useConstant } from './useConstant'; diff --git a/src/hooks/useConstant.js b/src/hooks/useConstant.js new file mode 100644 index 00000000000..b68018f63cd --- /dev/null +++ b/src/hooks/useConstant.js @@ -0,0 +1,11 @@ +import { useRef } from 'react'; + +export default function useConstant(fn) { + const ref = useRef(); + + if (!ref.current) { + ref.current = { v: fn() }; + } + + return ref.current.v; +} diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 29e5c697d11..c2b713d35b6 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -1,15 +1,15 @@ import { get, map, property } from 'lodash'; import PropTypes from 'prop-types'; +import { produce } from 'immer'; import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; import { NavigationEvents, withNavigationFocus } from 'react-navigation'; import { compose, mapProps } from 'recompact'; import { withUniswapAssets } from '../hoc'; import { position } from '../styles'; -import { isNewValueForPath } from '../utils'; +import { isNewValueForObjectPaths } from '../utils'; import { filterList } from '../utils/search'; import { interpolate } from '../components/animations'; -import { ExchangeCoinRow } from '../components/coin-row'; import { CurrencySelectionList, CurrencySelectModalHeader, @@ -49,6 +49,7 @@ class CurrencySelectModal extends Component { }; state = { + assetsToFavoriteQueue: {}, searchQuery: '', }; @@ -67,12 +68,21 @@ class CurrencySelectModal extends Component { const nextAssetsUniqueId = buildUniqueIdForListData(nextAssets); const isNewAssets = currentAssetsUniqueId !== nextAssetsUniqueId; - return ( - isNewAssets || - isNewValueForPath(this.props, nextProps, 'isFocused') || - isNewValueForPath(this.props, nextProps, 'type') || - isNewValueForPath(this.state, nextState, 'searchQuery') - ); + const isNewProps = isNewValueForObjectPaths(this.props, nextProps, [ + 'isFocused', + 'type', + ]); + + const isNewState = isNewValueForObjectPaths(this.state, nextState, [ + 'searchQuery', + 'assetsToFavoriteQueue', + ]); + + const shouldUpdate = isNewAssets || isNewProps || isNewState; + + // console.log('shouldUpdate CurrencySelectModal', shouldUpdate); + + return shouldUpdate; }; dangerouslySetIsGestureBlocked = isGestureBlocked => { @@ -86,6 +96,14 @@ class CurrencySelectModal extends Component { this.setState({ searchQuery }); }; + handleFavoriteAsset = (assetAddress, isFavorited) => { + this.setState( + produce(draft => { + draft.assetsToFavoriteQueue[assetAddress] = isFavorited; + }) + ); + }; + handlePressBack = () => { this.props.navigation.navigate('MainExchangeScreen'); }; @@ -100,7 +118,19 @@ class CurrencySelectModal extends Component { navigation.navigate('MainExchangeScreen'); }; - handleDidBlur = () => this.handleChangeSearchQuery(''); + handleDidBlur = () => { + const { uniswapUpdateFavorites } = this.props; + const { assetsToFavoriteQueue } = this.state; + + Object.keys(assetsToFavoriteQueue).map(assetToFavorite => + uniswapUpdateFavorites( + assetToFavorite, + assetsToFavoriteQueue[assetToFavorite] + ) + ); + + this.handleChangeSearchQuery(''); + }; handleWillBlur = () => this.dangerouslySetIsGestureBlocked(false); @@ -111,20 +141,6 @@ class CurrencySelectModal extends Component { } }; - renderCurrencyItem = item => { - const { type } = this.props; - - return ( - - ); - }; - searchInputRef = React.createRef(); render = () => { @@ -136,6 +152,10 @@ class CurrencySelectModal extends Component { type, } = this.props; + if (type === null || type === undefined) { + return null; + } + const { searchQuery } = this.state; let headerTitle = ''; @@ -185,9 +205,14 @@ class CurrencySelectModal extends Component { searchQuery={searchQuery} /> diff --git a/yarn.lock b/yarn.lock index 227a4c8455a..265160c5c2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -692,9 +692,9 @@ integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": - version "5.0.0-beta.131" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.131.tgz#55913b508397eab3cdc0bed9c1021b99b5e3efbe" - integrity sha512-tKtaqVs6jBk3o85WmIHEDlkZxUpX4pRIuSTIY2ElSLPJ31A7+iN8sf0/fdI7FH9Juza394YTbnjpbWNrYjBWow== + version "5.0.0-beta.132" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.132.tgz#d7d8585204df11a812e53e2547f3bb3070b97efd" + integrity sha512-k/DijFpuADnKczHlhuGrCwuq7fAYjTuoOe26h50JncYs5ZiKmtht3zzllVUs75jEac2KjEV6zRMOnFvG7hDsmg== dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" "@ethersproject/bytes" ">=5.0.0-beta.129" @@ -704,9 +704,9 @@ bn.js "^4.4.0" "@ethersproject/bignumber@>=5.0.0-beta.130": - version "5.0.0-beta.133" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.133.tgz#d4b51626b84e5cd0cda236c1c3caa5fd49d9b60f" - integrity sha512-bvp7hFp8yE/+vdLOo7TdtzYtxUgJJNnpLWg6pUnd3Vg/05uJX7LfGr0n4WQ7t8Ue+I48rZ2PyeCzpY49XxBTqQ== + version "5.0.0-beta.134" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.134.tgz#771fa3f1f8315aba27ea0e479d1e5953ce83f68b" + integrity sha512-gOqtMLl5ZTufp7ugt0XUYrTT5CawkoESDs55/E4BtgYhaEC43omiWPyHy6dGDY8QnJB2uMV+YE00ubuhxiG00Q== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/logger" ">=5.0.0-beta.129" @@ -714,9 +714,9 @@ bn.js "^4.4.0" "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0-beta.126": - version "5.0.0-beta.132" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.132.tgz#6664b468eb78b24f965014118e949cd85c0c3801" - integrity sha512-w8lf+xVdN3W48xg+JystkelbMWI7r8bRMpFKYIkNkKUc9JmxVI9voTV1AM/ELVCLpELYluZNZIpWJ/fSfQYs/A== + version "5.0.0-beta.133" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.133.tgz#9f0d2b40cfeaf9c88d93e51b3472135779e26119" + integrity sha512-5eNRc9+skcRocMBYbyMtlW1rwuPCYMPZJYIDGIbVtxY0+dC/SJVg7KbSOk9NLAROhrmh7NwjIs9fnAKe+KzjvQ== dependencies: "@ethersproject/logger" ">=5.0.0-beta.129" @@ -736,28 +736,28 @@ js-sha3 "0.5.7" "@ethersproject/logger@>=5.0.0-beta.129": - version "5.0.0-beta.131" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.131.tgz#d52ab173fd0b459117ce47e43f38d1e3b1a5add4" - integrity sha512-5WKvSvijhhQ5+7vCIJSU/fmxuGY2ENd+axeN/Gjk+0l1hZmYPSMvO4jJ1YSnu38BhhvI8aiVM3PDlmzAWwwv4g== + version "5.0.0-beta.132" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.132.tgz#310ab1318749ddab21c881301140b6d6b5723aab" + integrity sha512-qIUvCrtNKDjyy6TgYs9fgRZ0Ma3A8iziAh9jJ8aEdvyg70a8PLw7t+jN7S836VhbXaxjrKBsIZTHqWuzVFCVgQ== "@ethersproject/properties@>=5.0.0-beta.131": - version "5.0.0-beta.133" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.133.tgz#923368411404cfb4c59442a6c22777e69b17dc68" - integrity sha512-H9vG6h/wqWmonyS8mJyuIFJOlR0xHeUw4hWt6nplClYWOSVXR/RL10/tWKyXvu38efVVHgtXz4WH1Be2iq6e7g== + version "5.0.0-beta.134" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.134.tgz#bc751854c0040756f4ce96dab9097de51f3e8552" + integrity sha512-y1/F8X+tJPOGxx31e9KYPpKLFbempySb7CBL+t4oNvWD8StC2coECKUW2tI/mSTFQ3mW5X9JWcaYY/N6hvBYug== dependencies: "@ethersproject/logger" ">=5.0.0-beta.129" "@ethersproject/rlp@>=5.0.0-beta.126": - version "5.0.0-beta.129" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.129.tgz#a21c8600dbd1dc18c2e9e50544bccd6269eb4410" - integrity sha512-DRLFIk0EilPn8DZiA7CLJjTgttOWJJ4iKOSgfjJ9JHMGFtnbQv6TzrBEjYGldZWvcXjke+ejJZBXgePFOgANCA== + version "5.0.0-beta.130" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.130.tgz#3f219265fa6216316961cd3bc5fbe0d25439da87" + integrity sha512-VupRQw1Pxxnl1Fr9q0sohZAqhuzU+rt1HJxuUW+5ZeLv7EKwdNxUjSLzmS91os64L3cxv39mh4844UktI1FVVg== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": - version "5.0.0-beta.133" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.133.tgz#29e90392afa3a845be2a25e789fb49befed69a73" - integrity sha512-HECi1/szfKzFnkBgXNTzysGxLKeyNLEu3wlR//6LUpyYZ/xazenM/3Xhr4QuBPNssK8snpKyXL5MdR3yB4esFg== + version "5.0.0-beta.134" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.134.tgz#d15562ed260e961fd278964169707f12de7130b0" + integrity sha512-eqX+b13uC6goxdaZk7vzrwCaPKVGgNM60lTQ642GZVjXwYdqeGFqOMQXi6q9DDXzgx6WGXIGTjl9GS3qwKYQXg== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/constants" ">=5.0.0-beta.128" @@ -1107,9 +1107,9 @@ ws "^1.1.0" "@react-native-community/cli@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.1.tgz#d7dfec14c867a17793bb981dd90eef2d8fc7808a" - integrity sha512-fh7hZHNmGciBOIJHUdS4D6/7KaIlmdJLG0i/efxm7spuMI0uviWwz4IcjNRanFbAgYu3Yp4rfke+Gm/gcHSRaA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.4.tgz#a9dba1bc77855a6e45fccaabb017360645d936bb" + integrity sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA== dependencies: "@hapi/joi" "^15.0.3" "@react-native-community/cli-debugger-ui" "^3.0.0" @@ -1346,9 +1346,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.7.tgz#2496e9ff56196cc1429c72034e07eab6121b6f3f" - integrity sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw== + version "7.0.8" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.8.tgz#479a4ee3e291a403a1096106013ec22cf9b64012" + integrity sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw== dependencies: "@babel/types" "^7.3.0" @@ -1407,9 +1407,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.8.tgz#dab418655af39ce2fa99286a0bed21ef8072ac9d" - integrity sha512-XLla8N+iyfjvsa0KKV+BP/iGSoTmwxsu5Ci5sM33z9TjohF72DEz95iNvD6pPmemvbQgxAv/909G73gUn8QR7w== + version "12.12.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.11.tgz#bec2961975888d964196bf0016a2f984d793d3ce" + integrity sha512-O+x6uIpa6oMNTkPuHDa9MhMMehlxLAd5QcOvKRjAFsBVpeFWTOPnXbDvILvFgFFZfQ1xh1EZi1FbXxUix+zpsQ== "@types/node@^10.3.2": version "10.17.5" @@ -1998,16 +1998,16 @@ atob@^2.1.1: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.5.1: - version "9.7.1" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.1.tgz#9ffc44c55f5ca89253d9bb7186cefb01ef57747f" - integrity sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw== + version "9.7.2" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.2.tgz#26cf729fbb709323b40171a874304884dcceffed" + integrity sha512-LCAfcdej1182uVvPOZnytbq61AhnOZ/4JelDaJGDeNwewyU1AMaNthcHsyz1NRjTmd2FkurMckLWfkHg3Z//KA== dependencies: - browserslist "^4.7.2" - caniuse-lite "^1.0.30001006" + browserslist "^4.7.3" + caniuse-lite "^1.0.30001010" chalk "^2.4.2" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^7.0.21" + postcss "^7.0.23" postcss-value-parser "^4.0.2" aws-sign2@~0.7.0: @@ -2464,14 +2464,14 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.7.2: - version "4.7.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.2.tgz#1bb984531a476b5d389cedecb195b2cd69fb1348" - integrity sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw== +browserslist@^4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.3.tgz#02341f162b6bcc1e1028e30624815d4924442dc3" + integrity sha512-jWvmhqYpx+9EZm/FxcZSbUZyDEvDTLDi3nSAKbzEkyWvtI0mNSmUosey+5awDW1RUlrgXbQb5A6qY1xQH9U6MQ== dependencies: - caniuse-lite "^1.0.30001004" - electron-to-chromium "^1.3.295" - node-releases "^1.1.38" + caniuse-lite "^1.0.30001010" + electron-to-chromium "^1.3.306" + node-releases "^1.1.40" bser@^2.0.0: version "2.1.1" @@ -2636,10 +2636,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006: - version "1.0.30001010" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz#397a14034d384260453cc81994f494626d34b938" - integrity sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw== +caniuse-lite@^1.0.30001010: + version "1.0.30001011" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001011.tgz#0d6c4549c78c4a800bb043a83ca0cbe0aee6c6e1" + integrity sha512-h+Eqyn/YA6o6ZTqpS86PyRmNWOs1r54EBDcd2NTwwfsXQ8re1B38SnB+p2RKF8OUsyEIjeDU8XGec1RGO/wYCg== capture-exit@^2.0.0: version "2.0.0" @@ -3690,14 +3690,14 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= ejs@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.2.tgz#749037c4c09bd57626a6140afbe6b7e650661614" - integrity sha512-rHGwtpl67oih3xAHbZlpw5rQAt+YV1mSCu2fUZ9XNrfaGEhom7E+AUiMci+ByP4aSfuAWx7hE0BPuJLMrpXwOw== + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -electron-to-chromium@^1.3.295: - version "1.3.306" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz#e8265301d053d5f74e36cb876486830261fbe946" - integrity sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A== +electron-to-chromium@^1.3.306: + version "1.3.310" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.310.tgz#a6c0c194d93ff54fcdc6dc3843689abb5c4dec0c" + integrity sha512-ixvxy46JrDv5c8k1+th66Z+xDZD8zShNs6oh7hgyMpNZUgaoRBisXgFZKAyyhQTAj7oU2Y/uZ0AAsj/TY4N0tA== elliptic@6.3.3: version "6.3.3" @@ -3790,9 +3790,9 @@ entities@^2.0.0: integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== envinfo@^7.1.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.4.0.tgz#bef4ece9e717423aaf0c3584651430b735ad6630" - integrity sha512-FdDfnWnCVjxTTpWE3d6Jgh5JDIA3Cw7LCgpM/pI7kK1ORkjaqI2r6NqQ+ln2j0dfpgxY00AWieSvtkiZQKIItA== + version "7.5.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.5.0.tgz#91410bb6db262fb4f1409bd506e9ff57e91023f4" + integrity sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ== errno@^0.1.1, errno@~0.1.1: version "0.1.7" @@ -3842,12 +3842,12 @@ es-to-primitive@^1.2.0: is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.52" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.52.tgz#bb21777e919a04263736ded120a9d665f10ea63f" - integrity sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag== + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== dependencies: es6-iterator "~2.0.3" - es6-symbol "~3.1.2" + es6-symbol "~3.1.3" next-tick "~1.0.0" es6-iterator@~2.0.3: @@ -3871,7 +3871,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@~3.1.2: +es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== @@ -4045,10 +4045,10 @@ eslint-plugin-react@^7.12.4: prop-types "^15.7.2" resolve "^1.12.0" -eslint-plugin-relay@1.3.12: - version "1.3.12" - resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.3.12.tgz#1e7d936386650ccc7709c8f6eeb0210e0e226527" - integrity sha512-276RrlyF0112Mz8PbaDvYKmqBGYEm0WBCfMNunnm6jHQ0aClUbPUmNctJXpFjfurcZfNEOz22Nx3VUMVDIGIkw== +eslint-plugin-relay@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.4.1.tgz#5af2ac13e24bd01ad17b6a4014204918d65021cd" + integrity sha512-yb+p+4AxZTi2gXN7cZRfXMBFlRa5j6TtiVeq3yHXyy+tlgYNpxi/dDrP1+tcUTNP9vdaJovnfGZ5jp6kMiH9eg== dependencies: graphql "^14.0.0" @@ -4779,6 +4779,11 @@ funpermaproxy@^1.0.1: resolved "https://registry.yarnpkg.com/funpermaproxy/-/funpermaproxy-1.0.1.tgz#4650e69b7c334d9717c06beba9b339cc08ac3335" integrity sha512-9pEzs5vnNtR7ZGihly98w/mQ7blsvl68Wj30ZCDAXy7qDN4CWLLjdfjtH/P2m6whsnaJkw15hysCNHMXue+wdA== +fuzzysearch@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fuzzysearch/-/fuzzysearch-1.0.3.tgz#dffc80f6d6b04223f2226aa79dd194231096d008" + integrity sha1-3/yA9tawQiPyImqnndGUIxCW0Ag= + fwd-stream@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/fwd-stream/-/fwd-stream-1.0.4.tgz#ed281cabed46feecf921ee32dc4c50b372ac7cfa" @@ -5100,7 +5105,7 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.0: +has-symbols@^1.0.0, has-symbols@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== @@ -5795,11 +5800,11 @@ is-stream@^2.0.0: integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== dependencies: - has-symbols "^1.0.0" + has-symbols "^1.0.1" is-typedarray@~1.0.0: version "1.0.0" @@ -6926,9 +6931,9 @@ meow@^5.0.0: yargs-parser "^10.0.0" merge-anything@^2.2.4, merge-anything@^2.2.5: - version "2.4.1" - resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.1.tgz#e9bccaec1e49ec6cb5f77ca78c5770d1a35315e6" - integrity sha512-dYOIAl9GFCJNctSIHWOj9OJtarCjsD16P8ObCl6oxrujAG+kOvlwJuOD9/O9iYZ9aTi1RGpGTG9q9etIvuUikQ== + version "2.4.2" + resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.2.tgz#f7152fc4764ae02c024742afb14a989c1a0f1f27" + integrity sha512-/so+4seX7fdAhPI3m3bxwc60vhotzY9uM+1Z6C3GKeJBYzxt/lIrbs5uT9iwgM5aLi5kpJIPT7JzJfrrfloWHA== dependencies: is-what "^3.3.1" @@ -7889,10 +7894,10 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.38: - version "1.1.40" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.40.tgz#a94facfa8e2d612302601ca1361741d529c4515a" - integrity sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ== +node-releases@^1.1.40: + version "1.1.41" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.41.tgz#57674a82a37f812d18e3b26118aefaf53a00afed" + integrity sha512-+IctMa7wIs8Cfsa8iYzeaLTFwv5Y4r5jZud+4AnfymzeEXKBCavFX0KBgzVaPVqf0ywa6PrO8/b+bPqdwjGBSg== dependencies: semver "^6.3.0" @@ -8844,10 +8849,10 @@ postcss-value-parser@^4.0.2: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.7: - version "7.0.21" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" - integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.7: + version "7.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.23.tgz#9f9759fad661b15964f3cfc3140f66f1e05eadc1" + integrity sha512-hOlMf3ouRIFXD+j2VJecwssTwbvsPGJVMzupptg+85WA+i7MwyrydmQAgY3R+m0Bc0exunhbJmijy8u8+vufuQ== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -9182,9 +9187,9 @@ react-native-bundle-visualizer@^2.0.1: source-map-explorer "^2.1.0" react-native-camera@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.9.0.tgz#334d9d7be5476d673af4df954929958ecc36ed55" - integrity sha512-qUhog1yd7FQ9xRTxN1SP+T5f4uLuVY5eXx6mMlBCNsqvYSoKCWFHH1Kpil9fx7d2iOl/o09o/7kHNcSl9RkrkQ== + version "3.11.1" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.11.1.tgz#5c2851d8208f2aa47007bd123f6056aaf9c58e18" + integrity sha512-uzsGgXVKEh9PrOOOfYuFj9X/jnSv8i0b6upcsCkFVBtF7iIs/nED23ZSf2UTWsRH5LR07/yqA9PDebjh76hKVQ== dependencies: prop-types "^15.6.2" @@ -9260,10 +9265,10 @@ react-native-firebase@^5.5.6: opencollective-postinstall "^2.0.0" prop-types "^15.7.2" -react-native-gesture-handler@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.4.1.tgz#c38d9e57637b95e221722a79f2bafac62e3aeb21" - integrity sha512-Ffcs+SbEbkGaal0CClYL+v7A9y4OA5G5lW01qrzjxaqASp5C8BfnWSKuqYKE00s6bLwE5L4xnlHkG0yIxAtbrQ== +react-native-gesture-handler@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.1.tgz#681cef98954d48cd82f99f75de3ab203c8754354" + integrity sha512-n4+tXAplf7B3qoHgvOxmKfx8cr/hzCSxyEEGxO/3aYyvSYbyt1o6Q7hmTC2JuezllB44b4v/FcCTd6Rgu3MMfg== dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -9422,9 +9427,9 @@ react-native-svg@9.13.3: css-tree "^1.0.0-alpha.37" react-native-tab-view@^2.9.0: - version "2.10.2" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.10.2.tgz#35ae92f574f2220312138f479a99ad3cbf981b6f" - integrity sha512-DJMz7WDlQiykgvojaEPM5MKFNMlGC89SMhX++wkD6iJ4TK04NyUgvUKsZYuY7u6k0o0HtG7sNeexFsbxfwhrVg== + version "2.11.0" + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.11.0.tgz#2e57d1f617ccc88c7f452708804f3409f880b700" + integrity sha512-vqetlxGO7A8bnqvXcB50MWpRZAImXFrDGz1WCQKdCqe03Ey3ZzENe7yLuWrtBJYlepGfOLAsmCXv+wW82Yfm1w== react-native-tcp@^3.3.2: version "3.3.2" @@ -9469,12 +9474,12 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/8797a5cfcb8a3dbd233408fb4ac86d78239f5e3f" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/390d0895ba1dd059ed65d8292c566bd2e46a9eba" dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0" - "@react-native-community/cli-platform-android" "^3.0.0" - "@react-native-community/cli-platform-ios" "^3.0.0" + "@react-native-community/cli" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" abort-controller "^3.0.0" base64-js "^1.1.2" connect "^3.6.5" @@ -9502,10 +9507,10 @@ react-native@facebook/react-native: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.36: - version "2.0.0-alpha.36" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.36.tgz#b8b207a7523c7919f39713a652f178c161754a70" - integrity sha512-29X8H4Z55MXzf7YWANj7TsfB5tHizALF5VWu2kgTENobNJWbNSeiwemQqXhsp58YmaWTmKcE1GpfeW3tPEoEvA== +react-navigation-stack@2.0.0-alpha.37: + version "2.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.37.tgz#15c38f7ef9923a2b6739c2bc8441f8ab70af3ec3" + integrity sha512-2AcidUvhNgErV2QlV3s7wSdkbAJ+sQEAsHrHF4xK8PTf04I9+qG3/Ds9Orx31njhujHfuB5nN/77z+ih1iM+7g== react-navigation-tabs@2.5.6: version "2.5.6" @@ -10278,10 +10283,10 @@ schedule@0.5.0: dependencies: object-assign "^4.1.1" -scheduler@0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" - integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg== +scheduler@0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" + integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -11068,9 +11073,9 @@ superagent-proxy@^2.0.0: proxy-agent "3" superagent@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.0.tgz#9ce4f38bee64d65a56166423b573222fa1b8f041" - integrity sha512-7V6JVx5N+eTL1MMqRBX0v0bG04UjrjAvvZJTF/VDH/SH2GjSLqlrcYepFlpTrXpm37aSY6h3GGVWGxXl/98TKA== + version "5.1.1" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.1.tgz#f5c1336b0777e77e12a6f3962a060186342e43d0" + integrity sha512-bpTO/3yQsHPH5w6f7qPCWGTuhEV2w93fwFGpYODnUc5tPa3rmbHUCmwC7iuEFBQQJsyhiW1WVc/ISpfAEv6ojQ== dependencies: component-emitter "^1.3.0" cookiejar "^2.1.2" @@ -11717,6 +11722,11 @@ url@^0.10.3: punycode "1.3.2" querystring "0.2.0" +use-debounce@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-3.1.0.tgz#05a5c8cd3c2f309699f08961d7c8bbe7f68720bb" + integrity sha512-DEf3L/ZKkOSTARk/DHlC6KAAJKwMqpck8Zx06SM2Wr+LfU1TzhO8hZRzB/qbpSQqREYWQes24n1q9doeTMqF4g== + use-memo-one@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.1.tgz#39e6f08fe27e422a7d7b234b5f9056af313bd22c" @@ -11977,9 +11987,9 @@ which@1.3.1, which@^1.2.9, which@^1.3.0, which@^1.3.1: isexe "^2.0.0" which@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.1.tgz#f1cf94d07a8e571b6ff006aeb91d0300c47ef0a4" - integrity sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" @@ -12305,9 +12315,9 @@ yargs@^12.0.5: yargs-parser "^11.1.1" yargs@^14.2.0: - version "14.2.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.1.tgz#2bb87b57c12b9afea40bb4ed9745bb9eb5031a9b" - integrity sha512-rZ00XIuGAoI58F0weHyCP3PAN17wJqdN/pF8eMp+imuP+jSdMCD5t4bSf5d5FKPvEDrK9zYlnhO7bFYKQ5UYow== + version "14.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" + integrity sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA== dependencies: cliui "^5.0.0" decamelize "^1.2.0" From 2a60736661eeb472ad0caaae9d515e393e31e8f0 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 19 Nov 2019 00:19:43 -0500 Subject: [PATCH 541/636] Remove Kin from swap --- src/references/token-overrides.json | 3 --- src/references/uniswap-pairs.json | 6 ------ 2 files changed, 9 deletions(-) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 08e81905035..adb4452ca8d 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -75,9 +75,6 @@ "0x607F4C5BB672230e8672085532f7e901544a7375": { "name": "iExec" }, - "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { - "name": "Kin" - }, "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { "name": "Kleros" }, diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index ec15effabab..c6d68412d0c 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -137,12 +137,6 @@ "decimals": 9, "exchangeAddress": "0xA825CAE02B310E9901b4776806CE25db520c8642" }, - "0x818Fc6C2Ec5986bc6E2CBf00939d90556aB12ce5": { - "name": "Kin", - "symbol": "KIN", - "decimals": 18, - "exchangeAddress": "0xb7520a5F8c832c573d6BD0Df955fC5c9b72400F7" - }, "0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d": { "name": "Kleros", "symbol": "PNK", From cd485e8e2cf1c5b096a0c5a12db0dcf24daec702 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 23 Nov 2019 03:17:25 -0500 Subject: [PATCH 542/636] =?UTF-8?q?Break=20out=20logic=20from=20ButtonPres?= =?UTF-8?q?sAnimation=20into=20proc=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 56 +- package.json | 6 +- .../animations/ButtonPressAnimation.js | 84 +- src/components/animations/procs/cond.js | 17 + src/components/animations/procs/index.js | 15 + src/components/animations/procs/math.js | 4 + src/components/animations/procs/operators.js | 12 + src/components/animations/procs/timing.js | 84 ++ .../animations/procs/transformOrigin.js | 11 + .../animations/procs/updateState.js | 13 + src/hooks/index.js | 1 - src/hooks/useConstant.js | 11 - src/screens/CurrencySelectModal.js | 6 +- yarn.lock | 806 +++++++++--------- 14 files changed, 634 insertions(+), 492 deletions(-) create mode 100644 src/components/animations/procs/cond.js create mode 100644 src/components/animations/procs/math.js create mode 100644 src/components/animations/procs/operators.js create mode 100644 src/components/animations/procs/timing.js create mode 100644 src/components/animations/procs/transformOrigin.js create mode 100644 src/components/animations/procs/updateState.js delete mode 100644 src/hooks/index.js delete mode 100644 src/hooks/useConstant.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f264491825b..29eec764ab9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -391,7 +391,7 @@ PODS: - React - RNReactNativeHapticFeedback (1.8.2): - React - - RNReanimated (1.3.0): + - RNReanimated (1.4.0): - React - RNScreens (1.0.0-alpha.23): - React @@ -399,9 +399,9 @@ PODS: - React - RNSVG (9.13.3): - React - - SDWebImage (5.3.1): - - SDWebImage/Core (= 5.3.1) - - SDWebImage/Core (5.3.1) + - SDWebImage (5.3.2): + - SDWebImage/Core (= 5.3.2) + - SDWebImage/Core (5.3.2) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) @@ -636,8 +636,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 2f46475005546a849f4536fb0d9bbc6c947b180a - FBReactNativeSpec: fa241922044c423c26f9577be1b5645712cad339 + FBLazyVector: bb9fc4ac8ad481abfc658262730aa0cd29105793 + FBReactNativeSpec: 1cb863b5abf34acc6c0514c3ed1dc3f1cbef6ffa Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -653,15 +653,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 2b5646277a719d85c3d34612567fbfb1aadf9145 - RCTTypeSafety: ff6e3fec9f4af7fc6701114b37692b9006341a09 - React: 052db1fd4ac556dc1592417b2f609193da321474 - React-Core: e1f844506555a95e7a1040e41eeee769c106176b - React-CoreModules: 62ce394a4e1beaedd8555de319f9a20091131b70 - React-cxxreact: c84a96722f37ddd5aded39d348884df9836a7372 - React-jsi: a63afe42b704966ba3cc8b1cea48f3b122d34c4a - React-jsiexecutor: 20c480f3ea143218834c87c89a0efec93e902dca - React-jsinspector: 0e2b152e184ae4793bd15ff2db6cbf0216f2b975 + RCTRequired: 5c7236bbf0a85ac66b8cbfa983cac889547f1778 + RCTTypeSafety: b8adcc133dd28a5052f1c9100576a387d3f6e00f + React: d5a2094454524f5bb265c7bd0cfd373321603029 + React-Core: b88cae7ba8e7a3c6af4a76bc1fc18a0f6378c650 + React-CoreModules: d9a69d1c19196c255dcf595d71dda321c7eb0982 + React-cxxreact: 19fc38ac723387831e39e203edb291e1457379df + React-jsi: 0bedf89b92da6e7ecbbeaa9c1a241c86affaa5bd + React-jsiexecutor: e51443e84d5198caa26c53e6bdda964f58dc8518 + React-jsinspector: 0f9270878bbaa1fedf2e573cd43e48792d1619dd react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -672,16 +672,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 461bd041982eb739c1be94d9cfbf7818d1d05507 - React-RCTAnimation: 6b7b68991927e6ef83282a385bfe971f5fcd298c - React-RCTBlob: 9e7a1de1a9cfe750c0f3832a9b471a694f0ccb94 - React-RCTImage: 6a8489a99368f35b15755f805ec980e8d30741de - React-RCTLinking: f4621e7c7e0c892533ff0f6a7ed9a7ed5e4f55ca - React-RCTNetwork: 8a6b08e7bbd58fad2fb0661848011d9ccfcc14db - React-RCTSettings: 64f7701f3683abb3c6fced20a82d1e512c7e4e7e - React-RCTText: 6623e85ca666578e1744858d78b323291ced9ada - React-RCTVibration: c16066afc43000d7a2969adb27cb0f6e08d7cd08 - ReactCommon: ab029e0e08e9fc52630c3edc5b21c9c0648dcb9b + React-RCTActionSheet: 5251c300b9b9d7e5c7b38d1c3c130258a3cb9e24 + React-RCTAnimation: 11d6d0f698e183715109cbd800886087e1270faa + React-RCTBlob: f487ada7b57e46a92ca7239edf5370fdb70c3a40 + React-RCTImage: 6b1d315125038c086698eb0dfec8a78c034154d9 + React-RCTLinking: 0055f1c44f3544f908e34990467f83d25f8ad01f + React-RCTNetwork: 6da013dbe1444f8d3170be943d5b23abf43719f1 + React-RCTSettings: 884513d991b95e67c88171432997b13770b551ac + React-RCTText: 96c70d59c4fdfa5534ff594e509ef455658fb290 + React-RCTVibration: 88bf669028a221a5fb2467ecf95e43ce8f131213 + ReactCommon: 5aeb787b348070838dc868f8b48ddc7bea800679 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -695,18 +695,18 @@ SPEC CHECKSUMS: RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 - RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1 + RNReanimated: 8b675a650fc67c87f63d4345a1b2d4a699c25e4f RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c - SDWebImage: 7137d57385fb632129838c1e6ab9528a22c666cc + SDWebImage: 6ac2eb96571bff96ecde31a987172c5934a0eb7d SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: d827efa299f868ae67dea515f0727b7afaa4d2e1 + Yoga: 43ec3b62f85953e3df241983a36c5b2f1458b3f8 PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 diff --git a/package.json b/package.json index 5336e83dcc5..035db66f648 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "android": "react-native run-android", - "clean": "react-native-clean-project", + "clean": "react-native clean-project-auto", "start": "react-native start", "test": "jest test.js", "install-pods": "cd ios && pod install && cd ..", @@ -50,7 +50,6 @@ "eth-contract-metadata": "^1.9.3", "ethers": "^4.0.39", "events": "^1.1.1", - "fuzzysearch": "^1.0.3", "global": "^4.3.2", "grapheme-splitter": "^1.0.4", "https-browserify": "0.0.1", @@ -101,7 +100,7 @@ "react-native-qrcode-svg": "git+https://github.com/mikedemarais/react-native-qrcode-svg.git", "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", - "react-native-reanimated": "1.3.0", + "react-native-reanimated": "software-mansion/react-native-reanimated", "react-native-redash": "8.2.2", "react-native-safe-area-context": "^0.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", @@ -141,7 +140,6 @@ "timers-browserify": "^1.4.2", "tty-browserify": "0.0.0", "url": "^0.10.3", - "use-debounce": "^3.1.0", "util": "^0.10.3", "vm-browserify": "0.0.4" }, diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 4a06415c2b4..21f5de06ece 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -9,31 +9,33 @@ import { } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; -import { - contains, - transformOrigin as transformOriginUtil, - timing, -} from 'react-native-redash'; import stylePropType from 'react-style-proptype'; import { animations, colors } from '../../styles'; import { directionPropType } from '../../utils'; -import { interpolate } from './procs'; +import { + and, + cond as condProc, + contains, + divide, + eq, + greaterThan, + interpolate, + lessThan, + or, + set, + timing, + transformOrigin as transformOriginUtil, +} from './procs'; const { - and, block, call, Clock, cond, createAnimatedComponent, - divide, - eq, - or, event, - greaterThan, - lessThan, onChange, - set, + proc, stopClock, Value, } = Animated; @@ -66,6 +68,14 @@ const HapticFeedbackTypes = { selection: 'selection', }; +const isBetweenProc = proc( + (scaleTo, defaultScale, lessThanCondition, greaterThanCondition) => + or( + and(lessThan(scaleTo, defaultScale), lessThanCondition), + and(greaterThan(scaleTo, defaultScale), greaterThanCondition) + ) +); + export default class ButtonPressAnimation extends Component { static propTypes = { activeOpacity: PropTypes.number, @@ -205,13 +215,11 @@ export default class ButtonPressAnimation extends Component { const { activeOpacity, children, - defaultScale, disabled, exclusive, - scaleTo, style, - transformOrigin, tapRef, + transformOrigin, ...props } = this.props; @@ -231,10 +239,10 @@ export default class ButtonPressAnimation extends Component { (this.props.defaultScale - this.props.scaleTo) / 2; const opacity = - scaleTo > defaultScale + this.props.scaleTo > this.props.defaultScale ? activeOpacity - : interpolate(divide(this.scale, defaultScale), { - inputRange: [scaleTo, defaultScale], + : interpolate(divide(this.scale, this.props.defaultScale), { + inputRange: [this.props.scaleTo, this.props.defaultScale], outputRange: [activeOpacity, 1], }); @@ -273,15 +281,11 @@ export default class ButtonPressAnimation extends Component { ]), cond(contains([FAILED, CANCELLED, END], this.gestureState), [ cond( - or( - and( - greaterThan(this.props.defaultScale, this.props.scaleTo), - lessThan(this.scale, scaleDiff) - ), - and( - lessThan(this.props.defaultScale, this.props.scaleTo), - greaterThan(this.scale, scaleDiff) - ) + isBetweenProc( + this.props.scaleTo, + this.props.defaultScale, + lessThan(this.scale, scaleDiff), + greaterThan(this.scale, scaleDiff) ), block([stopClock(this.clock), set(this.shouldSpring, 0)]) ), @@ -289,14 +293,16 @@ export default class ButtonPressAnimation extends Component { ]), onChange( this.gestureState, - cond( + condProc( eq(this.gestureState, ACTIVE), [ call([], this.createInteraction), call([], this.createLongPressListener), call([], this.handlePressStart), ], - cond(eq(this.gestureState, END), [call([], this.handlePress)]) + condProc(eq(this.gestureState, END), [ + call([], this.handlePress), + ]) ) ), cond( @@ -314,17 +320,13 @@ export default class ButtonPressAnimation extends Component { ), cond( and( - or( - and( - greaterThan(this.props.defaultScale, this.props.scaleTo), - lessThan(this.scale, this.props.defaultScale) - ), - and( - lessThan(this.props.defaultScale, this.props.scaleTo), - greaterThan(this.scale, this.props.defaultScale) - ) - ), - eq(this.shouldSpring, 0) + eq(this.shouldSpring, 0), + isBetweenProc( + this.props.scaleTo, + this.props.defaultScale, + lessThan(this.scale, this.props.defaultScale), + greaterThan(this.scale, this.props.defaultScale) + ) ), set( this.scale, diff --git a/src/components/animations/procs/cond.js b/src/components/animations/procs/cond.js new file mode 100644 index 00000000000..42102505085 --- /dev/null +++ b/src/components/animations/procs/cond.js @@ -0,0 +1,17 @@ +import Animated from 'react-native-reanimated'; + +const condSingleCase = Animated.proc((conditional, trueCase) => + Animated.cond(conditional, trueCase) +); + +const condDoubleCase = Animated.proc((conditional, trueCase, falseCase) => + Animated.cond(conditional, trueCase, falseCase) +); + +export default function cond(conditional, trueCase, falseCase) { + if (falseCase) { + return condDoubleCase(conditional, trueCase, falseCase); + } + + return condSingleCase(conditional, trueCase); +} diff --git a/src/components/animations/procs/index.js b/src/components/animations/procs/index.js index 7d3b6e72dc9..2872bbd0ad3 100644 --- a/src/components/animations/procs/index.js +++ b/src/components/animations/procs/index.js @@ -1 +1,16 @@ +export { default as cond } from './cond'; export { default as interpolate } from './interpolate'; +export { divide, multiply } from './math'; +export { + and, + contains, + eq, + greaterThan, + lessThan, + not, + or, + set, +} from './operators'; +export { default as timing } from './timing'; +export { default as transformOrigin } from './transformOrigin'; +export { updateState } from './updateState'; diff --git a/src/components/animations/procs/math.js b/src/components/animations/procs/math.js new file mode 100644 index 00000000000..a3e29ab08eb --- /dev/null +++ b/src/components/animations/procs/math.js @@ -0,0 +1,4 @@ +import Animated from 'react-native-reanimated'; + +export const divide = Animated.proc((a, b) => Animated.divide(a, b)); +export const multiply = Animated.proc((a, b) => Animated.multiply(a, b)); diff --git a/src/components/animations/procs/operators.js b/src/components/animations/procs/operators.js new file mode 100644 index 00000000000..1f2e669f59c --- /dev/null +++ b/src/components/animations/procs/operators.js @@ -0,0 +1,12 @@ +import Animated from 'react-native-reanimated'; + +export const and = Animated.proc((a, b) => Animated.and(a, b)); +export const eq = Animated.proc((a, b) => Animated.eq(a, b)); +export const greaterThan = Animated.proc((a, b) => Animated.greaterThan(a, b)); +export const lessThan = Animated.proc((a, b) => Animated.lessThan(a, b)); +export const not = Animated.proc(node => Animated.not(node)); +export const or = Animated.proc((a, b) => Animated.or(a, b)); +export const set = Animated.proc((node, value) => Animated.set(node, value)); + +export const contains = (values, value) => + values.reduce((acc, v) => or(acc, eq(value, v)), new Animated.Value(0)); diff --git a/src/components/animations/procs/timing.js b/src/components/animations/procs/timing.js new file mode 100644 index 00000000000..ef97ffb7df4 --- /dev/null +++ b/src/components/animations/procs/timing.js @@ -0,0 +1,84 @@ +import Animated, { Easing } from 'react-native-reanimated'; +import { set } from './operators'; +import { updateState } from './updateState'; + +const { + block, + Clock, + clockRunning, + cond, + startClock, + stopClock, + Value, +} = Animated; + +const timingProc = Animated.proc( + (clock, finished, position, time, frameTime, toValue, duration) => + Animated.timing( + clock, + { + finished, + frameTime, + position, + time, + }, + { + duration, + easing: Easing.linear, + toValue, + } + ) +); + +const runTiming = (clock, state, config) => + timingProc( + clock, + state.finished, + state.position, + state.time, + state.frameTime, + config.toValue, + config.duration + ); + +export default function timing(params) { + const { clock, duration, easing, from, to } = { + clock: new Clock(), + duration: 250, + easing: Easing.linear, + from: 0, + to: 1, + ...params, + }; + + const state = { + finished: new Value(0), + frameTime: new Value(0), + position: new Value(0), + time: new Value(0), + }; + + const config = { + duration, + easing, + toValue: new Value(0), + }; + + return block([ + cond(clockRunning(clock), 0, [ + updateState( + from, + to, + state.finished, + state.position, + state.time, + state.frameTime, + config.toValue + ), + startClock(clock), + ]), + runTiming(clock, state, config), + cond(state.finished, stopClock(clock)), + set(from, state.position), + ]); +} diff --git a/src/components/animations/procs/transformOrigin.js b/src/components/animations/procs/transformOrigin.js new file mode 100644 index 00000000000..2b42983cc92 --- /dev/null +++ b/src/components/animations/procs/transformOrigin.js @@ -0,0 +1,11 @@ +import { multiply } from './math'; + +export default function transformOrigin(x, y, ...transformations) { + return [ + { translateX: x }, + { translateY: y }, + ...transformations, + { translateX: multiply(x, -1) }, + { translateY: multiply(y, -1) }, + ]; +} diff --git a/src/components/animations/procs/updateState.js b/src/components/animations/procs/updateState.js new file mode 100644 index 00000000000..498959aea86 --- /dev/null +++ b/src/components/animations/procs/updateState.js @@ -0,0 +1,13 @@ +import Animated from 'react-native-reanimated'; +import { set } from './operators'; + +export const updateState = Animated.proc( + (value, dest, finished, position, time, frameTime, toValue) => + Animated.block([ + set(finished, 0), + set(time, 0), + set(position, value), + set(frameTime, 0), + set(toValue, dest), + ]) +); diff --git a/src/hooks/index.js b/src/hooks/index.js deleted file mode 100644 index df52b2e2db8..00000000000 --- a/src/hooks/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as useConstant } from './useConstant'; diff --git a/src/hooks/useConstant.js b/src/hooks/useConstant.js deleted file mode 100644 index b68018f63cd..00000000000 --- a/src/hooks/useConstant.js +++ /dev/null @@ -1,11 +0,0 @@ -import { useRef } from 'react'; - -export default function useConstant(fn) { - const ref = useRef(); - - if (!ref.current) { - ref.current = { v: fn() }; - } - - return ref.current.v; -} diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index c2b713d35b6..0f70855082d 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -78,11 +78,7 @@ class CurrencySelectModal extends Component { 'assetsToFavoriteQueue', ]); - const shouldUpdate = isNewAssets || isNewProps || isNewState; - - // console.log('shouldUpdate CurrencySelectModal', shouldUpdate); - - return shouldUpdate; + return isNewAssets || isNewProps || isNewState; }; dangerouslySetIsGestureBlocked = isGestureBlocked => { diff --git a/yarn.lock b/yarn.lock index 265160c5c2e..099b5dba86b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,17 +10,17 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" - integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.4.tgz#37e864532200cb6b50ee9a4045f5f817840166ab" + integrity sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.2" - "@babel/helpers" "^7.7.0" - "@babel/parser" "^7.7.2" - "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.7.2" + "@babel/generator" "^7.7.4" + "@babel/helpers" "^7.7.4" + "@babel/parser" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" convert-source-map "^1.7.0" debug "^4.1.0" json5 "^2.1.0" @@ -29,140 +29,140 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.2.tgz#2f4852d04131a5e17ea4f6645488b5da66ebf3af" - integrity sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.4.tgz#db651e2840ca9aa66f327dcec1dc5f5fa9611369" + integrity sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg== dependencies: - "@babel/types" "^7.7.2" + "@babel/types" "^7.7.4" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz#efc54032d43891fe267679e63f6860aa7dbf4a5e" - integrity sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg== +"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz#bb3faf1e74b74bd547e867e48f551fa6b098b6ce" + integrity sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz#32dd9551d6ed3a5fc2edc50d6912852aa18274d9" - integrity sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz#5f73f2b28580e224b5b9bd03146a4015d6217f5f" + integrity sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ== dependencies: - "@babel/helper-explode-assignable-expression" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-explode-assignable-expression" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-builder-react-jsx@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.0.tgz#c6b8254d305bacd62beb648e4dea7d3ed79f352d" - integrity sha512-LSln3cexwInTMYYoFeVLKnYPPMfWNJ8PubTBs3hkh7wCu9iBaqq1OOyW+xGmEdLxT1nhsl+9SJ+h2oUDYz0l2A== +"@babel/helper-builder-react-jsx@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.4.tgz#da188d247508b65375b2c30cf59de187be6b0c66" + integrity sha512-kvbfHJNN9dg4rkEM4xn1s8d1/h6TYNvajy9L1wx4qLn9HFg0IkTsQi4rfBe92nxrPUFcMsHoMV+8rU7MJb3fCA== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" esutils "^2.0.0" -"@babel/helper-call-delegate@^7.4.4": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz#df8942452c2c1a217335ca7e393b9afc67f668dc" - integrity sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw== +"@babel/helper-call-delegate@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz#621b83e596722b50c0066f9dc37d3232e461b801" + integrity sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA== dependencies: - "@babel/helper-hoist-variables" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-hoist-variables" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-create-class-features-plugin@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz#bcdc223abbfdd386f94196ae2544987f8df775e8" - integrity sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA== +"@babel/helper-create-class-features-plugin@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.4.tgz#fce60939fd50618610942320a8d951b3b639da2d" + integrity sha512-l+OnKACG4uiDHQ/aJT8dwpR+LhCJALxL0mJ6nzjB25e5IPwqV1VOsY7ah6UB1DG+VOXAIMtuC54rFJGiHkxjgA== dependencies: - "@babel/helper-function-name" "^7.7.0" - "@babel/helper-member-expression-to-functions" "^7.7.0" - "@babel/helper-optimise-call-expression" "^7.7.0" + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-member-expression-to-functions" "^7.7.4" + "@babel/helper-optimise-call-expression" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.0" - "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/helper-replace-supers" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" -"@babel/helper-create-regexp-features-plugin@^7.7.0": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz#6f20443778c8fce2af2ff4206284afc0ced65db6" - integrity sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ== +"@babel/helper-create-regexp-features-plugin@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" + integrity sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A== dependencies: "@babel/helper-regex" "^7.4.4" regexpu-core "^4.6.0" -"@babel/helper-define-map@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz#60b0e9fd60def9de5054c38afde8c8ee409c7529" - integrity sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA== +"@babel/helper-define-map@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz#2841bf92eb8bd9c906851546fe6b9d45e162f176" + integrity sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg== dependencies: - "@babel/helper-function-name" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-function-name" "^7.7.4" + "@babel/types" "^7.7.4" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz#db2a6705555ae1f9f33b4b8212a546bc7f9dc3ef" - integrity sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg== +"@babel/helper-explode-assignable-expression@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz#fa700878e008d85dc51ba43e9fb835cddfe05c84" + integrity sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg== dependencies: - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-function-name@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz#44a5ad151cfff8ed2599c91682dda2ec2c8430a3" - integrity sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q== +"@babel/helper-function-name@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz#ab6e041e7135d436d8f0a3eca15de5b67a341a2e" + integrity sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ== dependencies: - "@babel/helper-get-function-arity" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-get-function-arity" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz#c604886bc97287a1d1398092bc666bc3d7d7aa2d" - integrity sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw== +"@babel/helper-get-function-arity@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" + integrity sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-hoist-variables@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz#b4552e4cfe5577d7de7b183e193e84e4ec538c81" - integrity sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ== +"@babel/helper-hoist-variables@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz#612384e3d823fdfaaf9fce31550fe5d4db0f3d12" + integrity sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-member-expression-to-functions@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz#472b93003a57071f95a541ea6c2b098398bcad8a" - integrity sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA== +"@babel/helper-member-expression-to-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz#356438e2569df7321a8326644d4b790d2122cb74" + integrity sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz#99c095889466e5f7b6d66d98dffc58baaf42654d" - integrity sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" + integrity sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" -"@babel/helper-module-transforms@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz#154a69f0c5b8fd4d39e49750ff7ac4faa3f36786" - integrity sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ== +"@babel/helper-module-transforms@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz#8d7cdb1e1f8ea3d8c38b067345924ac4f8e0879a" + integrity sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA== dependencies: - "@babel/helper-module-imports" "^7.7.0" - "@babel/helper-simple-access" "^7.7.0" - "@babel/helper-split-export-declaration" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-simple-access" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" lodash "^4.17.13" -"@babel/helper-optimise-call-expression@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz#4f66a216116a66164135dc618c5d8b7a959f9365" - integrity sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg== +"@babel/helper-optimise-call-expression@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" + integrity sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.4" "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" @@ -176,60 +176,60 @@ dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz#4d69ec653e8bff5bce62f5d33fc1508f223c75a7" - integrity sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.0" - "@babel/helper-wrap-function" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - -"@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz#d5365c8667fe7cbd13b8ddddceb9bd7f2b387512" - integrity sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.7.0" - "@babel/helper-optimise-call-expression" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - -"@babel/helper-simple-access@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz#97a8b6c52105d76031b86237dc1852b44837243d" - integrity sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g== - dependencies: - "@babel/template" "^7.7.0" - "@babel/types" "^7.7.0" - -"@babel/helper-split-export-declaration@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz#1365e74ea6c614deeb56ebffabd71006a0eb2300" - integrity sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA== - dependencies: - "@babel/types" "^7.7.0" - -"@babel/helper-wrap-function@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz#15af3d3e98f8417a60554acbb6c14e75e0b33b74" - integrity sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w== - dependencies: - "@babel/helper-function-name" "^7.7.0" - "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - -"@babel/helpers@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.0.tgz#359bb5ac3b4726f7c1fde0ec75f64b3f4275d60b" - integrity sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g== - dependencies: - "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" +"@babel/helper-remap-async-to-generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz#c68c2407350d9af0e061ed6726afb4fff16d0234" + integrity sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-wrap-function" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + +"@babel/helper-replace-supers@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz#3c881a6a6a7571275a72d82e6107126ec9e2cdd2" + integrity sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.7.4" + "@babel/helper-optimise-call-expression" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + +"@babel/helper-simple-access@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" + integrity sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A== + dependencies: + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" + +"@babel/helper-split-export-declaration@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz#57292af60443c4a3622cf74040ddc28e68336fd8" + integrity sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug== + dependencies: + "@babel/types" "^7.7.4" + +"@babel/helper-wrap-function@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" + integrity sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg== + dependencies: + "@babel/helper-function-name" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + +"@babel/helpers@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" + integrity sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg== + dependencies: + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" "@babel/highlight@^7.0.0": version "7.5.0" @@ -240,373 +240,373 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2": - version "7.7.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.3.tgz#5fad457c2529de476a248f75b0f090b3060af043" - integrity sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.4.tgz#75ab2d7110c2cf2fa949959afb05fa346d2231bb" + integrity sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g== "@babel/plugin-external-helpers@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz#7f4cb7dee651cd380d2034847d914288467a6be4" - integrity sha512-QFmtcCShFkyAsNtdCM3lJPmRe1iB+vPZymlB4LnDIKEBj2yKQLQKtoxXxJ8ePT5fwMl4QGg303p4mB0UsSI2/g== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.7.4.tgz#8aa7aa402f0e2ecb924611cbf30942a497dfd17e" + integrity sha512-RVGNajLaFlknbZLutaP/uv7Q+xmVs2LMlEWFXbcjLnwtBdPqAVpV3nzYIAJqri/VjJCUrhG5nALijtg0aND+XA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz#ac54e728ecf81d90e8f4d2a9c05a890457107917" - integrity sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.4.tgz#2f964f0cb18b948450362742e33e15211e77c2ba" + integrity sha512-EcuXeV4Hv1X3+Q1TsuOmyyxeTRiSqurGJ26+I/FW1WbymmRRapVORm6x1Zl3iDIHyRxEs+VXWp6qnlcfcJSbbw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.0" + "@babel/helper-create-class-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz#2c0ac2dcc36e3b2443fead2c3c5fc796fb1b5145" - integrity sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.7.4.tgz#890de3c0c475374638292df31f6582160b54d639" + integrity sha512-1t6dh7BHYUz4zD1m4pozYYEZy/3m8dgOr9owx3r0mPPI3iGKRUKUbIxfYmcJ4hwljs/dhd0qOTr1ZDUp43ix+w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.2.0" + "@babel/plugin-syntax-export-default-from" "^7.7.4" "@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz#41c360d59481d88e0ce3a3f837df10121a769b39" - integrity sha512-Amph7Epui1Dh/xxUxS2+K22/MUi6+6JVTvy3P58tja3B6yKTSjwwx0/d83rF7551D6PVSSoplQb8GCwqec7HRw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.7.4.tgz#7db302c83bc30caa89e38fee935635ef6bd11c28" + integrity sha512-TbYHmr1Gl1UC7Vo2HVuj/Naci5BEGNZ0AJhzqD2Vpr6QPFWpUmBRLrIDjedzx7/CShq0bRDS2gI4FIs77VHLVQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.7.4" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096" - integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz#cc57849894a5c774214178c8ab64f6334ec8af71" + integrity sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.7.4" "@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz#ec21e8aeb09ec6711bc0a39ca49520abee1de379" + integrity sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" "@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz#e9bf1f9b9ba10c77c033082da75f068389041af8" - integrity sha512-kj4gkZ6qUggkprRq3Uh5KP8XnE1MdIO0J7MhdDX8+rAbB6dJ2UrensGIS+0NPZAaaJ1Vr0PN6oLUgXMU1uMcSg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.7.4.tgz#3f04c2de1a942cbd3008324df8144b9cbc0ca0ba" + integrity sha512-JmgaS+ygAWDR/STPe3/7y0lNlHgS+19qZ9aC06nYLwQ/XB7c0q5Xs+ksFU3EDnp9EiEsO0dnRAOKeyLHTZuW3A== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.2.0" + "@babel/plugin-syntax-optional-chaining" "^7.7.4" "@babel/plugin-syntax-class-properties@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz#23b3b7b9bcdabd73672a9149f728cd3be6214812" - integrity sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.7.4.tgz#6048c129ea908a432a1ff85f1dc794dc62ddaa5e" + integrity sha512-JH3v5ZOeKT0qqdJ9BeBcZTFQiJOMax8RopSr1bH6ASkZKo2qWsvBML7W1mp89sszBRDBBRO8snqcByGdrMTdMg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-dynamic-import@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" + integrity sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz#edd83b7adc2e0d059e2467ca96c650ab6d2f3820" - integrity sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw== +"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.7.4.tgz#897f05808298060b52873fa804ff853540790ea1" + integrity sha512-j888jpjATLEzOWhKawq46UrpXnCRDbdhBd5io4jgwjJ3+CHHGCRb6PNAVEgs+BXIb+dNRAmnkv36zfB992PRVw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.2.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.0.tgz#5c9465bcd26354d5215294ea90ab1c706a571386" - integrity sha512-vQMV07p+L+jZeUnvX3pEJ9EiXGCjB5CTTvsirFD9rpEuATnoAvLBLoYbw1v5tyn3d2XxSuvEKi8cV3KqYUa0vQ== +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.2.0", "@babel/plugin-syntax-flow@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.4.tgz#6d91b59e1a0e4c17f36af2e10dd64ef220919d7b" + integrity sha512-2AMAWl5PsmM5KPkB22cvOkUyWk6MjUaqhHNU5nSPUl/ns3j5qLfw2SuYP5RbVZ0tfLvePr4zUScbICtDP2CUNw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" - integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.7.4.tgz#dab2b56a36fb6c3c222a1fbc71f7bf97f327a9ec" + integrity sha512-wuy6fiMe9y7HeZBWXYCGt2RGxZOj0BImZ9EyXJVnVGBKO/Br592rbR3rtIQn0eQhAk9vqaKP5n8tVqEFBQMfLg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz#f75083dfd5ade73e783db729bbd87e7b9efb7624" - integrity sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg== +"@babel/plugin-syntax-nullish-coalescing-operator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.7.4.tgz#e53b751d0c3061b1ba3089242524b65a7a9da12b" + integrity sha512-XKh/yIRPiQTOeBg0QJjEus5qiSKucKAiApNtO1psqG7D17xmE+X2i5ZqBEuSvo0HRuyPaKaSN/Gy+Ha9KFQolw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" - integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" + integrity sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== +"@babel/plugin-syntax-optional-catch-binding@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" + integrity sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-chaining@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz#a59d6ae8c167e7608eaa443fda9fa8fa6bf21dff" - integrity sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA== +"@babel/plugin-syntax-optional-chaining@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.7.4.tgz#c91fdde6de85d2eb8906daea7b21944c3610c901" + integrity sha512-2MqYD5WjZSbJdUagnJvIdSfkb/ucOC9/1fRJxm7GAxY6YQLWlUvkfxoNbUPcPLHJyetKUDQ4+yyuUyAoc0HriA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-typescript@^7.2.0": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz#a7cc3f66119a9f7ebe2de5383cce193473d65991" - integrity sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag== +"@babel/plugin-syntax-typescript@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.7.4.tgz#5d037ffa10f3b25a16f32570ebbe7a8c2efa304b" + integrity sha512-77blgY18Hud4NM1ggTA8xVT/dBENQf17OpiToSa2jSmEY3fWXD2jwrdVlO4kq5yzUTeF15WSQ6b4fByNvJcjpQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" + integrity sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz#e2b84f11952cf5913fe3438b7d2585042772f492" - integrity sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz#694cbeae6d613a34ef0292713fa42fb45c4470ba" + integrity sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg== dependencies: - "@babel/helper-module-imports" "^7.7.0" + "@babel/helper-module-imports" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.0" + "@babel/helper-remap-async-to-generator" "^7.7.4" "@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz#d0d9d5c269c78eaea76227ace214b8d01e4d837b" + integrity sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz#6e854e51fbbaa84351b15d4ddafe342f3a5d542a" - integrity sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz#200aad0dcd6bb80372f94d9e628ea062c58bf224" + integrity sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" "@babel/plugin-transform-classes@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz#b411ecc1b8822d24b81e5d184f24149136eddd4a" - integrity sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.0" - "@babel/helper-define-map" "^7.7.0" - "@babel/helper-function-name" "^7.7.0" - "@babel/helper-optimise-call-expression" "^7.7.0" + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz#c92c14be0a1399e15df72667067a8f510c9400ec" + integrity sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-define-map" "^7.7.4" + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-optimise-call-expression" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.0" - "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/helper-replace-supers" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz#e856c1628d3238ffe12d668eb42559f79a81910d" + integrity sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-destructuring@^7.0.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6" - integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz#2b713729e5054a1135097b6a67da1b6fe8789267" + integrity sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz#dd30c0191e3a1ba19bcc7e389bdfddc0729d5db9" + integrity sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz#8110f153e7360cfd5996eee68706cfad92d85256" - integrity sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.7.4.tgz#cc73f85944782df1d77d80977bc097920a8bf31a" + integrity sha512-w9dRNlHY5ElNimyMYy0oQowvQpwt/PRHI0QS98ZJCTZU2bvSnKXo5zEiD5u76FBPigTm8TkqzmnUTg16T7qbkA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" + "@babel/plugin-syntax-flow" "^7.7.4" "@babel/plugin-transform-for-of@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz#248800e3a5e507b1f103d8b4ca998e77c63932bc" + integrity sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-function-name@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz#0fa786f1eef52e3b7d4fc02e54b2129de8a04c2a" - integrity sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz#75a6d3303d50db638ff8b5385d12451c865025b1" + integrity sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g== dependencies: - "@babel/helper-function-name" "^7.7.0" + "@babel/helper-function-name" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-literals@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz#27fe87d2b5017a2a5a34d1c41a6b9f6a6262643e" + integrity sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-member-expression-literals@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz#aee127f2f3339fc34ce5e3055d7ffbf7aa26f19a" + integrity sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz#3e5ffb4fd8c947feede69cbe24c9554ab4113fe3" - integrity sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz#bee4386e550446343dd52a571eda47851ff857a3" + integrity sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA== dependencies: - "@babel/helper-module-transforms" "^7.7.0" + "@babel/helper-module-transforms" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.7.0" + "@babel/helper-simple-access" "^7.7.4" babel-plugin-dynamic-import-node "^2.3.0" "@babel/plugin-transform-object-assign@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz#6fdeea42be17040f119e38e23ea0f49f31968bde" - integrity sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.7.4.tgz#a31b70c434a00a078b2d4d10dbd59992fa70afca" + integrity sha512-0TpeUlnhQDwKxPLTIckdaWt46L2s61c/5w5snw1OUod5ehOJywZD98Ha3dFHVjeqkfOFtOTH7cqxddjxUuvcmg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-object-super@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz#48488937a2d586c0148451bf51af9d7dda567262" + integrity sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-replace-supers" "^7.7.4" "@babel/plugin-transform-parameters@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz#da4555c97f39b51ac089d31c7380f03bca4075ce" + integrity sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw== dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-call-delegate" "^7.7.4" + "@babel/helper-get-function-arity" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-property-literals@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz#2388d6505ef89b266103f450f9167e6bd73f98c2" + integrity sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-react-display-name@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" - integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.7.4.tgz#9f2b80b14ebc97eef4a9b29b612c58ed9c0d10dd" + integrity sha512-sBbIvqYkthai0X0vkD2xsAwluBp+LtNHH+/V4a5ydifmTtb8KOVOlrMIk/MYmIc4uTYDnjZUHQildYNo36SRJw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz#583b10c49cf057e237085bcbd8cc960bd83bd96b" - integrity sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.7.4.tgz#8994b1bf6014b133f5a46d3b7d1ee5f5e3e72c10" + integrity sha512-5ZU9FnPhqtHsOXxutRtXZAzoEJwDaP32QcobbMP1/qt7NYcsCNK8XgzJcJfoEr/ZnzVvUNInNjIW22Z6I8p9mg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/plugin-syntax-jsx" "^7.7.4" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.0.tgz#834b0723ba78cd4d24d7d629300c2270f516d0b7" - integrity sha512-mXhBtyVB1Ujfy+0L6934jeJcSXj/VCg6whZzEcgiiZHNS0PGC7vUCsZDQCxxztkpIdF+dY1fUMcjAgEOC3ZOMQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz#d91205717fae4e2f84d020cd3057ec02a10f11da" + integrity sha512-LixU4BS95ZTEAZdPaIuyg/k8FiiqN9laQ0dMHB4MlpydHY53uQdWCUrwjLr5o6ilS6fAgZey4Q14XBjl5tL6xw== dependencies: - "@babel/helper-builder-react-jsx" "^7.7.0" + "@babel/helper-builder-react-jsx" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/plugin-syntax-jsx" "^7.7.4" "@babel/plugin-transform-regenerator@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz#f1b20b535e7716b622c99e989259d7dd942dd9cc" - integrity sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz#d18eac0312a70152d7d914cbed2dc3999601cfc0" + integrity sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw== dependencies: regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz#2669f67c1fae0ae8d8bf696e4263ad52cb98b6f8" - integrity sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.4.tgz#51fe458c1c1fa98a8b07934f4ed38b6cd62177a6" + integrity sha512-O8kSkS5fP74Ad/8pfsCMGa8sBRdLxYoSReaARRNSz3FbFQj3z/QUvoUmJ28gn9BO93YfnXc3j+Xyaqe8cKDNBQ== dependencies: - "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-module-imports" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" resolve "^1.8.1" semver "^5.5.1" "@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" + integrity sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-spread@^7.0.0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd" - integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz#aa673b356fe6b7e70d69b6e33a17fef641008578" + integrity sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz#ffb68c05090c30732076b1285dc1401b404a123c" + integrity sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" "@babel/plugin-transform-template-literals@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz#1eb6411736dd3fe87dbd20cc6668e5121c17d604" + integrity sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-annotate-as-pure" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.2.tgz#eb9f14c516b5d36f4d6f3a9d7badae6d0fc313d4" - integrity sha512-UWhDaJRqdPUtdK1s0sKYdoRuqK0NepjZto2UZltvuCgMoMZmdjhgz5hcRokie/3aYEaSz3xvusyoayVaq4PjRg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.4.tgz#2974fd05f4e85c695acaf497f432342de9fc0636" + integrity sha512-X8e3tcPEKnwwPVG+vP/vSqEShkwODOEeyQGod82qrIuidwIrfnsGn11qPM1jBLF4MqguTXXYzm58d0dY+/wdpg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.0" + "@babel/helper-create-class-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript" "^7.2.0" + "@babel/plugin-syntax-typescript" "^7.7.4" "@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz#743d9bcc44080e3cc7d49259a066efa30f9187a3" - integrity sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz#a3c0f65b117c4c81c5b6484f2a5e7b95346b83ae" + integrity sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.0" + "@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" "@babel/register@^7.0.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.0.tgz#4e23ecf840296ef79c605baaa5c89e1a2426314b" - integrity sha512-HV3GJzTvSoyOMWGYn2TAh6uL6g+gqKTgEZ99Q3+X9UURT1VPT/WcU46R61XftIc5rXytcOHZ4Z0doDlsjPomIg== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.4.tgz#45a4956471a9df3b012b747f5781cc084ee8f128" + integrity sha512-/fmONZqL6ZMl9KJUYajetCrID6m0xmL4odX7v+Xvoxcv0DdbP/oO0TWIeLUCHqczQ6L6njDMqmqHFy2cp3FFsA== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.13" @@ -615,40 +615,40 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" - integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.4.tgz#b23a856751e4bf099262f867767889c0e3fe175b" + integrity sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw== dependencies: regenerator-runtime "^0.13.2" -"@babel/template@^7.0.0", "@babel/template@^7.4.0", "@babel/template@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.0.tgz#4fadc1b8e734d97f56de39c77de76f2562e597d0" - integrity sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ== +"@babel/template@^7.0.0", "@babel/template@^7.4.0", "@babel/template@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" + integrity sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.0" - "@babel/types" "^7.7.0" + "@babel/parser" "^7.7.4" + "@babel/types" "^7.7.4" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.2.tgz#ef0a65e07a2f3c550967366b3d9b62a2dcbeae09" - integrity sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" + integrity sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.2" - "@babel/helper-function-name" "^7.7.0" - "@babel/helper-split-export-declaration" "^7.7.0" - "@babel/parser" "^7.7.2" - "@babel/types" "^7.7.2" + "@babel/generator" "^7.7.4" + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/parser" "^7.7.4" + "@babel/types" "^7.7.4" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7" - integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" + integrity sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA== dependencies: esutils "^2.0.2" lodash "^4.17.13" @@ -1407,9 +1407,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.11.tgz#bec2961975888d964196bf0016a2f984d793d3ce" - integrity sha512-O+x6uIpa6oMNTkPuHDa9MhMMehlxLAd5QcOvKRjAFsBVpeFWTOPnXbDvILvFgFFZfQ1xh1EZi1FbXxUix+zpsQ== + version "12.12.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.12.tgz#529bc3e73dbb35dd9e90b0a1c83606a9d3264bdb" + integrity sha512-MGuvYJrPU0HUwqF7LqvIj50RZUX23Z+m583KBygKYUZLlZ88n6w28XRNJRJgsHukLEnLz6w6SvxZoLgbr5wLqQ== "@types/node@^10.3.2": version "10.17.5" @@ -1678,6 +1678,11 @@ animated@^0.2.2: invariant "^2.2.0" normalize-css-color "^1.0.1" +anser@^1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" + integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== + ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" @@ -3695,9 +3700,9 @@ ejs@^2.7.2: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== electron-to-chromium@^1.3.306: - version "1.3.310" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.310.tgz#a6c0c194d93ff54fcdc6dc3843689abb5c4dec0c" - integrity sha512-ixvxy46JrDv5c8k1+th66Z+xDZD8zShNs6oh7hgyMpNZUgaoRBisXgFZKAyyhQTAj7oU2Y/uZ0AAsj/TY4N0tA== + version "1.3.311" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.311.tgz#73baa361e2b1f44b7b4f1a443aaa1372f8074ebb" + integrity sha512-7GH6RKCzziLzJ9ejmbiBEdzHZsc6C3eRpav14dmRfTWMpNgMqpP1ukw/FU/Le2fR+ep642naq7a23xNdmh2s+A== elliptic@6.3.3: version "6.3.3" @@ -3710,9 +3715,9 @@ elliptic@6.3.3: inherits "^2.0.1" elliptic@^6.0.0: - version "6.5.1" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b" - integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg== + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -4086,9 +4091,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04" - integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g== + version "6.7.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.0.tgz#766162e383b236e61d873697f82c3a3e41392020" + integrity sha512-dQpj+PaHKHfXHQ2Imcw5d853PTvkUGbHk/MR68KQUl98EgKDCdh4vLRH1ZxhqeQjQFJeg8fgN0UwmNhN3l8dDQ== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4105,7 +4110,7 @@ eslint@^6.6.0: file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" - globals "^11.7.0" + globals "^12.1.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -4118,7 +4123,7 @@ eslint@^6.6.0: minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.2" + optionator "^0.8.3" progress "^2.0.0" regexpp "^2.0.1" semver "^6.1.2" @@ -4779,11 +4784,6 @@ funpermaproxy@^1.0.1: resolved "https://registry.yarnpkg.com/funpermaproxy/-/funpermaproxy-1.0.1.tgz#4650e69b7c334d9717c06beba9b339cc08ac3335" integrity sha512-9pEzs5vnNtR7ZGihly98w/mQ7blsvl68Wj30ZCDAXy7qDN4CWLLjdfjtH/P2m6whsnaJkw15hysCNHMXue+wdA== -fuzzysearch@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fuzzysearch/-/fuzzysearch-1.0.3.tgz#dffc80f6d6b04223f2226aa79dd194231096d008" - integrity sha1-3/yA9tawQiPyImqnndGUIxCW0Ag= - fwd-stream@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/fwd-stream/-/fwd-stream-1.0.4.tgz#ed281cabed46feecf921ee32dc4c50b372ac7cfa" @@ -4972,11 +4972,18 @@ global@^4.3.0, global@^4.3.2: min-document "^2.19.0" process "^0.11.10" -globals@^11.1.0, globals@^11.7.0: +globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^12.1.0: + version "12.3.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.3.0.tgz#1e564ee5c4dded2ab098b0f88f24702a3c56be13" + integrity sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw== + dependencies: + type-fest "^0.8.1" + globby@^9.2.0: version "9.2.0" resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" @@ -8234,7 +8241,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.1, optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -8585,9 +8592,9 @@ path-key@^2.0.0, path-key@^2.0.1: integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-key@^3.0.0, path-key@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.0.tgz#99a10d870a803bdd5ee6f0470e58dfcd2f9a54d3" - integrity sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.5: version "1.0.6" @@ -9360,10 +9367,9 @@ react-native-randombytes@^3.5.3: buffer "^4.9.1" sjcl "^1.0.3" -react-native-reanimated@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.3.0.tgz#581cdb0bd1ff05e7304b116af712ded0c7665ede" - integrity sha512-KFno6D0q09kx71IDuPa4qeC1t1msALsCMuli3/EN3YDf8XoM2CG53yzhVHMFtmcW0IUCySugHgxQiuT5BzwOPA== +react-native-reanimated@software-mansion/react-native-reanimated: + version "1.4.0" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/c70c1211d9e9f95959fffc832b030f6d249819b4" react-native-redash@8.2.2: version "8.2.2" @@ -9474,18 +9480,19 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/390d0895ba1dd059ed65d8292c566bd2e46a9eba" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/ac3c167ead8609410660da48b594fedc35b68489" dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" + "@react-native-community/cli" "^3.0.0" + "@react-native-community/cli-platform-android" "^3.0.0" + "@react-native-community/cli-platform-ios" "^3.0.0" abort-controller "^3.0.0" + anser "^1.4.9" base64-js "^1.1.2" connect "^3.6.5" create-react-class "^15.6.3" escape-string-regexp "^1.0.5" - eslint-plugin-relay "1.3.12" + eslint-plugin-relay "1.4.1" event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" @@ -9502,7 +9509,7 @@ react-native@facebook/react-native: react-devtools-core "^4.0.6" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.16.2" + scheduler "0.17.0" stacktrace-parser "^0.1.3" use-subscription "^1.0.0" whatwg-fetch "^3.0.0" @@ -11722,11 +11729,6 @@ url@^0.10.3: punycode "1.3.2" querystring "0.2.0" -use-debounce@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-3.1.0.tgz#05a5c8cd3c2f309699f08961d7c8bbe7f68720bb" - integrity sha512-DEf3L/ZKkOSTARk/DHlC6KAAJKwMqpck8Zx06SM2Wr+LfU1TzhO8hZRzB/qbpSQqREYWQes24n1q9doeTMqF4g== - use-memo-one@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.1.tgz#39e6f08fe27e422a7d7b234b5f9056af313bd22c" From 30e2cc5d9214499ff62a6c5db124a9c301d2d414 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Sat, 23 Nov 2019 04:21:08 -0500 Subject: [PATCH 543/636] Fixes Unlock button shadow cut off on bottom Fixes RAI-75 https://linear.app/issue/RAI-75 --- ios/Podfile.lock | 44 +++++++++---------- src/components/exchange/ExchangeInputField.js | 9 +++- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 29eec764ab9..c9e6881d561 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -636,8 +636,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: bb9fc4ac8ad481abfc658262730aa0cd29105793 - FBReactNativeSpec: 1cb863b5abf34acc6c0514c3ed1dc3f1cbef6ffa + FBLazyVector: 59b799add22f437873e4ac6ef8cf1f9dc00c1644 + FBReactNativeSpec: 2561c346427810549ab5347b476cba6d99f05aaa Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -653,15 +653,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 5c7236bbf0a85ac66b8cbfa983cac889547f1778 - RCTTypeSafety: b8adcc133dd28a5052f1c9100576a387d3f6e00f - React: d5a2094454524f5bb265c7bd0cfd373321603029 - React-Core: b88cae7ba8e7a3c6af4a76bc1fc18a0f6378c650 - React-CoreModules: d9a69d1c19196c255dcf595d71dda321c7eb0982 - React-cxxreact: 19fc38ac723387831e39e203edb291e1457379df - React-jsi: 0bedf89b92da6e7ecbbeaa9c1a241c86affaa5bd - React-jsiexecutor: e51443e84d5198caa26c53e6bdda964f58dc8518 - React-jsinspector: 0f9270878bbaa1fedf2e573cd43e48792d1619dd + RCTRequired: 50c304666e9012acb6c9809a61a7c3c615abe65f + RCTTypeSafety: 5ac012965e3f7a745d896c57452c341cfb3b33ff + React: 96873e225a870636257547d6c40a0c1c50397052 + React-Core: 90c991c695db7ad09c903011287df52de07a5578 + React-CoreModules: f509f23c91d1d1a19c38a58a98c91cb2092285ad + React-cxxreact: c6198d59a214fefcac17e6e82a66d62fbebff4e3 + React-jsi: 1826ee9c2b26dba98337629ada547dee318abf68 + React-jsiexecutor: 1167640ba4658c7cc77cbf3ec968020aeeccff7b + React-jsinspector: 26a53d756cf60137d7f4eaee8a99c1e043526194 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -672,16 +672,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 5251c300b9b9d7e5c7b38d1c3c130258a3cb9e24 - React-RCTAnimation: 11d6d0f698e183715109cbd800886087e1270faa - React-RCTBlob: f487ada7b57e46a92ca7239edf5370fdb70c3a40 - React-RCTImage: 6b1d315125038c086698eb0dfec8a78c034154d9 - React-RCTLinking: 0055f1c44f3544f908e34990467f83d25f8ad01f - React-RCTNetwork: 6da013dbe1444f8d3170be943d5b23abf43719f1 - React-RCTSettings: 884513d991b95e67c88171432997b13770b551ac - React-RCTText: 96c70d59c4fdfa5534ff594e509ef455658fb290 - React-RCTVibration: 88bf669028a221a5fb2467ecf95e43ce8f131213 - ReactCommon: 5aeb787b348070838dc868f8b48ddc7bea800679 + React-RCTActionSheet: 4cf9f1b716ff1a8b4081bb415e0b237a94d64e60 + React-RCTAnimation: 43b606950fd04d44bfb7caf3a96ae2aa4c62379e + React-RCTBlob: 5a81e0f5fcd1cdfffacf5c3bd71214437052f115 + React-RCTImage: bca61144ffac4f20423149ec0ed8674902bb08af + React-RCTLinking: e8bddd2993113a561b723d797f2b266d99655a4e + React-RCTNetwork: 1300b2a7e6ab359bb5ae4324b09285f9e32ce6b4 + React-RCTSettings: 3c5754c531ccf2aec6c34218eb2d1f8d7eaa0ecd + React-RCTText: 07cb60332845e0935a7cdf06bf425f225f6fe6ef + React-RCTVibration: eeda0047ef97e876f422495473257849a49725db + ReactCommon: 574f41c8c99208bb1903b3b048eca848b66d5b62 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -706,7 +706,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 43ec3b62f85953e3df241983a36c5b2f1458b3f8 + Yoga: faa53cd47c609ef1321b84b45d4f8244ad196a08 PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 diff --git a/src/components/exchange/ExchangeInputField.js b/src/components/exchange/ExchangeInputField.js index 7ad2a19ded7..edd2b8c8772 100644 --- a/src/components/exchange/ExchangeInputField.js +++ b/src/components/exchange/ExchangeInputField.js @@ -80,7 +80,14 @@ export default class ExchangeInputField extends Component { const skeletonColor = colors.alpha(colors.blueGreyDark, 0.1); return ( - + Date: Sat, 23 Nov 2019 04:25:53 -0500 Subject: [PATCH 544/636] Center the "unlocking" text to spinner in swap confirm button Fixes RAI-81 https://linear.app/issue/RAI-81 --- src/components/buttons/hold-to-authorize/UnlockingSpinner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/buttons/hold-to-authorize/UnlockingSpinner.js b/src/components/buttons/hold-to-authorize/UnlockingSpinner.js index 3d2d91458b6..6186ca1e8e3 100644 --- a/src/components/buttons/hold-to-authorize/UnlockingSpinner.js +++ b/src/components/buttons/hold-to-authorize/UnlockingSpinner.js @@ -26,7 +26,7 @@ const UnlockingSpinner = ({ interval, timeRemaining }) => { return ( - + Unlocking From c11e6b4a93d60893cc5662d5f135171d75434e28 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 25 Nov 2019 16:41:58 +0100 Subject: [PATCH 545/636] add padding to the transaction container to keep buttons away from very bottom of the screen --- src/components/send/SendAssetForm.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/send/SendAssetForm.js b/src/components/send/SendAssetForm.js index 3ef3981be69..516d599b9c6 100644 --- a/src/components/send/SendAssetForm.js +++ b/src/components/send/SendAssetForm.js @@ -65,7 +65,10 @@ const SendAssetForm = ({ selected: true, })} - + {selected.isNft ? ( ) : ( From 690409bb4d22d8103d14a2ddfb83fa1a3920de5d Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Mon, 25 Nov 2019 19:09:10 +0100 Subject: [PATCH 546/636] save keyboard height to local storage --- .../layout/KeyboardFixedOpenLayout.js | 17 ++++++++++------- src/handlers/localstorage/globalSettings.js | 5 +++++ src/screens/WalletScreen.js | 8 ++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index 392eefc8634..4b2e0b9c386 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -7,6 +7,7 @@ import { withKeyboardHeight } from '../../hoc'; import { padding, position } from '../../styles'; import { deviceUtils, safeAreaInsetValues } from '../../utils'; import Centered from './Centered'; +import { setKeyboardHeight } from '../../handlers/localstorage/globalSettings'; const FallbackKeyboardHeight = Math.floor( deviceUtils.dimensions.height * 0.333 @@ -32,12 +33,10 @@ class KeyboardFixedOpenLayout extends PureComponent { }; componentDidMount = () => { - if (!this.props.keyboardHeight) { - this.willShowListener = Keyboard.addListener( - 'keyboardWillShow', - this.keyboardWillShow - ); - } + this.willShowListener = Keyboard.addListener( + 'keyboardWillShow', + this.keyboardWillShow + ); }; componentWillUnmount = () => this.clearKeyboardListeners(); @@ -53,7 +52,11 @@ class KeyboardFixedOpenLayout extends PureComponent { }; keyboardWillShow = async ({ endCoordinates: { height } }) => { - this.props.setKeyboardHeight(Math.floor(height)); + if (height !== this.props.keyboardHeight) { + const keyboardHeight = Math.floor(height); + setKeyboardHeight(keyboardHeight); + this.props.setKeyboardHeight(keyboardHeight); + } this.clearKeyboardListeners(); }; diff --git a/src/handlers/localstorage/globalSettings.js b/src/handlers/localstorage/globalSettings.js index 3b28a358456..c9ba82441ad 100644 --- a/src/handlers/localstorage/globalSettings.js +++ b/src/handlers/localstorage/globalSettings.js @@ -1,6 +1,7 @@ import { getGlobal, saveGlobal } from './common'; const APPSTORE_REVIEW_COUNT = 'appStoreReviewRequestCount'; +const KEYBOARD_HEIGHT = 'keyboardHeight'; const LANGUAGE = 'language'; const NATIVE_CURRENCY = 'nativeCurrency'; @@ -13,6 +14,10 @@ export const getLanguage = () => getGlobal(LANGUAGE, 'en'); export const saveLanguage = language => saveGlobal(LANGUAGE, language); +export const getKeyboardHeight = () => getGlobal(KEYBOARD_HEIGHT, null); + +export const setKeyboardHeight = height => saveGlobal(KEYBOARD_HEIGHT, height); + export const getNativeCurrency = () => getGlobal(NATIVE_CURRENCY, 'USD'); export const saveNativeCurrency = nativeCurrency => diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index c1570e84065..4b890745b8f 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -22,9 +22,11 @@ import { withStatusBarStyle, withUniqueTokens, withUniswapLiquidityTokenInfo, + withKeyboardHeight, } from '../hoc'; import { position } from '../styles'; import { isNewValueForObjectPaths } from '../utils'; +import { getKeyboardHeight } from '../handlers/localstorage/globalSettings'; class WalletScreen extends Component { static propTypes = { @@ -41,6 +43,7 @@ class WalletScreen extends Component { refreshAccountData: PropTypes.func, scrollViewTracker: PropTypes.object, sections: PropTypes.array, + setKeyboardHeight: PropTypes.func, setSafeTimeout: PropTypes.func, uniqueTokens: PropTypes.array, }; @@ -48,6 +51,10 @@ class WalletScreen extends Component { componentDidMount = async () => { try { await this.props.initializeWallet(); + const keyboardheight = await getKeyboardHeight(); + if (keyboardheight) { + this.props.setKeyboardHeight(keyboardheight); + } } catch (error) { // TODO error state } @@ -114,6 +121,7 @@ export default compose( withNavigationFocus, withIsWalletEmpty, withIsWalletEthZero, + withKeyboardHeight, withStatusBarStyle('dark-content'), withProps(buildWalletSectionsSelector), withProps({ scrollViewTracker: new Animated.Value(0) }) From 999e8fc4f22456bca9b146c2a8811956e0f5ca4c Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 25 Nov 2019 22:25:37 -0500 Subject: [PATCH 547/636] Fix: populate output native price from Uniswap if not from Zerion --- src/screens/ExchangeModal.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index ac5918dae07..85037e334cf 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -497,11 +497,14 @@ class ExchangeModal extends Component { updatedOutputAmount, outputDecimals ); - if (rawUpdatedOutputAmount !== '0') { + let outputNativePrice = get(outputCurrency, 'price.value', null); + if (isNil(outputNativePrice)) { + outputNativePrice = this.getMarketPrice(); + } const updatedOutputAmountDisplay = updatePrecisionToDisplay( rawUpdatedOutputAmount, - get(outputCurrency, 'price.value') + outputNativePrice ); this.setOutputAmount( From 86a4a86b35922d034f4e429ea5dc43e4d08b7dac Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 25 Nov 2019 23:38:47 -0500 Subject: [PATCH 548/636] Fix formatting of converted input value given asset decimals --- src/helpers/__tests__/utilities.test.js | 11 +++++++++++ src/helpers/utilities.js | 10 ++++++---- src/redux/send.js | 6 +++++- src/screens/ExchangeModal.js | 6 +++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/helpers/__tests__/utilities.test.js b/src/helpers/__tests__/utilities.test.js index a537bb289bd..65580ae3e37 100644 --- a/src/helpers/__tests__/utilities.test.js +++ b/src/helpers/__tests__/utilities.test.js @@ -1,9 +1,20 @@ import { + convertAmountFromNativeValue, convertBipsToPercentage, handleSignificantDecimals, updatePrecisionToDisplay, } from '../utilities'; +it('convertAmountFromNativeValue', () => { + const result = convertAmountFromNativeValue('1', '40.00505', 5); + expect(result).toBe('0.02499'); +}); + +it('convertAmountFromNativeValue with trailing zeros', () => { + const result = convertAmountFromNativeValue('1', '1', 5); + expect(result).toBe('1'); +}); + it('handleSignificantDecimals greater than 1, decimals 2', () => { const result = handleSignificantDecimals('5.123', 2); expect(result).toBe('5.12'); diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index a18c73764b1..7c257e8a731 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -193,10 +193,12 @@ export const divide = (numberOne, numberTwo) => * @param {Number} priceUnit * @return {String} */ -export const convertAmountFromNativeValue = (value, priceUnit) => - BigNumber(value) - .dividedBy(BigNumber(priceUnit)) - .toFixed(); +export const convertAmountFromNativeValue = (value, priceUnit, decimals = 18) => + BigNumber( + BigNumber(value) + .dividedBy(BigNumber(priceUnit)) + .toFixed(decimals, BigNumber.ROUND_DOWN) + ).toFixed(); /** * @desc convert from string to number diff --git a/src/redux/send.js b/src/redux/send.js index 589f28b9cc8..6e534552e83 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -156,7 +156,11 @@ export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { let _assetAmount = ''; if (_nativeAmount.length) { const priceUnit = get(selected, 'price.value', 0); - const assetAmount = convertAmountFromNativeValue(_nativeAmount, priceUnit); + const assetAmount = convertAmountFromNativeValue( + _nativeAmount, + priceUnit, + selected.decimals + ); _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); } diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 85037e334cf..7ab49aba792 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -755,7 +755,11 @@ class ExchangeModal extends Component { if (isNil(nativePrice)) { nativePrice = this.getMarketPrice(); } - inputAmount = convertAmountFromNativeValue(nativeAmount, nativePrice); + inputAmount = convertAmountFromNativeValue( + nativeAmount, + nativePrice, + inputCurrency.decimals + ); inputAmountDisplay = updatePrecisionToDisplay( inputAmount, nativePrice, From 7e65e7261bb3731de38a07be94fccf830eff439f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Tue, 26 Nov 2019 03:03:55 -0500 Subject: [PATCH 549/636] Downgrade react-navigation-tabs --- package.json | 1 + src/screens/Routes.js | 2 +- yarn.lock | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 035db66f648..2803d15cc52 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,7 @@ "react-navigation": "4.0.10", "react-navigation-stack": "2.0.0-alpha.37", "react-navigation-tabs": "2.5.6", + "react-navigation-tabs-v1": "1.2.0", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", "react-spring": "^5.7.2", diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 71ad0bdea0e..87044defa0f 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -2,7 +2,7 @@ import analytics from '@segment/analytics-react-native'; import { get, omit } from 'lodash'; import React from 'react'; import { createAppContainer } from 'react-navigation'; -import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; +import { createMaterialTopTabNavigator } from 'react-navigation-tabs-v1'; import { createStackNavigator } from 'react-navigation-stack'; import { ExchangeModalNavigator, Navigation } from '../navigation'; import { updateTransitionProps } from '../redux/navigation'; diff --git a/yarn.lock b/yarn.lock index 099b5dba86b..1bb4bdedd6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9432,6 +9432,13 @@ react-native-svg@9.13.3: css-select "^2.0.2" css-tree "^1.0.0-alpha.37" +react-native-tab-view@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-1.4.1.tgz#f113cd87485808f0c991abec937f70fa380478b9" + integrity sha512-Bke8KkDcDhvB/z0AS7MnQKMD2p6Kwfc1rSKlMOvg9CC5CnClQ2QEnhPSbwegKDYhUkBI92iH/BYy7hNSm5kbUQ== + dependencies: + prop-types "^15.6.1" + react-native-tab-view@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.11.0.tgz#2e57d1f617ccc88c7f452708804f3409f880b700" @@ -9519,6 +9526,15 @@ react-navigation-stack@2.0.0-alpha.37: resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.37.tgz#15c38f7ef9923a2b6739c2bc8441f8ab70af3ec3" integrity sha512-2AcidUvhNgErV2QlV3s7wSdkbAJ+sQEAsHrHF4xK8PTf04I9+qG3/Ds9Orx31njhujHfuB5nN/77z+ih1iM+7g== +react-navigation-tabs-v1@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-navigation-tabs-v1/-/react-navigation-tabs-v1-1.2.0.tgz#7cdfdfee62689cc0835d87da574c81486b4ad6ee" + integrity sha512-vpd/WLmh5OZr1Bl2CONk5b4/pSNKeQCMcnlqFcOPFRsnkewLXlcyqax8G6wMSp3CRES1+X7DZxe133ybLgwdiA== + dependencies: + hoist-non-react-statics "^2.5.0" + prop-types "^15.6.1" + react-native-tab-view "^1.4.1" + react-navigation-tabs@2.5.6: version "2.5.6" resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.6.tgz#51f1a39b6c9525e6b5fe035945c243c04e53242b" From b08d988636a10a814c2cf875d432c87f06670ace Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Tue, 26 Nov 2019 03:20:20 -0500 Subject: [PATCH 550/636] Remove dead code --- src/screens/Routes.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 87044defa0f..482d682c24a 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -52,17 +52,6 @@ const SwipeStack = createMaterialTopTabNavigator( headerMode: 'none', initialLayout: deviceUtils.dimensions, initialRouteName: 'WalletScreen', - mode: 'modal', - springConfig: { - damping: 16, - mass: 0.3, - overshootClamping: false, - restDisplacementThreshold: 1, - restSpeedThreshold: 1, - stiffness: 140, - }, - swipeDistanceThreshold: 30, - swipeVelocityThreshold: 10, tabBarComponent: null, } ); From 6463fbae2cc391de8d47f1fd245076c1ad2decbf Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 26 Nov 2019 16:03:59 +0100 Subject: [PATCH 551/636] remove additional padding and change nftPaddingBottom offset --- src/components/send/SendAssetForm.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/send/SendAssetForm.js b/src/components/send/SendAssetForm.js index 516d599b9c6..f994f7acb5f 100644 --- a/src/components/send/SendAssetForm.js +++ b/src/components/send/SendAssetForm.js @@ -20,7 +20,7 @@ const Container = styled(Column)` overflow: hidden; `; -const nftPaddingBottom = safeAreaInsetValues.bottom + 19; +const nftPaddingBottom = safeAreaInsetValues.bottom + 39; const tokenPaddingBottom = sheetVerticalOffset + 19; const TransactionContainer = styled(Column).attrs({ @@ -65,10 +65,7 @@ const SendAssetForm = ({ selected: true, })} - + {selected.isNft ? ( ) : ( From e0da42bb0a7bed05ed3263bcb145563acade467a Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 27 Nov 2019 14:04:13 +0100 Subject: [PATCH 552/636] add keyboard heights function --- .../layout/KeyboardFixedOpenLayout.js | 5 ++-- src/helpers/keyboardHeight.js | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/helpers/keyboardHeight.js diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index 4b2e0b9c386..71688b4a878 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -8,9 +8,10 @@ import { padding, position } from '../../styles'; import { deviceUtils, safeAreaInsetValues } from '../../utils'; import Centered from './Centered'; import { setKeyboardHeight } from '../../handlers/localstorage/globalSettings'; +import { calculateKeyboardHeight } from '../../helpers/keyboardHeight'; -const FallbackKeyboardHeight = Math.floor( - deviceUtils.dimensions.height * 0.333 +const FallbackKeyboardHeight = calculateKeyboardHeight( + deviceUtils.dimensions.height ); const Container = styled.View` diff --git a/src/helpers/keyboardHeight.js b/src/helpers/keyboardHeight.js new file mode 100644 index 00000000000..eb636f6c6e6 --- /dev/null +++ b/src/helpers/keyboardHeight.js @@ -0,0 +1,25 @@ +import { deviceUtils } from '../utils'; + +export const calculateKeyboardHeight = screenHeight => { + let keyboardHeight = 0; + switch (screenHeight) { + case 568: + keyboardHeight = 216; + break; + case 667: + keyboardHeight = 216; + break; + case 736: + keyboardHeight = 226; + break; + case 812: + keyboardHeight = 291; + break; + case 896: + keyboardHeight = 301; + break; + default: + keyboardHeight = Math.floor(deviceUtils.dimensions.height * 0.333); + } + return keyboardHeight; +}; From ad43ccb82fe76272e1395631830599f784556810 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 27 Nov 2019 14:10:05 +0100 Subject: [PATCH 553/636] remove unnecessary import from keyboardHeight.js --- src/helpers/keyboardHeight.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/helpers/keyboardHeight.js b/src/helpers/keyboardHeight.js index eb636f6c6e6..a088322e5b0 100644 --- a/src/helpers/keyboardHeight.js +++ b/src/helpers/keyboardHeight.js @@ -1,5 +1,3 @@ -import { deviceUtils } from '../utils'; - export const calculateKeyboardHeight = screenHeight => { let keyboardHeight = 0; switch (screenHeight) { @@ -19,7 +17,7 @@ export const calculateKeyboardHeight = screenHeight => { keyboardHeight = 301; break; default: - keyboardHeight = Math.floor(deviceUtils.dimensions.height * 0.333); + keyboardHeight = Math.floor(screenHeight * 0.333); } return keyboardHeight; }; From c9c8ecb6fddc891cd80c07ea952023600b34b361 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 23 Nov 2019 12:47:46 -0500 Subject: [PATCH 554/636] Consolidate and remove SendComponentWithData --- src/components/SendComponentWithData.js | 297 ----------------------- src/components/fields/AddressField.js | 3 +- src/hoc/index.js | 1 + src/hoc/withDataInit.js | 3 +- src/hoc/withSend.js | 49 ++++ src/redux/gas.js | 4 +- src/redux/send.js | 25 +- src/screens/SendSheet.js | 189 +++------------ src/screens/SendSheetWithData.js | 310 +++++++++++++++++++++++- 9 files changed, 397 insertions(+), 484 deletions(-) delete mode 100644 src/components/SendComponentWithData.js create mode 100644 src/hoc/withSend.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js deleted file mode 100644 index b1e6e860db1..00000000000 --- a/src/components/SendComponentWithData.js +++ /dev/null @@ -1,297 +0,0 @@ -import { get } from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { compose } from 'recompact'; -import { estimateGasLimit } from '../handlers/web3'; -import { greaterThan } from '../helpers/utilities'; -import { checkIsValidAddress } from '../helpers/validators'; -import { withAccountData, withGas, withUniqueTokens } from '../hoc'; -import lang from '../languages'; -import { - sendClearFields, - sendMaxBalance, - sendModalInit, - sendToggleConfirmationView, - sendTransaction, - sendUpdateAssetAmount, - sendUpdateNativeAmount, - sendUpdateRecipient, - sendUpdateSelected, -} from '../redux/send'; -import { ethereumUtils } from '../utils'; - -const mapStateToProps = ({ send, settings }) => ({ - accountType: settings.accountType, - address: send.address, - assetAmount: send.assetAmount, - confirm: send.confirm, - fetching: send.fetching, - isSufficientBalance: send.isSufficientBalance, - nativeAmount: send.nativeAmount, - nativeCurrency: settings.nativeCurrency, - network: settings.network, - recipient: send.recipient, - selected: send.selected, - txHash: send.txHash, -}); - -/** - * Create SendComponent connected to redux with actions for sending assets. - * @param {Component} SendComponent React component for sending. - * @param {Object} options - * {Function} options.sendTransactionCallback Function to be run after sendTransaction redux action. - * {String} options.defaultAsset Symbol for default asset to send. - * @return {Component} SendComponent connected to redux. - */ -export const withSendComponentWithData = (SendComponent, options) => { - class SendComponentWithData extends Component { - static propTypes = { - accountType: PropTypes.string, - address: PropTypes.string, - assetAmount: PropTypes.string.isRequired, - assets: PropTypes.array.isRequired, - confirm: PropTypes.bool.isRequired, - fetching: PropTypes.bool.isRequired, - gasLimit: PropTypes.number, - gasPrices: PropTypes.object.isRequired, - gasUpdateDefaultGasLimit: PropTypes.func.isRequired, - gasUpdateTxFee: PropTypes.func.isRequired, - isSufficientBalance: PropTypes.bool.isRequired, - isSufficientGas: PropTypes.bool.isRequired, - nativeAmount: PropTypes.string.isRequired, - nativeCurrency: PropTypes.string.isRequired, - network: PropTypes.string.isRequired, - recipient: PropTypes.string.isRequired, - selected: PropTypes.object.isRequired, - selectedGasPrice: PropTypes.shape({ txFee: PropTypes.object }), - selectedGasPriceOption: PropTypes.string.isRequired, - sendClearFields: PropTypes.func.isRequired, - sendMaxBalance: PropTypes.func.isRequired, - sendModalInit: PropTypes.func.isRequired, - sendToggleConfirmationView: PropTypes.func.isRequired, - sendTransaction: PropTypes.func.isRequired, - sendUpdateAssetAmount: PropTypes.func.isRequired, - sendUpdateNativeAmount: PropTypes.func.isRequired, - sendUpdateRecipient: PropTypes.func.isRequired, - sendUpdateSelected: PropTypes.func.isRequired, - txFees: PropTypes.object.isRequired, - txHash: PropTypes.string.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isValidAddress: false, - showQRCodeReader: false, - }; - - this.defaultAsset = options.defaultAsset; - this.gasFormat = options.gasFormat || 'long'; - this.sendTransactionCallback = - options.sendTransactionCallback || function noop() {}; - } - - componentDidMount() { - this.props.sendModalInit({ - defaultAsset: this.defaultAsset, - gasFormat: this.gasFormat, - }); - this.props.gasUpdateDefaultGasLimit(); - } - - async componentDidUpdate(prevProps) { - const { address, assetAmount, recipient, selected } = this.props; - - if (recipient !== prevProps.recipient) { - const validAddress = await checkIsValidAddress(recipient); - // eslint-disable-next-line react/no-did-update-set-state - this.setState({ isValidAddress: validAddress }); - } - - if (this.state.isValidAddress) { - if ( - selected.symbol !== prevProps.selected.symbol || - recipient !== prevProps.recipient || - assetAmount !== prevProps.assetAmount - ) { - estimateGasLimit({ - address, - amount: assetAmount, - asset: selected, - recipient, - }) - .then(gasLimit => { - this.props.gasUpdateTxFee(gasLimit); - }) - .catch(() => { - this.props.gasUpdateTxFee(); - }); - } - } - } - - onAddressInputFocus = async () => { - const { recipient } = this.props; - - const validAddress = await checkIsValidAddress(recipient); - this.setState({ isValidAddress: validAddress }); - }; - - onAddressInputBlur = async () => { - const { recipient } = this.props; - - const validAddress = await checkIsValidAddress(recipient); - this.setState({ isValidAddress: validAddress }); - }; - - onGoBack = () => this.props.sendToggleConfirmationView(false); - - onSendMaxBalance = () => this.props.sendMaxBalance(); - - onSendAnother = () => { - this.props.sendToggleConfirmationView(false); - this.props.sendClearFields(); - this.props.sendModalInit({ defaultAsset: this.defaultAsset }); - }; - - onSubmit = async event => { - if (event && typeof event.preventDefault === 'function') { - event.preventDefault(); - } - - if (!this.props.selectedGasPrice.txFee) { - return; - } - - // Balance checks - if (!this.props.confirm) { - const isAddressValid = await checkIsValidAddress(this.props.recipient); - if (!isAddressValid) { - console.log(lang.t('notification.error.invalid_address')); - return; - } - if (this.props.selected.address === 'eth') { - const { - requestedAmount, - balance, - amountWithFees, - } = ethereumUtils.transactionData( - this.props.assets, - this.props.assetAmount, - this.props.selectedGasPrice - ); - - if (greaterThan(requestedAmount, balance)) { - return; - } - if (greaterThan(amountWithFees, balance)) { - return; - } - } else if (!this.props.selected.isNft) { - const { - requestedAmount, - balance, - txFee, - } = ethereumUtils.transactionData( - this.props.assets, - this.props.assetAmount, - this.props.selectedGasPrice - ); - - const tokenBalance = get(this.props, 'selected.balance.amount'); - - if (greaterThan(requestedAmount, tokenBalance)) { - return; - } - if (greaterThan(txFee, balance)) { - return; - } - } - - this.props.sendToggleConfirmationView(true); - - return this.props.sendTransaction( - { - address: this.props.address, - amount: this.props.assetAmount, - asset: this.props.selected, - gasLimit: this.props.gasLimit, - gasPrice: this.props.selectedGasPrice, - recipient: this.props.recipient, - }, - this.sendTransactionCallback - ); - } - }; - - onClose = () => { - this.props.sendClearFields(); - }; - - // QR Code Reader Handlers - toggleQRCodeReader = () => - this.setState(prevState => ({ - showQRCodeReader: !prevState.showQRCodeReader, - })); - - onQRCodeValidate = async rawData => { - const data = rawData.match(/0x\w{40}/g) - ? rawData.match(/0x\w{40}/g)[0] - : null; - let result = false; - if (data) { - result = await checkIsValidAddress(data); - } - const onError = () => - console.log(lang.t('notification.error.invalid_address_scanned')); - return { data, onError, result }; - }; - - onQRCodeScan = data => { - this.props.sendUpdateRecipient(data); - this.setState({ showQRCodeReader: false }); - }; - - onQRCodeError = () => { - console.log(lang.t('notification.error.failed_scanning_qr_code')); - }; - - render() { - return ( - - ); - } - } - - return compose( - connect(mapStateToProps, { - sendClearFields, - sendMaxBalance, - sendModalInit, - sendToggleConfirmationView, - sendTransaction, - sendUpdateAssetAmount, - sendUpdateNativeAmount, - sendUpdateRecipient, - sendUpdateSelected, - }), - withGas, - withAccountData, - withUniqueTokens - )(SendComponentWithData); -}; diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index 7a99260c0b5..bc0346dfe56 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -49,8 +49,9 @@ export default withNavigation( this.inputRef.focus() ); } + shouldComponentUpdate(nextProps, nextState) { - const isNewAddress = isNewValueForPath(this.props, this.state, 'address'); + const isNewAddress = isNewValueForPath(nextProps, this.state, 'address'); const isNewInputValue = isNewValueForPath( this.state, nextState, diff --git a/src/hoc/index.js b/src/hoc/index.js index c7eab59d81e..7fb726b791d 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -28,6 +28,7 @@ export { default as withRequests } from './withRequests'; export { default as withRotationForDirection } from './withRotationForDirection'; export { default as withSafeAreaViewInsetValues } from './withSafeAreaViewInsetValues'; export { default as withSelectedInput } from './withSelectedInput'; +export { default as withSend } from './withSend'; export { default as withSendFeedback } from './withSendFeedback'; export { default as withStatusBarStyle } from './withStatusBarStyle'; export { default as withTransactionConfirmationScreen } from './withTransactionConfirmationScreen'; diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index a258c3732c4..ada27b7a110 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -84,6 +84,7 @@ export default Component => }, clearAccountData: ownProps => async () => { web3ListenerClearState(); + gasClearState(); const p0 = ownProps.explorerClearState(); const p1 = ownProps.dataClearState(); const p2 = ownProps.clearIsWalletEmpty(); @@ -93,7 +94,6 @@ export default Component => const p6 = ownProps.nonceClearState(); const p7 = ownProps.requestsClearState(); const p8 = ownProps.uniswapClearState(); - const p9 = ownProps.gasClearState(); return promiseUtils.PromiseAllWithFails([ p0, p1, @@ -104,7 +104,6 @@ export default Component => p6, p7, p8, - p9, ]); }, initializeAccountData: ownProps => async () => { diff --git a/src/hoc/withSend.js b/src/hoc/withSend.js new file mode 100644 index 00000000000..e0ce21f582b --- /dev/null +++ b/src/hoc/withSend.js @@ -0,0 +1,49 @@ +import { connect } from 'react-redux'; +import { + sendClearFields, + sendCreatedTransaction, + sendMaxBalance, + sendModalInit, + sendToggleConfirmationView, + sendUpdateAssetAmount, + sendUpdateNativeAmount, + sendUpdateRecipient, + sendUpdateSelected, +} from '../redux/send'; + +const mapStateToProps = ({ + send: { + address, + assetAmount, + confirm, + fetching, + isSufficientBalance, + nativeAmount, + recipient, + selected, + txHash, + }, +}) => ({ + address, + assetAmount, + confirm, + fetching, + isSufficientBalance, + nativeAmount, + recipient, + selected, + txHash, +}); + +export default Component => + connect(mapStateToProps, { + sendClearFields, + sendCreatedTransaction, + sendMaxBalance, + sendModalInit, + sendToggleConfirmationView, + sendUpdateAssetAmount, + sendUpdateNativeAmount, + sendUpdateRecipient, + sendUpdateSelected, + })(Component); diff --git a/src/redux/gas.js b/src/redux/gas.js index bab930fa30b..f87b687bf43 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -177,9 +177,7 @@ const getSelectedGasPrice = ( }; }; -export const gasClearState = () => () => { - clearInterval(getGasPricesInterval); -}; +export const gasClearState = () => clearInterval(getGasPricesInterval); // -- Reducer --------------------------------------------------------------- // const INITIAL_STATE = { diff --git a/src/redux/send.js b/src/redux/send.js index 6e534552e83..97c59ea8972 100644 --- a/src/redux/send.js +++ b/src/redux/send.js @@ -1,10 +1,11 @@ import { get, isEmpty } from 'lodash'; +import { createSignableTransaction } from '../handlers/web3'; import { convertAmountAndPriceToNativeDisplay, convertAmountFromNativeValue, formatInputDecimals, } from '../helpers/utilities'; -import { createSignableTransaction } from '../handlers/web3'; +import { sendTransaction } from '../model/wallet'; import { ethereumUtils } from '../utils'; import { dataAddNewTransaction } from './data'; @@ -29,24 +30,15 @@ const SEND_CLEAR_FIELDS = 'send/SEND_CLEAR_FIELDS'; // -- Actions --------------------------------------------------------------- // -export const sendModalInit = (options = {}) => (dispatch, getState) => { +export const sendModalInit = () => (dispatch, getState) => { const { accountAddress } = getState().settings; - const { assets } = getState().data; - const selected = - assets.filter(asset => asset.address === options.defaultAsset)[0] || {}; dispatch({ - payload: { - address: accountAddress, - selected, - }, + payload: accountAddress, type: SEND_MODAL_INIT, }); }; -export const sendTransaction = ( - transactionDetails, - signAndSendTransactionCb -) => (dispatch, getState) => +export const sendCreatedTransaction = transactionDetails => dispatch => new Promise((resolve, reject) => { dispatch({ type: SEND_TRANSACTION_REQUEST }); const { @@ -57,7 +49,6 @@ export const sendTransaction = ( gasPrice, gasLimit, } = transactionDetails; - const { accountType } = getState().settings; const txDetails = { amount, asset, @@ -69,8 +60,7 @@ export const sendTransaction = ( }; return createSignableTransaction(txDetails) .then(signableTransactionDetails => { - signAndSendTransactionCb({ - accountType, + sendTransaction({ transaction: signableTransactionDetails, }) .then(txHash => { @@ -231,8 +221,7 @@ export default (state = INITIAL_STATE, action) => { case SEND_MODAL_INIT: return { ...state, - address: action.payload.address, - selected: action.payload.selected, + address: action.payload, }; case SEND_TRANSACTION_REQUEST: return { ...state, fetching: true }; diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 11305645f7d..a9337e5078f 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -1,10 +1,8 @@ -import analytics from '@segment/analytics-react-native'; -import { get, isEmpty, isString, toLower } from 'lodash'; +import { isEmpty } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; -import { compose, withHandlers, withProps } from 'recompact'; import styled from 'styled-components/primitives'; import { Column } from '../components/layout'; import { @@ -15,16 +13,8 @@ import { SendHeader, SendTransactionSpeed, } from '../components/send'; -import { - withAccountData, - withAccountSettings, - withContacts, - withDataInit, - withTransitionProps, - withUniqueTokens, -} from '../hoc'; import { borders, colors } from '../styles'; -import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; +import { deviceUtils, isNewValueForPath } from '../utils'; const statusBarHeight = getStatusBarHeight(true); @@ -40,70 +30,38 @@ const SheetContainer = styled(Column)` top: ${statusBarHeight}; `; -class SendSheet extends Component { +export default class SendSheet extends Component { static propTypes = { allAssets: PropTypes.array, assetAmount: PropTypes.string, contacts: PropTypes.object, fetchData: PropTypes.func, gasPrices: PropTypes.object, - gasUpdateGasPriceOption: PropTypes.func, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, nativeCurrencySymbol: PropTypes.string, navigation: PropTypes.object, - onSubmit: PropTypes.func, + onChangeAssetAmount: PropTypes.func, + onChangeInput: PropTypes.func, + onChangeNativeAmount: PropTypes.func, + onLongPressSend: PropTypes.func, + onPressTransactionSpeed: PropTypes.func, + onResetAssetSelection: PropTypes.func, + onSelectAsset: PropTypes.func, recipient: PropTypes.string, removeContact: PropTypes.func, selected: PropTypes.object, selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), - sendClearFields: PropTypes.func, - sendMaxBalance: PropTypes.func, - sendUpdateAssetAmount: PropTypes.func, - sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, - sendUpdateSelected: PropTypes.func, sortedContacts: PropTypes.array, }; - static defaultProps = { - isSufficientBalance: false, - isSufficientGas: false, - isValidAddress: false, - }; - - state = { - currentInput: '', - isAuthorizing: false, - }; - - componentDidMount = async () => { - const { navigation, sendUpdateRecipient } = this.props; - const address = get(navigation, 'state.params.address'); - - if (address) { - sendUpdateRecipient(address); - } - }; - componentDidUpdate(prevProps) { - const { - contacts, - isValidAddress, - navigation, - selected, - sendUpdateSelected, - } = this.props; - - const asset = get(navigation, 'state.params.asset'); + const { contacts, isValidAddress, navigation, selected } = this.props; if (isValidAddress && !prevProps.isValidAddress) { - if (asset) { - sendUpdateSelected(asset); - } - Keyboard.dismiss(); } @@ -136,91 +94,24 @@ class SendSheet extends Component { } } - componentWillUnmount() { - this.props.sendClearFields(); - } - - onChangeAssetAmount = assetAmount => { - if (isString(assetAmount)) { - this.props.sendUpdateAssetAmount(assetAmount); - analytics.track('Changed token input in Send flow'); - } - }; - - onChangeNativeAmount = nativeAmount => { - if (isString(nativeAmount)) { - this.props.sendUpdateNativeAmount(nativeAmount); - analytics.track('Changed native currency input in Send flow'); - } - }; - - onLongPressSend = () => { - this.setState({ isAuthorizing: true }); - - if (isIphoneX()) { - this.sendTransaction(); - } else { - this.onPressTransactionSpeed(this.sendTransaction); - } - }; - - onPressTransactionSpeed = onSuccess => { - const { gasPrices, gasUpdateGasPriceOption, txFees } = this.props; - gasUtils.showTransactionSpeedOptions( - gasPrices, - txFees, - gasUpdateGasPriceOption, - onSuccess - ); - }; - - onResetAssetSelection = () => { - analytics.track('Reset asset selection in Send flow'); - this.props.sendUpdateSelected({}); - }; - - onSelectAsset = asset => this.props.sendUpdateSelected(asset); - - sendTransaction = () => { - const { - assetAmount, - navigation, - onSubmit, - recipient, - selected, - sendClearFields, - } = this.props; - - if (Number(assetAmount) <= 0) return false; - - return onSubmit() - .then(() => { - this.setState({ isAuthorizing: false }); - analytics.track('Sent transaction', { - assetName: selected.name, - assetType: selected.isNft ? 'unique_token' : 'token', - isRecepientENS: toLower(recipient.slice(-4)) === '.eth', - }); - sendClearFields(); - navigation.navigate('ProfileScreen'); - }) - .catch(() => { - this.setState({ isAuthorizing: false }); - }); - }; - - onChangeInput = event => { - this.setState({ currentInput: event }); - this.props.sendUpdateRecipient(event); - }; - render() { const { allAssets, contacts, + currentInput, fetchData, + isAuthorizing, + isSufficientBalance, + isSufficientGas, isValidAddress, nativeCurrencySymbol, + onChangeAssetAmount, + onChangeInput, + onChangeNativeAmount, + onLongPressSend, + onPressTransactionSpeed, + onResetAssetSelection, + onSelectAsset, recipient, removeContact, selected, @@ -240,9 +131,8 @@ class SendSheet extends Component { @@ -259,7 +149,7 @@ class SendSheet extends Component { )} @@ -270,20 +160,22 @@ class SendSheet extends Component { buttonRenderer={ } - onChangeAssetAmount={this.onChangeAssetAmount} - onChangeNativeAmount={this.onChangeNativeAmount} - onResetAssetSelection={this.onResetAssetSelection} + onChangeAssetAmount={onChangeAssetAmount} + onChangeNativeAmount={onChangeNativeAmount} + onResetAssetSelection={onResetAssetSelection} selected={selected} txSpeedRenderer={ isIphoneX() && ( ) } @@ -295,18 +187,3 @@ class SendSheet extends Component { ); } } - -export default compose( - withAccountData, - withContacts, - withUniqueTokens, - withAccountSettings, - withDataInit, - withTransitionProps, - withProps(({ transitionProps: { isTransitioning } }) => ({ - isTransitioning, - })), - withHandlers({ - fetchData: ({ refreshAccountData }) => async () => refreshAccountData(), - }) -)(SendSheet); diff --git a/src/screens/SendSheetWithData.js b/src/screens/SendSheetWithData.js index 3e8d7a77d6b..676159f4113 100644 --- a/src/screens/SendSheetWithData.js +++ b/src/screens/SendSheetWithData.js @@ -1,11 +1,292 @@ -import { withSendComponentWithData } from '../components/SendComponentWithData'; -import { sendTransaction } from '../model/wallet'; +import analytics from '@segment/analytics-react-native'; +import { get, isString, toLower } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { isIphoneX } from 'react-native-iphone-x-helper'; +import { compose, withHandlers, withProps } from 'recompact'; +import { estimateGasLimit } from '../handlers/web3'; +import { greaterThan } from '../helpers/utilities'; +import { checkIsValidAddress } from '../helpers/validators'; +import { + withAccountData, + withAccountSettings, + withContacts, + withDataInit, + withGas, + withSend, + withTransitionProps, + withUniqueTokens, +} from '../hoc'; +import lang from '../languages'; +import { ethereumUtils, gasUtils, isNewValueForPath } from '../utils'; import SendSheet from './SendSheet'; -const SendSheetWithData = withSendComponentWithData(SendSheet, { - gasFormat: 'short', - sendTransactionCallback: sendTransaction, -}); +class SendSheetWithData extends Component { + static propTypes = { + address: PropTypes.string, + assetAmount: PropTypes.string.isRequired, + assets: PropTypes.array.isRequired, + confirm: PropTypes.bool.isRequired, + fetching: PropTypes.bool.isRequired, + gasLimit: PropTypes.number, + gasPrices: PropTypes.object.isRequired, + gasUpdateDefaultGasLimit: PropTypes.func.isRequired, + gasUpdateTxFee: PropTypes.func.isRequired, + isSufficientBalance: PropTypes.bool.isRequired, + isSufficientGas: PropTypes.bool.isRequired, + nativeAmount: PropTypes.string.isRequired, + nativeCurrency: PropTypes.string.isRequired, + network: PropTypes.string.isRequired, + recipient: PropTypes.string.isRequired, + selected: PropTypes.object.isRequired, + selectedGasPrice: PropTypes.shape({ txFee: PropTypes.object }), + selectedGasPriceOption: PropTypes.string.isRequired, + sendClearFields: PropTypes.func.isRequired, + sendCreatedTransaction: PropTypes.func.isRequired, + sendMaxBalance: PropTypes.func.isRequired, + sendModalInit: PropTypes.func.isRequired, + sendToggleConfirmationView: PropTypes.func.isRequired, + sendUpdateAssetAmount: PropTypes.func.isRequired, + sendUpdateNativeAmount: PropTypes.func.isRequired, + sendUpdateRecipient: PropTypes.func.isRequired, + sendUpdateSelected: PropTypes.func.isRequired, + txFees: PropTypes.object.isRequired, + txHash: PropTypes.string.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + contacts: [], + currentInput: '', + isAuthorizing: false, + isValidAddress: false, + }; + } + + componentDidMount() { + this.props.sendModalInit(); + this.props.gasUpdateDefaultGasLimit(); + + const { navigation, sendUpdateRecipient } = this.props; + const address = get(navigation, 'state.params.address'); + + if (address) { + sendUpdateRecipient(address); + } + } + + async componentDidUpdate(prevProps, prevState) { + const { + address, + assetAmount, + navigation, + recipient, + selected, + sendUpdateSelected, + } = this.props; + const { isValidAddress } = this.state; + + const asset = get(navigation, 'state.params.asset'); + + if (isValidAddress && !prevState.isValidAddress) { + if (asset) { + sendUpdateSelected(asset); + } + } + + const isNewRecipient = isNewValueForPath( + this.props, + prevProps, + 'recipient' + ); + if (isNewRecipient) { + const validAddress = await checkIsValidAddress(recipient); + // eslint-disable-next-line react/no-did-update-set-state + this.setState({ isValidAddress: validAddress }); + } + + if (isValidAddress) { + if ( + selected.symbol !== prevProps.selected.symbol || + recipient !== prevProps.recipient || + assetAmount !== prevProps.assetAmount + ) { + estimateGasLimit({ + address, + amount: assetAmount, + asset: selected, + recipient, + }) + .then(gasLimit => { + this.props.gasUpdateTxFee(gasLimit); + }) + .catch(() => { + this.props.gasUpdateTxFee(null); + }); + } + } + } + + componentWillUnmount() { + this.props.sendClearFields(); + } + + onChangeAssetAmount = assetAmount => { + if (isString(assetAmount)) { + this.props.sendUpdateAssetAmount(assetAmount); + analytics.track('Changed token input in Send flow'); + } + }; + + onChangeNativeAmount = nativeAmount => { + if (isString(nativeAmount)) { + this.props.sendUpdateNativeAmount(nativeAmount); + analytics.track('Changed native currency input in Send flow'); + } + }; + + onLongPressSend = () => { + this.setState({ isAuthorizing: true }); + + if (isIphoneX()) { + this.submitTransaction(); + } else { + this.onPressTransactionSpeed(this.submitTransaction); + } + }; + + onPressTransactionSpeed = onSuccess => { + const { gasPrices, gasUpdateGasPriceOption, txFees } = this.props; + gasUtils.showTransactionSpeedOptions( + gasPrices, + txFees, + gasUpdateGasPriceOption, + onSuccess + ); + }; + + onResetAssetSelection = () => { + analytics.track('Reset asset selection in Send flow'); + this.props.sendUpdateSelected({}); + }; + + onSelectAsset = asset => this.props.sendUpdateSelected(asset); + + submitTransaction = async () => { + const { + assetAmount, + navigation, + recipient, + selected, + sendClearFields, + } = this.props; + + if (Number(assetAmount) <= 0) return false; + + try { + await this.onSubmit(); + this.setState({ isAuthorizing: false }); + analytics.track('Sent transaction', { + assetName: selected.name, + assetType: selected.isNft ? 'unique_token' : 'token', + isRecepientENS: toLower(recipient.slice(-4)) === '.eth', + }); + sendClearFields(); + navigation.navigate('ProfileScreen'); + } catch { + this.setState({ isAuthorizing: false }); + } + }; + + onChangeInput = event => { + this.setState({ currentInput: event }); + this.props.sendUpdateRecipient(event); + }; + + onSubmit = async () => { + if (!this.props.selectedGasPrice.txFee) { + return; + } + + // Balance checks + if (!this.props.confirm) { + const isAddressValid = await checkIsValidAddress(this.props.recipient); + if (!isAddressValid) { + console.log(lang.t('notification.error.invalid_address')); + return; + } + if (this.props.selected.address === 'eth') { + const { + requestedAmount, + balance, + amountWithFees, + } = ethereumUtils.transactionData( + this.props.assets, + this.props.assetAmount, + this.props.selectedGasPrice + ); + + if (greaterThan(requestedAmount, balance)) { + return; + } + if (greaterThan(amountWithFees, balance)) { + return; + } + } else if (!this.props.selected.isNft) { + const { + requestedAmount, + balance, + txFee, + } = ethereumUtils.transactionData( + this.props.assets, + this.props.assetAmount, + this.props.selectedGasPrice + ); + + const tokenBalance = get(this.props, 'selected.balance.amount'); + + if (greaterThan(requestedAmount, tokenBalance)) { + return; + } + if (greaterThan(txFee, balance)) { + return; + } + } + + this.props.sendToggleConfirmationView(true); + + return this.props.sendCreatedTransaction({ + address: this.props.address, + amount: this.props.assetAmount, + asset: this.props.selected, + gasLimit: this.props.gasLimit, + gasPrice: this.props.selectedGasPrice, + recipient: this.props.recipient, + }); + } + }; + + render() { + return ( + + ); + } +} SendSheetWithData.navigationOptions = ({ navigation: { @@ -17,4 +298,19 @@ SendSheetWithData.navigationOptions = ({ }, }); -export default SendSheetWithData; +export default compose( + withAccountData, + withAccountSettings, + withContacts, + withDataInit, + withSend, + withGas, + withUniqueTokens, + withTransitionProps, + withProps(({ transitionProps: { isTransitioning } }) => ({ + isTransitioning, + })), + withHandlers({ + fetchData: ({ refreshAccountData }) => async () => refreshAccountData(), + }) +)(SendSheetWithData); From a7700ae45987cb4c5c16e9b35b62d94b2a949ae0 Mon Sep 17 00:00:00 2001 From: jinchung Date: Sat, 23 Nov 2019 12:49:36 -0500 Subject: [PATCH 555/636] Remove send redux and use state --- src/components/send/SendAssetForm.js | 7 +- src/hoc/index.js | 1 - src/hoc/withSend.js | 49 ----- src/redux/reducers.js | 2 - src/redux/send.js | 267 ------------------------- src/screens/ExchangeModal.js | 47 ----- src/screens/SendSheet.js | 5 + src/screens/SendSheetWithData.js | 288 +++++++++++++++++---------- 8 files changed, 198 insertions(+), 468 deletions(-) delete mode 100644 src/hoc/withSend.js delete mode 100644 src/redux/send.js diff --git a/src/components/send/SendAssetForm.js b/src/components/send/SendAssetForm.js index 3ef3981be69..3f6efbb5523 100644 --- a/src/components/send/SendAssetForm.js +++ b/src/components/send/SendAssetForm.js @@ -39,6 +39,7 @@ const SendAssetForm = ({ buttonRenderer, onResetAssetSelection, selected, + sendMaxBalance, txSpeedRenderer, ...props }) => { @@ -69,7 +70,11 @@ const SendAssetForm = ({ {selected.isNft ? ( ) : ( - + )} ({ - address, - assetAmount, - confirm, - fetching, - isSufficientBalance, - nativeAmount, - recipient, - selected, - txHash, -}); - -export default Component => - connect(mapStateToProps, { - sendClearFields, - sendCreatedTransaction, - sendMaxBalance, - sendModalInit, - sendToggleConfirmationView, - sendUpdateAssetAmount, - sendUpdateNativeAmount, - sendUpdateRecipient, - sendUpdateSelected, - })(Component); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 28a57b1bb20..6dc761475c6 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -16,7 +16,6 @@ import openStateSettings from './openStateSettings'; import requests from './requests'; import selectedInput from './selectedInput'; import selectedWithFab from './selectedWithFab'; -import send from './send'; import settings from './settings'; import uniqueTokens from './uniqueTokens'; import uniswap from './uniswap'; @@ -39,7 +38,6 @@ export default combineReducers({ requests, selectedInput, selectedWithFab, - send, settings, uniqueTokens, uniswap, diff --git a/src/redux/send.js b/src/redux/send.js deleted file mode 100644 index 97c59ea8972..00000000000 --- a/src/redux/send.js +++ /dev/null @@ -1,267 +0,0 @@ -import { get, isEmpty } from 'lodash'; -import { createSignableTransaction } from '../handlers/web3'; -import { - convertAmountAndPriceToNativeDisplay, - convertAmountFromNativeValue, - formatInputDecimals, -} from '../helpers/utilities'; -import { sendTransaction } from '../model/wallet'; -import { ethereumUtils } from '../utils'; -import { dataAddNewTransaction } from './data'; - -// -- Constants ------------------------------------------------------------- // - -const SEND_MODAL_INIT = 'send/SEND_MODAL_INIT'; - -const SEND_TRANSACTION_REQUEST = 'send/SEND_TRANSACTION_REQUEST'; -const SEND_TRANSACTION_SUCCESS = 'send/SEND_TRANSACTION_SUCCESS'; -const SEND_TRANSACTION_FAILURE = 'send/SEND_TRANSACTION_FAILURE'; - -const SEND_TOGGLE_CONFIRMATION_VIEW = 'send/SEND_TOGGLE_CONFIRMATION_VIEW'; - -const SEND_UPDATE_NATIVE_AMOUNT = 'send/SEND_UPDATE_NATIVE_AMOUNT'; - -const SEND_UPDATE_RECIPIENT = 'send/SEND_UPDATE_RECIPIENT'; -const SEND_UPDATE_ASSET_AMOUNT = 'send/SEND_UPDATE_ASSET_AMOUNT'; -const SEND_UPDATE_SELECTED = 'send/SEND_UPDATE_SELECTED'; -const SEND_UPDATE_NFT_SELECTED = 'send/SEND_UPDATE_NFT_SELECTED'; - -const SEND_CLEAR_FIELDS = 'send/SEND_CLEAR_FIELDS'; - -// -- Actions --------------------------------------------------------------- // - -export const sendModalInit = () => (dispatch, getState) => { - const { accountAddress } = getState().settings; - dispatch({ - payload: accountAddress, - type: SEND_MODAL_INIT, - }); -}; - -export const sendCreatedTransaction = transactionDetails => dispatch => - new Promise((resolve, reject) => { - dispatch({ type: SEND_TRANSACTION_REQUEST }); - const { - address, - recipient, - amount, - asset, - gasPrice, - gasLimit, - } = transactionDetails; - const txDetails = { - amount, - asset, - from: address, - gasLimit, - gasPrice: gasPrice.value.amount, - nonce: null, - to: recipient, - }; - return createSignableTransaction(txDetails) - .then(signableTransactionDetails => { - sendTransaction({ - transaction: signableTransactionDetails, - }) - .then(txHash => { - if (!isEmpty(txHash)) { - txDetails.hash = txHash; - dispatch(dataAddNewTransaction(txDetails)) - .then(() => { - dispatch({ - payload: txHash, - type: SEND_TRANSACTION_SUCCESS, - }); - resolve(txHash); - }) - .catch(error => { - reject(error); - }); - } else { - dispatch({ type: SEND_TRANSACTION_FAILURE }); - reject(new Error('No transaction hash.')); - } - }) - .catch(error => { - dispatch({ type: SEND_TRANSACTION_FAILURE }); - reject(error); - }); - }) - .catch(error => { - dispatch({ type: SEND_TRANSACTION_FAILURE }); - reject(error); - }); - }); - -export const sendToggleConfirmationView = boolean => (dispatch, getState) => { - let confirm = boolean; - if (!confirm) { - confirm = !getState().send.confirm; - } - dispatch({ - payload: confirm, - type: SEND_TOGGLE_CONFIRMATION_VIEW, - }); -}; - -export const sendUpdateRecipient = recipient => dispatch => - dispatch({ - payload: recipient, - type: SEND_UPDATE_RECIPIENT, - }); - -export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { - const { nativeCurrency } = getState().settings; - const { selected } = getState().send; - const { selectedGasPrice } = getState().gas; - const _assetAmount = assetAmount.replace(/[^0-9.]/g, ''); - let _nativeAmount = ''; - if (_assetAmount.length) { - const priceUnit = get(selected, 'price.value', 0); - const { amount: nativeAmount } = convertAmountAndPriceToNativeDisplay( - _assetAmount, - priceUnit, - nativeCurrency - ); - _nativeAmount = formatInputDecimals(nativeAmount, _assetAmount); - } - const balanceAmount = ethereumUtils.getBalanceAmount( - selectedGasPrice, - selected - ); - dispatch({ - payload: { - assetAmount: _assetAmount, - isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), - nativeAmount: _nativeAmount, - }, - type: SEND_UPDATE_ASSET_AMOUNT, - }); -}; - -export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { - const { selected } = getState().send; - const { selectedGasPrice } = getState().gas; - const _nativeAmount = nativeAmount.replace(/[^0-9.]/g, ''); - let _assetAmount = ''; - if (_nativeAmount.length) { - const priceUnit = get(selected, 'price.value', 0); - const assetAmount = convertAmountFromNativeValue( - _nativeAmount, - priceUnit, - selected.decimals - ); - _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); - } - - const balanceAmount = ethereumUtils.getBalanceAmount( - selectedGasPrice, - selected - ); - - dispatch({ - payload: { - assetAmount: _assetAmount, - isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), - nativeAmount: _nativeAmount, - }, - type: SEND_UPDATE_ASSET_AMOUNT, - }); -}; - -export const sendUpdateSelected = asset => (dispatch, getState) => { - if (get(asset, 'isNft')) { - dispatch({ - payload: { - selected: { - ...asset, - symbol: asset.asset_contract.name, - }, - }, - type: SEND_UPDATE_NFT_SELECTED, - }); - } else { - const state = getState(); - const assetAmount = get(state, 'send.assetAmount'); - dispatch({ - payload: asset, - type: SEND_UPDATE_SELECTED, - }); - dispatch(sendUpdateAssetAmount(assetAmount)); - } -}; - -export const sendMaxBalance = () => (dispatch, getState) => { - const { selected } = getState().send; - const { selectedGasPrice } = getState().gas; - const balanceAmount = ethereumUtils.getBalanceAmount( - selectedGasPrice, - selected - ); - dispatch(sendUpdateAssetAmount(balanceAmount)); -}; - -export const sendClearFields = () => ({ type: SEND_CLEAR_FIELDS }); - -// -- Reducer --------------------------------------------------------------- // -const INITIAL_STATE = { - address: '', - assetAmount: '', - confirm: false, - fetching: false, - isSufficientBalance: false, - nativeAmount: '', - recipient: '', - selected: {}, - txHash: '', -}; - -export default (state = INITIAL_STATE, action) => { - switch (action.type) { - case SEND_MODAL_INIT: - return { - ...state, - address: action.payload, - }; - case SEND_TRANSACTION_REQUEST: - return { ...state, fetching: true }; - case SEND_TRANSACTION_SUCCESS: - return { - ...state, - fetching: false, - txHash: action.payload, - }; - case SEND_TRANSACTION_FAILURE: - return { - ...state, - confirm: false, - fetching: false, - txHash: '', - }; - case SEND_TOGGLE_CONFIRMATION_VIEW: - return { ...state, confirm: action.payload }; - case SEND_UPDATE_RECIPIENT: - return { ...state, recipient: action.payload }; - case SEND_UPDATE_NATIVE_AMOUNT: - case SEND_UPDATE_ASSET_AMOUNT: - return { - ...state, - assetAmount: action.payload.assetAmount, - isSufficientBalance: action.payload.isSufficientBalance, - nativeAmount: action.payload.nativeAmount, - }; - case SEND_UPDATE_SELECTED: - return { ...state, selected: action.payload }; - case SEND_UPDATE_NFT_SELECTED: - return { - ...state, - assetAmount: '1', - isSufficientBalance: true, - selected: action.payload.selected, - }; - case SEND_CLEAR_FIELDS: - return { ...state, ...INITIAL_STATE }; - default: - return state; - } -}; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 7ab49aba792..90daa3eb2b9 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -7,7 +7,6 @@ import { tradeTokensForExactEthWithData, tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; -import BigNumber from 'bignumber.js'; import { get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; @@ -35,7 +34,6 @@ import { estimateSwapGasLimit, executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeValue, convertAmountToNativeAmount, - convertAmountToNativeDisplay, convertAmountToRawAmount, convertNumberToString, convertRawAmountToDecimalFormat, @@ -113,8 +111,6 @@ class ExchangeModal extends Component { inputAmountDisplay: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), - inputExecutionRate: null, - inputNativePrice: null, isAssetApproved: true, isAuthorizing: false, isSufficientBalance: true, @@ -123,8 +119,6 @@ class ExchangeModal extends Component { outputAmount: null, outputAmountDisplay: null, outputCurrency: null, - outputExecutionRate: null, - outputNativePrice: null, showConfirmButton: false, slippage: null, tradeDetails: null, @@ -336,7 +330,6 @@ class ExchangeModal extends Component { chainId, gasUpdateTxFee, inputReserve, - nativeCurrency, outputReserve, selectedGasPrice, } = this.props; @@ -420,38 +413,6 @@ class ExchangeModal extends Component { ); } - let inputExecutionRate = ''; - let outputExecutionRate = ''; - let inputNativePrice = ''; - let outputNativePrice = ''; - - if (inputCurrency) { - const inputPriceValue = get(inputCurrency, 'price.value', 0); - inputExecutionRate = updatePrecisionToDisplay( - get(tradeDetails, 'executionRate.rate', BigNumber(0)), - inputPriceValue - ); - - inputNativePrice = convertAmountToNativeDisplay( - inputPriceValue, - nativeCurrency - ); - } - - if (outputCurrency) { - const outputPriceValue = get(outputCurrency, 'price.value', 0); - outputExecutionRate = updatePrecisionToDisplay( - get(tradeDetails, 'executionRate.rateInverted', BigNumber(0)), - outputPriceValue, - true - ); - - outputNativePrice = convertAmountToNativeDisplay( - outputPriceValue, - nativeCurrency - ); - } - const slippage = convertNumberToString( get(tradeDetails, 'executionRateSlippage', 0) ); @@ -465,11 +426,7 @@ class ExchangeModal extends Component { parseFloat(inputBalance) >= parseFloat(inputAmount); this.setState({ - inputExecutionRate, - inputNativePrice, isSufficientBalance, - outputExecutionRate, - outputNativePrice, slippage, tradeDetails, }); @@ -811,8 +768,6 @@ class ExchangeModal extends Component { inputAmount, inputAmountDisplay, inputCurrency, - // inputExecutionRate, - // inputNativePrice, isAssetApproved, isAuthorizing, isSufficientBalance, @@ -821,8 +776,6 @@ class ExchangeModal extends Component { outputAmount, outputAmountDisplay, outputCurrency, - // outputExecutionRate, - // outputNativePrice, showConfirmButton, slippage, } = this.state; diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index a9337e5078f..4d9afa03cdd 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -35,8 +35,10 @@ export default class SendSheet extends Component { allAssets: PropTypes.array, assetAmount: PropTypes.string, contacts: PropTypes.object, + currentInput: PropTypes.string, fetchData: PropTypes.func, gasPrices: PropTypes.object, + isAuthorizing: PropTypes.bool, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, @@ -54,6 +56,7 @@ export default class SendSheet extends Component { selected: PropTypes.object, selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), + sendMaxBalance: PropTypes.func, sendUpdateRecipient: PropTypes.func, sortedContacts: PropTypes.array, }; @@ -116,6 +119,7 @@ export default class SendSheet extends Component { removeContact, selected, selectedGasPrice, + sendMaxBalance, sendableUniqueTokens, sendUpdateRecipient, sortedContacts, @@ -170,6 +174,7 @@ export default class SendSheet extends Component { onChangeNativeAmount={onChangeNativeAmount} onResetAssetSelection={onResetAssetSelection} selected={selected} + sendMaxBalance={sendMaxBalance} txSpeedRenderer={ isIphoneX() && ( { - if (isString(assetAmount)) { - this.props.sendUpdateAssetAmount(assetAmount); - analytics.track('Changed token input in Send flow'); + sendUpdateAssetAmount = assetAmount => { + const { nativeCurrency, selectedGasPrice } = this.props; + const { selected } = this.state; + const _assetAmount = assetAmount.replace(/[^0-9.]/g, ''); + let _nativeAmount = ''; + if (_assetAmount.length) { + const priceUnit = get(selected, 'price.value', 0); + const { amount: nativeAmount } = convertAmountAndPriceToNativeDisplay( + _assetAmount, + priceUnit, + nativeCurrency + ); + _nativeAmount = formatInputDecimals(nativeAmount, _assetAmount); } + const balanceAmount = ethereumUtils.getBalanceAmount( + selectedGasPrice, + selected + ); + this.setState({ + assetAmount: _assetAmount, + isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), + nativeAmount: _nativeAmount, + }); }; onChangeNativeAmount = nativeAmount => { - if (isString(nativeAmount)) { - this.props.sendUpdateNativeAmount(nativeAmount); - analytics.track('Changed native currency input in Send flow'); + if (!isString(nativeAmount)) return; + const { selected } = this.state; + const { selectedGasPrice } = this.props; + const _nativeAmount = nativeAmount.replace(/[^0-9.]/g, ''); + let _assetAmount = ''; + if (_nativeAmount.length) { + const priceUnit = get(selected, 'price.value', 0); + const assetAmount = convertAmountFromNativeValue( + _nativeAmount, + priceUnit, + selected.decimals + ); + _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); + } + + const balanceAmount = ethereumUtils.getBalanceAmount( + selectedGasPrice, + selected + ); + + this.setState({ + assetAmount: _assetAmount, + isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), + nativeAmount: _nativeAmount, + }); + analytics.track('Changed native currency input in Send flow'); + }; + + sendMaxBalance = () => { + const balanceAmount = ethereumUtils.getBalanceAmount( + this.props.selectedGasPrice, + this.state.selected + ); + this.sendUpdateAssetAmount(balanceAmount); + }; + + onChangeAssetAmount = assetAmount => { + if (isString(assetAmount)) { + this.sendUpdateAssetAmount(assetAmount); + analytics.track('Changed token input in Send flow'); } }; @@ -169,19 +206,12 @@ class SendSheetWithData extends Component { onResetAssetSelection = () => { analytics.track('Reset asset selection in Send flow'); - this.props.sendUpdateSelected({}); + this.sendUpdateSelected({}); }; - onSelectAsset = asset => this.props.sendUpdateSelected(asset); - submitTransaction = async () => { - const { - assetAmount, - navigation, - recipient, - selected, - sendClearFields, - } = this.props; + const { navigation } = this.props; + const { assetAmount, recipient, selected } = this.state; if (Number(assetAmount) <= 0) return false; @@ -193,39 +223,63 @@ class SendSheetWithData extends Component { assetType: selected.isNft ? 'unique_token' : 'token', isRecepientENS: toLower(recipient.slice(-4)) === '.eth', }); - sendClearFields(); navigation.navigate('ProfileScreen'); } catch { this.setState({ isAuthorizing: false }); } }; - onChangeInput = event => { - this.setState({ currentInput: event }); - this.props.sendUpdateRecipient(event); + onChangeInput = event => + this.setState({ currentInput: event, recipient: event }); + + sendUpdateRecipient = recipient => this.setState({ recipient }); + + sendUpdateSelected = selected => { + if (get(selected, 'isNft')) { + this.setState({ + assetAmount: '1', + isSufficientBalance: true, + selected: { + ...selected, + symbol: get(selected, 'asset_contract.name'), + }, + }); + } else { + const assetAmount = this.state.assetAmount; + this.setState({ selected }); + this.sendUpdateAssetAmount(assetAmount); + } }; onSubmit = async () => { - if (!this.props.selectedGasPrice.txFee) { + const { + accountAddress, + assets, + dataAddNewTransaction, + gasLimit, + selectedGasPrice, + } = this.props; + const { assetAmount, confirm, recipient, selected } = this.state; + if (!selectedGasPrice.txFee) { return; } // Balance checks - if (!this.props.confirm) { - const isAddressValid = await checkIsValidAddress(this.props.recipient); + if (!confirm) { + const isAddressValid = await checkIsValidAddress(recipient); if (!isAddressValid) { console.log(lang.t('notification.error.invalid_address')); return; } - if (this.props.selected.address === 'eth') { + if (selected.address === 'eth') { const { requestedAmount, balance, amountWithFees, } = ethereumUtils.transactionData( - this.props.assets, - this.props.assetAmount, - this.props.selectedGasPrice + assets, + assetAmount, + selectedGasPrice ); if (greaterThan(requestedAmount, balance)) { @@ -234,18 +288,18 @@ class SendSheetWithData extends Component { if (greaterThan(amountWithFees, balance)) { return; } - } else if (!this.props.selected.isNft) { + } else if (!selected.isNft) { const { requestedAmount, balance, txFee, } = ethereumUtils.transactionData( - this.props.assets, - this.props.assetAmount, - this.props.selectedGasPrice + assets, + assetAmount, + selectedGasPrice ); - const tokenBalance = get(this.props, 'selected.balance.amount'); + const tokenBalance = get(selected, 'balance.amount'); if (greaterThan(requestedAmount, tokenBalance)) { return; @@ -255,33 +309,65 @@ class SendSheetWithData extends Component { } } - this.props.sendToggleConfirmationView(true); - - return this.props.sendCreatedTransaction({ - address: this.props.address, - amount: this.props.assetAmount, - asset: this.props.selected, - gasLimit: this.props.gasLimit, - gasPrice: this.props.selectedGasPrice, - recipient: this.props.recipient, - }); + this.setState({ confirm: true }); + + const txDetails = { + amount: assetAmount, + asset: selected, + from: accountAddress, + gasLimit, + gasPrice: get(selectedGasPrice, 'value.amount'), + nonce: null, + to: recipient, + }; + try { + const signableTransaction = await createSignableTransaction(txDetails); + const txHash = sendTransaction({ + transaction: signableTransaction, + }); + if (!isEmpty(txHash)) { + txDetails.hash = txHash; + await dataAddNewTransaction(txDetails); + } + // eslint-disable-next-line no-empty + } catch (error) {} } }; render() { + const { + assetAmount, + contacts, + currentInput, + isAuthorizing, + isSufficientBalance, + isSufficientGas, + isValidAddress, + nativeAmount, + recipient, + selected, + } = this.state; return ( ); @@ -303,9 +389,9 @@ export default compose( withAccountSettings, withContacts, withDataInit, - withSend, withGas, withUniqueTokens, + withTransactionConfirmationScreen, withTransitionProps, withProps(({ transitionProps: { isTransitioning } }) => ({ isTransitioning, From 8d1cecd78ffd544c49e3fcef8055c8cd51fb8c4e Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 28 Nov 2019 04:00:51 -0500 Subject: [PATCH 556/636] Verifying data payload from OpenSea before parsing --- src/parsers/uniqueTokens.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/parsers/uniqueTokens.js b/src/parsers/uniqueTokens.js index f1f5ce7d78a..de4fd42de28 100644 --- a/src/parsers/uniqueTokens.js +++ b/src/parsers/uniqueTokens.js @@ -1,4 +1,4 @@ -import { filter, find, get, map, pick, uniq } from 'lodash'; +import { filter, find, get, isNil, map, pick, uniq } from 'lodash'; /** * @desc parse unique tokens from opensea @@ -6,7 +6,8 @@ import { filter, find, get, map, pick, uniq } from 'lodash'; * @return {Array} */ export const parseAccountUniqueTokens = data => { - const erc721s = get(data, 'data.assets', []); + const erc721s = get(data, 'data.assets', null); + if (isNil(erc721s)) throw new Error('Invalid data from OpenSea'); return erc721s.map( ({ asset_contract, background_color, token_id, ...asset }) => ({ ...pick(asset, [ From 22c69c468e213b4f0be76035e28bea6b6e25c479 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Thu, 28 Nov 2019 14:10:59 -0500 Subject: [PATCH 557/636] On profile screen, "Copy" -> "Copy Address" --- src/components/profile/ProfileMasthead.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/profile/ProfileMasthead.js b/src/components/profile/ProfileMasthead.js index b4df4ac997d..e077dd74374 100644 --- a/src/components/profile/ProfileMasthead.js +++ b/src/components/profile/ProfileMasthead.js @@ -54,7 +54,7 @@ const ProfileMasthead = ({ icon="copy" onPress={onPressCopy} scaleTo={0.82} - text="Copy" + text="Copy Address" /> Date: Thu, 28 Nov 2019 15:09:18 -0500 Subject: [PATCH 558/636] Fix: override token params for transactions --- src/parsers/transactions.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index 9841b16a788..830a75e1846 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -21,6 +21,7 @@ import { convertRawAmountToBalance, convertRawAmountToNativeDisplay, } from '../helpers/utilities'; +import { loweredTokenOverrides } from '../references'; import { isLowerCaseMatch } from '../utils'; const DIRECTION_OUT = 'out'; @@ -169,15 +170,19 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { internalTransactions = transformUniswapRefund(internalTransactions); } internalTransactions = internalTransactions.map((internalTxn, index) => { - const symbol = get(internalTxn, 'asset.symbol') || ''; + const address = toLower(get(internalTxn, 'asset.asset_code')); const updatedAsset = { - ...internalTxn.asset, - symbol: toUpper(symbol), + address, + decimals: get(internalTxn, 'asset.decimals'), + name: get(internalTxn, 'asset.name'), + symbol: toUpper(get(internalTxn, 'asset.symbol') || ''), + ...loweredTokenOverrides[address], }; const priceUnit = internalTxn.price || 0; + const valueUnit = internalTxn.value || 0; const nativeDisplay = convertRawAmountToNativeDisplay( - internalTxn.value, - internalTxn.asset.decimals, + valueUnit, + updatedAsset.decimals, priceUnit, nativeCurrency ); @@ -192,13 +197,13 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { return { ...transaction, - balance: convertRawAmountToBalance(internalTxn.value, updatedAsset), + balance: convertRawAmountToBalance(valueUnit, updatedAsset), from: internalTxn.address_from, hash: `${transaction.hash}-${index}`, - name: get(updatedAsset, 'name', ''), + name: updatedAsset.name, native: nativeDisplay, status, - symbol: get(updatedAsset, 'symbol', ''), + symbol: updatedAsset.symbol, to: internalTxn.address_to, }; }); From 7732fed9018b28275be1bb8708ef2a48fb22233e Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Sat, 30 Nov 2019 16:26:59 -0500 Subject: [PATCH 559/636] Add cDAI, fix alphabetization --- src/references/token-overrides.json | 28 ++++++++++++++++------------ src/references/uniswap-pairs.json | 18 ++++++++++++------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 3a8ce84d25e..6e22c4785bc 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -20,24 +20,16 @@ "0x107c4504cd79C5d2696Ea0030a8dD4e92601B82e": { "name": "Bloom" }, - "0x493c57c4763932315a328269e1adad09653b9081": { - "name": "Fulcrum Dai", - "symbol": "iDAI" - }, - "0x14094949152eddbfcd073717200da82fed8dc960": { - "name": "Fulcrum Sai", - "symbol": "iSAI" - }, - "0xf013406a0b1d544238083df0b93ad0d2cbe0f65f": { - "name": "Fulcrum USD Coin", - "symbol": "iUSDC" - }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { "name": "Chainlink" }, "0x41e5560054824eA6B0732E656E3Ad64E20e94E45": { "name": "Civic" }, + "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643": { + "name": "Compound Dai", + "symbol": "cDAI" + }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { "name": "Compound Sai", "symbol": "cSAI" @@ -67,6 +59,18 @@ "0x4946Fcea7C692606e8908002e55A582af44AC121": { "name": "FOAM" }, + "0x493c57c4763932315a328269e1adad09653b9081": { + "name": "Fulcrum Dai", + "symbol": "iDAI" + }, + "0x14094949152eddbfcd073717200da82fed8dc960": { + "name": "Fulcrum Sai", + "symbol": "iSAI" + }, + "0xf013406a0b1d544238083df0b93ad0d2cbe0f65f": { + "name": "Fulcrum USD Coin", + "symbol": "iUSDC" + }, "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b": { "name": "FunFair" }, diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index 65093f8e398..30a73ebf062 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -41,12 +41,6 @@ "decimals": 18, "exchangeAddress": "0x0E6A53B13688018A3df8C69f99aFB19A3068D04f" }, - "0x14094949152eddbfcd073717200da82fed8dc960": { - "name": "Fulcrum Sai", - "symbol": "iSAI", - "decimals": 18, - "exchangeAddress": "0x81eed7f1ecbd7fa9978fcc7584296fb0c215dc5c" - }, "0x514910771AF9Ca656af840dff83E8264EcF986CA": { "name": "Chainlink", "symbol": "LINK", @@ -59,6 +53,12 @@ "decimals": 8, "exchangeAddress": "0x1C6c712b1F4a7c263B1DBd8F97fb447c945d3b9a" }, + "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643": { + "name": "Compound Dai", + "symbol": "cDAI", + "decimals": 8, + "exchangeAddress": "0x34E89740adF97C3A9D3f63Cc2cE4a914382c230b" + }, "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC": { "name": "Compound Sai", "symbol": "cSAI", @@ -113,6 +113,12 @@ "decimals": 18, "exchangeAddress": "0xf79cb3BEA83BD502737586A6E8B133c378FD1fF2" }, + "0x14094949152eddbfcd073717200da82fed8dc960": { + "name": "Fulcrum Sai", + "symbol": "iSAI", + "decimals": 18, + "exchangeAddress": "0x81eed7f1ecbd7fa9978fcc7584296fb0c215dc5c" + }, "0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b": { "name": "FunFair", "symbol": "FUN", From c4dd4a55030d557f2d6bf96f554d7b1781499343 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Tue, 3 Dec 2019 16:24:43 -0500 Subject: [PATCH 560/636] Better styles for TransactionConfirmationScreen --- src/components/transaction/TransactionSheet.js | 2 +- src/navigation/transitions/effects.js | 2 +- src/screens/Routes.js | 4 ++-- src/screens/TransactionConfirmationScreen.js | 7 ++++--- src/styles/colors.js | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/transaction/TransactionSheet.js b/src/components/transaction/TransactionSheet.js index 34990829a7d..2252825a0ca 100644 --- a/src/components/transaction/TransactionSheet.js +++ b/src/components/transaction/TransactionSheet.js @@ -7,7 +7,7 @@ import Divider from '../Divider'; import { Column } from '../layout'; const Container = styled(Column).attrs({ justify: 'end' })` - ${borders.buildRadius('top', 15)} + ${borders.buildRadius('top', 20)} background-color: ${colors.white}; flex-grow: 0; padding-bottom: ${safeAreaInsetValues.bottom}; diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index a6b8b6ed8a9..e0a3d9416b3 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -61,7 +61,7 @@ const exchangeStyleInterpolator = ({ transform: [{ translateY }], }, containerStyle: { - backgroundColor: color(25, 25, 25, backgroundOpacity), + backgroundColor: color(20, 20, 20, backgroundOpacity), }, }; }; diff --git a/src/screens/Routes.js b/src/screens/Routes.js index 482d682c24a..15e15b03e8e 100644 --- a/src/screens/Routes.js +++ b/src/screens/Routes.js @@ -60,9 +60,9 @@ const MainNavigator = createStackNavigator( { ConfirmRequest: { navigationOptions: { - ...expandedPreset, + ...sheetPreset, onTransitionStart: props => { - expandedPreset.onTransitionStart(props); + sheetPreset.onTransitionStart(props); onTransitionStart(); }, }, diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 319cf7a3d1a..ecc7c65dd07 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -22,7 +22,7 @@ import { } from '../utils/signingMethods'; const CancelButtonContainer = styled.View` - bottom: 22; + bottom: 19; position: absolute; right: 19; `; @@ -169,9 +169,9 @@ export default class TransactionConfirmationScreen extends PureComponent { @@ -183,8 +183,9 @@ export default class TransactionConfirmationScreen extends PureComponent { diff --git a/src/styles/colors.js b/src/styles/colors.js index 3ad4683151a..14e2681684a 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; const base = { appleBlue: '#0E76FD', // 14, 118, 253 + backgroundGrey: '#141414', // 20, 20, 20 black: '#000000', // '0, 0, 0' blueGreyDark: '#3C4252', // '60, 66, 82' blueGreyDarker: '#0F0F11', // '15, 15, 17' From 78380663d734348d7f642ff2e81f2192596e7e60 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 3 Dec 2019 20:57:58 -0500 Subject: [PATCH 561/636] Revert "Merge pull request #252 from rainbow-me/@jin/send-remove-redux" This reverts commit c7c34037a84281dc022926940b6bcc1bd5d5efed, reversing changes made to c11eda2cdb9be1dfede643aad7abf39841c1e9c4. --- src/components/SendComponentWithData.js | 297 ++++++++++++++++++ src/components/fields/AddressField.js | 3 +- src/components/send/SendAssetForm.js | 7 +- src/hoc/withDataInit.js | 3 +- src/redux/gas.js | 4 +- src/redux/reducers.js | 2 + src/redux/send.js | 278 +++++++++++++++++ src/screens/ExchangeModal.js | 47 +++ src/screens/SendSheet.js | 192 +++++++++--- src/screens/SendSheetWithData.js | 394 +----------------------- 10 files changed, 792 insertions(+), 435 deletions(-) create mode 100644 src/components/SendComponentWithData.js create mode 100644 src/redux/send.js diff --git a/src/components/SendComponentWithData.js b/src/components/SendComponentWithData.js new file mode 100644 index 00000000000..b1e6e860db1 --- /dev/null +++ b/src/components/SendComponentWithData.js @@ -0,0 +1,297 @@ +import { get } from 'lodash'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { compose } from 'recompact'; +import { estimateGasLimit } from '../handlers/web3'; +import { greaterThan } from '../helpers/utilities'; +import { checkIsValidAddress } from '../helpers/validators'; +import { withAccountData, withGas, withUniqueTokens } from '../hoc'; +import lang from '../languages'; +import { + sendClearFields, + sendMaxBalance, + sendModalInit, + sendToggleConfirmationView, + sendTransaction, + sendUpdateAssetAmount, + sendUpdateNativeAmount, + sendUpdateRecipient, + sendUpdateSelected, +} from '../redux/send'; +import { ethereumUtils } from '../utils'; + +const mapStateToProps = ({ send, settings }) => ({ + accountType: settings.accountType, + address: send.address, + assetAmount: send.assetAmount, + confirm: send.confirm, + fetching: send.fetching, + isSufficientBalance: send.isSufficientBalance, + nativeAmount: send.nativeAmount, + nativeCurrency: settings.nativeCurrency, + network: settings.network, + recipient: send.recipient, + selected: send.selected, + txHash: send.txHash, +}); + +/** + * Create SendComponent connected to redux with actions for sending assets. + * @param {Component} SendComponent React component for sending. + * @param {Object} options + * {Function} options.sendTransactionCallback Function to be run after sendTransaction redux action. + * {String} options.defaultAsset Symbol for default asset to send. + * @return {Component} SendComponent connected to redux. + */ +export const withSendComponentWithData = (SendComponent, options) => { + class SendComponentWithData extends Component { + static propTypes = { + accountType: PropTypes.string, + address: PropTypes.string, + assetAmount: PropTypes.string.isRequired, + assets: PropTypes.array.isRequired, + confirm: PropTypes.bool.isRequired, + fetching: PropTypes.bool.isRequired, + gasLimit: PropTypes.number, + gasPrices: PropTypes.object.isRequired, + gasUpdateDefaultGasLimit: PropTypes.func.isRequired, + gasUpdateTxFee: PropTypes.func.isRequired, + isSufficientBalance: PropTypes.bool.isRequired, + isSufficientGas: PropTypes.bool.isRequired, + nativeAmount: PropTypes.string.isRequired, + nativeCurrency: PropTypes.string.isRequired, + network: PropTypes.string.isRequired, + recipient: PropTypes.string.isRequired, + selected: PropTypes.object.isRequired, + selectedGasPrice: PropTypes.shape({ txFee: PropTypes.object }), + selectedGasPriceOption: PropTypes.string.isRequired, + sendClearFields: PropTypes.func.isRequired, + sendMaxBalance: PropTypes.func.isRequired, + sendModalInit: PropTypes.func.isRequired, + sendToggleConfirmationView: PropTypes.func.isRequired, + sendTransaction: PropTypes.func.isRequired, + sendUpdateAssetAmount: PropTypes.func.isRequired, + sendUpdateNativeAmount: PropTypes.func.isRequired, + sendUpdateRecipient: PropTypes.func.isRequired, + sendUpdateSelected: PropTypes.func.isRequired, + txFees: PropTypes.object.isRequired, + txHash: PropTypes.string.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isValidAddress: false, + showQRCodeReader: false, + }; + + this.defaultAsset = options.defaultAsset; + this.gasFormat = options.gasFormat || 'long'; + this.sendTransactionCallback = + options.sendTransactionCallback || function noop() {}; + } + + componentDidMount() { + this.props.sendModalInit({ + defaultAsset: this.defaultAsset, + gasFormat: this.gasFormat, + }); + this.props.gasUpdateDefaultGasLimit(); + } + + async componentDidUpdate(prevProps) { + const { address, assetAmount, recipient, selected } = this.props; + + if (recipient !== prevProps.recipient) { + const validAddress = await checkIsValidAddress(recipient); + // eslint-disable-next-line react/no-did-update-set-state + this.setState({ isValidAddress: validAddress }); + } + + if (this.state.isValidAddress) { + if ( + selected.symbol !== prevProps.selected.symbol || + recipient !== prevProps.recipient || + assetAmount !== prevProps.assetAmount + ) { + estimateGasLimit({ + address, + amount: assetAmount, + asset: selected, + recipient, + }) + .then(gasLimit => { + this.props.gasUpdateTxFee(gasLimit); + }) + .catch(() => { + this.props.gasUpdateTxFee(); + }); + } + } + } + + onAddressInputFocus = async () => { + const { recipient } = this.props; + + const validAddress = await checkIsValidAddress(recipient); + this.setState({ isValidAddress: validAddress }); + }; + + onAddressInputBlur = async () => { + const { recipient } = this.props; + + const validAddress = await checkIsValidAddress(recipient); + this.setState({ isValidAddress: validAddress }); + }; + + onGoBack = () => this.props.sendToggleConfirmationView(false); + + onSendMaxBalance = () => this.props.sendMaxBalance(); + + onSendAnother = () => { + this.props.sendToggleConfirmationView(false); + this.props.sendClearFields(); + this.props.sendModalInit({ defaultAsset: this.defaultAsset }); + }; + + onSubmit = async event => { + if (event && typeof event.preventDefault === 'function') { + event.preventDefault(); + } + + if (!this.props.selectedGasPrice.txFee) { + return; + } + + // Balance checks + if (!this.props.confirm) { + const isAddressValid = await checkIsValidAddress(this.props.recipient); + if (!isAddressValid) { + console.log(lang.t('notification.error.invalid_address')); + return; + } + if (this.props.selected.address === 'eth') { + const { + requestedAmount, + balance, + amountWithFees, + } = ethereumUtils.transactionData( + this.props.assets, + this.props.assetAmount, + this.props.selectedGasPrice + ); + + if (greaterThan(requestedAmount, balance)) { + return; + } + if (greaterThan(amountWithFees, balance)) { + return; + } + } else if (!this.props.selected.isNft) { + const { + requestedAmount, + balance, + txFee, + } = ethereumUtils.transactionData( + this.props.assets, + this.props.assetAmount, + this.props.selectedGasPrice + ); + + const tokenBalance = get(this.props, 'selected.balance.amount'); + + if (greaterThan(requestedAmount, tokenBalance)) { + return; + } + if (greaterThan(txFee, balance)) { + return; + } + } + + this.props.sendToggleConfirmationView(true); + + return this.props.sendTransaction( + { + address: this.props.address, + amount: this.props.assetAmount, + asset: this.props.selected, + gasLimit: this.props.gasLimit, + gasPrice: this.props.selectedGasPrice, + recipient: this.props.recipient, + }, + this.sendTransactionCallback + ); + } + }; + + onClose = () => { + this.props.sendClearFields(); + }; + + // QR Code Reader Handlers + toggleQRCodeReader = () => + this.setState(prevState => ({ + showQRCodeReader: !prevState.showQRCodeReader, + })); + + onQRCodeValidate = async rawData => { + const data = rawData.match(/0x\w{40}/g) + ? rawData.match(/0x\w{40}/g)[0] + : null; + let result = false; + if (data) { + result = await checkIsValidAddress(data); + } + const onError = () => + console.log(lang.t('notification.error.invalid_address_scanned')); + return { data, onError, result }; + }; + + onQRCodeScan = data => { + this.props.sendUpdateRecipient(data); + this.setState({ showQRCodeReader: false }); + }; + + onQRCodeError = () => { + console.log(lang.t('notification.error.failed_scanning_qr_code')); + }; + + render() { + return ( + + ); + } + } + + return compose( + connect(mapStateToProps, { + sendClearFields, + sendMaxBalance, + sendModalInit, + sendToggleConfirmationView, + sendTransaction, + sendUpdateAssetAmount, + sendUpdateNativeAmount, + sendUpdateRecipient, + sendUpdateSelected, + }), + withGas, + withAccountData, + withUniqueTokens + )(SendComponentWithData); +}; diff --git a/src/components/fields/AddressField.js b/src/components/fields/AddressField.js index bc0346dfe56..7a99260c0b5 100644 --- a/src/components/fields/AddressField.js +++ b/src/components/fields/AddressField.js @@ -49,9 +49,8 @@ export default withNavigation( this.inputRef.focus() ); } - shouldComponentUpdate(nextProps, nextState) { - const isNewAddress = isNewValueForPath(nextProps, this.state, 'address'); + const isNewAddress = isNewValueForPath(this.props, this.state, 'address'); const isNewInputValue = isNewValueForPath( this.state, nextState, diff --git a/src/components/send/SendAssetForm.js b/src/components/send/SendAssetForm.js index 4250fff03aa..f994f7acb5f 100644 --- a/src/components/send/SendAssetForm.js +++ b/src/components/send/SendAssetForm.js @@ -39,7 +39,6 @@ const SendAssetForm = ({ buttonRenderer, onResetAssetSelection, selected, - sendMaxBalance, txSpeedRenderer, ...props }) => { @@ -70,11 +69,7 @@ const SendAssetForm = ({ {selected.isNft ? ( ) : ( - + )} }, clearAccountData: ownProps => async () => { web3ListenerClearState(); - gasClearState(); const p0 = ownProps.explorerClearState(); const p1 = ownProps.dataClearState(); const p2 = ownProps.clearIsWalletEmpty(); @@ -94,6 +93,7 @@ export default Component => const p6 = ownProps.nonceClearState(); const p7 = ownProps.requestsClearState(); const p8 = ownProps.uniswapClearState(); + const p9 = ownProps.gasClearState(); return promiseUtils.PromiseAllWithFails([ p0, p1, @@ -104,6 +104,7 @@ export default Component => p6, p7, p8, + p9, ]); }, initializeAccountData: ownProps => async () => { diff --git a/src/redux/gas.js b/src/redux/gas.js index f87b687bf43..bab930fa30b 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -177,7 +177,9 @@ const getSelectedGasPrice = ( }; }; -export const gasClearState = () => clearInterval(getGasPricesInterval); +export const gasClearState = () => () => { + clearInterval(getGasPricesInterval); +}; // -- Reducer --------------------------------------------------------------- // const INITIAL_STATE = { diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 6dc761475c6..28a57b1bb20 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -16,6 +16,7 @@ import openStateSettings from './openStateSettings'; import requests from './requests'; import selectedInput from './selectedInput'; import selectedWithFab from './selectedWithFab'; +import send from './send'; import settings from './settings'; import uniqueTokens from './uniqueTokens'; import uniswap from './uniswap'; @@ -38,6 +39,7 @@ export default combineReducers({ requests, selectedInput, selectedWithFab, + send, settings, uniqueTokens, uniswap, diff --git a/src/redux/send.js b/src/redux/send.js new file mode 100644 index 00000000000..6e534552e83 --- /dev/null +++ b/src/redux/send.js @@ -0,0 +1,278 @@ +import { get, isEmpty } from 'lodash'; +import { + convertAmountAndPriceToNativeDisplay, + convertAmountFromNativeValue, + formatInputDecimals, +} from '../helpers/utilities'; +import { createSignableTransaction } from '../handlers/web3'; +import { ethereumUtils } from '../utils'; +import { dataAddNewTransaction } from './data'; + +// -- Constants ------------------------------------------------------------- // + +const SEND_MODAL_INIT = 'send/SEND_MODAL_INIT'; + +const SEND_TRANSACTION_REQUEST = 'send/SEND_TRANSACTION_REQUEST'; +const SEND_TRANSACTION_SUCCESS = 'send/SEND_TRANSACTION_SUCCESS'; +const SEND_TRANSACTION_FAILURE = 'send/SEND_TRANSACTION_FAILURE'; + +const SEND_TOGGLE_CONFIRMATION_VIEW = 'send/SEND_TOGGLE_CONFIRMATION_VIEW'; + +const SEND_UPDATE_NATIVE_AMOUNT = 'send/SEND_UPDATE_NATIVE_AMOUNT'; + +const SEND_UPDATE_RECIPIENT = 'send/SEND_UPDATE_RECIPIENT'; +const SEND_UPDATE_ASSET_AMOUNT = 'send/SEND_UPDATE_ASSET_AMOUNT'; +const SEND_UPDATE_SELECTED = 'send/SEND_UPDATE_SELECTED'; +const SEND_UPDATE_NFT_SELECTED = 'send/SEND_UPDATE_NFT_SELECTED'; + +const SEND_CLEAR_FIELDS = 'send/SEND_CLEAR_FIELDS'; + +// -- Actions --------------------------------------------------------------- // + +export const sendModalInit = (options = {}) => (dispatch, getState) => { + const { accountAddress } = getState().settings; + const { assets } = getState().data; + const selected = + assets.filter(asset => asset.address === options.defaultAsset)[0] || {}; + dispatch({ + payload: { + address: accountAddress, + selected, + }, + type: SEND_MODAL_INIT, + }); +}; + +export const sendTransaction = ( + transactionDetails, + signAndSendTransactionCb +) => (dispatch, getState) => + new Promise((resolve, reject) => { + dispatch({ type: SEND_TRANSACTION_REQUEST }); + const { + address, + recipient, + amount, + asset, + gasPrice, + gasLimit, + } = transactionDetails; + const { accountType } = getState().settings; + const txDetails = { + amount, + asset, + from: address, + gasLimit, + gasPrice: gasPrice.value.amount, + nonce: null, + to: recipient, + }; + return createSignableTransaction(txDetails) + .then(signableTransactionDetails => { + signAndSendTransactionCb({ + accountType, + transaction: signableTransactionDetails, + }) + .then(txHash => { + if (!isEmpty(txHash)) { + txDetails.hash = txHash; + dispatch(dataAddNewTransaction(txDetails)) + .then(() => { + dispatch({ + payload: txHash, + type: SEND_TRANSACTION_SUCCESS, + }); + resolve(txHash); + }) + .catch(error => { + reject(error); + }); + } else { + dispatch({ type: SEND_TRANSACTION_FAILURE }); + reject(new Error('No transaction hash.')); + } + }) + .catch(error => { + dispatch({ type: SEND_TRANSACTION_FAILURE }); + reject(error); + }); + }) + .catch(error => { + dispatch({ type: SEND_TRANSACTION_FAILURE }); + reject(error); + }); + }); + +export const sendToggleConfirmationView = boolean => (dispatch, getState) => { + let confirm = boolean; + if (!confirm) { + confirm = !getState().send.confirm; + } + dispatch({ + payload: confirm, + type: SEND_TOGGLE_CONFIRMATION_VIEW, + }); +}; + +export const sendUpdateRecipient = recipient => dispatch => + dispatch({ + payload: recipient, + type: SEND_UPDATE_RECIPIENT, + }); + +export const sendUpdateAssetAmount = assetAmount => (dispatch, getState) => { + const { nativeCurrency } = getState().settings; + const { selected } = getState().send; + const { selectedGasPrice } = getState().gas; + const _assetAmount = assetAmount.replace(/[^0-9.]/g, ''); + let _nativeAmount = ''; + if (_assetAmount.length) { + const priceUnit = get(selected, 'price.value', 0); + const { amount: nativeAmount } = convertAmountAndPriceToNativeDisplay( + _assetAmount, + priceUnit, + nativeCurrency + ); + _nativeAmount = formatInputDecimals(nativeAmount, _assetAmount); + } + const balanceAmount = ethereumUtils.getBalanceAmount( + selectedGasPrice, + selected + ); + dispatch({ + payload: { + assetAmount: _assetAmount, + isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), + nativeAmount: _nativeAmount, + }, + type: SEND_UPDATE_ASSET_AMOUNT, + }); +}; + +export const sendUpdateNativeAmount = nativeAmount => (dispatch, getState) => { + const { selected } = getState().send; + const { selectedGasPrice } = getState().gas; + const _nativeAmount = nativeAmount.replace(/[^0-9.]/g, ''); + let _assetAmount = ''; + if (_nativeAmount.length) { + const priceUnit = get(selected, 'price.value', 0); + const assetAmount = convertAmountFromNativeValue( + _nativeAmount, + priceUnit, + selected.decimals + ); + _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); + } + + const balanceAmount = ethereumUtils.getBalanceAmount( + selectedGasPrice, + selected + ); + + dispatch({ + payload: { + assetAmount: _assetAmount, + isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), + nativeAmount: _nativeAmount, + }, + type: SEND_UPDATE_ASSET_AMOUNT, + }); +}; + +export const sendUpdateSelected = asset => (dispatch, getState) => { + if (get(asset, 'isNft')) { + dispatch({ + payload: { + selected: { + ...asset, + symbol: asset.asset_contract.name, + }, + }, + type: SEND_UPDATE_NFT_SELECTED, + }); + } else { + const state = getState(); + const assetAmount = get(state, 'send.assetAmount'); + dispatch({ + payload: asset, + type: SEND_UPDATE_SELECTED, + }); + dispatch(sendUpdateAssetAmount(assetAmount)); + } +}; + +export const sendMaxBalance = () => (dispatch, getState) => { + const { selected } = getState().send; + const { selectedGasPrice } = getState().gas; + const balanceAmount = ethereumUtils.getBalanceAmount( + selectedGasPrice, + selected + ); + dispatch(sendUpdateAssetAmount(balanceAmount)); +}; + +export const sendClearFields = () => ({ type: SEND_CLEAR_FIELDS }); + +// -- Reducer --------------------------------------------------------------- // +const INITIAL_STATE = { + address: '', + assetAmount: '', + confirm: false, + fetching: false, + isSufficientBalance: false, + nativeAmount: '', + recipient: '', + selected: {}, + txHash: '', +}; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case SEND_MODAL_INIT: + return { + ...state, + address: action.payload.address, + selected: action.payload.selected, + }; + case SEND_TRANSACTION_REQUEST: + return { ...state, fetching: true }; + case SEND_TRANSACTION_SUCCESS: + return { + ...state, + fetching: false, + txHash: action.payload, + }; + case SEND_TRANSACTION_FAILURE: + return { + ...state, + confirm: false, + fetching: false, + txHash: '', + }; + case SEND_TOGGLE_CONFIRMATION_VIEW: + return { ...state, confirm: action.payload }; + case SEND_UPDATE_RECIPIENT: + return { ...state, recipient: action.payload }; + case SEND_UPDATE_NATIVE_AMOUNT: + case SEND_UPDATE_ASSET_AMOUNT: + return { + ...state, + assetAmount: action.payload.assetAmount, + isSufficientBalance: action.payload.isSufficientBalance, + nativeAmount: action.payload.nativeAmount, + }; + case SEND_UPDATE_SELECTED: + return { ...state, selected: action.payload }; + case SEND_UPDATE_NFT_SELECTED: + return { + ...state, + assetAmount: '1', + isSufficientBalance: true, + selected: action.payload.selected, + }; + case SEND_CLEAR_FIELDS: + return { ...state, ...INITIAL_STATE }; + default: + return state; + } +}; diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 90daa3eb2b9..7ab49aba792 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -7,6 +7,7 @@ import { tradeTokensForExactEthWithData, tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; +import BigNumber from 'bignumber.js'; import { get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; @@ -34,6 +35,7 @@ import { estimateSwapGasLimit, executeSwap } from '../handlers/uniswap'; import { convertAmountFromNativeValue, convertAmountToNativeAmount, + convertAmountToNativeDisplay, convertAmountToRawAmount, convertNumberToString, convertRawAmountToDecimalFormat, @@ -111,6 +113,8 @@ class ExchangeModal extends Component { inputAmountDisplay: null, inputAsExactAmount: false, inputCurrency: ethereumUtils.getAsset(this.props.allAssets), + inputExecutionRate: null, + inputNativePrice: null, isAssetApproved: true, isAuthorizing: false, isSufficientBalance: true, @@ -119,6 +123,8 @@ class ExchangeModal extends Component { outputAmount: null, outputAmountDisplay: null, outputCurrency: null, + outputExecutionRate: null, + outputNativePrice: null, showConfirmButton: false, slippage: null, tradeDetails: null, @@ -330,6 +336,7 @@ class ExchangeModal extends Component { chainId, gasUpdateTxFee, inputReserve, + nativeCurrency, outputReserve, selectedGasPrice, } = this.props; @@ -413,6 +420,38 @@ class ExchangeModal extends Component { ); } + let inputExecutionRate = ''; + let outputExecutionRate = ''; + let inputNativePrice = ''; + let outputNativePrice = ''; + + if (inputCurrency) { + const inputPriceValue = get(inputCurrency, 'price.value', 0); + inputExecutionRate = updatePrecisionToDisplay( + get(tradeDetails, 'executionRate.rate', BigNumber(0)), + inputPriceValue + ); + + inputNativePrice = convertAmountToNativeDisplay( + inputPriceValue, + nativeCurrency + ); + } + + if (outputCurrency) { + const outputPriceValue = get(outputCurrency, 'price.value', 0); + outputExecutionRate = updatePrecisionToDisplay( + get(tradeDetails, 'executionRate.rateInverted', BigNumber(0)), + outputPriceValue, + true + ); + + outputNativePrice = convertAmountToNativeDisplay( + outputPriceValue, + nativeCurrency + ); + } + const slippage = convertNumberToString( get(tradeDetails, 'executionRateSlippage', 0) ); @@ -426,7 +465,11 @@ class ExchangeModal extends Component { parseFloat(inputBalance) >= parseFloat(inputAmount); this.setState({ + inputExecutionRate, + inputNativePrice, isSufficientBalance, + outputExecutionRate, + outputNativePrice, slippage, tradeDetails, }); @@ -768,6 +811,8 @@ class ExchangeModal extends Component { inputAmount, inputAmountDisplay, inputCurrency, + // inputExecutionRate, + // inputNativePrice, isAssetApproved, isAuthorizing, isSufficientBalance, @@ -776,6 +821,8 @@ class ExchangeModal extends Component { outputAmount, outputAmountDisplay, outputCurrency, + // outputExecutionRate, + // outputNativePrice, showConfirmButton, slippage, } = this.state; diff --git a/src/screens/SendSheet.js b/src/screens/SendSheet.js index 4d9afa03cdd..11305645f7d 100644 --- a/src/screens/SendSheet.js +++ b/src/screens/SendSheet.js @@ -1,8 +1,10 @@ -import { isEmpty } from 'lodash'; +import analytics from '@segment/analytics-react-native'; +import { get, isEmpty, isString, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { Keyboard, KeyboardAvoidingView } from 'react-native'; import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper'; +import { compose, withHandlers, withProps } from 'recompact'; import styled from 'styled-components/primitives'; import { Column } from '../components/layout'; import { @@ -13,8 +15,16 @@ import { SendHeader, SendTransactionSpeed, } from '../components/send'; +import { + withAccountData, + withAccountSettings, + withContacts, + withDataInit, + withTransitionProps, + withUniqueTokens, +} from '../hoc'; import { borders, colors } from '../styles'; -import { deviceUtils, isNewValueForPath } from '../utils'; +import { deviceUtils, gasUtils, isNewValueForPath } from '../utils'; const statusBarHeight = getStatusBarHeight(true); @@ -30,41 +40,70 @@ const SheetContainer = styled(Column)` top: ${statusBarHeight}; `; -export default class SendSheet extends Component { +class SendSheet extends Component { static propTypes = { allAssets: PropTypes.array, assetAmount: PropTypes.string, contacts: PropTypes.object, - currentInput: PropTypes.string, fetchData: PropTypes.func, gasPrices: PropTypes.object, - isAuthorizing: PropTypes.bool, + gasUpdateGasPriceOption: PropTypes.func, isSufficientBalance: PropTypes.bool, isSufficientGas: PropTypes.bool, isValidAddress: PropTypes.bool, nativeCurrencySymbol: PropTypes.string, navigation: PropTypes.object, - onChangeAssetAmount: PropTypes.func, - onChangeInput: PropTypes.func, - onChangeNativeAmount: PropTypes.func, - onLongPressSend: PropTypes.func, - onPressTransactionSpeed: PropTypes.func, - onResetAssetSelection: PropTypes.func, - onSelectAsset: PropTypes.func, + onSubmit: PropTypes.func, recipient: PropTypes.string, removeContact: PropTypes.func, selected: PropTypes.object, selectedGasPrice: PropTypes.object, sendableUniqueTokens: PropTypes.arrayOf(PropTypes.object), + sendClearFields: PropTypes.func, sendMaxBalance: PropTypes.func, + sendUpdateAssetAmount: PropTypes.func, + sendUpdateNativeAmount: PropTypes.func, sendUpdateRecipient: PropTypes.func, + sendUpdateSelected: PropTypes.func, sortedContacts: PropTypes.array, }; + static defaultProps = { + isSufficientBalance: false, + isSufficientGas: false, + isValidAddress: false, + }; + + state = { + currentInput: '', + isAuthorizing: false, + }; + + componentDidMount = async () => { + const { navigation, sendUpdateRecipient } = this.props; + const address = get(navigation, 'state.params.address'); + + if (address) { + sendUpdateRecipient(address); + } + }; + componentDidUpdate(prevProps) { - const { contacts, isValidAddress, navigation, selected } = this.props; + const { + contacts, + isValidAddress, + navigation, + selected, + sendUpdateSelected, + } = this.props; + + const asset = get(navigation, 'state.params.asset'); if (isValidAddress && !prevProps.isValidAddress) { + if (asset) { + sendUpdateSelected(asset); + } + Keyboard.dismiss(); } @@ -97,29 +136,95 @@ export default class SendSheet extends Component { } } + componentWillUnmount() { + this.props.sendClearFields(); + } + + onChangeAssetAmount = assetAmount => { + if (isString(assetAmount)) { + this.props.sendUpdateAssetAmount(assetAmount); + analytics.track('Changed token input in Send flow'); + } + }; + + onChangeNativeAmount = nativeAmount => { + if (isString(nativeAmount)) { + this.props.sendUpdateNativeAmount(nativeAmount); + analytics.track('Changed native currency input in Send flow'); + } + }; + + onLongPressSend = () => { + this.setState({ isAuthorizing: true }); + + if (isIphoneX()) { + this.sendTransaction(); + } else { + this.onPressTransactionSpeed(this.sendTransaction); + } + }; + + onPressTransactionSpeed = onSuccess => { + const { gasPrices, gasUpdateGasPriceOption, txFees } = this.props; + gasUtils.showTransactionSpeedOptions( + gasPrices, + txFees, + gasUpdateGasPriceOption, + onSuccess + ); + }; + + onResetAssetSelection = () => { + analytics.track('Reset asset selection in Send flow'); + this.props.sendUpdateSelected({}); + }; + + onSelectAsset = asset => this.props.sendUpdateSelected(asset); + + sendTransaction = () => { + const { + assetAmount, + navigation, + onSubmit, + recipient, + selected, + sendClearFields, + } = this.props; + + if (Number(assetAmount) <= 0) return false; + + return onSubmit() + .then(() => { + this.setState({ isAuthorizing: false }); + analytics.track('Sent transaction', { + assetName: selected.name, + assetType: selected.isNft ? 'unique_token' : 'token', + isRecepientENS: toLower(recipient.slice(-4)) === '.eth', + }); + sendClearFields(); + navigation.navigate('ProfileScreen'); + }) + .catch(() => { + this.setState({ isAuthorizing: false }); + }); + }; + + onChangeInput = event => { + this.setState({ currentInput: event }); + this.props.sendUpdateRecipient(event); + }; + render() { const { allAssets, contacts, - currentInput, fetchData, - isAuthorizing, - isSufficientBalance, - isSufficientGas, isValidAddress, nativeCurrencySymbol, - onChangeAssetAmount, - onChangeInput, - onChangeNativeAmount, - onLongPressSend, - onPressTransactionSpeed, - onResetAssetSelection, - onSelectAsset, recipient, removeContact, selected, selectedGasPrice, - sendMaxBalance, sendableUniqueTokens, sendUpdateRecipient, sortedContacts, @@ -135,8 +240,9 @@ export default class SendSheet extends Component { @@ -153,7 +259,7 @@ export default class SendSheet extends Component { )} @@ -164,23 +270,20 @@ export default class SendSheet extends Component { buttonRenderer={ } - onChangeAssetAmount={onChangeAssetAmount} - onChangeNativeAmount={onChangeNativeAmount} - onResetAssetSelection={onResetAssetSelection} + onChangeAssetAmount={this.onChangeAssetAmount} + onChangeNativeAmount={this.onChangeNativeAmount} + onResetAssetSelection={this.onResetAssetSelection} selected={selected} - sendMaxBalance={sendMaxBalance} txSpeedRenderer={ isIphoneX() && ( ) } @@ -192,3 +295,18 @@ export default class SendSheet extends Component { ); } } + +export default compose( + withAccountData, + withContacts, + withUniqueTokens, + withAccountSettings, + withDataInit, + withTransitionProps, + withProps(({ transitionProps: { isTransitioning } }) => ({ + isTransitioning, + })), + withHandlers({ + fetchData: ({ refreshAccountData }) => async () => refreshAccountData(), + }) +)(SendSheet); diff --git a/src/screens/SendSheetWithData.js b/src/screens/SendSheetWithData.js index 7aa66f0418c..3e8d7a77d6b 100644 --- a/src/screens/SendSheetWithData.js +++ b/src/screens/SendSheetWithData.js @@ -1,378 +1,11 @@ -import analytics from '@segment/analytics-react-native'; -import { get, isEmpty, isString, toLower } from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { isIphoneX } from 'react-native-iphone-x-helper'; -import { compose, withHandlers, withProps } from 'recompact'; -import { createSignableTransaction, estimateGasLimit } from '../handlers/web3'; -import { - convertAmountAndPriceToNativeDisplay, - convertAmountFromNativeValue, - formatInputDecimals, - greaterThan, -} from '../helpers/utilities'; -import { checkIsValidAddress } from '../helpers/validators'; -import { - withAccountData, - withAccountSettings, - withContacts, - withDataInit, - withGas, - withTransactionConfirmationScreen, - withTransitionProps, - withUniqueTokens, -} from '../hoc'; -import lang from '../languages'; +import { withSendComponentWithData } from '../components/SendComponentWithData'; import { sendTransaction } from '../model/wallet'; -import { ethereumUtils, gasUtils, isNewValueForPath } from '../utils'; import SendSheet from './SendSheet'; -class SendSheetWithData extends Component { - static propTypes = { - accountAddress: PropTypes.string, - assets: PropTypes.array.isRequired, - dataAddNewTransaction: PropTypes.func, - gasLimit: PropTypes.number, - gasPrices: PropTypes.object.isRequired, - gasUpdateDefaultGasLimit: PropTypes.func.isRequired, - gasUpdateTxFee: PropTypes.func.isRequired, - isSufficientGas: PropTypes.bool.isRequired, - nativeCurrency: PropTypes.string.isRequired, - network: PropTypes.string.isRequired, - selectedGasPrice: PropTypes.shape({ txFee: PropTypes.object }), - selectedGasPriceOption: PropTypes.string.isRequired, - txFees: PropTypes.object.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - assetAmount: '', - confirm: false, - contacts: [], - currentInput: '', - isAuthorizing: false, - isSufficientBalance: false, - isValidAddress: false, - nativeAmount: '', - recipient: '', - selected: {}, - }; - } - - componentDidMount() { - this.props.gasUpdateDefaultGasLimit(); - } - - async componentDidUpdate(prevProps, prevState) { - const { accountAddress, navigation } = this.props; - const { assetAmount, isValidAddress, recipient, selected } = this.state; - - const assetOverride = get(navigation, 'state.params.asset'); - const recipientOverride = get(navigation, 'state.params.address'); - - if (recipientOverride && !this.state.recipient) { - this.sendUpdateRecipient(recipientOverride); - } - - if (isValidAddress && !prevState.isValidAddress) { - if (assetOverride) { - this.sendUpdateSelected(assetOverride); - } - } - - const isNewRecipient = isNewValueForPath( - this.state, - prevState, - 'recipient' - ); - if (isNewRecipient) { - const validAddress = await checkIsValidAddress(recipient); - // eslint-disable-next-line react/no-did-update-set-state - this.setState({ isValidAddress: validAddress }); - } - - if (isValidAddress) { - if ( - selected.symbol !== prevState.selected.symbol || - recipient !== prevState.recipient || - assetAmount !== prevState.assetAmount - ) { - estimateGasLimit({ - address: accountAddress, - amount: assetAmount, - asset: selected, - recipient, - }) - .then(gasLimit => { - this.props.gasUpdateTxFee(gasLimit); - }) - .catch(() => { - this.props.gasUpdateTxFee(null); - }); - } - } - } - - sendUpdateAssetAmount = assetAmount => { - const { nativeCurrency, selectedGasPrice } = this.props; - const { selected } = this.state; - const _assetAmount = assetAmount.replace(/[^0-9.]/g, ''); - let _nativeAmount = ''; - if (_assetAmount.length) { - const priceUnit = get(selected, 'price.value', 0); - const { amount: nativeAmount } = convertAmountAndPriceToNativeDisplay( - _assetAmount, - priceUnit, - nativeCurrency - ); - _nativeAmount = formatInputDecimals(nativeAmount, _assetAmount); - } - const balanceAmount = ethereumUtils.getBalanceAmount( - selectedGasPrice, - selected - ); - this.setState({ - assetAmount: _assetAmount, - isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), - nativeAmount: _nativeAmount, - }); - }; - - onChangeNativeAmount = nativeAmount => { - if (!isString(nativeAmount)) return; - const { selected } = this.state; - const { selectedGasPrice } = this.props; - const _nativeAmount = nativeAmount.replace(/[^0-9.]/g, ''); - let _assetAmount = ''; - if (_nativeAmount.length) { - const priceUnit = get(selected, 'price.value', 0); - const assetAmount = convertAmountFromNativeValue( - _nativeAmount, - priceUnit, - selected.decimals - ); - _assetAmount = formatInputDecimals(assetAmount, _nativeAmount); - } - - const balanceAmount = ethereumUtils.getBalanceAmount( - selectedGasPrice, - selected - ); - - this.setState({ - assetAmount: _assetAmount, - isSufficientBalance: Number(_assetAmount) <= Number(balanceAmount), - nativeAmount: _nativeAmount, - }); - analytics.track('Changed native currency input in Send flow'); - }; - - sendMaxBalance = () => { - const balanceAmount = ethereumUtils.getBalanceAmount( - this.props.selectedGasPrice, - this.state.selected - ); - this.sendUpdateAssetAmount(balanceAmount); - }; - - onChangeAssetAmount = assetAmount => { - if (isString(assetAmount)) { - this.sendUpdateAssetAmount(assetAmount); - analytics.track('Changed token input in Send flow'); - } - }; - - onLongPressSend = () => { - this.setState({ isAuthorizing: true }); - - if (isIphoneX()) { - this.submitTransaction(); - } else { - this.onPressTransactionSpeed(this.submitTransaction); - } - }; - - onPressTransactionSpeed = onSuccess => { - const { gasPrices, gasUpdateGasPriceOption, txFees } = this.props; - gasUtils.showTransactionSpeedOptions( - gasPrices, - txFees, - gasUpdateGasPriceOption, - onSuccess - ); - }; - - onResetAssetSelection = () => { - analytics.track('Reset asset selection in Send flow'); - this.sendUpdateSelected({}); - }; - - submitTransaction = async () => { - const { navigation } = this.props; - const { assetAmount, recipient, selected } = this.state; - - if (Number(assetAmount) <= 0) return false; - - try { - await this.onSubmit(); - this.setState({ isAuthorizing: false }); - analytics.track('Sent transaction', { - assetName: selected.name, - assetType: selected.isNft ? 'unique_token' : 'token', - isRecepientENS: toLower(recipient.slice(-4)) === '.eth', - }); - navigation.navigate('ProfileScreen'); - } catch { - this.setState({ isAuthorizing: false }); - } - }; - - onChangeInput = event => - this.setState({ currentInput: event, recipient: event }); - - sendUpdateRecipient = recipient => this.setState({ recipient }); - - sendUpdateSelected = selected => { - if (get(selected, 'isNft')) { - this.setState({ - assetAmount: '1', - isSufficientBalance: true, - selected: { - ...selected, - symbol: get(selected, 'asset_contract.name'), - }, - }); - } else { - const assetAmount = this.state.assetAmount; - this.setState({ selected }); - this.sendUpdateAssetAmount(assetAmount); - } - }; - - onSubmit = async () => { - const { - accountAddress, - assets, - dataAddNewTransaction, - gasLimit, - selectedGasPrice, - } = this.props; - const { assetAmount, confirm, recipient, selected } = this.state; - if (!selectedGasPrice.txFee) { - return; - } - - // Balance checks - if (!confirm) { - const isAddressValid = await checkIsValidAddress(recipient); - if (!isAddressValid) { - console.log(lang.t('notification.error.invalid_address')); - return; - } - if (selected.address === 'eth') { - const { - requestedAmount, - balance, - amountWithFees, - } = ethereumUtils.transactionData( - assets, - assetAmount, - selectedGasPrice - ); - - if (greaterThan(requestedAmount, balance)) { - return; - } - if (greaterThan(amountWithFees, balance)) { - return; - } - } else if (!selected.isNft) { - const { - requestedAmount, - balance, - txFee, - } = ethereumUtils.transactionData( - assets, - assetAmount, - selectedGasPrice - ); - - const tokenBalance = get(selected, 'balance.amount'); - - if (greaterThan(requestedAmount, tokenBalance)) { - return; - } - if (greaterThan(txFee, balance)) { - return; - } - } - - this.setState({ confirm: true }); - - const txDetails = { - amount: assetAmount, - asset: selected, - from: accountAddress, - gasLimit, - gasPrice: get(selectedGasPrice, 'value.amount'), - nonce: null, - to: recipient, - }; - try { - const signableTransaction = await createSignableTransaction(txDetails); - const txHash = sendTransaction({ - transaction: signableTransaction, - }); - if (!isEmpty(txHash)) { - txDetails.hash = txHash; - await dataAddNewTransaction(txDetails); - } - // eslint-disable-next-line no-empty - } catch (error) {} - } - }; - - render() { - const { - assetAmount, - contacts, - currentInput, - isAuthorizing, - isSufficientBalance, - isSufficientGas, - isValidAddress, - nativeAmount, - recipient, - selected, - } = this.state; - return ( - - ); - } -} +const SendSheetWithData = withSendComponentWithData(SendSheet, { + gasFormat: 'short', + sendTransactionCallback: sendTransaction, +}); SendSheetWithData.navigationOptions = ({ navigation: { @@ -384,19 +17,4 @@ SendSheetWithData.navigationOptions = ({ }, }); -export default compose( - withAccountData, - withAccountSettings, - withContacts, - withDataInit, - withGas, - withUniqueTokens, - withTransactionConfirmationScreen, - withTransitionProps, - withProps(({ transitionProps: { isTransitioning } }) => ({ - isTransitioning, - })), - withHandlers({ - fetchData: ({ refreshAccountData }) => async () => refreshAccountData(), - }) -)(SendSheetWithData); +export default SendSheetWithData; From d9d29004a7896a3c6b64286afc046bb17ae49056 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 3 Dec 2019 23:21:33 -0500 Subject: [PATCH 562/636] update coin icons to latest --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 2803d15cc52..6118e0b6427 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "punycode": "^1.4.1", "querystring-es3": "^0.2.1", "react": "16.11.0", - "react-coin-icon": "0.1.12", + "react-coin-icon": "0.1.13", "react-fast-compare": "^2.0.4", "react-native": "facebook/react-native", "react-native-actionsheet": "^2.4.2", diff --git a/yarn.lock b/yarn.lock index 1bb4bdedd6d..13340e6f04a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5203,7 +5203,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^2.3.1: +hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: version "2.5.5" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== @@ -9133,10 +9133,10 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-coin-icon@0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.12.tgz#27468537670ef374506f95e0e30d340e49ef1c8c" - integrity sha512-EkF3r35Si9cevjXyQcDJFkw1zK2h9ctSV5NiFyucdMsZLdd9DefnR2ji8BKVg/X0bOKsrRXhqa7b15SsXImLOw== +react-coin-icon@0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.13.tgz#0eb148637a7714f3b74a493b71de0bba34353634" + integrity sha512-j+6r6EcXbTbdlpJCf8DvBAvl44mXXFCdrNh5Bj9P3y4KON2brMXpNrkrN1ixrx7y87F+n55K++DERoM3XqdbJg== dependencies: "@svgr/cli" "^4.3.0" lodash "^4.17.11" From 1d068c9957d347d4dfb698d07e8d7d2116058713 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 3 Dec 2019 23:23:39 -0500 Subject: [PATCH 563/636] remove wck from uniswap pairs --- src/references/uniswap-pairs.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index abcc91d0852..ea251f5bfdf 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -323,12 +323,6 @@ "decimals": 8, "exchangeAddress": "0x4d2f5cFbA55AE412221182D8475bC85799A5644b" }, - "0x09fE5f0236F0Ea5D930197DCE254d77B04128075": { - "name": "Wrapped CryptoKitties", - "symbol": "WCK", - "decimals": 18, - "exchangeAddress": "0x4FF7Fa493559c40aBd6D157a0bfC35Df68d8D0aC" - }, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": { "name": "Wrapped Ether", "symbol": "WETH", From e2941965dcd4aaa2bfb971229cf1e641cfd70c31 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 3 Dec 2019 23:52:03 -0500 Subject: [PATCH 564/636] update patch for react-native-tooltip to be compat with latest facebook/react-native#master --- ios/Podfile.lock | 44 +++++++++++------------ patches/react-native-tooltip+5.2.1.patch | 46 +++++++++++++++++++----- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c9e6881d561..c254a601f91 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -636,8 +636,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 59b799add22f437873e4ac6ef8cf1f9dc00c1644 - FBReactNativeSpec: 2561c346427810549ab5347b476cba6d99f05aaa + FBLazyVector: 91845057a416f016ac2f7370c69cffef34d32ba1 + FBReactNativeSpec: 8993361dfa53ee1098b670aaa2254b49b3a02bdc Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -653,15 +653,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 50c304666e9012acb6c9809a61a7c3c615abe65f - RCTTypeSafety: 5ac012965e3f7a745d896c57452c341cfb3b33ff - React: 96873e225a870636257547d6c40a0c1c50397052 - React-Core: 90c991c695db7ad09c903011287df52de07a5578 - React-CoreModules: f509f23c91d1d1a19c38a58a98c91cb2092285ad - React-cxxreact: c6198d59a214fefcac17e6e82a66d62fbebff4e3 - React-jsi: 1826ee9c2b26dba98337629ada547dee318abf68 - React-jsiexecutor: 1167640ba4658c7cc77cbf3ec968020aeeccff7b - React-jsinspector: 26a53d756cf60137d7f4eaee8a99c1e043526194 + RCTRequired: da9e407cb3043741e368a3da5e13cf82dcdd1b8e + RCTTypeSafety: b99208dda7883aa616ebeb0b8aeacb06a30f04c6 + React: 1850042a2b60f998c480261cf792bfe1c56df502 + React-Core: bb0225d151ea02e04a1e371c091ba6ee106e21ec + React-CoreModules: 5a40f4bb1ba75d478697b4be33492d5551905f7a + React-cxxreact: af7a7e4697ee63cd113e36f07480f30a5792917a + React-jsi: 54de809e314b32f2608e941930183adcf6594f6e + React-jsiexecutor: c0882b2387a70342c8580178595d173c9834b107 + React-jsinspector: 05cde31e8a387fa370e89c6cf096a16259e79186 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -672,16 +672,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 4cf9f1b716ff1a8b4081bb415e0b237a94d64e60 - React-RCTAnimation: 43b606950fd04d44bfb7caf3a96ae2aa4c62379e - React-RCTBlob: 5a81e0f5fcd1cdfffacf5c3bd71214437052f115 - React-RCTImage: bca61144ffac4f20423149ec0ed8674902bb08af - React-RCTLinking: e8bddd2993113a561b723d797f2b266d99655a4e - React-RCTNetwork: 1300b2a7e6ab359bb5ae4324b09285f9e32ce6b4 - React-RCTSettings: 3c5754c531ccf2aec6c34218eb2d1f8d7eaa0ecd - React-RCTText: 07cb60332845e0935a7cdf06bf425f225f6fe6ef - React-RCTVibration: eeda0047ef97e876f422495473257849a49725db - ReactCommon: 574f41c8c99208bb1903b3b048eca848b66d5b62 + React-RCTActionSheet: 3de31fadcc254f2a7f73da7b907c8c49329c8472 + React-RCTAnimation: c364cccab211ff7a70233feb11459036e44e74a5 + React-RCTBlob: 9f1294198274f1e56931db28a151c300cd7c0f97 + React-RCTImage: 14ba178f323db85c9c27adc288b5cf4f8cbb705a + React-RCTLinking: 4db54d206599304cc920be35c27c35ba6e8300ed + React-RCTNetwork: 71c142ffbff34628d159ea7a35fe1f6ec217dbb5 + React-RCTSettings: afaf3eb68ea3a12dc6542e830d04800f5397ca46 + React-RCTText: 658592bc4e0965724a529bf4bfa194a2415461fb + React-RCTVibration: 9bbbb0c16c3b8ff4ed8a06fc0578a6530ca6dcfe + ReactCommon: cd4c368a02c2cbca72acc8323b352676196b32a7 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -706,7 +706,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: faa53cd47c609ef1321b84b45d4f8244ad196a08 + Yoga: 4d2b9eb1e1f3aba25837e46104154741f9e250cd PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 diff --git a/patches/react-native-tooltip+5.2.1.patch b/patches/react-native-tooltip+5.2.1.patch index 4fd415b0e94..8426b6bbb0a 100644 --- a/patches/react-native-tooltip+5.2.1.patch +++ b/patches/react-native-tooltip+5.2.1.patch @@ -1,13 +1,43 @@ diff --git a/node_modules/react-native-tooltip/ToolTip.ios.js b/node_modules/react-native-tooltip/ToolTip.ios.js -index c6754e2..021a675 100644 +index c6754e2..997d584 100644 --- a/node_modules/react-native-tooltip/ToolTip.ios.js +++ b/node_modules/react-native-tooltip/ToolTip.ios.js -@@ -65,7 +65,7 @@ export default class ToolTip extends PureComponent { - if (this.props.longPress) { - props.onLongPress = this.showMenu; - } else { +@@ -57,20 +57,6 @@ export default class ToolTip extends PureComponent { + return null; + }; + +- getTouchableHighlightProps = () => { +- const props = {}; +- +- Object.keys(TouchableHighlight.propTypes).forEach((key) => props[key] = this.props[key]); +- +- if (this.props.longPress) { +- props.onLongPress = this.showMenu; +- } else { - props.onPress = this.showMenu; -+ // props.onPress = this.showMenu; - } +- } +- +- return props; +- }; +- + handleToolTipTextChange = (event) => { + const callback = this.getCallback(event.nativeEvent.text); + if (callback) { +@@ -83,13 +69,13 @@ export default class ToolTip extends PureComponent { + }; - return props; + render() { ++ const { children, ...props } = this.props; ++ + return ( + +- ++ + +- {this.props.children} ++ {children} + + + From 426ec61610449d6ea8028514f772a51154450037 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 4 Dec 2019 14:41:52 -0500 Subject: [PATCH 565/636] Bump version --- ios/Podfile.lock | 46 ++- ios/Rainbow.xcodeproj/project.pbxproj | 38 ++- .../xcshareddata/xcschemes/Rainbow.xcscheme | 6 +- ios/Rainbow/Info.plist | 318 +++++++++--------- package.json | 2 +- 5 files changed, 208 insertions(+), 202 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c254a601f91..dde8d3ecdf1 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -321,9 +321,7 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): - - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -636,8 +634,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 91845057a416f016ac2f7370c69cffef34d32ba1 - FBReactNativeSpec: 8993361dfa53ee1098b670aaa2254b49b3a02bdc + FBLazyVector: 3c4d0c09c616a7f3435e9e300f8bed746656be83 + FBReactNativeSpec: a7541d27fd4de76c8830473a54fa8747e17886bf Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -653,15 +651,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: da9e407cb3043741e368a3da5e13cf82dcdd1b8e - RCTTypeSafety: b99208dda7883aa616ebeb0b8aeacb06a30f04c6 - React: 1850042a2b60f998c480261cf792bfe1c56df502 - React-Core: bb0225d151ea02e04a1e371c091ba6ee106e21ec - React-CoreModules: 5a40f4bb1ba75d478697b4be33492d5551905f7a - React-cxxreact: af7a7e4697ee63cd113e36f07480f30a5792917a - React-jsi: 54de809e314b32f2608e941930183adcf6594f6e - React-jsiexecutor: c0882b2387a70342c8580178595d173c9834b107 - React-jsinspector: 05cde31e8a387fa370e89c6cf096a16259e79186 + RCTRequired: 50fddff608221b4ca8b129f765a2e92b79f9c261 + RCTTypeSafety: 77be7fa5f4fd4c84a8f939352b5a80decbb26661 + React: daf0e5b1018a37dde9cf6cd883ac16c699b591ca + React-Core: a640a9c5fff836386c65482e800e4bdc40161b23 + React-CoreModules: 2eee3557949a3f49d25f1178ccd68885a699d79b + React-cxxreact: c9b63613f129889ff78196039a2ad7b5dfaf78de + React-jsi: da26fa0b8b0fae04cc07da5ed9b73e26f4e9db78 + React-jsiexecutor: ee06cea084eab794d780e07c3d90fd9d41f97b66 + React-jsinspector: 620974c7af0b3ba3359c16a37e268868e0cf0dc0 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -672,16 +670,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 3de31fadcc254f2a7f73da7b907c8c49329c8472 - React-RCTAnimation: c364cccab211ff7a70233feb11459036e44e74a5 - React-RCTBlob: 9f1294198274f1e56931db28a151c300cd7c0f97 - React-RCTImage: 14ba178f323db85c9c27adc288b5cf4f8cbb705a - React-RCTLinking: 4db54d206599304cc920be35c27c35ba6e8300ed - React-RCTNetwork: 71c142ffbff34628d159ea7a35fe1f6ec217dbb5 - React-RCTSettings: afaf3eb68ea3a12dc6542e830d04800f5397ca46 - React-RCTText: 658592bc4e0965724a529bf4bfa194a2415461fb - React-RCTVibration: 9bbbb0c16c3b8ff4ed8a06fc0578a6530ca6dcfe - ReactCommon: cd4c368a02c2cbca72acc8323b352676196b32a7 + React-RCTActionSheet: 33d07af58cf3cb0add478ea1ab2ba1d903629a07 + React-RCTAnimation: b5840c31c2f6fbb7d5b1319c0e73936bcaa28d8b + React-RCTBlob: 2a89c6650e5f69d8acd041bc59b0e737b79f4d6a + React-RCTImage: 8fa6c8186733c3ee6ec5186083bc49f9c3979722 + React-RCTLinking: 3cac953827782da7ed38ba6da6af323767e207d1 + React-RCTNetwork: 70b5b9a37011f33b940eed78e49a31c05cbe9957 + React-RCTSettings: 2c77a4009001ccf2c8f8a0a102e4d00b3262261f + React-RCTText: d0980710307579b0d3b6dbfae44d8bcbd7bea030 + React-RCTVibration: cf223db4a76d8eded0245c8b50e63b0fc6ac7aaf + ReactCommon: 32bef46031a27dd9d4253fc1e0a2d1d6ce5cd91b ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -706,7 +704,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 4d2b9eb1e1f3aba25837e46104154741f9e250cd + Yoga: d12d620db862be3abc1d978608565c7dafbb6ab4 PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 723df0deaf7..37c6dac1990 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -405,7 +405,7 @@ 13B07F861A680F5B00A75B9A = { DevelopmentTeam = L74NQAQB8H; LastSwiftMigration = 1120; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; SystemCapabilities = { com.apple.Push = { enabled = 1; @@ -589,9 +589,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 4; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = L74NQAQB8H; FRAMEWORK_SEARCH_PATHS = ( @@ -615,6 +615,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + MARKETING_VERSION = 1.2.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -623,7 +624,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -639,9 +640,9 @@ CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = L74NQAQB8H; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -664,6 +665,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + MARKETING_VERSION = 1.2.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -672,7 +674,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -724,9 +726,9 @@ CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = L74NQAQB8H; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -748,6 +750,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + MARKETING_VERSION = 1.2.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -756,7 +759,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -809,9 +812,9 @@ CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = ""; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = L74NQAQB8H; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -833,6 +836,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + MARKETING_VERSION = 1.2.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -841,7 +845,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 324638f15cb..745aa70c08c 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -78,9 +78,9 @@ - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - Rainbow - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.1.5 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - rainbow - CFBundleURLSchemes - - rainbow - - - - CFBundleVersion - 3 - CodePushDeploymentKey - $(CODEPUSH_KEY) - ITSAppUsesNonExemptEncryption - - LSApplicationQueriesSchemes - - itms - itms-apps - twitter - - LSRequiresIPhoneOS - - NSAppTransportSecurity - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - - NSAppleMusicUsageDescription - Rainbow - NSBluetoothPeripheralUsageDescription - Rainbow - NSCalendarsUsageDescription - Rainbow - NSCameraUsageDescription - Used to scan QR codes - NSFaceIDUsageDescription - Used to sign transactions - NSLocationAlwaysUsageDescription - Rainbow - NSLocationWhenInUseUsageDescription - Rainbow - NSMicrophoneUsageDescription - Rainbow - NSMotionUsageDescription - Rainbow - NSSpeechRecognitionUsageDescription - Rainbow - UIAppFonts - - Graphik-Black.otf - Graphik-BlackItalic.otf - Graphik-Bold.otf - Graphik-BoldItalic.otf - Graphik-Extralight.otf - Graphik-ExtralightItalic.otf - Graphik-Light.otf - Graphik-LightItalic.otf - Graphik-Medium.otf - Graphik-MediumItalic.otf - Graphik-Regular.otf - Graphik-RegularItalic.otf - Graphik-Semibold.otf - Graphik-SemiboldItalic.otf - Graphik-Super.otf - Graphik-SuperItalic.otf - Graphik-Thin.otf - Graphik-ThinItalic.otf - SF-Pro-Display-Black.otf - SF-Pro-Display-BlackItalic.otf - SF-Pro-Display-Bold.otf - SF-Pro-Display-BoldItalic.otf - SF-Pro-Display-Heavy.otf - SF-Pro-Display-HeavyItalic.otf - SF-Pro-Display-Light.otf - SF-Pro-Display-LightItalic.otf - SF-Pro-Display-Medium.otf - SF-Pro-Display-MediumItalic.otf - SF-Pro-Display-Regular.otf - SF-Pro-Display-RegularItalic.otf - SF-Pro-Display-Semibold.otf - SF-Pro-Display-SemiboldItalic.otf - SF-Pro-Display-Thin.otf - SF-Pro-Display-ThinItalic.otf - SF-Pro-Display-Ultralight.otf - SF-Pro-Display-UltralightItalic.otf - SF-Pro-Text-Bold.otf - SF-Pro-Text-BoldItalic.otf - SF-Pro-Text-Heavy.otf - SF-Pro-Text-HeavyItalic.otf - SF-Pro-Text-Light.otf - SF-Pro-Text-LightItalic.otf - SF-Pro-Text-Medium.otf - SF-Pro-Text-MediumItalic.otf - SF-Pro-Text-Regular.otf - SF-Pro-Text-RegularItalic.otf - SF-Pro-Text-Semibold.otf - SF-Pro-Text-SemiboldItalic.otf - SFMono-Bold.otf - SFMono-Heavy.otf - SFMono-Light.otf - SFMono-Medium.otf - SFMono-Regular.otf - SFMono-Semibold.otf - - UIBackgroundModes - - remote-notification - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UIStatusBarStyle - UIStatusBarStyleDarkContent - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UIUserInterfaceStyle - Light - UIViewControllerBasedStatusBarAppearance - - + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + Rainbow + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + rainbow + CFBundleURLSchemes + + rainbow + + + + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + CodePushDeploymentKey + $(CODEPUSH_KEY) + ITSAppUsesNonExemptEncryption + + LSApplicationQueriesSchemes + + itms + itms-apps + twitter + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSAppleMusicUsageDescription + Rainbow + NSBluetoothAlwaysUsageDescription + Rainbow + NSBluetoothPeripheralUsageDescription + Rainbow + NSCalendarsUsageDescription + Rainbow + NSCameraUsageDescription + Used to scan QR codes + NSContactsUsageDescription + Rainbow + NSFaceIDUsageDescription + Used to sign transactions + NSLocationAlwaysUsageDescription + Rainbow + NSLocationWhenInUseUsageDescription + Rainbow + NSMicrophoneUsageDescription + Rainbow + NSMotionUsageDescription + Rainbow + NSSpeechRecognitionUsageDescription + Rainbow + UIAppFonts + + Graphik-Black.otf + Graphik-BlackItalic.otf + Graphik-Bold.otf + Graphik-BoldItalic.otf + Graphik-Extralight.otf + Graphik-ExtralightItalic.otf + Graphik-Light.otf + Graphik-LightItalic.otf + Graphik-Medium.otf + Graphik-MediumItalic.otf + Graphik-Regular.otf + Graphik-RegularItalic.otf + Graphik-Semibold.otf + Graphik-SemiboldItalic.otf + Graphik-Super.otf + Graphik-SuperItalic.otf + Graphik-Thin.otf + Graphik-ThinItalic.otf + SF-Pro-Display-Black.otf + SF-Pro-Display-BlackItalic.otf + SF-Pro-Display-Bold.otf + SF-Pro-Display-BoldItalic.otf + SF-Pro-Display-Heavy.otf + SF-Pro-Display-HeavyItalic.otf + SF-Pro-Display-Light.otf + SF-Pro-Display-LightItalic.otf + SF-Pro-Display-Medium.otf + SF-Pro-Display-MediumItalic.otf + SF-Pro-Display-Regular.otf + SF-Pro-Display-RegularItalic.otf + SF-Pro-Display-Semibold.otf + SF-Pro-Display-SemiboldItalic.otf + SF-Pro-Display-Thin.otf + SF-Pro-Display-ThinItalic.otf + SF-Pro-Display-Ultralight.otf + SF-Pro-Display-UltralightItalic.otf + SF-Pro-Text-Bold.otf + SF-Pro-Text-BoldItalic.otf + SF-Pro-Text-Heavy.otf + SF-Pro-Text-HeavyItalic.otf + SF-Pro-Text-Light.otf + SF-Pro-Text-LightItalic.otf + SF-Pro-Text-Medium.otf + SF-Pro-Text-MediumItalic.otf + SF-Pro-Text-Regular.otf + SF-Pro-Text-RegularItalic.otf + SF-Pro-Text-Semibold.otf + SF-Pro-Text-SemiboldItalic.otf + SFMono-Bold.otf + SFMono-Heavy.otf + SFMono-Light.otf + SFMono-Medium.otf + SFMono-Regular.otf + SFMono-Semibold.otf + + UIBackgroundModes + + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleDarkContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UIUserInterfaceStyle + Light + UIViewControllerBasedStatusBarAppearance + + diff --git a/package.json b/package.json index 6118e0b6427..35e4d314ffe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.1.6-3", + "version": "1.2.0-4", "private": true, "scripts": { "android": "react-native run-android", From c18f0f5b12dc1c5f0a73792de1e855c1a44f1c57 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 4 Dec 2019 18:30:10 -0500 Subject: [PATCH 566/636] Download only latest dSYMs for fastlane --- ios/fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index 327293eb805..9044d1f2819 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -15,7 +15,7 @@ default_platform(:ios) platform :ios do desc "Refresh dSYMs" lane :refresh_dsyms do - download_dsyms + download_dsyms(version: "latest") upload_symbols_to_crashlytics clean_build_artifacts end From 28e2b4db402a30929baa86150aba80dfd3473fce Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 4 Dec 2019 23:05:01 -0500 Subject: [PATCH 567/636] Use default txn confirmation screen for general WC txns --- src/redux/walletconnect.js | 7 ------- src/screens/TransactionConfirmationScreen.js | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/redux/walletconnect.js b/src/redux/walletconnect.js index 6b7983d9aec..f74988eb032 100644 --- a/src/redux/walletconnect.js +++ b/src/redux/walletconnect.js @@ -35,13 +35,6 @@ const WALLETCONNECT_CLEAR_TIMESTAMP = const WALLETCONNECT_CLEAR_STATE = 'walletconnect/WALLETCONNECT_CLEAR_STATE'; // -- Actions ---------------------------------------- // - -// TODO store approved list -/* -const previouslyApprovedDapps = [ -]; -*/ - const getNativeOptions = async () => { const language = 'en'; // TODO use lang from settings const token = await getFCMToken(); diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index ecc7c65dd07..49328f65bdb 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -138,7 +138,7 @@ export default class TransactionConfirmationScreen extends PureComponent { ); } - if (isTransactionDisplayType(method)) { + if (isTransactionDisplayType(method) && get(request, 'asset')) { return ( Date: Wed, 4 Dec 2019 23:07:56 -0500 Subject: [PATCH 568/636] Overwrite gasPrice if dapp does not send one --- .../TransactionConfirmationScreenWithData.js | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/screens/TransactionConfirmationScreenWithData.js b/src/screens/TransactionConfirmationScreenWithData.js index da5e002fc54..d8259b68f75 100644 --- a/src/screens/TransactionConfirmationScreenWithData.js +++ b/src/screens/TransactionConfirmationScreenWithData.js @@ -7,7 +7,7 @@ import React, { PureComponent } from 'react'; import { Alert, Vibration } from 'react-native'; import { withNavigationFocus } from 'react-navigation'; import { compose } from 'recompact'; -import { withTransactionConfirmationScreen } from '../hoc'; +import { withGas, withTransactionConfirmationScreen } from '../hoc'; import { signMessage, signPersonalMessage, @@ -15,6 +15,7 @@ import { sendTransaction, } from '../model/wallet'; import { estimateGas, getTransactionCount, toHex } from '../handlers/web3'; +import { gasUtils } from '../utils'; import { isMessageDisplayType, isSignFirstParamType, @@ -26,6 +27,7 @@ import TransactionConfirmationScreen from './TransactionConfirmationScreen'; class TransactionConfirmationScreenWithData extends PureComponent { static propTypes = { dataAddNewTransaction: PropTypes.func, + gasPrices: PropTypes.object, navigation: PropTypes.any, removeRequest: PropTypes.func, transactionCountNonce: PropTypes.number, @@ -66,7 +68,15 @@ class TransactionConfirmationScreenWithData extends PureComponent { const sendInsteadOfSign = method === SEND_TRANSACTION; const txPayload = get(params, '[0]'); - let { gasLimit } = txPayload; + let { gasLimit, gasPrice } = txPayload; + + if (isNil(gasPrice)) { + const { gasPrices } = this.props; + const rawGasPrice = get(gasPrices, `${gasUtils.NORMAL}.value.amount`); + if (rawGasPrice) { + gasPrice = toHex(rawGasPrice); + } + } if (isNil(gasLimit)) { try { @@ -83,7 +93,7 @@ class TransactionConfirmationScreenWithData extends PureComponent { web3TxnCount ); const nonce = ethers.utils.hexlify(maxTxnCount); - let txPayloadLatestNonce = { ...txPayload, nonce }; + let txPayloadLatestNonce = { ...txPayload, gasLimit, gasPrice, nonce }; txPayloadLatestNonce = omit(txPayloadLatestNonce, 'from'); let result = null; if (sendInsteadOfSign) { @@ -107,10 +117,10 @@ class TransactionConfirmationScreenWithData extends PureComponent { asset: get(displayDetails, 'request.asset'), dappName, from: get(displayDetails, 'request.from'), - gasLimit: get(displayDetails, 'request.gasLimit'), - gasPrice: get(displayDetails, 'request.gasPrice'), + gasLimit, + gasPrice, hash: result, - nonce: get(displayDetails, 'request.nonce'), + nonce, to: get(displayDetails, 'request.to'), }; this.props.dataAddNewTransaction(txDetails); @@ -220,6 +230,7 @@ class TransactionConfirmationScreenWithData extends PureComponent { } export default compose( + withGas, withNavigationFocus, withTransactionConfirmationScreen )(TransactionConfirmationScreenWithData); From 5a63df8a7b475f46590f595d19d4c828118f6ceb Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 5 Dec 2019 16:11:44 -0500 Subject: [PATCH 569/636] Development: reset Signing and Capabilities and Scheme --- ios/Rainbow.xcodeproj/project.pbxproj | 34 +++++++++---------- .../xcshareddata/xcschemes/Rainbow.xcscheme | 6 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 37c6dac1990..83e73bc1d51 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -405,7 +405,7 @@ 13B07F861A680F5B00A75B9A = { DevelopmentTeam = L74NQAQB8H; LastSwiftMigration = 1120; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Push = { enabled = 1; @@ -589,11 +589,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; DEAD_CODE_STRIPPING = NO; - DEVELOPMENT_TEAM = L74NQAQB8H; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -624,7 +624,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -640,10 +640,10 @@ CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; - DEVELOPMENT_TEAM = L74NQAQB8H; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -674,7 +674,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -726,10 +726,10 @@ CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; - DEVELOPMENT_TEAM = L74NQAQB8H; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -759,7 +759,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -812,10 +812,10 @@ CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = ""; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; - DEVELOPMENT_TEAM = L74NQAQB8H; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -845,7 +845,7 @@ PRODUCT_BUNDLE_IDENTIFIER = me.rainbow; PRODUCT_NAME = Rainbow; PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.rainbow"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Rainbow-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 745aa70c08c..324638f15cb 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -78,9 +78,9 @@ Date: Thu, 5 Dec 2019 17:46:39 -0500 Subject: [PATCH 570/636] Fix header buttons, improve ButtonPressAnimation haptics --- .../xcshareddata/xcschemes/Rainbow.xcscheme | 6 +- .../animations/ButtonPressAnimation.js | 3 +- src/components/animations/TouchableScale.js | 132 ++++++++++++++++++ src/components/animations/index.js | 1 + .../exchange/CurrencySelectModalHeader.js | 2 - src/components/header/BackButton.js | 2 - src/components/header/Header.js | 2 +- src/components/header/HeaderButton.js | 25 +++- src/components/icons/svg/CaretIcon.js | 2 +- src/components/icons/svg/GearIcon.js | 2 +- src/screens/ProfileScreen.js | 10 +- 11 files changed, 167 insertions(+), 20 deletions(-) create mode 100644 src/components/animations/TouchableScale.js diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 324638f15cb..745aa70c08c 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -78,9 +78,9 @@ { const { enableHapticFeedback, hapticType } = this.props; - if (enableHapticFeedback) { ReactNativeHapticFeedback.trigger(hapticType); } @@ -195,12 +194,12 @@ export default class ButtonPressAnimation extends Component { handlePress = () => { if (!this.longPressDetected && this.props.onPress) { - this.handleHaptic(); this.props.onPress(); } }; handlePressStart = () => { + this.handleHaptic(); if (this.props.onPressStart) { this.props.onPressStart(); } diff --git a/src/components/animations/TouchableScale.js b/src/components/animations/TouchableScale.js new file mode 100644 index 00000000000..3becd632749 --- /dev/null +++ b/src/components/animations/TouchableScale.js @@ -0,0 +1,132 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { TouchableWithoutFeedback, Animated } from 'react-native'; +import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; +import stylePropType from 'react-style-proptype'; + +const HapticFeedbackTypes = { + impactHeavy: 'impactHeavy', + impactLight: 'impactLight', + impactMedium: 'impactMedium', + notificationError: 'notificationError', + notificationSuccess: 'notificationSuccess', + notificationWarning: 'notificationWarning', + selection: 'selection', +}; + +export default class TouchableScale extends React.Component { + constructor(...args) { + super(...args); + const props = this.props; + + this.onPressIn = this.onPressIn.bind(this); + this.onPressOut = this.onPressOut.bind(this); + this.scaleAnimation = new Animated.Value(props.defaultScale); + } + + handleHaptic = () => { + const { enableHapticFeedback, hapticType } = this.props; + + if (enableHapticFeedback) { + ReactNativeHapticFeedback.trigger(hapticType); + } + }; + + onPressIn(...args) { + const props = this.props; + const friction = + typeof props.pressInFriction !== 'undefined' + ? props.pressInFriction + : props.friction; + const tension = + typeof props.pressInTension !== 'undefined' + ? props.pressInTension + : props.tension; + + Animated.spring(this.scaleAnimation, { + friction: friction, + tension: tension, + toValue: props.activeScale, + useNativeDriver: props.useNativeDriver, + }).start(); + + this.handleHaptic(); + + if (props.onPressIn) { + props.onPressIn(...args); + } + } + + onPressOut(...args) { + const props = this.props; + const tension = + typeof props.pressOutTension !== 'undefined' + ? props.pressOutTension + : props.tension; + const friction = + typeof props.pressOutFriction !== 'undefined' + ? props.pressOutFriction + : props.friction; + + Animated.spring(this.scaleAnimation, { + friction: friction, + tension: tension, + toValue: props.defaultScale, + useNativeDriver: props.useNativeDriver, + }).start(); + + if (props.onPressOut) { + props.onPressOut(...args); + } + } + + render() { + const props = this.props; + + return ( + + + {props.children} + + + ); + } +} + +TouchableScale.propTypes = { + ...TouchableWithoutFeedback.propTypes, + activeScale: PropTypes.number.isRequired, + defaultScale: PropTypes.number.isRequired, + enableHapticFeedback: PropTypes.bool, + friction: PropTypes.number.isRequired, + hapticType: PropTypes.oneOf(Object.keys(HapticFeedbackTypes)), + pressInFriction: PropTypes.number, + pressInTension: PropTypes.number, + pressOutFriction: PropTypes.number, + pressOutTension: PropTypes.number, + style: stylePropType, + tension: PropTypes.number.isRequired, + useNativeDriver: PropTypes.bool, +}; + +TouchableScale.defaultProps = { + activeScale: 0.9, + defaultScale: 1, + enableHapticFeedback: true, + friction: 3, + hapticType: HapticFeedbackTypes.selection, + tension: 150, + useNativeDriver: true, +}; diff --git a/src/components/animations/index.js b/src/components/animations/index.js index 298b131c880..5a03d03ca7e 100644 --- a/src/components/animations/index.js +++ b/src/components/animations/index.js @@ -7,3 +7,4 @@ export { default as RoundButtonSizeToggler } from './RoundButtonSizeToggler'; export { default as ScaleInAnimation } from './ScaleInAnimation'; export { default as SizeToggler } from './SizeToggler'; export { default as SpinAnimation } from './SpinAnimation'; +export { default as TouchableScale } from './TouchableScale'; diff --git a/src/components/exchange/CurrencySelectModalHeader.js b/src/components/exchange/CurrencySelectModalHeader.js index 8e6e85213a7..030478f26b0 100644 --- a/src/components/exchange/CurrencySelectModalHeader.js +++ b/src/components/exchange/CurrencySelectModalHeader.js @@ -35,11 +35,9 @@ const CurrencySelectModalHeader = ({ onPressBack, title }) => ( {title} diff --git a/src/components/header/BackButton.js b/src/components/header/BackButton.js index b22231559bb..1417ef40f44 100644 --- a/src/components/header/BackButton.js +++ b/src/components/header/BackButton.js @@ -13,8 +13,6 @@ const ContainerElement = omitProps('direction')(Flex); const Container = styled(ContainerElement).attrs({ align: 'end' })` height: 100%; padding-bottom: 2; - padding-left: ${({ direction }) => (direction === 'left' ? 0 : 20)}; - padding-right: ${({ direction }) => (direction === 'right' ? 0 : 20)}; `; const BackButton = ({ color, direction, onPress, ...props }) => ( diff --git a/src/components/header/Header.js b/src/components/header/Header.js index 57543ea8810..6fd1780a776 100644 --- a/src/components/header/Header.js +++ b/src/components/header/Header.js @@ -12,7 +12,7 @@ const Header = React.memo(props => ( ( - - + + {children} - + ); HeaderButton.propTypes = { - ...ButtonPressAnimation.propTypes, + ...TouchableScale.propTypes, children: PropTypes.node, onPress: PropTypes.func.isRequired, + useButtonPress: PropTypes.bool, +}; + +HeaderButton.defaultProps = { + useButtonPress: true, }; export default pure(HeaderButton); diff --git a/src/components/icons/svg/CaretIcon.js b/src/components/icons/svg/CaretIcon.js index 9197a58e211..5faf394638b 100644 --- a/src/components/icons/svg/CaretIcon.js +++ b/src/components/icons/svg/CaretIcon.js @@ -28,7 +28,7 @@ CaretIcon.propTypes = { }; CaretIcon.defaultProps = { - color: colors.black, + color: colors.dark, }; export default withRotationForDirection(CaretIcon); diff --git a/src/components/icons/svg/GearIcon.js b/src/components/icons/svg/GearIcon.js index cc67f836b90..470cd977f19 100644 --- a/src/components/icons/svg/GearIcon.js +++ b/src/components/icons/svg/GearIcon.js @@ -19,7 +19,7 @@ GearIcon.propTypes = { }; GearIcon.defaultProps = { - color: colors.black, + color: colors.dark, }; export default GearIcon; diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index f37e8012dcf..d05dd02d982 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -7,7 +7,7 @@ import { BackButton, Header, HeaderButton } from '../components/header'; import { FlexItem, Page } from '../components/layout'; import { Icon } from '../components/icons'; import { ProfileMasthead } from '../components/profile'; -import { position } from '../styles'; +import { colors, position } from '../styles'; const ProfileScreen = ({ accountAddress, @@ -24,9 +24,13 @@ const ProfileScreen = ({
- + - +
Date: Fri, 6 Dec 2019 13:34:48 -0500 Subject: [PATCH 571/636] Move haptic feedback to onPressOut --- src/components/animations/ButtonPressAnimation.js | 2 +- src/components/animations/TouchableScale.js | 4 ++-- src/components/header/HeaderButton.js | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index fd6f8479988..3fb7d2bf553 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -194,12 +194,12 @@ export default class ButtonPressAnimation extends Component { handlePress = () => { if (!this.longPressDetected && this.props.onPress) { + this.handleHaptic(); this.props.onPress(); } }; handlePressStart = () => { - this.handleHaptic(); if (this.props.onPressStart) { this.props.onPressStart(); } diff --git a/src/components/animations/TouchableScale.js b/src/components/animations/TouchableScale.js index 3becd632749..f70038bbf86 100644 --- a/src/components/animations/TouchableScale.js +++ b/src/components/animations/TouchableScale.js @@ -50,8 +50,6 @@ export default class TouchableScale extends React.Component { useNativeDriver: props.useNativeDriver, }).start(); - this.handleHaptic(); - if (props.onPressIn) { props.onPressIn(...args); } @@ -75,6 +73,8 @@ export default class TouchableScale extends React.Component { useNativeDriver: props.useNativeDriver, }).start(); + this.handleHaptic(); + if (props.onPressOut) { props.onPressOut(...args); } diff --git a/src/components/header/HeaderButton.js b/src/components/header/HeaderButton.js index a707a8d98d4..e585d93a13c 100644 --- a/src/components/header/HeaderButton.js +++ b/src/components/header/HeaderButton.js @@ -8,6 +8,7 @@ import { Flex } from '../layout'; const HeaderButton = ({ children, onPress, transformOrigin, ...props }) => ( Date: Fri, 6 Dec 2019 13:38:26 -0500 Subject: [PATCH 572/636] Revert Rainbow.xcscheme changes --- .../xcshareddata/xcschemes/Rainbow.xcscheme | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 745aa70c08c..324638f15cb 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -78,9 +78,9 @@ Date: Fri, 6 Dec 2019 13:42:30 -0500 Subject: [PATCH 573/636] Remove unnecessary enableHapticFeedback --- src/components/header/HeaderButton.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/header/HeaderButton.js b/src/components/header/HeaderButton.js index e585d93a13c..ff4a49d3afa 100644 --- a/src/components/header/HeaderButton.js +++ b/src/components/header/HeaderButton.js @@ -8,7 +8,6 @@ import { Flex } from '../layout'; const HeaderButton = ({ children, onPress, transformOrigin, ...props }) => ( Date: Fri, 6 Dec 2019 17:49:44 -0500 Subject: [PATCH 574/636] Check if asset exists in wallet before overwriting input currency --- src/screens/ExchangeModal.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 7ab49aba792..a0e05df54dc 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -8,7 +8,7 @@ import { tradeTokensForExactTokensWithData, } from '@uniswap/sdk'; import BigNumber from 'bignumber.js'; -import { get, isNil, toLower } from 'lodash'; +import { find, get, isNil, toLower } from 'lodash'; import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; import { TextInput, InteractionManager } from 'react-native'; @@ -85,6 +85,7 @@ class ExchangeModal extends Component { accountAddress: PropTypes.string, allAssets: PropTypes.array, allowances: PropTypes.object, + assetsAvailableOnUniswap: PropTypes.arrayOf(PropTypes.object), chainId: PropTypes.number, dataAddNewTransaction: PropTypes.func, gasLimit: PropTypes.number, @@ -276,6 +277,11 @@ class ExchangeModal extends Component { uniswapUpdateAllowances, } = this.props; const { inputCurrency } = this.state; + + if (isNil(inputCurrency)) { + return this.setState({ isAssetApproved: true }); + } + const { address: inputAddress, exchangeAddress } = inputCurrency; if (inputAddress === 'eth') { @@ -788,6 +794,7 @@ class ExchangeModal extends Component { inputCurrency, outputCurrency: previousOutputCurrency, } = this.state; + const { assetsAvailableOnUniswap } = this.props; this.props.uniswapUpdateOutputCurrency(outputCurrency); @@ -797,8 +804,16 @@ class ExchangeModal extends Component { showConfirmButton: !!outputCurrency, }); + const existsInWallet = find( + assetsAvailableOnUniswap, + asset => get(asset, 'address') === get(previousOutputCurrency, 'address') + ); if (userSelected && isSameAsset(inputCurrency, outputCurrency)) { - this.setInputCurrency(previousOutputCurrency, false); + if (existsInWallet) { + this.setInputCurrency(previousOutputCurrency, false); + } else { + this.setInputCurrency(null, false); + } } }; From ea4811081785934aa5ba635e70b99ac88708f21c Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 6 Dec 2019 19:21:35 -0500 Subject: [PATCH 575/636] Show confirm button only when both input and output currencies exist --- src/screens/ExchangeModal.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a0e05df54dc..eab242def14 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -741,7 +741,10 @@ class ExchangeModal extends Component { this.clearForm(); } - this.setState({ inputCurrency }); + this.setState({ + inputCurrency, + showConfirmButton: !!inputCurrency && !!outputCurrency, + }); this.props.uniswapUpdateInputCurrency(inputCurrency); if (userSelected && isSameAsset(inputCurrency, outputCurrency)) { @@ -801,7 +804,7 @@ class ExchangeModal extends Component { this.setState({ inputAsExactAmount: true, outputCurrency, - showConfirmButton: !!outputCurrency, + showConfirmButton: !!inputCurrency && !!outputCurrency, }); const existsInWallet = find( From 5140d41ef9ddcb3ebb23358555a1ae7a34095662 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 6 Dec 2019 19:30:07 -0500 Subject: [PATCH 576/636] Show Confirm button in Unlock state when input asset needs to be unlocked --- src/screens/ExchangeModal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index eab242def14..a8a05dd225b 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -902,7 +902,7 @@ class ExchangeModal extends Component { {isSlippageWarningVisible && ( )} - {showConfirmButton && ( + {(showConfirmButton || !isAssetApproved) && ( Date: Mon, 9 Dec 2019 20:51:29 +0100 Subject: [PATCH 577/636] Bump react-navigation-stack --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 6118e0b6427..0ee568dc54d 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", - "react-navigation-stack": "2.0.0-alpha.37", + "react-navigation-stack": "2.0.0-alpha.39", "react-navigation-tabs": "2.5.6", "react-navigation-tabs-v1": "1.2.0", "react-primitives": "^0.8.0", diff --git a/yarn.lock b/yarn.lock index 13340e6f04a..9a08f3634d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9521,10 +9521,10 @@ react-native@facebook/react-native: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.37: - version "2.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.37.tgz#15c38f7ef9923a2b6739c2bc8441f8ab70af3ec3" - integrity sha512-2AcidUvhNgErV2QlV3s7wSdkbAJ+sQEAsHrHF4xK8PTf04I9+qG3/Ds9Orx31njhujHfuB5nN/77z+ih1iM+7g== +react-navigation-stack@2.0.0-alpha.39: + version "2.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.39.tgz#e138a116f69397ead27d5760559489e23990ed3f" + integrity sha512-G6cKfiPodPpoTmEdTZhZQ1yYkjU9UeqM3W7KzEQp1Pk3iTswel9z+Arry1YFkR42zPDkzuSg7phU7VFwkvo+uw== react-navigation-tabs-v1@1.2.0: version "1.2.0" From 0497726949bae028605c9c5aa2a7d1e83253dd5c Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Mon, 9 Dec 2019 15:12:15 -0500 Subject: [PATCH 578/636] Merge 'Bump react-navigation-stack' into testflight/v1.2.0-4 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 35e4d314ffe..ca03f32839a 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", - "react-navigation-stack": "2.0.0-alpha.37", + "react-navigation-stack": "2.0.0-alpha.39", "react-navigation-tabs": "2.5.6", "react-navigation-tabs-v1": "1.2.0", "react-primitives": "^0.8.0", diff --git a/yarn.lock b/yarn.lock index 13340e6f04a..9a08f3634d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9521,10 +9521,10 @@ react-native@facebook/react-native: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" -react-navigation-stack@2.0.0-alpha.37: - version "2.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.37.tgz#15c38f7ef9923a2b6739c2bc8441f8ab70af3ec3" - integrity sha512-2AcidUvhNgErV2QlV3s7wSdkbAJ+sQEAsHrHF4xK8PTf04I9+qG3/Ds9Orx31njhujHfuB5nN/77z+ih1iM+7g== +react-navigation-stack@2.0.0-alpha.39: + version "2.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.39.tgz#e138a116f69397ead27d5760559489e23990ed3f" + integrity sha512-G6cKfiPodPpoTmEdTZhZQ1yYkjU9UeqM3W7KzEQp1Pk3iTswel9z+Arry1YFkR42zPDkzuSg7phU7VFwkvo+uw== react-navigation-tabs-v1@1.2.0: version "1.2.0" From 01ce32e88f674bbc2829bca742642714cf88e65b Mon Sep 17 00:00:00 2001 From: osdnk Date: Mon, 9 Dec 2019 21:42:10 +0100 Subject: [PATCH 579/636] Increase minDeltaX={20} in withBlockedHorizontalSwipe.js --- src/hoc/withBlockedHorizontalSwipe.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hoc/withBlockedHorizontalSwipe.js b/src/hoc/withBlockedHorizontalSwipe.js index 443e40f2f49..9087fa8a6db 100644 --- a/src/hoc/withBlockedHorizontalSwipe.js +++ b/src/hoc/withBlockedHorizontalSwipe.js @@ -6,7 +6,7 @@ import { setDisplayName } from 'recompact'; // before it got delivered to navigator export default InnerComponent => setDisplayName('HorizontalGestureBlocker')(props => ( - + From 9cf1e76fd067a6c72c011c3338bc9e7265bdde2c Mon Sep 17 00:00:00 2001 From: osdnk Date: Mon, 9 Dec 2019 22:12:37 +0100 Subject: [PATCH 580/636] Unify keyboard handling on send sheet, increase displacement and speed threshold --- src/components/send/SendHeader.js | 3 ++- src/navigation/transitions/effects.js | 2 ++ src/screens/SendSheet.js | 22 +++++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index 502d1fd98d7..b36c0ba63bc 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -35,6 +35,7 @@ const SheetHandle = compose( const contactPropType = PropTypes.shape({ address: PropTypes.string, color: PropTypes.number, + inputRef: PropTypes.func, nickname: PropTypes.string, removeContact: PropTypes.func, }); @@ -137,6 +138,7 @@ class SendHeader extends PureComponent { handleRef = ref => { this.input = ref; + this.props.handleRef(ref); }; onFocus = () => this.props.setSelectedInputId(this.input); @@ -161,7 +163,6 @@ class SendHeader extends PureComponent { { @@ -214,6 +229,10 @@ class SendSheet extends Component { this.props.sendUpdateRecipient(event); }; + handleRef = ref => { + this.input = ref; + }; + render() { const { allAssets, @@ -239,6 +258,7 @@ class SendSheet extends Component { Date: Mon, 9 Dec 2019 17:41:20 -0500 Subject: [PATCH 581/636] Fix shadow radius --- src/components/investment-cards/InvestmentCard.js | 8 +------- src/navigation/transitions/effects.js | 6 +++--- src/styles/shadow.js | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index e7a06051265..ed4286004ee 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -66,7 +66,7 @@ const InvestmentCard = enhance( paddingVertical={InvestmentCardMargin.vertical} style={{ shadowColor: colors.dark, - shadowOffset: { height: 1, width: 0 }, + shadowOffset: { height: 1.5, width: 0 }, shadowOpacity: 0.1, shadowRadius: 3, }} @@ -83,12 +83,6 @@ const InvestmentCard = enhance( borderRadius={InvestmentCardBorderRadius} justify="start" onLayout={onLayout} - overflow="hidden" - style={{ - shadowColor: 'black', - shadowOpacity: 1, - shadowRadius: 10, - }} > Date: Mon, 9 Dec 2019 17:42:51 -0500 Subject: [PATCH 582/636] Remove list component backgrounds --- src/components/investment-cards/InvestmentCard.js | 1 - src/components/list/ListHeader.js | 10 +--------- src/components/token-family/TokenFamilyHeader.js | 1 - 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index ed4286004ee..1d1d7e06d8c 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -51,7 +51,6 @@ const InvestmentCard = enhance( ( - Date: Mon, 9 Dec 2019 17:45:30 -0500 Subject: [PATCH 583/636] Improve unique token styles --- .../send/SendAssetFormCollectible.js | 8 ++- .../unique-token/UniqueTokenCard.js | 64 ++++++++++--------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/components/send/SendAssetFormCollectible.js b/src/components/send/SendAssetFormCollectible.js index 50669514ae7..33933454782 100644 --- a/src/components/send/SendAssetFormCollectible.js +++ b/src/components/send/SendAssetFormCollectible.js @@ -47,11 +47,17 @@ const SendAssetFormCollectible = enhance( {!!containerHeight && !!containerWidth && ( )} diff --git a/src/components/unique-token/UniqueTokenCard.js b/src/components/unique-token/UniqueTokenCard.js index f5c801bb9c0..ce4dfa830f0 100644 --- a/src/components/unique-token/UniqueTokenCard.js +++ b/src/components/unique-token/UniqueTokenCard.js @@ -1,19 +1,19 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { View } from 'react-native'; import stylePropType from 'react-style-proptype'; import { compose, onlyUpdateForKeys, withHandlers, withProps } from 'recompact'; import { withFabSendAction } from '../../hoc'; -import { colors, position } from '../../styles'; +import { colors } from '../../styles'; import { ButtonPressAnimation } from '../animations'; import Highlight from '../Highlight'; import InnerBorder from '../InnerBorder'; -import { Centered } from '../layout'; -import { ShadowStack } from '../shadow-stack'; import UniqueTokenImage from './UniqueTokenImage'; const UniqueTokenCardBorderRadius = 18; const UniqueTokenCard = ({ + borderEnabled, disabled, height, item: { background, image_preview_url, ...item }, @@ -21,7 +21,7 @@ const UniqueTokenCard = ({ onPressSend, highlight, resizeMode, - shadows, + shadowStyle, style, width, ...props @@ -33,41 +33,46 @@ const UniqueTokenCard = ({ onPress={onPress} onPressSend={onPressSend} scaleTo={0.94} + style={{ + shadowColor: colors.dark, + shadowOffset: { height: 1.5, width: 0 }, + shadowOpacity: 0.1, + shadowRadius: 3, + ...shadowStyle, + }} > - - - + {borderEnabled && ( + - - - - + )} + + ); }; UniqueTokenCard.propTypes = { + borderEnabled: PropTypes.bool, disabled: PropTypes.bool, height: PropTypes.number, highlight: PropTypes.bool, @@ -78,17 +83,14 @@ UniqueTokenCard.propTypes = { onPress: PropTypes.func, onPressSend: PropTypes.func, resizeMode: UniqueTokenImage.propTypes.resizeMode, - shadows: PropTypes.array, + shadowStyle: stylePropType, size: PropTypes.number, style: stylePropType, width: PropTypes.number, }; UniqueTokenCard.defaultProps = { - shadows: [ - [0, 1, 3, colors.dark, 0.06], - [0, 4, 6, colors.dark, 0.04], - ], + borderEnabled: true, }; export default compose( From 85d746e5efa5bfb3d0bc167e307ed249c47e1829 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 9 Dec 2019 18:49:36 -0500 Subject: [PATCH 584/636] Fix fallback gas prices and default values for time resolution --- src/helpers/time.js | 4 ++-- src/redux/gas.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/time.js b/src/helpers/time.js index d43d909acde..f0318306f39 100644 --- a/src/helpers/time.js +++ b/src/helpers/time.js @@ -13,10 +13,10 @@ const buildLocalizedTimeUnitString = ({ plural, short, unit }) => { }; const getHighestResolutionUnit = timeUnitValues => { - const highestResolutionUnit = findKey(timeUnitValues); + const highestResolutionUnit = findKey(timeUnitValues) || 'seconds'; return { unit: highestResolutionUnit, - value: timeUnitValues[highestResolutionUnit], + value: timeUnitValues[highestResolutionUnit] || 0, }; }; diff --git a/src/redux/gas.js b/src/redux/gas.js index bab930fa30b..9a1e5555615 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -24,14 +24,14 @@ let getGasPricesInterval = null; const getDefaultTxFees = () => (dispatch, getState) => { const { assets } = getState().data; - const { gasLimit } = getState().gas; + const { defaultGasLimit } = getState().gas; const { nativeCurrency } = getState().settings; const fallbackGasPrices = getFallbackGasPrices(); const ethPriceUnit = ethereumUtils.getEthPriceUnit(assets); const txFees = parseTxFees( fallbackGasPrices, ethPriceUnit, - gasLimit, + defaultGasLimit, nativeCurrency ); const selectedGasPrice = { From db6bbff1ed8bfa2f64a460e9664eee5b6644de5e Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Mon, 9 Dec 2019 19:34:34 -0500 Subject: [PATCH 585/636] Better styles for unique tokens and investment cards --- src/components/investment-cards/InvestmentCard.js | 12 ++++++++---- src/components/unique-token/UniqueTokenCard.js | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 1d1d7e06d8c..29d2ebcc830 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -65,8 +65,8 @@ const InvestmentCard = enhance( paddingVertical={InvestmentCardMargin.vertical} style={{ shadowColor: colors.dark, - shadowOffset: { height: 1.5, width: 0 }, - shadowOpacity: 0.1, + shadowOffset: { height: 2, width: 0 }, + shadowOpacity: 0.08, shadowRadius: 3, }} > @@ -93,12 +93,16 @@ const InvestmentCard = enhance( {children} - +
diff --git a/src/components/unique-token/UniqueTokenCard.js b/src/components/unique-token/UniqueTokenCard.js index ce4dfa830f0..2afc76ef640 100644 --- a/src/components/unique-token/UniqueTokenCard.js +++ b/src/components/unique-token/UniqueTokenCard.js @@ -35,8 +35,8 @@ const UniqueTokenCard = ({ scaleTo={0.94} style={{ shadowColor: colors.dark, - shadowOffset: { height: 1.5, width: 0 }, - shadowOpacity: 0.1, + shadowOffset: { height: 2, width: 0 }, + shadowOpacity: 0.08, shadowRadius: 3, ...shadowStyle, }} @@ -57,7 +57,7 @@ const UniqueTokenCard = ({ /> {borderEnabled && ( From 3d38ff4ffadd77af98c4ab71d314a5fb8801f2c0 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Mon, 9 Dec 2019 20:24:01 -0500 Subject: [PATCH 586/636] Add and disable ListHeader background gradient --- src/components/list/ListHeader.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/list/ListHeader.js b/src/components/list/ListHeader.js index 57bec6a6e11..220d4ae7e8a 100644 --- a/src/components/list/ListHeader.js +++ b/src/components/list/ListHeader.js @@ -19,6 +19,15 @@ const ListHeader = pure( titleRenderer, }) => ( + {/* + + */} Date: Mon, 9 Dec 2019 20:50:34 -0500 Subject: [PATCH 587/636] Add list backgrounds back in --- src/components/list/ListHeader.js | 19 +++++++++---------- .../token-family/TokenFamilyHeader.js | 1 + 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/list/ListHeader.js b/src/components/list/ListHeader.js index 220d4ae7e8a..99004a0c028 100644 --- a/src/components/list/ListHeader.js +++ b/src/components/list/ListHeader.js @@ -1,7 +1,8 @@ import PropTypes from 'prop-types'; import React, { createElement, Fragment } from 'react'; import { pure } from 'recompact'; -import { colors, padding } from '../../styles'; +import { colors, padding, position } from '../../styles'; +import LinearGradient from 'react-native-linear-gradient'; import { Row } from '../layout'; import { H1 } from '../text'; import ContextMenu from '../ContextMenu'; @@ -19,15 +20,13 @@ const ListHeader = pure( titleRenderer, }) => ( - {/* - - */} + Date: Mon, 9 Dec 2019 21:24:56 -0500 Subject: [PATCH 588/636] Revert "Unify keyboard handling on send sheet, increase displacement and speed threshold" --- src/components/send/SendHeader.js | 3 +-- src/navigation/transitions/effects.js | 2 -- src/screens/SendSheet.js | 22 +--------------------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/components/send/SendHeader.js b/src/components/send/SendHeader.js index b36c0ba63bc..502d1fd98d7 100644 --- a/src/components/send/SendHeader.js +++ b/src/components/send/SendHeader.js @@ -35,7 +35,6 @@ const SheetHandle = compose( const contactPropType = PropTypes.shape({ address: PropTypes.string, color: PropTypes.number, - inputRef: PropTypes.func, nickname: PropTypes.string, removeContact: PropTypes.func, }); @@ -138,7 +137,6 @@ class SendHeader extends PureComponent { handleRef = ref => { this.input = ref; - this.props.handleRef(ref); }; onFocus = () => this.props.setSelectedInputId(this.input); @@ -163,6 +161,7 @@ class SendHeader extends PureComponent { { @@ -229,10 +214,6 @@ class SendSheet extends Component { this.props.sendUpdateRecipient(event); }; - handleRef = ref => { - this.input = ref; - }; - render() { const { allAssets, @@ -258,7 +239,6 @@ class SendSheet extends Component { Date: Mon, 25 Nov 2019 22:22:26 -0500 Subject: [PATCH 589/636] Remove overzealous usage of Animated.proc after feedback from micha; --- src/components/GestureBlocker.js | 2 +- .../animations/ButtonPressAnimation.js | 32 ++++++++----------- src/components/animations/procs/cond.js | 17 ---------- src/components/animations/procs/index.js | 13 -------- src/components/animations/procs/math.js | 4 --- src/components/animations/procs/operators.js | 12 ------- src/components/animations/procs/timing.js | 2 +- .../animations/procs/transformOrigin.js | 11 ------- .../animations/procs/updateState.js | 11 +++---- src/components/icons/svg/ProgressIcon.js | 6 ++-- src/navigation/transitions/effects.js | 20 ++++++------ 11 files changed, 34 insertions(+), 96 deletions(-) delete mode 100644 src/components/animations/procs/cond.js delete mode 100644 src/components/animations/procs/math.js delete mode 100644 src/components/animations/procs/operators.js delete mode 100644 src/components/animations/procs/transformOrigin.js diff --git a/src/components/GestureBlocker.js b/src/components/GestureBlocker.js index d8df56a8ff0..b34468d8890 100644 --- a/src/components/GestureBlocker.js +++ b/src/components/GestureBlocker.js @@ -6,8 +6,8 @@ import { PanGestureHandler, TapGestureHandler, } from 'react-native-gesture-handler'; -import { deviceUtils } from '../utils'; import Animated from 'react-native-reanimated'; +import { deviceUtils } from '../utils'; const { call, cond, event, eq } = Animated; diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index 3fb7d2bf553..aae4b677c07 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -9,33 +9,31 @@ import { } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; -import stylePropType from 'react-style-proptype'; -import { animations, colors } from '../../styles'; -import { directionPropType } from '../../utils'; import { - and, - cond as condProc, contains, - divide, - eq, - greaterThan, - interpolate, - lessThan, - or, - set, - timing, transformOrigin as transformOriginUtil, -} from './procs'; +} from 'react-native-redash'; +import stylePropType from 'react-style-proptype'; +import { animations, colors } from '../../styles'; +import { directionPropType } from '../../utils'; +import { interpolate, timing } from './procs'; const { + and, block, call, Clock, cond, createAnimatedComponent, + divide, + eq, event, + greaterThan, + lessThan, onChange, + or, proc, + set, stopClock, Value, } = Animated; @@ -292,16 +290,14 @@ export default class ButtonPressAnimation extends Component { ]), onChange( this.gestureState, - condProc( + cond( eq(this.gestureState, ACTIVE), [ call([], this.createInteraction), call([], this.createLongPressListener), call([], this.handlePressStart), ], - condProc(eq(this.gestureState, END), [ - call([], this.handlePress), - ]) + cond(eq(this.gestureState, END), [call([], this.handlePress)]) ) ), cond( diff --git a/src/components/animations/procs/cond.js b/src/components/animations/procs/cond.js deleted file mode 100644 index 42102505085..00000000000 --- a/src/components/animations/procs/cond.js +++ /dev/null @@ -1,17 +0,0 @@ -import Animated from 'react-native-reanimated'; - -const condSingleCase = Animated.proc((conditional, trueCase) => - Animated.cond(conditional, trueCase) -); - -const condDoubleCase = Animated.proc((conditional, trueCase, falseCase) => - Animated.cond(conditional, trueCase, falseCase) -); - -export default function cond(conditional, trueCase, falseCase) { - if (falseCase) { - return condDoubleCase(conditional, trueCase, falseCase); - } - - return condSingleCase(conditional, trueCase); -} diff --git a/src/components/animations/procs/index.js b/src/components/animations/procs/index.js index 2872bbd0ad3..05981405f66 100644 --- a/src/components/animations/procs/index.js +++ b/src/components/animations/procs/index.js @@ -1,16 +1,3 @@ -export { default as cond } from './cond'; export { default as interpolate } from './interpolate'; -export { divide, multiply } from './math'; -export { - and, - contains, - eq, - greaterThan, - lessThan, - not, - or, - set, -} from './operators'; export { default as timing } from './timing'; -export { default as transformOrigin } from './transformOrigin'; export { updateState } from './updateState'; diff --git a/src/components/animations/procs/math.js b/src/components/animations/procs/math.js deleted file mode 100644 index a3e29ab08eb..00000000000 --- a/src/components/animations/procs/math.js +++ /dev/null @@ -1,4 +0,0 @@ -import Animated from 'react-native-reanimated'; - -export const divide = Animated.proc((a, b) => Animated.divide(a, b)); -export const multiply = Animated.proc((a, b) => Animated.multiply(a, b)); diff --git a/src/components/animations/procs/operators.js b/src/components/animations/procs/operators.js deleted file mode 100644 index 1f2e669f59c..00000000000 --- a/src/components/animations/procs/operators.js +++ /dev/null @@ -1,12 +0,0 @@ -import Animated from 'react-native-reanimated'; - -export const and = Animated.proc((a, b) => Animated.and(a, b)); -export const eq = Animated.proc((a, b) => Animated.eq(a, b)); -export const greaterThan = Animated.proc((a, b) => Animated.greaterThan(a, b)); -export const lessThan = Animated.proc((a, b) => Animated.lessThan(a, b)); -export const not = Animated.proc(node => Animated.not(node)); -export const or = Animated.proc((a, b) => Animated.or(a, b)); -export const set = Animated.proc((node, value) => Animated.set(node, value)); - -export const contains = (values, value) => - values.reduce((acc, v) => or(acc, eq(value, v)), new Animated.Value(0)); diff --git a/src/components/animations/procs/timing.js b/src/components/animations/procs/timing.js index ef97ffb7df4..37bae3d596f 100644 --- a/src/components/animations/procs/timing.js +++ b/src/components/animations/procs/timing.js @@ -1,5 +1,4 @@ import Animated, { Easing } from 'react-native-reanimated'; -import { set } from './operators'; import { updateState } from './updateState'; const { @@ -7,6 +6,7 @@ const { Clock, clockRunning, cond, + set, startClock, stopClock, Value, diff --git a/src/components/animations/procs/transformOrigin.js b/src/components/animations/procs/transformOrigin.js deleted file mode 100644 index 2b42983cc92..00000000000 --- a/src/components/animations/procs/transformOrigin.js +++ /dev/null @@ -1,11 +0,0 @@ -import { multiply } from './math'; - -export default function transformOrigin(x, y, ...transformations) { - return [ - { translateX: x }, - { translateY: y }, - ...transformations, - { translateX: multiply(x, -1) }, - { translateY: multiply(y, -1) }, - ]; -} diff --git a/src/components/animations/procs/updateState.js b/src/components/animations/procs/updateState.js index 498959aea86..845da8bce45 100644 --- a/src/components/animations/procs/updateState.js +++ b/src/components/animations/procs/updateState.js @@ -1,13 +1,12 @@ import Animated from 'react-native-reanimated'; -import { set } from './operators'; export const updateState = Animated.proc( (value, dest, finished, position, time, frameTime, toValue) => Animated.block([ - set(finished, 0), - set(time, 0), - set(position, value), - set(frameTime, 0), - set(toValue, dest), + Animated.set(finished, 0), + Animated.set(time, 0), + Animated.set(position, value), + Animated.set(frameTime, 0), + Animated.set(toValue, dest), ]) ); diff --git a/src/components/icons/svg/ProgressIcon.js b/src/components/icons/svg/ProgressIcon.js index d8a2994b094..6c0b0ea6593 100644 --- a/src/components/icons/svg/ProgressIcon.js +++ b/src/components/icons/svg/ProgressIcon.js @@ -17,14 +17,16 @@ const { max, min, multiply, + proc, sin, sub, } = Animated; const AnimatedPath = createAnimatedComponent(Path); -const convertProgress = progress => - divide(multiply(360, min(100, max(0, progress))), 100); +const convertProgress = proc(progress => + divide(multiply(360, min(100, max(0, progress))), 100) +); function polarToCartesian(center, radius, angleInDegrees) { const angleInRadians = divide( diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index e0a3d9416b3..bfd40378018 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -16,18 +16,18 @@ expand.translateY = deviceUtils.dimensions.height; export const sheetVerticalOffset = statusBarHeight; +function setShowingModal() { + store.dispatch(updateTransitionProps({ showingModal: true })); +} + const effectOpacity = Animated.proc((closing, current) => block([ cond( - // onStart or( and(eq(closing, 0), eq(current, 0)), and(eq(closing, 1), eq(current, 1)) ), - // setShowingModal - call([], () => { - store.dispatch(updateTransitionProps({ showingModal: true })); - }) + call([], setShowingModal) ), // return opacity value of 1 1, @@ -114,12 +114,10 @@ const sheetStyleInterpolator = ({ outputRange: [0, 0, 0, 1, 1], }); - const translateY = block([ - interpolate(current, { - inputRange: [0, 1], - outputRange: [screen.height, 0], - }), - ]); + const translateY = interpolate(current, { + inputRange: [0, 1], + outputRange: [screen.height, 0], + }); return { cardStyle: { From ef0d49d26b111cd3a853b4a1b05aa4fd9f6bb6c5 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 27 Nov 2019 01:42:24 -0500 Subject: [PATCH 590/636] Fixes LoadingOverlay not displaying while importing a new seed phrase Fixes RAI-87 https://linear.app/issue/RAI-87 --- ios/Podfile.lock | 86 +- package.json | 8 +- ... react-native-gesture-handler+1.5.2.patch} | 35 +- src/components/ActivityIndicator.js | 4 +- src/components/BlurOverlay.js | 39 - src/components/TouchableBackdrop.js | 16 +- .../animations/ButtonPressAnimation.js | 7 +- src/components/animations/procs/contains.js | 9 + src/components/animations/procs/index.js | 1 + src/components/asset-list/AssetList.js | 21 +- .../layout/KeyboardFixedOpenLayout.js | 18 +- src/components/modal/LoadingOverlay.js | 32 +- .../settings-menu/SettingsSection.js | 2 +- src/hoc/index.js | 2 - src/hoc/withBlurTransitionProps.js | 33 - src/hoc/withIsWalletImporting.js | 7 - src/navigation/transitions/effects.js | 28 +- src/redux/isWalletImporting.js | 20 - src/redux/reducers.js | 2 - src/screens/CurrencySelectModal.js | 1 - src/screens/ImportSeedPhraseSheet.js | 251 ++++-- src/screens/ImportSeedPhraseSheetWithData.js | 121 +-- src/screens/ProfileScreen.js | 4 - src/screens/ProfileScreenWithData.js | 2 - yarn.lock | 845 ++++++------------ 25 files changed, 606 insertions(+), 988 deletions(-) rename patches/{react-native-gesture-handler+1.4.1.patch => react-native-gesture-handler+1.5.2.patch} (55%) delete mode 100644 src/components/BlurOverlay.js create mode 100644 src/components/animations/procs/contains.js delete mode 100644 src/hoc/withBlurTransitionProps.js delete mode 100644 src/hoc/withIsWalletImporting.js delete mode 100644 src/redux/isWalletImporting.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index dde8d3ecdf1..f94f28cecfa 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -106,7 +106,7 @@ PODS: - nanopb/encode (= 0.3.9011) - nanopb/decode (0.3.9011) - nanopb/encode (0.3.9011) - - Protobuf (3.10.0) + - Protobuf (3.11.1) - RCTRequired (1000.0.0) - RCTTypeSafety (1000.0.0): - FBLazyVector (= 1000.0.0) @@ -272,17 +272,17 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.11.1): + - react-native-camera (3.13.1): - React - - react-native-camera/RCT (= 3.11.1) - - react-native-camera/RN (= 3.11.1) - - react-native-camera/RCT (3.11.1): + - react-native-camera/RCT (= 3.13.1) + - react-native-camera/RN (= 3.13.1) + - react-native-camera/RCT (3.13.1): - React - - react-native-camera/RN (3.11.1): + - react-native-camera/RN (3.13.1): - React - react-native-mail (4.1.0): - React - - react-native-netinfo (4.6.1): + - react-native-netinfo (4.7.0): - React - react-native-randombytes (3.5.3): - React @@ -321,7 +321,9 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -369,16 +371,16 @@ PODS: - React - SDWebImage (~> 5.0) - SDWebImageWebPCoder (~> 0.2.3) - - RNFirebase (5.5.6): + - RNFirebase (5.5.7): - Firebase/Core - React - - RNFirebase/Crashlytics (= 5.5.6) - - RNFirebase/Crashlytics (5.5.6): + - RNFirebase/Crashlytics (= 5.5.7) + - RNFirebase/Crashlytics (5.5.7): - Crashlytics - Fabric - Firebase/Core - React - - RNGestureHandler (1.5.1): + - RNGestureHandler (1.5.2): - React - RNInputMask (4.1.0) - RNKeychain (4.0.1): @@ -397,9 +399,9 @@ PODS: - React - RNSVG (9.13.3): - React - - SDWebImage (5.3.2): - - SDWebImage/Core (= 5.3.2) - - SDWebImage/Core (5.3.2) + - SDWebImage (5.4.0): + - SDWebImage/Core (= 5.4.0) + - SDWebImage/Core (5.4.0) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) @@ -634,8 +636,8 @@ SPEC CHECKSUMS: Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 3c4d0c09c616a7f3435e9e300f8bed746656be83 - FBReactNativeSpec: a7541d27fd4de76c8830473a54fa8747e17886bf + FBLazyVector: 1e9ce672fda9de40382179a3a108ea347827cd90 + FBReactNativeSpec: af5495c196b3783f767fb6ced84bd2dca2f549c3 Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -650,44 +652,44 @@ SPEC CHECKSUMS: JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd - Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 50fddff608221b4ca8b129f765a2e92b79f9c261 - RCTTypeSafety: 77be7fa5f4fd4c84a8f939352b5a80decbb26661 - React: daf0e5b1018a37dde9cf6cd883ac16c699b591ca - React-Core: a640a9c5fff836386c65482e800e4bdc40161b23 - React-CoreModules: 2eee3557949a3f49d25f1178ccd68885a699d79b - React-cxxreact: c9b63613f129889ff78196039a2ad7b5dfaf78de - React-jsi: da26fa0b8b0fae04cc07da5ed9b73e26f4e9db78 - React-jsiexecutor: ee06cea084eab794d780e07c3d90fd9d41f97b66 - React-jsinspector: 620974c7af0b3ba3359c16a37e268868e0cf0dc0 + Protobuf: 20d79da7f20b5928b80043b05080b816e802659e + RCTRequired: 1023a983f0fd535e21cc4275e0aa001386dad532 + RCTTypeSafety: 84a84d4d2645283c1a8d5332715c94b4be902bdb + React: 54320dcbdbbc0d1f3f876ec977eb8e17edaa0c3d + React-Core: e366bf653323b66e9bb484a6c81ef1c4ac1bf752 + React-CoreModules: 78d68ba9795504c894af8a213077334a7da5faba + React-cxxreact: 40bc3fa5a083d54f23ac4722d82b4c8efbf01bbe + React-jsi: 73b6c676dfd9d1a78a6a24ef4e87cb788d739c1b + React-jsiexecutor: 315a918f675d09b841f6e15c7a1b8ccee1c272de + React-jsinspector: b39f08824472325d439e9fe1cb11f1cd0eb33b79 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 + react-native-camera: 1df7f9a047591bbc2c9a7ec80bd6412d3c19579f react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 - react-native-netinfo: a59d8426a8484f739fe3a95dd6ad5af1435db05f + react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 33d07af58cf3cb0add478ea1ab2ba1d903629a07 - React-RCTAnimation: b5840c31c2f6fbb7d5b1319c0e73936bcaa28d8b - React-RCTBlob: 2a89c6650e5f69d8acd041bc59b0e737b79f4d6a - React-RCTImage: 8fa6c8186733c3ee6ec5186083bc49f9c3979722 - React-RCTLinking: 3cac953827782da7ed38ba6da6af323767e207d1 - React-RCTNetwork: 70b5b9a37011f33b940eed78e49a31c05cbe9957 - React-RCTSettings: 2c77a4009001ccf2c8f8a0a102e4d00b3262261f - React-RCTText: d0980710307579b0d3b6dbfae44d8bcbd7bea030 - React-RCTVibration: cf223db4a76d8eded0245c8b50e63b0fc6ac7aaf - ReactCommon: 32bef46031a27dd9d4253fc1e0a2d1d6ce5cd91b + React-RCTActionSheet: 57286323b3d94dbfd71adad919b4ab92198e4aec + React-RCTAnimation: 19bfc497c193db2eabfaad064bbb99cd386f451a + React-RCTBlob: 5133dc8fcccb2dbdc132a0bc95ad6c21bfc022dd + React-RCTImage: 6dc50c89253897f30d35e3a8cd25c39459a9688e + React-RCTLinking: 168d287d22895c179e3f160f59510bb7f5b87d30 + React-RCTNetwork: ecf08d6116841e851b143bfa49d192572baa64ee + React-RCTSettings: 6b3f45b105467a130df0825e6024cb694f7b17c5 + React-RCTText: 5df79aef0e0d69539741307dc1188d646b819c98 + React-RCTVibration: c7ada2e890ebbe198713be8b02a66c6df83737a6 + ReactCommon: a104a1dc2cff45c02934477fb654ceb0456623ab ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 - RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 - RNGestureHandler: 7add966bb5d90ee8cf38d4341f87814474357972 + RNFirebase: 3c0d26909841ad3c72ca46d85aba333ef49903bc + RNGestureHandler: 946a7691e41df61e2c4b1884deab41a4cdc3afff RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e @@ -697,14 +699,14 @@ SPEC CHECKSUMS: RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c - SDWebImage: 6ac2eb96571bff96ecde31a987172c5934a0eb7d + SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: d12d620db862be3abc1d978608565c7dafbb6ab4 + Yoga: ae868956135bffb0ce88a1e44d4f9d56ce69a99c PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 diff --git a/package.json b/package.json index ca03f32839a..7aa05f0b11a 100644 --- a/package.json +++ b/package.json @@ -84,8 +84,9 @@ "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-firebase": "^5.5.6", - "react-native-gesture-handler": "1.5.1", + "react-native-gesture-handler": "1.5.2", "react-native-haptic-feedback": "^1.8.2", + "react-native-hooks": "^0.9.0", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", @@ -116,8 +117,9 @@ "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", + "react-navigation-hooks": "^1.1.0", "react-navigation-stack": "2.0.0-alpha.39", - "react-navigation-tabs": "2.5.6", + "react-navigation-tabs": "2.6.2", "react-navigation-tabs-v1": "1.2.0", "react-primitives": "^0.8.0", "react-redux": "^5.0.7", @@ -147,7 +149,7 @@ "devDependencies": { "@babel/core": "^7.7.2", "@babel/runtime": "^7.7.2", - "@react-native-community/cli": "2.9.0", + "@react-native-community/cli": "3.0.4", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", diff --git a/patches/react-native-gesture-handler+1.4.1.patch b/patches/react-native-gesture-handler+1.5.2.patch similarity index 55% rename from patches/react-native-gesture-handler+1.4.1.patch rename to patches/react-native-gesture-handler+1.5.2.patch index a00f64c63e5..ccdc338ff08 100644 --- a/patches/react-native-gesture-handler+1.4.1.patch +++ b/patches/react-native-gesture-handler+1.5.2.patch @@ -1,5 +1,5 @@ diff --git a/node_modules/react-native-gesture-handler/Swipeable.js b/node_modules/react-native-gesture-handler/Swipeable.js -index 2627cbf..26d1d71 100644 +index 7da6911..a3f64a3 100644 --- a/node_modules/react-native-gesture-handler/Swipeable.js +++ b/node_modules/react-native-gesture-handler/Swipeable.js @@ -176,8 +176,8 @@ export default class Swipeable extends Component { @@ -22,6 +22,39 @@ index 2627cbf..26d1d71 100644 }; _animateRow = (fromValue, toValue, velocityX) => { +diff --git a/node_modules/react-native-gesture-handler/createHandler.js b/node_modules/react-native-gesture-handler/createHandler.js +index 1fc1bbe..fc151c9 100644 +--- a/node_modules/react-native-gesture-handler/createHandler.js ++++ b/node_modules/react-native-gesture-handler/createHandler.js +@@ -2,6 +2,7 @@ import React from 'react'; + import { + findNodeHandle as findNodeHandleRN, + NativeModules, ++ NativeEventEmitter, + Touchable, + Platform, + } from 'react-native'; +@@ -16,6 +17,20 @@ function findNodeHandle(node) { + + const { UIManager = {} } = NativeModules; + ++// We need to hook up one listener so that react-native will call ++// into our module and bless our events declared there in supportedEvents ++// of RNGestureHandlerModule.m. Otherwise when we start sending ++// events later, we might crash (seemingly only in release builds) with ++// an error like: ++// Unsupported top level event type "onGestureHandlerEvent" ++// Fixes: https://github.com/kmagiera/react-native-gesture-handler/issues/320 ++const unusedEmitter = new NativeEventEmitter(NativeModules.RNGestureHandlerModule) ++// It's not enough to create an emitter -- you must also add a listener because ++// react-native does this initialization lazily ++const subscription = unusedEmitter.addListener("onGestureHandlerEvent",function(next){}) ++// Now that our events are blessed by the system we can let go of the listener ++subscription.remove() ++ + const customGHEventsConfig = { + onGestureHandlerEvent: { registrationName: 'onGestureHandlerEvent' }, + onGestureHandlerStateChange: { diff --git a/node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj/xcuserdata/christian.xcuserdatad/xcschemes/xcschememanagement.plist b/node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj/xcuserdata/christian.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..cf96c26 diff --git a/src/components/ActivityIndicator.js b/src/components/ActivityIndicator.js index 2a7842a2ba0..38af1b9bce4 100644 --- a/src/components/ActivityIndicator.js +++ b/src/components/ActivityIndicator.js @@ -3,7 +3,6 @@ import React from 'react'; import { UIActivityIndicator } from 'react-native-indicators'; import { View } from 'react-primitives'; import stylePropType from 'react-style-proptype'; -import { pure } from 'recompact'; import { colors, position } from '../styles'; const ActivityIndicator = ({ color, isInteraction, size, style }) => ( @@ -29,4 +28,5 @@ ActivityIndicator.defaultProps = { size: 25, }; -export default pure(ActivityIndicator); +const neverRerender = () => true; +export default React.memo(ActivityIndicator, neverRerender); diff --git a/src/components/BlurOverlay.js b/src/components/BlurOverlay.js deleted file mode 100644 index 63b915025ce..00000000000 --- a/src/components/BlurOverlay.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { StyleSheet, View } from 'react-native'; -import Animated from 'react-native-reanimated'; -import { BlurView } from '@react-native-community/blur'; -import { interpolate } from './animations'; - -const AnimatedBlurView = Animated.createAnimatedComponent(BlurView); - -const interpolationConfig = { - inputRange: [0, 0.1, 1], - outputRange: [0, 0, 1], -}; - -const BlurOverlay = ({ blurType, intensity }) => ( - - - -); - -BlurOverlay.propTypes = { - blurType: PropTypes.oneOf(['default', 'light', 'dark']).isRequired, - intensity: PropTypes.object, -}; - -BlurOverlay.defaultProps = { - blurType: 'dark', - intensity: new Animated.Value(0), -}; - -export default React.memo(BlurOverlay); diff --git a/src/components/TouchableBackdrop.js b/src/components/TouchableBackdrop.js index c8978cad0b5..34853a4a6ad 100644 --- a/src/components/TouchableBackdrop.js +++ b/src/components/TouchableBackdrop.js @@ -1,17 +1,16 @@ import PropTypes from 'prop-types'; import React from 'react'; import { BorderlessButton } from 'react-native-gesture-handler'; -import { withNeverRerender } from '../hoc'; import { colors, position } from '../styles'; -const TouchableBackdrop = props => ( +const TouchableBackdrop = ({ zIndex, ...props }) => ( zIndex}; - `} {...props} + {...position.centeredAsObject} + {...position.coverAsObject} + activeOpacity={1} + backgroundColor={colors.transparent} + zIndex={zIndex} /> ); @@ -23,4 +22,5 @@ TouchableBackdrop.defaultProps = { zIndex: 0, }; -export default withNeverRerender(TouchableBackdrop); +const neverRerender = () => true; +export default React.memo(TouchableBackdrop, neverRerender); diff --git a/src/components/animations/ButtonPressAnimation.js b/src/components/animations/ButtonPressAnimation.js index aae4b677c07..edf990ca71d 100644 --- a/src/components/animations/ButtonPressAnimation.js +++ b/src/components/animations/ButtonPressAnimation.js @@ -9,14 +9,11 @@ import { } from 'react-native-gesture-handler'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; -import { - contains, - transformOrigin as transformOriginUtil, -} from 'react-native-redash'; +import { transformOrigin as transformOriginUtil } from 'react-native-redash'; import stylePropType from 'react-style-proptype'; import { animations, colors } from '../../styles'; import { directionPropType } from '../../utils'; -import { interpolate, timing } from './procs'; +import { contains, interpolate, timing } from './procs'; const { and, diff --git a/src/components/animations/procs/contains.js b/src/components/animations/procs/contains.js new file mode 100644 index 00000000000..475e3d0e037 --- /dev/null +++ b/src/components/animations/procs/contains.js @@ -0,0 +1,9 @@ +import Animated from 'react-native-reanimated'; + +const { eq, or, proc, Value } = Animated; + +const containsProc = proc((acc, value, v) => or(acc, eq(value, v))); + +export default function contains(values, value) { + return values.reduce((acc, v) => containsProc(acc, value, v), new Value(0)); +} diff --git a/src/components/animations/procs/index.js b/src/components/animations/procs/index.js index 05981405f66..4ad25fffb5e 100644 --- a/src/components/animations/procs/index.js +++ b/src/components/animations/procs/index.js @@ -1,3 +1,4 @@ +export { default as contains } from './contains'; export { default as interpolate } from './interpolate'; export { default as timing } from './timing'; export { updateState } from './updateState'; diff --git a/src/components/asset-list/AssetList.js b/src/components/asset-list/AssetList.js index 4cc39fb77e0..b01ec822d2c 100644 --- a/src/components/asset-list/AssetList.js +++ b/src/components/asset-list/AssetList.js @@ -1,7 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { compose, onlyUpdateForKeys } from 'recompact'; -import { withIsWalletImporting } from '../../hoc'; +import isEqual from 'react-fast-compare'; import { safeAreaInsetValues } from '../../utils'; import { FabWrapper, FloatingActionButton } from '../fab'; import { ListFooter } from '../list'; @@ -10,6 +9,7 @@ import RecyclerAssetList from './RecyclerAssetList'; const FabSizeWithPadding = FloatingActionButton.size + FabWrapper.bottomPosition * 2; + const PaddingBottom = safeAreaInsetValues.bottom + FabSizeWithPadding - ListFooter.height; @@ -17,17 +17,16 @@ const AssetList = ({ fetchData, hideHeader, isEmpty, - isImporting, isWalletEthZero, scrollViewTracker, sections, ...props }) => - isEmpty || isImporting ? ( + isEmpty ? ( ) : ( + prev.isEmpty === next.isEmpty && + prev.isWalletEthZero === next.isWalletEthZero && + prev.sections.length === next.sections.length && + isEqual(prev.sections, next.sections); + +export default React.memo(AssetList, arePropsEqual); diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index 71688b4a878..de47b818bc7 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -1,7 +1,6 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import { Keyboard, KeyboardAvoidingView } from 'react-native'; -import { compose } from 'recompact'; import styled from 'styled-components/primitives'; import { withKeyboardHeight } from '../../hoc'; import { padding, position } from '../../styles'; @@ -34,10 +33,12 @@ class KeyboardFixedOpenLayout extends PureComponent { }; componentDidMount = () => { - this.willShowListener = Keyboard.addListener( - 'keyboardWillShow', - this.keyboardWillShow - ); + if (!this.willShowListener) { + this.willShowListener = Keyboard.addListener( + 'keyboardWillShow', + this.keyboardWillShow + ); + } }; componentWillUnmount = () => this.clearKeyboardListeners(); @@ -46,8 +47,6 @@ class KeyboardFixedOpenLayout extends PureComponent { clearKeyboardListeners = () => { if (this.willShowListener) { - // console.log('this.willShowListener', this.willShowListener); - this.willShowListener.remove(); } }; @@ -78,7 +77,4 @@ class KeyboardFixedOpenLayout extends PureComponent { }; } -export default compose( - withKeyboardHeight - // onlyUpdateForKeys(['height']), -)(KeyboardFixedOpenLayout); +export default withKeyboardHeight(KeyboardFixedOpenLayout); diff --git a/src/components/modal/LoadingOverlay.js b/src/components/modal/LoadingOverlay.js index 9b3c99465b1..7569a21c87c 100644 --- a/src/components/modal/LoadingOverlay.js +++ b/src/components/modal/LoadingOverlay.js @@ -2,16 +2,17 @@ import { BlurView } from '@react-native-community/blur'; import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components/primitives'; -import { colors, padding } from '../../styles'; +import { colors, padding, position } from '../../styles'; import ActivityIndicator from '../ActivityIndicator'; import { Centered } from '../layout'; import { Text } from '../text'; import TouchableBackdrop from '../TouchableBackdrop'; const Overlay = styled(Centered)` - ${padding(19, 19, 22)} + ${padding(19, 19, 22)}; background-color: ${colors.alpha(colors.blueGreyDark, 0.15)}; border-radius: 20; + overflow: hidden; `; const Title = styled(Text).attrs({ @@ -23,22 +24,31 @@ const Title = styled(Text).attrs({ margin-left: 8; `; -const LoadingOverlay = ({ title }) => ( - ( + - - - {title && {title}} + + + + {title && {title}} + + - + ); LoadingOverlay.propTypes = { title: PropTypes.string, }; -export default React.memo(LoadingOverlay); +const neverRerender = () => true; +export default React.memo(LoadingOverlay, neverRerender); diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index 23287408750..a53b561f878 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -122,7 +122,7 @@ const SettingsSection = ({ } - label="Import Wallet" + label="Replace Wallet" onPress={onPressImportSeedPhrase} /> state.transitionProps; - -const interpolationConfig = { - inputRange: [0, 1], - outputRange: [0, 1], -}; - -const withBlurTransitionProps = ({ - isTransitioning, - showingModal, - position, -}) => ({ - blurIntensity: - isTransitioning || showingModal - ? interpolate(position, interpolationConfig) - : new Animated.Value(0), -}); - -const withBlurTransitionPropsSelector = createSelector( - [transitionPropsSelector], - withBlurTransitionProps -); - -export default compose( - withTransitionProps, - withProps(withBlurTransitionPropsSelector) -); diff --git a/src/hoc/withIsWalletImporting.js b/src/hoc/withIsWalletImporting.js deleted file mode 100644 index a5370cb33ce..00000000000 --- a/src/hoc/withIsWalletImporting.js +++ /dev/null @@ -1,7 +0,0 @@ -import { connect } from 'react-redux'; -import { setIsWalletImporting } from '../redux/isWalletImporting'; - -const mapStateToProps = ({ isWalletImporting }) => isWalletImporting; - -export default Component => - connect(mapStateToProps, { setIsWalletImporting })(Component); diff --git a/src/navigation/transitions/effects.js b/src/navigation/transitions/effects.js index bfd40378018..100b6111ded 100644 --- a/src/navigation/transitions/effects.js +++ b/src/navigation/transitions/effects.js @@ -1,13 +1,11 @@ import { StatusBar } from 'react-native'; import Animated from 'react-native-reanimated'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; -import store from '../../redux/store'; -import { updateTransitionProps } from '../../redux/navigation'; import { interpolate } from '../../components/animations'; import { deviceUtils } from '../../utils'; import { colors } from '../../styles'; -const { and, block, call, color, cond, eq, or, SpringUtils } = Animated; +const { color, SpringUtils } = Animated; const statusBarHeight = getStatusBarHeight(true); @@ -16,26 +14,7 @@ expand.translateY = deviceUtils.dimensions.height; export const sheetVerticalOffset = statusBarHeight; -function setShowingModal() { - store.dispatch(updateTransitionProps({ showingModal: true })); -} - -const effectOpacity = Animated.proc((closing, current) => - block([ - cond( - or( - and(eq(closing, 0), eq(current, 0)), - and(eq(closing, 1), eq(current, 1)) - ), - call([], setShowingModal) - ), - // return opacity value of 1 - 1, - ]) -); - const exchangeStyleInterpolator = ({ - closing, current: { progress: current }, layouts: { screen }, }) => { @@ -52,7 +31,7 @@ const exchangeStyleInterpolator = ({ return { cardStyle: { - opacity: effectOpacity(closing, current), + opacity: 1, shadowColor: colors.black, shadowOffset: { height: 10, width: 0 }, shadowOpacity: 0.4, @@ -67,7 +46,6 @@ const exchangeStyleInterpolator = ({ }; const expandStyleInterpolator = ({ - closing, current: { progress: current }, layouts: { screen }, }) => { @@ -84,7 +62,7 @@ const expandStyleInterpolator = ({ return { cardStyle: { - opacity: effectOpacity(closing, current), + opacity: 1, shadowColor: colors.dark, shadowOffset: { height: 10, width: 0 }, shadowOpacity: 0.6, diff --git a/src/redux/isWalletImporting.js b/src/redux/isWalletImporting.js deleted file mode 100644 index 88f3a483fe8..00000000000 --- a/src/redux/isWalletImporting.js +++ /dev/null @@ -1,20 +0,0 @@ -import produce from 'immer'; - -// -- Constants --------------------------------------- // -const SET_IS_WALLET_IMPORTING = 'isWalletImporting/SET_IS_WALLET_IMPORTING'; - -export const setIsWalletImporting = payload => dispatch => - dispatch({ - payload, - type: SET_IS_WALLET_IMPORTING, - }); - -// -- Reducer ----------------------------------------- // -const INITIAL_STATE = { isImporting: false }; - -export default (state = INITIAL_STATE, action) => - produce(state, draft => { - if (action.type === SET_IS_WALLET_IMPORTING) { - draft.isImporting = action.payload; - } - }); diff --git a/src/redux/reducers.js b/src/redux/reducers.js index 28a57b1bb20..7ae90502b48 100644 --- a/src/redux/reducers.js +++ b/src/redux/reducers.js @@ -8,7 +8,6 @@ import gas from './gas'; import imageDimensionsCache from './imageDimensionsCache'; import isWalletEmpty from './isWalletEmpty'; import isWalletEthZero from './isWalletEthZero'; -import isWalletImporting from './isWalletImporting'; import keyboardHeight from './keyboardHeight'; import navigation from './navigation'; import nonce from './nonce'; @@ -31,7 +30,6 @@ export default combineReducers({ imageDimensionsCache, isWalletEmpty, isWalletEthZero, - isWalletImporting, keyboardHeight, navigation, nonce, diff --git a/src/screens/CurrencySelectModal.js b/src/screens/CurrencySelectModal.js index 0f70855082d..611443b8dbe 100644 --- a/src/screens/CurrencySelectModal.js +++ b/src/screens/CurrencySelectModal.js @@ -208,7 +208,6 @@ class CurrencySelectModal extends Component { showFavoriteButton: type === CurrencySelectionTypes.output, }} listItems={listItems} - searchQuery={searchQuery} showList={isFocused} type={type} /> diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index 8434a78b89c..793497c8519 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -1,18 +1,23 @@ +import analytics from '@segment/analytics-react-native'; import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { KeyboardAvoidingView } from 'react-native'; +import { useClipboard } from 'react-native-hooks'; import { BorderlessButton } from 'react-native-gesture-handler'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; -import { pure } from 'recompact'; +import { useNavigation } from 'react-navigation-hooks'; import styled from 'styled-components/primitives'; +import { Alert } from '../components/alerts'; import { Icon } from '../components/icons'; import { MultiLineInput } from '../components/inputs'; -import { Centered, Column, Row } from '../components/layout'; +import { Centered, Column, Row, RowWithMargins } from '../components/layout'; import { LoadingOverlay } from '../components/modal'; import { Text } from '../components/text'; import { sheetVerticalOffset } from '../navigation/transitions/effects'; -import { borders, colors, padding } from '../styles'; +import { borders, colors, padding, shadow } from '../styles'; +import { isValidSeed as validateSeed } from '../helpers/validators'; +const keyboardVerticalOffset = sheetVerticalOffset + 19; const statusBarHeight = getStatusBarHeight(true); const Container = styled(Column).attrs({ @@ -33,94 +38,166 @@ const HandleIcon = styled(Icon).attrs({ margin-bottom: 2; `; -const ImportButton = styled(Row).attrs({ - align: 'center', - component: BorderlessButton, -})` - ${padding(6, 8)} - background: ${props => (props.disabled ? '#D2D3D7' : colors.appleBlue)}; +const StyledImportButton = styled(BorderlessButton)` + ${padding(6, 8)}; + ${shadow.build(0, 6, 10, colors.dark, 0.14)}; + background-color: ${({ disabled }) => + disabled ? '#D2D3D7' : colors.appleBlue}; border-radius: 15px; - shadow-color: ${colors.dark}; - shadow-offset: 0px 6px; - shadow-opacity: 0.14; - shadow-radius: 10; `; -const ImportSeedPhraseSheet = ({ - isClipboardContentsValidSeedPhrase, - isImporting, - isSeedPhraseValid, - onImportSeedPhrase, - onInputChange, - onPasteSeedPhrase, - onPressEnterKey, - seedPhrase, -}) => ( - - - - Import - - - - - - - - {!!seedPhrase && ( - - )} - - {seedPhrase ? 'Import' : 'Paste'} - - - - - {isImporting && } - +const ConfirmImportAlert = onSuccess => + Alert({ + buttons: [ + { + onPress: onSuccess, + style: 'destructive', + text: 'Delete and Import', + }, + { + style: 'cancel', + text: 'Cancel', + }, + ], + message: + 'Importing this private key will overwrite your existing wallet. Before continuing, please make sure you’ve transferred its contents or backed up its private key.', + title: 'Are you sure you want to import?', + }); + +const ImportButton = ({ disabled, onPress, seedPhrase }) => ( + + + {!!seedPhrase && ( + + )} + + {seedPhrase ? 'Import' : 'Paste'} + + + ); +const ImportSeedPhraseSheet = ({ initializeWallet, isEmpty }) => { + const [clipboard] = useClipboard(); + const { navigate, setParams } = useNavigation(); + const [isImporting, setImporting] = useState(false); + const [seedPhrase, setSeedPhrase] = useState(''); + + const isClipboardValidSeedPhrase = useMemo(() => validateSeed(clipboard), [ + clipboard, + ]); + + const isSeedPhraseValid = useMemo(() => validateSeed(seedPhrase), [ + seedPhrase, + ]); + + const toggleImporting = useCallback( + newImportingState => { + setImporting(newImportingState); + setParams({ gesturesEnabled: !newImportingState }); + }, + [setImporting, setParams] + ); + + const handleSetSeedPhrase = useCallback( + text => { + if (isImporting) return null; + return setSeedPhrase(text); + }, + [isImporting, setSeedPhrase] + ); + + const onPressImportButton = () => { + if (isSeedPhraseValid && seedPhrase) { + return ConfirmImportAlert(() => toggleImporting(true)); + } + + if (isClipboardValidSeedPhrase && clipboard) { + return handleSetSeedPhrase(clipboard); + } + }; + + useEffect(() => { + if (isImporting) { + const id = setTimeout(() => { + initializeWallet(seedPhrase.trim()) + .then(success => { + if (success) { + toggleImporting(false); + analytics.track('Imported seed phrase', { + hadPreviousAddressWithValue: isEmpty, + }); + navigate('WalletScreen'); + } else { + toggleImporting(false); + } + }) + .catch(error => { + toggleImporting(false); + console.error('error importing seed phrase: ', error); + }); + }, 50); + + return () => clearTimeout(id); + } + }, [ + initializeWallet, + isEmpty, + isImporting, + navigate, + seedPhrase, + toggleImporting, + ]); + + return ( + + + + Import + + + + + + + + + {isImporting && ( + + )} + + + ); +}; + ImportSeedPhraseSheet.propTypes = { - isClipboardContentsValidSeedPhrase: PropTypes.bool, - isImporting: PropTypes.bool, - isSeedPhraseValid: PropTypes.bool, - onImportSeedPhrase: PropTypes.func, - onInputChange: PropTypes.func, - onPasteSeedPhrase: PropTypes.func, - onPressEnterKey: PropTypes.func, - seedPhrase: PropTypes.string, + initializeWallet: PropTypes.func, + isEmpty: PropTypes.bool, }; -export default pure(ImportSeedPhraseSheet); +const neverRerender = () => true; +export default React.memo(ImportSeedPhraseSheet, neverRerender); diff --git a/src/screens/ImportSeedPhraseSheetWithData.js b/src/screens/ImportSeedPhraseSheetWithData.js index aa89e121aca..c83ba754591 100644 --- a/src/screens/ImportSeedPhraseSheetWithData.js +++ b/src/screens/ImportSeedPhraseSheetWithData.js @@ -1,128 +1,13 @@ -import analytics from '@segment/analytics-react-native'; import { get } from 'lodash'; -import { Clipboard, InteractionManager, Linking } from 'react-native'; -import { withNavigation } from 'react-navigation'; -import { - compose, - lifecycle, - onlyUpdateForKeys, - withHandlers, - withProps, - withState, -} from 'recompact'; -import { Alert } from '../components/alerts'; -import { withDataInit, withIsWalletEmpty, withIsWalletImporting } from '../hoc'; +import { compose, pure } from 'recompact'; +import { withDataInit, withIsWalletEmpty } from '../hoc'; import { deviceUtils } from '../utils'; import ImportSeedPhraseSheet from './ImportSeedPhraseSheet'; -import { isValidSeed as validateSeed } from '../helpers/validators'; - -const ConfirmImportAlert = onSuccess => - Alert({ - buttons: [ - { - onPress: onSuccess, - style: 'destructive', - text: 'Delete and Import', - }, - { - style: 'cancel', - text: 'Cancel', - }, - ], - message: - 'Importing this private key will overwrite your existing wallet. Before continuing, please make sure you’ve transferred its contents or backed up its private key.', - title: 'Are you sure you want to import?', - }); const ImportSeedPhraseSheetWithData = compose( withDataInit, withIsWalletEmpty, - withIsWalletImporting, - withNavigation, - withState('clipboardContents', 'setClipboardContents', ''), - withState('seedPhrase', 'setSeedPhrase', ''), - withHandlers({ - importSeedPhrase: ({ - initializeWallet, - isEmpty, - navigation, - seedPhrase, - setIsWalletImporting, - }) => async () => { - try { - const address = await initializeWallet(seedPhrase.trim()); - if (address) { - analytics.track('Imported seed phrase', { - hadPreviousAddressWithValue: isEmpty, - }); - setIsWalletImporting(false); - navigation.navigate('WalletScreen'); - } else { - setIsWalletImporting(false); - } - } catch (error) { - setIsWalletImporting(false); - console.error('error importing seed phrase: ', error); - } - }, - }), - withHandlers({ - getClipboardContents: ({ setClipboardContents }) => async () => - Clipboard.getString().then(setClipboardContents), - onImportSeedPhrase: ({ setIsWalletImporting }) => () => - ConfirmImportAlert(() => setIsWalletImporting(true)), - onInputChange: ({ isImporting, setSeedPhrase }) => ({ nativeEvent }) => { - if (!isImporting) { - setSeedPhrase(nativeEvent.text); - } - }, - onPasteSeedPhrase: ({ setSeedPhrase }) => () => { - Clipboard.getString() - .then(setSeedPhrase) - .catch(error => console.log(error)); - }, - onPressHelp: () => () => Linking.openURL('http://rainbow.me'), - }), - withProps(({ clipboardContents, seedPhrase }) => ({ - isClipboardContentsValidSeedPhrase: validateSeed(clipboardContents), - isSeedPhraseValid: validateSeed(seedPhrase), - })), - onlyUpdateForKeys([ - 'isClipboardContentsValidSeedPhrase', - 'isImporting', - 'isSeedPhraseValid', - 'seedPhrase', - ]), - lifecycle({ - componentDidMount() { - this.props.getClipboardContents(); - }, - componentDidUpdate(prevProps) { - const { - getClipboardContents, - importSeedPhrase, - isImporting, - navigation, - } = this.props; - - getClipboardContents(); - - if (isImporting !== prevProps.isImporting) { - navigation.setParams({ gesturesEnabled: !isImporting }); - } - - if (!prevProps.isImporting && isImporting) { - InteractionManager.runAfterInteractions(importSeedPhrase); - } - }, - }), - withHandlers({ - onPressEnterKey: ({ onImportSeedPhrase, seedPhrase }) => () => { - if (seedPhrase) { - onImportSeedPhrase(); - } - }, - }) + pure )(ImportSeedPhraseSheet); ImportSeedPhraseSheetWithData.navigationOptions = ({ navigation }) => ({ diff --git a/src/screens/ProfileScreen.js b/src/screens/ProfileScreen.js index d05dd02d982..6669a38ae10 100644 --- a/src/screens/ProfileScreen.js +++ b/src/screens/ProfileScreen.js @@ -2,7 +2,6 @@ import PropTypes from 'prop-types'; import React from 'react'; import { ActivityList } from '../components/activity-list'; import AddFundsInterstitial from '../components/AddFundsInterstitial'; -import BlurOverlay from '../components/BlurOverlay'; import { BackButton, Header, HeaderButton } from '../components/header'; import { FlexItem, Page } from '../components/layout'; import { Icon } from '../components/icons'; @@ -11,7 +10,6 @@ import { colors, position } from '../styles'; const ProfileScreen = ({ accountAddress, - blurIntensity, isEmpty, nativeCurrency, navigation, @@ -48,13 +46,11 @@ const ProfileScreen = ({ transactionsCount={transactionsCount} /> {isEmpty && } - ); ProfileScreen.propTypes = { accountAddress: PropTypes.string, - blurIntensity: PropTypes.object, isEmpty: PropTypes.bool, nativeCurrency: PropTypes.string, navigation: PropTypes.object, diff --git a/src/screens/ProfileScreenWithData.js b/src/screens/ProfileScreenWithData.js index d9f951f2c8d..05c1402e642 100644 --- a/src/screens/ProfileScreenWithData.js +++ b/src/screens/ProfileScreenWithData.js @@ -3,7 +3,6 @@ import { setDisplayName } from 'recompose'; import { withAccountSettings, withAccountTransactions, - withBlurTransitionProps, withIsWalletEmpty, withRequests, } from '../hoc'; @@ -13,7 +12,6 @@ export default compose( setDisplayName('ProfileScreen'), withAccountSettings, withAccountTransactions, - withBlurTransitionProps, withIsWalletEmpty, withRequests, withHandlers({ diff --git a/yarn.lock b/yarn.lock index 9a08f3634d0..14f0a82f361 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,14 +10,14 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.2": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.4.tgz#37e864532200cb6b50ee9a4045f5f817840166ab" - integrity sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ== + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.5.tgz#ae1323cd035b5160293307f50647e83f8ba62f7e" + integrity sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw== dependencies: "@babel/code-frame" "^7.5.5" "@babel/generator" "^7.7.4" "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.4" + "@babel/parser" "^7.7.5" "@babel/template" "^7.7.4" "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" @@ -145,10 +145,10 @@ dependencies: "@babel/types" "^7.7.4" -"@babel/helper-module-transforms@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz#8d7cdb1e1f8ea3d8c38b067345924ac4f8e0879a" - integrity sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA== +"@babel/helper-module-transforms@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz#d044da7ffd91ec967db25cd6748f704b6b244835" + integrity sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw== dependencies: "@babel/helper-module-imports" "^7.7.4" "@babel/helper-simple-access" "^7.7.4" @@ -240,10 +240,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.4.tgz#75ab2d7110c2cf2fa949959afb05fa346d2231bb" - integrity sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.5.tgz#cbf45321619ac12d83363fcf9c94bb67fa646d71" + integrity sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig== "@babel/plugin-external-helpers@^7.0.0": version "7.7.4" @@ -293,9 +293,9 @@ "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" "@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.7.4.tgz#3f04c2de1a942cbd3008324df8144b9cbc0ca0ba" - integrity sha512-JmgaS+ygAWDR/STPe3/7y0lNlHgS+19qZ9aC06nYLwQ/XB7c0q5Xs+ksFU3EDnp9EiEsO0dnRAOKeyLHTZuW3A== + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.7.5.tgz#f0835f044cef85b31071a924010a2a390add11d4" + integrity sha512-sOwFqT8JSchtJeDD+CjmWCaiFoLxY4Ps7NjvwHC/U7l4e9i5pTRNt8nDMIFSOUL+ncFbYSwruHM8WknYItWdXw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-chaining" "^7.7.4" @@ -475,11 +475,11 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz#bee4386e550446343dd52a571eda47851ff857a3" - integrity sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA== + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz#1d27f5eb0bcf7543e774950e5b2fa782e637b345" + integrity sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q== dependencies: - "@babel/helper-module-transforms" "^7.7.4" + "@babel/helper-module-transforms" "^7.7.5" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.7.4" babel-plugin-dynamic-import-node "^2.3.0" @@ -540,16 +540,16 @@ "@babel/plugin-syntax-jsx" "^7.7.4" "@babel/plugin-transform-regenerator@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz#d18eac0312a70152d7d914cbed2dc3999601cfc0" - integrity sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw== + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz#3a8757ee1a2780f390e89f246065ecf59c26fce9" + integrity sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw== dependencies: regenerator-transform "^0.14.0" "@babel/plugin-transform-runtime@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.4.tgz#51fe458c1c1fa98a8b07934f4ed38b6cd62177a6" - integrity sha512-O8kSkS5fP74Ad/8pfsCMGa8sBRdLxYoSReaARRNSz3FbFQj3z/QUvoUmJ28gn9BO93YfnXc3j+Xyaqe8cKDNBQ== + version "7.7.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.6.tgz#4f2b548c88922fb98ec1c242afd4733ee3e12f61" + integrity sha512-tajQY+YmXR7JjTwRvwL4HePqoL3DYxpYXIHKVvrOIvJmeHe2y1w4tz5qz9ObUDC9m76rCzIMPyn4eERuwA4a4A== dependencies: "@babel/helper-module-imports" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" @@ -615,9 +615,9 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.4.tgz#b23a856751e4bf099262f867767889c0e3fe175b" - integrity sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw== + version "7.7.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" + integrity sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw== dependencies: regenerator-runtime "^0.13.2" @@ -692,9 +692,9 @@ integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": - version "5.0.0-beta.132" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.132.tgz#d7d8585204df11a812e53e2547f3bb3070b97efd" - integrity sha512-k/DijFpuADnKczHlhuGrCwuq7fAYjTuoOe26h50JncYs5ZiKmtht3zzllVUs75jEac2KjEV6zRMOnFvG7hDsmg== + version "5.0.0-beta.133" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.0-beta.133.tgz#b6bf2c298da5701c61038e4cdfac2e0038b884ce" + integrity sha512-7SjGhZ3xClqlmzqNNzESKlHbBeEzDWXIeKUBbSzK3Ce9PgK6uboiNe53fgqzhrRVOMhD1J4Q+oIm4DsTv37FWg== dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" "@ethersproject/bytes" ">=5.0.0-beta.129" @@ -704,9 +704,9 @@ bn.js "^4.4.0" "@ethersproject/bignumber@>=5.0.0-beta.130": - version "5.0.0-beta.134" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.134.tgz#771fa3f1f8315aba27ea0e479d1e5953ce83f68b" - integrity sha512-gOqtMLl5ZTufp7ugt0XUYrTT5CawkoESDs55/E4BtgYhaEC43omiWPyHy6dGDY8QnJB2uMV+YE00ubuhxiG00Q== + version "5.0.0-beta.135" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.0-beta.135.tgz#9d464df8967f5d314d109497e4f25ab82314c098" + integrity sha512-7Tw2NgHzK7o+70bwyoaIZCbRycz+saWNU0sLOYnis3qYXwYsdTL+Rm0PMGA2v4jyHJt7BPS2pxGww+akVXbX+w== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/logger" ">=5.0.0-beta.129" @@ -714,50 +714,50 @@ bn.js "^4.4.0" "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0-beta.126": - version "5.0.0-beta.133" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.133.tgz#9f0d2b40cfeaf9c88d93e51b3472135779e26119" - integrity sha512-5eNRc9+skcRocMBYbyMtlW1rwuPCYMPZJYIDGIbVtxY0+dC/SJVg7KbSOk9NLAROhrmh7NwjIs9fnAKe+KzjvQ== + version "5.0.0-beta.134" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.0-beta.134.tgz#eb6b9a200be02d6d539f90086fbfad26ec63d0d5" + integrity sha512-2BULy5x0BuHPRzuGjEYWndJieDaRAaZUbMk53fZjH4yjhKMHDGADQQOtaSD4wN+H183YOXMGdtlCrRGJ1N+uNg== dependencies: "@ethersproject/logger" ">=5.0.0-beta.129" "@ethersproject/constants@>=5.0.0-beta.128": - version "5.0.0-beta.131" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.131.tgz#7d976e80e1e2c1900cdb23066071ab71ec2c9945" - integrity sha512-6goMTEnnPCYGCiNL80KbaLeaMvFQjdbAGmXD91zOm3zKJKEw92kQ4vJDR0YYnbw/TMRWi+8wI7Vz+y83BOUBQw== + version "5.0.0-beta.132" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.0-beta.132.tgz#068cc97493fbc1543299bda79e0e726310e129a4" + integrity sha512-ioO7Ez8Xatk5z3lVzzEhRjXng1le1sTzfuD3v8gUozrzgLXyl0X81Go1Nadj7qPgo68HziIFcm5kRFp4SdJa0A== dependencies: "@ethersproject/bignumber" ">=5.0.0-beta.130" "@ethersproject/keccak256@>=5.0.0-beta.127": - version "5.0.0-beta.130" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.130.tgz#fd9c2adefeb31f0abb137af35a9eda2216a58584" - integrity sha512-wE2kkSqhXUYbr3VB7YSaQ16lVoyCiIUlSJ6UBckY55gPYIgpAaHb2TCY4rtxeKGpHkv/j+1DyKGB/UYSb+KCew== + version "5.0.0-beta.131" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.0-beta.131.tgz#b5778723ee75208065b9b9ad30c71d480f41bb31" + integrity sha512-KQnqMwGV0IMOjAr/UTFO8DuLrmN1uaMvcV3zh9hiXhh3rCuY+WXdeUh49w1VQ94kBKmaP0qfGb7z4SdhUWUHjw== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" js-sha3 "0.5.7" "@ethersproject/logger@>=5.0.0-beta.129": - version "5.0.0-beta.132" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.132.tgz#310ab1318749ddab21c881301140b6d6b5723aab" - integrity sha512-qIUvCrtNKDjyy6TgYs9fgRZ0Ma3A8iziAh9jJ8aEdvyg70a8PLw7t+jN7S836VhbXaxjrKBsIZTHqWuzVFCVgQ== + version "5.0.0-beta.133" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.0-beta.133.tgz#2d62d495ed413c7045054d4f99a0fb4920079b2e" + integrity sha512-1ISf7rFKFbMHlEB37JS7Oy3FgFlvzF2Ze2uFZMJHGKp9xgDvFy1VHNMBM1KrJPK4AqCZXww0//e2keLsN3g/Cw== "@ethersproject/properties@>=5.0.0-beta.131": - version "5.0.0-beta.134" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.134.tgz#bc751854c0040756f4ce96dab9097de51f3e8552" - integrity sha512-y1/F8X+tJPOGxx31e9KYPpKLFbempySb7CBL+t4oNvWD8StC2coECKUW2tI/mSTFQ3mW5X9JWcaYY/N6hvBYug== + version "5.0.0-beta.135" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.0-beta.135.tgz#51a0a5d72ca034b5ae845d43ed409eb3576a3ca7" + integrity sha512-R4ROFaFh86n09eE+MWMPzaB87V5OSgqu0gtQ7LjUvkFF3eqdpdvLVD4N93hvCKNZcjGHI4WmazDUlpuXZVgDkA== dependencies: "@ethersproject/logger" ">=5.0.0-beta.129" "@ethersproject/rlp@>=5.0.0-beta.126": - version "5.0.0-beta.130" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.130.tgz#3f219265fa6216316961cd3bc5fbe0d25439da87" - integrity sha512-VupRQw1Pxxnl1Fr9q0sohZAqhuzU+rt1HJxuUW+5ZeLv7EKwdNxUjSLzmS91os64L3cxv39mh4844UktI1FVVg== + version "5.0.0-beta.131" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.0-beta.131.tgz#4a0c0c314e26ed7f01be6bca16308d629a8022d2" + integrity sha512-sUJUGbywlnuk2frkSWzWiGenTrwOnrKQaNKJqjCGmK35x0WIzcR4/1gC6jWa0hpWJT6Seq6J6SCT5CS+ZWCFNw== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/strings@^5.0.0-beta.125": - version "5.0.0-beta.134" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.134.tgz#d15562ed260e961fd278964169707f12de7130b0" - integrity sha512-eqX+b13uC6goxdaZk7vzrwCaPKVGgNM60lTQ642GZVjXwYdqeGFqOMQXi6q9DDXzgx6WGXIGTjl9GS3qwKYQXg== + version "5.0.0-beta.135" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.0-beta.135.tgz#7754a805831383bf1838cd097d26c6135e96a745" + integrity sha512-MiZSJPhAQggXb3XA/XS4jmwmj5CsknMXk/XIzNZB7eYqEGA2i7sQV7+o6DOE+3lq5k5BhB8OaDziogNCOGAouA== dependencies: "@ethersproject/bytes" ">=5.0.0-beta.129" "@ethersproject/constants" ">=5.0.0-beta.128" @@ -997,19 +997,6 @@ dependencies: serve-static "^1.13.1" -"@react-native-community/cli-platform-android@^2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" - integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== - dependencies: - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - execa "^1.0.0" - jetifier "^1.6.2" - logkitty "^0.6.0" - slash "^3.0.0" - xmldoc "^1.1.2" - "@react-native-community/cli-platform-android@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz#e652abce79a7c1e3a8280228123e99df2c4b97b6" @@ -1023,15 +1010,6 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^2.9.0": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.10.0.tgz#ee494d2f9a8f8727bd5eb3c446f22ebb5429b624" - integrity sha512-z5BQKyT/bgTSdHhvsFNf++6VP50vtOOaITnNKvw4954wURjv5JOQh1De3BngyaDOoGfV1mXkCxutqAXqSeuIjw== - dependencies: - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - xcode "^2.0.0" - "@react-native-community/cli-platform-ios@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz#3a48a449c0c33af3b0b3d19d3256de99388fe15f" @@ -1042,16 +1020,6 @@ js-yaml "^3.13.1" xcode "^2.0.0" -"@react-native-community/cli-tools@^2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb" - integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ== - dependencies: - chalk "^2.4.2" - lodash "^4.17.5" - mime "^2.4.1" - node-fetch "^2.5.0" - "@react-native-community/cli-tools@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0.tgz#fe48b80822ed7e49b8af051f9fe41e22a2a710b1" @@ -1067,46 +1035,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652" integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg== -"@react-native-community/cli@2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" - integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.9.0" - "@react-native-community/cli-platform-ios" "^2.9.0" - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - commander "^2.19.0" - compression "^1.7.1" - connect "^3.6.5" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - envinfo "^7.1.0" - errorhandler "^1.5.0" - execa "^1.0.0" - fs-extra "^7.0.1" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.54.1" - metro-config "^0.54.1" - metro-core "^0.54.1" - metro-react-native-babel-transformer "^0.54.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-notifier "^5.2.1" - open "^6.2.0" - ora "^3.4.0" - plist "^3.0.0" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" - ws "^1.1.0" - -"@react-native-community/cli@^3.0.0": +"@react-native-community/cli@3.0.4", "@react-native-community/cli@^3.0.0": version "3.0.4" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.4.tgz#a9dba1bc77855a6e45fccaabb017360645d936bb" integrity sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA== @@ -1156,9 +1085,9 @@ integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== "@react-native-community/netinfo@^4.6.0": - version "4.6.1" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.1.tgz#09960b49217d555e54144f54e63485fe55d673ad" - integrity sha512-RIcrNzVnkes6/d5jFprce8i6ruUO9+/FVZZgejlu/TSnysyFXHNJKgcIqxbKx+7XfQxfjrCGeCvsfYxrFrU0zw== + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.7.0.tgz#7482d36836cac69d0a0ae25581f65bc472639930" + integrity sha512-a/sDB+AsLEUNmhAUlAaTYeXKyQdFGBUfatqKkX5jluBo2CB3OAuTHfm7rSjcaLB9EmG5iSq3fOTpync2E7EYTA== "@react-navigation/core@^3.5.1": version "3.5.1" @@ -1407,14 +1336,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.12.tgz#529bc3e73dbb35dd9e90b0a1c83606a9d3264bdb" - integrity sha512-MGuvYJrPU0HUwqF7LqvIj50RZUX23Z+m583KBygKYUZLlZ88n6w28XRNJRJgsHukLEnLz6w6SvxZoLgbr5wLqQ== - -"@types/node@^10.3.2": - version "10.17.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.5.tgz#c1920150f7b90708a7d0f3add12a06bc9123c055" - integrity sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA== + version "12.12.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.16.tgz#3ebcbd7bf978fa4c5120fee8be57083271a8b3ac" + integrity sha512-vRuMyoOr5yfNf8QWxXegOjeyjpWJxFePzHzmBOIzDIzo+rSqF94RW0PkS6y4T2+VjAWLXHWrfbIJY3E3aS7lUw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1627,9 +1551,9 @@ acorn@^5.5.3: integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" - integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== + version "6.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" + integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== acorn@^7.1.0: version "7.1.0" @@ -1781,7 +1705,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== @@ -2003,12 +1927,12 @@ atob@^2.1.1: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.5.1: - version "9.7.2" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.2.tgz#26cf729fbb709323b40171a874304884dcceffed" - integrity sha512-LCAfcdej1182uVvPOZnytbq61AhnOZ/4JelDaJGDeNwewyU1AMaNthcHsyz1NRjTmd2FkurMckLWfkHg3Z//KA== + version "9.7.3" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.3.tgz#fd42ed03f53de9beb4ca0d61fb4f7268a9bb50b4" + integrity sha512-8T5Y1C5Iyj6PgkPSFd0ODvK9DIleuPKUPYniNxybS47g2k2wFgLZ46lGQHlBuGKIAEV8fbCDfKCCRS1tvOgc3Q== dependencies: - browserslist "^4.7.3" - caniuse-lite "^1.0.30001010" + browserslist "^4.8.0" + caniuse-lite "^1.0.30001012" chalk "^2.4.2" normalize-range "^0.1.2" num2fraction "^1.2.2" @@ -2021,9 +1945,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + version "1.9.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" + integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A== axios@^0.19.0: version "0.19.0" @@ -2469,16 +2393,16 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.7.3: - version "4.7.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.3.tgz#02341f162b6bcc1e1028e30624815d4924442dc3" - integrity sha512-jWvmhqYpx+9EZm/FxcZSbUZyDEvDTLDi3nSAKbzEkyWvtI0mNSmUosey+5awDW1RUlrgXbQb5A6qY1xQH9U6MQ== +browserslist@^4.8.0: + version "4.8.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" + integrity sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA== dependencies: - caniuse-lite "^1.0.30001010" - electron-to-chromium "^1.3.306" - node-releases "^1.1.40" + caniuse-lite "^1.0.30001015" + electron-to-chromium "^1.3.322" + node-releases "^1.1.42" -bser@^2.0.0: +bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== @@ -2641,10 +2565,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001010: - version "1.0.30001011" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001011.tgz#0d6c4549c78c4a800bb043a83ca0cbe0aee6c6e1" - integrity sha512-h+Eqyn/YA6o6ZTqpS86PyRmNWOs1r54EBDcd2NTwwfsXQ8re1B38SnB+p2RKF8OUsyEIjeDU8XGec1RGO/wYCg== +caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001015: + version "1.0.30001015" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz#15a7ddf66aba786a71d99626bc8f2b91c6f0f5f0" + integrity sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ== capture-exit@^2.0.0: version "2.0.0" @@ -2843,6 +2767,15 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + clone-deep@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" @@ -2966,7 +2899,7 @@ colors@^1.0.3: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -3113,9 +3046,9 @@ core-js@^1.0.0: integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1: - version "2.6.10" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f" - integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA== + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -3257,7 +3190,7 @@ css-to-react-native@^2.2.2: css-color-keywords "^1.0.0" postcss-value-parser "^3.3.0" -css-tree@1.0.0-alpha.37, css-tree@^1.0.0-alpha.37: +css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== @@ -3265,6 +3198,14 @@ css-tree@1.0.0-alpha.37, css-tree@^1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" +css-tree@^1.0.0-alpha.37: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + css-what@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" @@ -3694,27 +3635,17 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.7.2: - version "2.7.4" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" - integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== - -electron-to-chromium@^1.3.306: - version "1.3.311" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.311.tgz#73baa361e2b1f44b7b4f1a443aaa1372f8074ebb" - integrity sha512-7GH6RKCzziLzJ9ejmbiBEdzHZsc6C3eRpav14dmRfTWMpNgMqpP1ukw/FU/Le2fR+ep642naq7a23xNdmh2s+A== +ejs@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.1.tgz#30c8f6ee9948502cc32e85c37a3f8b39b5a614a5" + integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw== -elliptic@6.3.3: - version "6.3.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" - integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - inherits "^2.0.1" +electron-to-chromium@^1.3.322: + version "1.3.322" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" + integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA== -elliptic@^6.0.0: +elliptic@6.5.2, elliptic@^6.0.0: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== @@ -3822,22 +3753,22 @@ errorhandler@^1.5.0: escape-html "~1.0.3" es-abstract@^1.12.0, es-abstract@^1.15.0, es-abstract@^1.5.1, es-abstract@^1.7.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.0.tgz#d3a26dc9c3283ac9750dca569586e976d9dcc06d" - integrity sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg== + version "1.16.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.3.tgz#52490d978f96ff9f89ec15b5cf244304a5bca161" + integrity sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw== dependencies: - es-to-primitive "^1.2.0" + es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" - has-symbols "^1.0.0" + has-symbols "^1.0.1" is-callable "^1.1.4" is-regex "^1.0.4" - object-inspect "^1.6.0" + object-inspect "^1.7.0" object-keys "^1.1.1" string.prototype.trimleft "^2.1.0" string.prototype.trimright "^2.1.0" -es-to-primitive@^1.2.0: +es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== @@ -3943,11 +3874,11 @@ eslint-import-resolver-node@^0.3.1: resolve "^1.5.0" eslint-module-utils@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c" - integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw== + version "2.5.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz#cdf0b40d623032274ccd2abd7e64c4e524d6e19c" + integrity sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw== dependencies: - debug "^2.6.8" + debug "^2.6.9" pkg-dir "^2.0.0" eslint-plugin-babel@^5.3.0: @@ -3965,6 +3896,11 @@ eslint-plugin-eslint-comments@^3.1.1: escape-string-regexp "^1.0.5" ignore "^5.0.5" +eslint-plugin-eslint-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5" + integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg== + eslint-plugin-flowtype@^3.6.1: version "3.13.0" resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.13.0.tgz#e241ebd39c0ce519345a3f074ec1ebde4cf80f2c" @@ -4036,19 +3972,20 @@ eslint-plugin-react-native@^3.6.0: eslint-plugin-react-native-globals "^0.1.1" eslint-plugin-react@^7.12.4: - version "7.16.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.16.0.tgz#9928e4f3e2122ed3ba6a5b56d0303ba3e41d8c09" - integrity sha512-GacBAATewhhptbK3/vTP09CbFrgUJmBSaaRcWdbQLFvUZy9yVcQxigBNHGPU/KE2AyHpzj3AWXpxoMTsIDiHug== + version "7.17.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz#a31b3e134b76046abe3cd278e7482bd35a1d12d7" + integrity sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" + eslint-plugin-eslint-plugin "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.2.1" + jsx-ast-utils "^2.2.3" object.entries "^1.1.0" - object.fromentries "^2.0.0" + object.fromentries "^2.0.1" object.values "^1.1.0" prop-types "^15.7.2" - resolve "^1.12.0" + resolve "^1.13.1" eslint-plugin-relay@1.4.1: version "1.4.1" @@ -4091,9 +4028,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.6.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.0.tgz#766162e383b236e61d873697f82c3a3e41392020" - integrity sha512-dQpj+PaHKHfXHQ2Imcw5d853PTvkUGbHk/MR68KQUl98EgKDCdh4vLRH1ZxhqeQjQFJeg8fgN0UwmNhN3l8dDQ== + version "6.7.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" + integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4187,14 +4124,13 @@ eth-contract-metadata@^1.9.3: integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA== ethers@^4.0.28, ethers@^4.0.39: - version "4.0.39" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.39.tgz#5ce9dfffedb03936415743f63b37d96280886a47" - integrity sha512-QVtC8TTUgTrnlQjQvdFJ7fkSWKwp8HVTbKRmrdbVryrPzJHMTf3WSeRNvLF2enGyAFtyHJyFNnjN0fSshcEr9w== + version "4.0.40" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.40.tgz#6e1963d10b5d336a13cd81b519c230cc17624653" + integrity sha512-MC9BtV7Hpq4dgFONEfanx9aU9GhhoWU270F+/wegHZXA7FR+2KXFdt36YIQYLmVY5ykUWswDxd+f9EVkIa7JOA== dependencies: - "@types/node" "^10.3.2" aes-js "3.0.0" bn.js "^4.4.0" - elliptic "6.3.3" + elliptic "6.5.2" hash.js "1.1.3" js-sha3 "0.5.7" scrypt-js "2.0.4" @@ -4321,9 +4257,9 @@ expect@^24.9.0: jest-regex-util "^24.9.0" ext@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.2.0.tgz#8dd8d2dd21bcced3045be09621fa0cbf73908ba4" - integrity sha512-0ccUQK/9e3NreLFg6K6np8aPyRgwycx+oFGtfx1dSp7Wj00Ozw9r05FgBRlzjf2XBM7LAzwgLyDscRrtSU91hA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== dependencies: type "^2.0.0" @@ -4447,17 +4383,17 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fast-safe-stringify@^2.0.6: +fast-safe-stringify@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== fb-watchman@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" - integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== dependencies: - bser "^2.0.0" + bser "2.1.1" fbjs-css-vars@^1.0.0: version "1.0.2" @@ -4670,13 +4606,13 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@^2.3.3: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== +form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" form-data@~2.3.2: @@ -4964,7 +4900,7 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" -global@^4.3.0, global@^4.3.2: +global@^4.3.2: version "4.4.0" resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== @@ -5348,9 +5284,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.0.tgz#07f462b7d95f7e86c214a861ecacd766d42b8c0a" - integrity sha512-G7gRqKbi9NE025XVyqyTV98dxUOtdKvu/P1QRaVZfA55aEcXgjbxPdm+TlWdcSMNPKijlaHNz61DGPyelouRlA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.1.tgz#1a1184fa758f68f1b5573db840825fb5164cceca" + integrity sha512-KFHV1ivrBmPCVRhjy9oBooypnPfJ876NTrWXMNoUhXFAaWWAViVqZ4l6HxPST52qcN82qqsR38/pCGYRWP5W7w== import-fresh@^2.0.0: version "2.0.0" @@ -5819,9 +5755,9 @@ is-typedarray@~1.0.0: integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-what@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.3.1.tgz#79502181f40226e2d8c09226999db90ef7c1bcbe" - integrity sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA== + version "3.4.0" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.4.0.tgz#a9b3fe0c22f52d49efef977f640da44e65a3f866" + integrity sha512-oFdBRuSY9PocqPoUUseDXek4I+A1kWGigZGhuG+7GEkp0tRkek11adc0HbTEVsNvtojV7rp0uhf5LWtGvHzoOQ== is-whitespace-character@^1.0.0: version "1.0.3" @@ -6308,9 +6244,9 @@ jest@^24.9.0: jest-cli "^24.9.0" jetifier@^1.6.2: - version "1.6.4" - resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.4.tgz#6159db8e275d97980d26162897a0648b6d4a3222" - integrity sha512-+f/4OLeqY8RAmXnonI1ffeY1DR8kMNJPhv5WMFehchf7U71cjMQVKkOz1n6asz6kfVoAqKNWJz1A/18i18AcXA== + version "1.6.5" + resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.5.tgz#ea87324a4230bef20a9651178ecab978ee54a8cb" + integrity sha512-T7yzBSu9PR+DqjYt+I0KVO1XTb1QhAfHnXV5Nd3xpbXM6Xg4e3vP60Q4qkNU8Fh6PHC2PivPUNN3rY7G2MxcDQ== js-sha3@0.5.7: version "0.5.7" @@ -6455,7 +6391,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsx-ast-utils@^2.2.1: +jsx-ast-utils@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== @@ -6733,7 +6669,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -6901,6 +6837,11 @@ mdn-data@2.0.4: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -6938,9 +6879,9 @@ meow@^5.0.0: yargs-parser "^10.0.0" merge-anything@^2.2.4, merge-anything@^2.2.5: - version "2.4.2" - resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.2.tgz#f7152fc4764ae02c024742afb14a989c1a0f1f27" - integrity sha512-/so+4seX7fdAhPI3m3bxwc60vhotzY9uM+1Z6C3GKeJBYzxt/lIrbs5uT9iwgM5aLi5kpJIPT7JzJfrrfloWHA== + version "2.4.4" + resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.4.tgz#6226b2ac3d3d3fc5fb9e8d23aa400df25f98fdf0" + integrity sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ== dependencies: is-what "^3.3.1" @@ -6975,24 +6916,6 @@ methods@^1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -metro-babel-register@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.54.1.tgz#7d2bfe444b1ccef8de99aedc7d9330891d806076" - integrity sha512-j3VydgncUG8HP6AZala6GTIt3V01nptodnnOke3JMYLqgk8EJ1LOVOdotK9pXi80o7EmmNKFs/LyyH8z+uAJzQ== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - metro-babel-register@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.3.tgz#d0cfb38adf45cb35965649ede794f2308562e20f" @@ -7029,13 +6952,6 @@ metro-babel-register@0.57.0: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-transformer@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" - integrity sha512-2aiAnuYBdcLV1VINb8ENAA4keIaJIepHgR9+iRvIde+9GSjKnexqx4nNmJN392285gRDp1fVZ7uY0uQawK/A5g== - dependencies: - "@babel/core" "^7.0.0" - metro-babel-transformer@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz#6559c3a8565238a704a181353cef59fdb974e6db" @@ -7052,23 +6968,6 @@ metro-babel-transformer@0.57.0: "@babel/core" "^7.0.0" metro-source-map "0.57.0" -metro-babel7-plugin-react-transform@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" - integrity sha512-jWm5myuMoZAOhoPsa8ItfDxdTcOzKhTTzzhFlbZnRamE7i9qybeMdrZt8KHQpF7i2p/mKzE9Yhf4ouOz5K/jHg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - -metro-cache@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1" - integrity sha512-RxCFoNcANHXZYi4MIQNnqh68gUnC3bMpzCFJY5pBoqqdrkkn8ibYglBweA0/DW7hx1OZTJWelwS1Dp8xxmE2CA== - dependencies: - jest-serializer "^24.4.0" - metro-core "0.54.1" - mkdirp "^0.5.1" - rimraf "^2.5.4" - metro-cache@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.3.tgz#1b0759bc45291cc3ffc77736c09dcfbd322edb8b" @@ -7079,18 +6978,6 @@ metro-cache@0.56.3: mkdirp "^0.5.1" rimraf "^2.5.4" -metro-config@0.54.1, metro-config@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd" - integrity sha512-FpxrA+63rGkPGvGI653dvuSreJzU+eOTILItVnnhmqwn2SAK5V00N/qGTOIJe2YIuWEFXwCzw9lXmANrXbwuGg== - dependencies: - cosmiconfig "^5.0.5" - jest-validate "^24.7.0" - metro "0.54.1" - metro-cache "0.54.1" - metro-core "0.54.1" - pretty-format "^24.7.0" - metro-config@0.56.3, metro-config@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.3.tgz#b16e600817c58c768946f24b039d2a1ba6a67651" @@ -7103,16 +6990,6 @@ metro-config@0.56.3, metro-config@^0.56.0: metro-core "0.56.3" pretty-format "^24.7.0" -metro-core@0.54.1, metro-core@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b" - integrity sha512-8oz3Ck7QFBzW9dG9tKFhrXHKPu2Ajx3R7eatf61Gl6Jf/tF7PNouv3wHxPsJW3oXDFiwKLszd89+OgleTGkB5g== - dependencies: - jest-haste-map "^24.7.1" - lodash.throttle "^4.1.1" - metro-resolver "0.54.1" - wordwrap "^1.0.0" - metro-core@0.56.3, metro-core@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.3.tgz#34bb3a92621fd9b1ed3e6a01c6a4324fbb1201d9" @@ -7123,17 +7000,6 @@ metro-core@0.56.3, metro-core@^0.56.0: metro-resolver "0.56.3" wordwrap "^1.0.0" -metro-inspector-proxy@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.54.1.tgz#0ef48ee3feb11c6da47aa100151a9bf2a7c358ee" - integrity sha512-sf6kNu7PgFW6U+hU7YGZfbAUKAPVvCJhY8YVu/A1RMKH9nNULrCo+jlWh0gWgmFfWRQiAPCElevROg+5somk8A== - dependencies: - connect "^3.6.5" - debug "^2.2.0" - rxjs "^5.4.3" - ws "^1.1.5" - yargs "^9.0.0" - metro-inspector-proxy@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.3.tgz#48046f9e3f7153be2409e0bee9252dede932ac39" @@ -7145,13 +7011,6 @@ metro-inspector-proxy@0.56.3: ws "^1.1.5" yargs "^9.0.0" -metro-minify-uglify@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3" - integrity sha512-z+pOPna/8IxD4OhjW6Xo1mV2EszgqqQHqBm1FdmtdF6IpWkQp33qpDBNEi9NGZTOr7pp2bvcxZnvNJdC2lrK9Q== - dependencies: - uglify-es "^3.1.9" - metro-minify-uglify@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.3.tgz#763b26895f79d0589d3391dc94083d348cf9c2be" @@ -7159,48 +7018,6 @@ metro-minify-uglify@0.56.3: dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8" - integrity sha512-Hfr32+u5yYl3qhYQJU8NQ26g4kQlc3yFMg7keVR/3H8rwBIbFqXgsKt8oe0dOrv7WvrMqBHhDtVdU9ls3sSq8g== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.54.1" - react-transform-hmr "^1.0.4" - metro-react-native-babel-preset@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz#5a1097c2f94e8ee0797a8ba2ab8f86d096f4c093" @@ -7294,16 +7111,6 @@ metro-react-native-babel-transformer@0.57.0: metro-react-native-babel-preset "0.57.0" metro-source-map "0.57.0" -metro-react-native-babel-transformer@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" - integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "0.54.1" - metro-react-native-babel-preset "0.54.1" - metro-react-native-babel-transformer@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" @@ -7315,13 +7122,6 @@ metro-react-native-babel-transformer@^0.56.0: metro-react-native-babel-preset "0.56.3" metro-source-map "0.56.3" -metro-resolver@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" - integrity sha512-Byv1LIawYAASy9CFRwzrncYnqaFGLe8vpw178EtzStqP05Hu6hXSqkNTrfoXa+3V9bPFGCrVzFx2NY3gFp2btg== - dependencies: - absolute-path "^0.0.0" - metro-resolver@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.3.tgz#f18978b919a5ecc67028732609a564880715ef75" @@ -7329,15 +7129,6 @@ metro-resolver@0.56.3: dependencies: absolute-path "^0.0.0" -metro-source-map@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5" - integrity sha512-E9iSYMSUSq5qYi1R2hTQtxH4Mxjzfgr/jaSmQIWi7h3fG2P1qOZNNSzeaeUeTK+s2N/ksVlkcL5kMikol8CDrQ== - dependencies: - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - source-map "^0.5.6" - metro-source-map@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.3.tgz#0cadc9f9eca9ece224a6fd28b9e4fa3a9834e24c" @@ -7386,65 +7177,6 @@ metro-symbolicate@0.57.0: through2 "^2.0.1" vlq "^1.0.0" -metro@0.54.1, metro@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.54.1.tgz#a629be00abee5a450a25a8f71c24745f70cc9b44" - integrity sha512-6ODPT4mEo4FCpbExRNnQAcZmf1VeNvYOTMj2Na03FjGqhNODHhI2U/wF/Ul5gqTyJ2dVdkXeyvKW3gl/LrnJRg== - dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.1.2" - buffer-crc32 "^0.2.13" - chalk "^2.4.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" - invariant "^2.2.4" - jest-haste-map "^24.7.1" - jest-worker "^24.6.0" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-babel-register "0.54.1" - metro-babel-transformer "0.54.1" - metro-cache "0.54.1" - metro-config "0.54.1" - metro-core "0.54.1" - metro-inspector-proxy "0.54.1" - metro-minify-uglify "0.54.1" - metro-react-native-babel-preset "0.54.1" - metro-resolver "0.54.1" - metro-source-map "0.54.1" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - react-transform-hmr "^1.0.4" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" - source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.5" - xpipe "^1.0.5" - yargs "^9.0.0" - metro@0.56.3, metro@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.3.tgz#3a38706bf6b1200421e871a4c53ddc2f359f65a9" @@ -7901,10 +7633,10 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.40: - version "1.1.41" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.41.tgz#57674a82a37f812d18e3b26118aefaf53a00afed" - integrity sha512-+IctMa7wIs8Cfsa8iYzeaLTFwv5Y4r5jZud+4AnfymzeEXKBCavFX0KBgzVaPVqf0ywa6PrO8/b+bPqdwjGBSg== +node-releases@^1.1.42: + version "1.1.42" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7" + integrity sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA== dependencies: semver "^6.3.0" @@ -7961,14 +7693,21 @@ normalize-svg-path@^1.0.1: svg-arc-to-cubic-bezier "^3.0.0" npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== npm-packlist@^1.1.6: - version "1.4.6" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" - integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== + version "1.4.7" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.7.tgz#9e954365a06b80b18111ea900945af4f88ed4848" + integrity sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -8058,7 +7797,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.6.0: +object-inspect@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== @@ -8109,7 +7848,7 @@ object.entries@^1.1.0: function-bind "^1.1.1" has "^1.0.3" -object.fromentries@^2.0.0: +object.fromentries@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704" integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA== @@ -8857,9 +8596,9 @@ postcss-value-parser@^4.0.2: integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.7: - version "7.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.23.tgz#9f9759fad661b15964f3cfc3140f66f1e05eadc1" - integrity sha512-hOlMf3ouRIFXD+j2VJecwssTwbvsPGJVMzupptg+85WA+i7MwyrydmQAgY3R+m0Bc0exunhbJmijy8u8+vufuQ== + version "7.0.24" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.24.tgz#972c3c5be431b32e40caefe6c81b5a19117704c2" + integrity sha512-Xl0XvdNWg+CblAXzNvbSOUvgJXwSjmbAKORqyw9V2AlHrm1js2gFw9y3jibBAhpKZi8b5JzJCVh/FyzPsTtgTA== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -9002,9 +8741,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: - version "1.4.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" - integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== + version "1.6.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" + integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== public-encrypt@^4.0.0: version "4.0.3" @@ -9059,7 +8798,7 @@ qrcode@^1.2.0: pngjs "^3.3.0" yargs "^13.2.4" -qs@^6.7.0: +qs@^6.9.1: version "6.9.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== @@ -9142,24 +8881,19 @@ react-coin-icon@0.1.13: lodash "^4.17.11" styled-components "4.4.1" -react-deep-force-update@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" - integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== - react-devtools-core@^4.0.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.2.0.tgz#d8c445809dd9fc331f619e0a1f61a7accf432080" - integrity sha512-e3EcP63jYypZLPxxfEoYTk0L53wtphIxQD6/wVXQ9uBbYNqCd3/O9dbeBtC3v1VpZj/IcelTj6yisAdrfgxgWg== + version "4.2.1" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.2.1.tgz#0122ccb8a041b0b61811425a57e9dec05125e9d8" + integrity sha512-Puo0PwkpxWZY4E0cU7lpOR6Lh5UhGoOScSdhVtvK6HK6InC6+k9ypyVHI2ar2OoBasm3wP5mJlDHcUmbmqF78w== dependencies: es6-symbol "^3" shell-quote "^1.6.1" ws "^7" react-display-name@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.4.tgz#e2a670b81d79a2204335510c01246f4c92ff12cf" - integrity sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA== + version "0.2.5" + resolved "https://registry.yarnpkg.com/react-display-name/-/react-display-name-0.2.5.tgz#304c7cbfb59ee40389d436e1a822c17fe27936c6" + integrity sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg== react-fast-compare@^2.0.4: version "2.0.4" @@ -9194,9 +8928,9 @@ react-native-bundle-visualizer@^2.0.1: source-map-explorer "^2.1.0" react-native-camera@^3.9.0: - version "3.11.1" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.11.1.tgz#5c2851d8208f2aa47007bd123f6056aaf9c58e18" - integrity sha512-uzsGgXVKEh9PrOOOfYuFj9X/jnSv8i0b6upcsCkFVBtF7iIs/nED23ZSf2UTWsRH5LR07/yqA9PDebjh76hKVQ== + version "3.13.1" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.13.1.tgz#016a011ca264d7044e2f1ad11fc624b90020aeb9" + integrity sha512-HXCo75sFYOJRqtbiG12ttoG6K4UdS1mfOwu6NoQmxj6IV2KrNgdOYO4YTyLymGUXNs3LyOWpJskVvCRupoFA3A== dependencies: prop-types "^15.6.2" @@ -9208,9 +8942,9 @@ react-native-circular-progress@^1.3.4: prop-types "^15.7.2" react-native-clean-project@^3.1.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.2.4.tgz#55a71006eb4336dff91d0ca5ab3564d8f0db45cc" - integrity sha512-VF5angZrFIxFILH4NxFsJk5QCjGdPam/Ti4ht2Wd25RbwAyDMPjVNLD2NYf3jZPUCbVtl3TR+uN9uAt1RBnb8g== + version "3.3.0" + resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-3.3.0.tgz#89974c4a291123e6d1f72c32185a012a649f1fa8" + integrity sha512-IudFlNsaQd6QcgcbTZcNEXDlrJ9zzRspIUV7yvBX3bfB72Z9et9hIceH9+F+xYSlvwUSB4L/fvkIPosYKa+q9Q== react-native-code-push@^5.6.0: version "5.7.0" @@ -9265,17 +8999,17 @@ react-native-fast-image@andrewschenk-linx/react-native-fast-image#fix-ios-xcode- resolved "https://codeload.github.com/andrewschenk-linx/react-native-fast-image/tar.gz/d19ae11a6469de94cb49211d00a7bc002ea76ff8" react-native-firebase@^5.5.6: - version "5.5.6" - resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-5.5.6.tgz#17b34ec0d5dc39afaaf0e159fd160f6339e0f707" - integrity sha512-AdbpGwKEEiMFgaRar9WOPc8Li4sfxR//WOyNQzxYsQ1fpARC908j7feqy2gu73SLqk4wzIrnlfJWakOe0/Bclg== + version "5.5.7" + resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-5.5.7.tgz#d03d69c774af280c80c63bede59f65c5f7e8f26c" + integrity sha512-vWUdF6lE22iKSE1gh3bxzzfcA7OCoY1VLASF/XFAlXdGzw4/ksRrdcgdItkNSUnrYG3+pB46ah+OaTHPENPmuQ== dependencies: opencollective-postinstall "^2.0.0" prop-types "^15.7.2" -react-native-gesture-handler@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.1.tgz#681cef98954d48cd82f99f75de3ab203c8754354" - integrity sha512-n4+tXAplf7B3qoHgvOxmKfx8cr/hzCSxyEEGxO/3aYyvSYbyt1o6Q7hmTC2JuezllB44b4v/FcCTd6Rgu3MMfg== +react-native-gesture-handler@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.2.tgz#281111550bf1eee10b7feba5278d142169892731" + integrity sha512-Xp03dq4XYVTD0xmWx4DW4eX+ox1NQLjHmbykspTdS5FCNIVIOekVXRLFCw1698/v8dYUHApNo6K3s3BCD8fqPA== dependencies: hammerjs "^2.0.8" hoist-non-react-statics "^2.3.1" @@ -9287,6 +9021,11 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== +react-native-hooks@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/react-native-hooks/-/react-native-hooks-0.9.0.tgz#589fc2390296d9afe03327298dabcf0a1f350910" + integrity sha512-yqSAH0zxqjYHYPo6mPut3dEROoB5qMvsAbN3EK0MDQrWA5zdqmzgTEpS9/qwXaIyllk6hQbHxYnRTWq2uq4tJQ== + react-native-indicators@0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" @@ -9369,7 +9108,7 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/c70c1211d9e9f95959fffc832b030f6d249819b4" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/fa2f249537b6f5fb122b3ead1d404b91f39addce" react-native-redash@8.2.2: version "8.2.2" @@ -9439,7 +9178,7 @@ react-native-tab-view@^1.4.1: dependencies: prop-types "^15.6.1" -react-native-tab-view@^2.9.0: +react-native-tab-view@^2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.11.0.tgz#2e57d1f617ccc88c7f452708804f3409f880b700" integrity sha512-vqetlxGO7A8bnqvXcB50MWpRZAImXFrDGz1WCQKdCqe03Ey3ZzENe7yLuWrtBJYlepGfOLAsmCXv+wW82Yfm1w== @@ -9487,7 +9226,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/ac3c167ead8609410660da48b594fedc35b68489" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/64b4b33363b3747516951dac4b1f607519fcfe0a" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0" @@ -9521,6 +9260,11 @@ react-native@facebook/react-native: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" +react-navigation-hooks@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-navigation-hooks/-/react-navigation-hooks-1.1.0.tgz#337c41a50ebc7b9030bb9d9333cd4fd6e1f86b68" + integrity sha512-ZY/aiYJ88KXaOo8iOa4171O/0x6ztGhUPd2OYzdaJhLT/tP64zi5HB/RZFImuKhaBTODXjoSpFaOTA5xpePG4g== + react-navigation-stack@2.0.0-alpha.39: version "2.0.0-alpha.39" resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.0.0-alpha.39.tgz#e138a116f69397ead27d5760559489e23990ed3f" @@ -9535,15 +9279,15 @@ react-navigation-tabs-v1@1.2.0: prop-types "^15.6.1" react-native-tab-view "^1.4.1" -react-navigation-tabs@2.5.6: - version "2.5.6" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.5.6.tgz#51f1a39b6c9525e6b5fe035945c243c04e53242b" - integrity sha512-4WivEAsChJ+MuJ6JHxhAUMekHnVIt/zc4y/07KChXD5NBkSE0sk4vmMRndZQ6AP3n/ZihACcfigBAsMoqt0JXA== +react-navigation-tabs@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.6.2.tgz#6611f3bbc5fcbc004a96a457e1dbe8d957d09ef5" + integrity sha512-b7Bwio3pOyb2dJOsfICm1eXUCekULO63VitLlkslsuwB5v5qXD9u+TkuSGADPiAybRH3Fts4cQX/xA5WGsIsfg== dependencies: hoist-non-react-statics "^3.3.0" react-lifecycles-compat "^3.0.4" react-native-safe-area-view "^0.14.6" - react-native-tab-view "^2.9.0" + react-native-tab-view "^2.11.0" react-navigation@4.0.10: version "4.0.10" @@ -9563,14 +9307,6 @@ react-primitives@^0.8.0: prop-types "^15.7.2" react-timer-mixin "^0.13.4" -react-proxy@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a" - integrity sha1-nb/Z2SdSjDqp9ETkVYw3gwq4wmo= - dependencies: - lodash "^4.6.1" - react-deep-force-update "^1.0.0" - react-redux@^5.0.7: version "5.1.2" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.2.tgz#b19cf9e21d694422727bf798e934a916c4080f57" @@ -9618,14 +9354,6 @@ react-timer-mixin@^0.13.4: resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz#75a00c3c94c13abe29b43d63b4c65a88fc8264d3" integrity sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q== -react-transform-hmr@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" - integrity sha1-4aQL0Krvxy6N/Xp82gmvhQZjl7s= - dependencies: - global "^4.3.0" - react-proxy "^1.1.7" - react@16.11.0: version "16.11.0" resolved "https://registry.yarnpkg.com/react/-/react-16.11.0.tgz#d294545fe62299ccee83363599bf904e4a07fdbb" @@ -10090,7 +9818,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7, resolve@1.8.1, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: +resolve@1.1.7, resolve@1.8.1, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== @@ -10349,7 +10077,7 @@ semver@5.5.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -10635,21 +10363,21 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.1.tgz#7e7f833cbb7a807dc3a76608c0d581909353852c" - integrity sha512-GSHrlyGFhcXhjdWgM+ysY7d11eZMN2gvLsW56qFOdV3ZCsZCM/tl8tt3PXu5BUvllNKPRCGyv2mbWjbZrvEdmA== + version "2.1.2" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.2.tgz#305d61efbb1d1ebbf24a9fffef718635054d509c" + integrity sha512-rgujHHHwf0/HCSTFbdTPJETGTgbGqVDD068Ob/wfV41u3AdU8iknSvGTDoU8vCIUeZuLnHX4JYsQ1RMd129XCQ== dependencies: btoa "^1.2.1" chalk "^3.0.0" convert-source-map "^1.7.0" - ejs "^2.7.2" + ejs "^3.0.1" escape-html "^1.0.3" glob "^7.1.6" lodash "^4.17.15" open "^7.0.0" source-map "^0.7.3" temp "^0.9.1" - yargs "^14.2.0" + yargs "^15.0.2" source-map-resolve@^0.5.0: version "0.5.2" @@ -10772,9 +10500,9 @@ stack-utils@^1.0.1: integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== stacktrace-parser@^0.1.3: - version "0.1.7" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.7.tgz#9ed005638a5e79dcf256611da1dfb4871e6fd14d" - integrity sha512-Evm+NuZ2ZTwGazsbsZC+EV1EGsvyxgIvtNwbyFfeXaq/8L78M5Kdh0qpmQaTkUpbOAKbbPP7c7qZa7u8XFsrUA== + version "0.1.8" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.8.tgz#28b0272bd9aeb41636f0c8265c03ba270c865e1b" + integrity sha512-ig5rHJSdJrAsVqdb3oAI/8C6aQ7dEwJXoy/TIEIOTzdJHssmn12o6RsFoeQSLHoKjq0lX+kqhmnLDpyQTuWiJA== dependencies: type-fest "^0.7.1" @@ -10858,7 +10586,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== @@ -11096,21 +10824,21 @@ superagent-proxy@^2.0.0: proxy-agent "3" superagent@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.1.tgz#f5c1336b0777e77e12a6f3962a060186342e43d0" - integrity sha512-bpTO/3yQsHPH5w6f7qPCWGTuhEV2w93fwFGpYODnUc5tPa3rmbHUCmwC7iuEFBQQJsyhiW1WVc/ISpfAEv6ojQ== + version "5.1.2" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.2.tgz#b122f3a62b14c4d638612667033a7eb43c4f4d83" + integrity sha512-VwPCbi9H02qDtTbdY+e3+cK5XR0YHsJy9hmeCOXLQ8ezjq8+S1Bs4MdNRmpmf2QjDBetD7drG7/nEta7E3E6Sg== dependencies: component-emitter "^1.3.0" cookiejar "^2.1.2" debug "^4.1.1" - fast-safe-stringify "^2.0.6" - form-data "^2.3.3" + fast-safe-stringify "^2.0.7" + form-data "^3.0.0" formidable "^1.2.1" methods "^1.1.2" mime "^2.4.4" - qs "^6.7.0" + qs "^6.9.1" readable-stream "^3.4.0" - semver "^6.1.1" + semver "^6.3.0" supports-color@6.0.0: version "6.0.0" @@ -11533,9 +11261,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.9.tgz#85d353edb6ddfb62a9d798f36e91792249320611" - integrity sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw== + version "3.7.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" + integrity sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -11894,9 +11622,9 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.7" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.7.tgz#8d85f3c1d46a1e58e9867d747552fb8c83d934fd" - integrity sha512-y3MN2+/yph3yoIHGmHu4ScYpm285L58XVvfGkd49xTQzLja4apxSbwzsYcP9QsqS0W7KuvoyiPhqksiudoMwjg== + version "3.4.9" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.9.tgz#7ce485bb0f9a07b4d879c988baac9be2222909ad" + integrity sha512-4VCpZ9ooea/Zc/MTnj1ccc9C7rqcoinKVQLhLoi6jw6yueSf4y4tg/YIUiPPVMlEAG7ZCPS+NVmqxisQ+mOsSw== dependencies: jsonc-parser "^2.2.0" vscode-languageserver-textdocument "^1.0.0-next.4" @@ -11910,9 +11638,9 @@ vscode-languageserver-textdocument@^1.0.0-next.4: integrity sha512-1jp/zAidN/bF/sqPimhBX1orH5G4rzRw63k75TesukJDuxm8yW79ECStWbDSy41BHGOwSGN4M69QFvhancSr5A== vscode-languageserver-types@^3.15.0-next.6: - version "3.15.0-next.8" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.8.tgz#59bfe70e5690bcef7d28d0f3a7f813915edf62e1" - integrity sha512-AEfWrSNyeamWMKPehh/kd3nBnKD9ZGCPhzfxMnW9YNqElSh28G2+Puk3knIQWyaWyV6Bzh28ok9BRJsPzXFCkQ== + version "3.15.0-next.9" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz#957a9d1d5998a02edf62298fb7e37d9efcc6c157" + integrity sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw== vscode-nls@^4.1.1: version "4.1.1" @@ -12057,6 +11785,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -12274,10 +12011,10 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08" - integrity sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ== +yargs-parser@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" + integrity sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" @@ -12332,22 +12069,22 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^14.2.0: - version "14.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" - integrity sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA== +yargs@^15.0.2: + version "15.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.0.2.tgz#4248bf218ef050385c4f7e14ebdf425653d13bd3" + integrity sha512-GH/X/hYt+x5hOat4LMnCqMd8r5Cv78heOMIJn1hr7QPPBqfeC6p89Y78+WB9yGDvfpCvgasfmWLzNzEioOUD9Q== dependencies: - cliui "^5.0.0" + cliui "^6.0.0" decamelize "^1.2.0" - find-up "^3.0.0" + find-up "^4.1.0" get-caller-file "^2.0.1" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" - string-width "^3.0.0" + string-width "^4.2.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^15.0.0" + yargs-parser "^16.1.0" yargs@^9.0.0: version "9.0.1" From b999b8a5dc414c799462becf86315d1a7d064c9b Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Tue, 10 Dec 2019 23:19:20 +0100 Subject: [PATCH 591/636] small balances rerendering performance improvemnts --- .../asset-list/RecyclerAssetList.js | 58 ++++++++++++++----- .../investment-cards/InvestmentCard.js | 1 + 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList.js b/src/components/asset-list/RecyclerAssetList.js index 11a83aeae09..c171668d4f4 100644 --- a/src/components/asset-list/RecyclerAssetList.js +++ b/src/components/asset-list/RecyclerAssetList.js @@ -77,6 +77,7 @@ const layoutItemAnimator = new LayoutItemAnimator(); const reloadHeightOffsetTop = -60; const reloadHeightOffsetBottom = -62; +let smallBalancedChanged = false; const AssetListHeaderRenderer = pure(data => ); @@ -107,6 +108,28 @@ const hasRowChanged = (r1, r2) => { ); } + if ( + r1.item && + r2.item && + r1.item.smallBalancesContainer && + r2.item.smallBalancesContainer + ) { + if (r1.item.assets.length !== r2.item.assets.length) { + smallBalancedChanged = true; + } else if (r2.item.assets.length > 0) { + for (let i = 0; i < r2.item.assets.length; i++) { + if (r1.item.assets[i].native) { + if ( + r1.item.assets[i].native.balance.display !== + r2.item.assets[i].native.balance.display + ) { + smallBalancedChanged = true; + } + } + } + } + } + return ( isNewAsset || isNewAssetBalance || @@ -615,6 +638,8 @@ class RecyclerAssetList extends Component { position = 0; + renderList = []; + scrollToOffset = (position, animated) => { setTimeout(() => { this.rlv.scrollToOffset(0, position, animated); @@ -720,20 +745,27 @@ class RecyclerAssetList extends Component { } if (type === ViewTypes.COIN_SMALL_BALANCES) { - const renderList = []; - for (let i = 0; i < item.assets.length; i++) { - renderList.push( - renderItem({ - item: { - ...item.assets[i], - isSmall: true, - }, - key: `CoinSmallBalances${i}`, - }) - ); + if ( + this.renderList.length !== item.assets.length || + smallBalancedChanged + ) { + smallBalancedChanged = false; + const renderList = []; + for (let i = 0; i < item.assets.length; i++) { + renderList.push( + renderItem({ + item: { + ...item.assets[i], + isSmall: true, + }, + key: `CoinSmallBalances${i}`, + }) + ); + } + this.renderList = renderList; } - return ; + return ; } const isNotUniqueToken = @@ -767,7 +799,6 @@ class RecyclerAssetList extends Component { fetchData, hideHeader, renderAheadOffset, - ...props } = this.props; const { dataProvider, headersIndices } = this.state; @@ -775,7 +806,6 @@ class RecyclerAssetList extends Component { Date: Tue, 10 Dec 2019 21:13:29 -0500 Subject: [PATCH 592/636] Remove investment card background --- src/components/investment-cards/InvestmentCard.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/investment-cards/InvestmentCard.js b/src/components/investment-cards/InvestmentCard.js index 3650cbe7ede..29d2ebcc830 100644 --- a/src/components/investment-cards/InvestmentCard.js +++ b/src/components/investment-cards/InvestmentCard.js @@ -51,7 +51,6 @@ const InvestmentCard = enhance( Date: Mon, 9 Dec 2019 21:33:12 -0500 Subject: [PATCH 593/636] Remove RN firebase v5 --- ios/Podfile | 8 -- ios/Podfile.lock | 165 +++++++++++++++---------- ios/Rainbow/AppDelegate.m | 6 +- package.json | 4 +- src/App.js | 1 - src/model/firebase.js | 27 +--- yarn.lock | 253 +++++++++++++++++++++----------------- 7 files changed, 243 insertions(+), 221 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 914b1afcc56..28a077b73c4 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -5,14 +5,6 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ ENV['COCOAPODS_DISABLE_STATS'] = 'true' target 'Rainbow' do - # Crashlytics - pod 'Fabric', '~> 1.7.11' - pod 'Crashlytics', '~> 3.10.7' - - # Firebase - pod 'Firebase/Core', '~> 6.2.0' - pod 'Firebase/Messaging', '~> 6.2.0' - # Core React pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" diff --git a/ios/Podfile.lock b/ios/Podfile.lock index dde8d3ecdf1..f24105fc9ab 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -9,10 +9,10 @@ PODS: - JWT (~> 3.0.0-beta.7) - React - SSZipArchive (~> 2.1) - - Crashlytics (3.10.9): - - Fabric (~> 1.7.13) + - Crashlytics (3.12.0): + - Fabric (~> 1.9.0) - DoubleConversion (1.1.6) - - Fabric (1.7.13) + - Fabric (1.9.0) - FBLazyVector (1000.0.0) - FBReactNativeSpec (1000.0.0): - Folly (= 2018.10.22.00) @@ -21,40 +21,49 @@ PODS: - React-Core (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - - Firebase/Core (6.2.0): + - Firebase/Core (6.13.0): - Firebase/CoreOnly - - FirebaseAnalytics (= 6.0.1) - - Firebase/CoreOnly (6.2.0): - - FirebaseCore (= 6.0.2) - - Firebase/Messaging (6.2.0): + - FirebaseAnalytics (= 6.1.6) + - Firebase/CoreOnly (6.13.0): + - FirebaseCore (= 6.4.0) + - Firebase/Messaging (6.13.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 4.0.2) - - FirebaseAnalytics (6.0.1): - - FirebaseCore (~> 6.0) - - FirebaseInstanceID (~> 4.1) - - GoogleAppMeasurement (= 6.0.1) + - FirebaseMessaging (~> 4.1.9) + - FirebaseAnalytics (6.1.6): + - FirebaseCore (~> 6.4) + - FirebaseInstanceID (~> 4.2) + - GoogleAppMeasurement (= 6.1.6) - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - - nanopb (~> 0.3) + - nanopb (= 0.3.9011) - FirebaseAnalyticsInterop (1.4.0) - - FirebaseCore (6.0.2): - - GoogleUtilities/Environment (~> 6.0) - - GoogleUtilities/Logger (~> 6.0) + - FirebaseCore (6.4.0): + - FirebaseCoreDiagnostics (~> 1.0) + - FirebaseCoreDiagnosticsInterop (~> 1.0) + - GoogleUtilities/Environment (~> 6.2) + - GoogleUtilities/Logger (~> 6.2) + - FirebaseCoreDiagnostics (1.1.2): + - FirebaseCoreDiagnosticsInterop (~> 1.0) + - GoogleDataTransportCCTSupport (~> 1.0) + - GoogleUtilities/Environment (~> 6.2) + - GoogleUtilities/Logger (~> 6.2) + - nanopb (~> 0.3.901) + - FirebaseCoreDiagnosticsInterop (1.1.0) - FirebaseInstanceID (4.2.7): - FirebaseCore (~> 6.0) - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/UserDefaults (~> 6.0) - - FirebaseMessaging (4.0.2): - - FirebaseAnalyticsInterop (~> 1.1) - - FirebaseCore (~> 6.0) + - FirebaseMessaging (4.1.9): + - FirebaseAnalyticsInterop (~> 1.3) + - FirebaseCore (~> 6.2) - FirebaseInstanceID (~> 4.1) - GoogleUtilities/AppDelegateSwizzler (~> 6.2) - GoogleUtilities/Environment (~> 6.2) - GoogleUtilities/Reachability (~> 6.2) - GoogleUtilities/UserDefaults (~> 6.2) - - Protobuf (~> 3.1) + - Protobuf (>= 3.9.2, ~> 3.9) - FLAnimatedImage (1.0.12) - Folly (2018.10.22.00): - boost-for-react-native @@ -66,12 +75,16 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - GoogleAppMeasurement (6.0.1): + - GoogleAppMeasurement (6.1.6): - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - - nanopb (~> 0.3) + - nanopb (= 0.3.9011) + - GoogleDataTransport (3.2.0) + - GoogleDataTransportCCTSupport (1.2.2): + - GoogleDataTransport (~> 3.2) + - nanopb (~> 0.3.901) - GoogleUtilities/AppDelegateSwizzler (6.3.2): - GoogleUtilities/Environment - GoogleUtilities/Logger @@ -369,15 +382,19 @@ PODS: - React - SDWebImage (~> 5.0) - SDWebImageWebPCoder (~> 0.2.3) - - RNFirebase (5.5.6): - - Firebase/Core + - RNFBApp (6.2.0): + - Firebase/Core (~> 6.13.0) - React - - RNFirebase/Crashlytics (= 5.5.6) - - RNFirebase/Crashlytics (5.5.6): - - Crashlytics - - Fabric - - Firebase/Core + - RNFBCrashlytics (6.2.0): + - Crashlytics (~> 3.12.0) + - Fabric (~> 1.9.0) + - Firebase/Core (~> 6.13.0) + - React + - RNFBApp + - RNFBMessaging (6.2.0): + - Firebase/Messaging (~> 6.13.0) - React + - RNFBApp - RNGestureHandler (1.5.1): - React - RNInputMask (4.1.0) @@ -417,13 +434,9 @@ PODS: DEPENDENCIES: - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) - CodePush (from `../node_modules/react-native-code-push`) - - Crashlytics (~> 3.10.7) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - Fabric (~> 1.7.11) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) - - Firebase/Core (~> 6.2.0) - - Firebase/Messaging (~> 6.2.0) - FLAnimatedImage - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) @@ -466,7 +479,9 @@ DEPENDENCIES: - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNFastImage (from `../node_modules/react-native-fast-image`) - - RNFirebase (from `../node_modules/react-native-firebase/ios`) + - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" + - "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)" + - "RNFBMessaging (from `../node_modules/@react-native-firebase/messaging`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNInputMask (from `../node_modules/react-native-text-input-mask/ios/InputMask`) - RNKeychain (from `../node_modules/react-native-keychain`) @@ -494,10 +509,14 @@ SPEC REPOS: - FirebaseAnalytics - FirebaseAnalyticsInterop - FirebaseCore + - FirebaseCoreDiagnostics + - FirebaseCoreDiagnosticsInterop - FirebaseInstanceID - FirebaseMessaging - FLAnimatedImage - GoogleAppMeasurement + - GoogleDataTransport + - GoogleDataTransportCCTSupport - GoogleUtilities - JWT - libwebp @@ -592,8 +611,12 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-device-info" RNFastImage: :path: "../node_modules/react-native-fast-image" - RNFirebase: - :path: "../node_modules/react-native-firebase/ios" + RNFBApp: + :path: "../node_modules/@react-native-firebase/app" + RNFBCrashlytics: + :path: "../node_modules/@react-native-firebase/crashlytics" + RNFBMessaging: + :path: "../node_modules/@react-native-firebase/messaging" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNInputMask: @@ -631,35 +654,39 @@ SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 CodePush: d2e54ad42df82a8db65b2d23d8191b950ba945e1 - Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c + Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 - Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 - FBLazyVector: 3c4d0c09c616a7f3435e9e300f8bed746656be83 - FBReactNativeSpec: a7541d27fd4de76c8830473a54fa8747e17886bf - Firebase: 5965bac23e7fcb5fa6d926ed429c9ecef8a2014e - FirebaseAnalytics: 629301c2b9925f3537d4093a17a72751ae5b7084 + Fabric: f988e33c97f08930a413e08123064d2e5f68d655 + FBLazyVector: cee5277c189088563dfbfcdfb2fb90ce482549b7 + FBReactNativeSpec: d89f618c1087b284b7930ca8431a4b9b7dd01663 + Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 + FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 - FirebaseCore: b0f0262acebfa540e5f97b3832dbb13186980822 + FirebaseCore: 307ea2508df730c5865334e41965bd9ea344b0e5 + FirebaseCoreDiagnostics: 511f4f3ed7d440bb69127e8b97c2bc8befae639e + FirebaseCoreDiagnosticsInterop: e9b1b023157e3a2fc6418b5cb601e79b9af7b3a0 FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e - FirebaseMessaging: 20b6626c41be7840aed7a3dd9a14003efae3d588 + FirebaseMessaging: e8d71368a5c579083da02203146c953f3386d503 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - GoogleAppMeasurement: 51d8d9ea48f0ca44484d29cfbdef976fbd4fc336 + GoogleAppMeasurement: dfe55efa543e899d906309eaaac6ca26d249862f + GoogleDataTransport: 8e9b210c97d55fbff306cc5468ff91b9cb32dcf5 + GoogleDataTransportCCTSupport: ef79a4728b864946a8aafdbab770d5294faf3b5f GoogleUtilities: 547a86735c6f0ee30ad17e94df4fc21f616b71cb JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 50fddff608221b4ca8b129f765a2e92b79f9c261 - RCTTypeSafety: 77be7fa5f4fd4c84a8f939352b5a80decbb26661 - React: daf0e5b1018a37dde9cf6cd883ac16c699b591ca - React-Core: a640a9c5fff836386c65482e800e4bdc40161b23 - React-CoreModules: 2eee3557949a3f49d25f1178ccd68885a699d79b - React-cxxreact: c9b63613f129889ff78196039a2ad7b5dfaf78de - React-jsi: da26fa0b8b0fae04cc07da5ed9b73e26f4e9db78 - React-jsiexecutor: ee06cea084eab794d780e07c3d90fd9d41f97b66 - React-jsinspector: 620974c7af0b3ba3359c16a37e268868e0cf0dc0 + RCTRequired: 3718135886395b0fa06d65511d9839a21e1c4237 + RCTTypeSafety: cb607d0b629091f1b6fce5d95fe09cee7c6715fd + React: 53b5a3d7bfb52ed8bbe55f6a4c147adab4bba4f4 + React-Core: f74a5e1c147171ff271d345f209e5340cf101459 + React-CoreModules: c44fd5637e4e96d907dbe2c57800a886c2980181 + React-cxxreact: 370308ed0aabc8b5dc29b8b38d07171514e59740 + React-jsi: ed8c383e93950c7f4175153571d0af11a0f272b1 + React-jsiexecutor: f8e63cd38810b258de43d7ce58d9fb60ecb87536 + React-jsinspector: 435a4f58ddbcf07ebd202401913451d15aec3c26 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -670,23 +697,25 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 33d07af58cf3cb0add478ea1ab2ba1d903629a07 - React-RCTAnimation: b5840c31c2f6fbb7d5b1319c0e73936bcaa28d8b - React-RCTBlob: 2a89c6650e5f69d8acd041bc59b0e737b79f4d6a - React-RCTImage: 8fa6c8186733c3ee6ec5186083bc49f9c3979722 - React-RCTLinking: 3cac953827782da7ed38ba6da6af323767e207d1 - React-RCTNetwork: 70b5b9a37011f33b940eed78e49a31c05cbe9957 - React-RCTSettings: 2c77a4009001ccf2c8f8a0a102e4d00b3262261f - React-RCTText: d0980710307579b0d3b6dbfae44d8bcbd7bea030 - React-RCTVibration: cf223db4a76d8eded0245c8b50e63b0fc6ac7aaf - ReactCommon: 32bef46031a27dd9d4253fc1e0a2d1d6ce5cd91b + React-RCTActionSheet: 7ef91294a1b9b73b2ea8ab4795253caf06440db9 + React-RCTAnimation: 26602115e92a18318fa85962fb06932101f9cad2 + React-RCTBlob: 011677c5f98bef3e749d8eb743ce7942732a65e6 + React-RCTImage: 1e9184b0f93d6e367a47eb6df146d9a372c6366e + React-RCTLinking: 2adb6836662921a1d65bab45e1e1a44770abe495 + React-RCTNetwork: 53d39cb9969c6d7f2279dbea9e1ba7dccd4a997e + React-RCTSettings: cb95158be9c445092e215e71dcc2a1505e44662a + React-RCTText: c753688e7b91fe95aa0156918983b6a84441064e + React-RCTVibration: 8e8b76d18b9bd2d99822085a7be08f5d5043c9a9 + ReactCommon: 21cfc09dff47ac417086143cabcf4505aade833b ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 - RNFirebase: ac0de8b24c6f91ae9459575491ed6a77327619c6 + RNFBApp: 5b215aacc09105a1761de31b9a0eb2abcce06253 + RNFBCrashlytics: 0469cb96b00904e0c9604b9636d8eeab31115b08 + RNFBMessaging: be0b936394416ec5503add603f2c0a641c353063 RNGestureHandler: 7add966bb5d90ee8cf38d4341f87814474357972 RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 @@ -704,8 +733,8 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: d12d620db862be3abc1d978608565c7dafbb6ab4 + Yoga: 0116cce1e3bce6b133fb6b3064a6722e14e49a6b -PODFILE CHECKSUM: d26524c88116d0c3459c8687a18e347aae23c6b2 +PODFILE CHECKSUM: aef26f80c98a94feb5ccc3dae817781bd425ca10 COCOAPODS: 1.8.4 diff --git a/ios/Rainbow/AppDelegate.m b/ios/Rainbow/AppDelegate.m index 1ced4283042..90412bb2b71 100644 --- a/ios/Rainbow/AppDelegate.m +++ b/ios/Rainbow/AppDelegate.m @@ -5,24 +5,20 @@ * LICENSE file in the root directory of this source tree. */ +@import Firebase; #import "AppDelegate.h" #import #import #import #import #import -#import -#import "RNFirebaseMessaging.h" -#import "RNFirebaseNotifications.h" #import "RNSplashScreen.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Firebase - Push Notifications [FIRApp configure]; - [RNFirebaseNotifications configure]; [application registerForRemoteNotifications]; // React Native - Defaults diff --git a/package.json b/package.json index ca03f32839a..d3edd682a33 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,9 @@ "@react-native-community/blur": "^3.3.1", "@react-native-community/masked-view": "^0.1.5", "@react-native-community/netinfo": "^4.6.0", + "@react-native-firebase/app": "^6.2.0", + "@react-native-firebase/crashlytics": "^6.2.0", + "@react-native-firebase/messaging": "^6.2.0", "@segment/analytics-react-native": "^1.0.1", "@staltz/react-native-tcp": "^3.3.1", "@tradle/react-native-http": "^2.0.1", @@ -83,7 +86,6 @@ "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", - "react-native-firebase": "^5.5.6", "react-native-gesture-handler": "1.5.1", "react-native-haptic-feedback": "^1.8.2", "react-native-indicators": "0.17.0", diff --git a/src/App.js b/src/App.js index 51644cb50a0..662e7b04e72 100644 --- a/src/App.js +++ b/src/App.js @@ -7,7 +7,6 @@ import { AppRegistry, AppState, Linking } from 'react-native'; // eslint-disable-next-line import/default import CodePush from 'react-native-code-push'; import { REACT_APP_SEGMENT_API_WRITE_KEY } from 'react-native-dotenv'; -import firebase from 'react-native-firebase'; // eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; // eslint-disable-next-line import/no-unresolved diff --git a/src/model/firebase.js b/src/model/firebase.js index 06b347f358a..bc0b9b2214a 100644 --- a/src/model/firebase.js +++ b/src/model/firebase.js @@ -1,6 +1,6 @@ +import messaging from '@react-native-firebase/messaging'; import lang from 'i18n-js'; import { get } from 'lodash'; -import firebase from 'react-native-firebase'; import { Alert } from '../components/alerts'; import { getLocal, saveLocal } from '../handlers/localstorage/common'; @@ -15,7 +15,7 @@ export const getFCMToken = async () => { export const saveFCMToken = async () => { try { - const fcmToken = await firebase.messaging().getToken(); + const fcmToken = await messaging().getToken(); if (fcmToken) { saveLocal('rainbowFcmToken', { data: fcmToken }); } @@ -24,10 +24,9 @@ export const saveFCMToken = async () => { } }; -export const hasPermission = async () => firebase.messaging().hasPermission(); +export const hasPermission = () => messaging().hasPermission(); -export const requestPermission = async () => - firebase.messaging().requestPermission(); +export const requestPermission = () => messaging().requestPermission(); export const checkPushNotificationPermissions = async () => { const arePushNotificationsAuthorized = await hasPermission(); @@ -51,22 +50,6 @@ export const checkPushNotificationPermissions = async () => { }; export const registerTokenRefreshListener = () => - firebase.messaging().onTokenRefresh(fcmToken => { + messaging().onTokenRefresh(fcmToken => { saveLocal('rainbowFcmToken', { data: fcmToken }); }); - -export const registerNotificationListener = () => - firebase.notifications().onNotification(() => { - console.log('onNotification'); - }); - -// TODO this.onPushNotificationOpened -export const registerNotificationOpenedListener = () => - firebase.notifications().onNotificationOpened(notificationOpen => { - const { callId, sessionId } = notificationOpen.notification.data; - // eslint-disable-next-line babel/no-invalid-this - this.onPushNotificationOpened(callId, sessionId, false); - }); - -export const getInitialNotification = () => - firebase.notifications().getInitialNotification(); diff --git a/yarn.lock b/yarn.lock index 9a08f3634d0..60158c504cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1010,7 +1010,7 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-android@^3.0.0": +"@react-native-community/cli-platform-android@^3.0.0-alpha.1": version "3.0.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz#e652abce79a7c1e3a8280228123e99df2c4b97b6" integrity sha512-rNO9DmRiVhB6aP2DVUjEJv7ecriTARDZND88ny3xNVUkrD1Y+zwF6aZu3eoT52VXOxLCSLiJzz19OiyGmfqxYg== @@ -1032,7 +1032,7 @@ chalk "^2.4.2" xcode "^2.0.0" -"@react-native-community/cli-platform-ios@^3.0.0": +"@react-native-community/cli-platform-ios@^3.0.0-alpha.1": version "3.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz#3a48a449c0c33af3b0b3d19d3256de99388fe15f" integrity sha512-QoNVlDj8eMXRZk9uktPFsctHurQpv9jKmiu6mQii4NEtT2npE7g1hbWpRNojutBsfgmCdQGDHd9uB54eeCnYgg== @@ -1106,7 +1106,7 @@ shell-quote "1.6.1" ws "^1.1.0" -"@react-native-community/cli@^3.0.0": +"@react-native-community/cli@^3.0.0-alpha.1": version "3.0.4" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.4.tgz#a9dba1bc77855a6e45fccaabb017360645d936bb" integrity sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA== @@ -1160,6 +1160,32 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.1.tgz#09960b49217d555e54144f54e63485fe55d673ad" integrity sha512-RIcrNzVnkes6/d5jFprce8i6ruUO9+/FVZZgejlu/TSnysyFXHNJKgcIqxbKx+7XfQxfjrCGeCvsfYxrFrU0zw== +"@react-native-firebase/app-types@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/app-types/-/app-types-6.2.0.tgz#4d3c0e7fa4e4f00061c52b1a32d76e85e5db9f2c" + integrity sha512-3UW3cuCgY/JMp+7n6bLeRXKDS/JcXwnHwL0RUIUHg2NhlNAXmIUQbbl0gZbW10YHRnW7D3+JE60Mpm9atTzh9g== + +"@react-native-firebase/app@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/app/-/app-6.2.0.tgz#2d4327399f5e8021d7bad264624f1a29f0741f6c" + integrity sha512-LlYvml2hhqE28T9rU0SpwcKvlrwp0QyY90HTV0tvEEfGaCahd9xlIj7IFQCXNUNYICFi7Vn2YjxAZNF8KgKpmQ== + dependencies: + "@react-native-firebase/app-types" "6.2.0" + opencollective-postinstall "^2.0.1" + superstruct "^0.6.2" + +"@react-native-firebase/crashlytics@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/crashlytics/-/crashlytics-6.2.0.tgz#7c2add9857f1f26d6d317590dc2c301144ea1e50" + integrity sha512-yk25Uu2F/moeoa3DFtt88SA5jqib5wXff7MhAX9vkvcDqWwEaZtT0Clk/+ObMHs/rL6LUtLhHwo6qfYzknVEfQ== + dependencies: + stacktrace-js "^2.0.0" + +"@react-native-firebase/messaging@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/messaging/-/messaging-6.2.0.tgz#d882e650f9b21aff54482f9cedfa677cef85ccfb" + integrity sha512-RqgpUkiDqp/aIgMoQUOAfMtVB9bWnii8Ii4jrQQQ10dAPUW6+HmqxFIQlzi6blsbltAc5ESGk29Tl2SUbISIQA== + "@react-navigation/core@^3.5.1": version "3.5.1" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.5.1.tgz#7a2339fca3496979305fb3a8ab88c2ca8d8c214d" @@ -1678,11 +1704,6 @@ animated@^0.2.2: invariant "^2.2.0" normalize-css-color "^1.0.1" -anser@^1.4.9: - version "1.4.9" - resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" - integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== - ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" @@ -2156,7 +2177,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0, babel-preset-fbjs@^3.3.0: +babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz#a6024764ea86c8e06a22d794ca8b69534d263541" integrity sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw== @@ -2854,6 +2875,16 @@ clone-deep@^0.2.4: lazy-cache "^1.0.3" shallow-clone "^0.1.2" +clone-deep@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713" + integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ== + dependencies: + for-own "^1.0.0" + is-plain-object "^2.0.4" + kind-of "^6.0.0" + shallow-clone "^1.0.0" + clone-regexp@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f" @@ -3813,6 +3844,13 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.4.tgz#a757397dc5d9de973ac9a5d7d4e8ade7cfae9101" + integrity sha512-fZ0KkoxSjLFmhW5lHbUT3tLwy3nX1qEzMYo8koY1vrsAco53CMT1djnBSeC/wUjTEZRhZl9iRw7PaMaxfJ4wzQ== + dependencies: + stackframe "^1.1.0" + errorhandler@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.1.tgz#b9ba5d17cf90744cd1e851357a6e75bf806a9a91" @@ -4050,10 +4088,10 @@ eslint-plugin-react@^7.12.4: prop-types "^15.7.2" resolve "^1.12.0" -eslint-plugin-relay@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.4.1.tgz#5af2ac13e24bd01ad17b6a4014204918d65021cd" - integrity sha512-yb+p+4AxZTi2gXN7cZRfXMBFlRa5j6TtiVeq3yHXyy+tlgYNpxi/dDrP1+tcUTNP9vdaJovnfGZ5jp6kMiH9eg== +eslint-plugin-relay@1.3.12: + version "1.3.12" + resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.3.12.tgz#1e7d936386650ccc7709c8f6eeb0210e0e226527" + integrity sha512-276RrlyF0112Mz8PbaDvYKmqBGYEm0WBCfMNunnm6jHQ0aClUbPUmNctJXpFjfurcZfNEOz22Nx3VUMVDIGIkw== dependencies: graphql "^14.0.0" @@ -4660,6 +4698,13 @@ for-own@^0.1.3: dependencies: for-in "^1.0.1" +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + foreach@~2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -5189,10 +5234,10 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-engine@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.3.0.tgz#c03ded211102eef775045a5f55e286783db8ad48" - integrity sha512-Xl21n/FohkoeQyz/9AeisoePhXaLvXRyT41xkYHOrqoNr+pkLUGc1xIo486ctIxSp5SN4BkN6T3YFWOdD0ntaQ== +hermes-engine@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" + integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== hmac-drbg@^1.0.0: version "1.0.1" @@ -6499,7 +6544,7 @@ kind-of@^5.0.0: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== -kind-of@^6.0.0, kind-of@^6.0.2: +kind-of@^6.0.0, kind-of@^6.0.1, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== @@ -7011,24 +7056,6 @@ metro-babel-register@0.56.3: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-register@0.57.0: - version "0.57.0" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.57.0.tgz#43acb47a7f45543428830db5634b33e8e7543c39" - integrity sha512-toZwgFY/y/+8GxSLT6kDRI5/hcnm7VtVglMo8WN9p9LEeGjKgWeJrf6YrrqQ8L+Ycy771w00jHZVw2QwlvCQUQ== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - metro-babel-transformer@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" @@ -7044,14 +7071,6 @@ metro-babel-transformer@0.56.3: "@babel/core" "^7.0.0" metro-source-map "0.56.3" -metro-babel-transformer@0.57.0: - version "0.57.0" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.57.0.tgz#8f4bd17ad5631937cdb5651e7d77f9c73b9f935c" - integrity sha512-679BstNiPUUt5a4f86iJTa7q8jFntgd9SQBVWN+CLI5L9T7iTxi7JDbR+oHIOi3OT/dBlY9s2dWZCVAuNW9DHA== - dependencies: - "@babel/core" "^7.0.0" - metro-source-map "0.57.0" - metro-babel7-plugin-react-transform@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" @@ -7242,7 +7261,7 @@ metro-react-native-babel-preset@0.56.3: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-preset@0.57.0, metro-react-native-babel-preset@^0.57.0: +metro-react-native-babel-preset@^0.57.0: version "0.57.0" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.57.0.tgz#bbbce26a20d9ca3fdc08f0df564bc982b82651b7" integrity sha512-pvLh1QOwdxsjgYE2a+4aTKs3LSF3+t4jscxHtkND6wsJnKVVspLt8FkDaORa6zr3Fq12tVpEt5NJMdgtWqBpaA== @@ -7283,16 +7302,16 @@ metro-react-native-babel-preset@0.57.0, metro-react-native-babel-preset@^0.57.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@0.57.0: - version "0.57.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.57.0.tgz#60e3b97f73f016c138096c1a706ccc3bc4590fcf" - integrity sha512-Pw8N3InjUVJT23w/LNKwrWeXY50aODv2js/WCfwguZqriJqELOCxF1BWgvsChGNuDpkl0ihKct4224w0+4ktyA== +metro-react-native-babel-transformer@0.56.3, metro-react-native-babel-transformer@^0.56.0: + version "0.56.3" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" + integrity sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw== dependencies: "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.3.0" - metro-babel-transformer "0.57.0" - metro-react-native-babel-preset "0.57.0" - metro-source-map "0.57.0" + babel-preset-fbjs "^3.1.2" + metro-babel-transformer "0.56.3" + metro-react-native-babel-preset "0.56.3" + metro-source-map "0.56.3" metro-react-native-babel-transformer@^0.54.1: version "0.54.1" @@ -7304,17 +7323,6 @@ metro-react-native-babel-transformer@^0.54.1: metro-babel-transformer "0.54.1" metro-react-native-babel-preset "0.54.1" -metro-react-native-babel-transformer@^0.56.0: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" - integrity sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "0.56.3" - metro-react-native-babel-preset "0.56.3" - metro-source-map "0.56.3" - metro-resolver@0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" @@ -7351,19 +7359,6 @@ metro-source-map@0.56.3: source-map "^0.5.6" vlq "^1.0.0" -metro-source-map@0.57.0: - version "0.57.0" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.57.0.tgz#f6715b8687041804e4e0679bad4e8946bf9dd5a7" - integrity sha512-hYd2MmLUOmOJkQCzABLV3mYW7JwzkfvL9SUAHhRDzUS4Z69k+Yh2805HpH8/gN6SGvfw0PuPXXEixtvW66b6yQ== - dependencies: - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - invariant "^2.2.4" - metro-symbolicate "0.57.0" - ob1 "0.57.0" - source-map "^0.5.6" - vlq "^1.0.0" - metro-symbolicate@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz#20f9dc52fab3209903715716402692b3ac16831c" @@ -7375,17 +7370,6 @@ metro-symbolicate@0.56.3: through2 "^2.0.1" vlq "^1.0.0" -metro-symbolicate@0.57.0: - version "0.57.0" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.57.0.tgz#64693841190ad3d9b832af0490f16e95f51e4045" - integrity sha512-Gq30gqGAGYIpO7FdeUboQXaMUeiQqq2VNiPaLJg67zCz9FKLuS3Laf4i/mpUCzHv9+lqcEKIOEYP7SQaluUIPQ== - dependencies: - invariant "^2.2.4" - metro-source-map "0.57.0" - source-map "^0.5.6" - through2 "^2.0.1" - vlq "^1.0.0" - metro@0.54.1, metro@^0.54.1: version "0.54.1" resolved "https://registry.yarnpkg.com/metro/-/metro-0.54.1.tgz#a629be00abee5a450a25a8f71c24745f70cc9b44" @@ -8034,11 +8018,6 @@ ob1@0.56.3: resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.3.tgz#5829e446587c9bf89c22ece4f3757b29f2ccfd18" integrity sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ== -ob1@0.57.0: - version "0.57.0" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.57.0.tgz#2023173d54579ed5b28dc5943ab5d977401dbe0d" - integrity sha512-BRAyYcG7NeA8vZFQ/oMqw1fiRLdFcxi/x9DJ3KWeaSI7+tiO3MZwMjnkL9sdsZMEL4OtpggbeAK2dL3zYNiI1A== - object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -8208,7 +8187,7 @@ open@^7.0.0: dependencies: is-wsl "^2.1.0" -opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2: +opencollective-postinstall@^2.0.1, opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== @@ -9264,14 +9243,6 @@ react-native-fast-image@andrewschenk-linx/react-native-fast-image#fix-ios-xcode- version "7.0.2" resolved "https://codeload.github.com/andrewschenk-linx/react-native-fast-image/tar.gz/d19ae11a6469de94cb49211d00a7bc002ea76ff8" -react-native-firebase@^5.5.6: - version "5.5.6" - resolved "https://registry.yarnpkg.com/react-native-firebase/-/react-native-firebase-5.5.6.tgz#17b34ec0d5dc39afaaf0e159fd160f6339e0f707" - integrity sha512-AdbpGwKEEiMFgaRar9WOPc8Li4sfxR//WOyNQzxYsQ1fpARC908j7feqy2gu73SLqk4wzIrnlfJWakOe0/Bclg== - dependencies: - opencollective-postinstall "^2.0.0" - prop-types "^15.7.2" - react-native-gesture-handler@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.1.tgz#681cef98954d48cd82f99f75de3ab203c8754354" @@ -9490,25 +9461,24 @@ react-native@facebook/react-native: resolved "https://codeload.github.com/facebook/react-native/tar.gz/ac3c167ead8609410660da48b594fedc35b68489" dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0" - "@react-native-community/cli-platform-android" "^3.0.0" - "@react-native-community/cli-platform-ios" "^3.0.0" + "@react-native-community/cli" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" abort-controller "^3.0.0" - anser "^1.4.9" base64-js "^1.1.2" connect "^3.6.5" create-react-class "^15.6.3" escape-string-regexp "^1.0.5" - eslint-plugin-relay "1.4.1" + eslint-plugin-relay "1.3.12" event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermes-engine "~0.3.0" + hermes-engine "^0.2.1" invariant "^2.2.4" jsc-android "^245459.0.0" - metro-babel-register "0.57.0" - metro-react-native-babel-transformer "0.57.0" - metro-source-map "0.57.0" + metro-babel-register "0.56.3" + metro-react-native-babel-transformer "0.56.3" + metro-source-map "0.56.3" nullthrows "^1.1.1" pretty-format "^24.7.0" promise "^7.1.1" @@ -9516,7 +9486,7 @@ react-native@facebook/react-native: react-devtools-core "^4.0.6" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.17.0" + scheduler "0.16.2" stacktrace-parser "^0.1.3" use-subscription "^1.0.0" whatwg-fetch "^3.0.0" @@ -10306,10 +10276,10 @@ schedule@0.5.0: dependencies: object-assign "^4.1.1" -scheduler@0.17.0: - version "0.17.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" - integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA== +scheduler@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" + integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -10441,6 +10411,15 @@ shallow-clone@^0.1.2: lazy-cache "^0.2.3" mixin-object "^2.0.1" +shallow-clone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571" + integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA== + dependencies: + is-extendable "^0.1.1" + kind-of "^5.0.0" + mixin-object "^2.0.1" + shallowequal@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" @@ -10675,6 +10654,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -10766,11 +10750,40 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-generator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.4.tgz#027513eab2b195bbb43b9c8360ba2dd0ab54de09" + integrity sha512-ha1gosTNcgxwzo9uKTQ8zZ49aUp5FIUW58YHFxCqaAHtE0XqBg0chGFYA1MfmW//x1KWq3F4G7Ug7bJh4RiRtg== + dependencies: + stackframe "^1.1.0" + stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stackframe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83" + integrity sha512-Vx6W1Yvy+AM1R/ckVwcHQHV147pTPBKWCRLrXMuPrFVfvBUc3os7PR1QLIWCMhPpRg5eX9ojzbQIMLGBwyLjqg== + +stacktrace-gps@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.3.tgz#b89f84cc13bb925b96607e737b617c8715facf57" + integrity sha512-51Rr7dXkyFUKNmhY/vqZWK+EvdsfFSRiQVtgHTFlAdNIYaDD7bVh21yBHXaNWAvTD+w+QSjxHg7/v6Tz4veExA== + dependencies: + source-map "0.5.6" + stackframe "^1.1.0" + +stacktrace-js@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.1.tgz#ebdb0e9a16e6f171f96ca7878404e7f15c3d42ba" + integrity sha512-13oDNgBSeWtdGa4/2BycNyKqe+VktCoJ8VLx4pDoJkwGGJVtiHdfMOAj3aW9xTi8oR2v34z9IcvfCvT6XNdNAw== + dependencies: + error-stack-parser "^2.0.4" + stack-generator "^2.0.4" + stacktrace-gps "^3.0.3" + stacktrace-parser@^0.1.3: version "0.1.7" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.7.tgz#9ed005638a5e79dcf256611da1dfb4871e6fd14d" @@ -11112,6 +11125,14 @@ superagent@^5.1.0: readable-stream "^3.4.0" semver "^6.1.1" +superstruct@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.6.2.tgz#c5eb034806a17ff98d036674169ef85e4c7f6a1c" + integrity sha512-lvA97MFAJng3rfjcafT/zGTSWm6Tbpk++DP6It4Qg7oNaeM+2tdJMuVgGje21/bIpBEs6iQql1PJH6dKTjl4Ig== + dependencies: + clone-deep "^2.0.1" + kind-of "^6.0.1" + supports-color@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" From ebe04ccd05dc8a6d859729a73c0bf70858103f8c Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz Date: Wed, 11 Dec 2019 16:08:22 +0100 Subject: [PATCH 594/636] add white background to prevent sections overlay --- src/components/list/ListHeader.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/list/ListHeader.js b/src/components/list/ListHeader.js index 99004a0c028..800cc94aa4b 100644 --- a/src/components/list/ListHeader.js +++ b/src/components/list/ListHeader.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React, { createElement, Fragment } from 'react'; +import { View } from 'react-native'; import { pure } from 'recompact'; import { colors, padding, position } from '../../styles'; import LinearGradient from 'react-native-linear-gradient'; @@ -7,6 +8,7 @@ import { Row } from '../layout'; import { H1 } from '../text'; import ContextMenu from '../ContextMenu'; import Divider from '../Divider'; +import { deviceUtils } from '../../utils'; const height = 42; @@ -42,6 +44,15 @@ const ListHeader = pure( {children} {showDivider && } + {!isSticky && title !== 'Balances' && ( + + )} ) ); From 35314cb4fa02c95f428ed9c26d6b20622c145412 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 10 Dec 2019 18:25:48 -0500 Subject: [PATCH 595/636] Include react native push notifications ios --- ios/Podfile | 2 + ios/Podfile.lock | 52 ++++++----- ios/Rainbow.xcodeproj/project.pbxproj | 22 +++++ ios/Rainbow/AppDelegate.m | 18 ++-- package.json | 1 + src/App.js | 93 +++++++------------ src/hoc/withDeepLink.js | 2 +- .../TransactionConfirmationScreenWithData.js | 7 +- yarn.lock | 7 ++ 9 files changed, 108 insertions(+), 96 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 28a077b73c4..88310e0fb60 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -46,4 +46,6 @@ target 'Rainbow' do use_native_modules! + pod 'RNCPushNotificationIOS', :path => '../node_modules/@react-native-community/push-notification-ios' + end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f24105fc9ab..33fdf96451f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -376,6 +376,8 @@ PODS: - React - RNCMaskedView (0.1.5): - React + - RNCPushNotificationIOS (1.0.3): + - React - RNDeviceInfo (2.3.2): - React - RNFastImage (7.0.2): @@ -477,6 +479,7 @@ DEPENDENCIES: - "RNAnalytics (from `../node_modules/@segment/analytics-react-native`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" + - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNFastImage (from `../node_modules/react-native-fast-image`) - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" @@ -607,6 +610,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/async-storage" RNCMaskedView: :path: "../node_modules/@react-native-community/masked-view" + RNCPushNotificationIOS: + :path: "../node_modules/@react-native-community/push-notification-ios" RNDeviceInfo: :path: "../node_modules/react-native-device-info" RNFastImage: @@ -657,8 +662,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: cee5277c189088563dfbfcdfb2fb90ce482549b7 - FBReactNativeSpec: d89f618c1087b284b7930ca8431a4b9b7dd01663 + FBLazyVector: d404836aeeaa2d8acfdbcdebbe70f77a2e4fe4e4 + FBReactNativeSpec: 4dbf83fb73710a5a35d0c894c5e3ed0dcbac2450 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -678,15 +683,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 3718135886395b0fa06d65511d9839a21e1c4237 - RCTTypeSafety: cb607d0b629091f1b6fce5d95fe09cee7c6715fd - React: 53b5a3d7bfb52ed8bbe55f6a4c147adab4bba4f4 - React-Core: f74a5e1c147171ff271d345f209e5340cf101459 - React-CoreModules: c44fd5637e4e96d907dbe2c57800a886c2980181 - React-cxxreact: 370308ed0aabc8b5dc29b8b38d07171514e59740 - React-jsi: ed8c383e93950c7f4175153571d0af11a0f272b1 - React-jsiexecutor: f8e63cd38810b258de43d7ce58d9fb60ecb87536 - React-jsinspector: 435a4f58ddbcf07ebd202401913451d15aec3c26 + RCTRequired: 803acce5991522ab267d01eaa10a87da037233f3 + RCTTypeSafety: 3a8265cde2a81a2796a443878169993faf60aa76 + React: f6ecd230cd4efecf6af176921ab4de3d11a07964 + React-Core: 05930428f3aead2f87e24e0d874840841e913868 + React-CoreModules: 913abd1bd37142fe3a48bfeebf2d31e995d1b166 + React-cxxreact: efaca513c76a265ce5779d3ea1defa47f8bd65d6 + React-jsi: 901c02f197134dc58f26434420d9c4e103e48edf + React-jsiexecutor: 44f2200c6914c98c10cb078bc5a3fba2d13008bb + React-jsinspector: e69cce41a49d95767abb96b0abc3b976bfe71b77 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 576f6dbb490af4285de1f8002a09dd3daa86c112 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -697,20 +702,21 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 7ef91294a1b9b73b2ea8ab4795253caf06440db9 - React-RCTAnimation: 26602115e92a18318fa85962fb06932101f9cad2 - React-RCTBlob: 011677c5f98bef3e749d8eb743ce7942732a65e6 - React-RCTImage: 1e9184b0f93d6e367a47eb6df146d9a372c6366e - React-RCTLinking: 2adb6836662921a1d65bab45e1e1a44770abe495 - React-RCTNetwork: 53d39cb9969c6d7f2279dbea9e1ba7dccd4a997e - React-RCTSettings: cb95158be9c445092e215e71dcc2a1505e44662a - React-RCTText: c753688e7b91fe95aa0156918983b6a84441064e - React-RCTVibration: 8e8b76d18b9bd2d99822085a7be08f5d5043c9a9 - ReactCommon: 21cfc09dff47ac417086143cabcf4505aade833b + React-RCTActionSheet: 6ba1728ad985692e5fb3f71b5f43f026ece558d3 + React-RCTAnimation: d87bd4d3d816cdb8085141c60721326ed0e6c972 + React-RCTBlob: 8000ae9818e72a6ffda06f6adcfec59e30d354e4 + React-RCTImage: 00a1e7e7e87cd1d416b9ea46fc21633ddfd42ae0 + React-RCTLinking: f2301e75e9610aa35278a522f6f8a9dfc5835505 + React-RCTNetwork: b93c472f746642c6d6807bcf0a2e4691ad41ab09 + React-RCTSettings: 51990ae52e8da0aa1b9f5cce02f6976b0ad1af17 + React-RCTText: feb3453236dcdd195878d576988df9c8fd500a19 + React-RCTVibration: f1224b7b0eefef4b4e3f503889efd72791c52db5 + ReactCommon: edc5a0b6f4b94e8dccd14145beb8940321be5698 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 + RNCPushNotificationIOS: 83ec11fe19d4ea9e32cc339d8e7d2cc3c88f543e RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFBApp: 5b215aacc09105a1761de31b9a0eb2abcce06253 @@ -733,8 +739,8 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 0116cce1e3bce6b133fb6b3064a6722e14e49a6b + Yoga: 9ead55da0909bc1214fd81897f52280e84b83e1d -PODFILE CHECKSUM: aef26f80c98a94feb5ccc3dae817781bd425ca10 +PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 COCOAPODS: 1.8.4 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 83e73bc1d51..0ad54c7cfc0 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -383,6 +383,8 @@ 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 3CF823D3218F310D0024B77B /* ShellScript */, + 7D8EDE895DE18700A743F64E /* [CP-User] [RNFB] Core Configuration */, + 8C1D9934C43085FED5C8B69C /* [CP-User] [RNFB] Crashlytics Configuration */, ); buildRules = ( ); @@ -532,6 +534,26 @@ shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Fabric/run\"\n"; }; + 7D8EDE895DE18700A743F64E /* [CP-User] [RNFB] Core Configuration */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + name = "[CP-User] [RNFB] Core Configuration"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n _JSON_OUTPUT_BASE64=$(python -c 'import json,sys,base64;print(base64.b64encode(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"').read())['${_JSON_ROOT}'])))' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes usful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"firebase_crashlytics_collection_enabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\n\n # config.admob_delay_app_measurement_init\n _ADMOB_DELAY_APP_MEASUREMENT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_delay_app_measurement_init\")\n if [[ $_ADMOB_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.admob_ios_app_id\n _ADMOB_IOS_APP_ID=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"admob_ios_app_id\")\n if [[ $_ADMOB_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_ADMOB_IOS_APP_ID\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in ${_TARGET_PLIST} ${_DSYM_PLIST} ; do\n if [[ -f ${plist} ]]; then\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n\n\n\n"; + }; + 8C1D9934C43085FED5C8B69C /* [CP-User] [RNFB] Crashlytics Configuration */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + name = "[CP-User] [RNFB] Crashlytics Configuration"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nset -e\n\nif [[ ${PODS_ROOT} ]]; then\n echo \"info: Exec Fabric Run from Pods\"\n \"${PODS_ROOT}/Fabric/run\"\nelse\n echo \"info: Exec Fabric Run from framework\"\n \"${PROJECT_DIR}/Fabric.framework/run\"\nfi\n"; + }; B448B1B66A188D3AC6DA3639 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Rainbow/AppDelegate.m b/ios/Rainbow/AppDelegate.m index 90412bb2b71..16151f7b516 100644 --- a/ios/Rainbow/AppDelegate.m +++ b/ios/Rainbow/AppDelegate.m @@ -12,6 +12,7 @@ #import #import #import +#import #import "RNSplashScreen.h" @implementation AppDelegate @@ -50,16 +51,17 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge #endif } -- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { - [[RNFirebaseNotifications instance] didReceiveLocalNotification:notification]; -} - -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{ - [[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; +// Required for the notification event. You must call the completion handler after handling the remote notification. +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo +fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler +{ + [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } -- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - [[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings]; +// Required for the localNotification event. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification +{ + [RNCPushNotificationIOS didReceiveLocalNotification:notification]; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url diff --git a/package.json b/package.json index d3edd682a33..412c36ff097 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@react-native-community/blur": "^3.3.1", "@react-native-community/masked-view": "^0.1.5", "@react-native-community/netinfo": "^4.6.0", + "@react-native-community/push-notification-ios": "^1.0.3", "@react-native-firebase/app": "^6.2.0", "@react-native-firebase/crashlytics": "^6.2.0", "@react-native-firebase/messaging": "^6.2.0", diff --git a/src/App.js b/src/App.js index 662e7b04e72..9e1d1614ba6 100644 --- a/src/App.js +++ b/src/App.js @@ -1,3 +1,5 @@ +// eslint-disable-next-line import/default +import PushNotificationIOS from '@react-native-community/push-notification-ios'; import analytics from '@segment/analytics-react-native'; import { get, last } from 'lodash'; import PropTypes from 'prop-types'; @@ -37,7 +39,6 @@ useScreens(false); class App extends Component { static propTypes = { addDeepLinkRequest: PropTypes.func, - appInitTimestamp: PropTypes.number, requestsForTopic: PropTypes.func, walletConnectClearTimestamp: PropTypes.func, walletConnectOnSessionRequest: PropTypes.func, @@ -50,58 +51,33 @@ class App extends Component { AppState.addEventListener('change', this.handleAppStateChange); Linking.addEventListener('url', this.handleOpenLinkingURL); await this.handleInitializeAnalytics(); - firebase - .notifications() - .getInitialNotification() - .then(notificationOpen => { - if (notificationOpen) { - const topic = get(notificationOpen, 'notification.data.topic'); - this.onPushNotificationOpened(topic, false); - } - }); - saveFCMToken(); this.onTokenRefreshListener = registerTokenRefreshListener(); - - // notification while app in foreground - this.notificationListener = firebase - .notifications() - .onNotification(notification => { - const route = Navigation.getActiveRouteName(); - if (route === 'ConfirmRequest') { - const localNotification = new firebase.notifications.Notification() - .setTitle(notification.title) - .setBody(notification.body) - .setData({ ...notification.data, fromLocal: true }); - firebase.notifications().displayNotification(localNotification); - } else { - const topic = get(notification, 'data.topic'); - this.onPushNotificationOpened(topic, true); - } - }); - - // notification opened from background - this.notificationOpenedListener = firebase - .notifications() - .onNotificationOpened(notificationOpen => { - const topic = get(notificationOpen, 'notification.data.topic'); - const fromLocal = get( - notificationOpen, - 'notification.data.fromLocal', - false - ); - this.onPushNotificationOpened(topic, false, fromLocal); - }); + PushNotificationIOS.addEventListener( + 'notification', + this.onRemoteNotification + ); } componentWillUnmount() { AppState.removeEventListener('change', this.handleAppStateChange); Linking.removeEventListener('url', this.handleOpenLinkingURL); - this.notificationListener(); - this.notificationOpenedListener(); + PushNotificationIOS.removeEventListener( + 'notification', + this.onRemoteNotification + ); this.onTokenRefreshListener(); } + onRemoteNotification = notification => { + const { appState } = this.state; + const topic = get(notification, '_data.topic'); + notification.finish(PushNotificationIOS.FetchResult.NoData); + const shouldOpenAutomatically = + appState === 'active' || appState === 'inactive'; + this.onPushNotificationOpened(topic, shouldOpenAutomatically); + }; + handleOpenLinkingURL = ({ url }) => { const { addDeepLinkRequest, walletConnectOnSessionRequest } = this.props; Linking.canOpenURL(url).then(supported => { @@ -118,28 +94,21 @@ class App extends Component { }); }; - onPushNotificationOpened = (topic, autoOpened = false, fromLocal = false) => { - const { appInitTimestamp, requestsForTopic } = this.props; + onPushNotificationOpened = (topic, openAutomatically = false) => { + const { requestsForTopic } = this.props; const requests = requestsForTopic(topic); - if (requests && requests.length === 1) { - const request = requests[0]; - - const transactionTimestamp = get(request, 'displayDetails.timestampInMs'); - const isNewTransaction = - appInitTimestamp && transactionTimestamp > appInitTimestamp; - - if (!autoOpened || isNewTransaction) { - return Navigation.handleAction({ - params: { autoOpened, transactionDetails: request }, - routeName: 'ConfirmRequest', - }); - } + if (openAutomatically && requests) { + return Navigation.handleAction({ + params: { openAutomatically, transactionDetails: last(requests) }, + routeName: 'ConfirmRequest', + }); } - if (fromLocal) { + if (requests && requests.length === 1) { + const request = requests[0]; return Navigation.handleAction({ - params: { autoOpened, transactionDetails: last(requests) }, + params: { openAutomatically, transactionDetails: request }, routeName: 'ConfirmRequest', }); } @@ -172,7 +141,7 @@ class App extends Component { handleAppStateChange = async nextAppState => { if (nextAppState === 'active') { this.props.walletConnectUpdateTimestamp(); - await firebase.notifications().removeAllDeliveredNotifications(); + PushNotificationIOS.removeAllDeliveredNotifications(); } if (nextAppState === 'background') { this.props.walletConnectClearTimestamp(); @@ -198,7 +167,7 @@ const AppWithRedux = compose( withDeepLink, withWalletConnectConnections, withWalletConnectOnSessionRequest, - connect(({ walletconnect: { appInitTimestamp } }) => ({ appInitTimestamp }), { + connect(null, { requestsForTopic, }) )(App); diff --git a/src/hoc/withDeepLink.js b/src/hoc/withDeepLink.js index 287e2a9011e..19b38f5c8c4 100644 --- a/src/hoc/withDeepLink.js +++ b/src/hoc/withDeepLink.js @@ -124,8 +124,8 @@ export default Component => }; return Navigation.handleAction({ params: { - autoOpened: true, callback: redirect, + openAutomatically: true, transactionDetails: request, }, routeName: 'ConfirmRequest', diff --git a/src/screens/TransactionConfirmationScreenWithData.js b/src/screens/TransactionConfirmationScreenWithData.js index d8259b68f75..bbf99b7f066 100644 --- a/src/screens/TransactionConfirmationScreenWithData.js +++ b/src/screens/TransactionConfirmationScreenWithData.js @@ -36,8 +36,11 @@ class TransactionConfirmationScreenWithData extends PureComponent { }; componentDidMount() { - const autoOpened = get(this.props, 'navigation.state.params.autoOpened'); - if (autoOpened) { + const openAutomatically = get( + this.props, + 'navigation.state.params.openAutomatically' + ); + if (openAutomatically) { Vibration.vibrate(); } } diff --git a/yarn.lock b/yarn.lock index 60158c504cc..e13cf7cbd08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1160,6 +1160,13 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.6.1.tgz#09960b49217d555e54144f54e63485fe55d673ad" integrity sha512-RIcrNzVnkes6/d5jFprce8i6ruUO9+/FVZZgejlu/TSnysyFXHNJKgcIqxbKx+7XfQxfjrCGeCvsfYxrFrU0zw== +"@react-native-community/push-notification-ios@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@react-native-community/push-notification-ios/-/push-notification-ios-1.0.3.tgz#cd2c7f29aeeb431942eda0bd729738fd2b444ae9" + integrity sha512-f+Y3lFLt5OBWHDtGHE+PiZH4aLeS8w2D47c0G/S5XpzeGoEeggOiALtou/r6raiVLP+D5CrLkIBMs2U2+LGJhw== + dependencies: + invariant "^2.2.4" + "@react-native-firebase/app-types@6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@react-native-firebase/app-types/-/app-types-6.2.0.tgz#4d3c0e7fa4e4f00061c52b1a32d76e85e5db9f2c" From 7c31552a0c30ff9388db910af03c8a0f4cf71e98 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 10 Dec 2019 20:35:58 -0500 Subject: [PATCH 596/636] Remove unused app init timestamp --- src/App.js | 13 +------------ src/hoc/withWalletConnectConnections.js | 8 +------- src/redux/walletconnect.js | 16 ---------------- 3 files changed, 2 insertions(+), 35 deletions(-) diff --git a/src/App.js b/src/App.js index 9e1d1614ba6..e86dac93a8a 100644 --- a/src/App.js +++ b/src/App.js @@ -17,11 +17,7 @@ import { connect, Provider } from 'react-redux'; import { compose, withProps } from 'recompact'; import { FlexItem } from './components/layout'; import OfflineBadge from './components/OfflineBadge'; -import { - withDeepLink, - withWalletConnectConnections, - withWalletConnectOnSessionRequest, -} from './hoc'; +import { withDeepLink, withWalletConnectOnSessionRequest } from './hoc'; import { registerTokenRefreshListener, saveFCMToken } from './model/firebase'; import * as keychain from './model/keychain'; import { Navigation } from './navigation'; @@ -40,9 +36,7 @@ class App extends Component { static propTypes = { addDeepLinkRequest: PropTypes.func, requestsForTopic: PropTypes.func, - walletConnectClearTimestamp: PropTypes.func, walletConnectOnSessionRequest: PropTypes.func, - walletConnectUpdateTimestamp: PropTypes.func, }; state = { appState: AppState.currentState }; @@ -140,12 +134,8 @@ class App extends Component { handleAppStateChange = async nextAppState => { if (nextAppState === 'active') { - this.props.walletConnectUpdateTimestamp(); PushNotificationIOS.removeAllDeliveredNotifications(); } - if (nextAppState === 'background') { - this.props.walletConnectClearTimestamp(); - } this.setState({ appState: nextAppState }); }; @@ -165,7 +155,6 @@ class App extends Component { const AppWithRedux = compose( withProps({ store }), withDeepLink, - withWalletConnectConnections, withWalletConnectOnSessionRequest, connect(null, { requestsForTopic, diff --git a/src/hoc/withWalletConnectConnections.js b/src/hoc/withWalletConnectConnections.js index c454eeeca51..0fab67d1b58 100644 --- a/src/hoc/withWalletConnectConnections.js +++ b/src/hoc/withWalletConnectConnections.js @@ -3,11 +3,7 @@ import { connect } from 'react-redux'; import { compose, withProps } from 'recompact'; import { createSelector } from 'reselect'; import { sortList } from '../helpers/sortList'; -import { - walletConnectClearTimestamp, - walletConnectDisconnectAllByDappName, - walletConnectUpdateTimestamp, -} from '../redux/walletconnect'; +import { walletConnectDisconnectAllByDappName } from '../redux/walletconnect'; const mapStateToProps = ({ walletconnect: { walletConnectors } }) => ({ walletConnectors, @@ -48,9 +44,7 @@ const walletConnectSelector = createSelector( export default Component => compose( connect(mapStateToProps, { - walletConnectClearTimestamp, walletConnectDisconnectAllByDappName, - walletConnectUpdateTimestamp, }), withProps(walletConnectSelector) )(Component); diff --git a/src/redux/walletconnect.js b/src/redux/walletconnect.js index f74988eb032..48dfb6d7a2a 100644 --- a/src/redux/walletconnect.js +++ b/src/redux/walletconnect.js @@ -28,10 +28,6 @@ const WALLETCONNECT_REMOVE_SESSION = 'walletconnect/WALLETCONNECT_REMOVE_SESSION'; const WALLETCONNECT_INIT_SESSIONS = 'walletconnect/WALLETCONNECT_INIT_SESSIONS'; -const WALLETCONNECT_INIT_TIMESTAMP = - 'walletconnect/WALLETCONNECT_INIT_TIMESTAMP'; -const WALLETCONNECT_CLEAR_TIMESTAMP = - 'walletconnect/WALLETCONNECT_CLEAR_TIMESTAMP'; const WALLETCONNECT_CLEAR_STATE = 'walletconnect/WALLETCONNECT_CLEAR_STATE'; // -- Actions ---------------------------------------- // @@ -126,12 +122,6 @@ const listenOnNewMessages = walletConnector => dispatch => { return walletConnector; }; -export const walletConnectUpdateTimestamp = () => dispatch => - dispatch({ payload: Date.now(), type: WALLETCONNECT_INIT_TIMESTAMP }); - -export const walletConnectClearTimestamp = () => dispatch => - dispatch({ type: WALLETCONNECT_CLEAR_TIMESTAMP }); - export const walletConnectClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; removeWalletConnect(accountAddress, network); @@ -139,7 +129,6 @@ export const walletConnectClearState = () => (dispatch, getState) => { }; export const walletConnectLoadState = () => async (dispatch, getState) => { - dispatch(walletConnectUpdateTimestamp()); const { accountAddress, network } = getState().settings; let walletConnectors = {}; try { @@ -321,7 +310,6 @@ export const walletConnectSendStatus = (peerId, requestId, result) => async ( // -- Reducer ----------------------------------------- // const INITIAL_STATE = { - appInitTimestamp: null, pendingRequests: {}, walletConnectors: {}, }; @@ -338,10 +326,6 @@ export default (state = INITIAL_STATE, action) => { return { ...state, walletConnectors: action.payload }; case WALLETCONNECT_INIT_SESSIONS: return { ...state, walletConnectors: action.payload }; - case WALLETCONNECT_INIT_TIMESTAMP: - return { ...state, appInitTimestamp: action.payload }; - case WALLETCONNECT_CLEAR_TIMESTAMP: - return { ...state, appInitTimestamp: null }; case WALLETCONNECT_CLEAR_STATE: return { ...state, ...INITIAL_STATE }; default: From ac12a19ecc57cf7e4d97a84e5680f6a6a9480a47 Mon Sep 17 00:00:00 2001 From: jinchung Date: Mon, 2 Dec 2019 17:30:05 -0500 Subject: [PATCH 597/636] Support remote list of token overrides --- src/handlers/tokenOverrides.js | 30 ++++++++++++++++++++++++++++ src/hoc/withDataInit.js | 8 +++++++- src/parsers/accounts.js | 9 ++++----- src/parsers/transactions.js | 15 ++++++++++---- src/redux/data.js | 31 +++++++++++++++++++++++++---- src/references/index.js | 16 ++++++++------- src/references/token-overrides.json | 3 --- 7 files changed, 88 insertions(+), 24 deletions(-) create mode 100644 src/handlers/tokenOverrides.js diff --git a/src/handlers/tokenOverrides.js b/src/handlers/tokenOverrides.js new file mode 100644 index 00000000000..285da0347ad --- /dev/null +++ b/src/handlers/tokenOverrides.js @@ -0,0 +1,30 @@ +import axios from 'axios'; +import { get, mapKeys, toLower } from 'lodash'; + +/** + * Configuration for api + * @type axios instance + */ +const tokenOverridesEndpoint = axios.create({ + baseURL: + 'https://raw.githubusercontent.com/rainbow-me/asset-overrides/master/token-overrides.json', + headers: { + Accept: 'application/json', + }, + timeout: 20000, // 20 secs +}); + +/** + * @desc get token overrides + * @return {Promise} + */ +export const apiGetTokenOverrides = async () => { + try { + const data = await tokenOverridesEndpoint.get(); + const overrides = get(data, 'data') || {}; + return mapKeys(overrides, (value, address) => toLower(address)); + } catch (error) { + console.log('Error getting token overrides', error); + throw error; + } +}; diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index a258c3732c4..7372bdc5c87 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -6,7 +6,11 @@ import { compose, withHandlers } from 'recompact'; import { getIsWalletEmpty } from '../handlers/localstorage/accountLocal'; import { hasEthBalance } from '../handlers/web3'; import { walletInit } from '../model/wallet'; -import { dataClearState, dataLoadState } from '../redux/data'; +import { + dataClearState, + dataLoadState, + dataTokenOverridesInit, +} from '../redux/data'; import { explorerClearState, explorerInit } from '../redux/explorer'; import { gasClearState, gasPricesInit } from '../redux/gas'; import { clearIsWalletEmpty } from '../redux/isWalletEmpty'; @@ -51,6 +55,7 @@ export default Component => contactsLoadState, dataClearState, dataLoadState, + dataTokenOverridesInit, explorerClearState, explorerInit, gasClearState, @@ -109,6 +114,7 @@ export default Component => }, initializeAccountData: ownProps => async () => { try { + await ownProps.dataTokenOverridesInit(); ownProps.explorerInit(); ownProps.gasPricesInit(); ownProps.web3ListenerInit(); diff --git a/src/parsers/accounts.js b/src/parsers/accounts.js index f9b2853a33f..5396cdd3cd0 100644 --- a/src/parsers/accounts.js +++ b/src/parsers/accounts.js @@ -1,6 +1,5 @@ import { get, toUpper } from 'lodash'; import { convertRawAmountToBalance } from '../helpers/utilities'; -import { loweredTokenOverrides } from '../references'; import { dedupeUniqueTokens } from './uniqueTokens'; /** @@ -8,10 +7,10 @@ import { dedupeUniqueTokens } from './uniqueTokens'; * @param {Object} [data] * @return {Array} */ -export const parseAccountAssets = (data, uniqueTokens) => { +export const parseAccountAssets = (data, uniqueTokens, tokenOverrides) => { const dedupedAssets = dedupeUniqueTokens(data, uniqueTokens); let assets = dedupedAssets.map(assetData => { - const asset = parseAsset(assetData.asset); + const asset = parseAsset(assetData.asset, tokenOverrides); return { ...asset, balance: convertRawAmountToBalance(assetData.quantity, asset), @@ -26,7 +25,7 @@ export const parseAccountAssets = (data, uniqueTokens) => { * @param {Object} assetData * @return {Object} */ -export const parseAsset = assetData => { +export const parseAsset = (assetData, tokenOverrides) => { const address = get(assetData, 'asset_code', null); const name = get(assetData, 'name') || 'Unknown Token'; let symbol = get(assetData, 'symbol') || '———'; @@ -40,7 +39,7 @@ export const parseAsset = assetData => { price: get(assetData, 'price'), symbol: toUpper(symbol), uniqueId: address || name, - ...loweredTokenOverrides[address], + ...tokenOverrides[address], }; return asset; }; diff --git a/src/parsers/transactions.js b/src/parsers/transactions.js index 830a75e1846..17a74a0de8b 100644 --- a/src/parsers/transactions.js +++ b/src/parsers/transactions.js @@ -21,7 +21,6 @@ import { convertRawAmountToBalance, convertRawAmountToNativeDisplay, } from '../helpers/utilities'; -import { loweredTokenOverrides } from '../references'; import { isLowerCaseMatch } from '../utils'; const DIRECTION_OUT = 'out'; @@ -45,13 +44,16 @@ export default ( accountAddress, nativeCurrency, existingTransactions, + tokenOverrides, appended = false ) => { const data = appended ? dataFromLastTxHash(transactionData, existingTransactions) : transactionData; const parsedNewTransactions = flatten( - data.map(txn => parseTransaction(txn, accountAddress, nativeCurrency)) + data.map(txn => + parseTransaction(txn, accountAddress, nativeCurrency, tokenOverrides) + ) ); const [pendingTransactions, remainingTransactions] = partition( existingTransactions, @@ -102,7 +104,12 @@ const transformUniswapRefund = internalTransactions => { return compact([updatedOut, txnIn]); }; -const parseTransaction = (txn, accountAddress, nativeCurrency) => { +const parseTransaction = ( + txn, + accountAddress, + nativeCurrency, + tokenOverrides +) => { const transaction = pick(txn, [ 'hash', 'nonce', @@ -176,7 +183,7 @@ const parseTransaction = (txn, accountAddress, nativeCurrency) => { decimals: get(internalTxn, 'asset.decimals'), name: get(internalTxn, 'asset.name'), symbol: toUpper(get(internalTxn, 'asset.symbol') || ''), - ...loweredTokenOverrides[address], + ...tokenOverrides[address], }; const priceUnit = internalTxn.price || 0; const valueUnit = internalTxn.value || 0; diff --git a/src/redux/data.js b/src/redux/data.js index 8f62c5ead63..2d8817a4e63 100644 --- a/src/redux/data.js +++ b/src/redux/data.js @@ -7,9 +7,11 @@ import { saveAssets, saveLocalTransactions, } from '../handlers/localstorage/accountLocal'; +import { apiGetTokenOverrides } from '../handlers/tokenOverrides'; import { parseAccountAssets, parseAsset } from '../parsers/accounts'; import { parseNewTransaction } from '../parsers/newTransaction'; import parseTransactions from '../parsers/transactions'; +import { loweredTokenOverridesFallback } from '../references'; import { isLowerCaseMatch } from '../utils'; import { uniswapRemovePendingApproval, @@ -22,6 +24,7 @@ import { const DATA_UPDATE_ASSETS = 'data/DATA_UPDATE_ASSETS'; const DATA_UPDATE_TRANSACTIONS = 'data/DATA_UPDATE_TRANSACTIONS'; +const DATA_UPDATE_TOKEN_OVERRIDES = 'data/DATA_UPDATE_TOKEN_OVERRIDES'; const DATA_LOAD_ASSETS_REQUEST = 'data/DATA_LOAD_ASSETS_REQUEST'; const DATA_LOAD_ASSETS_SUCCESS = 'data/DATA_LOAD_ASSETS_SUCCESS'; @@ -61,6 +64,14 @@ export const dataLoadState = () => async (dispatch, getState) => { } }; +export const dataTokenOverridesInit = () => async dispatch => { + try { + const tokenOverrides = await apiGetTokenOverrides(); + dispatch(dataUpdateTokenOverrides(tokenOverrides)); + // eslint-disable-next-line no-empty + } catch (error) {} +}; + export const dataClearState = () => (dispatch, getState) => { const { accountAddress, network } = getState().settings; removeAssets(accountAddress, network); @@ -98,13 +109,14 @@ export const transactionsReceived = (message, appended = false) => ( const transactionData = get(message, 'payload.transactions', []); if (!transactionData.length) return; const { accountAddress, nativeCurrency, network } = getState().settings; - const { transactions } = getState().data; + const { transactions, tokenOverrides } = getState().data; if (!transactionData.length) return; const { approvalTransactions, dedupedResults } = parseTransactions( transactionData, accountAddress, nativeCurrency, transactions, + tokenOverrides, appended ); dispatch(uniswapRemovePendingApproval(approvalTransactions)); @@ -141,6 +153,7 @@ export const addressAssetsReceived = ( const isValidMeta = dispatch(checkMeta(message)); if (!isValidMeta) return; + const { tokenOverrides } = getState().data; const { accountAddress, network } = getState().settings; const { uniqueTokens } = getState().uniqueTokens; const assets = get(message, 'payload.assets', []); @@ -149,7 +162,7 @@ export const addressAssetsReceived = ( return symbol === 'UNI' || symbol === 'uni-v1'; }); dispatch(uniswapUpdateLiquidityTokens(liquidityTokens, append || change)); - let parsedAssets = parseAccountAssets(assets, uniqueTokens); + let parsedAssets = parseAccountAssets(assets, uniqueTokens, tokenOverrides); if (append || change) { const { assets: existingAssets } = getState().data; parsedAssets = uniqBy( @@ -164,10 +177,17 @@ export const addressAssetsReceived = ( }); }; -export const assetsReceived = message => dispatch => { +export const dataUpdateTokenOverrides = tokenOverrides => dispatch => + dispatch({ + payload: tokenOverrides, + type: DATA_UPDATE_TOKEN_OVERRIDES, + }); + +export const assetsReceived = message => (dispatch, getState) => { + const { tokenOverrides } = getState().data; const assets = get(message, 'payload.assets', []); if (!assets.length) return; - const parsedAssets = map(assets, asset => parseAsset(asset)); + const parsedAssets = map(assets, asset => parseAsset(asset, tokenOverrides)); dispatch(uniswapUpdateAssets(parsedAssets)); }; @@ -202,6 +222,7 @@ const INITIAL_STATE = { assets: [], loadingAssets: false, loadingTransactions: false, + tokenOverrides: loweredTokenOverridesFallback, transactions: [], }; @@ -209,6 +230,8 @@ export default (state = INITIAL_STATE, action) => { switch (action.type) { case DATA_UPDATE_ASSETS: return { ...state, assets: action.payload }; + case DATA_UPDATE_TOKEN_OVERRIDES: + return { ...state, tokenOverrides: action.payload }; case DATA_UPDATE_TRANSACTIONS: return { ...state, transactions: action.payload }; case DATA_LOAD_TRANSACTIONS_REQUEST: diff --git a/src/references/index.js b/src/references/index.js index 5fb2f2734f6..1fe9c52ac6b 100644 --- a/src/references/index.js +++ b/src/references/index.js @@ -1,20 +1,22 @@ import { keys, mapKeys, mapValues, toLower } from 'lodash'; -import tokenOverrides from './token-overrides.json'; -import uniswapAssetsRaw from './uniswap-pairs.json'; +import tokenOverridesFallback from './token-overrides.json'; +import uniswapAssetsFallback from './uniswap-pairs.json'; -export const loweredTokenOverrides = mapKeys(tokenOverrides, (value, address) => - toLower(address) +export const loweredTokenOverridesFallback = mapKeys( + tokenOverridesFallback, + (_, address) => toLower(address) ); -const uniswapAssetsRawLoweredKeys = mapKeys(uniswapAssetsRaw, (value, key) => - toLower(key) +const uniswapAssetsRawLoweredKeys = mapKeys( + uniswapAssetsFallback, + (value, key) => toLower(key) ); export const uniswapAssetsClean = mapValues( uniswapAssetsRawLoweredKeys, (value, key) => ({ ...value, - ...loweredTokenOverrides[key], + ...loweredTokenOverridesFallback[key], }) ); diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 3d61da0c3c2..5896e9c2c7e 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -181,9 +181,6 @@ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": { "name": "Wrapped Bitcoin" }, - "0x09fE5f0236F0Ea5D930197DCE254d77B04128075": { - "name": "Wrapped CryptoKitties" - }, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": { "name": "Wrapped Ether" } From 52357eaf9d072280f0db54b62f2899db63db5c80 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 3 Dec 2019 17:47:31 -0500 Subject: [PATCH 598/636] Support remote list of Uniswap pairs --- src/handlers/uniswap.js | 27 ++++++++++++++++++++++++++- src/hoc/withDataInit.js | 3 +++ src/hoc/withUniswapAssets.js | 29 +++++++++++++++++++---------- src/redux/explorer.js | 29 +++++++++++++++++++---------- src/redux/uniswap.js | 35 +++++++++++++++++++++++++++++++++-- src/references/index.js | 10 ++++------ 6 files changed, 104 insertions(+), 29 deletions(-) diff --git a/src/handlers/uniswap.js b/src/handlers/uniswap.js index 77424402617..c34f82edc77 100644 --- a/src/handlers/uniswap.js +++ b/src/handlers/uniswap.js @@ -1,7 +1,8 @@ import { getExecutionDetails, getTokenReserves } from '@uniswap/sdk'; +import axios from 'axios'; import contractMap from 'eth-contract-metadata'; import { ethers } from 'ethers'; -import { get, map, toLower, zipObject } from 'lodash'; +import { get, map, mapKeys, mapValues, toLower, zipObject } from 'lodash'; import { convertRawAmountToDecimalFormat, divide, @@ -13,6 +14,30 @@ import exchangeABI from '../references/uniswap-exchange-abi.json'; import erc20ABI from '../references/erc20-abi.json'; import { toHex, web3Provider } from './web3'; +const uniswapPairsEndpoint = axios.create({ + baseURL: + 'https://raw.githubusercontent.com/rainbow-me/asset-overrides/master/uniswap-pairs.json', + headers: { + Accept: 'application/json', + }, + timeout: 20000, // 20 secs +}); + +export const getUniswapPairs = async tokenOverrides => { + try { + const data = await uniswapPairsEndpoint.get(); + const pairs = get(data, 'data') || {}; + const loweredPairs = mapKeys(pairs, (_, key) => toLower(key)); + return mapValues(loweredPairs, (value, key) => ({ + ...value, + ...tokenOverrides[key], + })); + } catch (error) { + console.log('Error getting uniswap pairs', error); + throw error; + } +}; + const convertArgsForEthers = methodArguments => methodArguments.map(arg => typeof arg === 'object' ? ethers.utils.bigNumberify(arg.toFixed()) : arg diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 7372bdc5c87..e3595f8f2ac 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -29,6 +29,7 @@ import { import { uniswapLoadState, uniswapClearState, + uniswapPairsInit, uniswapUpdateState, } from '../redux/uniswap'; import { @@ -72,6 +73,7 @@ export default Component => uniqueTokensRefreshState, uniswapClearState, uniswapLoadState, + uniswapPairsInit, uniswapUpdateState, walletConnectClearState, walletConnectLoadState, @@ -116,6 +118,7 @@ export default Component => try { await ownProps.dataTokenOverridesInit(); ownProps.explorerInit(); + ownProps.uniswapPairsInit(); ownProps.gasPricesInit(); ownProps.web3ListenerInit(); await ownProps.uniqueTokensRefreshState(); diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 1f8cec1b167..298f33e31ce 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -3,6 +3,7 @@ import { filter, get, includes, + keys, map, partition, sortBy, @@ -13,20 +14,21 @@ import { connect } from 'react-redux'; import { compose, withProps } from 'recompact'; import { createSelector } from 'reselect'; import { uniswapUpdateFavorites } from '../redux/uniswap'; -import { uniswapAssetAddresses, uniswapAssetsClean } from '../references'; import withAccountData from './withAccountData'; const allAssetsSelector = state => state.allAssets; const uniswapAssetsSelector = state => state.uniswapAssets; const uniswapFavoritesSelector = state => state.favorites; +const uniswapPairsSelector = state => state.pairs; -const filterUniswapAssetsByAvailability = ({ address }) => - uniswapAssetAddresses.includes(address); +const filterUniswapAssetsByAvailability = uniswapAssetAddresses => ({ + address, +}) => uniswapAssetAddresses.includes(address); -export const includeExchangeAddress = asset => ({ +export const includeExchangeAddress = uniswapPairs => asset => ({ ...asset, exchangeAddress: get( - uniswapAssetsClean, + uniswapPairs, `[${toLower(asset.address)}].exchangeAddress` ), }); @@ -38,9 +40,15 @@ const includeFavorite = asset => ({ favorite: true, }); -const withAssetsAvailableOnUniswap = allAssets => { - const availableAssets = filter(allAssets, filterUniswapAssetsByAvailability); - const assetsAvailableOnUniswap = map(availableAssets, includeExchangeAddress); +const withAssetsAvailableOnUniswap = (allAssets, uniswapPairs) => { + const availableAssets = filter( + allAssets, + filterUniswapAssetsByAvailability(keys(uniswapPairs)) + ); + const assetsAvailableOnUniswap = map( + availableAssets, + includeExchangeAddress(uniswapPairs) + ); return { assetsAvailableOnUniswap }; }; @@ -56,7 +64,7 @@ const withSortedUniswapAssets = (unsortedUniswapAssets, favorites) => { }; const withAssetsAvailableOnUniswapSelector = createSelector( - [allAssetsSelector], + [allAssetsSelector, uniswapPairsSelector], withAssetsAvailableOnUniswap ); @@ -65,8 +73,9 @@ const withSortedUniswapAssetsSelector = createSelector( withSortedUniswapAssets ); -const mapStateToProps = ({ uniswap: { favorites, uniswapAssets } }) => ({ +const mapStateToProps = ({ uniswap: { favorites, pairs, uniswapAssets } }) => ({ favorites, + pairs, uniswapAssets, }); diff --git a/src/redux/explorer.js b/src/redux/explorer.js index cea477d65c4..30f73b00405 100644 --- a/src/redux/explorer.js +++ b/src/redux/explorer.js @@ -1,7 +1,6 @@ -import { isNil, toLower } from 'lodash'; +import { isNil, keys, toLower } from 'lodash'; import { DATA_API_KEY, DATA_ORIGIN } from 'react-native-dotenv'; import io from 'socket.io-client'; -import { uniswapAssetAddresses } from '../references'; import { addressAssetsReceived, assetsReceived, @@ -69,6 +68,7 @@ const assetsSubscription = (assetCodes, currency, action = 'subscribe') => [ const explorerUnsubscribe = () => (dispatch, getState) => { const { addressSocket, assetsSocket } = getState().explorer; const { accountAddress, nativeCurrency } = getState().settings; + const { pairs } = getState().uniswap; if (!isNil(addressSocket)) { addressSocket.emit( ...addressSubscription(accountAddress, nativeCurrency, 'unsubscribe') @@ -77,11 +77,7 @@ const explorerUnsubscribe = () => (dispatch, getState) => { } if (!isNil(assetsSocket)) { assetsSocket.emit( - ...assetsSubscription( - uniswapAssetAddresses, - nativeCurrency, - 'unsubscribe' - ) + ...assetsSubscription(keys(pairs), nativeCurrency, 'unsubscribe') ); assetsSocket.close(); } @@ -92,8 +88,23 @@ export const explorerClearState = () => dispatch => { dispatch({ type: EXPLORER_CLEAR_STATE }); }; +export const resubscribeAssets = (oldAddresses, addresses) => ( + dispatch, + getState +) => { + const { nativeCurrency } = getState().settings; + const { assetsSocket } = getState().explorer; + if (!isNil(assetsSocket)) { + assetsSocket.emit( + ...assetsSubscription(keys(oldAddresses), nativeCurrency, 'unsubscribe') + ); + assetsSocket.emit(...assetsSubscription(addresses, nativeCurrency)); + } +}; + export const explorerInit = () => (dispatch, getState) => { const { accountAddress, nativeCurrency } = getState().settings; + const { pairs } = getState().uniswap; const addressSocket = createSocket('address'); const assetsSocket = createSocket('assets'); dispatch({ @@ -101,9 +112,7 @@ export const explorerInit = () => (dispatch, getState) => { type: EXPLORER_UPDATE_SOCKETS, }); assetsSocket.on(messages.CONNECT, () => { - assetsSocket.emit( - ...assetsSubscription(uniswapAssetAddresses, nativeCurrency) - ); + assetsSocket.emit(...assetsSubscription(keys(pairs), nativeCurrency)); dispatch(listenOnAssetMessages(assetsSocket)); }); addressSocket.on(messages.CONNECT, () => { diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index f7cc073ea0e..b9f43ebc4db 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -7,6 +7,7 @@ import { invertBy, isEmpty, keyBy, + keys, map, mapValues, omit, @@ -29,8 +30,14 @@ import { saveUniswapFavorites, saveUniswapPendingApprovals, } from '../handlers/localstorage/uniswap'; -import { getLiquidityInfo, getReserve } from '../handlers/uniswap'; +import { + getLiquidityInfo, + getReserve, + getUniswapPairs, +} from '../handlers/uniswap'; import { includeExchangeAddress } from '../hoc/withUniswapAssets'; +import { cleanUniswapAssetsFallback } from '../references'; +import { resubscribeAssets } from './explorer'; // -- Constants ------------------------------------------------------------- // const UNISWAP_LOAD_REQUEST = 'uniswap/UNISWAP_LOAD_REQUEST'; @@ -40,6 +47,8 @@ const UNISWAP_LOAD_FAILURE = 'uniswap/UNISWAP_LOAD_FAILURE'; const UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS = 'uniswap/UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS'; +const UNISWAP_UPDATE_PAIRS = 'uniswap/UNISWAP_UPDATE_PAIRS'; + const UNISWAP_UPDATE_REQUEST = 'uniswap/UNISWAP_UPDATE_REQUEST'; const UNISWAP_UPDATE_SUCCESS = 'uniswap/UNISWAP_UPDATE_SUCCESS'; const UNISWAP_UPDATE_FAILURE = 'uniswap/UNISWAP_UPDATE_FAILURE'; @@ -102,6 +111,17 @@ export const uniswapLoadState = () => async (dispatch, getState) => { } }; +export const uniswapPairsInit = () => async (dispatch, getState) => { + try { + const { tokenOverrides } = getState().data; + const { pairs: existingPairs } = getState().uniswap; + const pairs = await getUniswapPairs(tokenOverrides); + dispatch(uniswapUpdatePairs(pairs)); + dispatch(resubscribeAssets(keys(existingPairs), keys(pairs))); + // eslint-disable-next-line no-empty + } catch (error) {} +}; + export const uniswapUpdateTokenReserves = ( inputReserve, outputReserve @@ -227,7 +247,8 @@ export const uniswapUpdateAllowances = tokenAddressAllowances => ( export const uniswapUpdateAssets = assets => (dispatch, getState) => { const { accountAddress, network } = getState().settings; - const uniswapAssetPrices = map(assets, includeExchangeAddress); + const { pairs } = getState().uniswap; + const uniswapAssetPrices = map(assets, includeExchangeAddress(pairs)); const mappedAssets = keyBy(uniswapAssetPrices, lowerAddress); dispatch({ payload: mappedAssets, @@ -236,6 +257,12 @@ export const uniswapUpdateAssets = assets => (dispatch, getState) => { saveUniswapAssets(mappedAssets, accountAddress, network); }; +export const uniswapUpdatePairs = pairs => dispatch => + dispatch({ + payload: pairs, + type: UNISWAP_UPDATE_PAIRS, + }); + export const uniswapUpdateAssetPrice = (address, price) => ( dispatch, getState @@ -314,6 +341,7 @@ export const INITIAL_UNISWAP_STATE = { loadingUniswap: false, outputCurrency: null, outputReserve: null, + pairs: cleanUniswapAssetsFallback, pendingApprovals: {}, uniswapAssets: {}, uniswapLiquidityTokenInfo: {}, @@ -328,6 +356,9 @@ export default (state = INITIAL_UNISWAP_STATE, action) => case UNISWAP_LOAD_LIQUIDITY_TOKEN_INFO_SUCCESS: draft.uniswapLiquidityTokenInfo = action.payload; break; + case UNISWAP_UPDATE_PAIRS: + draft.pairs = action.payload; + break; case UNISWAP_LOAD_SUCCESS: draft.allowances = action.payload.allowances; draft.favorites = action.payload.favorites; diff --git a/src/references/index.js b/src/references/index.js index 1fe9c52ac6b..c72fd596d22 100644 --- a/src/references/index.js +++ b/src/references/index.js @@ -1,4 +1,4 @@ -import { keys, mapKeys, mapValues, toLower } from 'lodash'; +import { mapKeys, mapValues, toLower } from 'lodash'; import tokenOverridesFallback from './token-overrides.json'; import uniswapAssetsFallback from './uniswap-pairs.json'; @@ -7,17 +7,15 @@ export const loweredTokenOverridesFallback = mapKeys( (_, address) => toLower(address) ); -const uniswapAssetsRawLoweredKeys = mapKeys( +const loweredUniswapAssetsFallback = mapKeys( uniswapAssetsFallback, (value, key) => toLower(key) ); -export const uniswapAssetsClean = mapValues( - uniswapAssetsRawLoweredKeys, +export const cleanUniswapAssetsFallback = mapValues( + loweredUniswapAssetsFallback, (value, key) => ({ ...value, ...loweredTokenOverridesFallback[key], }) ); - -export const uniswapAssetAddresses = keys(uniswapAssetsRawLoweredKeys); From b27102f3eaa07af5d26d08b610e03c8c23bd5fa6 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 11 Dec 2019 16:55:29 -0500 Subject: [PATCH 599/636] disable token overrides --- src/hoc/withDataInit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index e3595f8f2ac..ce25ad55e31 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -116,7 +116,7 @@ export default Component => }, initializeAccountData: ownProps => async () => { try { - await ownProps.dataTokenOverridesInit(); + // await ownProps.dataTokenOverridesInit(); ownProps.explorerInit(); ownProps.uniswapPairsInit(); ownProps.gasPricesInit(); From 8c2d8ab01474d977b9fb4a831e077188b8f3b6f8 Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Wed, 11 Dec 2019 19:24:11 -0500 Subject: [PATCH 600/636] Improve import confirmation alert copy --- src/screens/ImportSeedPhraseSheet.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index 793497c8519..c87d2dd5c48 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -51,8 +51,7 @@ const ConfirmImportAlert = onSuccess => buttons: [ { onPress: onSuccess, - style: 'destructive', - text: 'Delete and Import', + text: 'Import Wallet', }, { style: 'cancel', @@ -60,8 +59,8 @@ const ConfirmImportAlert = onSuccess => }, ], message: - 'Importing this private key will overwrite your existing wallet. Before continuing, please make sure you’ve transferred its contents or backed up its private key.', - title: 'Are you sure you want to import?', + 'This will replace your existing wallet.\n\nBefore continuing, please make sure you’ve backed up or emptied it!', + title: '🚨 Careful 🚨', }); const ImportButton = ({ disabled, onPress, seedPhrase }) => ( From 4d1737f7a63ef75484031b1a654491e29286eb49 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 20:45:37 -0500 Subject: [PATCH 601/636] Integrate Sentry --- android/app/build.gradle | 1 + ios/Podfile.lock | 62 +++-- ios/Rainbow.xcodeproj/project.pbxproj | 6 +- package.json | 1 + src/App.js | 10 +- yarn.lock | 344 +++++++++++++------------- 6 files changed, 226 insertions(+), 198 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 74c2077ff23..7a996d8df86 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -77,6 +77,7 @@ project.ext.react = [ ] apply from: "../../node_modules/react-native/react.gradle" +apply from: "../../node_modules/@sentry/react-native/sentry.gradle" apply from: "../../node_modules/react-native-code-push/android/codepush.gradle" /** diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e6c2fb5e7a0..cb1c2f58471 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -334,9 +334,7 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): - - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -414,6 +412,9 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React + - RNSentry (1.2.0): + - React + - Sentry (~> 4.4.0) - RNStoreReview (0.1.5): - React - RNSVG (9.13.3): @@ -424,6 +425,9 @@ PODS: - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) + - Sentry (4.4.3): + - Sentry/Core (= 4.4.3) + - Sentry/Core (4.4.3) - SRSRadialGradient (1.0.0): - React - SSZipArchive (2.2.2) @@ -495,6 +499,7 @@ DEPENDENCIES: - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) + - "RNSentry (from `../node_modules/@sentry/react-native`)" - RNStoreReview (from `../node_modules/react-native-store-review/ios`) - RNSVG (from `../node_modules/react-native-svg`) - SRSRadialGradient (from `../node_modules/react-native-radial-gradient/ios`) @@ -529,6 +534,7 @@ SPEC REPOS: - Protobuf - SDWebImage - SDWebImageWebPCoder + - Sentry - SSZipArchive EXTERNAL SOURCES: @@ -640,6 +646,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" + RNSentry: + :path: "../node_modules/@sentry/react-native" RNStoreReview: :path: "../node_modules/react-native-store-review/ios" RNSVG: @@ -664,8 +672,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: d404836aeeaa2d8acfdbcdebbe70f77a2e4fe4e4 - FBReactNativeSpec: 4dbf83fb73710a5a35d0c894c5e3ed0dcbac2450 + FBLazyVector: 819f6346db17ab2e478505a141eb03b81ec987e5 + FBReactNativeSpec: 8783576777bb2f564f3d632232d17b5ebe718508 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -684,16 +692,16 @@ SPEC CHECKSUMS: JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd - Protobuf: a4dc852ad69c027ca2166ed287b856697814375b - RCTRequired: 803acce5991522ab267d01eaa10a87da037233f3 - RCTTypeSafety: 3a8265cde2a81a2796a443878169993faf60aa76 - React: f6ecd230cd4efecf6af176921ab4de3d11a07964 - React-Core: 05930428f3aead2f87e24e0d874840841e913868 - React-CoreModules: 913abd1bd37142fe3a48bfeebf2d31e995d1b166 - React-cxxreact: efaca513c76a265ce5779d3ea1defa47f8bd65d6 - React-jsi: 901c02f197134dc58f26434420d9c4e103e48edf - React-jsiexecutor: 44f2200c6914c98c10cb078bc5a3fba2d13008bb - React-jsinspector: e69cce41a49d95767abb96b0abc3b976bfe71b77 + Protobuf: 20d79da7f20b5928b80043b05080b816e802659e + RCTRequired: 050b52195fd4a3734b14622c3060368137c2cce3 + RCTTypeSafety: a50b5ac437c7feba50396f2b85431499fe22c846 + React: 5984b8456f8e83b2609935f1e188714ae9da01d3 + React-Core: 0d789180fcef897535596fee945f3b4caf9ecea9 + React-CoreModules: 3a21a44a5c80a6372cf40e0ced849b597c377b8e + React-cxxreact: 4a154094e80071227154767175d77512a6d184f2 + React-jsi: 9e4b30831a63b7b9804e4403a792853790e524e8 + React-jsiexecutor: a4ab14e11578382aa0df9c95ef95d8d33da0b605 + React-jsinspector: 619bae388f66f13e8a4b094898de2a6c2417ce39 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 1df7f9a047591bbc2c9a7ec80bd6412d3c19579f react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -704,16 +712,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 6ba1728ad985692e5fb3f71b5f43f026ece558d3 - React-RCTAnimation: d87bd4d3d816cdb8085141c60721326ed0e6c972 - React-RCTBlob: 8000ae9818e72a6ffda06f6adcfec59e30d354e4 - React-RCTImage: 00a1e7e7e87cd1d416b9ea46fc21633ddfd42ae0 - React-RCTLinking: f2301e75e9610aa35278a522f6f8a9dfc5835505 - React-RCTNetwork: b93c472f746642c6d6807bcf0a2e4691ad41ab09 - React-RCTSettings: 51990ae52e8da0aa1b9f5cce02f6976b0ad1af17 - React-RCTText: feb3453236dcdd195878d576988df9c8fd500a19 - React-RCTVibration: f1224b7b0eefef4b4e3f503889efd72791c52db5 - ReactCommon: edc5a0b6f4b94e8dccd14145beb8940321be5698 + React-RCTActionSheet: 3b8143662e17e117a8ab7794be08c381d894f582 + React-RCTAnimation: eb7889dd47c9a39791572cd2b1519ac2aa03d519 + React-RCTBlob: edfb49d23e4c5498a2a371df2eb504fc9fbc588a + React-RCTImage: 187f4c136ee36b0700b5b6d9ffdd9c03e4deff3b + React-RCTLinking: 55868cf6130190ecceb0365af62889172385b9c6 + React-RCTNetwork: ac5092cd1f8dde03d890aa445b39030a570010e5 + React-RCTSettings: aafce4fe24e5dbca7a08e813a128c986d09f6b2a + React-RCTText: 299f71e927c3f7f6fe0636c5ff12876851e4c2cf + React-RCTVibration: 7239997201b76f7fa93226f9a74c6db50f6edd30 + ReactCommon: 08828c927c18463da3b25be7c1083cc6d2f2c150 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -724,7 +732,7 @@ SPEC CHECKSUMS: RNFBApp: 5b215aacc09105a1761de31b9a0eb2abcce06253 RNFBCrashlytics: 0469cb96b00904e0c9604b9636d8eeab31115b08 RNFBMessaging: be0b936394416ec5503add603f2c0a641c353063 - RNGestureHandler: 7add966bb5d90ee8cf38d4341f87814474357972 + RNGestureHandler: 946a7691e41df61e2c4b1884deab41a4cdc3afff RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e @@ -732,16 +740,18 @@ SPEC CHECKSUMS: RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 8b675a650fc67c87f63d4345a1b2d4a699c25e4f RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 + RNSentry: b63ba6a29ee142b5c3221896be8ff6cda587e03f RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 + Sentry: 14bdd673870e8cf64932b149fad5bbbf39a9b390 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 9ead55da0909bc1214fd81897f52280e84b83e1d + Yoga: e8b2e61404f15aa7fdd630d65755530125c1ada6 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 0ad54c7cfc0..dacf3e6a6a5 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ C37D7F7EA236460085DB5BFA /* SF-Pro-Text-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1736F851327A41C3815212E7 /* SF-Pro-Text-BoldItalic.otf */; }; C5D098E8B85D40048FE4946A /* Graphik-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A9AF25703474604964D6EC1 /* Graphik-Light.otf */; }; C66451ECC2944B439E123CF2 /* SF-Pro-Display-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = BE239BA93F6B4EDC867B1A41 /* SF-Pro-Display-Black.otf */; }; + C72F456C99A646399192517D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 98AED33BAB4247CEBEF8464D /* libz.tbd */; }; CAD3BF43528D47159190E17B /* SF-Pro-Display-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 3459F05BF10649C4A787D900 /* SF-Pro-Display-MediumItalic.otf */; }; CB988C526B0C48FC9750A038 /* SF-Pro-Display-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 84DB92DCDF5D4374B26FFCC6 /* SF-Pro-Display-BoldItalic.otf */; }; DBBDEB86E54044EE8712C882 /* Graphik-BlackItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEC826911B5641B8AF788BB3 /* Graphik-BlackItalic.otf */; }; @@ -143,6 +144,7 @@ 93D62D49D9CA46F292BD9869 /* Graphik-Extralight.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Graphik-Extralight.otf"; path = "../src/assets/fonts/Graphik-Extralight.otf"; sourceTree = ""; }; 944CF612F0304DF281E33B66 /* SF-Pro-Text-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Text-Regular.otf"; path = "../src/assets/fonts/SF-Pro-Text-Regular.otf"; sourceTree = ""; }; 95F2888C850F40C8A26E083B /* SFMono-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SFMono-Regular.otf"; path = "../src/assets/fonts/SFMono-Regular.otf"; sourceTree = ""; }; + 98AED33BAB4247CEBEF8464D /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 9DEADFA4826D4D0BAA950D21 /* libRNFIRMessaging.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFIRMessaging.a; sourceTree = ""; }; 9DF45B9EB38D4E8FA18A04C6 /* SF-Pro-Display-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "SF-Pro-Display-Light.otf"; path = "../src/assets/fonts/SF-Pro-Display-Light.otf"; sourceTree = ""; }; A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; @@ -182,6 +184,7 @@ files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, 0E56AA9A8843EB50FA4BDD4F /* libPods-Rainbow.a in Frameworks */, + C72F456C99A646399192517D /* libz.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -262,6 +265,7 @@ 24979E3620F84003007EB0DA /* Protobuf.framework */, 2D16E6891FA4F8E400B85C8A /* libReact.a */, 6C1814FA03B309E79858CD16 /* libPods-Rainbow.a */, + 98AED33BAB4247CEBEF8464D /* libz.tbd */, ); name = Frameworks; sourceTree = ""; @@ -518,7 +522,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_ARGS=--max-old-space-size=2048\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "export SENTRY_PROPERTIES=sentry.properties\nexport NODE_ARGS=--max-old-space-size=2048\n../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh\n"; }; 3CF823D3218F310D0024B77B /* ShellScript */ = { isa = PBXShellScriptBuildPhase; diff --git a/package.json b/package.json index e2b8bbc3128..492510ffe81 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@react-native-firebase/crashlytics": "^6.2.0", "@react-native-firebase/messaging": "^6.2.0", "@segment/analytics-react-native": "^1.0.1", + "@sentry/react-native": "^1.2.0", "@staltz/react-native-tcp": "^3.3.1", "@tradle/react-native-http": "^2.0.1", "@uniswap/sdk": "^1.0.0-beta.4", diff --git a/src/App.js b/src/App.js index e86dac93a8a..65772dc8186 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,7 @@ // eslint-disable-next-line import/default import PushNotificationIOS from '@react-native-community/push-notification-ios'; import analytics from '@segment/analytics-react-native'; +import { init as initSentry } from '@sentry/react-native'; import { get, last } from 'lodash'; import PropTypes from 'prop-types'; import nanoid from 'nanoid/non-secure'; @@ -8,7 +9,10 @@ import React, { Component } from 'react'; import { AppRegistry, AppState, Linking } from 'react-native'; // eslint-disable-next-line import/default import CodePush from 'react-native-code-push'; -import { REACT_APP_SEGMENT_API_WRITE_KEY } from 'react-native-dotenv'; +import { + REACT_APP_SEGMENT_API_WRITE_KEY, + SENTRY_ENDPOINT, +} from 'react-native-dotenv'; // eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; // eslint-disable-next-line import/no-unresolved @@ -26,6 +30,10 @@ import { requestsForTopic } from './redux/requests'; import Routes from './screens/Routes'; import { parseQueryParams } from './utils'; +initSentry({ + dsn: SENTRY_ENDPOINT, +}); + if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; } diff --git a/yarn.lock b/yarn.lock index 5f8bf08d9f7..4bb8485a954 100644 --- a/yarn.lock +++ b/yarn.lock @@ -997,19 +997,6 @@ dependencies: serve-static "^1.13.1" -"@react-native-community/cli-platform-android@^2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e" - integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag== - dependencies: - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - execa "^1.0.0" - jetifier "^1.6.2" - logkitty "^0.6.0" - slash "^3.0.0" - xmldoc "^1.1.2" - "@react-native-community/cli-platform-android@^3.0.0-alpha.1": version "3.0.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz#e652abce79a7c1e3a8280228123e99df2c4b97b6" @@ -1023,15 +1010,6 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^2.9.0": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.10.0.tgz#ee494d2f9a8f8727bd5eb3c446f22ebb5429b624" - integrity sha512-z5BQKyT/bgTSdHhvsFNf++6VP50vtOOaITnNKvw4954wURjv5JOQh1De3BngyaDOoGfV1mXkCxutqAXqSeuIjw== - dependencies: - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - xcode "^2.0.0" - "@react-native-community/cli-platform-ios@^3.0.0-alpha.1": version "3.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz#3a48a449c0c33af3b0b3d19d3256de99388fe15f" @@ -1057,46 +1035,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652" integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg== -"@react-native-community/cli@2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc" - integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-platform-android" "^2.9.0" - "@react-native-community/cli-platform-ios" "^2.9.0" - "@react-native-community/cli-tools" "^2.8.3" - chalk "^2.4.2" - commander "^2.19.0" - compression "^1.7.1" - connect "^3.6.5" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - envinfo "^7.1.0" - errorhandler "^1.5.0" - execa "^1.0.0" - fs-extra "^7.0.1" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.54.1" - metro-config "^0.54.1" - metro-core "^0.54.1" - metro-react-native-babel-transformer "^0.54.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-notifier "^5.2.1" - open "^6.2.0" - ora "^3.4.0" - plist "^3.0.0" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" - ws "^1.1.0" - -"@react-native-community/cli@^3.0.0-alpha.1": +"@react-native-community/cli@3.0.4", "@react-native-community/cli@^3.0.0-alpha.1": version "3.0.4" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.4.tgz#a9dba1bc77855a6e45fccaabb017360645d936bb" integrity sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA== @@ -1207,6 +1146,107 @@ resolved "https://registry.yarnpkg.com/@segment/analytics-react-native/-/analytics-react-native-1.1.0.tgz#209c28a7b6f60c80bdce8e7c66bfb26aaeef9ed6" integrity sha512-9a4/uvsP+MebvoLDpUAjeeflgDVQjYaPEYp22JpAZiMlr0Tmsrrbwud/FE/bHeMX6HeLfgeCghhK4GvfeZsc9g== +"@sentry/browser@^5.10.0": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.10.2.tgz#0bbb05505c58ea998c833cffec3f922fe4b4fa58" + integrity sha512-r3eyBu2ln7odvWtXARCZPzpuGrKsD6U9F3gKTu4xdFkA0swSLUvS7AC2FUksj/1BE23y+eB/zzPT+RYJ58tidA== + dependencies: + "@sentry/core" "5.10.2" + "@sentry/types" "5.10.0" + "@sentry/utils" "5.10.2" + tslib "^1.9.3" + +"@sentry/cli@^1.48.0": + version "1.49.0" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.49.0.tgz#174152978acbe6023986a8fb0b247cf58b4653d8" + integrity sha512-Augz7c42Cxz/xWQ/NOVjUGePKVA370quvskWbCICMUwxcTvKnCLI+7KDdzEoCexj4MSuxFfBzLnrrn4w2+c9TQ== + dependencies: + fs-copy-file-sync "^1.1.1" + https-proxy-agent "^3.0.0" + mkdirp "^0.5.1" + node-fetch "^2.1.2" + progress "2.0.0" + proxy-from-env "^1.0.0" + +"@sentry/core@5.10.2", "@sentry/core@^5.10.0": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.10.2.tgz#1cb64489e6f8363c3249415b49d3f1289814825f" + integrity sha512-sKVeFH3v8K8xw2vM5MKMnnyAAwih+JSE3pbNL0CcCCA+/SwX+3jeAo2BhgXev2SAR/TjWW+wmeC9TdIW7KyYbg== + dependencies: + "@sentry/hub" "5.10.2" + "@sentry/minimal" "5.10.2" + "@sentry/types" "5.10.0" + "@sentry/utils" "5.10.2" + tslib "^1.9.3" + +"@sentry/hub@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.10.2.tgz#25d9f36b8f7c5cb65cf486737fa61dc9bf69b7e3" + integrity sha512-hSlZIiu3hcR/I5yEhlpN9C0nip+U7hiRzRzUQaBiHO4YG4TC58NqnOPR89D/ekiuHIXzFpjW9OQmqtAMRoSUYA== + dependencies: + "@sentry/types" "5.10.0" + "@sentry/utils" "5.10.2" + tslib "^1.9.3" + +"@sentry/integrations@^5.10.0": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-5.10.2.tgz#44f5c55d1619d816c0f20208a3727bb07abb98c8" + integrity sha512-yvIJ6aXpzWlwD1WGTxvaeCm7JmNs4flWXKLlPWm2CEwgWBfjyaWjW7PqlA0jUOnLGCeYzgFD3AdUPlpgCsFXXA== + dependencies: + "@sentry/types" "5.10.0" + "@sentry/utils" "5.10.2" + tslib "^1.9.3" + +"@sentry/minimal@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.10.2.tgz#267c2f3aa6877a0fe7a86971942e83f3ee616580" + integrity sha512-GalixiM9sckYfompH5HHTp9XT2BcjawBkcl1DMEKUBEi37+kUq0bivOBmnN1G/I4/wWOUdnAI/kagDWaWpbZPg== + dependencies: + "@sentry/hub" "5.10.2" + "@sentry/types" "5.10.0" + tslib "^1.9.3" + +"@sentry/react-native@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.0.tgz#244ec5f07a4eb07d3d56e7b50fe00f479a733eb5" + integrity sha512-GPY+1dBLgx5I/eOuj+dyMO8DGSoPTatB13WpYbFouGNbx3Ni4SD6EwpU+VdJtqtqVQ0OUVMNm+w/lX4+ggmU5g== + dependencies: + "@sentry/browser" "^5.10.0" + "@sentry/core" "^5.10.0" + "@sentry/integrations" "^5.10.0" + "@sentry/types" "^5.10.0" + "@sentry/utils" "^5.10.0" + "@sentry/wizard" "^1.0.2" + +"@sentry/types@5.10.0", "@sentry/types@^5.10.0": + version "5.10.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.10.0.tgz#4f0ba31b6e4d5371112c38279f11f66c73b43746" + integrity sha512-TW20GzkCWsP6uAxR2JIpIkiitCKyIOfkyDsKBeLqYj4SaZjfvBPnzgNCcYR0L0UsP1/Es6oHooZfIGSkp6GGxQ== + +"@sentry/utils@5.10.2", "@sentry/utils@^5.10.0": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.10.2.tgz#261f575079d30aaf604e59f5f4de0aa21db22252" + integrity sha512-UcbbaFpYrGSV448lQ16Cr+W/MPuKUflQQUdrMCt5vgaf5+M7kpozlcji4GGGZUCXIA7oRP93ABoXj55s1OM9zw== + dependencies: + "@sentry/types" "5.10.0" + tslib "^1.9.3" + +"@sentry/wizard@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@sentry/wizard/-/wizard-1.0.2.tgz#346d1ecbeef7b765120ec8627053443456660f0d" + integrity sha512-/mS9SWcgc8uqrOhiwyGqusGnWXf4hvIiYpUGJGw4vxL8gZ3k+UMSKaEw46p+ND1X8y2RRgFJh7h7q2dtXa8QvQ== + dependencies: + "@sentry/cli" "^1.48.0" + chalk "^2.4.1" + glob "^7.1.3" + inquirer "^6.2.0" + lodash "^4.17.15" + opn "^5.4.0" + r2 "^2.0.1" + read-env "^1.3.0" + xcode "2.0.0" + yargs "^12.0.2" + "@staltz/react-native-tcp@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@staltz/react-native-tcp/-/react-native-tcp-3.3.1.tgz#c5be709adafd802ec12e4542b0aa350efa86b2dd" @@ -1727,7 +1767,7 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= -ansi-escapes@^3.0.0: +ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== @@ -2639,6 +2679,11 @@ camelcase-keys@^4.0.0: map-obj "^2.0.0" quick-lru "^1.0.0" +camelcase@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -2671,7 +2716,7 @@ capture-stack-trace@^1.0.0: resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== -caseless@~0.12.0: +caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= @@ -4754,6 +4799,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-copy-file-sync@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz#11bf32c096c10d126e5f6b36d06eece776062918" + integrity sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ== + fs-extra@^0.22.1: version "0.22.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.22.1.tgz#5fd6f8049dc976ca19eb2355d658173cabcce056" @@ -5542,6 +5592,25 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" +inquirer@^6.2.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + inquirer@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" @@ -5862,7 +5931,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -6782,7 +6851,7 @@ lodash.unescape@4.0.1: resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -7047,13 +7116,6 @@ metro-babel-register@0.56.3: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-transformer@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc" - integrity sha512-2aiAnuYBdcLV1VINb8ENAA4keIaJIepHgR9+iRvIde+9GSjKnexqx4nNmJN392285gRDp1fVZ7uY0uQawK/A5g== - dependencies: - "@babel/core" "^7.0.0" - metro-babel-transformer@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz#6559c3a8565238a704a181353cef59fdb974e6db" @@ -7062,23 +7124,6 @@ metro-babel-transformer@0.56.3: "@babel/core" "^7.0.0" metro-source-map "0.56.3" -metro-babel7-plugin-react-transform@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996" - integrity sha512-jWm5myuMoZAOhoPsa8ItfDxdTcOzKhTTzzhFlbZnRamE7i9qybeMdrZt8KHQpF7i2p/mKzE9Yhf4ouOz5K/jHg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - -metro-cache@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1" - integrity sha512-RxCFoNcANHXZYi4MIQNnqh68gUnC3bMpzCFJY5pBoqqdrkkn8ibYglBweA0/DW7hx1OZTJWelwS1Dp8xxmE2CA== - dependencies: - jest-serializer "^24.4.0" - metro-core "0.54.1" - mkdirp "^0.5.1" - rimraf "^2.5.4" - metro-cache@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.3.tgz#1b0759bc45291cc3ffc77736c09dcfbd322edb8b" @@ -7222,23 +7267,6 @@ metro-react-native-babel-transformer@0.56.3, metro-react-native-babel-transforme metro-react-native-babel-preset "0.56.3" metro-source-map "0.56.3" -metro-react-native-babel-transformer@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17" - integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "0.54.1" - metro-react-native-babel-preset "0.54.1" - -metro-resolver@0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087" - integrity sha512-Byv1LIawYAASy9CFRwzrncYnqaFGLe8vpw178EtzStqP05Hu6hXSqkNTrfoXa+3V9bPFGCrVzFx2NY3gFp2btg== - dependencies: - absolute-path "^0.0.0" - metro-resolver@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.3.tgz#f18978b919a5ecc67028732609a564880715ef75" @@ -7270,65 +7298,6 @@ metro-symbolicate@0.56.3: through2 "^2.0.1" vlq "^1.0.0" -metro@0.54.1, metro@^0.54.1: - version "0.54.1" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.54.1.tgz#a629be00abee5a450a25a8f71c24745f70cc9b44" - integrity sha512-6ODPT4mEo4FCpbExRNnQAcZmf1VeNvYOTMj2Na03FjGqhNODHhI2U/wF/Ul5gqTyJ2dVdkXeyvKW3gl/LrnJRg== - dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.1.2" - buffer-crc32 "^0.2.13" - chalk "^2.4.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" - invariant "^2.2.4" - jest-haste-map "^24.7.1" - jest-worker "^24.6.0" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-babel-register "0.54.1" - metro-babel-transformer "0.54.1" - metro-cache "0.54.1" - metro-config "0.54.1" - metro-core "0.54.1" - metro-inspector-proxy "0.54.1" - metro-minify-uglify "0.54.1" - metro-react-native-babel-preset "0.54.1" - metro-resolver "0.54.1" - metro-source-map "0.54.1" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - react-transform-hmr "^1.0.4" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" - source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.5" - xpipe "^1.0.5" - yargs "^9.0.0" - metro@0.56.3, metro@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.3.tgz#3a38706bf6b1200421e871a4c53ddc2f359f65a9" @@ -7743,7 +7712,7 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.2.0, node-fetch@^2.5.0: +node-fetch@^2.0.0-alpha.8, node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.5.0: version "2.6.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== @@ -8119,6 +8088,13 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" +opn@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -8803,6 +8779,11 @@ process@^0.11.10, process@^0.11.9, process@~0.11.0: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + integrity sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8= + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -8979,6 +8960,15 @@ quick-lru@^1.0.0: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= +r2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/r2/-/r2-2.0.1.tgz#94cd802ecfce9a622549c8182032d8e4a2b2e612" + integrity sha512-EEmxoxYCe3LHzAUhRIRxdCKERpeRNmlLj6KLUSORqnK6dWl/K5ShmDGZqM2lRZQeqJgF+wyqk0s1M7SWUveNOQ== + dependencies: + caseless "^0.12.0" + node-fetch "^2.0.0-alpha.8" + typedarray-to-buffer "^3.1.2" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -9501,6 +9491,13 @@ react@16.11.0: object-assign "^4.1.1" prop-types "^15.6.2" +read-env@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/read-env/-/read-env-1.3.0.tgz#e26e1e446992b3216e9a3c6f6ac51064fe91fdff" + integrity sha512-DbCgZ8oHwZreK/E2E27RGk3EUPapMhYGSGIt02k9sX6R3tCFc4u4tkltKvkCvzEQ3SOLUaiYHAnGb+TdsnPp0A== + dependencies: + camelcase "5.0.0" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -11370,7 +11367,7 @@ ts-object-utils@0.0.5: resolved "https://registry.yarnpkg.com/ts-object-utils/-/ts-object-utils-0.0.5.tgz#95361cdecd7e52167cfc5e634c76345e90a26077" integrity sha1-lTYc3s1+UhZ8/F5jTHY0XpCiYHc= -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== @@ -11431,6 +11428,13 @@ type@^2.0.0: resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== +typedarray-to-buffer@^3.1.2: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -12074,7 +12078,7 @@ xcode@1.0.0: simple-plist "^0.2.1" uuid "3.0.1" -xcode@^2.0.0: +xcode@2.0.0, xcode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.0.0.tgz#134f1f94c26fbfe8a9aaa9724bfb2772419da1a2" integrity sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw== @@ -12240,7 +12244,7 @@ yargs@13.3.0, yargs@^13.0.0, yargs@^13.2.4, yargs@^13.3.0: y18n "^4.0.0" yargs-parser "^13.1.1" -yargs@^12.0.5: +yargs@^12.0.2, yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== From 2fa503f9a7fdd6e1a85fab9af9035e431e2c2f7b Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 18:23:58 -0500 Subject: [PATCH 602/636] Update Fastlane to upload dsyms to Sentry --- ios/Gemfile | 3 + ios/Gemfile.lock | 161 ++++++++++++++++++++++++++ ios/Rainbow.xcodeproj/project.pbxproj | 1 + ios/fastlane/Fastfile | 5 +- ios/fastlane/Pluginfile | 5 + 5 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 ios/Gemfile.lock create mode 100644 ios/fastlane/Pluginfile diff --git a/ios/Gemfile b/ios/Gemfile index 7a118b49be7..cdd3a6b3491 100644 --- a/ios/Gemfile +++ b/ios/Gemfile @@ -1,3 +1,6 @@ source "https://rubygems.org" gem "fastlane" + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/ios/Gemfile.lock b/ios/Gemfile.lock new file mode 100644 index 00000000000..e65bcd9e17a --- /dev/null +++ b/ios/Gemfile.lock @@ -0,0 +1,161 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.2) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + atomos (0.1.3) + babosa (1.0.3) + claide (1.0.3) + colored (1.2) + colored2 (3.1.2) + commander-fastlane (4.4.6) + highline (~> 1.7.2) + declarative (0.0.10) + declarative-option (0.1.0) + digest-crc (0.4.1) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.7.5) + emoji_regex (1.0.1) + excon (0.70.0) + faraday (0.17.1) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + faraday_middleware (0.13.1) + faraday (>= 0.7.4, < 1.0) + fastimage (2.1.7) + fastlane (2.137.0) + CFPropertyList (>= 2.3, < 4.0.0) + addressable (>= 2.3, < 3.0.0) + babosa (>= 1.0.2, < 2.0.0) + bundler (>= 1.12.0, < 3.0.0) + colored + commander-fastlane (>= 4.4.6, < 5.0.0) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 2.0) + excon (>= 0.45.0, < 1.0.0) + faraday (~> 0.17) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 0.13.1) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-api-client (>= 0.21.2, < 0.24.0) + google-cloud-storage (>= 1.15.0, < 2.0.0) + highline (>= 1.7.2, < 2.0.0) + json (< 3.0.0) + jwt (~> 2.1.0) + mini_magick (>= 4.9.4, < 5.0.0) + multi_xml (~> 0.5) + multipart-post (~> 2.0.0) + plist (>= 3.1.0, < 4.0.0) + public_suffix (~> 2.0.0) + rubyzip (>= 1.3.0, < 2.0.0) + security (= 0.1.3) + simctl (~> 1.6.3) + slack-notifier (>= 2.0.0, < 3.0.0) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.8.1, < 2.0.0) + xcpretty (~> 0.3.0) + xcpretty-travis-formatter (>= 0.0.3) + fastlane-plugin-sentry (1.6.0) + gh_inspector (1.1.3) + google-api-client (0.23.9) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.5, < 0.7.0) + httpclient (>= 2.8.1, < 3.0) + mime-types (~> 3.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.0) + signet (~> 0.9) + google-cloud-core (1.3.2) + google-cloud-env (~> 1.0) + google-cloud-env (1.2.1) + faraday (~> 0.11) + google-cloud-storage (1.16.0) + digest-crc (~> 0.4) + google-api-client (~> 0.23) + google-cloud-core (~> 1.2) + googleauth (>= 0.6.2, < 0.10.0) + googleauth (0.6.7) + faraday (~> 0.12) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (~> 0.7) + highline (1.7.10) + http-cookie (1.0.3) + domain_name (~> 0.5) + httpclient (2.8.3) + json (2.3.0) + jwt (2.1.0) + memoist (0.16.2) + mime-types (3.3) + mime-types-data (~> 3.2015) + mime-types-data (3.2019.1009) + mini_magick (4.9.5) + multi_json (1.14.1) + multi_xml (0.6.0) + multipart-post (2.0.0) + nanaimo (0.2.6) + naturally (2.2.0) + os (1.0.1) + plist (3.5.0) + public_suffix (2.0.5) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rouge (2.0.7) + rubyzip (1.3.0) + security (0.1.3) + signet (0.11.0) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simctl (1.6.6) + CFPropertyList + naturally + slack-notifier (2.3.2) + terminal-notifier (2.0.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + tty-cursor (0.7.0) + tty-screen (0.7.0) + tty-spinner (0.9.2) + tty-cursor (~> 0.7) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.6) + unicode-display_width (1.6.0) + word_wrap (1.0.0) + xcodeproj (1.13.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.2.6) + xcpretty (0.3.0) + rouge (~> 2.0.7) + xcpretty-travis-formatter (1.0.0) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + ruby + +DEPENDENCIES + fastlane + fastlane-plugin-sentry + +BUNDLED WITH + 1.16.2 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index dacf3e6a6a5..7698b0da717 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -617,6 +617,7 @@ CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = YES; CURRENT_PROJECT_VERSION = 4; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = ""; diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index 9044d1f2819..b502f9b8417 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -17,6 +17,7 @@ platform :ios do lane :refresh_dsyms do download_dsyms(version: "latest") upload_symbols_to_crashlytics + sentry_upload_dsym clean_build_artifacts end @@ -44,9 +45,7 @@ platform :ios do pilot( app_identifier: "me.rainbow" ) - download_dsyms - upload_symbols_to_crashlytics - clean_build_artifacts + refresh_dsyms end desc "Submit a new Internal build to Apple TestFlight" diff --git a/ios/fastlane/Pluginfile b/ios/fastlane/Pluginfile new file mode 100644 index 00000000000..a152560f423 --- /dev/null +++ b/ios/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-sentry' From aa1518e5f9fcae93bf1392ceeebc6919694eae97 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 19:40:59 -0500 Subject: [PATCH 603/636] Add preliminary exception captures for Sentry --- config/test/jest-setup.js | 4 ++++ src/hoc/withDataInit.js | 4 ++++ src/model/wallet.js | 12 ++++++++++++ src/redux/gas.js | 2 ++ src/redux/uniqueTokens.js | 2 ++ 5 files changed, 24 insertions(+) diff --git a/config/test/jest-setup.js b/config/test/jest-setup.js index 8f7c8040669..d7be8046b9a 100644 --- a/config/test/jest-setup.js +++ b/config/test/jest-setup.js @@ -5,6 +5,10 @@ jest.mock('@segment/analytics-react-native', () => ({ setup: () => null, })); +jest.mock('@sentry/react-native', () => ({ + captureException: () => null, +})); + jest.autoMockOff(); jest.mock('react-native-keychain', () => ({ getGenericPassword: jest.fn(), diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index ce25ad55e31..13216abcbf4 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -1,3 +1,4 @@ +import { captureException } from '@sentry/react-native'; import delay from 'delay'; import { isNil } from 'lodash'; import { Alert } from 'react-native'; @@ -125,6 +126,7 @@ export default Component => } catch (error) { // TODO error state console.log('Error initializing account data: ', error); + captureException(error); } }, loadAccountData: ownProps => async () => { @@ -150,6 +152,7 @@ export default Component => ]); } catch (error) { console.log('Error refreshing data', error); + captureException(error); throw error; } }, @@ -194,6 +197,7 @@ export default Component => } catch (error) { // TODO specify error states more granular ownProps.onHideSplashScreen(); + captureException(error); Alert.alert( 'Import failed due to an invalid private key. Please try again.' ); diff --git a/src/model/wallet.js b/src/model/wallet.js index f10220b1b44..156122fa95e 100644 --- a/src/model/wallet.js +++ b/src/model/wallet.js @@ -1,3 +1,4 @@ +import { captureException } from '@sentry/react-native'; import { ethers } from 'ethers'; import lang from 'i18n-js'; import { get, isEmpty, isNil } from 'lodash'; @@ -80,10 +81,12 @@ export const sendTransaction = async ({ transaction }) => { return result.hash; } catch (error) { Alert.alert(lang.t('wallet.transaction.alert.failed_transaction')); + captureException(error); return null; } } catch (error) { Alert.alert(lang.t('wallet.transaction.alert.authentication')); + captureException(error); return null; } }; @@ -96,10 +99,12 @@ export const signTransaction = async ({ transaction }) => { return await wallet.sign(transaction); } catch (error) { Alert.alert(lang.t('wallet.transaction.alert.failed_transaction')); + captureException(error); return null; } } catch (error) { Alert.alert(lang.t('wallet.transaction.alert.authentication')); + captureException(error); return null; } }; @@ -117,10 +122,12 @@ export const signMessage = async ( ); return await ethers.utils.joinSignature(sigParams); } catch (error) { + captureException(error); return null; } } catch (error) { Alert.alert(lang.t('wallet.transaction.alert.authentication')); + captureException(error); return null; } }; @@ -136,10 +143,12 @@ export const signPersonalMessage = async ( isHexString(message) ? ethers.utils.arrayify(message) : message ); } catch (error) { + captureException(error); return null; } } catch (error) { Alert.alert(lang.t('wallet.transaction.alert.authentication')); + captureException(error); return null; } }; @@ -157,6 +166,7 @@ export const loadAddress = async () => { try { return await keychain.loadString(addressKey); } catch (error) { + captureException(error); return null; } }; @@ -183,6 +193,7 @@ const createWallet = async seed => { } return null; } catch (error) { + captureException(error); return null; } }; @@ -220,6 +231,7 @@ const loadPrivateKey = async ( }); return privateKey; } catch (error) { + captureException(error); return null; } }; diff --git a/src/redux/gas.js b/src/redux/gas.js index 9a1e5555615..07a54cf8645 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -1,3 +1,4 @@ +import { captureException } from '@sentry/react-native'; import { get, isEmpty } from 'lodash'; import { apiGetGasPrices } from '../handlers/gasPrices'; import { fromWei } from '../helpers/utilities'; @@ -77,6 +78,7 @@ export const gasPricesInit = () => (dispatch, getState) => payload: fallbackGasPrices, type: GAS_PRICES_FAILURE, }); + captureException(error); fetchReject(error); }); }); diff --git a/src/redux/uniqueTokens.js b/src/redux/uniqueTokens.js index f95d0f01c70..5251a105aa3 100644 --- a/src/redux/uniqueTokens.js +++ b/src/redux/uniqueTokens.js @@ -1,3 +1,4 @@ +import { captureException } from '@sentry/react-native'; import { without } from 'lodash'; import { apiGetAccountUniqueTokens } from '../handlers/opensea-api'; import { @@ -78,6 +79,7 @@ export const uniqueTokensRefreshState = () => (dispatch, getState) => }) .catch(error => { dispatch({ type: UNIQUE_TOKENS_GET_UNIQUE_TOKENS_FAILURE }); + captureException(error); fetchReject(error); }); }); From 63d78d571fd3e01d46b685ce5215f103b49aef42 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 20:02:59 -0500 Subject: [PATCH 604/636] Add breadcrumbs for Sentry to wallet initialization --- src/hoc/withDataInit.js | 6 +++++- src/utils/index.js | 1 + src/utils/sentry.js | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/utils/sentry.js diff --git a/src/hoc/withDataInit.js b/src/hoc/withDataInit.js index 13216abcbf4..87956cd9d55 100644 --- a/src/hoc/withDataInit.js +++ b/src/hoc/withDataInit.js @@ -46,7 +46,7 @@ import { web3ListenerClearState, web3ListenerInit, } from '../redux/web3listener'; -import { promiseUtils } from '../utils'; +import { promiseUtils, sentryUtils } from '../utils'; import withHideSplashScreen from './withHideSplashScreen'; export default Component => @@ -118,6 +118,7 @@ export default Component => initializeAccountData: ownProps => async () => { try { // await ownProps.dataTokenOverridesInit(); + sentryUtils.addInfoBreadcrumb('Initialize account data'); ownProps.explorerInit(); ownProps.uniswapPairsInit(); ownProps.gasPricesInit(); @@ -130,6 +131,7 @@ export default Component => } }, loadAccountData: ownProps => async () => { + sentryUtils.addInfoBreadcrumb('Load wallet data'); await ownProps.openStateSettingsLoadState(); const p1 = ownProps.settingsLoadState(); const p2 = ownProps.dataLoadState(); @@ -160,6 +162,7 @@ export default Component => withHandlers({ initializeWallet: ownProps => async seedPhrase => { try { + sentryUtils.addInfoBreadcrumb('Start wallet setup'); const { isImported, isNew, walletAddress } = await walletInit( seedPhrase ); @@ -192,6 +195,7 @@ export default Component => await ownProps.loadAccountData(); } ownProps.onHideSplashScreen(); + sentryUtils.addInfoBreadcrumb('Hide splash screen'); ownProps.initializeAccountData(); return walletAddress; } catch (error) { diff --git a/src/utils/index.js b/src/utils/index.js index eae6f18f6bd..1eac30d1a8b 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -15,4 +15,5 @@ export { default as parseQueryParams } from './parseQueryParams'; export { default as promiseUtils } from './promise'; export { default as reduceArrayToObject } from './reduceArrayToObject'; export { default as safeAreaInsetValues } from './safeAreaInsetValues'; +export { default as sentryUtils } from './sentry'; export { default as statusBar } from './statusBar'; diff --git a/src/utils/sentry.js b/src/utils/sentry.js new file mode 100644 index 00000000000..0e18d493a7e --- /dev/null +++ b/src/utils/sentry.js @@ -0,0 +1,11 @@ +import { addBreadcrumb } from '@sentry/react-native'; + +const addInfoBreadcrumb = message => + addBreadcrumb({ + level: 'info', + message, + }); + +export default { + addInfoBreadcrumb, +}; From 364f432fd3d9a44ba8bd61c7f618f8c0f4a21553 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 20:03:59 -0500 Subject: [PATCH 605/636] Keep Sentry compatible with CodePush --- src/App.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 65772dc8186..d50a160663e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,7 @@ // eslint-disable-next-line import/default import PushNotificationIOS from '@react-native-community/push-notification-ios'; import analytics from '@segment/analytics-react-native'; -import { init as initSentry } from '@sentry/react-native'; +import { init as initSentry, setRelease } from '@sentry/react-native'; import { get, last } from 'lodash'; import PropTypes from 'prop-types'; import nanoid from 'nanoid/non-secure'; @@ -38,6 +38,12 @@ if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; } +CodePush.getUpdateMetadata().then(update => { + if (update) { + setRelease(update.appVersion + '-codepush:' + update.label); + } +}); + useScreens(false); class App extends Component { From d8f8b030ef4ebe2a92c771314448b1fc79309c46 Mon Sep 17 00:00:00 2001 From: jinchung Date: Wed, 11 Dec 2019 19:56:46 -0500 Subject: [PATCH 606/636] Removing unused internal lane --- ios/fastlane/Fastfile | 29 ----------------------------- ios/fastlane/README.md | 5 ----- 2 files changed, 34 deletions(-) diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index b502f9b8417..ec587a75f2c 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -47,33 +47,4 @@ platform :ios do ) refresh_dsyms end - - desc "Submit a new Internal build to Apple TestFlight" - lane :internal do - update_info_plist( - plist_path: "Rainbow/Info.plist", - display_name: "Internal" - ) - update_app_identifier( - app_identifier: "me.rainbow.internal", - xcodeproj: "Rainbow.xcodeproj", - plist_path: "Rainbow/Info.plist", - ) - match( - type: "appstore", - app_identifier: "me.rainbow.internal", - git_url: "git@github.com:rainbow-me/rainbow-code-signing.git" - ) - gym( - scheme: "Rainbow", - export_method: "app-store", - include_symbols: true, - ) - pilot( - app_identifier: "me.rainbow.internal" - ) - download_dsyms - upload_symbols_to_crashlytics - clean_build_artifacts - end end diff --git a/ios/fastlane/README.md b/ios/fastlane/README.md index 75c01d65a04..a3d69dc0be7 100644 --- a/ios/fastlane/README.md +++ b/ios/fastlane/README.md @@ -26,11 +26,6 @@ Refresh dSYMs fastlane ios beta ``` Submit a new Beta build to Apple TestFlight -### ios internal -``` -fastlane ios internal -``` -Submit a new Internal build to Apple TestFlight ---- From e58a558c7109c57237a966c65c6a39e92d46a5b6 Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 22:52:50 -0500 Subject: [PATCH 607/636] Create a release branch for v1.2.2 --- CHANGELOG.md | 15 +++++++++++--- ios/Podfile.lock | 44 +++++++++++++++++++++--------------------- ios/Rainbow/Info.plist | 2 ++ 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97e07e83561..f866a4d6df9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ## [Unreleased] ### Added -* Support for deeplinking -* Support eth_signTransaction + +### Removed + +### Changed + +## [1.2.2-1](https://github.com/rainbow-me/rainbow/releases/tag/v1.2.2-1) +### Added +* Uniswap support +* Add to contacts +* Support for deep linking +* Support for Sentry ### Changed -* Updated icons and splash screen +* Upgraded Firebase ## [1.1.5-2](https://github.com/rainbow-me/rainbow/releases/tag/v1.1.5-2) ### Changed diff --git a/ios/Podfile.lock b/ios/Podfile.lock index cb1c2f58471..2381d1b0fa9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -672,8 +672,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 819f6346db17ab2e478505a141eb03b81ec987e5 - FBReactNativeSpec: 8783576777bb2f564f3d632232d17b5ebe718508 + FBLazyVector: 0c8f16d9593ebad7f10791657bc1e1fb25c9e4d7 + FBReactNativeSpec: ad0ac4f5ceb4d0751442a3279a90cd439a8946d8 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -693,15 +693,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: 20d79da7f20b5928b80043b05080b816e802659e - RCTRequired: 050b52195fd4a3734b14622c3060368137c2cce3 - RCTTypeSafety: a50b5ac437c7feba50396f2b85431499fe22c846 - React: 5984b8456f8e83b2609935f1e188714ae9da01d3 - React-Core: 0d789180fcef897535596fee945f3b4caf9ecea9 - React-CoreModules: 3a21a44a5c80a6372cf40e0ced849b597c377b8e - React-cxxreact: 4a154094e80071227154767175d77512a6d184f2 - React-jsi: 9e4b30831a63b7b9804e4403a792853790e524e8 - React-jsiexecutor: a4ab14e11578382aa0df9c95ef95d8d33da0b605 - React-jsinspector: 619bae388f66f13e8a4b094898de2a6c2417ce39 + RCTRequired: 4bff03fb8e73a84de3effa45afb6e9fe2d369359 + RCTTypeSafety: cae5afa03fe5ad152ab88b57de114d6e924c6a90 + React: dd5fc27559ffff9c10daafaa4eb6047fec676719 + React-Core: 36df299bda3947558bffdba2d3ed1ac119c28928 + React-CoreModules: 05fa745f9c0ede0c4c0bdc9faa76b570d2a7a430 + React-cxxreact: 849bbf450d0b03ca6d928e8c7fa4d12d1939bb2d + React-jsi: 0372845dd9be330ccb15cfef5bcd28b0d9537ca5 + React-jsiexecutor: 856e38224bf26f12f5becfb3ccc6743853588555 + React-jsinspector: 4362afcdf41b3e2129ffe43c8e9c78fa1c72b889 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 1df7f9a047591bbc2c9a7ec80bd6412d3c19579f react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -712,16 +712,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 3b8143662e17e117a8ab7794be08c381d894f582 - React-RCTAnimation: eb7889dd47c9a39791572cd2b1519ac2aa03d519 - React-RCTBlob: edfb49d23e4c5498a2a371df2eb504fc9fbc588a - React-RCTImage: 187f4c136ee36b0700b5b6d9ffdd9c03e4deff3b - React-RCTLinking: 55868cf6130190ecceb0365af62889172385b9c6 - React-RCTNetwork: ac5092cd1f8dde03d890aa445b39030a570010e5 - React-RCTSettings: aafce4fe24e5dbca7a08e813a128c986d09f6b2a - React-RCTText: 299f71e927c3f7f6fe0636c5ff12876851e4c2cf - React-RCTVibration: 7239997201b76f7fa93226f9a74c6db50f6edd30 - ReactCommon: 08828c927c18463da3b25be7c1083cc6d2f2c150 + React-RCTActionSheet: 24e10177336fabb6d4225b8f7dcae0578c004ed1 + React-RCTAnimation: d42afd4d6068196f726ef555ef5390264472afb5 + React-RCTBlob: da0c00a5432821fbe734e102870b7e7653d5b7c2 + React-RCTImage: 34723ca1d0c27bfcfb4a09d0833b4e5395b3bb79 + React-RCTLinking: cb67c94e286bfca8ac8aefedb36f637d05b49037 + React-RCTNetwork: d84ef16e0c65c468a2a729896e5776d831795dc8 + React-RCTSettings: f3801a6b4124d6b3b864269028b9bd37d0d3b816 + React-RCTText: b940518c1fa1b648e45a99faf075ba0bfa9bb625 + React-RCTVibration: ffadac9ae2cf004f45cb164eda5820f061b9006d + ReactCommon: 71b393deff5112ced3ea4399fdf9d9322f25fb9a ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -751,7 +751,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: e8b2e61404f15aa7fdd630d65755530125c1ada6 + Yoga: 9d3eee93aa8637e12bb63443b72b334f2c43cd18 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/ios/Rainbow/Info.plist b/ios/Rainbow/Info.plist index 65a7e779a81..abc00b1dea4 100644 --- a/ios/Rainbow/Info.plist +++ b/ios/Rainbow/Info.plist @@ -80,6 +80,8 @@ Rainbow NSMotionUsageDescription Rainbow + NSPhotoLibraryUsageDescription + Rainbow NSSpeechRecognitionUsageDescription Rainbow UIAppFonts From 8b27a79b7164ca5d052a0ea543a27b586caaa50c Mon Sep 17 00:00:00 2001 From: jinchung Date: Thu, 12 Dec 2019 23:44:42 -0500 Subject: [PATCH 608/636] Include Sentry properties files --- android/sentry.properties | 4 ++++ ios/sentry.properties | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 android/sentry.properties create mode 100644 ios/sentry.properties diff --git a/android/sentry.properties b/android/sentry.properties new file mode 100644 index 00000000000..a8f8225c9b4 --- /dev/null +++ b/android/sentry.properties @@ -0,0 +1,4 @@ +defaults.url=https://sentry.io/ +defaults.org=rainbow-me +defaults.project=rainbow-wallet +cli.executable=node_modules/@sentry/cli/bin/sentry-cli diff --git a/ios/sentry.properties b/ios/sentry.properties new file mode 100644 index 00000000000..a8f8225c9b4 --- /dev/null +++ b/ios/sentry.properties @@ -0,0 +1,4 @@ +defaults.url=https://sentry.io/ +defaults.org=rainbow-me +defaults.project=rainbow-wallet +cli.executable=node_modules/@sentry/cli/bin/sentry-cli From 6b20775d555efe7b219ad1dfa0de846c66025dc1 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 13 Dec 2019 01:50:43 -0500 Subject: [PATCH 609/636] =?UTF-8?q?Disable=20Sentry=20for=20=E2=80=98devel?= =?UTF-8?q?opment=E2=80=99=20builds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/App.js b/src/App.js index d50a160663e..f7657c86958 100644 --- a/src/App.js +++ b/src/App.js @@ -30,12 +30,10 @@ import { requestsForTopic } from './redux/requests'; import Routes from './screens/Routes'; import { parseQueryParams } from './utils'; -initSentry({ - dsn: SENTRY_ENDPOINT, -}); - if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; +} else { + initSentry({ dsn: SENTRY_ENDPOINT }); } CodePush.getUpdateMetadata().then(update => { From 05bd5337b3ecb8c68dca47a11c731e8bb4200a75 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Fri, 13 Dec 2019 01:52:29 -0500 Subject: [PATCH 610/636] Fix the broken initial autofocus effect on Swap Modal Fixes RAI-140 https://linear.app/issue/RAI-140 --- ios/Podfile.lock | 58 ++++---- src/screens/ExchangeModal.js | 23 ++-- yarn.lock | 247 ++++++++++++++++++++++++----------- 3 files changed, 211 insertions(+), 117 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2381d1b0fa9..dd4896ebf94 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -285,13 +285,13 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.13.1): + - react-native-camera (3.14.0): - React - - react-native-camera/RCT (= 3.13.1) - - react-native-camera/RN (= 3.13.1) - - react-native-camera/RCT (3.13.1): + - react-native-camera/RCT (= 3.14.0) + - react-native-camera/RN (= 3.14.0) + - react-native-camera/RCT (3.14.0): - React - - react-native-camera/RN (3.13.1): + - react-native-camera/RN (3.14.0): - React - react-native-mail (4.1.0): - React @@ -334,7 +334,9 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -672,8 +674,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 0c8f16d9593ebad7f10791657bc1e1fb25c9e4d7 - FBReactNativeSpec: ad0ac4f5ceb4d0751442a3279a90cd439a8946d8 + FBLazyVector: 79ecc874031236eebb3e9e5ffc2141086e16e847 + FBReactNativeSpec: 5c88f1630d22de0aceaacc621c74240634db37eb Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -693,17 +695,17 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: 20d79da7f20b5928b80043b05080b816e802659e - RCTRequired: 4bff03fb8e73a84de3effa45afb6e9fe2d369359 - RCTTypeSafety: cae5afa03fe5ad152ab88b57de114d6e924c6a90 - React: dd5fc27559ffff9c10daafaa4eb6047fec676719 - React-Core: 36df299bda3947558bffdba2d3ed1ac119c28928 - React-CoreModules: 05fa745f9c0ede0c4c0bdc9faa76b570d2a7a430 - React-cxxreact: 849bbf450d0b03ca6d928e8c7fa4d12d1939bb2d - React-jsi: 0372845dd9be330ccb15cfef5bcd28b0d9537ca5 - React-jsiexecutor: 856e38224bf26f12f5becfb3ccc6743853588555 - React-jsinspector: 4362afcdf41b3e2129ffe43c8e9c78fa1c72b889 + RCTRequired: 9084bed4910a631f6b9e0adbd82861b1c6eb6114 + RCTTypeSafety: e57c1b42239672cbab98d41350603f54212490e8 + React: 3950154959c79f0003347cfb42d5bea280be85d2 + React-Core: 03c3b8d777397f1a11f91819f071ffa989a53a6d + React-CoreModules: 6d594e2bd581aca66519995401b7fdcce50fee1a + React-cxxreact: 386d1f74b37a901bc3a4a06ccad5e3b8bf11bccb + React-jsi: b916b09ecd0956a90109e1cd218883229998f273 + React-jsiexecutor: aecfc8420de9ace6ea78f3b50688b089c4401572 + React-jsinspector: 4b34c2a995846801442cb9f147a70deb6b0a11c9 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 1df7f9a047591bbc2c9a7ec80bd6412d3c19579f + react-native-camera: 9f79d18f91fc8c35d693f1846d84a8b9094bcc65 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 @@ -712,16 +714,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 24e10177336fabb6d4225b8f7dcae0578c004ed1 - React-RCTAnimation: d42afd4d6068196f726ef555ef5390264472afb5 - React-RCTBlob: da0c00a5432821fbe734e102870b7e7653d5b7c2 - React-RCTImage: 34723ca1d0c27bfcfb4a09d0833b4e5395b3bb79 - React-RCTLinking: cb67c94e286bfca8ac8aefedb36f637d05b49037 - React-RCTNetwork: d84ef16e0c65c468a2a729896e5776d831795dc8 - React-RCTSettings: f3801a6b4124d6b3b864269028b9bd37d0d3b816 - React-RCTText: b940518c1fa1b648e45a99faf075ba0bfa9bb625 - React-RCTVibration: ffadac9ae2cf004f45cb164eda5820f061b9006d - ReactCommon: 71b393deff5112ced3ea4399fdf9d9322f25fb9a + React-RCTActionSheet: 7fa31ae3a9c06cefab8f31a269a9c88f51d59707 + React-RCTAnimation: af3ae170bd4000dcf971a6108aeb49a15073c10f + React-RCTBlob: 3865f337cdddd685e6ab1be89caddb404ba91beb + React-RCTImage: f8bf76d61bd6c0ad98ee23bec11a3ac7d293a03b + React-RCTLinking: 3cc931c5f39e77235e59f6cc5cf900443b35d5b0 + React-RCTNetwork: 95a254130217387eeb9c97dfcfbe55f75c9cb1a5 + React-RCTSettings: bcfffacfc88602532825c49ccb866cb4cc5e7174 + React-RCTText: be83a902438b819fdb9d99132132ecc8d3bcfcd7 + React-RCTVibration: e96a5af6ccc9ce1211ef2c72524f4975ad023d47 + ReactCommon: 531f5a47f0ab764f6ad72bf0e5680954801b5cdd ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -751,7 +753,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 9d3eee93aa8637e12bb63443b72b334f2c43cd18 + Yoga: 11364219d2b5158d2d16c9479f13f528534a6857 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index a8a05dd225b..778db20cb58 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -142,19 +142,6 @@ class ExchangeModal extends Component { 'pendingApprovals', ]); - // Code below is a workaround. We noticed that opening keyboard while animation - // (with autofocus) can lead to frame drops. In order not to limit this - // I manually can focus instead of relying on built-in autofocus. - // Maybe that's not perfect, but works for now ¯\_(ツ)_/¯ - if ( - this.props.isTransitioning && - nextProps.isTransitioning && - this.lastFocusedInput === null - ) { - this.inputFocusInteractionHandle = InteractionManager.runAfterInteractions( - this.focusInputField - ); - } const isNewState = isNewValueForObjectPaths(this.state, nextState, [ 'approvalCreationTimestamp', 'approvalEstimatedTimeInMs', @@ -248,6 +235,16 @@ class ExchangeModal extends Component { assignInputFieldRef = ref => { this.inputFieldRef = ref; + + // Code below is a workaround. We noticed that opening keyboard while animation + // (with autofocus) can lead to frame drops. In order not to limit this + // I manually can focus instead of relying on built-in autofocus. + // Maybe that's not perfect, but works for now ¯\_(ツ)_/¯ + if (this.lastFocusedInput === null) { + this.inputFocusInteractionHandle = InteractionManager.runAfterInteractions( + this.focusInputField + ); + } }; assignNativeFieldRef = ref => { this.nativeFieldRef = ref; diff --git a/yarn.lock b/yarn.lock index 4bb8485a954..f6798315d5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -984,9 +984,9 @@ integrity sha512-EJGsbrHubK1mGxPjWB74AaHAd5m9I+Gg2RRPZzMK6org7QOU9WOBnIMFqoeVto3hKOaEPlk8NV74H6G34/2pZQ== "@react-native-community/blur@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.3.1.tgz#bc9ecd6d85d89739d8180138716535ac7cfa4680" - integrity sha512-UfH2ut/l4GpZHeq/TGx3BrmyXSCSBBwBCVx1DhPodP3k959zJ2ajgXa3PiU/qjutftTUw6KH9Frsh2U0ax9dMQ== + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.4.1.tgz#dec04c7d60dd6a4fa7e3af3506feefec804728d0" + integrity sha512-XhbS230J7BGuoEamjPFZ5jUWDOW16y+vD0Soyq9Iv1qL8R47esGl54bnfUSMH10WhNXrQzvPxkMzap+ONHpE2w== dependencies: prop-types "^15.5.10" @@ -997,7 +997,7 @@ dependencies: serve-static "^1.13.1" -"@react-native-community/cli-platform-android@^3.0.0-alpha.1": +"@react-native-community/cli-platform-android@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz#e652abce79a7c1e3a8280228123e99df2c4b97b6" integrity sha512-rNO9DmRiVhB6aP2DVUjEJv7ecriTARDZND88ny3xNVUkrD1Y+zwF6aZu3eoT52VXOxLCSLiJzz19OiyGmfqxYg== @@ -1010,7 +1010,7 @@ slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^3.0.0-alpha.1": +"@react-native-community/cli-platform-ios@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz#3a48a449c0c33af3b0b3d19d3256de99388fe15f" integrity sha512-QoNVlDj8eMXRZk9uktPFsctHurQpv9jKmiu6mQii4NEtT2npE7g1hbWpRNojutBsfgmCdQGDHd9uB54eeCnYgg== @@ -1035,7 +1035,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652" integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg== -"@react-native-community/cli@3.0.4", "@react-native-community/cli@^3.0.0-alpha.1": +"@react-native-community/cli@3.0.4", "@react-native-community/cli@^3.0.0": version "3.0.4" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.4.tgz#a9dba1bc77855a6e45fccaabb017360645d936bb" integrity sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA== @@ -1394,9 +1394,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.0.tgz#f1ec1c104d1bb463556ecb724018ab788d0c172a" - integrity sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw== + version "7.6.1" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" + integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== dependencies: "@babel/types" "^7.0.0" @@ -1470,9 +1470,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.16.tgz#3ebcbd7bf978fa4c5120fee8be57083271a8b3ac" - integrity sha512-vRuMyoOr5yfNf8QWxXegOjeyjpWJxFePzHzmBOIzDIzo+rSqF94RW0PkS6y4T2+VjAWLXHWrfbIJY3E3aS7lUw== + version "12.12.17" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.17.tgz#191b71e7f4c325ee0fb23bc4a996477d92b8c39b" + integrity sha512-Is+l3mcHvs47sKy+afn2O1rV4ldZFU7W8101cNlOd+MRbjM4Onida8jSZnJdTe/0Pcf25g9BNIUsuugmE6puHA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1736,6 +1736,11 @@ animated@^0.2.2: invariant "^2.2.0" normalize-css-color "^1.0.1" +anser@^1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" + integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== + ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" @@ -1924,12 +1929,12 @@ array-find-index@^1.0.1: integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-includes@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" - integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.0.tgz#48a929ef4c6bb1fa6dc4a92c9b023a261b0ca404" + integrity sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ== dependencies: - define-properties "^1.1.2" - es-abstract "^1.7.0" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.0" array-map@~0.0.0: version "0.0.0" @@ -2209,7 +2214,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: +babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0, babel-preset-fbjs@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz#a6024764ea86c8e06a22d794ca8b69534d263541" integrity sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw== @@ -3903,7 +3908,7 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.12.0, es-abstract@^1.15.0, es-abstract@^1.5.1, es-abstract@^1.7.0: +es-abstract@^1.12.0, es-abstract@^1.5.1: version "1.16.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.3.tgz#52490d978f96ff9f89ec15b5cf244304a5bca161" integrity sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw== @@ -3919,6 +3924,23 @@ es-abstract@^1.12.0, es-abstract@^1.15.0, es-abstract@^1.5.1, es-abstract@^1.7.0 string.prototype.trimleft "^2.1.0" string.prototype.trimright "^2.1.0" +es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1: + version "1.17.0-next.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" + integrity sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.0" + string.prototype.trimright "^2.1.0" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -4138,10 +4160,10 @@ eslint-plugin-react@^7.12.4: prop-types "^15.7.2" resolve "^1.13.1" -eslint-plugin-relay@1.3.12: - version "1.3.12" - resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.3.12.tgz#1e7d936386650ccc7709c8f6eeb0210e0e226527" - integrity sha512-276RrlyF0112Mz8PbaDvYKmqBGYEm0WBCfMNunnm6jHQ0aClUbPUmNctJXpFjfurcZfNEOz22Nx3VUMVDIGIkw== +eslint-plugin-relay@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.4.1.tgz#5af2ac13e24bd01ad17b6a4014204918d65021cd" + integrity sha512-yb+p+4AxZTi2gXN7cZRfXMBFlRa5j6TtiVeq3yHXyy+tlgYNpxi/dDrP1+tcUTNP9vdaJovnfGZ5jp6kMiH9eg== dependencies: graphql "^14.0.0" @@ -4350,16 +4372,17 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-2.1.0.tgz#e5d3ecd837d2a60ec50f3da78fd39767747bbe99" - integrity sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw== +execa@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" + human-signals "^1.1.1" is-stream "^2.0.0" merge-stream "^2.0.0" - npm-run-path "^3.0.0" + npm-run-path "^4.0.0" onetime "^5.1.0" p-finally "^2.0.0" signal-exit "^3.0.2" @@ -5288,10 +5311,10 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-engine@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" - integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== +hermes-engine@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.3.0.tgz#c03ded211102eef775045a5f55e286783db8ad48" + integrity sha512-Xl21n/FohkoeQyz/9AeisoePhXaLvXRyT41xkYHOrqoNr+pkLUGc1xIo486ctIxSp5SN4BkN6T3YFWOdD0ntaQ== hmac-drbg@^1.0.0: version "1.0.1" @@ -5384,6 +5407,11 @@ https-proxy-agent@^3.0.0: agent-base "^4.3.0" debug "^3.1.0" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + husky@^2.4.0: version "2.7.0" resolved "https://registry.yarnpkg.com/husky/-/husky-2.7.0.tgz#c0a9a6a3b51146224e11bba0b46bba546e461d05" @@ -7116,6 +7144,24 @@ metro-babel-register@0.56.3: core-js "^2.2.2" escape-string-regexp "^1.0.5" +metro-babel-register@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.57.0.tgz#43acb47a7f45543428830db5634b33e8e7543c39" + integrity sha512-toZwgFY/y/+8GxSLT6kDRI5/hcnm7VtVglMo8WN9p9LEeGjKgWeJrf6YrrqQ8L+Ycy771w00jHZVw2QwlvCQUQ== + dependencies: + "@babel/core" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/register" "^7.0.0" + core-js "^2.2.2" + escape-string-regexp "^1.0.5" + metro-babel-transformer@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz#6559c3a8565238a704a181353cef59fdb974e6db" @@ -7124,6 +7170,14 @@ metro-babel-transformer@0.56.3: "@babel/core" "^7.0.0" metro-source-map "0.56.3" +metro-babel-transformer@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.57.0.tgz#8f4bd17ad5631937cdb5651e7d77f9c73b9f935c" + integrity sha512-679BstNiPUUt5a4f86iJTa7q8jFntgd9SQBVWN+CLI5L9T7iTxi7JDbR+oHIOi3OT/dBlY9s2dWZCVAuNW9DHA== + dependencies: + "@babel/core" "^7.0.0" + metro-source-map "0.57.0" + metro-cache@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.3.tgz#1b0759bc45291cc3ffc77736c09dcfbd322edb8b" @@ -7215,7 +7269,7 @@ metro-react-native-babel-preset@0.56.3: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-preset@^0.57.0: +metro-react-native-babel-preset@0.57.0, metro-react-native-babel-preset@^0.57.0: version "0.57.0" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.57.0.tgz#bbbce26a20d9ca3fdc08f0df564bc982b82651b7" integrity sha512-pvLh1QOwdxsjgYE2a+4aTKs3LSF3+t4jscxHtkND6wsJnKVVspLt8FkDaORa6zr3Fq12tVpEt5NJMdgtWqBpaA== @@ -7256,7 +7310,18 @@ metro-react-native-babel-preset@^0.57.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@0.56.3, metro-react-native-babel-transformer@^0.56.0: +metro-react-native-babel-transformer@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.57.0.tgz#60e3b97f73f016c138096c1a706ccc3bc4590fcf" + integrity sha512-Pw8N3InjUVJT23w/LNKwrWeXY50aODv2js/WCfwguZqriJqELOCxF1BWgvsChGNuDpkl0ihKct4224w0+4ktyA== + dependencies: + "@babel/core" "^7.0.0" + babel-preset-fbjs "^3.3.0" + metro-babel-transformer "0.57.0" + metro-react-native-babel-preset "0.57.0" + metro-source-map "0.57.0" + +metro-react-native-babel-transformer@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz#e68205230be65c07290b932f7684226013dae310" integrity sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw== @@ -7287,6 +7352,19 @@ metro-source-map@0.56.3: source-map "^0.5.6" vlq "^1.0.0" +metro-source-map@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.57.0.tgz#f6715b8687041804e4e0679bad4e8946bf9dd5a7" + integrity sha512-hYd2MmLUOmOJkQCzABLV3mYW7JwzkfvL9SUAHhRDzUS4Z69k+Yh2805HpH8/gN6SGvfw0PuPXXEixtvW66b6yQ== + dependencies: + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + invariant "^2.2.4" + metro-symbolicate "0.57.0" + ob1 "0.57.0" + source-map "^0.5.6" + vlq "^1.0.0" + metro-symbolicate@0.56.3: version "0.56.3" resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz#20f9dc52fab3209903715716402692b3ac16831c" @@ -7298,6 +7376,17 @@ metro-symbolicate@0.56.3: through2 "^2.0.1" vlq "^1.0.0" +metro-symbolicate@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.57.0.tgz#64693841190ad3d9b832af0490f16e95f51e4045" + integrity sha512-Gq30gqGAGYIpO7FdeUboQXaMUeiQqq2VNiPaLJg67zCz9FKLuS3Laf4i/mpUCzHv9+lqcEKIOEYP7SQaluUIPQ== + dependencies: + invariant "^2.2.4" + metro-source-map "0.57.0" + source-map "^0.5.6" + through2 "^2.0.1" + vlq "^1.0.0" + metro@0.56.3, metro@^0.56.0: version "0.56.3" resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.3.tgz#3a38706bf6b1200421e871a4c53ddc2f359f65a9" @@ -7840,10 +7929,10 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" - integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== +npm-run-path@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.0.tgz#d644ec1bd0569187d2a52909971023a0a58e8438" + integrity sha512-8eyAOAH+bYXFPSnNnKr3J+yoybe8O87Is5rtAQ8qRczJz1ajcsjg8l2oZqP+Ppx15Ii3S1vUTjQN2h4YO2tWWQ== dependencies: path-key "^3.0.0" @@ -7894,6 +7983,11 @@ ob1@0.56.3: resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.3.tgz#5829e446587c9bf89c22ece4f3757b29f2ccfd18" integrity sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ== +ob1@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.57.0.tgz#2023173d54579ed5b28dc5943ab5d977401dbe0d" + integrity sha512-BRAyYcG7NeA8vZFQ/oMqw1fiRLdFcxi/x9DJ3KWeaSI7+tiO3MZwMjnkL9sdsZMEL4OtpggbeAK2dL3zYNiI1A== + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -7955,22 +8049,22 @@ object.assign@4.1.0, object.assign@^4.1.0: object-keys "^1.0.11" object.entries@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519" - integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" + integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== dependencies: define-properties "^1.1.3" - es-abstract "^1.12.0" + es-abstract "^1.17.0-next.1" function-bind "^1.1.1" has "^1.0.3" object.fromentries@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704" - integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" + integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== dependencies: define-properties "^1.1.3" - es-abstract "^1.15.0" + es-abstract "^1.17.0-next.1" function-bind "^1.1.1" has "^1.0.3" @@ -8049,7 +8143,7 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -open@^6.2.0, open@^6.4.0: +open@^6.2.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== @@ -9053,21 +9147,21 @@ react-native-actionsheet@^2.4.2: integrity sha512-DBoWIvVwuWXuptF4t46pBqkFxaUxS+rsIdHiA05t0n4BdTIDV2R4s9bLEUVOGzb94D7VxIamsXZPA/3mmw+SXg== react-native-bundle-visualizer@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/react-native-bundle-visualizer/-/react-native-bundle-visualizer-2.0.4.tgz#63c61e42f5749590a4ec8149a732472752f4fef8" - integrity sha512-0WzH/tI/vIi/CjjkixLoS8+u96LF77NA3vu64IFayddjllFV2RVL9iW/jsM4/157OU/4MbAqcSzFnLtPqQuFXw== + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-native-bundle-visualizer/-/react-native-bundle-visualizer-2.1.1.tgz#9f94364097caf0c0e146ac6ab5a83f9af52aa2d2" + integrity sha512-2zRiZhU9ymiKzfkUnI9w8X8PCnn1ie4+uLZ1aSLfjh9tENNI2TzEXmYquiUL4dLe8if3FpEDhefa+OjLE0NNoA== dependencies: - chalk "^2.4.2" - execa "^2.0.4" + chalk "^3.0.0" + execa "^3.4.0" minimist "^1.2.0" - open "^6.4.0" + open "^7.0.0" rimraf "^3.0.0" - source-map-explorer "^2.1.0" + source-map-explorer "^2.1.2" react-native-camera@^3.9.0: - version "3.13.1" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.13.1.tgz#016a011ca264d7044e2f1ad11fc624b90020aeb9" - integrity sha512-HXCo75sFYOJRqtbiG12ttoG6K4UdS1mfOwu6NoQmxj6IV2KrNgdOYO4YTyLymGUXNs3LyOWpJskVvCRupoFA3A== + version "3.14.0" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.14.0.tgz#04d74444691bab68adce718daea459c7949b61c1" + integrity sha512-F+n9Ap91vXBqkfX2sbWFpMUIAADhCXOJEkggEqxh/ul9oL81vP8WscpcCBlbei7NZ3BLvrgFa8qgauNrZelQgw== dependencies: prop-types "^15.6.2" @@ -9237,7 +9331,7 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/fa2f249537b6f5fb122b3ead1d404b91f39addce" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/dfd97c51eeb9ef1ea35ffb5253a48cf3689e16c9" react-native-redash@8.2.2: version "8.2.2" @@ -9355,27 +9449,28 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/64b4b33363b3747516951dac4b1f607519fcfe0a" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/19bf2027d1095bf2655a84a006ed74e6adae4df3" dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" - "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" + "@react-native-community/cli" "^3.0.0" + "@react-native-community/cli-platform-android" "^3.0.0" + "@react-native-community/cli-platform-ios" "^3.0.0" abort-controller "^3.0.0" + anser "^1.4.9" base64-js "^1.1.2" connect "^3.6.5" create-react-class "^15.6.3" escape-string-regexp "^1.0.5" - eslint-plugin-relay "1.3.12" + eslint-plugin-relay "1.4.1" event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermes-engine "^0.2.1" + hermes-engine "~0.3.0" invariant "^2.2.4" jsc-android "^245459.0.0" - metro-babel-register "0.56.3" - metro-react-native-babel-transformer "0.56.3" - metro-source-map "0.56.3" + metro-babel-register "0.57.0" + metro-react-native-babel-transformer "0.57.0" + metro-source-map "0.57.0" nullthrows "^1.1.1" pretty-format "^24.7.0" promise "^7.1.1" @@ -9383,7 +9478,7 @@ react-native@facebook/react-native: react-devtools-core "^4.0.6" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.16.2" + scheduler "0.17.0" stacktrace-parser "^0.1.3" use-subscription "^1.0.0" whatwg-fetch "^3.0.0" @@ -9757,9 +9852,9 @@ regjsgen@^0.5.0: integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== + version "0.6.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.1.tgz#5b6b28c418f312ef42898dc6865ae2d4b9f0f7a2" + integrity sha512-7LutE94sz/NKSYegK+/4E77+8DipxF+Qn2Tmu362AcmsF2NYq/wx3+ObvU90TKEhjf7hQoFXo23ajjrXP7eUgg== dependencies: jsesc "~0.5.0" @@ -10169,10 +10264,10 @@ schedule@0.5.0: dependencies: object-assign "^4.1.1" -scheduler@0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" - integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg== +scheduler@0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" + integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -10506,7 +10601,7 @@ socks@~2.3.2: ip "1.1.5" smart-buffer "^4.1.0" -source-map-explorer@^2.1.0: +source-map-explorer@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.2.tgz#305d61efbb1d1ebbf24a9fffef718635054d509c" integrity sha512-rgujHHHwf0/HCSTFbdTPJETGTgbGqVDD068Ob/wfV41u3AdU8iknSvGTDoU8vCIUeZuLnHX4JYsQ1RMd129XCQ== From b27c3d5416b2260204668dc4df3d1d58ca465700 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 13 Dec 2019 14:53:39 -0500 Subject: [PATCH 611/636] Update locaton for finding native tag on input ref --- src/screens/ExchangeModal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index 778db20cb58..c80216e3215 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -78,7 +78,7 @@ const isSameAsset = (a, b) => { return assetA === assetB; }; -const getNativeTag = field => get(field, '_nativeTag'); +const getNativeTag = field => get(field, '_inputRef._nativeTag'); class ExchangeModal extends Component { static propTypes = { From 119ba8e4853f6f4a1783f55c5ed42f44203a4fc8 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 13 Dec 2019 16:12:18 -0500 Subject: [PATCH 612/636] Include an environment tag for Sentry --- src/App.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index f7657c86958..0ade912c184 100644 --- a/src/App.js +++ b/src/App.js @@ -12,6 +12,7 @@ import CodePush from 'react-native-code-push'; import { REACT_APP_SEGMENT_API_WRITE_KEY, SENTRY_ENDPOINT, + SENTRY_ENVIRONMENT, } from 'react-native-dotenv'; // eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; @@ -33,7 +34,7 @@ import { parseQueryParams } from './utils'; if (process.env.NODE_ENV === 'development') { console.disableYellowBox = true; } else { - initSentry({ dsn: SENTRY_ENDPOINT }); + initSentry({ dsn: SENTRY_ENDPOINT, environment: SENTRY_ENVIRONMENT }); } CodePush.getUpdateMetadata().then(update => { From 1a4ad9fc64898c604eb97786e5057301722bbef7 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 17 Dec 2019 00:12:19 -0500 Subject: [PATCH 613/636] Fix network error causing app to crash --- src/redux/gas.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/redux/gas.js b/src/redux/gas.js index 07a54cf8645..2e3d0b919ca 100644 --- a/src/redux/gas.js +++ b/src/redux/gas.js @@ -73,7 +73,6 @@ export const gasPricesInit = () => (dispatch, getState) => fetchResolve(true); }) .catch(error => { - console.error(error); dispatch({ payload: fallbackGasPrices, type: GAS_PRICES_FAILURE, From cc93c9a20efaaf1b32ddf58c4968d1170c8e69a9 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 11 Dec 2019 03:08:13 -0500 Subject: [PATCH 614/636] Upgrade react-native-device-info and react-native-netinfo --- package.json | 12 +- src/components/OfflineBadge.js | 98 +++++------- src/components/gas/GasSpeedLabelPagerItem.js | 4 +- .../qrcode-scanner/QRCodeScanner.js | 149 +++++++++++------- .../settings-menu/SettingsSection.js | 4 +- src/hoc/index.js | 1 - src/hoc/withNetInfo.js | 23 --- src/hooks/index.js | 4 + src/hooks/useAppState.js | 21 +++ src/hooks/useClipboard.js | 26 +++ src/hooks/useInternetStatus.js | 17 ++ src/hooks/usePrevious.js | 11 ++ src/screens/ImportSeedPhraseSheet.js | 2 +- src/screens/QRScannerScreen.js | 136 ++++++++-------- src/screens/TransactionConfirmationScreen.js | 12 -- 15 files changed, 280 insertions(+), 240 deletions(-) delete mode 100644 src/hoc/withNetInfo.js create mode 100644 src/hooks/index.js create mode 100644 src/hooks/useAppState.js create mode 100644 src/hooks/useClipboard.js create mode 100644 src/hooks/useInternetStatus.js create mode 100644 src/hooks/usePrevious.js diff --git a/package.json b/package.json index 492510ffe81..bd354d58eb4 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.6.2", - "@react-native-community/blur": "^3.3.1", + "@react-native-community/blur": "^3.4.1", "@react-native-community/masked-view": "^0.1.5", - "@react-native-community/netinfo": "^4.6.0", + "@react-native-community/netinfo": "^5.0.0", "@react-native-community/push-notification-ios": "^1.0.3", "@react-native-firebase/app": "^6.2.0", "@react-native-firebase/crashlytics": "^6.2.0", @@ -84,13 +84,12 @@ "react-native-circular-progress": "^1.3.4", "react-native-code-push": "^5.6.0", "react-native-crypto": "^2.2.0", - "react-native-device-info": "^2.1.3", + "react-native-device-info": "5.3.1", "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-gesture-handler": "1.5.2", "react-native-haptic-feedback": "^1.8.2", - "react-native-hooks": "^0.9.0", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", @@ -106,18 +105,17 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "software-mansion/react-native-reanimated", - "react-native-redash": "8.2.2", + "react-native-redash": "mikedemarais/react-native-redash#transitions", "react-native-safe-area-context": "^0.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "9.13.3", + "react-native-svg": "9.13.6", "react-native-tcp": "^3.3.2", "react-native-text-input-mask": "waqas19921/react-native-text-input-mask", "react-native-tooltip": "marcosrdz/react-native-tooltip#master", - "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", diff --git a/src/components/OfflineBadge.js b/src/components/OfflineBadge.js index 22a6a036465..d3985e15994 100644 --- a/src/components/OfflineBadge.js +++ b/src/components/OfflineBadge.js @@ -1,22 +1,16 @@ -import analytics from '@segment/analytics-react-native'; -import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; +import React from 'react'; import Animated from 'react-native-reanimated'; -import { compose, onlyUpdateForKeys } from 'recompact'; +import { useSpringTransition } from 'react-native-redash'; import styled from 'styled-components'; -import { withNetInfo } from '../hoc'; +import { useInternetStatus } from '../hooks'; import { colors, padding, shadow } from '../styles'; import { interpolate } from './animations'; import { Icon } from './icons'; -import { RowWithMargins } from './layout'; +import { Centered, RowWithMargins } from './layout'; import { Text } from './text'; -const { spring, Value, View } = Animated; - -const Badge = styled(RowWithMargins).attrs({ - align: 'center', - component: View, - justify: 'center', +const StyledBadge = styled(RowWithMargins).attrs({ + component: Centered, margin: 5, self: 'center', })` @@ -31,60 +25,44 @@ const Badge = styled(RowWithMargins).attrs({ const DefaultAnimationValue = 60; -class OfflineBadge extends PureComponent { - static propTypes = { - isConnected: PropTypes.bool, - }; - - static defaultProps = { - isConnected: true, - }; - - componentDidMount = () => this.runAnimation(); - - componentDidUpdate = () => this.runAnimation(); - - animation = new Value(DefaultAnimationValue); - - runAnimation = () => { - const { isConnected } = this.props; +const OfflineBadge = () => { + const isConnected = useInternetStatus(); - return spring(this.animation, { - damping: 14, - mass: 1, - overshootClamping: false, - restDisplacementThreshold: 0.001, - restSpeedThreshold: 0.001, - stiffness: 121.6, - toValue: isConnected ? DefaultAnimationValue : 0, - }).start(({ finished }) => { - if (!finished) return null; - return isConnected - ? analytics.track('Reconnected after offline') - : analytics.track('Offline / lost connection'); - }); - }; + const animation = useSpringTransition(isConnected, { + damping: 14, + mass: 1, + overshootClamping: false, + restDisplacementThreshold: 0.001, + restSpeedThreshold: 0.001, + stiffness: 121.6, + }); - render = () => ( - - - - Offline - - + + + + Offline + + + ); -} +}; -export default compose( - withNetInfo, - onlyUpdateForKeys(['isConnected']) -)(OfflineBadge); +const neverRerender = () => true; +export default React.memo(OfflineBadge, neverRerender); diff --git a/src/components/gas/GasSpeedLabelPagerItem.js b/src/components/gas/GasSpeedLabelPagerItem.js index 5edd195bd76..d02cf7cfbc1 100644 --- a/src/components/gas/GasSpeedLabelPagerItem.js +++ b/src/components/gas/GasSpeedLabelPagerItem.js @@ -6,7 +6,7 @@ import Animated, { Transitioning, Transition, } from 'react-native-reanimated'; -import { useToggle } from 'react-native-redash'; +import { useTimingTransition } from 'react-native-redash'; import { withProps } from 'recompact'; import { gasUtils } from '../../utils'; import { interpolate } from '../animations'; @@ -51,7 +51,7 @@ const GasSpeedLabelPagerItem = ({ label, selected, shouldAnimate }) => { const isFirst = index === 0; const isLast = index === gasUtils.GasSpeedOrder.length - 1; - const transitionVal = useToggle( + const transitionVal = useTimingTransition( !selected, duration + (isFirst ? 50 : 0), Easing.out(Easing.ease) diff --git a/src/components/qrcode-scanner/QRCodeScanner.js b/src/components/qrcode-scanner/QRCodeScanner.js index f44454deeb9..bd126c2dbb0 100644 --- a/src/components/qrcode-scanner/QRCodeScanner.js +++ b/src/components/qrcode-scanner/QRCodeScanner.js @@ -1,84 +1,115 @@ import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import DeviceInfo from 'react-native-device-info'; +import React, { useEffect, useRef, useState } from 'react'; import FastImage from 'react-native-fast-image'; -import stylePropType from 'react-style-proptype'; -import styled from 'styled-components/primitives'; +import { Transition, Transitioning } from 'react-native-reanimated'; import SimulatorFakeCameraImageSource from '../../assets/simulator-fake-camera-image.jpg'; +import { usePrevious } from '../../hooks'; import { colors, position } from '../../styles'; +import { isNewValueForObjectPaths } from '../../utils'; import { Centered } from '../layout'; import { ErrorText } from '../text'; import QRCodeScannerCamera from './QRCodeScannerCamera'; import QRCodeScannerCrosshair from './QRCodeScannerCrosshair'; -const Container = styled(Centered).attrs({ direction: 'column' })` - ${position.cover}; - background-color: ${colors.black}; -`; +const transition = ( + +); -export default class QRCodeScanner extends PureComponent { - static propTypes = { - contentStyles: stylePropType, - enableCamera: PropTypes.bool, - enableScanning: PropTypes.bool, - isCameraAuthorized: PropTypes.bool, - onSuccess: PropTypes.func, - showCrosshairText: PropTypes.bool, - }; +const QRCodeScanner = ({ + contentPositionBottom, + contentPositionTop, + enableCamera, + enableScanning, + isCameraAuthorized, + isEmulator, + onSuccess, + showCrosshairText, +}) => { + const ref = useRef(); + const [error, setError] = useState(null); + const [isInitialized, setInitialized] = useState(false); - state = { - error: null, - isInitialized: false, - }; - - handleCameraReady = () => this.setState({ isInitialized: true }); - - handleMountError = () => this.setState({ error: 'mounting' }); - - renderCamera = () => { - if (DeviceInfo.isEmulator()) { - return ( - - ); + const prevContentPositionBottom = usePrevious(contentPositionBottom); + useEffect(() => { + if (ref.current && contentPositionBottom !== prevContentPositionBottom) { + ref.current.animateNextTransition(); } + }, [contentPositionBottom, prevContentPositionBottom]); - return this.props.enableCamera ? ( + let cameraRenderer = null; + if (isEmulator) { + cameraRenderer = ( + + ); + } else if (enableCamera) { + cameraRenderer = ( setInitialized(true)} + onMountError={() => setError('mounting')} + onSuccess={onSuccess} /> - ) : null; - }; - - render = () => { - const { contentStyles, isCameraAuthorized, showCrosshairText } = this.props; - const { error, isInitialized } = this.state; + ); + } - const showErrorMessage = error && !isInitialized; - const showCrosshair = !error && !showErrorMessage; + const showErrorMessage = error && !isInitialized; + const showCrosshair = !error && !showErrorMessage; - return ( - - {this.renderCamera()} - {isCameraAuthorized && ( - + return ( + + {cameraRenderer} + {isCameraAuthorized && ( + + {showErrorMessage && ( )} {showCrosshair && ( )} - )} - - ); - }; -} + + )} + + ); +}; + +QRCodeScanner.propTypes = { + contentPositionBottom: PropTypes.node, + contentPositionTop: PropTypes.node, + enableCamera: PropTypes.bool, + enableScanning: PropTypes.bool, + isCameraAuthorized: PropTypes.bool, + isEmulator: PropTypes.bool, + onSuccess: PropTypes.func, + showCrosshairText: PropTypes.bool, +}; + +const arePropsEqual = (prev, next) => + !isNewValueForObjectPaths(prev, next, [ + 'contentPositionBottom', + 'enableCamera', + 'enableScanning', + 'isCameraAuthorized', + 'showCrosshairText', + ]); + +export default React.memo(QRCodeScanner, arePropsEqual); diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index a53b561f878..ef1a0927265 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -2,7 +2,7 @@ import { upperFirst } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { InteractionManager, Linking, ScrollView } from 'react-native'; -import DeviceInfo from 'react-native-device-info'; +import { isEmulatorSync } from 'react-native-device-info'; import FastImage from 'react-native-fast-image'; import * as StoreReview from 'react-native-store-review'; import { compose, onlyUpdateForKeys, withHandlers } from 'recompact'; @@ -178,7 +178,7 @@ export default compose( const shouldDeeplinkToAppStore = count >= maxRequestCount || !StoreReview.isAvailable; - if (shouldDeeplinkToAppStore && !DeviceInfo.isEmulator()) { + if (shouldDeeplinkToAppStore && !isEmulatorSync()) { Linking.openURL(SettingsExternalURLs.review); } else { onCloseModal(); diff --git a/src/hoc/index.js b/src/hoc/index.js index d6ce99cfba5..1235ba1c52c 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -17,7 +17,6 @@ export { default as withIsWalletEmpty } from './withIsWalletEmpty'; export { default as withIsWalletEthZero } from './withIsWalletEthZero'; export { default as withKeyboardHeight } from './withKeyboardHeight'; export { default as withMessageSigningScreen } from './withMessageSigningScreen'; -export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; export { default as withOpenFamilyTabs } from './withOpenFamilyTabs'; export { default as withOpenInvestmentCards } from './withOpenInvestmentCards'; diff --git a/src/hoc/withNetInfo.js b/src/hoc/withNetInfo.js deleted file mode 100644 index 1ab24409561..00000000000 --- a/src/hoc/withNetInfo.js +++ /dev/null @@ -1,23 +0,0 @@ -import NetInfo from '@react-native-community/netinfo'; -import { compose, lifecycle, withState } from 'recompact'; - -const withNetInfo = ComponentToWrap => - compose( - withState('isConnected', 'setIsConnected', true), - lifecycle({ - componentDidMount() { - NetInfo.isConnected.addEventListener( - 'connectionChange', - this.props.setIsConnected - ); - }, - componentWillUnmount() { - NetInfo.isConnected.removeEventListener( - 'connectionChange', - this.props.setIsConnected - ); - }, - }) - )(ComponentToWrap); - -export default withNetInfo; diff --git a/src/hooks/index.js b/src/hooks/index.js new file mode 100644 index 00000000000..858107499ff --- /dev/null +++ b/src/hooks/index.js @@ -0,0 +1,4 @@ +export { default as useAppState } from './useAppState'; +export { default as useClipboard } from './useClipboard'; +export { default as useInternetStatus } from './useInternetStatus'; +export { default as usePrevious } from './usePrevious'; diff --git a/src/hooks/useAppState.js b/src/hooks/useAppState.js new file mode 100644 index 00000000000..e8ef6e5b259 --- /dev/null +++ b/src/hooks/useAppState.js @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; +import { AppState } from 'react-native'; + +export default function useAppState() { + const currentState = AppState.currentState; + const [appState, setAppState] = useState(currentState); + + function onChange(newState) { + setAppState(newState); + } + + useEffect(() => { + AppState.addEventListener('change', onChange); + + return () => { + AppState.removeEventListener('change', onChange); + }; + }); + + return appState; +} diff --git a/src/hooks/useClipboard.js b/src/hooks/useClipboard.js new file mode 100644 index 00000000000..5fd0bd43933 --- /dev/null +++ b/src/hooks/useClipboard.js @@ -0,0 +1,26 @@ +import { useCallback, useEffect, useState } from 'react'; +import { Clipboard } from 'react-native'; +import useAppState from './useAppState'; + +export default function useClipBoard() { + const appState = useAppState(); + const [data, updateClipboardData] = useState(''); + + async function updateClipboard() { + const content = await Clipboard.getString(); + updateClipboardData(content); + } + + useEffect(() => { + if (appState === 'active') { + updateClipboard(); + } + }, [appState]); + + const setString = useCallback(content => { + Clipboard.setString(content); + updateClipboardData(content); + }, []); + + return [data, setString]; +} diff --git a/src/hooks/useInternetStatus.js b/src/hooks/useInternetStatus.js new file mode 100644 index 00000000000..216d779a204 --- /dev/null +++ b/src/hooks/useInternetStatus.js @@ -0,0 +1,17 @@ +import { useNetInfo } from '@react-native-community/netinfo'; +import analytics from '@segment/analytics-react-native'; +import { useEffect } from 'react'; + +export default function useInternetStatus() { + const { isInternetReachable } = useNetInfo(); + + useEffect(() => { + if (isInternetReachable) { + analytics.track('Reconnected after offline'); + } else { + analytics.track('Offline / lost connection'); + } + }, [isInternetReachable]); + + return isInternetReachable; +} diff --git a/src/hooks/usePrevious.js b/src/hooks/usePrevious.js new file mode 100644 index 00000000000..ed46581cb01 --- /dev/null +++ b/src/hooks/usePrevious.js @@ -0,0 +1,11 @@ +import { useEffect, useRef } from 'react'; + +export default function usePrevious(value) { + const ref = useRef(); + + useEffect(() => { + ref.current = value; + }, [value]); + + return ref.current; +} diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index c87d2dd5c48..8fb508796a6 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -2,7 +2,6 @@ import analytics from '@segment/analytics-react-native'; import PropTypes from 'prop-types'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { KeyboardAvoidingView } from 'react-native'; -import { useClipboard } from 'react-native-hooks'; import { BorderlessButton } from 'react-native-gesture-handler'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; import { useNavigation } from 'react-navigation-hooks'; @@ -13,6 +12,7 @@ import { MultiLineInput } from '../components/inputs'; import { Centered, Column, Row, RowWithMargins } from '../components/layout'; import { LoadingOverlay } from '../components/modal'; import { Text } from '../components/text'; +import { useClipboard } from '../hooks'; import { sheetVerticalOffset } from '../navigation/transitions/effects'; import { borders, colors, padding, shadow } from '../styles'; import { isValidSeed as validateSeed } from '../helpers/validators'; diff --git a/src/screens/QRScannerScreen.js b/src/screens/QRScannerScreen.js index 0661191906f..24888abd0b3 100644 --- a/src/screens/QRScannerScreen.js +++ b/src/screens/QRScannerScreen.js @@ -1,8 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import DeviceInfo from 'react-native-device-info'; -import { onlyUpdateForKeys } from 'recompact'; -import styled from 'styled-components/primitives'; +import { useIsEmulator } from 'react-native-device-info'; +import { useSafeArea } from 'react-native-safe-area-context'; import { BubbleSheet } from '../components/bubble-sheet'; import { Button } from '../components/buttons'; import { BackButton, Header } from '../components/header'; @@ -13,20 +12,7 @@ import { WalletConnectList, } from '../components/walletconnect-list'; import { colors, position } from '../styles'; -import { safeAreaInsetValues } from '../utils'; - -const Container = styled(Centered)` - ${position.size('100%')}; - background-color: ${colors.black}; - overflow: hidden; -`; - -const QRScannerScreenHeader = styled(Header).attrs({ - justify: 'space-between', -})` - position: absolute; - top: 0; -`; +import { isNewValueForObjectPaths } from '../utils'; const QRScannerScreen = ({ enableScanning, @@ -40,52 +26,58 @@ const QRScannerScreen = ({ walletConnectorsByDappName, walletConnectorsCount, ...props -}) => ( - - - - - {DeviceInfo.isEmulator() && ( - - )} - - { + const { result: isEmulator } = useIsEmulator(); + const insets = useSafeArea(); + + return ( + - {walletConnectorsCount ? ( - - ) : ( - - )} - - -); + +
+ + {isEmulator && ( + + )} +
+ + {walletConnectorsCount ? ( + + ) : ( + + )} + + + ); +}; QRScannerScreen.propTypes = { enableScanning: PropTypes.bool, @@ -97,19 +89,17 @@ QRScannerScreen.propTypes = { onSheetLayout: PropTypes.func, sheetHeight: PropTypes.number, showSheet: PropTypes.bool, - showWalletConnectSheet: PropTypes.bool, walletConnectorsByDappName: PropTypes.arrayOf(PropTypes.object), walletConnectorsCount: PropTypes.number, }; -QRScannerScreen.defaultProps = { - showWalletConnectSheet: true, -}; +const arePropsEqual = (prev, next) => + !isNewValueForObjectPaths(prev, next, [ + 'enableScanning', + 'isCameraAuthorized', + 'isFocused', + 'sheetHeight', + 'walletConnectorsCount', + ]); -export default onlyUpdateForKeys([ - 'enableScanning', - 'isCameraAuthorized', - 'isFocused', - 'sheetHeight', - 'walletConnectorsCount', -])(QRScannerScreen); +export default React.memo(QRScannerScreen, arePropsEqual); diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 49328f65bdb..bf1d8813839 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import lang from 'i18n-js'; import { Animated } from 'react-native'; -import TouchID from 'react-native-touch-id'; import styled from 'styled-components'; import { Button, HoldToAuthorizeButton } from '../components/buttons'; import { RequestVendorLogoIcon } from '../components/coin-icon'; @@ -54,21 +53,10 @@ export default class TransactionConfirmationScreen extends PureComponent { }; state = { - biometryType: null, isAuthorizing: false, sendLongPressProgress: new Animated.Value(0), }; - componentDidMount() { - TouchID.isSupported() - .then(biometryType => { - this.setState({ biometryType }); - }) - .catch(() => { - this.setState({ biometryType: 'FaceID' }); - }); - } - componentWillUnmount() { this.state.sendLongPressProgress.stopAnimation(); } From 2eb1fd6ccfd99e0c5b6af0c1122ca74c8a46f4a5 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 11 Dec 2019 03:12:29 -0500 Subject: [PATCH 615/636] update biometric icon assets --- src/components/icons/Icon.js | 2 ++ src/components/icons/svg/FaceIdIcon.js | 5 +++-- src/components/icons/svg/PasscodeIcon.js | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/components/icons/svg/PasscodeIcon.js diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index 8015745bd1f..cd93193d9d7 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -25,6 +25,7 @@ import HandleIcon from './svg/HandleIcon'; import InboxIcon from './svg/InboxIcon'; import LockIcon from './svg/LockIcon'; import OfflineIcon from './svg/OfflineIcon'; +import PasscodeIcon from './svg/PasscodeIcon'; import ProgressIcon from './svg/ProgressIcon'; import SearchIcon from './svg/SearchIcon'; import SendIcon from './svg/SendIcon'; @@ -66,6 +67,7 @@ Icon.IconTypes = { inbox: InboxIcon, lock: LockIcon, offline: OfflineIcon, + passcode: PasscodeIcon, progress: ProgressIcon, search: SearchIcon, send: SendIcon, diff --git a/src/components/icons/svg/FaceIdIcon.js b/src/components/icons/svg/FaceIdIcon.js index bbab6d3c2a5..e8856c266b5 100644 --- a/src/components/icons/svg/FaceIdIcon.js +++ b/src/components/icons/svg/FaceIdIcon.js @@ -4,9 +4,10 @@ import Svg, { Path } from 'svgs'; import { colors } from '../../../styles'; const FaceIdIcon = ({ color, ...props }) => ( - + diff --git a/src/components/icons/svg/PasscodeIcon.js b/src/components/icons/svg/PasscodeIcon.js new file mode 100644 index 00000000000..b67e8226de8 --- /dev/null +++ b/src/components/icons/svg/PasscodeIcon.js @@ -0,0 +1,24 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import Svg, { Path } from 'svgs'; +import { colors } from '../../../styles'; + +const PasscodeIcon = ({ color, ...props }) => ( + + + +); + +PasscodeIcon.propTypes = { + color: PropTypes.string, +}; + +PasscodeIcon.defaultProps = { + color: colors.white, +}; + +export default PasscodeIcon; From 4b5a060ce4722c536dab604cf4c4b2934dc0cbfc Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 11 Dec 2019 03:14:41 -0500 Subject: [PATCH 616/636] patch react-native-keychain to detect user overrides --- package.json | 2 +- patches/react-native-keychain+4.0.3.patch | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 patches/react-native-keychain+4.0.3.patch diff --git a/package.json b/package.json index bd354d58eb4..f5ccfbc13e5 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", - "react-native-keychain": "4.0.1", + "react-native-keychain": "4.0.3", "react-native-languages": "^3.0.0", "react-native-level-fs": "^3.0.1", "react-native-linear-gradient": "^2.5.6", diff --git a/patches/react-native-keychain+4.0.3.patch b/patches/react-native-keychain+4.0.3.patch new file mode 100644 index 00000000000..7fa4f9a8ad3 --- /dev/null +++ b/patches/react-native-keychain+4.0.3.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m +index c4ad7e5..ada736b 100644 +--- a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m ++++ b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m +@@ -270,7 +270,7 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server + { + NSError *aerr = nil; + LAContext *context = [LAContext new]; +- BOOL canBeProtected = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&aerr]; ++ BOOL canBeProtected = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&aerr]; + + if (!aerr && canBeProtected) { + if (@available(iOS 11, *)) { From f0a4d721b24fd1e0ef72c47e07e9a6c44a0c46c3 Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 17 Dec 2019 00:49:34 -0500 Subject: [PATCH 617/636] Version bump to v1.2.2 (4) --- CHANGELOG.md | 2 +- ios/Podfile.lock | 46 +++++++++++++-------------- ios/Rainbow.xcodeproj/project.pbxproj | 8 ++--- package.json | 2 +- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f866a4d6df9..d61fe405bc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ### Changed -## [1.2.2-1](https://github.com/rainbow-me/rainbow/releases/tag/v1.2.2-1) +## [1.2.2-4](https://github.com/rainbow-me/rainbow/releases/tag/v1.2.2-4) ### Added * Uniswap support * Add to contacts diff --git a/ios/Podfile.lock b/ios/Podfile.lock index dd4896ebf94..5449fbe431e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -334,9 +334,7 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): - - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -674,8 +672,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 79ecc874031236eebb3e9e5ffc2141086e16e847 - FBReactNativeSpec: 5c88f1630d22de0aceaacc621c74240634db37eb + FBLazyVector: 2af25bce3a891b34fe16a791d2a06785ae5c45e1 + FBReactNativeSpec: 2fa33b58b0342284947ae6a3ec72cd3064eb022a Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -695,15 +693,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: 20d79da7f20b5928b80043b05080b816e802659e - RCTRequired: 9084bed4910a631f6b9e0adbd82861b1c6eb6114 - RCTTypeSafety: e57c1b42239672cbab98d41350603f54212490e8 - React: 3950154959c79f0003347cfb42d5bea280be85d2 - React-Core: 03c3b8d777397f1a11f91819f071ffa989a53a6d - React-CoreModules: 6d594e2bd581aca66519995401b7fdcce50fee1a - React-cxxreact: 386d1f74b37a901bc3a4a06ccad5e3b8bf11bccb - React-jsi: b916b09ecd0956a90109e1cd218883229998f273 - React-jsiexecutor: aecfc8420de9ace6ea78f3b50688b089c4401572 - React-jsinspector: 4b34c2a995846801442cb9f147a70deb6b0a11c9 + RCTRequired: cdcdc30117ff0f2a87941afee9ab36b8cb155c06 + RCTTypeSafety: 74f86cba43cfb997f63ca567197de68bd6631733 + React: 52ed0b0fa2f188c8ecb11b0029f0e43e566ae0b6 + React-Core: 33000f449ae1109977dfbf65da4fdd121e501f2c + React-CoreModules: 48e98b6534513f6f18633405a23038c785e7660a + React-cxxreact: d93c4c6cb5155ea4850165e0e788569853c0a64c + React-jsi: cfd0b406b39afc0fa005d274266b3f6a88fc9d12 + React-jsiexecutor: a3d288efafd9b40a42f7f33c106b18d0ef30e984 + React-jsinspector: 9fa0dfdabbb01fe17802ada871538f107c4ae329 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 9f79d18f91fc8c35d693f1846d84a8b9094bcc65 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -714,16 +712,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 7fa31ae3a9c06cefab8f31a269a9c88f51d59707 - React-RCTAnimation: af3ae170bd4000dcf971a6108aeb49a15073c10f - React-RCTBlob: 3865f337cdddd685e6ab1be89caddb404ba91beb - React-RCTImage: f8bf76d61bd6c0ad98ee23bec11a3ac7d293a03b - React-RCTLinking: 3cc931c5f39e77235e59f6cc5cf900443b35d5b0 - React-RCTNetwork: 95a254130217387eeb9c97dfcfbe55f75c9cb1a5 - React-RCTSettings: bcfffacfc88602532825c49ccb866cb4cc5e7174 - React-RCTText: be83a902438b819fdb9d99132132ecc8d3bcfcd7 - React-RCTVibration: e96a5af6ccc9ce1211ef2c72524f4975ad023d47 - ReactCommon: 531f5a47f0ab764f6ad72bf0e5680954801b5cdd + React-RCTActionSheet: d0845ce6ab6ebdec085a356e97d44e0425c05598 + React-RCTAnimation: 4e25b953efc9576cbdf934f36946c8761fce2f74 + React-RCTBlob: d9a088ec6fcaf32d92d841b4e5eff7aa3908f13b + React-RCTImage: 7efb39872c98b6bf94e7f7bdd7104f378e3aaf1d + React-RCTLinking: 0b79ffa83417cc1055d1e13a3890dad6a5172513 + React-RCTNetwork: 5b34de314d5188bba5b4c75f501b6975ae32b596 + React-RCTSettings: 2eff9bbddceb4c086c34208d0093144104dc7bbd + React-RCTText: f85a794628ccf639e161ecc91da9ec69b9e67f0a + React-RCTVibration: 21825611859898e0fac42e881d1ebe0400184900 + ReactCommon: b9d840903c3f5b49872d947ff0cefe144c4be575 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -753,7 +751,7 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 11364219d2b5158d2d16c9479f13f528534a6857 + Yoga: 2d949b4137f22f70fa3ddf4c9de43b0cc671a827 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 7698b0da717..f23fb2b243a 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -642,7 +642,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); - MARKETING_VERSION = 1.2.0; + MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -692,7 +692,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); - MARKETING_VERSION = 1.2.0; + MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -777,7 +777,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); - MARKETING_VERSION = 1.2.0; + MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -863,7 +863,7 @@ "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); - MARKETING_VERSION = 1.2.0; + MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", diff --git a/package.json b/package.json index 492510ffe81..32e2590d827 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.2.0-4", + "version": "1.2.2-4", "private": true, "scripts": { "android": "react-native run-android", From ee6c2ba5d19218a3f17214642e5a775658c9564f Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 17 Dec 2019 00:16:42 -0500 Subject: [PATCH 618/636] Attempt to optimize xcode build times by tweaking compiler settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follows advice laid out by @kelset in this gist 👉️ https://gist.github.com/kelset/2eb61161a68d1ab35337d1eaa9a05e78 --- ios/Podfile | 15 +- ios/Podfile.lock | 64 +++---- ios/Rainbow.xcodeproj/project.pbxproj | 24 +++ .../xcshareddata/xcschemes/Rainbow.xcscheme | 2 +- yarn.lock | 158 ++++++++---------- 5 files changed, 145 insertions(+), 118 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 88310e0fb60..5e727a73d3f 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,4 +1,4 @@ -platform :ios, '10.0' +platform :ios, '11.0' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' # Prevent Cocoapods from collecting stats, which adds time to each pod installation @@ -45,7 +45,18 @@ target 'Rainbow' do use_native_modules! - pod 'RNCPushNotificationIOS', :path => '../node_modules/@react-native-community/push-notification-ios' end + +post_install do |installer| + # Improve the Pods project setting to match with the ones we want to have for the project + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)'] + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'RCT_ENABLE_INSPECTOR=0' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'ENABLE_PACKAGER_CONNECTION=0' + end + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5449fbe431e..3a6fed86986 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -119,7 +119,7 @@ PODS: - nanopb/encode (= 0.3.9011) - nanopb/decode (0.3.9011) - nanopb/encode (0.3.9011) - - Protobuf (3.11.1) + - Protobuf (3.11.2) - RCTRequired (1000.0.0) - RCTTypeSafety (1000.0.0): - FBLazyVector (= 1000.0.0) @@ -285,13 +285,13 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.14.0): + - react-native-camera (3.15.0): - React - - react-native-camera/RCT (= 3.14.0) - - react-native-camera/RN (= 3.14.0) - - react-native-camera/RCT (3.14.0): + - react-native-camera/RCT (= 3.15.0) + - react-native-camera/RN (= 3.15.0) + - react-native-camera/RCT (3.15.0): - React - - react-native-camera/RN (3.14.0): + - react-native-camera/RN (3.15.0): - React - react-native-mail (4.1.0): - React @@ -334,7 +334,9 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -672,8 +674,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 2af25bce3a891b34fe16a791d2a06785ae5c45e1 - FBReactNativeSpec: 2fa33b58b0342284947ae6a3ec72cd3064eb022a + FBLazyVector: 9937910f2681d66c0d28631d16058aeec6b1d009 + FBReactNativeSpec: 84bac6a4bcb261924c1e19c60833d0916439dba9 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -692,18 +694,18 @@ SPEC CHECKSUMS: JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd - Protobuf: 20d79da7f20b5928b80043b05080b816e802659e - RCTRequired: cdcdc30117ff0f2a87941afee9ab36b8cb155c06 - RCTTypeSafety: 74f86cba43cfb997f63ca567197de68bd6631733 - React: 52ed0b0fa2f188c8ecb11b0029f0e43e566ae0b6 - React-Core: 33000f449ae1109977dfbf65da4fdd121e501f2c - React-CoreModules: 48e98b6534513f6f18633405a23038c785e7660a - React-cxxreact: d93c4c6cb5155ea4850165e0e788569853c0a64c - React-jsi: cfd0b406b39afc0fa005d274266b3f6a88fc9d12 - React-jsiexecutor: a3d288efafd9b40a42f7f33c106b18d0ef30e984 - React-jsinspector: 9fa0dfdabbb01fe17802ada871538f107c4ae329 + Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 + RCTRequired: 8261e5489a9c6a59fc1fb2ad37966ac8c76fd674 + RCTTypeSafety: cfe8ceac14dd07464e36cc5a6db4d60c89c8d0c4 + React: 1594d3f52fc5de51b1e55a521f93d07d68b814fb + React-Core: 4d1aba76c386522959c0d3d4e51ebb0554ad015f + React-CoreModules: 3a9d2a1c2df1936927163a19fdb0f2a5a13c1d76 + React-cxxreact: 06df23866978079cfb525c68bf8b59bb52884a4e + React-jsi: a9e632da28b1168e8b41e92cc69c5c88d1af4642 + React-jsiexecutor: 8e5e9d516a76c5ebbd5fa557a371de68f7b9d2b6 + React-jsinspector: beded58f6e205bc58a38a3c57ce87443d7d20848 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 9f79d18f91fc8c35d693f1846d84a8b9094bcc65 + react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 @@ -712,16 +714,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: d0845ce6ab6ebdec085a356e97d44e0425c05598 - React-RCTAnimation: 4e25b953efc9576cbdf934f36946c8761fce2f74 - React-RCTBlob: d9a088ec6fcaf32d92d841b4e5eff7aa3908f13b - React-RCTImage: 7efb39872c98b6bf94e7f7bdd7104f378e3aaf1d - React-RCTLinking: 0b79ffa83417cc1055d1e13a3890dad6a5172513 - React-RCTNetwork: 5b34de314d5188bba5b4c75f501b6975ae32b596 - React-RCTSettings: 2eff9bbddceb4c086c34208d0093144104dc7bbd - React-RCTText: f85a794628ccf639e161ecc91da9ec69b9e67f0a - React-RCTVibration: 21825611859898e0fac42e881d1ebe0400184900 - ReactCommon: b9d840903c3f5b49872d947ff0cefe144c4be575 + React-RCTActionSheet: 1c82cde015e743883cb80b6846949e0ce971d77c + React-RCTAnimation: 34328140d4295757f618aa997b0db8f7ca63f15d + React-RCTBlob: 954ec69326178e62b0425c1fc1662b046d473964 + React-RCTImage: b0d39340cb001dafbcb353d856ed3ab8ed842d2e + React-RCTLinking: 5ba5ceddfa18388cec61323f14653633d650bc1d + React-RCTNetwork: f36b6bc184f45f9c11b695ecf5dcc6bcf41c2714 + React-RCTSettings: 086ae71d112cf26d42435d3e98c8acccdfb678d6 + React-RCTText: 91ca55794c1eaf44e59ca6160fd561fec5697c49 + React-RCTVibration: 7f9ac599dfeb48f11e6ad50add4b09ac3f38366b + ReactCommon: bfd19eca47e6320353b895fa3eab70223efe6923 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -751,8 +753,8 @@ SPEC CHECKSUMS: TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 2d949b4137f22f70fa3ddf4c9de43b0cc671a827 + Yoga: f013762d91dd7bfd536dedce0d6c4a52ca0401cf -PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 +PODFILE CHECKSUM: e38b8f3a80d4f969b2bd4796967957156faf7531 COCOAPODS: 1.8.4 diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index f23fb2b243a..957ba4743bf 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -613,6 +613,7 @@ baseConfigurationReference = 66C5D39A1EDC48A6255FF83C /* Pods-Rainbow.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_OPTIMIZATION = time; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; @@ -620,11 +621,14 @@ COPY_PHASE_STRIP = YES; CURRENT_PROJECT_VERSION = 4; DEAD_CODE_STRIPPING = NO; + DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", ); + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_UNROLL_LOOPS = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -636,12 +640,14 @@ "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + LLVM_LTO = YES; MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", @@ -664,17 +670,21 @@ baseConfigurationReference = A671DF9861FA8D2C9A6FCB91 /* Pods-Rainbow.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_OPTIMIZATION = ""; CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "CHq9hB40PBZqHTxL-f-Wd_rK4anl1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_UNROLL_LOOPS = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -686,12 +696,14 @@ "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + LLVM_LTO = YES; MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", @@ -750,17 +762,21 @@ baseConfigurationReference = E93A96605FE51CFC31676801 /* Pods-Rainbow.staging.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_OPTIMIZATION = ""; CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = "Xf8eimmB0-W22TRNCwL9tZNO9xev1e7a8912-936f-4ce7-8505-32a075039f51"; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_UNROLL_LOOPS = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -771,12 +787,14 @@ "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + LLVM_LTO = YES; MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", @@ -836,17 +854,21 @@ baseConfigurationReference = 15B240C971E54630F3158955 /* Pods-Rainbow.localrelease.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_OPTIMIZATION = time; CLANG_ENABLE_MODULES = YES; CODEPUSH_KEY = ""; CODE_SIGN_ENTITLEMENTS = Rainbow/Rainbow.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_UNROLL_LOOPS = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Frameworks", @@ -857,12 +879,14 @@ "$(SRCROOT)/../node_modules/react-native-text-input-mask/ios/**", ); INFOPLIST_FILE = Rainbow/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", "\"$(SRCROOT)/Rainbow\"", ); + LLVM_LTO = YES; MARKETING_VERSION = 1.2.2; OTHER_LDFLAGS = ( "$(inherited)", diff --git a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme index 324638f15cb..a8093514504 100644 --- a/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme +++ b/ios/Rainbow.xcodeproj/xcshareddata/xcschemes/Rainbow.xcscheme @@ -3,7 +3,7 @@ LastUpgradeVersion = "0620" version = "1.3"> Date: Tue, 17 Dec 2019 00:51:23 -0500 Subject: [PATCH 619/636] Add Saint Fame $FAME token --- package.json | 2 +- src/references/token-overrides.json | 3 +++ src/references/uniswap-pairs.json | 6 ++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 492510ffe81..7cadca4c65e 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "punycode": "^1.4.1", "querystring-es3": "^0.2.1", "react": "16.11.0", - "react-coin-icon": "0.1.13", + "react-coin-icon": "0.1.14", "react-fast-compare": "^2.0.4", "react-native": "facebook/react-native", "react-native-actionsheet": "^2.4.2", diff --git a/src/references/token-overrides.json b/src/references/token-overrides.json index 5896e9c2c7e..a12605a1b50 100644 --- a/src/references/token-overrides.json +++ b/src/references/token-overrides.json @@ -141,6 +141,9 @@ "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359": { "name": "Sai" }, + "0x06f65b8cfcb13a9fe37d836fe9708da38ecb29b2": { + "name": "Saint Fame" + }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT" }, diff --git a/src/references/uniswap-pairs.json b/src/references/uniswap-pairs.json index ea251f5bfdf..b789cedfbd6 100644 --- a/src/references/uniswap-pairs.json +++ b/src/references/uniswap-pairs.json @@ -251,6 +251,12 @@ "decimals": 18, "exchangeAddress": "0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14" }, + "0x06f65b8cfcb13a9fe37d836fe9708da38ecb29b2": { + "name": "Saint Fame", + "symbol": "FAME", + "decimals": 18, + "exchangeAddress": "0x5e7907aC70b9a781365c72F2acEE96710bdA042e" + }, "0x4156D3342D5c385a87D264F90653733592000581": { "name": "SALT", "symbol": "SALT", From 7c5c4ab0a7958eecd93d9a3535f8b8bb3d0c1a8e Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 17 Dec 2019 00:15:09 -0500 Subject: [PATCH 620/636] Disable longPress in HoldToAuthorizeButtonIcon for certain biometryTypes Fixes RAI-119 https://linear.app/issue/RAI-119 --- ios/Podfile.lock | 82 ++++--- package.json | 2 +- src/App.js | 15 +- src/components/animations/ScaleInAnimation.js | 2 +- src/components/animations/index.js | 2 +- src/components/asset-list/AssetList.js | 14 +- .../HoldToAuthorizeButton.js | 184 ++++++++------- .../HoldToAuthorizeButtonIcon.js | 23 +- .../exchange/ConfirmExchangeButton.js | 23 +- src/components/icons/BiometryIcon.js | 78 +++---- src/components/icons/svg/PasscodeIcon.js | 27 ++- src/components/send/SendButton.js | 3 +- src/hooks/index.js | 1 + src/hooks/useAppState.js | 20 +- src/hooks/useBiometryType.js | 54 +++++ src/hooks/useClipboard.js | 6 +- src/hooks/useStorage.js | 33 +++ src/screens/TransactionConfirmationScreen.js | 22 +- src/utils/deviceUtils.js | 3 +- src/utils/haptics.js | 23 ++ src/utils/index.js | 1 + yarn.lock | 210 ++++++++---------- 22 files changed, 468 insertions(+), 360 deletions(-) create mode 100644 src/hooks/useBiometryType.js create mode 100644 src/hooks/useStorage.js create mode 100644 src/utils/haptics.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index dd4896ebf94..5c2b5a57570 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -119,7 +119,7 @@ PODS: - nanopb/encode (= 0.3.9011) - nanopb/decode (0.3.9011) - nanopb/encode (0.3.9011) - - Protobuf (3.11.1) + - Protobuf (3.11.2) - RCTRequired (1000.0.0) - RCTTypeSafety (1000.0.0): - FBLazyVector (= 1000.0.0) @@ -285,17 +285,17 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.14.0): + - react-native-camera (3.15.0): - React - - react-native-camera/RCT (= 3.14.0) - - react-native-camera/RN (= 3.14.0) - - react-native-camera/RCT (3.14.0): + - react-native-camera/RCT (= 3.15.0) + - react-native-camera/RN (= 3.15.0) + - react-native-camera/RCT (3.15.0): - React - - react-native-camera/RN (3.14.0): + - react-native-camera/RN (3.15.0): - React - react-native-mail (4.1.0): - React - - react-native-netinfo (4.7.0): + - react-native-netinfo (5.0.0): - React - react-native-randombytes (3.5.3): - React @@ -380,7 +380,7 @@ PODS: - React - RNCPushNotificationIOS (1.0.3): - React - - RNDeviceInfo (2.3.2): + - RNDeviceInfo (5.3.1): - React - RNFastImage (7.0.2): - React @@ -402,7 +402,7 @@ PODS: - RNGestureHandler (1.5.2): - React - RNInputMask (4.1.0) - - RNKeychain (4.0.1): + - RNKeychain (4.0.3): - React - RNLanguages (3.0.2): - React @@ -419,7 +419,7 @@ PODS: - Sentry (~> 4.4.0) - RNStoreReview (0.1.5): - React - - RNSVG (9.13.3): + - RNSVG (9.13.6): - React - SDWebImage (5.4.0): - SDWebImage/Core (= 5.4.0) @@ -437,8 +437,6 @@ PODS: - React - ToolTipMenu (5.2.1): - React - - TouchID (4.4.1): - - React - Yoga (1.14.0) DEPENDENCIES: @@ -507,7 +505,6 @@ DEPENDENCIES: - SRSRadialGradient (from `../node_modules/react-native-radial-gradient/ios`) - TcpSockets (from `../node_modules/react-native-tcp`) - ToolTipMenu (from `../node_modules/react-native-tooltip`) - - TouchID (from `../node_modules/react-native-touch-id`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -660,8 +657,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-tcp" ToolTipMenu: :path: "../node_modules/react-native-tooltip" - TouchID: - :path: "../node_modules/react-native-touch-id" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -674,8 +669,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 79ecc874031236eebb3e9e5ffc2141086e16e847 - FBReactNativeSpec: 5c88f1630d22de0aceaacc621c74240634db37eb + FBLazyVector: 6fdbec96876def36649fbd37a79bb66c2ca0f934 + FBReactNativeSpec: 35aa98e7b8521d74f3ea9a7f9a5a84dd8a02a478 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -694,49 +689,49 @@ SPEC CHECKSUMS: JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd - Protobuf: 20d79da7f20b5928b80043b05080b816e802659e - RCTRequired: 9084bed4910a631f6b9e0adbd82861b1c6eb6114 - RCTTypeSafety: e57c1b42239672cbab98d41350603f54212490e8 - React: 3950154959c79f0003347cfb42d5bea280be85d2 - React-Core: 03c3b8d777397f1a11f91819f071ffa989a53a6d - React-CoreModules: 6d594e2bd581aca66519995401b7fdcce50fee1a - React-cxxreact: 386d1f74b37a901bc3a4a06ccad5e3b8bf11bccb - React-jsi: b916b09ecd0956a90109e1cd218883229998f273 - React-jsiexecutor: aecfc8420de9ace6ea78f3b50688b089c4401572 - React-jsinspector: 4b34c2a995846801442cb9f147a70deb6b0a11c9 + Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 + RCTRequired: eeebccb8cdeb32a92cfd75492800cf905de36916 + RCTTypeSafety: 0fcc89877b56727b00149aedda51bf4502982e13 + React: cb9c930b74a87600eeaa019554435741e35384bf + React-Core: 8c1fcef647f4d852b7ef158db967734efe40f552 + React-CoreModules: 0cddf8228068e4fdee11c5fe5d41e25f7de1b00e + React-cxxreact: 7bb2f46f90043160f02f97660845ae8bfe9ad015 + React-jsi: 4c2a52ce4e8169b3e9b897d3bd22c042ffbae558 + React-jsiexecutor: c02c74b564cb3f89ac1f56720f43df3fb58575d0 + React-jsinspector: fd153d75c557b4b1670601069e13f704ba80185e react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 9f79d18f91fc8c35d693f1846d84a8b9094bcc65 + react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 - react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 + react-native-netinfo: 841c2a83fe7df998fed56fd48b73229f17a5aa5b react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 7fa31ae3a9c06cefab8f31a269a9c88f51d59707 - React-RCTAnimation: af3ae170bd4000dcf971a6108aeb49a15073c10f - React-RCTBlob: 3865f337cdddd685e6ab1be89caddb404ba91beb - React-RCTImage: f8bf76d61bd6c0ad98ee23bec11a3ac7d293a03b - React-RCTLinking: 3cc931c5f39e77235e59f6cc5cf900443b35d5b0 - React-RCTNetwork: 95a254130217387eeb9c97dfcfbe55f75c9cb1a5 - React-RCTSettings: bcfffacfc88602532825c49ccb866cb4cc5e7174 - React-RCTText: be83a902438b819fdb9d99132132ecc8d3bcfcd7 - React-RCTVibration: e96a5af6ccc9ce1211ef2c72524f4975ad023d47 - ReactCommon: 531f5a47f0ab764f6ad72bf0e5680954801b5cdd + React-RCTActionSheet: 6cb962c7955837e9f3db3580039d1f539410716c + React-RCTAnimation: ade24eb32b88f5311618dd2f4ce06fa15e8c348f + React-RCTBlob: b9957b715bf6079991fc372d9caca3ff3ddb328a + React-RCTImage: 218535c10986a203a5f9bbd4ad30db06879edcb0 + React-RCTLinking: 9bbfcedf6c7040fc356150b9d6986302f0d084d8 + React-RCTNetwork: 9a8bdba7373b0dfdaab3c51a2b36aafa364e27d8 + React-RCTSettings: 7ed52fb20bc45c89384ed2c094ecdb456cce8051 + React-RCTText: 4bb3b55897e080f36caa155df65a426d095493b2 + React-RCTVibration: 7aee713aa2e101aa32015aac1997269b10617f00 + ReactCommon: d4ffbab7d574e645ab78c6edb8e1ac1ac6ab338f ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNCPushNotificationIOS: 83ec11fe19d4ea9e32cc339d8e7d2cc3c88f543e - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 + RNDeviceInfo: 6f20764111df002b4484f90cbe0a861be29bcc6c RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFBApp: 5b215aacc09105a1761de31b9a0eb2abcce06253 RNFBCrashlytics: 0469cb96b00904e0c9604b9636d8eeab31115b08 RNFBMessaging: be0b936394416ec5503add603f2c0a641c353063 RNGestureHandler: 946a7691e41df61e2c4b1884deab41a4cdc3afff RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 - RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 + RNKeychain: f5783613aa3095af63345ddb9626a729bd4a3897 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 @@ -744,7 +739,7 @@ SPEC CHECKSUMS: RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 RNSentry: b63ba6a29ee142b5c3221896be8ff6cda587e03f RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c + RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 Sentry: 14bdd673870e8cf64932b149fad5bbbf39a9b390 @@ -752,8 +747,7 @@ SPEC CHECKSUMS: SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: 11364219d2b5158d2d16c9479f13f528534a6857 + Yoga: ee9d98c1a44748e5cbecc5935a800fb505a04f76 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/package.json b/package.json index f5ccfbc13e5..9f7814dd884 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "software-mansion/react-native-reanimated", - "react-native-redash": "mikedemarais/react-native-redash#transitions", + "react-native-redash": "^9.0.0", "react-native-safe-area-context": "^0.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", diff --git a/src/App.js b/src/App.js index 0ade912c184..d8c96be2de7 100644 --- a/src/App.js +++ b/src/App.js @@ -16,6 +16,7 @@ import { } from 'react-native-dotenv'; // eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; // eslint-disable-next-line import/no-unresolved import { useScreens } from 'react-native-screens'; import { connect, Provider } from 'react-redux'; @@ -156,12 +157,14 @@ class App extends Component { Navigation.setTopLevelNavigator(navigatorRef); render = () => ( - - - - - - + + + + + + + + ); } diff --git a/src/components/animations/ScaleInAnimation.js b/src/components/animations/ScaleInAnimation.js index 0ae38f051f9..c52ce4c1cbd 100644 --- a/src/components/animations/ScaleInAnimation.js +++ b/src/components/animations/ScaleInAnimation.js @@ -8,10 +8,10 @@ import { interpolate } from './procs'; const ScaleInAnimation = ({ range, scaleTo, style, value, ...props }) => ( - isEmpty ? ( +}) => { + const insets = useSafeArea(); + + return isEmpty ? ( ); +}; AssetList.propTypes = { fetchData: PropTypes.func.isRequired, diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js index 55054e54c1b..9adce36645a 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js @@ -5,18 +5,21 @@ import { State, TapGestureHandler, } from 'react-native-gesture-handler'; -import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { withProps } from 'recompact'; import styled from 'styled-components/primitives'; +import { useBiometryType, BiometryTypes } from '../../../hooks'; import { colors, padding } from '../../../styles'; +import { haptics } from '../../../utils'; import InnerBorder from '../../InnerBorder'; import { Centered } from '../../layout'; import { ShadowStack } from '../../shadow-stack'; import { Text } from '../../text'; import HoldToAuthorizeButtonIcon from './HoldToAuthorizeButtonIcon'; -const { divide, multiply, timing, Value, View } = Animated; +const { divide, multiply, proc, timing, Value } = Animated; + +const { ACTIVE, BEGAN, END } = State; const ButtonBorderRadius = 30; const ButtonHeight = 59; @@ -38,7 +41,8 @@ const ButtonShadows = { ], }; -const progressDurationMs = 500; // @christian approves +const buttonScaleDurationMs = 150; +const longPressProgressDurationMs = 500; // @christian approves const Content = styled(Centered)` ${padding(15)}; @@ -56,24 +60,21 @@ const Title = withProps({ weight: 'semibold', })(Text); -const buildAnimation = (value, options) => { - const { duration = 150, isInteraction = false, toValue } = options; - - return timing(value, { +const animate = (value, { duration = buttonScaleDurationMs, toValue }) => + timing(value, { duration, easing: Easing.inOut(Easing.ease), - isInteraction, toValue, - useNativeDriver: true, }); -}; -const calculateReverseDuration = progess => - multiply(divide(progess, 100), progressDurationMs); +const calculateReverseDuration = proc(longPressProgress => + multiply(divide(longPressProgress, 100), longPressProgressDurationMs) +); -export default class HoldToAuthorizeButton extends PureComponent { +class HoldToAuthorizeButton extends PureComponent { static propTypes = { backgroundColor: PropTypes.string, + biometryType: PropTypes.string, children: PropTypes.any, disabled: PropTypes.bool, disabledBackgroundColor: PropTypes.string, @@ -81,7 +82,6 @@ export default class HoldToAuthorizeButton extends PureComponent { isAuthorizing: PropTypes.bool, label: PropTypes.string, onLongPress: PropTypes.func.isRequired, - onPress: PropTypes.func, shadows: PropTypes.arrayOf(PropTypes.array), style: PropTypes.object, theme: PropTypes.oneOf(['light', 'dark']), @@ -103,105 +103,92 @@ export default class HoldToAuthorizeButton extends PureComponent { } }; - scale = new Value(1); - - tapHandlerState = 1; + buttonScale = new Value(1); - animation = new Value(0); + longPressProgress = new Value(0); onFinishAuthorizing = () => { - const { disabled } = this.props; - if (!disabled) { - buildAnimation(this.animation, { - duration: calculateReverseDuration(this.animation), - isInteraction: true, + if (!this.props.disabled) { + animate(this.longPressProgress, { + duration: calculateReverseDuration(this.longPressProgress), toValue: 0, }).start(() => this.setState({ isAuthorizing: false })); } }; - onTapChange = ({ nativeEvent: { state } }) => { - const { disabled, onPress } = this.props; - - this.tapHandlerState = state; - - if (state === State.BEGAN) { - if (disabled) { - ReactNativeHapticFeedback.trigger('notificationWarning'); - buildAnimation(this.scale, { toValue: 0.99 }).start(() => { - buildAnimation(this.scale, { toValue: 1 }).start(); - }); - } else { - buildAnimation(this.scale, { toValue: 0.97 }).start(); - buildAnimation(this.animation, { - duration: progressDurationMs, - toValue: 100, - }).start(); - } - } else if (!disabled && state === State.ACTIVE) { - if (onPress) { - onPress(); - } - } else if (!disabled && state === State.END) { - buildAnimation(this.scale, { toValue: 1 }).start(); - buildAnimation(this.animation, { - duration: calculateReverseDuration(this.animation), - isInteraction: true, - toValue: 0, - }).start(); + handlePress = () => { + if (this.props.onLongPress) { + this.props.onLongPress(); } }; - onLongPressChange = ({ nativeEvent }) => { - const { disabled, onLongPress } = this.props; + onLongPressChange = ({ nativeEvent: { state } }) => { + const { disabled, enableLongPress } = this.props; - if (!disabled && nativeEvent.state === State.ACTIVE) { - ReactNativeHapticFeedback.trigger('notificationSuccess'); + if (state === ACTIVE && !disabled && enableLongPress) { + haptics.notificationSuccess(); - buildAnimation(this.scale, { - isInteraction: true, + animate(this.buttonScale, { toValue: 1, }).start(() => this.setState({ isAuthorizing: true })); - if (onLongPress) { - onLongPress(); - } + this.handlePress(); } }; - renderContent = () => { - const { children, disabled, hideBiometricIcon, label } = this.props; - - const { isAuthorizing } = this.state; + onTapChange = ({ nativeEvent: { state } }) => { + const { disabled, enableLongPress } = this.props; - if (children) { - return children; + if (disabled) { + if (state === BEGAN) { + animate(this.buttonScale, { toValue: 0.99 }).start(() => { + haptics.notificationWarning(); + animate(this.buttonScale, { toValue: 1 }).start(); + }); + } + } else { + if (state === ACTIVE) { + if (!enableLongPress) { + this.handlePress(); + } + } else if (state === BEGAN) { + animate(this.buttonScale, { toValue: 0.97 }).start(); + if (enableLongPress) { + animate(this.longPressProgress, { + duration: longPressProgressDurationMs, + toValue: 100, + }).start(); + } + } else if (state === END) { + animate(this.buttonScale, { toValue: 1 }).start(); + if (enableLongPress) { + animate(this.longPressProgress, { + duration: calculateReverseDuration(this.longPressProgress), + toValue: 0, + }).start(); + } + } } - - return ( - - {!disabled && !hideBiometricIcon && ( - - )} - {isAuthorizing ? 'Authorizing' : label} - - ); }; render() { const { backgroundColor, + biometryType, + children, disabled, disabledBackgroundColor, + enableLongPress, + hideBiometricIcon, + label, shadows, style, theme, ...props } = this.props; + const { isAuthorizing } = this.state; + let bgColor = backgroundColor; if (disabled) { bgColor = disabledBackgroundColor || ButtonDisabledBgColor[theme]; @@ -210,12 +197,13 @@ export default class HoldToAuthorizeButton extends PureComponent { return ( - - {this.renderContent()} + {children || ( + + {!disabled && !hideBiometricIcon && ( + + )} + {isAuthorizing ? 'Authorizing' : label} + + )} - + ); } } + +const HoldToAuthorizeButtonWithBiometrics = ({ label, ...props }) => { + const biometryType = useBiometryType(); + const enableLongPress = + biometryType === BiometryTypes.FaceID || + biometryType === BiometryTypes.none; + + return ( + + ); +}; + +export default React.memo(HoldToAuthorizeButtonWithBiometrics); diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js index 50521a3b95e..997e436b2e5 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js @@ -9,20 +9,19 @@ import { Centered } from '../../layout'; const { cond, divide, greaterThan } = Animated; -const BiometryIconSize = 31; -const IconContainer = styled(Centered)` - ${position.size(BiometryIconSize)}; - left: 19; - margin-bottom: 2; +const Container = styled(Centered)` + ${position.size(31)}; + left: 15; position: absolute; `; -const HoldToAuthorizeButtonIcon = ({ animatedValue }) => ( - - - +const HoldToAuthorizeButtonIcon = ({ animatedValue, biometryType }) => ( + + + ( > - + ); HoldToAuthorizeButtonIcon.propTypes = { animatedValue: PropTypes.object, + biometryType: PropTypes.string, }; -export default React.memo(HoldToAuthorizeButtonIcon); +const arePropsEqual = (prev, next) => prev.biometryType === next.biometryType; +export default React.memo(HoldToAuthorizeButtonIcon, arePropsEqual); diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 111e9d12435..c62e042cd16 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -4,6 +4,12 @@ import { colors } from '../../styles'; import { HoldToAuthorizeButton, UnlockingSpinner } from '../buttons'; import { SlippageWarningTheshold } from './SlippageWarning'; +const ConfirmExchangeButtonShadows = [ + [0, 3, 5, colors.black, 0.2], + [0, 6, 10, colors.black, 0.14], + [0, 1, 18, colors.black, 0.12], +]; + const ConfirmExchangeButton = ({ disabled, inputCurrencyName, @@ -36,21 +42,12 @@ const ConfirmExchangeButton = ({ hideBiometricIcon={isUnlockingAsset || !isAssetApproved} isAuthorizing={isAuthorizing} label={label} - onLongPress={isAssetApproved ? onSubmit : null} - onPress={isAssetApproved ? null : onUnlockAsset} - shadows={[ - [0, 3, 5, colors.black, 0.2], - [0, 6, 10, colors.black, 0.14], - [0, 1, 18, colors.black, 0.12], - ]} + onLongPress={isAssetApproved ? onSubmit : onUnlockAsset} + shadows={ConfirmExchangeButtonShadows} theme="dark" {...props} > - {isUnlockingAsset ? ( - - ) : ( - undefined - )} + {isUnlockingAsset && } ); }; @@ -68,4 +65,4 @@ ConfirmExchangeButton.propTypes = { timeRemaining: PropTypes.string, }; -export default ConfirmExchangeButton; +export default React.memo(ConfirmExchangeButton); diff --git a/src/components/icons/BiometryIcon.js b/src/components/icons/BiometryIcon.js index 4b292f7719a..7950d91770d 100644 --- a/src/components/icons/BiometryIcon.js +++ b/src/components/icons/BiometryIcon.js @@ -1,61 +1,41 @@ import PropTypes from 'prop-types'; import React from 'react'; -import TouchID from 'react-native-touch-id'; -import stylePropType from 'react-style-proptype'; -import { - compose, - lifecycle, - omitProps, - onlyUpdateForKeys, - withHandlers, - withProps, - withState, -} from 'recompact'; import { position } from '../../styles'; import { Centered } from '../layout'; import Icon from './Icon'; -const DefaultBiometryType = 'FaceID'; +const BiometryTypeStyles = { + faceid: { + ...position.sizeAsObject(27), + marginBottom: 2, + marginLeft: 4, + }, + passcode: { + height: 25, + marginBottom: 4, + marginLeft: 4, + width: 18, + }, + touchid: { + ...position.sizeAsObject(31), + marginBottom: 1, + }, +}; -const BiometryIcon = ({ isFaceID, size, style, ...props }) => ( - - - -); +const BiometryIcon = ({ biometryType, ...props }) => { + if (!biometryType || biometryType === 'none') return null; + const type = biometryType.toLowerCase(); -BiometryIcon.propTypes = { - isFaceID: PropTypes.bool, - size: PropTypes.number, - style: stylePropType, + return ( + + + + ); }; -BiometryIcon.defaultProps = { - size: 34, +BiometryIcon.propTypes = { + biometryType: PropTypes.string, }; -export default compose( - withState('biometryType', 'setBiometryType', DefaultBiometryType), - withHandlers({ - setBiometryType: ({ setBiometryType }) => biometryType => { - setBiometryType(biometryType || DefaultBiometryType); - }, - }), - lifecycle({ - componentDidMount() { - TouchID.isSupported().then(this.props.setBiometryType); - }, - }), - withProps(({ biometryType }) => ({ - isFaceID: biometryType === DefaultBiometryType, - })), - onlyUpdateForKeys(['biometryType', 'size']), - omitProps('biometryType', 'setBiometryType') -)(BiometryIcon); +const arePropsEqual = (prev, next) => prev.biometryType === next.biometryType; +export default React.memo(BiometryIcon, arePropsEqual); diff --git a/src/components/icons/svg/PasscodeIcon.js b/src/components/icons/svg/PasscodeIcon.js index b67e8226de8..879f179b4df 100644 --- a/src/components/icons/svg/PasscodeIcon.js +++ b/src/components/icons/svg/PasscodeIcon.js @@ -1,15 +1,28 @@ import PropTypes from 'prop-types'; import React from 'react'; -import Svg, { Path } from 'svgs'; +import Svg, { Defs, G, LinearGradient, Path, Stop } from 'svgs'; import { colors } from '../../../styles'; const PasscodeIcon = ({ color, ...props }) => ( - - + + + + + + + + + + + + + ); diff --git a/src/components/send/SendButton.js b/src/components/send/SendButton.js index f35a6318167..92cd8e40adb 100644 --- a/src/components/send/SendButton.js +++ b/src/components/send/SendButton.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { pure } from 'recompose'; import { HoldToAuthorizeButton } from '../buttons'; const SendButton = ({ @@ -46,4 +45,4 @@ SendButton.propTypes = { onLongPress: PropTypes.func, }; -export default pure(SendButton); +export default React.memo(SendButton); diff --git a/src/hooks/index.js b/src/hooks/index.js index 858107499ff..3264f26a0c8 100644 --- a/src/hooks/index.js +++ b/src/hooks/index.js @@ -2,3 +2,4 @@ export { default as useAppState } from './useAppState'; export { default as useClipboard } from './useClipboard'; export { default as useInternetStatus } from './useInternetStatus'; export { default as usePrevious } from './usePrevious'; +export { default as useBiometryType, BiometryTypes } from './useBiometryType'; diff --git a/src/hooks/useAppState.js b/src/hooks/useAppState.js index e8ef6e5b259..f2966cad7c2 100644 --- a/src/hooks/useAppState.js +++ b/src/hooks/useAppState.js @@ -1,9 +1,17 @@ import { useEffect, useState } from 'react'; import { AppState } from 'react-native'; +import usePrevious from './usePrevious'; + +const AppStateTypes = { + active: 'active', + background: 'background', + inactive: 'inactive', +}; export default function useAppState() { const currentState = AppState.currentState; const [appState, setAppState] = useState(currentState); + const prevAppState = usePrevious(appState); function onChange(newState) { setAppState(newState); @@ -11,11 +19,13 @@ export default function useAppState() { useEffect(() => { AppState.addEventListener('change', onChange); - - return () => { - AppState.removeEventListener('change', onChange); - }; + return () => AppState.removeEventListener('change', onChange); }); - return appState; + return { + appState, + justBecameActive: + appState === AppStateTypes.active && + prevAppState !== AppStateTypes.active, + }; } diff --git a/src/hooks/useBiometryType.js b/src/hooks/useBiometryType.js new file mode 100644 index 00000000000..42b5a7b5993 --- /dev/null +++ b/src/hooks/useBiometryType.js @@ -0,0 +1,54 @@ +import { isNil } from 'lodash'; +import { useEffect } from 'react'; +import { isPinOrFingerprintSet } from 'react-native-device-info'; +import * as Keychain from 'react-native-keychain'; +import useAppState from './useAppState'; +import usePrevious from './usePrevious'; +import useStorage from './useStorage'; + +export const BiometryTypes = { + FaceID: 'FaceID', + none: 'none', + passcode: 'passcode', + TouchID: 'TouchID', +}; + +export default function useBiometryType() { + const { justBecameActive } = useAppState(); + const [biometryType, setBiometryType] = useStorage( + 'biometryType', + BiometryTypes.none + ); + const prevBiometricType = usePrevious(biometryType); + + useEffect(() => { + let mounted = true; + + const getSupportedBiometryType = async () => { + let type = await Keychain.getSupportedBiometryType(); + + if (isNil(type)) { + // 💡️ When `getSupportedBiometryType` returns `null` it can mean either: + // A) the user has no device passcode/biometrics at all + // B) the user has gone into Settings and disabled biometrics specifically for Rainbow + type = await isPinOrFingerprintSet().then(isPinOrFingerprintSet => + isPinOrFingerprintSet ? BiometryTypes.passcode : BiometryTypes.none + ); + } + + if (mounted && type !== prevBiometricType) { + setBiometryType(type); + } + }; + + if (justBecameActive) { + getSupportedBiometryType(); + } + + return () => { + mounted = false; + }; + }, [justBecameActive, prevBiometricType, setBiometryType]); + + return biometryType; +} diff --git a/src/hooks/useClipboard.js b/src/hooks/useClipboard.js index 5fd0bd43933..07d9e04fb24 100644 --- a/src/hooks/useClipboard.js +++ b/src/hooks/useClipboard.js @@ -3,7 +3,7 @@ import { Clipboard } from 'react-native'; import useAppState from './useAppState'; export default function useClipBoard() { - const appState = useAppState(); + const { justBecameActive } = useAppState(); const [data, updateClipboardData] = useState(''); async function updateClipboard() { @@ -12,10 +12,10 @@ export default function useClipBoard() { } useEffect(() => { - if (appState === 'active') { + if (justBecameActive) { updateClipboard(); } - }, [appState]); + }, [justBecameActive]); const setString = useCallback(content => { Clipboard.setString(content); diff --git a/src/hooks/useStorage.js b/src/hooks/useStorage.js new file mode 100644 index 00000000000..ddd4564626a --- /dev/null +++ b/src/hooks/useStorage.js @@ -0,0 +1,33 @@ +import AsyncStorage from '@react-native-community/async-storage'; +import { useEffect, useState } from 'react'; + +export default function useAsyncStorage(key, defaultValue) { + const [state, setState] = useState({ + hydrated: false, + storageValue: defaultValue, + }); + + const { hydrated, storageValue } = state; + + async function pullFromStorage() { + const fromStorage = await AsyncStorage.getItem(key); + let value = defaultValue; + if (fromStorage) { + value = JSON.parse(fromStorage); + } + setState({ hydrated: true, storageValue: value }); + } + + async function updateStorage(newValue) { + setState({ hydrated: true, storageValue: newValue }); + const stringifiedValue = JSON.stringify(newValue); + await AsyncStorage.setItem(key, stringifiedValue); + } + + useEffect(() => { + pullFromStorage(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return [storageValue, updateStorage, hydrated]; +} diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index bf1d8813839..f77cb8d96ec 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -97,15 +97,19 @@ export default class TransactionConfirmationScreen extends PureComponent { } }; - renderSendButton = () => ( - - ); + renderSendButton = () => { + const { method } = this.props; + const { isAuthorizing } = this.state; + const label = `Hold to ${method === SEND_TRANSACTION ? 'Send' : 'Sign'}`; + + return ( + + ); + }; requestHeader = () => { const { method } = this.props; diff --git a/src/utils/deviceUtils.js b/src/utils/deviceUtils.js index e9abf291a0c..c79d9a9197c 100644 --- a/src/utils/deviceUtils.js +++ b/src/utils/deviceUtils.js @@ -1,7 +1,6 @@ -import { pick } from 'lodash'; import { Dimensions } from 'react-native'; -const { height, width } = pick(Dimensions.get('window'), ['height', 'width']); +const { height, width } = Dimensions.get('window'); const deviceUtils = {}; diff --git a/src/utils/haptics.js b/src/utils/haptics.js new file mode 100644 index 00000000000..50bcdda95da --- /dev/null +++ b/src/utils/haptics.js @@ -0,0 +1,23 @@ +import { keys, map } from 'lodash'; +import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; +import reduceArrayToObject from './reduceArrayToObject'; + +export const HapticFeedbackTypes = { + impactHeavy: 'impactHeavy', + impactLight: 'impactLight', + impactMedium: 'impactMedium', + notificationError: 'notificationError', + notificationSuccess: 'notificationSuccess', + notificationWarning: 'notificationWarning', + selection: 'selection', +}; + +const hapticToTrigger = haptic => ({ + [haptic]: () => ReactNativeHapticFeedback.trigger(haptic), +}); + +const haptics = reduceArrayToObject( + map(keys(HapticFeedbackTypes), hapticToTrigger) +); + +export default haptics; diff --git a/src/utils/index.js b/src/utils/index.js index 1eac30d1a8b..a89fef6f8df 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -6,6 +6,7 @@ export { default as dimensionsPropType } from './dimensionsPropType'; export { default as directionPropType } from './directionPropType'; export { default as ethereumUtils } from './ethereumUtils'; export { default as gasUtils } from './gas'; +export { default as haptics } from './haptics'; export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForObjectPaths } from './isNewValueForObjectPaths'; diff --git a/yarn.lock b/yarn.lock index f6798315d5e..4a51fb11908 100644 --- a/yarn.lock +++ b/yarn.lock @@ -983,7 +983,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.6.2.tgz#a19ca7149c4dfe8216f2330e6b1ebfe2d075ef92" integrity sha512-EJGsbrHubK1mGxPjWB74AaHAd5m9I+Gg2RRPZzMK6org7QOU9WOBnIMFqoeVto3hKOaEPlk8NV74H6G34/2pZQ== -"@react-native-community/blur@^3.3.1": +"@react-native-community/blur@^3.4.1": version "3.4.1" resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.4.1.tgz#dec04c7d60dd6a4fa7e3af3506feefec804728d0" integrity sha512-XhbS230J7BGuoEamjPFZ5jUWDOW16y+vD0Soyq9Iv1qL8R47esGl54bnfUSMH10WhNXrQzvPxkMzap+ONHpE2w== @@ -1084,10 +1084,10 @@ resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.5.tgz#25421be6cd943a4b1660b62cfbcd45be8891462c" integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== -"@react-native-community/netinfo@^4.6.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.7.0.tgz#7482d36836cac69d0a0ae25581f65bc472639930" - integrity sha512-a/sDB+AsLEUNmhAUlAaTYeXKyQdFGBUfatqKkX5jluBo2CB3OAuTHfm7rSjcaLB9EmG5iSq3fOTpync2E7EYTA== +"@react-native-community/netinfo@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.0.0.tgz#c8708558c9a116c138a43bed4bb0b4af85f111bc" + integrity sha512-MDvQ+jh9P1S8/CvxLyDqWFNc31oL5a2UkVtOyGFslLmxbO3Q4h/xFPM+b2NJ97GvQAsdhL18EpOWVu1AXodeFw== "@react-native-community/push-notification-ios@^1.0.3": version "1.0.3" @@ -1470,9 +1470,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.17.tgz#191b71e7f4c325ee0fb23bc4a996477d92b8c39b" - integrity sha512-Is+l3mcHvs47sKy+afn2O1rV4ldZFU7W8101cNlOd+MRbjM4Onida8jSZnJdTe/0Pcf25g9BNIUsuugmE6puHA== + version "12.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.18.tgz#8d16634797d63c2af5bc647ce879f8de20b56469" + integrity sha512-DBkZuIMFuAfjJHiunyRc+aNvmXYNwV1IPMgGKGlwCp6zh6MKrVtmvjSWK/axWcD25KJffkXgkfvFra8ndenXAw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2027,7 +2027,7 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-limiter@^1.0.0, async-limiter@~1.0.0: +async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== @@ -2347,6 +2347,13 @@ bignumber.js@^9.0.0: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + bl@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/bl/-/bl-0.8.2.tgz#c9b6bca08d1bc2ea00fc8afb4f1a5fd1e1c66e4e" @@ -2705,9 +2712,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001015: - version "1.0.30001015" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz#15a7ddf66aba786a71d99626bc8f2b91c6f0f5f0" - integrity sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ== + version "1.0.30001016" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001016.tgz#16ea48d7d6e8caf3cad3295c2d746fe38c4e7f66" + integrity sha512-yYQ2QfotceRiH4U+h1Us86WJXtVHDmy3nEKIdYPsZCYnOV5/tMgGbmoIlrMzmh2VXlproqYtVaKeGDBkMZifFA== capture-exit@^2.0.0: version "2.0.0" @@ -3908,22 +3915,6 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.12.0, es-abstract@^1.5.1: - version "1.16.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.3.tgz#52490d978f96ff9f89ec15b5cf244304a5bca161" - integrity sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-inspect "^1.7.0" - object-keys "^1.1.1" - string.prototype.trimleft "^2.1.0" - string.prototype.trimright "^2.1.0" - es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1: version "1.17.0-next.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" @@ -4121,9 +4112,9 @@ eslint-plugin-markdown@^1.0.0: unified "^6.1.2" eslint-plugin-prettier@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba" - integrity sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba" + integrity sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA== dependencies: prettier-linter-helpers "^1.0.0" @@ -4548,9 +4539,9 @@ fast-glob@^2.2.6: micromatch "^3.1.10" fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@~2.0.6: version "2.0.6" @@ -4646,7 +4637,7 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" -file-uri-to-path@1: +file-uri-to-path@1, file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== @@ -4876,12 +4867,12 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + version "1.2.11" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" + integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== dependencies: + bindings "^1.5.0" nan "^2.12.1" - node-pre-gyp "^0.12.0" ftp@~0.3.10: version "0.3.10" @@ -5640,9 +5631,9 @@ inquirer@^6.2.0: through "^2.3.6" inquirer@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" - integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== + version "7.0.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.1.tgz#13f7980eedc73c689feff3994b109c4e799c6ebb" + integrity sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw== dependencies: ansi-escapes "^4.2.1" chalk "^2.4.2" @@ -5653,7 +5644,7 @@ inquirer@^7.0.0: lodash "^4.17.15" mute-stream "0.0.8" run-async "^2.2.0" - rxjs "^6.4.0" + rxjs "^6.5.3" string-width "^4.1.0" strip-ansi "^5.1.0" through "^2.3.6" @@ -5926,11 +5917,11 @@ is-redirect@^1.0.0: integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== dependencies: - has "^1.0.1" + has "^1.0.3" is-regexp@^2.0.0: version "2.1.0" @@ -7705,9 +7696,9 @@ nan@^2.12.1, nan@^2.14.0: integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanoid@^2.1.6: - version "2.1.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.7.tgz#d775e3e7c6470bbaaae3da9a647a80e228e0abf7" - integrity sha512-fmS3qwDldm4bE01HCIRqNk+f255CNjnAoeV3Zzzv0KemObHKqYgirVaZA9DtKcjogicWjYcHkJs4D5A8CjnuVQ== + version "2.1.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.8.tgz#2dbb0224231b246e3b4c819de7bfea6384dabf08" + integrity sha512-g1z+n5s26w0TGKh7gjn7HCqurNKMZWzH08elXzh/gM/csQHd/UqDV6uxMghQYg9IvqRPm1QpeMk50YMofHvEjQ== nanomatch@^1.2.9: version "1.2.13" @@ -7827,10 +7818,10 @@ node-notifier@^5.2.1, node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== +node-pre-gyp@*: + version "0.14.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" + integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -7841,7 +7832,7 @@ node-pre-gyp@^0.12.0: rc "^1.2.7" rimraf "^2.6.1" semver "^5.3.0" - tar "^4" + tar "^4.4.2" node-releases@^1.1.42: version "1.1.42" @@ -8013,9 +8004,9 @@ object-inspect@^1.7.0: integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== object-is@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" - integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= + version "1.0.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" + integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -8069,12 +8060,12 @@ object.fromentries@^2.0.1: has "^1.0.3" object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" object.omit@^3.0.0: version "3.0.0" @@ -8091,12 +8082,12 @@ object.pick@^1.1.1, object.pick@^1.3.0: isobject "^3.0.1" object.values@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" - integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== dependencies: define-properties "^1.1.3" - es-abstract "^1.12.0" + es-abstract "^1.17.0-next.1" function-bind "^1.1.1" has "^1.0.3" @@ -8813,9 +8804,9 @@ postcss-value-parser@^4.0.2: integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.7: - version "7.0.24" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.24.tgz#972c3c5be431b32e40caefe6c81b5a19117704c2" - integrity sha512-Xl0XvdNWg+CblAXzNvbSOUvgJXwSjmbAKORqyw9V2AlHrm1js2gFw9y3jibBAhpKZi8b5JzJCVh/FyzPsTtgTA== + version "7.0.25" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.25.tgz#dd2a2a753d50b13bed7a2009b4a18ac14d9db21e" + integrity sha512-NXXVvWq9icrm/TgQC0O6YVFi4StfJz46M1iNd/h6B26Nvh/HKI+q4YZtFN/EjcInZliEscO/WL10BXnc1E5nwg== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -9159,9 +9150,9 @@ react-native-bundle-visualizer@^2.0.1: source-map-explorer "^2.1.2" react-native-camera@^3.9.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.14.0.tgz#04d74444691bab68adce718daea459c7949b61c1" - integrity sha512-F+n9Ap91vXBqkfX2sbWFpMUIAADhCXOJEkggEqxh/ul9oL81vP8WscpcCBlbei7NZ3BLvrgFa8qgauNrZelQgw== + version "3.15.0" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.0.tgz#dd8c7fcf75b347e0b07c1dedeba2ba47504ff80a" + integrity sha512-GoRq2gHMvidcMCzj0AjaIbrJy5ZRE1XxLUIGN+M/Ev2r2RXGFWBToGoDvy4KZcwF3THWefVAZL1It+fT8pvxgQ== dependencies: prop-types "^15.6.2" @@ -9206,10 +9197,10 @@ react-native-crypto@^2.2.0: public-encrypt "^4.0.0" randomfill "^1.0.3" -react-native-device-info@^2.1.3: - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +react-native-device-info@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-5.3.1.tgz#d764732c4841b6b6c2f42516e8840075717ea88a" + integrity sha512-e/fRDoah+HxItscOJTGJY8zyVKmBUdf53VWIDGLGV4VVZ0mfzIQ2uo0ULGri0vjGUYqgyqgnW3jybPSznMxKcA== react-native-dotenv@^0.2.0: version "0.2.0" @@ -9244,11 +9235,6 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -react-native-hooks@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/react-native-hooks/-/react-native-hooks-0.9.0.tgz#589fc2390296d9afe03327298dabcf0a1f350910" - integrity sha512-yqSAH0zxqjYHYPo6mPut3dEROoB5qMvsAbN3EK0MDQrWA5zdqmzgTEpS9/qwXaIyllk6hQbHxYnRTWq2uq4tJQ== - react-native-indicators@0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" @@ -9266,10 +9252,10 @@ react-native-iphone-x-helper@^1.2.1: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== -react-native-keychain@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.1.tgz#c332f5d9aaf597255ae6ea4ca7d5c84a24684a1d" - integrity sha512-AqQp4Hib9y5DP5es5umEAhxKG7L0bA8cHNFhvlqs6oUcbUoKtXmhLDo3wzvnCF+bm8DXpGhvkU6P0LkfO0AgPQ== +react-native-keychain@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.3.tgz#38c6c0021ed697b6149d460dd5910c3c92d36ae7" + integrity sha512-mXlBcHueQ3i73GU9hc7giXJqkh+oL0f8As2H+1XWW2GovkM7xQEZNoro3DsYDIWzFW3eRoF8DmUZIGbLLEVp3Q== react-native-languages@^3.0.0: version "3.0.2" @@ -9331,12 +9317,12 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/dfd97c51eeb9ef1ea35ffb5253a48cf3689e16c9" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/c7d9cb4a5bb855b9bd944c19947564b8ee2152e6" -react-native-redash@8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-8.2.2.tgz#e2944490fbd150087043cbb6b93cf804aa932313" - integrity sha512-9LYrtR/Y4HrEpuL+CjkI3bqygwSC3S9gF1CP/to1Q5QulR42sFMknR9X/NNFDwmbmvAZoV4soHNhGpHCkGtqvg== +react-native-redash@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.0.0.tgz#3fe5426c982a036cc4e7b2df9a94bd210ddd5750" + integrity sha512-2OV8ECpI6ruCwGA3nkhv1j3dGLUhoUVVDwgzAwOfhFrF3LglUaDhT8IG3DQFw7Q5sUuyPQY7HjLu9P0VkQ94LA== dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -9386,10 +9372,10 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -react-native-svg@9.13.3: - version "9.13.3" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.3.tgz#6414b337d55af169ac2487ab70f3108404434446" - integrity sha512-H50b2m4jvrQ7KxKs8uYSuWecr6e5XC7BDfS7DaA96+0Owjh0C9DksI5l8SRyHnmE+emiYMPu6Qqfr9dCyKkaJQ== +react-native-svg@9.13.6: + version "9.13.6" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.6.tgz#5365fba2bc460054b90851e71f2a71006a5d373f" + integrity sha512-vjjuJhEhQCwWjqsgWyGy6/C/LIBM2REDxB40FU1PMhi8T3zQUwUHnA6M15pJKlQG8vaZyA+QnLyIVhjtujRgig== dependencies: css-select "^2.0.2" css-tree "^1.0.0-alpha.37" @@ -9426,11 +9412,6 @@ react-native-tooltip@marcosrdz/react-native-tooltip#master: version "5.2.1" resolved "https://codeload.github.com/marcosrdz/react-native-tooltip/tar.gz/e0e88d212b5b7f350e5eabba87f588a32e0f2590" -react-native-touch-id@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/react-native-touch-id/-/react-native-touch-id-4.4.1.tgz#8b1bb2d04c30bac36bb9696d2d723e719c4a8b08" - integrity sha512-1jTl8fC+0fxvqegy/XXTyo6vMvPhjzkoDdaqoYZx0OH8AT250NuXnNPyKktvigIcys3+2acciqOeaCall7lrvg== - react-native-udp@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.6.1.tgz#ce9f2479f8af6d1bb356cfee69c89cf92fdd50be" @@ -9449,7 +9430,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/19bf2027d1095bf2655a84a006ed74e6adae4df3" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/69e9f3a3891a9b4a9acd58e97ae4e6f9ebcf968d" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0" @@ -9808,11 +9789,12 @@ regex-not@^1.0.0, regex-not@^1.0.2: safe-regex "^1.1.0" regexp.prototype.flags@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c" - integrity sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== dependencies: - define-properties "^1.1.2" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" regexpp@^2.0.1: version "2.0.1" @@ -10196,7 +10178,7 @@ rxjs@^5.4.3: dependencies: symbol-observable "1.0.1" -rxjs@^6.4.0: +rxjs@^6.4.0, rxjs@^6.5.3: version "6.5.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== @@ -11226,7 +11208,7 @@ tail@^2.0.0: resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== -tar@^4: +tar@^4.4.2: version "4.4.13" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== @@ -11910,9 +11892,9 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.9" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.9.tgz#7ce485bb0f9a07b4d879c988baac9be2222909ad" - integrity sha512-4VCpZ9ooea/Zc/MTnj1ccc9C7rqcoinKVQLhLoi6jw6yueSf4y4tg/YIUiPPVMlEAG7ZCPS+NVmqxisQ+mOsSw== + version "3.4.10" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.10.tgz#2ff5ff4e4f31acd160619081ca279306933aaf8f" + integrity sha512-0Uy1bgVvnTkTjPOOZUCWFmXR71YgKAGu3XE3bIi9IPwTsn5apiqulOaz1UMs2ldlrHeLgsdHGEkFJnDhxtqyVQ== dependencies: jsonc-parser "^2.2.0" vscode-languageserver-textdocument "^1.0.0-next.4" @@ -12146,11 +12128,9 @@ ws@^5.2.0: async-limiter "~1.0.0" ws@^7: - version "7.2.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.0.tgz#422eda8c02a4b5dba7744ba66eebbd84bcef0ec7" - integrity sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg== - dependencies: - async-limiter "^1.0.0" + version "7.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" + integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== ws@~6.1.0: version "6.1.4" From 6a65e8e7db296184ea8db72b959425317fb82b9a Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 17 Dec 2019 02:07:50 -0500 Subject: [PATCH 621/636] Prevent unlock button getting disabled when !isSufficientBalance Fixes RAI-111 https://linear.app/issue/RAI-111 --- src/components/exchange/ConfirmExchangeButton.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index c62e042cd16..b64d20b55a3 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -36,7 +36,12 @@ const ConfirmExchangeButton = ({ return ( Date: Tue, 17 Dec 2019 04:14:20 -0500 Subject: [PATCH 622/636] Add defaults for "favorited" assets in Swap flow Sets ETH, DAI, and SOCKS as the default "favorite" assets Fixes RAI-130 https://linear.app/issue/RAI-130 --- ios/Podfile.lock | 50 ++++--- package.json | 1 + src/handlers/localstorage/uniswap.js | 12 +- src/hoc/withUniswapAssets.js | 19 +-- src/hooks/useStorage.js | 44 ++---- src/redux/uniswap.js | 9 +- yarn.lock | 200 ++------------------------- 7 files changed, 83 insertions(+), 252 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5c2b5a57570..9ce15d76dd2 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -293,6 +293,8 @@ PODS: - React - react-native-camera/RN (3.15.0): - React + - react-native-hooks-persist (1.0.3): + - React - react-native-mail (4.1.0): - React - react-native-netinfo (5.0.0): @@ -462,6 +464,7 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-camera (from `../node_modules/react-native-camera`) + - react-native-hooks-persist (from `../node_modules/react-native-hooks-persist`) - react-native-mail (from `../node_modules/react-native-mail`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-randombytes (from `../node_modules/react-native-randombytes`) @@ -573,6 +576,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/blur" react-native-camera: :path: "../node_modules/react-native-camera" + react-native-hooks-persist: + :path: "../node_modules/react-native-hooks-persist" react-native-mail: :path: "../node_modules/react-native-mail" react-native-netinfo: @@ -669,8 +674,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 6fdbec96876def36649fbd37a79bb66c2ca0f934 - FBReactNativeSpec: 35aa98e7b8521d74f3ea9a7f9a5a84dd8a02a478 + FBLazyVector: e7a6d9af306035b18059ad93f32899e390fade72 + FBReactNativeSpec: 6ccecedee3f384c7d4aad9e7ff0c8b5c58a02412 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -690,17 +695,18 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: eeebccb8cdeb32a92cfd75492800cf905de36916 - RCTTypeSafety: 0fcc89877b56727b00149aedda51bf4502982e13 - React: cb9c930b74a87600eeaa019554435741e35384bf - React-Core: 8c1fcef647f4d852b7ef158db967734efe40f552 - React-CoreModules: 0cddf8228068e4fdee11c5fe5d41e25f7de1b00e - React-cxxreact: 7bb2f46f90043160f02f97660845ae8bfe9ad015 - React-jsi: 4c2a52ce4e8169b3e9b897d3bd22c042ffbae558 - React-jsiexecutor: c02c74b564cb3f89ac1f56720f43df3fb58575d0 - React-jsinspector: fd153d75c557b4b1670601069e13f704ba80185e + RCTRequired: 2d286795f7788c7955ec6a4428f2565b630c6198 + RCTTypeSafety: f8b867cbec38be2e60c742983b84787ca93a1dd0 + React: 54deb94a31a7003b210298f471454078f6e9a160 + React-Core: 6514780e552233e5ec64cde60a093ae1da42293b + React-CoreModules: f69bd322dfb8984d8c86afca3c0bc0004e12f6b9 + React-cxxreact: 66cc02b54ab543071bafc33fea878ab47e1fe139 + React-jsi: ecc5648a5810729d5b5dc225ffc382e6021d4002 + React-jsiexecutor: 4928ff60ddfc51b7196e6fa5c0cc9c3fed71f206 + React-jsinspector: a3798eb4b1c375e1d4bc3243c0995b8d3292ab15 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb + react-native-hooks-persist: 956cc2055c81b9e8e8fc91e1d6a404abb02dfa8e react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 react-native-netinfo: 841c2a83fe7df998fed56fd48b73229f17a5aa5b react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 @@ -709,16 +715,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 6cb962c7955837e9f3db3580039d1f539410716c - React-RCTAnimation: ade24eb32b88f5311618dd2f4ce06fa15e8c348f - React-RCTBlob: b9957b715bf6079991fc372d9caca3ff3ddb328a - React-RCTImage: 218535c10986a203a5f9bbd4ad30db06879edcb0 - React-RCTLinking: 9bbfcedf6c7040fc356150b9d6986302f0d084d8 - React-RCTNetwork: 9a8bdba7373b0dfdaab3c51a2b36aafa364e27d8 - React-RCTSettings: 7ed52fb20bc45c89384ed2c094ecdb456cce8051 - React-RCTText: 4bb3b55897e080f36caa155df65a426d095493b2 - React-RCTVibration: 7aee713aa2e101aa32015aac1997269b10617f00 - ReactCommon: d4ffbab7d574e645ab78c6edb8e1ac1ac6ab338f + React-RCTActionSheet: 67084a731390e9ab2826188f3ecdab9d4bbe6429 + React-RCTAnimation: 9e3ec0ae6eaccb90613ee5b554b5e4d1ddd3f493 + React-RCTBlob: 203966b5b92876226d006a380ecebe9c97ffe540 + React-RCTImage: 71a39803369551179fa98a89f0edbe4346f8481b + React-RCTLinking: 12cbf883ceef2edebaa35e2e2b0738806088b13e + React-RCTNetwork: 7c636dae175b0db9581bdc01328fa862a45c439d + React-RCTSettings: 21c0be3aded8ba2e4e3a9fef3c68b6d2f5bf0517 + React-RCTText: b3dadaa5d91454d81b240e2c8d852cec1af693ff + React-RCTVibration: 3ad34fbe24ef11d1cc6f009bae9df66ad3ffcac9 + ReactCommon: e9bf317a5767c43cb932c09aeb680e3280ffc58f ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -747,7 +753,7 @@ SPEC CHECKSUMS: SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - Yoga: ee9d98c1a44748e5cbecc5935a800fb505a04f76 + Yoga: 86d6d484923536958fc866cd20f040887be31213 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/package.json b/package.json index 9f7814dd884..9e52646daf6 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-gesture-handler": "1.5.2", "react-native-haptic-feedback": "^1.8.2", + "react-native-hooks-persist": "^1.0.3", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", diff --git a/src/handlers/localstorage/uniswap.js b/src/handlers/localstorage/uniswap.js index 539ad21d435..df2a916573c 100644 --- a/src/handlers/localstorage/uniswap.js +++ b/src/handlers/localstorage/uniswap.js @@ -22,7 +22,17 @@ const uniswapAccountLocalKeys = [ PENDING_APPROVALS, ]; -export const getUniswapFavorites = () => getGlobal(UNISWAP_FAVORITES, []); +export const DefaultUniswapFavorites = [ + // Ethereum + 'eth', + // DAI + '0x6b175474e89094c44da98b954eedeac495271d0f', + // SOCKS + '0x23B608675a2B2fB1890d3ABBd85c5775c51691d5', +]; + +export const getUniswapFavorites = () => + getGlobal(UNISWAP_FAVORITES, DefaultUniswapFavorites); export const saveUniswapFavorites = favorites => saveGlobal(UNISWAP_FAVORITES, favorites); diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 298f33e31ce..ce4b9a56c92 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -33,9 +33,7 @@ export const includeExchangeAddress = uniswapPairs => asset => ({ ), }); -const lowerAssetName = asset => toLower(asset.name); - -const includeFavorite = asset => ({ +const appendFavoriteKey = asset => ({ ...asset, favorite: true, }); @@ -52,14 +50,17 @@ const withAssetsAvailableOnUniswap = (allAssets, uniswapPairs) => { return { assetsAvailableOnUniswap }; }; -const withSortedUniswapAssets = (unsortedUniswapAssets, favorites) => { - const sortedAssets = sortBy(values(unsortedUniswapAssets), lowerAssetName); - const [favoriteAssets, remainingAssets] = partition(sortedAssets, asset => - includes(favorites, asset.address) +const withSortedUniswapAssets = (assets, favorites) => { + const sorted = sortBy(values(assets), ({ name }) => toLower(name)); + const [favorited, notFavorited] = partition(sorted, ({ address }) => + includes(map(favorites, toLower), toLower(address)) ); - const labeledFavorites = map(favoriteAssets, includeFavorite); + return { - sortedUniswapAssets: concat(labeledFavorites, remainingAssets), + sortedUniswapAssets: concat( + map(favorited, appendFavoriteKey), + notFavorited + ), }; }; diff --git a/src/hooks/useStorage.js b/src/hooks/useStorage.js index ddd4564626a..37303a7aae3 100644 --- a/src/hooks/useStorage.js +++ b/src/hooks/useStorage.js @@ -1,33 +1,13 @@ -import AsyncStorage from '@react-native-community/async-storage'; -import { useEffect, useState } from 'react'; - -export default function useAsyncStorage(key, defaultValue) { - const [state, setState] = useState({ - hydrated: false, - storageValue: defaultValue, - }); - - const { hydrated, storageValue } = state; - - async function pullFromStorage() { - const fromStorage = await AsyncStorage.getItem(key); - let value = defaultValue; - if (fromStorage) { - value = JSON.parse(fromStorage); - } - setState({ hydrated: true, storageValue: value }); - } - - async function updateStorage(newValue) { - setState({ hydrated: true, storageValue: newValue }); - const stringifiedValue = JSON.stringify(newValue); - await AsyncStorage.setItem(key, stringifiedValue); - } - - useEffect(() => { - pullFromStorage(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return [storageValue, updateStorage, hydrated]; +import { useCallback } from 'react'; +import { + removeStatePersist, + useStatePersist, +} from 'react-native-hooks-persist'; + +const DEFAULT_DB_NAME = 'globalStorage'; + +export default function useStorage(key, defaultValue, db = DEFAULT_DB_NAME) { + const [value, update] = useStatePersist(db, key, defaultValue); + const remove = useCallback(() => removeStatePersist(db, key), [db, key]); + return [value, update, remove]; } diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index b9f43ebc4db..33158c189bc 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -31,6 +31,7 @@ import { saveUniswapPendingApprovals, } from '../handlers/localstorage/uniswap'; import { + DefaultUniswapFavorites, getLiquidityInfo, getReserve, getUniswapPairs, @@ -218,9 +219,11 @@ export const uniswapUpdateFavorites = (assetAddress, add = true) => ( ) => { const address = toLower(assetAddress); const { favorites } = getState().uniswap; + const normalizedFavorites = map(favorites, toLower); + const updatedFavorites = add - ? uniq(concat(favorites, address)) - : without(favorites, address); + ? uniq(concat(normalizedFavorites, address)) + : without(normalizedFavorites, address); dispatch({ payload: updatedFavorites, type: UNISWAP_UPDATE_FAVORITES, @@ -333,7 +336,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => // -- Reducer --------------------------------------------------------------- // export const INITIAL_UNISWAP_STATE = { allowances: {}, - favorites: [], + favorites: DefaultUniswapFavorites, fetchingUniswap: false, inputCurrency: null, inputReserve: null, diff --git a/yarn.lock b/yarn.lock index 4a51fb11908..ecc104026e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1617,11 +1617,6 @@ abab@^2.0.0: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -1860,19 +1855,6 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2810,11 +2792,6 @@ child-process-promise@^2.2.0: node-version "^1.0.0" promise-polyfill "^6.0.1" -chownr@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== - chroma-js@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.0.tgz#c0be48a21fe797ef8965608c1c4f911ef2da49d5" @@ -3164,11 +3141,6 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -3461,7 +3433,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@^3.1.0, debug@^3.2.6: +debug@3.2.6, debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -3582,11 +3554,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - denodeify@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" @@ -3610,11 +3577,6 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - detect-newline@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" @@ -4854,13 +4816,6 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -4904,20 +4859,6 @@ fwd-stream@^1.0.4: dependencies: readable-stream "~1.0.26-4" -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -5230,11 +5171,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -5431,7 +5367,7 @@ i18next@^17.0.3: dependencies: "@babel/runtime" "^7.3.1" -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5443,13 +5379,6 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== -ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" - ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -7568,21 +7497,6 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -7599,7 +7513,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -7727,15 +7641,6 @@ ncp@~2.0.0: resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -7818,22 +7723,6 @@ node-notifier@^5.2.1, node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" -node-pre-gyp@*: - version "0.14.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" - integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4.4.2" - node-releases@^1.1.42: version "1.1.42" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7" @@ -7846,14 +7735,6 @@ node-version@^1.0.0: resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - normalize-css-color@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/normalize-css-color/-/normalize-css-color-1.0.2.tgz#02991e97cccec6623fe573afbbf0de6a1f3e9f8d" @@ -7893,26 +7774,6 @@ normalize-svg-path@^1.0.1: dependencies: svg-arc-to-cubic-bezier "^3.0.0" -npm-bundled@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" - integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-packlist@^1.1.6: - version "1.4.7" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.7.tgz#9e954365a06b80b18111ea900945af4f88ed4848" - integrity sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -7927,16 +7788,6 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -8217,11 +8068,6 @@ ora@^3.4.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -8250,14 +8096,6 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - output-file-sync@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" @@ -9084,7 +8922,7 @@ raw-body@^2.2.0: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: +rc@^1.0.1, rc@^1.1.6: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -9235,6 +9073,11 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== +react-native-hooks-persist@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/react-native-hooks-persist/-/react-native-hooks-persist-1.0.3.tgz#19016914213b2982113cb1825c52936b2d8cdb67" + integrity sha512-4LOANCf3B63HwVAe5vdm7tXkrNto3GLgiocAWSGhRuZ3/vZ7W+wu9j7dHZRtrybOlpSlLRlSKxpcL4873Oc9tw== + react-native-indicators@0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" @@ -9636,7 +9479,7 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: +readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -10078,7 +9921,7 @@ rimraf@2.6.3, rimraf@~2.6.2: dependencies: glob "^7.1.3" -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -10279,7 +10122,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -10333,7 +10176,7 @@ serve-static@^1.13.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -11208,19 +11051,6 @@ tail@^2.0.0: resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== -tar@^4.4.2: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - telnet-client@0.15.3: version "0.15.3" resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-0.15.3.tgz#99ec754e4acf6fa51dc69898f574df3c2550712e" @@ -12009,7 +11839,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@1.1.3, wide-align@^1.1.0: +wide-align@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== @@ -12251,7 +12081,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== From 1995559238ee9f6ca624de7b4f9bd57b642f6db9 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 17 Dec 2019 04:16:42 -0500 Subject: [PATCH 623/636] transition the KeyboardFixedOpenLayout when its height changes --- .../layout/KeyboardFixedOpenLayout.js | 118 ++++++++++-------- 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/src/components/layout/KeyboardFixedOpenLayout.js b/src/components/layout/KeyboardFixedOpenLayout.js index de47b818bc7..202e8f45713 100644 --- a/src/components/layout/KeyboardFixedOpenLayout.js +++ b/src/components/layout/KeyboardFixedOpenLayout.js @@ -1,80 +1,90 @@ import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Keyboard, KeyboardAvoidingView } from 'react-native'; +import { Transition, Transitioning } from 'react-native-reanimated'; import styled from 'styled-components/primitives'; import { withKeyboardHeight } from '../../hoc'; import { padding, position } from '../../styles'; import { deviceUtils, safeAreaInsetValues } from '../../utils'; import Centered from './Centered'; -import { setKeyboardHeight } from '../../handlers/localstorage/globalSettings'; +import { setKeyboardHeight as storeKeyboardHeight } from '../../handlers/localstorage/globalSettings'; import { calculateKeyboardHeight } from '../../helpers/keyboardHeight'; -const FallbackKeyboardHeight = calculateKeyboardHeight( - deviceUtils.dimensions.height -); +const deviceHeight = deviceUtils.dimensions.height; -const Container = styled.View` - left: 0; - position: absolute; - right: 0; - top: 0; -`; +const FallbackKeyboardHeight = calculateKeyboardHeight(deviceHeight); + +const containerStyle = { + left: 0, + position: 'absolute', + right: 0, + top: 0, +}; const InnerWrapper = styled(Centered)` ${padding(safeAreaInsetValues.top, 0, 10)}; ${position.size('100%')}; `; -class KeyboardFixedOpenLayout extends PureComponent { - static propTypes = { - children: PropTypes.node, - keyboardHeight: PropTypes.number, - setKeyboardHeight: PropTypes.func, - }; - - componentDidMount = () => { - if (!this.willShowListener) { - this.willShowListener = Keyboard.addListener( - 'keyboardWillShow', - this.keyboardWillShow - ); - } - }; +const transition = ( + +); - componentWillUnmount = () => this.clearKeyboardListeners(); +const KeyboardFixedOpenLayout = ({ + keyboardHeight, + setKeyboardHeight, + ...props +}) => { + const ref = useRef(); + const [didMeasure, setDidMeasure] = useState(false); + const resolvedKeyboardHeight = keyboardHeight || FallbackKeyboardHeight; - willShowListener = undefined; + const handleKeyboardWillShow = useCallback( + async ({ endCoordinates: { height } }) => { + if (height !== keyboardHeight) { + const newHeight = Math.floor(height); + setDidMeasure(true); + storeKeyboardHeight(newHeight); + setKeyboardHeight(newHeight); + } + }, + [keyboardHeight, setDidMeasure, setKeyboardHeight] + ); - clearKeyboardListeners = () => { - if (this.willShowListener) { - this.willShowListener.remove(); - } - }; + useEffect(() => { + let listener = undefined; - keyboardWillShow = async ({ endCoordinates: { height } }) => { - if (height !== this.props.keyboardHeight) { - const keyboardHeight = Math.floor(height); - setKeyboardHeight(keyboardHeight); - this.props.setKeyboardHeight(keyboardHeight); + if (!didMeasure) { + listener = Keyboard.addListener( + 'keyboardWillShow', + handleKeyboardWillShow + ); } - this.clearKeyboardListeners(); - }; - render = () => { - const { keyboardHeight } = this.props; + return () => { + if (listener) { + listener.remove(); + } + }; + }, [didMeasure, handleKeyboardWillShow]); - const resolvedKeyboardHeight = keyboardHeight || FallbackKeyboardHeight; - const containerHeight = - deviceUtils.dimensions.height - resolvedKeyboardHeight; + return ( + + + + + + ); +}; - return ( - - - - - - ); - }; -} +KeyboardFixedOpenLayout.propTypes = { + keyboardHeight: PropTypes.number, + setKeyboardHeight: PropTypes.func, +}; export default withKeyboardHeight(KeyboardFixedOpenLayout); From 78c81b6fae1d4b7010d0bf262084c83a40c8b421 Mon Sep 17 00:00:00 2001 From: Wojciech Stanisz <42337257+wojtus7@users.noreply.github.com> Date: Tue, 17 Dec 2019 10:54:37 +0100 Subject: [PATCH 624/636] fix conditional logic mistake (#294) --- src/screens/ExchangeModal.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/screens/ExchangeModal.js b/src/screens/ExchangeModal.js index c80216e3215..dc809f6eab3 100644 --- a/src/screens/ExchangeModal.js +++ b/src/screens/ExchangeModal.js @@ -142,6 +142,20 @@ class ExchangeModal extends Component { 'pendingApprovals', ]); + // Code below is a workaround. We noticed that opening keyboard while animation + // (with autofocus) can lead to frame drops. In order not to limit this + // I manually can focus instead of relying on built-in autofocus. + // Maybe that's not perfect, but works for now ¯\_(ツ)_/¯ + if ( + this.props.isTransitioning && + !nextProps.isTransitioning && + this.lastFocusedInput === null + ) { + this.inputFocusInteractionHandle = InteractionManager.runAfterInteractions( + this.focusInputField + ); + } + const isNewState = isNewValueForObjectPaths(this.state, nextState, [ 'approvalCreationTimestamp', 'approvalEstimatedTimeInMs', @@ -235,16 +249,6 @@ class ExchangeModal extends Component { assignInputFieldRef = ref => { this.inputFieldRef = ref; - - // Code below is a workaround. We noticed that opening keyboard while animation - // (with autofocus) can lead to frame drops. In order not to limit this - // I manually can focus instead of relying on built-in autofocus. - // Maybe that's not perfect, but works for now ¯\_(ツ)_/¯ - if (this.lastFocusedInput === null) { - this.inputFocusInteractionHandle = InteractionManager.runAfterInteractions( - this.focusInputField - ); - } }; assignNativeFieldRef = ref => { this.nativeFieldRef = ref; From 07c72b58cb33e6e5cc16f3c9d272b59ea5743c8b Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 17 Dec 2019 11:59:58 -0500 Subject: [PATCH 625/636] Move default uniswap favorites constant to references --- src/handlers/localstorage/uniswap.js | 10 +--------- src/redux/uniswap.js | 6 ++++-- src/references/index.js | 9 +++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/handlers/localstorage/uniswap.js b/src/handlers/localstorage/uniswap.js index df2a916573c..b79fd9d284f 100644 --- a/src/handlers/localstorage/uniswap.js +++ b/src/handlers/localstorage/uniswap.js @@ -1,4 +1,5 @@ import { forEach } from 'lodash'; +import { DefaultUniswapFavorites } from '../../references'; import { getAccountLocal, getGlobal, @@ -22,15 +23,6 @@ const uniswapAccountLocalKeys = [ PENDING_APPROVALS, ]; -export const DefaultUniswapFavorites = [ - // Ethereum - 'eth', - // DAI - '0x6b175474e89094c44da98b954eedeac495271d0f', - // SOCKS - '0x23B608675a2B2fB1890d3ABBd85c5775c51691d5', -]; - export const getUniswapFavorites = () => getGlobal(UNISWAP_FAVORITES, DefaultUniswapFavorites); diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 33158c189bc..00f5b61fc5e 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -31,13 +31,15 @@ import { saveUniswapPendingApprovals, } from '../handlers/localstorage/uniswap'; import { - DefaultUniswapFavorites, getLiquidityInfo, getReserve, getUniswapPairs, } from '../handlers/uniswap'; import { includeExchangeAddress } from '../hoc/withUniswapAssets'; -import { cleanUniswapAssetsFallback } from '../references'; +import { + cleanUniswapAssetsFallback, + DefaultUniswapFavorites, +} from '../references'; import { resubscribeAssets } from './explorer'; // -- Constants ------------------------------------------------------------- // diff --git a/src/references/index.js b/src/references/index.js index c72fd596d22..4206cb7ce04 100644 --- a/src/references/index.js +++ b/src/references/index.js @@ -2,6 +2,15 @@ import { mapKeys, mapValues, toLower } from 'lodash'; import tokenOverridesFallback from './token-overrides.json'; import uniswapAssetsFallback from './uniswap-pairs.json'; +export const DefaultUniswapFavorites = [ + // Ethereum + 'eth', + // DAI + '0x6b175474e89094c44da98b954eedeac495271d0f', + // SOCKS + '0x23B608675a2B2fB1890d3ABBd85c5775c51691d5', +]; + export const loweredTokenOverridesFallback = mapKeys( tokenOverridesFallback, (_, address) => toLower(address) From 49f0002756995e827aa414b8b3addeb6f1fa9f06 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Wed, 18 Dec 2019 12:42:24 -0500 Subject: [PATCH 626/636] remove attempt at useStorage hook --- ios/Podfile.lock | 80 +++++------ package.json | 1 - src/hooks/useBiometryType.js | 12 +- src/hooks/useStorage.js | 13 -- yarn.lock | 252 +++++++++++++++++++++++++++++------ 5 files changed, 252 insertions(+), 106 deletions(-) delete mode 100644 src/hooks/useStorage.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9ce15d76dd2..552a50e96cd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -55,7 +55,7 @@ PODS: - FirebaseCore (~> 6.0) - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/UserDefaults (~> 6.0) - - FirebaseMessaging (4.1.9): + - FirebaseMessaging (4.1.10): - FirebaseAnalyticsInterop (~> 1.3) - FirebaseCore (~> 6.2) - FirebaseInstanceID (~> 4.1) @@ -82,26 +82,26 @@ PODS: - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (= 0.3.9011) - GoogleDataTransport (3.2.0) - - GoogleDataTransportCCTSupport (1.2.2): + - GoogleDataTransportCCTSupport (1.2.3): - GoogleDataTransport (~> 3.2) - nanopb (~> 0.3.901) - - GoogleUtilities/AppDelegateSwizzler (6.3.2): + - GoogleUtilities/AppDelegateSwizzler (6.4.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.3.2) - - GoogleUtilities/Logger (6.3.2): + - GoogleUtilities/Environment (6.4.0) + - GoogleUtilities/Logger (6.4.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.3.2): + - GoogleUtilities/MethodSwizzler (6.4.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.3.2): + - GoogleUtilities/Network (6.4.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.3.2)" - - GoogleUtilities/Reachability (6.3.2): + - "GoogleUtilities/NSData+zlib (6.4.0)" + - GoogleUtilities/Reachability (6.4.0): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.3.2): + - GoogleUtilities/UserDefaults (6.4.0): - GoogleUtilities/Logger - JWT (3.0.0-beta.12): - Base64 (~> 1.1.2) @@ -293,8 +293,6 @@ PODS: - React - react-native-camera/RN (3.15.0): - React - - react-native-hooks-persist (1.0.3): - - React - react-native-mail (4.1.0): - React - react-native-netinfo (5.0.0): @@ -416,7 +414,7 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React - - RNSentry (1.2.0): + - RNSentry (1.2.1): - React - Sentry (~> 4.4.0) - RNStoreReview (0.1.5): @@ -464,7 +462,6 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-camera (from `../node_modules/react-native-camera`) - - react-native-hooks-persist (from `../node_modules/react-native-hooks-persist`) - react-native-mail (from `../node_modules/react-native-mail`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-randombytes (from `../node_modules/react-native-randombytes`) @@ -576,8 +573,6 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/blur" react-native-camera: :path: "../node_modules/react-native-camera" - react-native-hooks-persist: - :path: "../node_modules/react-native-hooks-persist" react-native-mail: :path: "../node_modules/react-native-mail" react-native-netinfo: @@ -674,8 +669,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: e7a6d9af306035b18059ad93f32899e390fade72 - FBReactNativeSpec: 6ccecedee3f384c7d4aad9e7ff0c8b5c58a02412 + FBLazyVector: f4bf59b48e6732b1b5d328248ab8794130748b92 + FBReactNativeSpec: bed51880b4206526f796433048ca5d929f1cf52d Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -683,30 +678,29 @@ SPEC CHECKSUMS: FirebaseCoreDiagnostics: 511f4f3ed7d440bb69127e8b97c2bc8befae639e FirebaseCoreDiagnosticsInterop: e9b1b023157e3a2fc6418b5cb601e79b9af7b3a0 FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e - FirebaseMessaging: e8d71368a5c579083da02203146c953f3386d503 + FirebaseMessaging: 089b7a4991425783384acc8bcefcd78c0af913bd FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleAppMeasurement: dfe55efa543e899d906309eaaac6ca26d249862f GoogleDataTransport: 8e9b210c97d55fbff306cc5468ff91b9cb32dcf5 - GoogleDataTransportCCTSupport: ef79a4728b864946a8aafdbab770d5294faf3b5f - GoogleUtilities: 547a86735c6f0ee30ad17e94df4fc21f616b71cb + GoogleDataTransportCCTSupport: 202d7cdf9c4a7d81a2bb7f7e7e1ba6faa421b1f2 + GoogleUtilities: 29bd0d8f850efbd28cff6d99e8b7da1f8d236bcf JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: 2d286795f7788c7955ec6a4428f2565b630c6198 - RCTTypeSafety: f8b867cbec38be2e60c742983b84787ca93a1dd0 - React: 54deb94a31a7003b210298f471454078f6e9a160 - React-Core: 6514780e552233e5ec64cde60a093ae1da42293b - React-CoreModules: f69bd322dfb8984d8c86afca3c0bc0004e12f6b9 - React-cxxreact: 66cc02b54ab543071bafc33fea878ab47e1fe139 - React-jsi: ecc5648a5810729d5b5dc225ffc382e6021d4002 - React-jsiexecutor: 4928ff60ddfc51b7196e6fa5c0cc9c3fed71f206 - React-jsinspector: a3798eb4b1c375e1d4bc3243c0995b8d3292ab15 + RCTRequired: adc14902dcd9bd96162bff839191031802d1bbdf + RCTTypeSafety: 1bfc26cae1495204b3ee8e2aa1a416b586be2361 + React: b6779e9431357663e2a761ca8b2384d37b81d585 + React-Core: bbd3079bfbcfab4ccbbff76e508864d5be4c2d9f + React-CoreModules: 88908075a740de7f7772f9f67248af8786c4e892 + React-cxxreact: c8533f3dba7760196f4bd88ef5e1fdacbde47c0b + React-jsi: 654b98b363c44145e9e39901f8be23696b5b69fe + React-jsiexecutor: 808812487bafd8fb39d0aeecd7bea852622a310a + React-jsinspector: 74c057ffb291d70dcf8297f46ba7cafff428e823 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb - react-native-hooks-persist: 956cc2055c81b9e8e8fc91e1d6a404abb02dfa8e react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 react-native-netinfo: 841c2a83fe7df998fed56fd48b73229f17a5aa5b react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 @@ -715,16 +709,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 67084a731390e9ab2826188f3ecdab9d4bbe6429 - React-RCTAnimation: 9e3ec0ae6eaccb90613ee5b554b5e4d1ddd3f493 - React-RCTBlob: 203966b5b92876226d006a380ecebe9c97ffe540 - React-RCTImage: 71a39803369551179fa98a89f0edbe4346f8481b - React-RCTLinking: 12cbf883ceef2edebaa35e2e2b0738806088b13e - React-RCTNetwork: 7c636dae175b0db9581bdc01328fa862a45c439d - React-RCTSettings: 21c0be3aded8ba2e4e3a9fef3c68b6d2f5bf0517 - React-RCTText: b3dadaa5d91454d81b240e2c8d852cec1af693ff - React-RCTVibration: 3ad34fbe24ef11d1cc6f009bae9df66ad3ffcac9 - ReactCommon: e9bf317a5767c43cb932c09aeb680e3280ffc58f + React-RCTActionSheet: 5de50477a51ffa4bda8b1a2e3a663cd0aa0f248a + React-RCTAnimation: eda92681d80e790260b52ec9935c49917a182cd3 + React-RCTBlob: afa0ba6924c6cf2c471230bf24e03339dddadaa1 + React-RCTImage: eddac7c4a8315fa421a62538667e98daf0108ba8 + React-RCTLinking: b99a0100e0b3ad204de94d1eba9a28996d6ba602 + React-RCTNetwork: 9d78746a30295a327da01f9916b134b71e50f002 + React-RCTSettings: f331fcb5217b2c70b76d6069b512a9b1b732fde1 + React-RCTText: 4f3cb6823a9eabae7068e2a93f3b8d71a8f0a25e + React-RCTVibration: e5a3c9aca8f46c3aadc4da9a0918e32bc192ad51 + ReactCommon: 8d4559452b8c852c80df07ab2db6d71da97ce3a0 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -743,7 +737,7 @@ SPEC CHECKSUMS: RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 8b675a650fc67c87f63d4345a1b2d4a699c25e4f RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 - RNSentry: b63ba6a29ee142b5c3221896be8ff6cda587e03f + RNSentry: 9b1d983b2d5d1c215ba6490348fd2a4cc23a8a9d RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 @@ -753,7 +747,7 @@ SPEC CHECKSUMS: SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - Yoga: 86d6d484923536958fc866cd20f040887be31213 + Yoga: 613f9f1fadd893d425056f50d642946aa1587728 PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/package.json b/package.json index 9e52646daf6..9f7814dd884 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,6 @@ "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-gesture-handler": "1.5.2", "react-native-haptic-feedback": "^1.8.2", - "react-native-hooks-persist": "^1.0.3", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", diff --git a/src/hooks/useBiometryType.js b/src/hooks/useBiometryType.js index 42b5a7b5993..e1e1a2274a5 100644 --- a/src/hooks/useBiometryType.js +++ b/src/hooks/useBiometryType.js @@ -1,10 +1,9 @@ import { isNil } from 'lodash'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { isPinOrFingerprintSet } from 'react-native-device-info'; import * as Keychain from 'react-native-keychain'; import useAppState from './useAppState'; import usePrevious from './usePrevious'; -import useStorage from './useStorage'; export const BiometryTypes = { FaceID: 'FaceID', @@ -15,10 +14,7 @@ export const BiometryTypes = { export default function useBiometryType() { const { justBecameActive } = useAppState(); - const [biometryType, setBiometryType] = useStorage( - 'biometryType', - BiometryTypes.none - ); + const [biometryType, setBiometryType] = useState(null); const prevBiometricType = usePrevious(biometryType); useEffect(() => { @@ -41,14 +37,14 @@ export default function useBiometryType() { } }; - if (justBecameActive) { + if (!biometryType || justBecameActive) { getSupportedBiometryType(); } return () => { mounted = false; }; - }, [justBecameActive, prevBiometricType, setBiometryType]); + }, [biometryType, justBecameActive, prevBiometricType, setBiometryType]); return biometryType; } diff --git a/src/hooks/useStorage.js b/src/hooks/useStorage.js deleted file mode 100644 index 37303a7aae3..00000000000 --- a/src/hooks/useStorage.js +++ /dev/null @@ -1,13 +0,0 @@ -import { useCallback } from 'react'; -import { - removeStatePersist, - useStatePersist, -} from 'react-native-hooks-persist'; - -const DEFAULT_DB_NAME = 'globalStorage'; - -export default function useStorage(key, defaultValue, db = DEFAULT_DB_NAME) { - const [value, update] = useStatePersist(db, key, defaultValue); - const remove = useCallback(() => removeStatePersist(db, key), [db, key]); - return [value, update, remove]; -} diff --git a/yarn.lock b/yarn.lock index ecc104026e0..7e7cf3cae74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1207,9 +1207,9 @@ tslib "^1.9.3" "@sentry/react-native@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.0.tgz#244ec5f07a4eb07d3d56e7b50fe00f479a733eb5" - integrity sha512-GPY+1dBLgx5I/eOuj+dyMO8DGSoPTatB13WpYbFouGNbx3Ni4SD6EwpU+VdJtqtqVQ0OUVMNm+w/lX4+ggmU5g== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.1.tgz#a015ed280ffa8afde3f775b91d173ad7c884e169" + integrity sha512-JE2B/pMvd7+3TFdzs03+DOdrALAHd8bAphJ8tk+nWjX7oQVJNgVn/IvnJfKxasHHBXQ2z+42Xy9n2Fqam/Gq0w== dependencies: "@sentry/browser" "^5.10.0" "@sentry/core" "^5.10.0" @@ -1470,9 +1470,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.18.tgz#8d16634797d63c2af5bc647ce879f8de20b56469" - integrity sha512-DBkZuIMFuAfjJHiunyRc+aNvmXYNwV1IPMgGKGlwCp6zh6MKrVtmvjSWK/axWcD25KJffkXgkfvFra8ndenXAw== + version "12.12.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.21.tgz#aa44a6363291c7037111c47e4661ad210aded23f" + integrity sha512-8sRGhbpU+ck1n0PGAUgVrWrWdjSW2aqNeyC15W88GRsMpSwzv6RJGlLhE7s2RhVSOdyDmxbqlWSeThq4/7xqlA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1617,6 +1617,11 @@ abab@^2.0.0: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -1855,6 +1860,19 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2792,6 +2810,11 @@ child-process-promise@^2.2.0: node-version "^1.0.0" promise-polyfill "^6.0.1" +chownr@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== + chroma-js@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.0.tgz#c0be48a21fe797ef8965608c1c4f911ef2da49d5" @@ -3141,6 +3164,11 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -3410,9 +3438,9 @@ date-fns@^1.30.1: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.8.15: - version "1.8.17" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.17.tgz#53ec413f2a7b02afbea1846d61bb260fa8567cea" - integrity sha512-47VY/htqYqr9GHd7HW/h56PpQzRBSJcxIQFwqL3P20bMF/3az5c3PWdVY3LmPXFl6cQCYHL7c79b9ov+2bOBbw== + version "1.8.18" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.18.tgz#c9b3fcd5a8eca96ed20a907f4491516d6eda15c9" + integrity sha512-JBMJZghNK8TtuoPnKNIzW9xavVVigld/zmZNpZSyQbkb2Opp55YIfZUpE4OEqPF/iyUVQTKcn1bC2HtC8B7s3g== debounce@^1.2.0: version "1.2.0" @@ -3433,7 +3461,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@^3.1.0: +debug@3.2.6, debug@^3.1.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -3554,6 +3582,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + denodeify@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" @@ -3577,6 +3610,11 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + detect-newline@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" @@ -4816,6 +4854,13 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -4859,6 +4904,20 @@ fwd-stream@^1.0.4: dependencies: readable-stream "~1.0.26-4" +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -5171,6 +5230,11 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -5367,7 +5431,7 @@ i18next@^17.0.3: dependencies: "@babel/runtime" "^7.3.1" -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5379,6 +5443,13 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -5395,9 +5466,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.1.tgz#1a1184fa758f68f1b5573db840825fb5164cceca" - integrity sha512-KFHV1ivrBmPCVRhjy9oBooypnPfJ876NTrWXMNoUhXFAaWWAViVqZ4l6HxPST52qcN82qqsR38/pCGYRWP5W7w== + version "5.0.2" + resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.2.tgz#34eb50c69abb8c04acd0f942244c5eefe62a4e4e" + integrity sha512-O3MChd2M5aOt7NNVRTnH8Wt+Mu+degWN4WsS3U+f1ggM2nMPO+cj/JJobgBUz4WeEEPxKIQO6sN/Dq5hnOmqaQ== import-fresh@^2.0.0: version "2.0.0" @@ -7497,6 +7568,21 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -7513,7 +7599,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -7641,6 +7727,15 @@ ncp@~2.0.0: resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= +needle@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -7723,10 +7818,26 @@ node-notifier@^5.2.1, node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" +node-pre-gyp@*: + version "0.14.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" + integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4.4.2" + node-releases@^1.1.42: - version "1.1.42" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7" - integrity sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA== + version "1.1.43" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.43.tgz#2c6ca237f88ce11d49631f11190bb01f8d0549f2" + integrity sha512-Rmfnj52WNhvr83MvuAWHEqXVoZXCcDQssSOffU4n4XOL9sPrP61mSZ88g25NqmABDvH7PiAlFCzoSCSdzA293w== dependencies: semver "^6.3.0" @@ -7735,6 +7846,14 @@ node-version@^1.0.0: resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + normalize-css-color@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/normalize-css-color/-/normalize-css-color-1.0.2.tgz#02991e97cccec6623fe573afbbf0de6a1f3e9f8d" @@ -7774,6 +7893,26 @@ normalize-svg-path@^1.0.1: dependencies: svg-arc-to-cubic-bezier "^3.0.0" +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.7" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.7.tgz#9e954365a06b80b18111ea900945af4f88ed4848" + integrity sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -7788,6 +7927,16 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -8068,6 +8217,11 @@ ora@^3.4.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -8096,6 +8250,14 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + output-file-sync@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" @@ -8922,7 +9084,7 @@ raw-body@^2.2.0: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.0.1, rc@^1.1.6: +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -9073,11 +9235,6 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -react-native-hooks-persist@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/react-native-hooks-persist/-/react-native-hooks-persist-1.0.3.tgz#19016914213b2982113cb1825c52936b2d8cdb67" - integrity sha512-4LOANCf3B63HwVAe5vdm7tXkrNto3GLgiocAWSGhRuZ3/vZ7W+wu9j7dHZRtrybOlpSlLRlSKxpcL4873Oc9tw== - react-native-indicators@0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" @@ -9160,7 +9317,7 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/c7d9cb4a5bb855b9bd944c19947564b8ee2152e6" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/abada27d23b37be466c4f4f6f1e8206983d35d07" react-native-redash@^9.0.0: version "9.0.0" @@ -9273,7 +9430,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/69e9f3a3891a9b4a9acd58e97ae4e6f9ebcf968d" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/048f88a33a53ebd4e45865b319c42291f1d6c7f2" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0" @@ -9479,7 +9636,7 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@~2.3.6: +readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -9921,7 +10078,7 @@ rimraf@2.6.3, rimraf@~2.6.2: dependencies: glob "^7.1.3" -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -10122,7 +10279,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -10176,7 +10333,7 @@ serve-static@^1.13.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -11051,6 +11208,19 @@ tail@^2.0.0: resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== +tar@^4.4.2: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + telnet-client@0.15.3: version "0.15.3" resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-0.15.3.tgz#99ec754e4acf6fa51dc69898f574df3c2550712e" @@ -11722,22 +11892,22 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.10" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.10.tgz#2ff5ff4e4f31acd160619081ca279306933aaf8f" - integrity sha512-0Uy1bgVvnTkTjPOOZUCWFmXR71YgKAGu3XE3bIi9IPwTsn5apiqulOaz1UMs2ldlrHeLgsdHGEkFJnDhxtqyVQ== + version "3.4.11" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.11.tgz#7c0632bccc4b2b955f99f99f43d96d3eece1de42" + integrity sha512-26Qv1SFp6x3XmCqU1BRceRsSKRO3xkQa6/K8ziSRt52/LQPiw5ipSxlGVSlzIoi5LCmQVEqUajhiVEMNlFXhNw== dependencies: jsonc-parser "^2.2.0" - vscode-languageserver-textdocument "^1.0.0-next.4" - vscode-languageserver-types "^3.15.0-next.6" + vscode-languageserver-textdocument "^1.0.0-next.5" + vscode-languageserver-types "^3.15.0-next.9" vscode-nls "^4.1.1" - vscode-uri "^2.1.0" + vscode-uri "^2.1.1" -vscode-languageserver-textdocument@^1.0.0-next.4: +vscode-languageserver-textdocument@^1.0.0-next.5: version "1.0.0-next.5" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.5.tgz#dbb7a45dd973a19261a7c57ab9a439c40f3799ee" integrity sha512-1jp/zAidN/bF/sqPimhBX1orH5G4rzRw63k75TesukJDuxm8yW79ECStWbDSy41BHGOwSGN4M69QFvhancSr5A== -vscode-languageserver-types@^3.15.0-next.6: +vscode-languageserver-types@^3.15.0-next.9: version "3.15.0-next.9" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz#957a9d1d5998a02edf62298fb7e37d9efcc6c157" integrity sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw== @@ -11747,7 +11917,7 @@ vscode-nls@^4.1.1: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== -vscode-uri@^2.1.0: +vscode-uri@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90" integrity sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A== @@ -11839,7 +12009,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@1.1.3: +wide-align@1.1.3, wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== @@ -12081,7 +12251,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.2: +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== From 4336c4ff28b98968bdc6ba248a1916511a729a11 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 23 Dec 2019 03:46:13 -0500 Subject: [PATCH 627/636] Fix missing OfflineBadge Fixes RAI-143 https://linear.app/issue/RAI-143 --- src/App.js | 2 +- src/components/OfflineBadge.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index d8c96be2de7..8fd49fc9325 100644 --- a/src/App.js +++ b/src/App.js @@ -160,8 +160,8 @@ class App extends Component { - + diff --git a/src/components/OfflineBadge.js b/src/components/OfflineBadge.js index d3985e15994..642e1602f1f 100644 --- a/src/components/OfflineBadge.js +++ b/src/components/OfflineBadge.js @@ -1,6 +1,6 @@ import React from 'react'; import Animated from 'react-native-reanimated'; -import { useSpringTransition } from 'react-native-redash'; +import { bin, useSpringTransition } from 'react-native-redash'; import styled from 'styled-components'; import { useInternetStatus } from '../hooks'; import { colors, padding, shadow } from '../styles'; @@ -28,7 +28,7 @@ const DefaultAnimationValue = 60; const OfflineBadge = () => { const isConnected = useInternetStatus(); - const animation = useSpringTransition(isConnected, { + const animation = useSpringTransition(bin(isConnected), { damping: 14, mass: 1, overshootClamping: false, From b28239555efb3962208713ec8c84a6b5a84027b6 Mon Sep 17 00:00:00 2001 From: jinchung Date: Fri, 27 Dec 2019 12:22:02 -0500 Subject: [PATCH 628/636] Subscribing to net info listener --- src/hooks/useInternetStatus.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/hooks/useInternetStatus.js b/src/hooks/useInternetStatus.js index 216d779a204..7520325cbe1 100644 --- a/src/hooks/useInternetStatus.js +++ b/src/hooks/useInternetStatus.js @@ -1,17 +1,27 @@ -import { useNetInfo } from '@react-native-community/netinfo'; +import NetInfo from '@react-native-community/netinfo'; import analytics from '@segment/analytics-react-native'; -import { useEffect } from 'react'; +import { isNil } from 'lodash'; +import { useEffect, useState } from 'react'; export default function useInternetStatus() { - const { isInternetReachable } = useNetInfo(); + const [isInternetReachable, setIsInternetReachable] = useState(true); - useEffect(() => { - if (isInternetReachable) { - analytics.track('Reconnected after offline'); - } else { - analytics.track('Offline / lost connection'); + function onChange(newState) { + const { isInternetReachable: newIsInternetReachable } = newState; + if (!isNil(newIsInternetReachable)) { + setIsInternetReachable(newIsInternetReachable); + if (newIsInternetReachable) { + analytics.track('Reconnected after offline'); + } else { + analytics.track('Offline / lost connection'); + } } - }, [isInternetReachable]); + } + + useEffect(() => { + const unsubscribe = NetInfo.addEventListener(onChange); + return unsubscribe; + }, []); return isInternetReachable; } From 9fce3fc2cc3e4c464e1ea1d02268190682d3a39f Mon Sep 17 00:00:00 2001 From: Christian Baroni Date: Wed, 1 Jan 2020 13:45:38 +0100 Subject: [PATCH 629/636] Show copy tooltip onPress instead of onPressIn --- src/components/CopyTooltip.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/CopyTooltip.js b/src/components/CopyTooltip.js index 6a3b0f6f207..73939a17fc3 100644 --- a/src/components/CopyTooltip.js +++ b/src/components/CopyTooltip.js @@ -34,7 +34,7 @@ class CopyTooltip extends PureComponent { handleHideTooltip = () => this.tooltip.hideMenu(); - handlePressIn = () => this.tooltip.showMenu(); + handlePress = () => this.tooltip.showMenu(); handleRef = ref => { this.tooltip = ref; @@ -45,7 +45,7 @@ class CopyTooltip extends PureComponent { {...this.props} actions={[{ onPress: this.handleCopy, text: this.props.tooltipText }]} activeOpacity={this.props.activeOpacity} - onPressIn={this.handlePressIn} + onPress={this.handlePress} ref={this.handleRef} underlayColor={colors.transparent} /> From 81002a683d5a307922c7f6ddeb0e217294a03190 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 6 Jan 2020 17:50:59 -0500 Subject: [PATCH 630/636] Changes after @jinchung code review --- ios/Podfile.lock | 78 ++--- src/hooks/useBiometryType.js | 2 +- src/hooks/useClipboard.js | 2 +- src/screens/QRScannerScreen.js | 1 - yarn.lock | 512 +++++++++++++++++---------------- 5 files changed, 303 insertions(+), 292 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 552a50e96cd..4cb01bf2a6b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -285,17 +285,17 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.15.0): + - react-native-camera (3.15.1): - React - - react-native-camera/RCT (= 3.15.0) - - react-native-camera/RN (= 3.15.0) - - react-native-camera/RCT (3.15.0): + - react-native-camera/RCT (= 3.15.1) + - react-native-camera/RN (= 3.15.1) + - react-native-camera/RCT (3.15.1): - React - - react-native-camera/RN (3.15.0): + - react-native-camera/RN (3.15.1): - React - react-native-mail (4.1.0): - React - - react-native-netinfo (5.0.0): + - react-native-netinfo (5.3.2): - React - react-native-randombytes (3.5.3): - React @@ -306,7 +306,7 @@ PODS: - react-native-text-input-mask (2.0.0): - React - RNInputMask - - react-native-udp (2.6.1): + - react-native-udp (2.7.0): - React - react-native-version-number (0.3.6): - React @@ -421,9 +421,9 @@ PODS: - React - RNSVG (9.13.6): - React - - SDWebImage (5.4.0): - - SDWebImage/Core (= 5.4.0) - - SDWebImage/Core (5.4.0) + - SDWebImage (5.4.1): + - SDWebImage/Core (= 5.4.1) + - SDWebImage/Core (5.4.1) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) @@ -667,10 +667,10 @@ SPEC CHECKSUMS: BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 CodePush: d2e54ad42df82a8db65b2d23d8191b950ba945e1 Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 - DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 + DoubleConversion: cde416483dac037923206447da6e1454df403714 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: f4bf59b48e6732b1b5d328248ab8794130748b92 - FBReactNativeSpec: bed51880b4206526f796433048ca5d929f1cf52d + FBLazyVector: 904ace83555a7813bc9117a045dff654ae711d39 + FBReactNativeSpec: ac66550fd5331a88a825860ae4e45e058571ef73 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -680,8 +680,8 @@ SPEC CHECKSUMS: FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e FirebaseMessaging: 089b7a4991425783384acc8bcefcd78c0af913bd FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 - Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 - glog: 1f3da668190260b06b429bb211bfbee5cd790c28 + Folly: f1c65c1bdabb35617432cac9cf17d0cad310ce6f + glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 GoogleAppMeasurement: dfe55efa543e899d906309eaaac6ca26d249862f GoogleDataTransport: 8e9b210c97d55fbff306cc5468ff91b9cb32dcf5 GoogleDataTransportCCTSupport: 202d7cdf9c4a7d81a2bb7f7e7e1ba6faa421b1f2 @@ -690,35 +690,35 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: adc14902dcd9bd96162bff839191031802d1bbdf - RCTTypeSafety: 1bfc26cae1495204b3ee8e2aa1a416b586be2361 - React: b6779e9431357663e2a761ca8b2384d37b81d585 - React-Core: bbd3079bfbcfab4ccbbff76e508864d5be4c2d9f - React-CoreModules: 88908075a740de7f7772f9f67248af8786c4e892 - React-cxxreact: c8533f3dba7760196f4bd88ef5e1fdacbde47c0b - React-jsi: 654b98b363c44145e9e39901f8be23696b5b69fe - React-jsiexecutor: 808812487bafd8fb39d0aeecd7bea852622a310a - React-jsinspector: 74c057ffb291d70dcf8297f46ba7cafff428e823 + RCTRequired: fc5f657b89514039fccfe826c524126538ef5da3 + RCTTypeSafety: 7860ee3c7d06cd49de0a12dde6784c925853cedf + React: 3da88a786975d0d2244b076b0696411defd3d37c + React-Core: 39042bc55d07e4fabf6588892d9eaf88dca37051 + React-CoreModules: ceae464bbadcbaf58a1031768c137dd88f339f60 + React-cxxreact: 03194eb1b9d558d6f48efa7d41a93b90318c3016 + React-jsi: 22a0960d7040824a23dff7701d7738f3c1d5807f + React-jsiexecutor: 00e5aebe98359d913d43af8cc23d5ebb17083723 + React-jsinspector: 56e72f672b35aeade701012e6e39876897546cfb react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb + react-native-camera: 1ba3e7f2375a6b44ae09ce9be70268e0b225bc10 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 - react-native-netinfo: 841c2a83fe7df998fed56fd48b73229f17a5aa5b + react-native-netinfo: 817823a90f13ced48413875c0820df04c3aae28d react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 - react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 + react-native-udp: ff9d13e523f2b58e6bc5d4d32321ac60671b5dc9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 5de50477a51ffa4bda8b1a2e3a663cd0aa0f248a - React-RCTAnimation: eda92681d80e790260b52ec9935c49917a182cd3 - React-RCTBlob: afa0ba6924c6cf2c471230bf24e03339dddadaa1 - React-RCTImage: eddac7c4a8315fa421a62538667e98daf0108ba8 - React-RCTLinking: b99a0100e0b3ad204de94d1eba9a28996d6ba602 - React-RCTNetwork: 9d78746a30295a327da01f9916b134b71e50f002 - React-RCTSettings: f331fcb5217b2c70b76d6069b512a9b1b732fde1 - React-RCTText: 4f3cb6823a9eabae7068e2a93f3b8d71a8f0a25e - React-RCTVibration: e5a3c9aca8f46c3aadc4da9a0918e32bc192ad51 - ReactCommon: 8d4559452b8c852c80df07ab2db6d71da97ce3a0 + React-RCTActionSheet: 48dc86f556d46f012c92fdc4fce37e2f61972a7a + React-RCTAnimation: f2b22ff8ee4a8f726cb2a2c0489dc43160a9ba78 + React-RCTBlob: e1cc220434c170cfb87972c5f9ddeca42bc859c2 + React-RCTImage: a71a7ae08498f10f025cb3859e623bc35d984ac2 + React-RCTLinking: 8cd1a2e5855917d8202dbbec645ce96a4dc56599 + React-RCTNetwork: 52edddadac17aebf35340cc890d366033bcaa497 + React-RCTSettings: 5ef91ca864871af290fc7f181a1fc8cf931023fa + React-RCTText: ad1509728a06baaf16810c807ae86fd0f94218cd + React-RCTVibration: 72d3e98346f20ac4c59649bff2a02f229048625e + ReactCommon: b3d60106340b0c5cb774de530a3ec44e99d3365e ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -740,14 +740,14 @@ SPEC CHECKSUMS: RNSentry: 9b1d983b2d5d1c215ba6490348fd2a4cc23a8a9d RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f - SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 + SDWebImage: 29c340dbdcef342bb13125553f4e19ce056b07a7 SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 Sentry: 14bdd673870e8cf64932b149fad5bbbf39a9b390 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - Yoga: 613f9f1fadd893d425056f50d642946aa1587728 + Yoga: d35afc581c45e82ecabf981b93d17f02ae19c49f PODFILE CHECKSUM: b931004d050eac701cdeaa72c5a620b2c25d49a0 diff --git a/src/hooks/useBiometryType.js b/src/hooks/useBiometryType.js index e1e1a2274a5..73e6a317f5b 100644 --- a/src/hooks/useBiometryType.js +++ b/src/hooks/useBiometryType.js @@ -44,7 +44,7 @@ export default function useBiometryType() { return () => { mounted = false; }; - }, [biometryType, justBecameActive, prevBiometricType, setBiometryType]); + }, [biometryType, justBecameActive, prevBiometricType]); return biometryType; } diff --git a/src/hooks/useClipboard.js b/src/hooks/useClipboard.js index 07d9e04fb24..bcc749245d5 100644 --- a/src/hooks/useClipboard.js +++ b/src/hooks/useClipboard.js @@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from 'react'; import { Clipboard } from 'react-native'; import useAppState from './useAppState'; -export default function useClipBoard() { +export default function useClipboard() { const { justBecameActive } = useAppState(); const [data, updateClipboardData] = useState(''); diff --git a/src/screens/QRScannerScreen.js b/src/screens/QRScannerScreen.js index 24888abd0b3..fe89d8ad067 100644 --- a/src/screens/QRScannerScreen.js +++ b/src/screens/QRScannerScreen.js @@ -88,7 +88,6 @@ QRScannerScreen.propTypes = { onScanSuccess: PropTypes.func, onSheetLayout: PropTypes.func, sheetHeight: PropTypes.number, - showSheet: PropTypes.bool, walletConnectorsByDappName: PropTypes.arrayOf(PropTypes.object), walletConnectorsCount: PropTypes.number, }; diff --git a/yarn.lock b/yarn.lock index 7e7cf3cae74..15cbe702b47 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,14 +10,14 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.2": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.5.tgz#ae1323cd035b5160293307f50647e83f8ba62f7e" - integrity sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" + integrity sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.4" + "@babel/generator" "^7.7.7" "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.5" + "@babel/parser" "^7.7.7" "@babel/template" "^7.7.4" "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" @@ -29,10 +29,10 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.4.tgz#db651e2840ca9aa66f327dcec1dc5f5fa9611369" - integrity sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4", "@babel/generator@^7.7.7": + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" + integrity sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ== dependencies: "@babel/types" "^7.7.4" jsesc "^2.5.1" @@ -240,10 +240,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.5": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.5.tgz#cbf45321619ac12d83363fcf9c94bb67fa646d71" - integrity sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" + integrity sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw== "@babel/plugin-external-helpers@^7.0.0": version "7.7.4" @@ -277,9 +277,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.7.4" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz#cc57849894a5c774214178c8ab64f6334ec8af71" - integrity sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.7.tgz#9f27075004ab99be08c5c1bd653a2985813cb370" + integrity sha512-3qp9I8lelgzNedI3hrhkvhaEYree6+WHnyA/q4Dza9z7iEIs1eyhWyJnetk3jJ69RT0AT4G0UhEGwyGFJ7GUuQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.7.4" @@ -500,9 +500,9 @@ "@babel/helper-replace-supers" "^7.7.4" "@babel/plugin-transform-parameters@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz#da4555c97f39b51ac089d31c7380f03bca4075ce" - integrity sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.7.tgz#7a884b2460164dc5f194f668332736584c760007" + integrity sha512-OhGSrf9ZBrr1fw84oFXj5hgi8Nmg+E2w5L7NhnG0lPvpDtqd7dbyilM2/vR8CKbJ907RyxPh2kj6sBCSSfI9Ew== dependencies: "@babel/helper-call-delegate" "^7.7.4" "@babel/helper-get-function-arity" "^7.7.4" @@ -531,9 +531,9 @@ "@babel/plugin-syntax-jsx" "^7.7.4" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz#d91205717fae4e2f84d020cd3057ec02a10f11da" - integrity sha512-LixU4BS95ZTEAZdPaIuyg/k8FiiqN9laQ0dMHB4MlpydHY53uQdWCUrwjLr5o6ilS6fAgZey4Q14XBjl5tL6xw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.7.tgz#5cbaa7445b4a09f774029f3cc7bb448ff3122a5d" + integrity sha512-SlPjWPbva2+7/ZJbGcoqjl4LsQaLpKEzxW9hcxU7675s24JmdotJOSJ4cgAbV82W3FcZpHIGmRZIlUL8ayMvjw== dependencies: "@babel/helper-builder-react-jsx" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" @@ -604,9 +604,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/register@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.4.tgz#45a4956471a9df3b012b747f5781cc084ee8f128" - integrity sha512-/fmONZqL6ZMl9KJUYajetCrID6m0xmL4odX7v+Xvoxcv0DdbP/oO0TWIeLUCHqczQ6L6njDMqmqHFy2cp3FFsA== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.7.tgz#46910c4d1926b9c6096421b23d1f9e159c1dcee1" + integrity sha512-S2mv9a5dc2pcpg/ConlKZx/6wXaEwHeqfo7x/QbXsdCAZm+WJC1ekVvL1TVxNsedTs5y/gG63MhJTEsmwmjtiA== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.13" @@ -615,9 +615,9 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": - version "7.7.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" - integrity sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" + integrity sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA== dependencies: regenerator-runtime "^0.13.2" @@ -670,26 +670,26 @@ minimist "^1.2.0" "@emotion/is-prop-valid@^0.8.1": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz#2dda0791f0eafa12b7a0a5b39858405cc7bde983" - integrity sha512-6ZODuZSFofbxSbcxwsFz+6ioPjb0ISJRRPLZ+WIbjcU2IMU0Io+RGQjjaTgOvNQl007KICBm7zXQaYQEC1r6Bg== + version "0.8.6" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.6.tgz#4757646f0a58e9dec614c47c838e7147d88c263c" + integrity sha512-mnZMho3Sq8BfzkYYRVc8ilQTnc8U02Ytp6J1AwM6taQStZ3AhsEJBX2LzhA/LJirNCwM2VtHL3VFIZ+sNJUgUQ== dependencies: - "@emotion/memoize" "0.7.3" + "@emotion/memoize" "0.7.4" -"@emotion/memoize@0.7.3": - version "0.7.3" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78" - integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow== +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== "@emotion/stylis@^0.8.3": - version "0.8.4" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.4.tgz#6c51afdf1dd0d73666ba09d2eb6c25c220d6fe4c" - integrity sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ== + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== "@emotion/unitless@^0.7.0": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.4.tgz#a87b4b04e5ae14a88d48ebef15015f6b7d1f5677" - integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== "@ethersproject/address@^5.0.0-beta.125": version "5.0.0-beta.133" @@ -1085,9 +1085,9 @@ integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== "@react-native-community/netinfo@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.0.0.tgz#c8708558c9a116c138a43bed4bb0b4af85f111bc" - integrity sha512-MDvQ+jh9P1S8/CvxLyDqWFNc31oL5a2UkVtOyGFslLmxbO3Q4h/xFPM+b2NJ97GvQAsdhL18EpOWVu1AXodeFw== + version "5.3.2" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.3.2.tgz#7b6ee417c2a905663e10de176c00eeab09bdd14c" + integrity sha512-npNcLAz6iWzwRNh+0tSFMlR+xkpSz9NWzX+5AxW40KE6qEZGWdE3dtGBKsezMdWD2Fh+6Je6P6hgUEF8xuZrbA== "@react-native-community/push-notification-ios@^1.0.3": version "1.0.3" @@ -1460,9 +1460,9 @@ "@types/istanbul-lib-report" "*" "@types/json-schema@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" - integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== "@types/minimatch@*": version "3.0.3" @@ -1470,9 +1470,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.21" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.21.tgz#aa44a6363291c7037111c47e4661ad210aded23f" - integrity sha512-8sRGhbpU+ck1n0PGAUgVrWrWdjSW2aqNeyC15W88GRsMpSwzv6RJGlLhE7s2RhVSOdyDmxbqlWSeThq4/7xqlA== + version "13.1.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.4.tgz#4cfd90175a200ee9b02bd6b1cd19bc349741607e" + integrity sha512-Lue/mlp2egZJoHXZr4LndxDAd7i/7SQYhV0EjWfb/a4/OZ6tuVwMCVPiwkU5nsEipxEf7hmkSU7Em5VQ8P5NGA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1516,9 +1516,9 @@ integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== "@types/yargs@^13.0.0": - version "13.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" - integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== + version "13.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.4.tgz#53d231cebe1a540e7e13727fc1f0d13ad4a9ba3b" + integrity sha512-Ke1WmBbIkVM8bpvsNEcGgQM70XcEh/nbpxQhW7FhrsbCsXSY9BmLB1+LHtD7r9zrsOcFlLiF+a/UeJsdfw3C5A== dependencies: "@types/yargs-parser" "*" @@ -1569,37 +1569,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -"@walletconnect/core@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.39.tgz#43d05dbabcaeea491c0ee213ed60d2236672010f" - integrity sha512-cJSQe2Ao4okSvohNjA7Bs7Z+0BAznfVVTWBECIX/bGoSFpkAWabGY2Pn2gIYhobQMLSFpE6ZlZ4QfvlPO8HyPw== +"@walletconnect/core@^1.0.0-beta.42": + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.42.tgz#cb9b098590255577571a90b9bda83a0f920020d8" + integrity sha512-Q7pDpTj2/bm7rkAbI+5/mf7SdurLXDfznjvE6jZGg8o23wsYamnkwLnqVMkqeFyUjY7bpHxWqakY813wmmlrZw== dependencies: - "@walletconnect/types" "^1.0.0-beta.39" - "@walletconnect/utils" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.42" + "@walletconnect/utils" "^1.0.0-beta.42" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.39.tgz#0db212eba9087055822a89bf73d1cebc5762639e" - integrity sha512-d/QAjL/Rp1lrJeblsHpl+Fa6HTz40A93X5l6oTV0YFAG7bZDPl+OogM337WnjZWfwcn1XaKXSwsmG1NXTQn4Yg== + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.42.tgz#3e703a62d80db6f10470ecdd443a3c4025973e3f" + integrity sha512-pcgIx+d4LFjXAgI8+n60fqh5YN/YiVtGhcqdVC/9dadcV/9C0YkFYQiYAXNqXPx/FzaA0+4X8PSyEZY4P61A7g== dependencies: - "@walletconnect/core" "^1.0.0-beta.39" - "@walletconnect/types" "^1.0.0-beta.39" - "@walletconnect/utils" "^1.0.0-beta.39" + "@walletconnect/core" "^1.0.0-beta.42" + "@walletconnect/types" "^1.0.0-beta.42" + "@walletconnect/utils" "^1.0.0-beta.42" -"@walletconnect/types@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.39.tgz#e84463f32d6c450376db3d0ce56f0ece6608bfa7" - integrity sha512-YO/g1HVnFxcMNiUI9LEWEDe5uVHw8D7JzJol+bT71iXymzolnsbG32OayCJM9nHqT48Rpz1EGIno8EjW9jH2OQ== +"@walletconnect/types@^1.0.0-beta.42": + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.42.tgz#1a0db31b37b7765985f78e2b0f2942407685cdcf" + integrity sha512-YBpcYdYGEacOob5VF0/8LRGz/uGynFcwoj9RIEOkDl9JqGQMaXhlZ1M48AfEp8NVQvXRF+cSc3moPDwu3+9USw== -"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.39.tgz#8909b9cffa3999b046ce32cbb21b8ddca97b9183" - integrity sha512-AOlhPkK+IUzGG5iDTupKdUwNW4on1aAj5NyLMMN1+htr06hqaCV8F9HeYibSen22wdSUuLXkIQNy3SR3LPcehA== +"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.42": + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.42.tgz#60304d0ed902a532ac9e535905b5a1c4c8063069" + integrity sha512-/eLcm+tEcvqlYaEaG/L7c+3uNrugZs3a30bwYUbNvlmzYWTNBzU/EV18CGavlZLc/Pb2XtPXevGtDsLlvtR7/Q== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.42" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1840,9 +1840,9 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" - integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== dependencies: "@types/color-name" "^1.1.1" color-convert "^2.0.1" @@ -1929,12 +1929,13 @@ array-find-index@^1.0.1: integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-includes@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.0.tgz#48a929ef4c6bb1fa6dc4a92c9b023a261b0ca404" - integrity sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ== + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== dependencies: define-properties "^1.1.3" - es-abstract "^1.17.0-next.0" + es-abstract "^1.17.0" + is-string "^1.0.5" array-map@~0.0.0: version "0.0.0" @@ -2055,7 +2056,7 @@ asyncstorage-down@^4.2.0: ltgt "^2.1.3" tiny-queue "0.2.0" -atob@^2.1.1: +atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -2535,13 +2536,13 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.8.0: - version "4.8.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" - integrity sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA== + version "4.8.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.3.tgz#65802fcd77177c878e015f0e3189f2c4f627ba44" + integrity sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg== dependencies: - caniuse-lite "^1.0.30001015" + caniuse-lite "^1.0.30001017" electron-to-chromium "^1.3.322" - node-releases "^1.1.42" + node-releases "^1.1.44" bser@2.1.1: version "2.1.1" @@ -2711,10 +2712,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001015: - version "1.0.30001016" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001016.tgz#16ea48d7d6e8caf3cad3295c2d746fe38c4e7f66" - integrity sha512-yYQ2QfotceRiH4U+h1Us86WJXtVHDmy3nEKIdYPsZCYnOV5/tMgGbmoIlrMzmh2VXlproqYtVaKeGDBkMZifFA== +caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001017: + version "1.0.30001019" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001019.tgz#857e3fccaad2b2feb3f1f6d8a8f62d747ea648e1" + integrity sha512-6ljkLtF1KM5fQ+5ZN0wuyVvvebJxgJPTmScOMaFuQN2QuOzvRJnWSKfzQskQU5IOU4Gap3zasYPIinzwUjoj/g== capture-exit@^2.0.0: version "2.0.0" @@ -2992,15 +2993,13 @@ code-push@^2.0.6: yazl "^2.4.1" code-push@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.0.1.tgz#d6d48b1e112a49148b2244b0213afaf3f818645b" - integrity sha512-UgktdhS47nxtUdGB1l4D6JBnuGB20hMT7QswGj6gQgQbiTjSmOBJ0MK/09fyeYzWKjUnJBEmUud08rC7WzKFMw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.1.0.tgz#02b43b8f8cae1d8d281437aa5635c288399a48ca" + integrity sha512-SwEWx/MLEkRh/oXw4kvi8AIVzR7R2HFWKjsZwX3BWMLEudus3kekwuO2ufk9nYxHcDBZjUfao0G3HIkV9P2Cbw== dependencies: q "^1.4.1" recursive-fs "^1.1.2" - slash "3.0.0" - superagent "^5.1.0" - superagent-proxy "^2.0.0" + slash "^3.0.0" yazl "^2.4.1" collapse-white-space@^1.0.2: @@ -3103,11 +3102,11 @@ component-inherit@0.0.3: integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= compressible@~2.0.16: - version "2.0.17" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" - integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== dependencies: - mime-db ">= 1.40.0 < 2" + mime-db ">= 1.43.0 < 2" compression@^1.7.1: version "1.7.4" @@ -3438,9 +3437,9 @@ date-fns@^1.30.1: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.8.15: - version "1.8.18" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.18.tgz#c9b3fcd5a8eca96ed20a907f4491516d6eda15c9" - integrity sha512-JBMJZghNK8TtuoPnKNIzW9xavVVigld/zmZNpZSyQbkb2Opp55YIfZUpE4OEqPF/iyUVQTKcn1bC2HtC8B7s3g== + version "1.8.19" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe" + integrity sha512-7kqOoj3oQSmqbvtvGFLU5iYqies+SqUiEGNT0UtUPPxcPYgY1BrkXR0Cq2R9HYSimBXN+xHkEN4Hi399W+Ovlg== debounce@^1.2.0: version "1.2.0" @@ -3797,9 +3796,9 @@ ejs@^3.0.1: integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw== electron-to-chromium@^1.3.322: - version "1.3.322" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" - integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA== + version "1.3.327" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.327.tgz#516f28b4271727004362b4ac814494ae64d9dde7" + integrity sha512-DNMd91VtKt44LIkFtpICxAWu/GSGFLUMDM/kFINJ3Oe47OimSnbMvO3ChkUCdUyit+pRdhdCcM3+i5bpli5gqg== elliptic@6.5.2, elliptic@^6.0.0: version "6.5.2" @@ -3901,11 +3900,11 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.4.tgz#a757397dc5d9de973ac9a5d7d4e8ade7cfae9101" - integrity sha512-fZ0KkoxSjLFmhW5lHbUT3tLwy3nX1qEzMYo8koY1vrsAco53CMT1djnBSeC/wUjTEZRhZl9iRw7PaMaxfJ4wzQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== dependencies: - stackframe "^1.1.0" + stackframe "^1.1.1" errorhandler@^1.5.0: version "1.5.1" @@ -3915,22 +3914,22 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1: - version "1.17.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" - integrity sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw== +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" + integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.4" - is-regex "^1.0.4" + is-callable "^1.1.5" + is-regex "^1.0.5" object-inspect "^1.7.0" object-keys "^1.1.1" object.assign "^4.1.0" - string.prototype.trimleft "^2.1.0" - string.prototype.trimright "^2.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -3990,9 +3989,9 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.x.x, escodegen@^1.9.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" - integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== + version "1.12.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.1.tgz#08770602a74ac34c7a90ca9229e7d51e379abc76" + integrity sha512-Q8t2YZ+0e0pc7NRVj3B4tSQ9rim1oi4Fh46k2xhJ2qOiEwhQfdjyEQddWdj7ZFaKmU+5104vn1qrcjEPWq+bgQ== dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -4192,9 +4191,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.6.0: - version "6.7.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" - integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4288,9 +4287,9 @@ eth-contract-metadata@^1.9.3: integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA== ethers@^4.0.28, ethers@^4.0.39: - version "4.0.40" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.40.tgz#6e1963d10b5d336a13cd81b519c230cc17624653" - integrity sha512-MC9BtV7Hpq4dgFONEfanx9aU9GhhoWU270F+/wegHZXA7FR+2KXFdt36YIQYLmVY5ykUWswDxd+f9EVkIa7JOA== + version "4.0.42" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.42.tgz#7def83a1f770b84d44cf1c2dfc58b7fd29d1d45d" + integrity sha512-2gmmt5x683Xz4QwGDBVJhrdXevVAEr5fnXPGDPou2AKB+zklrirGpl0w1SHBn7Wa9hbL2z6MvP3n7k8Yss2MFg== dependencies: aes-js "3.0.0" bn.js "^4.4.0" @@ -5420,9 +5419,9 @@ husky@^2.4.0: slash "^3.0.0" i18n-js@^3.0.11: - version "3.5.0" - resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.0.tgz#e2c41e1f90405d691d33ddce260f3dff9743215e" - integrity sha512-XosH7plfEisWo5XEYxkdlwONsDVQ3sYI3ZoKXcjXdyq+9eVNIJg2h2oPsgadfqcXxpPHMVMNBgmiyW3aEJXg1g== + version "3.5.1" + resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.1.tgz#9787450894059bec1af791123231e59898eb97c1" + integrity sha512-nJgbE5Vj9qzOQfjdVd/uoMoO8ppVaB/3LB6KOmMfD8IQ1vNNh307iHyQLK8ZnLYWkAszfPvVpYmUt1Le/RuHMQ== i18next@^17.0.3: version "17.3.1" @@ -5466,9 +5465,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.2.tgz#34eb50c69abb8c04acd0f942244c5eefe62a4e4e" - integrity sha512-O3MChd2M5aOt7NNVRTnH8Wt+Mu+degWN4WsS3U+f1ggM2nMPO+cj/JJobgBUz4WeEEPxKIQO6sN/Dq5hnOmqaQ== + version "5.1.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-5.1.0.tgz#38d9eba40dbb0389b7ae7b8b99e4661df0cf89e3" + integrity sha512-t6gyFtTcokCuI0tX9KQZJQAkIjSqo/nTeJnwojfty69EzrorZbywwhZ8qNNlF+faajHeRnhOvM2F40KHLFCghQ== import-fresh@^2.0.0: version "2.0.0" @@ -5631,9 +5630,9 @@ inquirer@^6.2.0: through "^2.3.6" inquirer@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.1.tgz#13f7980eedc73c689feff3994b109c4e799c6ebb" - integrity sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw== + version "7.0.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.2.tgz#b39b205b95c9424839a1fd991d60426cf9bbc0e9" + integrity sha512-cZGvHaHwcR9E3xK9EGO5pHKELU+yaeJO7l2qGKIbqk4bCuDuAn15LCoUTS2nSkfv9JybFlnAGrOcVpCDZZOLhw== dependencies: ansi-escapes "^4.2.1" chalk "^2.4.2" @@ -5728,10 +5727,10 @@ is-buffer@^2.0.0, is-buffer@^2.0.2, is-buffer@~2.0.3: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== is-ci@^1.0.10: version "1.2.1" @@ -5762,9 +5761,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== is-decimal@^1.0.0: version "1.0.3" @@ -5916,7 +5915,7 @@ is-redirect@^1.0.0: resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= -is-regex@^1.0.4: +is-regex@^1.0.4, is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== @@ -5943,6 +5942,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -5956,9 +5960,9 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-what@^3.3.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.4.0.tgz#a9b3fe0c22f52d49efef977f640da44e65a3f866" - integrity sha512-oFdBRuSY9PocqPoUUseDXek4I+A1kWGigZGhuG+7GEkp0tRkek11adc0HbTEVsNvtojV7rp0uhf5LWtGvHzoOQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.5.0.tgz#c50b0e8f3021e0b39410c159bea43a5510d99027" + integrity sha512-00pwt/Jf7IaRh5m2Dp93Iw8LG2cd3OpDj3NrD1XPNUpAWVxPvBP296p4IiGmIU4Ur0f3f56IoIM+fS2pFYF+tQ== is-whitespace-character@^1.0.0: version "1.0.3" @@ -6086,9 +6090,9 @@ istanbul-reports@^2.2.6: handlebars "^4.1.2" iterall@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" - integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== jest-changed-files@^24.9.0: version "24.9.0" @@ -7472,10 +7476,10 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== mime-db@~1.23.0: version "1.23.0" @@ -7490,11 +7494,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== dependencies: - mime-db "1.42.0" + mime-db "1.43.0" mime@1.6.0: version "1.6.0" @@ -7834,10 +7838,10 @@ node-pre-gyp@*: semver "^5.3.0" tar "^4.4.2" -node-releases@^1.1.42: - version "1.1.43" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.43.tgz#2c6ca237f88ce11d49631f11190bb01f8d0549f2" - integrity sha512-Rmfnj52WNhvr83MvuAWHEqXVoZXCcDQssSOffU4n4XOL9sPrP61mSZ88g25NqmABDvH7PiAlFCzoSCSdzA293w== +node-releases@^1.1.44: + version "1.1.44" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.44.tgz#cd66438a6eb875e3eb012b6a12e48d9f4326ffd7" + integrity sha512-NwbdvJyR7nrcGrXvKAvzc5raj/NkoJudkarh2yIpJ4t0NH4aqjUDz/486P+ynIW5eokKOfzGNRdYoLfBlomruw== dependencies: semver "^6.3.0" @@ -7921,9 +7925,9 @@ npm-run-path@^2.0.0: path-key "^2.0.0" npm-run-path@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.0.tgz#d644ec1bd0569187d2a52909971023a0a58e8438" - integrity sha512-8eyAOAH+bYXFPSnNnKr3J+yoybe8O87Is5rtAQ8qRczJz1ajcsjg8l2oZqP+Ppx15Ii3S1vUTjQN2h4YO2tWWQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" @@ -8302,9 +8306,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== dependencies: p-try "^2.0.0" @@ -8598,9 +8602,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.1.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5" - integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA== + version "2.2.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" + integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== pify@^2.0.0: version "2.3.0" @@ -8804,9 +8808,9 @@ postcss-value-parser@^4.0.2: integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.7: - version "7.0.25" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.25.tgz#dd2a2a753d50b13bed7a2009b4a18ac14d9db21e" - integrity sha512-NXXVvWq9icrm/TgQC0O6YVFi4StfJz46M1iNd/h6B26Nvh/HKI+q4YZtFN/EjcInZliEscO/WL10BXnc1E5nwg== + version "7.0.26" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587" + integrity sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -8954,9 +8958,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: - version "1.6.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" - integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" + integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== public-encrypt@^4.0.0: version "4.0.3" @@ -9104,9 +9108,9 @@ react-coin-icon@0.1.13: styled-components "4.4.1" react-devtools-core@^4.0.6: - version "4.2.1" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.2.1.tgz#0122ccb8a041b0b61811425a57e9dec05125e9d8" - integrity sha512-Puo0PwkpxWZY4E0cU7lpOR6Lh5UhGoOScSdhVtvK6HK6InC6+k9ypyVHI2ar2OoBasm3wP5mJlDHcUmbmqF78w== + version "4.4.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.4.0.tgz#614cabe5f3d6fb69730dc76da10f8fa4eb033695" + integrity sha512-ayyz+clbjekj5rqTjieI/eE0xGZkgotklVnxfa4Pyk9se5+AHUAhUwMhLvK5N2+mR2PGOZkv159RDTmvgs+wZQ== dependencies: es6-symbol "^3" shell-quote "^1.6.1" @@ -9150,9 +9154,9 @@ react-native-bundle-visualizer@^2.0.1: source-map-explorer "^2.1.2" react-native-camera@^3.9.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.0.tgz#dd8c7fcf75b347e0b07c1dedeba2ba47504ff80a" - integrity sha512-GoRq2gHMvidcMCzj0AjaIbrJy5ZRE1XxLUIGN+M/Ev2r2RXGFWBToGoDvy4KZcwF3THWefVAZL1It+fT8pvxgQ== + version "3.15.1" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.1.tgz#8e4eb67cb6687b5250f849b348f0d19a01649105" + integrity sha512-xj1sljzFq8HVX22d2T945dsJdK/KFb3jaXUHEYGwMp/zz0ypIs3mY3NezdpyYpS1ioKKzdIcLrxz2VKzDCXaCg== dependencies: prop-types "^15.6.2" @@ -9317,12 +9321,12 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/abada27d23b37be466c4f4f6f1e8206983d35d07" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/1ea8cc3d8b713d4bac2529c010b035c6d1529df4" react-native-redash@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.0.0.tgz#3fe5426c982a036cc4e7b2df9a94bd210ddd5750" - integrity sha512-2OV8ECpI6ruCwGA3nkhv1j3dGLUhoUVVDwgzAwOfhFrF3LglUaDhT8IG3DQFw7Q5sUuyPQY7HjLu9P0VkQ94LA== + version "9.5.4" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.5.4.tgz#61871ef547c1b505e66b2fcdf1eef26db0ad6c0b" + integrity sha512-1NfBORcLESwtkDyZD0dyK/mdkr9YJ7IQ4zlxSQpqMLr/KOgNp3Hsri+cJe/dqfwRhyCPo64DSJgvFQu3kYT/kw== dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -9413,9 +9417,9 @@ react-native-tooltip@marcosrdz/react-native-tooltip#master: resolved "https://codeload.github.com/marcosrdz/react-native-tooltip/tar.gz/e0e88d212b5b7f350e5eabba87f588a32e0f2590" react-native-udp@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.6.1.tgz#ce9f2479f8af6d1bb356cfee69c89cf92fdd50be" - integrity sha512-KctAXtfBjRe+rGLvms92C82MsrZUwUyODwGskY6mDPigMaDTmsKdNqLCXgWh0g6ZmB2UtOzFsbPphy36NyM3KA== + version "2.7.0" + resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.7.0.tgz#d04c5100fcbff343f8a2bf35a3025743d8960f93" + integrity sha512-tT+Wn0yLbdaTohXkGGor0HYgScGaASWCaCLSO1kCIUdNke7AtcOX5a5nfNLYrEjdUn7/2HRofuplyky7iJHSQA== dependencies: base64-js "0.0.8" events "^1.0.2" @@ -9430,7 +9434,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/048f88a33a53ebd4e45865b319c42291f1d6c7f2" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/bd0c37e456392090507f227b8fb90c1eb7c3d327" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0" @@ -9637,9 +9641,9 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea string_decoder "~0.10.x" readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -9739,9 +9743,9 @@ redux-thunk@^2.3.0: integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== redux@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796" - integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q== + version "4.0.5" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" + integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== dependencies: loose-envify "^1.4.0" symbol-observable "^1.2.0" @@ -9834,9 +9838,9 @@ regjsgen@^0.5.0: integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== regjsparser@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.1.tgz#5b6b28c418f312ef42898dc6865ae2d4b9f0f7a2" - integrity sha512-7LutE94sz/NKSYegK+/4E77+8DipxF+Qn2Tmu362AcmsF2NYq/wx3+ObvU90TKEhjf7hQoFXo23ajjrXP7eUgg== + version "0.6.2" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.2.tgz#fd62c753991467d9d1ffe0a9f67f27a529024b96" + integrity sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q== dependencies: jsesc "~0.5.0" @@ -10179,9 +10183,9 @@ rxjs@^5.4.3: symbol-observable "1.0.1" rxjs@^6.4.0, rxjs@^6.5.3: - version "6.5.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" - integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== dependencies: tslib "^1.9.0" @@ -10584,9 +10588,9 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.2.tgz#305d61efbb1d1ebbf24a9fffef718635054d509c" - integrity sha512-rgujHHHwf0/HCSTFbdTPJETGTgbGqVDD068Ob/wfV41u3AdU8iknSvGTDoU8vCIUeZuLnHX4JYsQ1RMd129XCQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.2.1.tgz#4bd236a1fe73e8b9db475f60197c48fc041928b8" + integrity sha512-vfjS5IRaENgXtTq2Bym0ctEorYGYNHLVCVZZeL1fvkD5iBoWKMlUhF/oFBTcTn9cxry1flplyvk0QGTROafB3Q== dependencies: btoa "^1.2.1" chalk "^3.0.0" @@ -10598,14 +10602,14 @@ source-map-explorer@^2.1.2: open "^7.0.0" source-map "^0.7.3" temp "^0.9.1" - yargs "^15.0.2" + yargs "^15.1.0" source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: - atob "^2.1.1" + atob "^2.1.2" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" @@ -10721,29 +10725,29 @@ stable@^0.1.8: integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-generator@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.4.tgz#027513eab2b195bbb43b9c8360ba2dd0ab54de09" - integrity sha512-ha1gosTNcgxwzo9uKTQ8zZ49aUp5FIUW58YHFxCqaAHtE0XqBg0chGFYA1MfmW//x1KWq3F4G7Ug7bJh4RiRtg== + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== dependencies: - stackframe "^1.1.0" + stackframe "^1.1.1" stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== -stackframe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83" - integrity sha512-Vx6W1Yvy+AM1R/ckVwcHQHV147pTPBKWCRLrXMuPrFVfvBUc3os7PR1QLIWCMhPpRg5eX9ojzbQIMLGBwyLjqg== +stackframe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.1.tgz#ffef0a3318b1b60c3b58564989aca5660729ec71" + integrity sha512-0PlYhdKh6AfFxRyK/v+6/k+/mMfyiEBbTM5L94D0ZytQnJ166wuwoTYLHFWGbs2dpA8Rgq763KGWmN1EQEYHRQ== stacktrace-gps@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.3.tgz#b89f84cc13bb925b96607e737b617c8715facf57" - integrity sha512-51Rr7dXkyFUKNmhY/vqZWK+EvdsfFSRiQVtgHTFlAdNIYaDD7bVh21yBHXaNWAvTD+w+QSjxHg7/v6Tz4veExA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== dependencies: source-map "0.5.6" - stackframe "^1.1.0" + stackframe "^1.1.1" stacktrace-js@^2.0.0: version "2.0.1" @@ -10850,18 +10854,18 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimleft@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" - integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" -string.prototype.trimright@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" - integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" @@ -11079,9 +11083,9 @@ superagent-proxy@^2.0.0: proxy-agent "3" superagent@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.2.tgz#b122f3a62b14c4d638612667033a7eb43c4f4d83" - integrity sha512-VwPCbi9H02qDtTbdY+e3+cK5XR0YHsJy9hmeCOXLQ8ezjq8+S1Bs4MdNRmpmf2QjDBetD7drG7/nEta7E3E6Sg== + version "5.1.3" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.3.tgz#9502db541559d3d9e7acfa30f70d1186c0faa88d" + integrity sha512-2bno1Nb4uvZPECTJ7NDYlae6Q8LLQoZZZ9Vumd346jU1UGVkNC/lQI42jHwtrqVoepyt0QxNKFty01IRKgD4CA== dependencies: component-emitter "^1.3.0" cookiejar "^2.1.2" @@ -11518,9 +11522,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= ua-parser-js@^0.7.18: - version "0.7.20" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" - integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== + version "0.7.21" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" + integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ== uglify-es@^3.1.9: version "3.3.9" @@ -11531,9 +11535,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.7.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" - integrity sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== + version "3.7.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a" + integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -12153,7 +12157,7 @@ xcode@1.0.0: simple-plist "^0.2.1" uuid "3.0.1" -xcode@2.0.0, xcode@^2.0.0: +xcode@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.0.0.tgz#134f1f94c26fbfe8a9aaa9724bfb2772419da1a2" integrity sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw== @@ -12161,6 +12165,14 @@ xcode@2.0.0, xcode@^2.0.0: simple-plist "^1.0.0" uuid "^3.3.2" +xcode@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.1.0.tgz#bab64a7e954bb50ca8d19da7e09531c65a43ecfe" + integrity sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ== + dependencies: + simple-plist "^1.0.0" + uuid "^3.3.2" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -12189,9 +12201,9 @@ xmldoc@^1.1.2: sax "^1.2.1" xmldom@0.1.x: - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" + integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== xmlhttprequest-ssl@~1.5.4: version "1.5.5" @@ -12337,10 +12349,10 @@ yargs@^12.0.2, yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^15.0.2: - version "15.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.0.2.tgz#4248bf218ef050385c4f7e14ebdf425653d13bd3" - integrity sha512-GH/X/hYt+x5hOat4LMnCqMd8r5Cv78heOMIJn1hr7QPPBqfeC6p89Y78+WB9yGDvfpCvgasfmWLzNzEioOUD9Q== +yargs@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" + integrity sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg== dependencies: cliui "^6.0.0" decamelize "^1.2.0" From e391616f7c71a232eaf9a19c04d9c81c7412ec10 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Mon, 6 Jan 2020 18:00:57 -0500 Subject: [PATCH 631/636] Changes after @jinchung code review (continued..) --- src/hooks/useAppState.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hooks/useAppState.js b/src/hooks/useAppState.js index f2966cad7c2..cbcb4685662 100644 --- a/src/hooks/useAppState.js +++ b/src/hooks/useAppState.js @@ -9,8 +9,7 @@ const AppStateTypes = { }; export default function useAppState() { - const currentState = AppState.currentState; - const [appState, setAppState] = useState(currentState); + const [appState, setAppState] = useState(AppState.currentState); const prevAppState = usePrevious(appState); function onChange(newState) { @@ -20,7 +19,7 @@ export default function useAppState() { useEffect(() => { AppState.addEventListener('change', onChange); return () => AppState.removeEventListener('change', onChange); - }); + }, []); return { appState, From be62888700ad5b2b4da821be92ebe2cd3d489726 Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 7 Jan 2020 17:34:37 -0500 Subject: [PATCH 632/636] Revert "Merge pull request #290 from rainbow-me/better-biometric-button" This reverts commit 835faf9210f8b7d463818389d285f21149f9e53d, reversing changes made to 9cf1bac18fcc7d9a864c103efd1994c23b3fa4eb. --- ios/Podfile.lock | 126 ++-- package.json | 14 +- patches/react-native-keychain+4.0.3.patch | 13 - src/App.js | 15 +- src/components/OfflineBadge.js | 98 +-- src/components/animations/ScaleInAnimation.js | 2 +- src/components/animations/index.js | 2 +- src/components/asset-list/AssetList.js | 14 +- .../HoldToAuthorizeButton.js | 184 +++--- .../HoldToAuthorizeButtonIcon.js | 23 +- .../exchange/ConfirmExchangeButton.js | 30 +- src/components/gas/GasSpeedLabelPagerItem.js | 4 +- src/components/icons/BiometryIcon.js | 78 ++- src/components/icons/Icon.js | 2 - src/components/icons/svg/FaceIdIcon.js | 5 +- src/components/icons/svg/PasscodeIcon.js | 37 -- .../qrcode-scanner/QRCodeScanner.js | 149 ++--- src/components/send/SendButton.js | 3 +- .../settings-menu/SettingsSection.js | 4 +- src/handlers/localstorage/uniswap.js | 4 +- src/hoc/index.js | 1 + src/hoc/withNetInfo.js | 23 + src/hoc/withUniswapAssets.js | 19 +- src/hooks/index.js | 5 - src/hooks/useAppState.js | 30 - src/hooks/useBiometryType.js | 50 -- src/hooks/useClipboard.js | 26 - src/hooks/useInternetStatus.js | 27 - src/hooks/usePrevious.js | 11 - src/redux/uniswap.js | 13 +- src/references/index.js | 9 - src/screens/ImportSeedPhraseSheet.js | 2 +- src/screens/QRScannerScreen.js | 137 +++-- src/screens/TransactionConfirmationScreen.js | 34 +- src/utils/deviceUtils.js | 3 +- src/utils/haptics.js | 23 - src/utils/index.js | 1 - yarn.lock | 577 +++++++++--------- 38 files changed, 797 insertions(+), 1001 deletions(-) delete mode 100644 patches/react-native-keychain+4.0.3.patch delete mode 100644 src/components/icons/svg/PasscodeIcon.js create mode 100644 src/hoc/withNetInfo.js delete mode 100644 src/hooks/index.js delete mode 100644 src/hooks/useAppState.js delete mode 100644 src/hooks/useBiometryType.js delete mode 100644 src/hooks/useClipboard.js delete mode 100644 src/hooks/useInternetStatus.js delete mode 100644 src/hooks/usePrevious.js delete mode 100644 src/utils/haptics.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5f00b27fd43..3a6fed86986 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -55,7 +55,7 @@ PODS: - FirebaseCore (~> 6.0) - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/UserDefaults (~> 6.0) - - FirebaseMessaging (4.1.10): + - FirebaseMessaging (4.1.9): - FirebaseAnalyticsInterop (~> 1.3) - FirebaseCore (~> 6.2) - FirebaseInstanceID (~> 4.1) @@ -82,26 +82,26 @@ PODS: - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (= 0.3.9011) - GoogleDataTransport (3.2.0) - - GoogleDataTransportCCTSupport (1.2.3): + - GoogleDataTransportCCTSupport (1.2.2): - GoogleDataTransport (~> 3.2) - nanopb (~> 0.3.901) - - GoogleUtilities/AppDelegateSwizzler (6.4.0): + - GoogleUtilities/AppDelegateSwizzler (6.3.2): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.4.0) - - GoogleUtilities/Logger (6.4.0): + - GoogleUtilities/Environment (6.3.2) + - GoogleUtilities/Logger (6.3.2): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.4.0): + - GoogleUtilities/MethodSwizzler (6.3.2): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.4.0): + - GoogleUtilities/Network (6.3.2): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.4.0)" - - GoogleUtilities/Reachability (6.4.0): + - "GoogleUtilities/NSData+zlib (6.3.2)" + - GoogleUtilities/Reachability (6.3.2): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.4.0): + - GoogleUtilities/UserDefaults (6.3.2): - GoogleUtilities/Logger - JWT (3.0.0-beta.12): - Base64 (~> 1.1.2) @@ -285,17 +285,17 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.15.1): + - react-native-camera (3.15.0): - React - - react-native-camera/RCT (= 3.15.1) - - react-native-camera/RN (= 3.15.1) - - react-native-camera/RCT (3.15.1): + - react-native-camera/RCT (= 3.15.0) + - react-native-camera/RN (= 3.15.0) + - react-native-camera/RCT (3.15.0): - React - - react-native-camera/RN (3.15.1): + - react-native-camera/RN (3.15.0): - React - react-native-mail (4.1.0): - React - - react-native-netinfo (5.3.2): + - react-native-netinfo (4.7.0): - React - react-native-randombytes (3.5.3): - React @@ -306,7 +306,7 @@ PODS: - react-native-text-input-mask (2.0.0): - React - RNInputMask - - react-native-udp (2.7.0): + - react-native-udp (2.6.1): - React - react-native-version-number (0.3.6): - React @@ -380,7 +380,7 @@ PODS: - React - RNCPushNotificationIOS (1.0.3): - React - - RNDeviceInfo (5.3.1): + - RNDeviceInfo (2.3.2): - React - RNFastImage (7.0.2): - React @@ -402,7 +402,7 @@ PODS: - RNGestureHandler (1.5.2): - React - RNInputMask (4.1.0) - - RNKeychain (4.0.3): + - RNKeychain (4.0.1): - React - RNLanguages (3.0.2): - React @@ -414,16 +414,16 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React - - RNSentry (1.2.1): + - RNSentry (1.2.0): - React - Sentry (~> 4.4.0) - RNStoreReview (0.1.5): - React - - RNSVG (9.13.6): + - RNSVG (9.13.3): - React - - SDWebImage (5.4.1): - - SDWebImage/Core (= 5.4.1) - - SDWebImage/Core (5.4.1) + - SDWebImage (5.4.0): + - SDWebImage/Core (= 5.4.0) + - SDWebImage/Core (5.4.0) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) @@ -437,6 +437,8 @@ PODS: - React - ToolTipMenu (5.2.1): - React + - TouchID (4.4.1): + - React - Yoga (1.14.0) DEPENDENCIES: @@ -505,6 +507,7 @@ DEPENDENCIES: - SRSRadialGradient (from `../node_modules/react-native-radial-gradient/ios`) - TcpSockets (from `../node_modules/react-native-tcp`) - ToolTipMenu (from `../node_modules/react-native-tooltip`) + - TouchID (from `../node_modules/react-native-touch-id`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -657,6 +660,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-tcp" ToolTipMenu: :path: "../node_modules/react-native-tooltip" + TouchID: + :path: "../node_modules/react-native-touch-id" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -667,10 +672,10 @@ SPEC CHECKSUMS: BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 CodePush: d2e54ad42df82a8db65b2d23d8191b950ba945e1 Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 - DoubleConversion: cde416483dac037923206447da6e1454df403714 + DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 904ace83555a7813bc9117a045dff654ae711d39 - FBReactNativeSpec: ac66550fd5331a88a825860ae4e45e058571ef73 + FBLazyVector: 9937910f2681d66c0d28631d16058aeec6b1d009 + FBReactNativeSpec: 84bac6a4bcb261924c1e19c60833d0916439dba9 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -678,76 +683,77 @@ SPEC CHECKSUMS: FirebaseCoreDiagnostics: 511f4f3ed7d440bb69127e8b97c2bc8befae639e FirebaseCoreDiagnosticsInterop: e9b1b023157e3a2fc6418b5cb601e79b9af7b3a0 FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e - FirebaseMessaging: 089b7a4991425783384acc8bcefcd78c0af913bd + FirebaseMessaging: e8d71368a5c579083da02203146c953f3386d503 FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 - Folly: f1c65c1bdabb35617432cac9cf17d0cad310ce6f - glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 + Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 + glog: 1f3da668190260b06b429bb211bfbee5cd790c28 GoogleAppMeasurement: dfe55efa543e899d906309eaaac6ca26d249862f GoogleDataTransport: 8e9b210c97d55fbff306cc5468ff91b9cb32dcf5 - GoogleDataTransportCCTSupport: 202d7cdf9c4a7d81a2bb7f7e7e1ba6faa421b1f2 - GoogleUtilities: 29bd0d8f850efbd28cff6d99e8b7da1f8d236bcf + GoogleDataTransportCCTSupport: ef79a4728b864946a8aafdbab770d5294faf3b5f + GoogleUtilities: 547a86735c6f0ee30ad17e94df4fc21f616b71cb JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: fc5f657b89514039fccfe826c524126538ef5da3 - RCTTypeSafety: 7860ee3c7d06cd49de0a12dde6784c925853cedf - React: 3da88a786975d0d2244b076b0696411defd3d37c - React-Core: 39042bc55d07e4fabf6588892d9eaf88dca37051 - React-CoreModules: ceae464bbadcbaf58a1031768c137dd88f339f60 - React-cxxreact: 03194eb1b9d558d6f48efa7d41a93b90318c3016 - React-jsi: 22a0960d7040824a23dff7701d7738f3c1d5807f - React-jsiexecutor: 00e5aebe98359d913d43af8cc23d5ebb17083723 - React-jsinspector: 56e72f672b35aeade701012e6e39876897546cfb + RCTRequired: 8261e5489a9c6a59fc1fb2ad37966ac8c76fd674 + RCTTypeSafety: cfe8ceac14dd07464e36cc5a6db4d60c89c8d0c4 + React: 1594d3f52fc5de51b1e55a521f93d07d68b814fb + React-Core: 4d1aba76c386522959c0d3d4e51ebb0554ad015f + React-CoreModules: 3a9d2a1c2df1936927163a19fdb0f2a5a13c1d76 + React-cxxreact: 06df23866978079cfb525c68bf8b59bb52884a4e + React-jsi: a9e632da28b1168e8b41e92cc69c5c88d1af4642 + React-jsiexecutor: 8e5e9d516a76c5ebbd5fa557a371de68f7b9d2b6 + React-jsinspector: beded58f6e205bc58a38a3c57ce87443d7d20848 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 1ba3e7f2375a6b44ae09ce9be70268e0b225bc10 + react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 - react-native-netinfo: 817823a90f13ced48413875c0820df04c3aae28d + react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 - react-native-udp: ff9d13e523f2b58e6bc5d4d32321ac60671b5dc9 + react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 48dc86f556d46f012c92fdc4fce37e2f61972a7a - React-RCTAnimation: f2b22ff8ee4a8f726cb2a2c0489dc43160a9ba78 - React-RCTBlob: e1cc220434c170cfb87972c5f9ddeca42bc859c2 - React-RCTImage: a71a7ae08498f10f025cb3859e623bc35d984ac2 - React-RCTLinking: 8cd1a2e5855917d8202dbbec645ce96a4dc56599 - React-RCTNetwork: 52edddadac17aebf35340cc890d366033bcaa497 - React-RCTSettings: 5ef91ca864871af290fc7f181a1fc8cf931023fa - React-RCTText: ad1509728a06baaf16810c807ae86fd0f94218cd - React-RCTVibration: 72d3e98346f20ac4c59649bff2a02f229048625e - ReactCommon: b3d60106340b0c5cb774de530a3ec44e99d3365e + React-RCTActionSheet: 1c82cde015e743883cb80b6846949e0ce971d77c + React-RCTAnimation: 34328140d4295757f618aa997b0db8f7ca63f15d + React-RCTBlob: 954ec69326178e62b0425c1fc1662b046d473964 + React-RCTImage: b0d39340cb001dafbcb353d856ed3ab8ed842d2e + React-RCTLinking: 5ba5ceddfa18388cec61323f14653633d650bc1d + React-RCTNetwork: f36b6bc184f45f9c11b695ecf5dcc6bcf41c2714 + React-RCTSettings: 086ae71d112cf26d42435d3e98c8acccdfb678d6 + React-RCTText: 91ca55794c1eaf44e59ca6160fd561fec5697c49 + React-RCTVibration: 7f9ac599dfeb48f11e6ad50add4b09ac3f38366b + ReactCommon: bfd19eca47e6320353b895fa3eab70223efe6923 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNCPushNotificationIOS: 83ec11fe19d4ea9e32cc339d8e7d2cc3c88f543e - RNDeviceInfo: 6f20764111df002b4484f90cbe0a861be29bcc6c + RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFBApp: 5b215aacc09105a1761de31b9a0eb2abcce06253 RNFBCrashlytics: 0469cb96b00904e0c9604b9636d8eeab31115b08 RNFBMessaging: be0b936394416ec5503add603f2c0a641c353063 RNGestureHandler: 946a7691e41df61e2c4b1884deab41a4cdc3afff RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 - RNKeychain: f5783613aa3095af63345ddb9626a729bd4a3897 + RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 8b675a650fc67c87f63d4345a1b2d4a699c25e4f RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 - RNSentry: 9b1d983b2d5d1c215ba6490348fd2a4cc23a8a9d + RNSentry: b63ba6a29ee142b5c3221896be8ff6cda587e03f RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f - SDWebImage: 29c340dbdcef342bb13125553f4e19ce056b07a7 + RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c + SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 Sentry: 14bdd673870e8cf64932b149fad5bbbf39a9b390 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - Yoga: d35afc581c45e82ecabf981b93d17f02ae19c49f + TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 + Yoga: f013762d91dd7bfd536dedce0d6c4a52ca0401cf PODFILE CHECKSUM: e38b8f3a80d4f969b2bd4796967957156faf7531 diff --git a/package.json b/package.json index 35a39cbf4ff..32e2590d827 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.6.2", - "@react-native-community/blur": "^3.4.1", + "@react-native-community/blur": "^3.3.1", "@react-native-community/masked-view": "^0.1.5", - "@react-native-community/netinfo": "^5.0.0", + "@react-native-community/netinfo": "^4.6.0", "@react-native-community/push-notification-ios": "^1.0.3", "@react-native-firebase/app": "^6.2.0", "@react-native-firebase/crashlytics": "^6.2.0", @@ -84,16 +84,17 @@ "react-native-circular-progress": "^1.3.4", "react-native-code-push": "^5.6.0", "react-native-crypto": "^2.2.0", - "react-native-device-info": "5.3.1", + "react-native-device-info": "^2.1.3", "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-gesture-handler": "1.5.2", "react-native-haptic-feedback": "^1.8.2", + "react-native-hooks": "^0.9.0", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", - "react-native-keychain": "4.0.3", + "react-native-keychain": "4.0.1", "react-native-languages": "^3.0.0", "react-native-level-fs": "^3.0.1", "react-native-linear-gradient": "^2.5.6", @@ -105,17 +106,18 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "software-mansion/react-native-reanimated", - "react-native-redash": "^9.0.0", + "react-native-redash": "8.2.2", "react-native-safe-area-context": "^0.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "9.13.6", + "react-native-svg": "9.13.3", "react-native-tcp": "^3.3.2", "react-native-text-input-mask": "waqas19921/react-native-text-input-mask", "react-native-tooltip": "marcosrdz/react-native-tooltip#master", + "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", diff --git a/patches/react-native-keychain+4.0.3.patch b/patches/react-native-keychain+4.0.3.patch deleted file mode 100644 index 7fa4f9a8ad3..00000000000 --- a/patches/react-native-keychain+4.0.3.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m -index c4ad7e5..ada736b 100644 ---- a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m -+++ b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m -@@ -270,7 +270,7 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server - { - NSError *aerr = nil; - LAContext *context = [LAContext new]; -- BOOL canBeProtected = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&aerr]; -+ BOOL canBeProtected = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&aerr]; - - if (!aerr && canBeProtected) { - if (@available(iOS 11, *)) { diff --git a/src/App.js b/src/App.js index 8fd49fc9325..0ade912c184 100644 --- a/src/App.js +++ b/src/App.js @@ -16,7 +16,6 @@ import { } from 'react-native-dotenv'; // eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; -import { SafeAreaProvider } from 'react-native-safe-area-context'; // eslint-disable-next-line import/no-unresolved import { useScreens } from 'react-native-screens'; import { connect, Provider } from 'react-redux'; @@ -157,14 +156,12 @@ class App extends Component { Navigation.setTopLevelNavigator(navigatorRef); render = () => ( - - - - - - - - + + + + + + ); } diff --git a/src/components/OfflineBadge.js b/src/components/OfflineBadge.js index 642e1602f1f..22a6a036465 100644 --- a/src/components/OfflineBadge.js +++ b/src/components/OfflineBadge.js @@ -1,16 +1,22 @@ -import React from 'react'; +import analytics from '@segment/analytics-react-native'; +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; import Animated from 'react-native-reanimated'; -import { bin, useSpringTransition } from 'react-native-redash'; +import { compose, onlyUpdateForKeys } from 'recompact'; import styled from 'styled-components'; -import { useInternetStatus } from '../hooks'; +import { withNetInfo } from '../hoc'; import { colors, padding, shadow } from '../styles'; import { interpolate } from './animations'; import { Icon } from './icons'; -import { Centered, RowWithMargins } from './layout'; +import { RowWithMargins } from './layout'; import { Text } from './text'; -const StyledBadge = styled(RowWithMargins).attrs({ - component: Centered, +const { spring, Value, View } = Animated; + +const Badge = styled(RowWithMargins).attrs({ + align: 'center', + component: View, + justify: 'center', margin: 5, self: 'center', })` @@ -25,44 +31,60 @@ const StyledBadge = styled(RowWithMargins).attrs({ const DefaultAnimationValue = 60; -const OfflineBadge = () => { - const isConnected = useInternetStatus(); +class OfflineBadge extends PureComponent { + static propTypes = { + isConnected: PropTypes.bool, + }; + + static defaultProps = { + isConnected: true, + }; + + componentDidMount = () => this.runAnimation(); + + componentDidUpdate = () => this.runAnimation(); + + animation = new Value(DefaultAnimationValue); + + runAnimation = () => { + const { isConnected } = this.props; - const animation = useSpringTransition(bin(isConnected), { - damping: 14, - mass: 1, - overshootClamping: false, - restDisplacementThreshold: 0.001, - restSpeedThreshold: 0.001, - stiffness: 121.6, - }); + return spring(this.animation, { + damping: 14, + mass: 1, + overshootClamping: false, + restDisplacementThreshold: 0.001, + restSpeedThreshold: 0.001, + stiffness: 121.6, + toValue: isConnected ? DefaultAnimationValue : 0, + }).start(({ finished }) => { + if (!finished) return null; + return isConnected + ? analytics.track('Reconnected after offline') + : analytics.track('Offline / lost connection'); + }); + }; - return ( - ( + - - - - Offline - - - + + + Offline + + ); -}; +} -const neverRerender = () => true; -export default React.memo(OfflineBadge, neverRerender); +export default compose( + withNetInfo, + onlyUpdateForKeys(['isConnected']) +)(OfflineBadge); diff --git a/src/components/animations/ScaleInAnimation.js b/src/components/animations/ScaleInAnimation.js index c52ce4c1cbd..0ae38f051f9 100644 --- a/src/components/animations/ScaleInAnimation.js +++ b/src/components/animations/ScaleInAnimation.js @@ -8,10 +8,10 @@ import { interpolate } from './procs'; const ScaleInAnimation = ({ range, scaleTo, style, value, ...props }) => ( { - const insets = useSafeArea(); - - return isEmpty ? ( +}) => + isEmpty ? ( ); -}; AssetList.propTypes = { fetchData: PropTypes.func.isRequired, diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js index 9adce36645a..55054e54c1b 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js @@ -5,21 +5,18 @@ import { State, TapGestureHandler, } from 'react-native-gesture-handler'; +import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { withProps } from 'recompact'; import styled from 'styled-components/primitives'; -import { useBiometryType, BiometryTypes } from '../../../hooks'; import { colors, padding } from '../../../styles'; -import { haptics } from '../../../utils'; import InnerBorder from '../../InnerBorder'; import { Centered } from '../../layout'; import { ShadowStack } from '../../shadow-stack'; import { Text } from '../../text'; import HoldToAuthorizeButtonIcon from './HoldToAuthorizeButtonIcon'; -const { divide, multiply, proc, timing, Value } = Animated; - -const { ACTIVE, BEGAN, END } = State; +const { divide, multiply, timing, Value, View } = Animated; const ButtonBorderRadius = 30; const ButtonHeight = 59; @@ -41,8 +38,7 @@ const ButtonShadows = { ], }; -const buttonScaleDurationMs = 150; -const longPressProgressDurationMs = 500; // @christian approves +const progressDurationMs = 500; // @christian approves const Content = styled(Centered)` ${padding(15)}; @@ -60,21 +56,24 @@ const Title = withProps({ weight: 'semibold', })(Text); -const animate = (value, { duration = buttonScaleDurationMs, toValue }) => - timing(value, { +const buildAnimation = (value, options) => { + const { duration = 150, isInteraction = false, toValue } = options; + + return timing(value, { duration, easing: Easing.inOut(Easing.ease), + isInteraction, toValue, + useNativeDriver: true, }); +}; -const calculateReverseDuration = proc(longPressProgress => - multiply(divide(longPressProgress, 100), longPressProgressDurationMs) -); +const calculateReverseDuration = progess => + multiply(divide(progess, 100), progressDurationMs); -class HoldToAuthorizeButton extends PureComponent { +export default class HoldToAuthorizeButton extends PureComponent { static propTypes = { backgroundColor: PropTypes.string, - biometryType: PropTypes.string, children: PropTypes.any, disabled: PropTypes.bool, disabledBackgroundColor: PropTypes.string, @@ -82,6 +81,7 @@ class HoldToAuthorizeButton extends PureComponent { isAuthorizing: PropTypes.bool, label: PropTypes.string, onLongPress: PropTypes.func.isRequired, + onPress: PropTypes.func, shadows: PropTypes.arrayOf(PropTypes.array), style: PropTypes.object, theme: PropTypes.oneOf(['light', 'dark']), @@ -103,92 +103,105 @@ class HoldToAuthorizeButton extends PureComponent { } }; - buttonScale = new Value(1); + scale = new Value(1); + + tapHandlerState = 1; - longPressProgress = new Value(0); + animation = new Value(0); onFinishAuthorizing = () => { - if (!this.props.disabled) { - animate(this.longPressProgress, { - duration: calculateReverseDuration(this.longPressProgress), + const { disabled } = this.props; + if (!disabled) { + buildAnimation(this.animation, { + duration: calculateReverseDuration(this.animation), + isInteraction: true, toValue: 0, }).start(() => this.setState({ isAuthorizing: false })); } }; - handlePress = () => { - if (this.props.onLongPress) { - this.props.onLongPress(); + onTapChange = ({ nativeEvent: { state } }) => { + const { disabled, onPress } = this.props; + + this.tapHandlerState = state; + + if (state === State.BEGAN) { + if (disabled) { + ReactNativeHapticFeedback.trigger('notificationWarning'); + buildAnimation(this.scale, { toValue: 0.99 }).start(() => { + buildAnimation(this.scale, { toValue: 1 }).start(); + }); + } else { + buildAnimation(this.scale, { toValue: 0.97 }).start(); + buildAnimation(this.animation, { + duration: progressDurationMs, + toValue: 100, + }).start(); + } + } else if (!disabled && state === State.ACTIVE) { + if (onPress) { + onPress(); + } + } else if (!disabled && state === State.END) { + buildAnimation(this.scale, { toValue: 1 }).start(); + buildAnimation(this.animation, { + duration: calculateReverseDuration(this.animation), + isInteraction: true, + toValue: 0, + }).start(); } }; - onLongPressChange = ({ nativeEvent: { state } }) => { - const { disabled, enableLongPress } = this.props; + onLongPressChange = ({ nativeEvent }) => { + const { disabled, onLongPress } = this.props; - if (state === ACTIVE && !disabled && enableLongPress) { - haptics.notificationSuccess(); + if (!disabled && nativeEvent.state === State.ACTIVE) { + ReactNativeHapticFeedback.trigger('notificationSuccess'); - animate(this.buttonScale, { + buildAnimation(this.scale, { + isInteraction: true, toValue: 1, }).start(() => this.setState({ isAuthorizing: true })); - this.handlePress(); + if (onLongPress) { + onLongPress(); + } } }; - onTapChange = ({ nativeEvent: { state } }) => { - const { disabled, enableLongPress } = this.props; + renderContent = () => { + const { children, disabled, hideBiometricIcon, label } = this.props; - if (disabled) { - if (state === BEGAN) { - animate(this.buttonScale, { toValue: 0.99 }).start(() => { - haptics.notificationWarning(); - animate(this.buttonScale, { toValue: 1 }).start(); - }); - } - } else { - if (state === ACTIVE) { - if (!enableLongPress) { - this.handlePress(); - } - } else if (state === BEGAN) { - animate(this.buttonScale, { toValue: 0.97 }).start(); - if (enableLongPress) { - animate(this.longPressProgress, { - duration: longPressProgressDurationMs, - toValue: 100, - }).start(); - } - } else if (state === END) { - animate(this.buttonScale, { toValue: 1 }).start(); - if (enableLongPress) { - animate(this.longPressProgress, { - duration: calculateReverseDuration(this.longPressProgress), - toValue: 0, - }).start(); - } - } + const { isAuthorizing } = this.state; + + if (children) { + return children; } + + return ( + + {!disabled && !hideBiometricIcon && ( + + )} + {isAuthorizing ? 'Authorizing' : label} + + ); }; render() { const { backgroundColor, - biometryType, - children, disabled, disabledBackgroundColor, - enableLongPress, - hideBiometricIcon, - label, shadows, style, theme, ...props } = this.props; - const { isAuthorizing } = this.state; - let bgColor = backgroundColor; if (disabled) { bgColor = disabledBackgroundColor || ButtonDisabledBgColor[theme]; @@ -197,13 +210,12 @@ class HoldToAuthorizeButton extends PureComponent { return ( - - {children || ( - - {!disabled && !hideBiometricIcon && ( - - )} - {isAuthorizing ? 'Authorizing' : label} - - )} + {this.renderContent()} - + ); } } - -const HoldToAuthorizeButtonWithBiometrics = ({ label, ...props }) => { - const biometryType = useBiometryType(); - const enableLongPress = - biometryType === BiometryTypes.FaceID || - biometryType === BiometryTypes.none; - - return ( - - ); -}; - -export default React.memo(HoldToAuthorizeButtonWithBiometrics); diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js index 997e436b2e5..50521a3b95e 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js @@ -9,19 +9,20 @@ import { Centered } from '../../layout'; const { cond, divide, greaterThan } = Animated; -const Container = styled(Centered)` - ${position.size(31)}; - left: 15; +const BiometryIconSize = 31; +const IconContainer = styled(Centered)` + ${position.size(BiometryIconSize)}; + left: 19; + margin-bottom: 2; position: absolute; `; -const HoldToAuthorizeButtonIcon = ({ animatedValue, biometryType }) => ( - - - +const HoldToAuthorizeButtonIcon = ({ animatedValue }) => ( + + + ( > - + ); HoldToAuthorizeButtonIcon.propTypes = { animatedValue: PropTypes.object, - biometryType: PropTypes.string, }; -const arePropsEqual = (prev, next) => prev.biometryType === next.biometryType; -export default React.memo(HoldToAuthorizeButtonIcon, arePropsEqual); +export default React.memo(HoldToAuthorizeButtonIcon); diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index b64d20b55a3..111e9d12435 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -4,12 +4,6 @@ import { colors } from '../../styles'; import { HoldToAuthorizeButton, UnlockingSpinner } from '../buttons'; import { SlippageWarningTheshold } from './SlippageWarning'; -const ConfirmExchangeButtonShadows = [ - [0, 3, 5, colors.black, 0.2], - [0, 6, 10, colors.black, 0.14], - [0, 1, 18, colors.black, 0.12], -]; - const ConfirmExchangeButton = ({ disabled, inputCurrencyName, @@ -36,23 +30,27 @@ const ConfirmExchangeButton = ({ return ( - {isUnlockingAsset && } + {isUnlockingAsset ? ( + + ) : ( + undefined + )} ); }; @@ -70,4 +68,4 @@ ConfirmExchangeButton.propTypes = { timeRemaining: PropTypes.string, }; -export default React.memo(ConfirmExchangeButton); +export default ConfirmExchangeButton; diff --git a/src/components/gas/GasSpeedLabelPagerItem.js b/src/components/gas/GasSpeedLabelPagerItem.js index d02cf7cfbc1..5edd195bd76 100644 --- a/src/components/gas/GasSpeedLabelPagerItem.js +++ b/src/components/gas/GasSpeedLabelPagerItem.js @@ -6,7 +6,7 @@ import Animated, { Transitioning, Transition, } from 'react-native-reanimated'; -import { useTimingTransition } from 'react-native-redash'; +import { useToggle } from 'react-native-redash'; import { withProps } from 'recompact'; import { gasUtils } from '../../utils'; import { interpolate } from '../animations'; @@ -51,7 +51,7 @@ const GasSpeedLabelPagerItem = ({ label, selected, shouldAnimate }) => { const isFirst = index === 0; const isLast = index === gasUtils.GasSpeedOrder.length - 1; - const transitionVal = useTimingTransition( + const transitionVal = useToggle( !selected, duration + (isFirst ? 50 : 0), Easing.out(Easing.ease) diff --git a/src/components/icons/BiometryIcon.js b/src/components/icons/BiometryIcon.js index 7950d91770d..4b292f7719a 100644 --- a/src/components/icons/BiometryIcon.js +++ b/src/components/icons/BiometryIcon.js @@ -1,41 +1,61 @@ import PropTypes from 'prop-types'; import React from 'react'; +import TouchID from 'react-native-touch-id'; +import stylePropType from 'react-style-proptype'; +import { + compose, + lifecycle, + omitProps, + onlyUpdateForKeys, + withHandlers, + withProps, + withState, +} from 'recompact'; import { position } from '../../styles'; import { Centered } from '../layout'; import Icon from './Icon'; -const BiometryTypeStyles = { - faceid: { - ...position.sizeAsObject(27), - marginBottom: 2, - marginLeft: 4, - }, - passcode: { - height: 25, - marginBottom: 4, - marginLeft: 4, - width: 18, - }, - touchid: { - ...position.sizeAsObject(31), - marginBottom: 1, - }, -}; +const DefaultBiometryType = 'FaceID'; -const BiometryIcon = ({ biometryType, ...props }) => { - if (!biometryType || biometryType === 'none') return null; - const type = biometryType.toLowerCase(); +const BiometryIcon = ({ isFaceID, size, style, ...props }) => ( + + + +); - return ( - - - - ); +BiometryIcon.propTypes = { + isFaceID: PropTypes.bool, + size: PropTypes.number, + style: stylePropType, }; -BiometryIcon.propTypes = { - biometryType: PropTypes.string, +BiometryIcon.defaultProps = { + size: 34, }; -const arePropsEqual = (prev, next) => prev.biometryType === next.biometryType; -export default React.memo(BiometryIcon, arePropsEqual); +export default compose( + withState('biometryType', 'setBiometryType', DefaultBiometryType), + withHandlers({ + setBiometryType: ({ setBiometryType }) => biometryType => { + setBiometryType(biometryType || DefaultBiometryType); + }, + }), + lifecycle({ + componentDidMount() { + TouchID.isSupported().then(this.props.setBiometryType); + }, + }), + withProps(({ biometryType }) => ({ + isFaceID: biometryType === DefaultBiometryType, + })), + onlyUpdateForKeys(['biometryType', 'size']), + omitProps('biometryType', 'setBiometryType') +)(BiometryIcon); diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index cd93193d9d7..8015745bd1f 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -25,7 +25,6 @@ import HandleIcon from './svg/HandleIcon'; import InboxIcon from './svg/InboxIcon'; import LockIcon from './svg/LockIcon'; import OfflineIcon from './svg/OfflineIcon'; -import PasscodeIcon from './svg/PasscodeIcon'; import ProgressIcon from './svg/ProgressIcon'; import SearchIcon from './svg/SearchIcon'; import SendIcon from './svg/SendIcon'; @@ -67,7 +66,6 @@ Icon.IconTypes = { inbox: InboxIcon, lock: LockIcon, offline: OfflineIcon, - passcode: PasscodeIcon, progress: ProgressIcon, search: SearchIcon, send: SendIcon, diff --git a/src/components/icons/svg/FaceIdIcon.js b/src/components/icons/svg/FaceIdIcon.js index e8856c266b5..bbab6d3c2a5 100644 --- a/src/components/icons/svg/FaceIdIcon.js +++ b/src/components/icons/svg/FaceIdIcon.js @@ -4,10 +4,9 @@ import Svg, { Path } from 'svgs'; import { colors } from '../../../styles'; const FaceIdIcon = ({ color, ...props }) => ( - + diff --git a/src/components/icons/svg/PasscodeIcon.js b/src/components/icons/svg/PasscodeIcon.js deleted file mode 100644 index 879f179b4df..00000000000 --- a/src/components/icons/svg/PasscodeIcon.js +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Svg, { Defs, G, LinearGradient, Path, Stop } from 'svgs'; -import { colors } from '../../../styles'; - -const PasscodeIcon = ({ color, ...props }) => ( - - - - - - - - - - - - - - -); - -PasscodeIcon.propTypes = { - color: PropTypes.string, -}; - -PasscodeIcon.defaultProps = { - color: colors.white, -}; - -export default PasscodeIcon; diff --git a/src/components/qrcode-scanner/QRCodeScanner.js b/src/components/qrcode-scanner/QRCodeScanner.js index bd126c2dbb0..f44454deeb9 100644 --- a/src/components/qrcode-scanner/QRCodeScanner.js +++ b/src/components/qrcode-scanner/QRCodeScanner.js @@ -1,115 +1,84 @@ import PropTypes from 'prop-types'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { PureComponent } from 'react'; +import DeviceInfo from 'react-native-device-info'; import FastImage from 'react-native-fast-image'; -import { Transition, Transitioning } from 'react-native-reanimated'; +import stylePropType from 'react-style-proptype'; +import styled from 'styled-components/primitives'; import SimulatorFakeCameraImageSource from '../../assets/simulator-fake-camera-image.jpg'; -import { usePrevious } from '../../hooks'; import { colors, position } from '../../styles'; -import { isNewValueForObjectPaths } from '../../utils'; import { Centered } from '../layout'; import { ErrorText } from '../text'; import QRCodeScannerCamera from './QRCodeScannerCamera'; import QRCodeScannerCrosshair from './QRCodeScannerCrosshair'; -const transition = ( - -); +const Container = styled(Centered).attrs({ direction: 'column' })` + ${position.cover}; + background-color: ${colors.black}; +`; -const QRCodeScanner = ({ - contentPositionBottom, - contentPositionTop, - enableCamera, - enableScanning, - isCameraAuthorized, - isEmulator, - onSuccess, - showCrosshairText, -}) => { - const ref = useRef(); - const [error, setError] = useState(null); - const [isInitialized, setInitialized] = useState(false); +export default class QRCodeScanner extends PureComponent { + static propTypes = { + contentStyles: stylePropType, + enableCamera: PropTypes.bool, + enableScanning: PropTypes.bool, + isCameraAuthorized: PropTypes.bool, + onSuccess: PropTypes.func, + showCrosshairText: PropTypes.bool, + }; - const prevContentPositionBottom = usePrevious(contentPositionBottom); - useEffect(() => { - if (ref.current && contentPositionBottom !== prevContentPositionBottom) { - ref.current.animateNextTransition(); + state = { + error: null, + isInitialized: false, + }; + + handleCameraReady = () => this.setState({ isInitialized: true }); + + handleMountError = () => this.setState({ error: 'mounting' }); + + renderCamera = () => { + if (DeviceInfo.isEmulator()) { + return ( + + ); } - }, [contentPositionBottom, prevContentPositionBottom]); - let cameraRenderer = null; - if (isEmulator) { - cameraRenderer = ( - - ); - } else if (enableCamera) { - cameraRenderer = ( + return this.props.enableCamera ? ( setInitialized(true)} - onMountError={() => setError('mounting')} - onSuccess={onSuccess} + enableScanning={this.props.enableScanning} + onCameraReady={this.handleCameraReady} + onMountError={this.handleMountError} + onSuccess={this.props.onSuccess} /> - ); - } + ) : null; + }; - const showErrorMessage = error && !isInitialized; - const showCrosshair = !error && !showErrorMessage; + render = () => { + const { contentStyles, isCameraAuthorized, showCrosshairText } = this.props; + const { error, isInitialized } = this.state; - return ( - - {cameraRenderer} - {isCameraAuthorized && ( - - + const showErrorMessage = error && !isInitialized; + const showCrosshair = !error && !showErrorMessage; + + return ( + + {this.renderCamera()} + {isCameraAuthorized && ( + {showErrorMessage && ( )} {showCrosshair && ( )} - - )} - - ); -}; - -QRCodeScanner.propTypes = { - contentPositionBottom: PropTypes.node, - contentPositionTop: PropTypes.node, - enableCamera: PropTypes.bool, - enableScanning: PropTypes.bool, - isCameraAuthorized: PropTypes.bool, - isEmulator: PropTypes.bool, - onSuccess: PropTypes.func, - showCrosshairText: PropTypes.bool, -}; - -const arePropsEqual = (prev, next) => - !isNewValueForObjectPaths(prev, next, [ - 'contentPositionBottom', - 'enableCamera', - 'enableScanning', - 'isCameraAuthorized', - 'showCrosshairText', - ]); - -export default React.memo(QRCodeScanner, arePropsEqual); + )} + + ); + }; +} diff --git a/src/components/send/SendButton.js b/src/components/send/SendButton.js index 92cd8e40adb..f35a6318167 100644 --- a/src/components/send/SendButton.js +++ b/src/components/send/SendButton.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { pure } from 'recompose'; import { HoldToAuthorizeButton } from '../buttons'; const SendButton = ({ @@ -45,4 +46,4 @@ SendButton.propTypes = { onLongPress: PropTypes.func, }; -export default React.memo(SendButton); +export default pure(SendButton); diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index ef1a0927265..a53b561f878 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -2,7 +2,7 @@ import { upperFirst } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { InteractionManager, Linking, ScrollView } from 'react-native'; -import { isEmulatorSync } from 'react-native-device-info'; +import DeviceInfo from 'react-native-device-info'; import FastImage from 'react-native-fast-image'; import * as StoreReview from 'react-native-store-review'; import { compose, onlyUpdateForKeys, withHandlers } from 'recompact'; @@ -178,7 +178,7 @@ export default compose( const shouldDeeplinkToAppStore = count >= maxRequestCount || !StoreReview.isAvailable; - if (shouldDeeplinkToAppStore && !isEmulatorSync()) { + if (shouldDeeplinkToAppStore && !DeviceInfo.isEmulator()) { Linking.openURL(SettingsExternalURLs.review); } else { onCloseModal(); diff --git a/src/handlers/localstorage/uniswap.js b/src/handlers/localstorage/uniswap.js index b79fd9d284f..539ad21d435 100644 --- a/src/handlers/localstorage/uniswap.js +++ b/src/handlers/localstorage/uniswap.js @@ -1,5 +1,4 @@ import { forEach } from 'lodash'; -import { DefaultUniswapFavorites } from '../../references'; import { getAccountLocal, getGlobal, @@ -23,8 +22,7 @@ const uniswapAccountLocalKeys = [ PENDING_APPROVALS, ]; -export const getUniswapFavorites = () => - getGlobal(UNISWAP_FAVORITES, DefaultUniswapFavorites); +export const getUniswapFavorites = () => getGlobal(UNISWAP_FAVORITES, []); export const saveUniswapFavorites = favorites => saveGlobal(UNISWAP_FAVORITES, favorites); diff --git a/src/hoc/index.js b/src/hoc/index.js index 1235ba1c52c..d6ce99cfba5 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -17,6 +17,7 @@ export { default as withIsWalletEmpty } from './withIsWalletEmpty'; export { default as withIsWalletEthZero } from './withIsWalletEthZero'; export { default as withKeyboardHeight } from './withKeyboardHeight'; export { default as withMessageSigningScreen } from './withMessageSigningScreen'; +export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; export { default as withOpenFamilyTabs } from './withOpenFamilyTabs'; export { default as withOpenInvestmentCards } from './withOpenInvestmentCards'; diff --git a/src/hoc/withNetInfo.js b/src/hoc/withNetInfo.js new file mode 100644 index 00000000000..1ab24409561 --- /dev/null +++ b/src/hoc/withNetInfo.js @@ -0,0 +1,23 @@ +import NetInfo from '@react-native-community/netinfo'; +import { compose, lifecycle, withState } from 'recompact'; + +const withNetInfo = ComponentToWrap => + compose( + withState('isConnected', 'setIsConnected', true), + lifecycle({ + componentDidMount() { + NetInfo.isConnected.addEventListener( + 'connectionChange', + this.props.setIsConnected + ); + }, + componentWillUnmount() { + NetInfo.isConnected.removeEventListener( + 'connectionChange', + this.props.setIsConnected + ); + }, + }) + )(ComponentToWrap); + +export default withNetInfo; diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index ce4b9a56c92..298f33e31ce 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -33,7 +33,9 @@ export const includeExchangeAddress = uniswapPairs => asset => ({ ), }); -const appendFavoriteKey = asset => ({ +const lowerAssetName = asset => toLower(asset.name); + +const includeFavorite = asset => ({ ...asset, favorite: true, }); @@ -50,17 +52,14 @@ const withAssetsAvailableOnUniswap = (allAssets, uniswapPairs) => { return { assetsAvailableOnUniswap }; }; -const withSortedUniswapAssets = (assets, favorites) => { - const sorted = sortBy(values(assets), ({ name }) => toLower(name)); - const [favorited, notFavorited] = partition(sorted, ({ address }) => - includes(map(favorites, toLower), toLower(address)) +const withSortedUniswapAssets = (unsortedUniswapAssets, favorites) => { + const sortedAssets = sortBy(values(unsortedUniswapAssets), lowerAssetName); + const [favoriteAssets, remainingAssets] = partition(sortedAssets, asset => + includes(favorites, asset.address) ); - + const labeledFavorites = map(favoriteAssets, includeFavorite); return { - sortedUniswapAssets: concat( - map(favorited, appendFavoriteKey), - notFavorited - ), + sortedUniswapAssets: concat(labeledFavorites, remainingAssets), }; }; diff --git a/src/hooks/index.js b/src/hooks/index.js deleted file mode 100644 index 3264f26a0c8..00000000000 --- a/src/hooks/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export { default as useAppState } from './useAppState'; -export { default as useClipboard } from './useClipboard'; -export { default as useInternetStatus } from './useInternetStatus'; -export { default as usePrevious } from './usePrevious'; -export { default as useBiometryType, BiometryTypes } from './useBiometryType'; diff --git a/src/hooks/useAppState.js b/src/hooks/useAppState.js deleted file mode 100644 index cbcb4685662..00000000000 --- a/src/hooks/useAppState.js +++ /dev/null @@ -1,30 +0,0 @@ -import { useEffect, useState } from 'react'; -import { AppState } from 'react-native'; -import usePrevious from './usePrevious'; - -const AppStateTypes = { - active: 'active', - background: 'background', - inactive: 'inactive', -}; - -export default function useAppState() { - const [appState, setAppState] = useState(AppState.currentState); - const prevAppState = usePrevious(appState); - - function onChange(newState) { - setAppState(newState); - } - - useEffect(() => { - AppState.addEventListener('change', onChange); - return () => AppState.removeEventListener('change', onChange); - }, []); - - return { - appState, - justBecameActive: - appState === AppStateTypes.active && - prevAppState !== AppStateTypes.active, - }; -} diff --git a/src/hooks/useBiometryType.js b/src/hooks/useBiometryType.js deleted file mode 100644 index 73e6a317f5b..00000000000 --- a/src/hooks/useBiometryType.js +++ /dev/null @@ -1,50 +0,0 @@ -import { isNil } from 'lodash'; -import { useEffect, useState } from 'react'; -import { isPinOrFingerprintSet } from 'react-native-device-info'; -import * as Keychain from 'react-native-keychain'; -import useAppState from './useAppState'; -import usePrevious from './usePrevious'; - -export const BiometryTypes = { - FaceID: 'FaceID', - none: 'none', - passcode: 'passcode', - TouchID: 'TouchID', -}; - -export default function useBiometryType() { - const { justBecameActive } = useAppState(); - const [biometryType, setBiometryType] = useState(null); - const prevBiometricType = usePrevious(biometryType); - - useEffect(() => { - let mounted = true; - - const getSupportedBiometryType = async () => { - let type = await Keychain.getSupportedBiometryType(); - - if (isNil(type)) { - // 💡️ When `getSupportedBiometryType` returns `null` it can mean either: - // A) the user has no device passcode/biometrics at all - // B) the user has gone into Settings and disabled biometrics specifically for Rainbow - type = await isPinOrFingerprintSet().then(isPinOrFingerprintSet => - isPinOrFingerprintSet ? BiometryTypes.passcode : BiometryTypes.none - ); - } - - if (mounted && type !== prevBiometricType) { - setBiometryType(type); - } - }; - - if (!biometryType || justBecameActive) { - getSupportedBiometryType(); - } - - return () => { - mounted = false; - }; - }, [biometryType, justBecameActive, prevBiometricType]); - - return biometryType; -} diff --git a/src/hooks/useClipboard.js b/src/hooks/useClipboard.js deleted file mode 100644 index bcc749245d5..00000000000 --- a/src/hooks/useClipboard.js +++ /dev/null @@ -1,26 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import { Clipboard } from 'react-native'; -import useAppState from './useAppState'; - -export default function useClipboard() { - const { justBecameActive } = useAppState(); - const [data, updateClipboardData] = useState(''); - - async function updateClipboard() { - const content = await Clipboard.getString(); - updateClipboardData(content); - } - - useEffect(() => { - if (justBecameActive) { - updateClipboard(); - } - }, [justBecameActive]); - - const setString = useCallback(content => { - Clipboard.setString(content); - updateClipboardData(content); - }, []); - - return [data, setString]; -} diff --git a/src/hooks/useInternetStatus.js b/src/hooks/useInternetStatus.js deleted file mode 100644 index 7520325cbe1..00000000000 --- a/src/hooks/useInternetStatus.js +++ /dev/null @@ -1,27 +0,0 @@ -import NetInfo from '@react-native-community/netinfo'; -import analytics from '@segment/analytics-react-native'; -import { isNil } from 'lodash'; -import { useEffect, useState } from 'react'; - -export default function useInternetStatus() { - const [isInternetReachable, setIsInternetReachable] = useState(true); - - function onChange(newState) { - const { isInternetReachable: newIsInternetReachable } = newState; - if (!isNil(newIsInternetReachable)) { - setIsInternetReachable(newIsInternetReachable); - if (newIsInternetReachable) { - analytics.track('Reconnected after offline'); - } else { - analytics.track('Offline / lost connection'); - } - } - } - - useEffect(() => { - const unsubscribe = NetInfo.addEventListener(onChange); - return unsubscribe; - }, []); - - return isInternetReachable; -} diff --git a/src/hooks/usePrevious.js b/src/hooks/usePrevious.js deleted file mode 100644 index ed46581cb01..00000000000 --- a/src/hooks/usePrevious.js +++ /dev/null @@ -1,11 +0,0 @@ -import { useEffect, useRef } from 'react'; - -export default function usePrevious(value) { - const ref = useRef(); - - useEffect(() => { - ref.current = value; - }, [value]); - - return ref.current; -} diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index 00f5b61fc5e..b9f43ebc4db 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -36,10 +36,7 @@ import { getUniswapPairs, } from '../handlers/uniswap'; import { includeExchangeAddress } from '../hoc/withUniswapAssets'; -import { - cleanUniswapAssetsFallback, - DefaultUniswapFavorites, -} from '../references'; +import { cleanUniswapAssetsFallback } from '../references'; import { resubscribeAssets } from './explorer'; // -- Constants ------------------------------------------------------------- // @@ -221,11 +218,9 @@ export const uniswapUpdateFavorites = (assetAddress, add = true) => ( ) => { const address = toLower(assetAddress); const { favorites } = getState().uniswap; - const normalizedFavorites = map(favorites, toLower); - const updatedFavorites = add - ? uniq(concat(normalizedFavorites, address)) - : without(normalizedFavorites, address); + ? uniq(concat(favorites, address)) + : without(favorites, address); dispatch({ payload: updatedFavorites, type: UNISWAP_UPDATE_FAVORITES, @@ -338,7 +333,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => // -- Reducer --------------------------------------------------------------- // export const INITIAL_UNISWAP_STATE = { allowances: {}, - favorites: DefaultUniswapFavorites, + favorites: [], fetchingUniswap: false, inputCurrency: null, inputReserve: null, diff --git a/src/references/index.js b/src/references/index.js index 4206cb7ce04..c72fd596d22 100644 --- a/src/references/index.js +++ b/src/references/index.js @@ -2,15 +2,6 @@ import { mapKeys, mapValues, toLower } from 'lodash'; import tokenOverridesFallback from './token-overrides.json'; import uniswapAssetsFallback from './uniswap-pairs.json'; -export const DefaultUniswapFavorites = [ - // Ethereum - 'eth', - // DAI - '0x6b175474e89094c44da98b954eedeac495271d0f', - // SOCKS - '0x23B608675a2B2fB1890d3ABBd85c5775c51691d5', -]; - export const loweredTokenOverridesFallback = mapKeys( tokenOverridesFallback, (_, address) => toLower(address) diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index 8fb508796a6..c87d2dd5c48 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -2,6 +2,7 @@ import analytics from '@segment/analytics-react-native'; import PropTypes from 'prop-types'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { KeyboardAvoidingView } from 'react-native'; +import { useClipboard } from 'react-native-hooks'; import { BorderlessButton } from 'react-native-gesture-handler'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; import { useNavigation } from 'react-navigation-hooks'; @@ -12,7 +13,6 @@ import { MultiLineInput } from '../components/inputs'; import { Centered, Column, Row, RowWithMargins } from '../components/layout'; import { LoadingOverlay } from '../components/modal'; import { Text } from '../components/text'; -import { useClipboard } from '../hooks'; import { sheetVerticalOffset } from '../navigation/transitions/effects'; import { borders, colors, padding, shadow } from '../styles'; import { isValidSeed as validateSeed } from '../helpers/validators'; diff --git a/src/screens/QRScannerScreen.js b/src/screens/QRScannerScreen.js index fe89d8ad067..0661191906f 100644 --- a/src/screens/QRScannerScreen.js +++ b/src/screens/QRScannerScreen.js @@ -1,7 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { useIsEmulator } from 'react-native-device-info'; -import { useSafeArea } from 'react-native-safe-area-context'; +import DeviceInfo from 'react-native-device-info'; +import { onlyUpdateForKeys } from 'recompact'; +import styled from 'styled-components/primitives'; import { BubbleSheet } from '../components/bubble-sheet'; import { Button } from '../components/buttons'; import { BackButton, Header } from '../components/header'; @@ -12,7 +13,20 @@ import { WalletConnectList, } from '../components/walletconnect-list'; import { colors, position } from '../styles'; -import { isNewValueForObjectPaths } from '../utils'; +import { safeAreaInsetValues } from '../utils'; + +const Container = styled(Centered)` + ${position.size('100%')}; + background-color: ${colors.black}; + overflow: hidden; +`; + +const QRScannerScreenHeader = styled(Header).attrs({ + justify: 'space-between', +})` + position: absolute; + top: 0; +`; const QRScannerScreen = ({ enableScanning, @@ -26,58 +40,52 @@ const QRScannerScreen = ({ walletConnectorsByDappName, walletConnectorsCount, ...props -}) => { - const { result: isEmulator } = useIsEmulator(); - const insets = useSafeArea(); - - return ( - - ( + + + + -
- - {isEmulator && ( - - )} -
- - {walletConnectorsCount ? ( - - ) : ( - - )} - -
- ); -}; + {DeviceInfo.isEmulator() && ( + + )} + + + {walletConnectorsCount ? ( + + ) : ( + + )} + + +); QRScannerScreen.propTypes = { enableScanning: PropTypes.bool, @@ -88,17 +96,20 @@ QRScannerScreen.propTypes = { onScanSuccess: PropTypes.func, onSheetLayout: PropTypes.func, sheetHeight: PropTypes.number, + showSheet: PropTypes.bool, + showWalletConnectSheet: PropTypes.bool, walletConnectorsByDappName: PropTypes.arrayOf(PropTypes.object), walletConnectorsCount: PropTypes.number, }; -const arePropsEqual = (prev, next) => - !isNewValueForObjectPaths(prev, next, [ - 'enableScanning', - 'isCameraAuthorized', - 'isFocused', - 'sheetHeight', - 'walletConnectorsCount', - ]); +QRScannerScreen.defaultProps = { + showWalletConnectSheet: true, +}; -export default React.memo(QRScannerScreen, arePropsEqual); +export default onlyUpdateForKeys([ + 'enableScanning', + 'isCameraAuthorized', + 'isFocused', + 'sheetHeight', + 'walletConnectorsCount', +])(QRScannerScreen); diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index f77cb8d96ec..49328f65bdb 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import lang from 'i18n-js'; import { Animated } from 'react-native'; +import TouchID from 'react-native-touch-id'; import styled from 'styled-components'; import { Button, HoldToAuthorizeButton } from '../components/buttons'; import { RequestVendorLogoIcon } from '../components/coin-icon'; @@ -53,10 +54,21 @@ export default class TransactionConfirmationScreen extends PureComponent { }; state = { + biometryType: null, isAuthorizing: false, sendLongPressProgress: new Animated.Value(0), }; + componentDidMount() { + TouchID.isSupported() + .then(biometryType => { + this.setState({ biometryType }); + }) + .catch(() => { + this.setState({ biometryType: 'FaceID' }); + }); + } + componentWillUnmount() { this.state.sendLongPressProgress.stopAnimation(); } @@ -97,19 +109,15 @@ export default class TransactionConfirmationScreen extends PureComponent { } }; - renderSendButton = () => { - const { method } = this.props; - const { isAuthorizing } = this.state; - const label = `Hold to ${method === SEND_TRANSACTION ? 'Send' : 'Sign'}`; - - return ( - - ); - }; + renderSendButton = () => ( + + ); requestHeader = () => { const { method } = this.props; diff --git a/src/utils/deviceUtils.js b/src/utils/deviceUtils.js index c79d9a9197c..e9abf291a0c 100644 --- a/src/utils/deviceUtils.js +++ b/src/utils/deviceUtils.js @@ -1,6 +1,7 @@ +import { pick } from 'lodash'; import { Dimensions } from 'react-native'; -const { height, width } = Dimensions.get('window'); +const { height, width } = pick(Dimensions.get('window'), ['height', 'width']); const deviceUtils = {}; diff --git a/src/utils/haptics.js b/src/utils/haptics.js deleted file mode 100644 index 50bcdda95da..00000000000 --- a/src/utils/haptics.js +++ /dev/null @@ -1,23 +0,0 @@ -import { keys, map } from 'lodash'; -import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import reduceArrayToObject from './reduceArrayToObject'; - -export const HapticFeedbackTypes = { - impactHeavy: 'impactHeavy', - impactLight: 'impactLight', - impactMedium: 'impactMedium', - notificationError: 'notificationError', - notificationSuccess: 'notificationSuccess', - notificationWarning: 'notificationWarning', - selection: 'selection', -}; - -const hapticToTrigger = haptic => ({ - [haptic]: () => ReactNativeHapticFeedback.trigger(haptic), -}); - -const haptics = reduceArrayToObject( - map(keys(HapticFeedbackTypes), hapticToTrigger) -); - -export default haptics; diff --git a/src/utils/index.js b/src/utils/index.js index a89fef6f8df..1eac30d1a8b 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -6,7 +6,6 @@ export { default as dimensionsPropType } from './dimensionsPropType'; export { default as directionPropType } from './directionPropType'; export { default as ethereumUtils } from './ethereumUtils'; export { default as gasUtils } from './gas'; -export { default as haptics } from './haptics'; export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForObjectPaths } from './isNewValueForObjectPaths'; diff --git a/yarn.lock b/yarn.lock index 968de00b380..db673a62952 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,14 +10,14 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.2": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" - integrity sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ== + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.5.tgz#ae1323cd035b5160293307f50647e83f8ba62f7e" + integrity sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.7" + "@babel/generator" "^7.7.4" "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.7" + "@babel/parser" "^7.7.5" "@babel/template" "^7.7.4" "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" @@ -29,10 +29,10 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4", "@babel/generator@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" - integrity sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.4.tgz#db651e2840ca9aa66f327dcec1dc5f5fa9611369" + integrity sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg== dependencies: "@babel/types" "^7.7.4" jsesc "^2.5.1" @@ -240,10 +240,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" - integrity sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.5.tgz#cbf45321619ac12d83363fcf9c94bb67fa646d71" + integrity sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig== "@babel/plugin-external-helpers@^7.0.0": version "7.7.4" @@ -277,9 +277,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.7.4" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.7.tgz#9f27075004ab99be08c5c1bd653a2985813cb370" - integrity sha512-3qp9I8lelgzNedI3hrhkvhaEYree6+WHnyA/q4Dza9z7iEIs1eyhWyJnetk3jJ69RT0AT4G0UhEGwyGFJ7GUuQ== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz#cc57849894a5c774214178c8ab64f6334ec8af71" + integrity sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.7.4" @@ -500,9 +500,9 @@ "@babel/helper-replace-supers" "^7.7.4" "@babel/plugin-transform-parameters@^7.0.0": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.7.tgz#7a884b2460164dc5f194f668332736584c760007" - integrity sha512-OhGSrf9ZBrr1fw84oFXj5hgi8Nmg+E2w5L7NhnG0lPvpDtqd7dbyilM2/vR8CKbJ907RyxPh2kj6sBCSSfI9Ew== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz#da4555c97f39b51ac089d31c7380f03bca4075ce" + integrity sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw== dependencies: "@babel/helper-call-delegate" "^7.7.4" "@babel/helper-get-function-arity" "^7.7.4" @@ -531,9 +531,9 @@ "@babel/plugin-syntax-jsx" "^7.7.4" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.7.tgz#5cbaa7445b4a09f774029f3cc7bb448ff3122a5d" - integrity sha512-SlPjWPbva2+7/ZJbGcoqjl4LsQaLpKEzxW9hcxU7675s24JmdotJOSJ4cgAbV82W3FcZpHIGmRZIlUL8ayMvjw== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz#d91205717fae4e2f84d020cd3057ec02a10f11da" + integrity sha512-LixU4BS95ZTEAZdPaIuyg/k8FiiqN9laQ0dMHB4MlpydHY53uQdWCUrwjLr5o6ilS6fAgZey4Q14XBjl5tL6xw== dependencies: "@babel/helper-builder-react-jsx" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" @@ -604,9 +604,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/register@^7.0.0": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.7.tgz#46910c4d1926b9c6096421b23d1f9e159c1dcee1" - integrity sha512-S2mv9a5dc2pcpg/ConlKZx/6wXaEwHeqfo7x/QbXsdCAZm+WJC1ekVvL1TVxNsedTs5y/gG63MhJTEsmwmjtiA== + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.4.tgz#45a4956471a9df3b012b747f5781cc084ee8f128" + integrity sha512-/fmONZqL6ZMl9KJUYajetCrID6m0xmL4odX7v+Xvoxcv0DdbP/oO0TWIeLUCHqczQ6L6njDMqmqHFy2cp3FFsA== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.13" @@ -615,9 +615,9 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" - integrity sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA== + version "7.7.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" + integrity sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw== dependencies: regenerator-runtime "^0.13.2" @@ -670,26 +670,26 @@ minimist "^1.2.0" "@emotion/is-prop-valid@^0.8.1": - version "0.8.6" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.6.tgz#4757646f0a58e9dec614c47c838e7147d88c263c" - integrity sha512-mnZMho3Sq8BfzkYYRVc8ilQTnc8U02Ytp6J1AwM6taQStZ3AhsEJBX2LzhA/LJirNCwM2VtHL3VFIZ+sNJUgUQ== + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz#2dda0791f0eafa12b7a0a5b39858405cc7bde983" + integrity sha512-6ZODuZSFofbxSbcxwsFz+6ioPjb0ISJRRPLZ+WIbjcU2IMU0Io+RGQjjaTgOvNQl007KICBm7zXQaYQEC1r6Bg== dependencies: - "@emotion/memoize" "0.7.4" + "@emotion/memoize" "0.7.3" -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== +"@emotion/memoize@0.7.3": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78" + integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow== "@emotion/stylis@^0.8.3": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + version "0.8.4" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.4.tgz#6c51afdf1dd0d73666ba09d2eb6c25c220d6fe4c" + integrity sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ== "@emotion/unitless@^0.7.0": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.4.tgz#a87b4b04e5ae14a88d48ebef15015f6b7d1f5677" + integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== "@ethersproject/address@^5.0.0-beta.125": version "5.0.0-beta.133" @@ -983,7 +983,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.6.2.tgz#a19ca7149c4dfe8216f2330e6b1ebfe2d075ef92" integrity sha512-EJGsbrHubK1mGxPjWB74AaHAd5m9I+Gg2RRPZzMK6org7QOU9WOBnIMFqoeVto3hKOaEPlk8NV74H6G34/2pZQ== -"@react-native-community/blur@^3.4.1": +"@react-native-community/blur@^3.3.1": version "3.4.1" resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.4.1.tgz#dec04c7d60dd6a4fa7e3af3506feefec804728d0" integrity sha512-XhbS230J7BGuoEamjPFZ5jUWDOW16y+vD0Soyq9Iv1qL8R47esGl54bnfUSMH10WhNXrQzvPxkMzap+ONHpE2w== @@ -1084,10 +1084,10 @@ resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.5.tgz#25421be6cd943a4b1660b62cfbcd45be8891462c" integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== -"@react-native-community/netinfo@^5.0.0": - version "5.3.2" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.3.2.tgz#7b6ee417c2a905663e10de176c00eeab09bdd14c" - integrity sha512-npNcLAz6iWzwRNh+0tSFMlR+xkpSz9NWzX+5AxW40KE6qEZGWdE3dtGBKsezMdWD2Fh+6Je6P6hgUEF8xuZrbA== +"@react-native-community/netinfo@^4.6.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.7.0.tgz#7482d36836cac69d0a0ae25581f65bc472639930" + integrity sha512-a/sDB+AsLEUNmhAUlAaTYeXKyQdFGBUfatqKkX5jluBo2CB3OAuTHfm7rSjcaLB9EmG5iSq3fOTpync2E7EYTA== "@react-native-community/push-notification-ios@^1.0.3": version "1.0.3" @@ -1207,9 +1207,9 @@ tslib "^1.9.3" "@sentry/react-native@^1.2.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.1.tgz#a015ed280ffa8afde3f775b91d173ad7c884e169" - integrity sha512-JE2B/pMvd7+3TFdzs03+DOdrALAHd8bAphJ8tk+nWjX7oQVJNgVn/IvnJfKxasHHBXQ2z+42Xy9n2Fqam/Gq0w== + version "1.2.0" + resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.0.tgz#244ec5f07a4eb07d3d56e7b50fe00f479a733eb5" + integrity sha512-GPY+1dBLgx5I/eOuj+dyMO8DGSoPTatB13WpYbFouGNbx3Ni4SD6EwpU+VdJtqtqVQ0OUVMNm+w/lX4+ggmU5g== dependencies: "@sentry/browser" "^5.10.0" "@sentry/core" "^5.10.0" @@ -1460,9 +1460,9 @@ "@types/istanbul-lib-report" "*" "@types/json-schema@^7.0.3": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" - integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + version "7.0.3" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" + integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== "@types/minimatch@*": version "3.0.3" @@ -1470,9 +1470,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "13.1.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.4.tgz#4cfd90175a200ee9b02bd6b1cd19bc349741607e" - integrity sha512-Lue/mlp2egZJoHXZr4LndxDAd7i/7SQYhV0EjWfb/a4/OZ6tuVwMCVPiwkU5nsEipxEf7hmkSU7Em5VQ8P5NGA== + version "12.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.18.tgz#8d16634797d63c2af5bc647ce879f8de20b56469" + integrity sha512-DBkZuIMFuAfjJHiunyRc+aNvmXYNwV1IPMgGKGlwCp6zh6MKrVtmvjSWK/axWcD25KJffkXgkfvFra8ndenXAw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1516,9 +1516,9 @@ integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== "@types/yargs@^13.0.0": - version "13.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.4.tgz#53d231cebe1a540e7e13727fc1f0d13ad4a9ba3b" - integrity sha512-Ke1WmBbIkVM8bpvsNEcGgQM70XcEh/nbpxQhW7FhrsbCsXSY9BmLB1+LHtD7r9zrsOcFlLiF+a/UeJsdfw3C5A== + version "13.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" + integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== dependencies: "@types/yargs-parser" "*" @@ -1569,37 +1569,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -"@walletconnect/core@^1.0.0-beta.42": - version "1.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.42.tgz#cb9b098590255577571a90b9bda83a0f920020d8" - integrity sha512-Q7pDpTj2/bm7rkAbI+5/mf7SdurLXDfznjvE6jZGg8o23wsYamnkwLnqVMkqeFyUjY7bpHxWqakY813wmmlrZw== +"@walletconnect/core@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.39.tgz#43d05dbabcaeea491c0ee213ed60d2236672010f" + integrity sha512-cJSQe2Ao4okSvohNjA7Bs7Z+0BAznfVVTWBECIX/bGoSFpkAWabGY2Pn2gIYhobQMLSFpE6ZlZ4QfvlPO8HyPw== dependencies: - "@walletconnect/types" "^1.0.0-beta.42" - "@walletconnect/utils" "^1.0.0-beta.42" + "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/utils" "^1.0.0-beta.39" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.42.tgz#3e703a62d80db6f10470ecdd443a3c4025973e3f" - integrity sha512-pcgIx+d4LFjXAgI8+n60fqh5YN/YiVtGhcqdVC/9dadcV/9C0YkFYQiYAXNqXPx/FzaA0+4X8PSyEZY4P61A7g== + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.39.tgz#0db212eba9087055822a89bf73d1cebc5762639e" + integrity sha512-d/QAjL/Rp1lrJeblsHpl+Fa6HTz40A93X5l6oTV0YFAG7bZDPl+OogM337WnjZWfwcn1XaKXSwsmG1NXTQn4Yg== dependencies: - "@walletconnect/core" "^1.0.0-beta.42" - "@walletconnect/types" "^1.0.0-beta.42" - "@walletconnect/utils" "^1.0.0-beta.42" + "@walletconnect/core" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/utils" "^1.0.0-beta.39" -"@walletconnect/types@^1.0.0-beta.42": - version "1.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.42.tgz#1a0db31b37b7765985f78e2b0f2942407685cdcf" - integrity sha512-YBpcYdYGEacOob5VF0/8LRGz/uGynFcwoj9RIEOkDl9JqGQMaXhlZ1M48AfEp8NVQvXRF+cSc3moPDwu3+9USw== +"@walletconnect/types@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.39.tgz#e84463f32d6c450376db3d0ce56f0ece6608bfa7" + integrity sha512-YO/g1HVnFxcMNiUI9LEWEDe5uVHw8D7JzJol+bT71iXymzolnsbG32OayCJM9nHqT48Rpz1EGIno8EjW9jH2OQ== -"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.42": - version "1.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.42.tgz#60304d0ed902a532ac9e535905b5a1c4c8063069" - integrity sha512-/eLcm+tEcvqlYaEaG/L7c+3uNrugZs3a30bwYUbNvlmzYWTNBzU/EV18CGavlZLc/Pb2XtPXevGtDsLlvtR7/Q== +"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.39": + version "1.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.39.tgz#8909b9cffa3999b046ce32cbb21b8ddca97b9183" + integrity sha512-AOlhPkK+IUzGG5iDTupKdUwNW4on1aAj5NyLMMN1+htr06hqaCV8F9HeYibSen22wdSUuLXkIQNy3SR3LPcehA== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.42" + "@walletconnect/types" "^1.0.0-beta.39" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1840,9 +1840,9 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + version "4.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" + integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== dependencies: "@types/color-name" "^1.1.1" color-convert "^2.0.1" @@ -1929,13 +1929,12 @@ array-find-index@^1.0.1: integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-includes@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.0.tgz#48a929ef4c6bb1fa6dc4a92c9b023a261b0ca404" + integrity sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ== dependencies: define-properties "^1.1.3" - es-abstract "^1.17.0" - is-string "^1.0.5" + es-abstract "^1.17.0-next.0" array-map@~0.0.0: version "0.0.0" @@ -2056,7 +2055,7 @@ asyncstorage-down@^4.2.0: ltgt "^2.1.3" tiny-queue "0.2.0" -atob@^2.1.2: +atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -2536,13 +2535,13 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.8.0: - version "4.8.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.3.tgz#65802fcd77177c878e015f0e3189f2c4f627ba44" - integrity sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg== + version "4.8.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" + integrity sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA== dependencies: - caniuse-lite "^1.0.30001017" + caniuse-lite "^1.0.30001015" electron-to-chromium "^1.3.322" - node-releases "^1.1.44" + node-releases "^1.1.42" bser@2.1.1: version "2.1.1" @@ -2712,10 +2711,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001017: - version "1.0.30001019" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001019.tgz#857e3fccaad2b2feb3f1f6d8a8f62d747ea648e1" - integrity sha512-6ljkLtF1KM5fQ+5ZN0wuyVvvebJxgJPTmScOMaFuQN2QuOzvRJnWSKfzQskQU5IOU4Gap3zasYPIinzwUjoj/g== +caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001015: + version "1.0.30001016" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001016.tgz#16ea48d7d6e8caf3cad3295c2d746fe38c4e7f66" + integrity sha512-yYQ2QfotceRiH4U+h1Us86WJXtVHDmy3nEKIdYPsZCYnOV5/tMgGbmoIlrMzmh2VXlproqYtVaKeGDBkMZifFA== capture-exit@^2.0.0: version "2.0.0" @@ -2993,13 +2992,15 @@ code-push@^2.0.6: yazl "^2.4.1" code-push@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.1.0.tgz#02b43b8f8cae1d8d281437aa5635c288399a48ca" - integrity sha512-SwEWx/MLEkRh/oXw4kvi8AIVzR7R2HFWKjsZwX3BWMLEudus3kekwuO2ufk9nYxHcDBZjUfao0G3HIkV9P2Cbw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.0.1.tgz#d6d48b1e112a49148b2244b0213afaf3f818645b" + integrity sha512-UgktdhS47nxtUdGB1l4D6JBnuGB20hMT7QswGj6gQgQbiTjSmOBJ0MK/09fyeYzWKjUnJBEmUud08rC7WzKFMw== dependencies: q "^1.4.1" recursive-fs "^1.1.2" - slash "^3.0.0" + slash "3.0.0" + superagent "^5.1.0" + superagent-proxy "^2.0.0" yazl "^2.4.1" collapse-white-space@^1.0.2: @@ -3102,11 +3103,11 @@ component-inherit@0.0.3: integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + version "2.0.17" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" + integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== dependencies: - mime-db ">= 1.43.0 < 2" + mime-db ">= 1.40.0 < 2" compression@^1.7.1: version "1.7.4" @@ -3437,9 +3438,9 @@ date-fns@^1.30.1: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.8.15: - version "1.8.19" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe" - integrity sha512-7kqOoj3oQSmqbvtvGFLU5iYqies+SqUiEGNT0UtUPPxcPYgY1BrkXR0Cq2R9HYSimBXN+xHkEN4Hi399W+Ovlg== + version "1.8.17" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.17.tgz#53ec413f2a7b02afbea1846d61bb260fa8567cea" + integrity sha512-47VY/htqYqr9GHd7HW/h56PpQzRBSJcxIQFwqL3P20bMF/3az5c3PWdVY3LmPXFl6cQCYHL7c79b9ov+2bOBbw== debounce@^1.2.0: version "1.2.0" @@ -3796,9 +3797,9 @@ ejs@^3.0.1: integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw== electron-to-chromium@^1.3.322: - version "1.3.327" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.327.tgz#516f28b4271727004362b4ac814494ae64d9dde7" - integrity sha512-DNMd91VtKt44LIkFtpICxAWu/GSGFLUMDM/kFINJ3Oe47OimSnbMvO3ChkUCdUyit+pRdhdCcM3+i5bpli5gqg== + version "1.3.322" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" + integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA== elliptic@6.5.2, elliptic@^6.0.0: version "6.5.2" @@ -3900,11 +3901,11 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" - integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + version "2.0.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.4.tgz#a757397dc5d9de973ac9a5d7d4e8ade7cfae9101" + integrity sha512-fZ0KkoxSjLFmhW5lHbUT3tLwy3nX1qEzMYo8koY1vrsAco53CMT1djnBSeC/wUjTEZRhZl9iRw7PaMaxfJ4wzQ== dependencies: - stackframe "^1.1.1" + stackframe "^1.1.0" errorhandler@^1.5.0: version "1.5.1" @@ -3914,23 +3915,22 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" - -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" - integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== +es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1: + version "1.17.0-next.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" + integrity sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" + is-callable "^1.1.4" + is-regex "^1.0.4" object-inspect "^1.7.0" object-keys "^1.1.1" object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" + string.prototype.trimleft "^2.1.0" + string.prototype.trimright "^2.1.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -3990,9 +3990,9 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.x.x, escodegen@^1.9.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.1.tgz#08770602a74ac34c7a90ca9229e7d51e379abc76" - integrity sha512-Q8t2YZ+0e0pc7NRVj3B4tSQ9rim1oi4Fh46k2xhJ2qOiEwhQfdjyEQddWdj7ZFaKmU+5104vn1qrcjEPWq+bgQ== + version "1.12.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" + integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -4192,9 +4192,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.6.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + version "6.7.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" + integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4288,9 +4288,9 @@ eth-contract-metadata@^1.9.3: integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA== ethers@^4.0.28, ethers@^4.0.39: - version "4.0.42" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.42.tgz#7def83a1f770b84d44cf1c2dfc58b7fd29d1d45d" - integrity sha512-2gmmt5x683Xz4QwGDBVJhrdXevVAEr5fnXPGDPou2AKB+zklrirGpl0w1SHBn7Wa9hbL2z6MvP3n7k8Yss2MFg== + version "4.0.40" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.40.tgz#6e1963d10b5d336a13cd81b519c230cc17624653" + integrity sha512-MC9BtV7Hpq4dgFONEfanx9aU9GhhoWU270F+/wegHZXA7FR+2KXFdt36YIQYLmVY5ykUWswDxd+f9EVkIa7JOA== dependencies: aes-js "3.0.0" bn.js "^4.4.0" @@ -5420,9 +5420,9 @@ husky@^2.4.0: slash "^3.0.0" i18n-js@^3.0.11: - version "3.5.1" - resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.1.tgz#9787450894059bec1af791123231e59898eb97c1" - integrity sha512-nJgbE5Vj9qzOQfjdVd/uoMoO8ppVaB/3LB6KOmMfD8IQ1vNNh307iHyQLK8ZnLYWkAszfPvVpYmUt1Le/RuHMQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.0.tgz#e2c41e1f90405d691d33ddce260f3dff9743215e" + integrity sha512-XosH7plfEisWo5XEYxkdlwONsDVQ3sYI3ZoKXcjXdyq+9eVNIJg2h2oPsgadfqcXxpPHMVMNBgmiyW3aEJXg1g== i18next@^17.0.3: version "17.3.1" @@ -5466,9 +5466,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/immer/-/immer-5.1.0.tgz#38d9eba40dbb0389b7ae7b8b99e4661df0cf89e3" - integrity sha512-t6gyFtTcokCuI0tX9KQZJQAkIjSqo/nTeJnwojfty69EzrorZbywwhZ8qNNlF+faajHeRnhOvM2F40KHLFCghQ== + version "5.0.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.1.tgz#1a1184fa758f68f1b5573db840825fb5164cceca" + integrity sha512-KFHV1ivrBmPCVRhjy9oBooypnPfJ876NTrWXMNoUhXFAaWWAViVqZ4l6HxPST52qcN82qqsR38/pCGYRWP5W7w== import-fresh@^2.0.0: version "2.0.0" @@ -5631,9 +5631,9 @@ inquirer@^6.2.0: through "^2.3.6" inquirer@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.2.tgz#b39b205b95c9424839a1fd991d60426cf9bbc0e9" - integrity sha512-cZGvHaHwcR9E3xK9EGO5pHKELU+yaeJO7l2qGKIbqk4bCuDuAn15LCoUTS2nSkfv9JybFlnAGrOcVpCDZZOLhw== + version "7.0.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.1.tgz#13f7980eedc73c689feff3994b109c4e799c6ebb" + integrity sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw== dependencies: ansi-escapes "^4.2.1" chalk "^2.4.2" @@ -5728,10 +5728,10 @@ is-buffer@^2.0.0, is-buffer@^2.0.2, is-buffer@~2.0.3: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-ci@^1.0.10: version "1.2.1" @@ -5762,9 +5762,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-decimal@^1.0.0: version "1.0.3" @@ -5916,7 +5916,7 @@ is-redirect@^1.0.0: resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= -is-regex@^1.0.4, is-regex@^1.0.5: +is-regex@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== @@ -5943,11 +5943,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -5961,9 +5956,9 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-what@^3.3.1: - version "3.5.0" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.5.0.tgz#c50b0e8f3021e0b39410c159bea43a5510d99027" - integrity sha512-00pwt/Jf7IaRh5m2Dp93Iw8LG2cd3OpDj3NrD1XPNUpAWVxPvBP296p4IiGmIU4Ur0f3f56IoIM+fS2pFYF+tQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.4.0.tgz#a9b3fe0c22f52d49efef977f640da44e65a3f866" + integrity sha512-oFdBRuSY9PocqPoUUseDXek4I+A1kWGigZGhuG+7GEkp0tRkek11adc0HbTEVsNvtojV7rp0uhf5LWtGvHzoOQ== is-whitespace-character@^1.0.0: version "1.0.3" @@ -6091,9 +6086,9 @@ istanbul-reports@^2.2.6: handlebars "^4.1.2" iterall@^1.2.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" - integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== jest-changed-files@^24.9.0: version "24.9.0" @@ -7477,10 +7472,10 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": + version "1.42.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" + integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== mime-db@~1.23.0: version "1.23.0" @@ -7495,11 +7490,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + version "2.1.25" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" + integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== dependencies: - mime-db "1.43.0" + mime-db "1.42.0" mime@1.6.0: version "1.6.0" @@ -7839,10 +7834,10 @@ node-pre-gyp@*: semver "^5.3.0" tar "^4.4.2" -node-releases@^1.1.44: - version "1.1.44" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.44.tgz#cd66438a6eb875e3eb012b6a12e48d9f4326ffd7" - integrity sha512-NwbdvJyR7nrcGrXvKAvzc5raj/NkoJudkarh2yIpJ4t0NH4aqjUDz/486P+ynIW5eokKOfzGNRdYoLfBlomruw== +node-releases@^1.1.42: + version "1.1.42" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7" + integrity sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA== dependencies: semver "^6.3.0" @@ -7926,9 +7921,9 @@ npm-run-path@^2.0.0: path-key "^2.0.0" npm-run-path@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + version "4.0.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.0.tgz#d644ec1bd0569187d2a52909971023a0a58e8438" + integrity sha512-8eyAOAH+bYXFPSnNnKr3J+yoybe8O87Is5rtAQ8qRczJz1ajcsjg8l2oZqP+Ppx15Ii3S1vUTjQN2h4YO2tWWQ== dependencies: path-key "^3.0.0" @@ -8307,9 +8302,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: p-try "^2.0.0" @@ -8603,9 +8598,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.2.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" - integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== + version "2.1.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5" + integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA== pify@^2.0.0: version "2.3.0" @@ -8809,9 +8804,9 @@ postcss-value-parser@^4.0.2: integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.7: - version "7.0.26" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587" - integrity sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA== + version "7.0.25" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.25.tgz#dd2a2a753d50b13bed7a2009b4a18ac14d9db21e" + integrity sha512-NXXVvWq9icrm/TgQC0O6YVFi4StfJz46M1iNd/h6B26Nvh/HKI+q4YZtFN/EjcInZliEscO/WL10BXnc1E5nwg== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -8959,9 +8954,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: - version "1.7.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== + version "1.6.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" + integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== public-encrypt@^4.0.0: version "4.0.3" @@ -9109,9 +9104,9 @@ react-coin-icon@0.1.13: styled-components "4.4.1" react-devtools-core@^4.0.6: - version "4.4.0" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.4.0.tgz#614cabe5f3d6fb69730dc76da10f8fa4eb033695" - integrity sha512-ayyz+clbjekj5rqTjieI/eE0xGZkgotklVnxfa4Pyk9se5+AHUAhUwMhLvK5N2+mR2PGOZkv159RDTmvgs+wZQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.2.1.tgz#0122ccb8a041b0b61811425a57e9dec05125e9d8" + integrity sha512-Puo0PwkpxWZY4E0cU7lpOR6Lh5UhGoOScSdhVtvK6HK6InC6+k9ypyVHI2ar2OoBasm3wP5mJlDHcUmbmqF78w== dependencies: es6-symbol "^3" shell-quote "^1.6.1" @@ -9155,9 +9150,9 @@ react-native-bundle-visualizer@^2.0.1: source-map-explorer "^2.1.2" react-native-camera@^3.9.0: - version "3.15.1" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.1.tgz#8e4eb67cb6687b5250f849b348f0d19a01649105" - integrity sha512-xj1sljzFq8HVX22d2T945dsJdK/KFb3jaXUHEYGwMp/zz0ypIs3mY3NezdpyYpS1ioKKzdIcLrxz2VKzDCXaCg== + version "3.15.0" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.0.tgz#dd8c7fcf75b347e0b07c1dedeba2ba47504ff80a" + integrity sha512-GoRq2gHMvidcMCzj0AjaIbrJy5ZRE1XxLUIGN+M/Ev2r2RXGFWBToGoDvy4KZcwF3THWefVAZL1It+fT8pvxgQ== dependencies: prop-types "^15.6.2" @@ -9202,10 +9197,10 @@ react-native-crypto@^2.2.0: public-encrypt "^4.0.0" randomfill "^1.0.3" -react-native-device-info@5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-5.3.1.tgz#d764732c4841b6b6c2f42516e8840075717ea88a" - integrity sha512-e/fRDoah+HxItscOJTGJY8zyVKmBUdf53VWIDGLGV4VVZ0mfzIQ2uo0ULGri0vjGUYqgyqgnW3jybPSznMxKcA== +react-native-device-info@^2.1.3: + version "2.3.2" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" + integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== react-native-dotenv@^0.2.0: version "0.2.0" @@ -9240,6 +9235,11 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== +react-native-hooks@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/react-native-hooks/-/react-native-hooks-0.9.0.tgz#589fc2390296d9afe03327298dabcf0a1f350910" + integrity sha512-yqSAH0zxqjYHYPo6mPut3dEROoB5qMvsAbN3EK0MDQrWA5zdqmzgTEpS9/qwXaIyllk6hQbHxYnRTWq2uq4tJQ== + react-native-indicators@0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" @@ -9257,10 +9257,10 @@ react-native-iphone-x-helper@^1.2.1: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== -react-native-keychain@4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.3.tgz#38c6c0021ed697b6149d460dd5910c3c92d36ae7" - integrity sha512-mXlBcHueQ3i73GU9hc7giXJqkh+oL0f8As2H+1XWW2GovkM7xQEZNoro3DsYDIWzFW3eRoF8DmUZIGbLLEVp3Q== +react-native-keychain@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.1.tgz#c332f5d9aaf597255ae6ea4ca7d5c84a24684a1d" + integrity sha512-AqQp4Hib9y5DP5es5umEAhxKG7L0bA8cHNFhvlqs6oUcbUoKtXmhLDo3wzvnCF+bm8DXpGhvkU6P0LkfO0AgPQ== react-native-languages@^3.0.0: version "3.0.2" @@ -9322,12 +9322,12 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/1ea8cc3d8b713d4bac2529c010b035c6d1529df4" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/c7d9cb4a5bb855b9bd944c19947564b8ee2152e6" -react-native-redash@^9.0.0: - version "9.5.4" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.5.4.tgz#61871ef547c1b505e66b2fcdf1eef26db0ad6c0b" - integrity sha512-1NfBORcLESwtkDyZD0dyK/mdkr9YJ7IQ4zlxSQpqMLr/KOgNp3Hsri+cJe/dqfwRhyCPo64DSJgvFQu3kYT/kw== +react-native-redash@8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-8.2.2.tgz#e2944490fbd150087043cbb6b93cf804aa932313" + integrity sha512-9LYrtR/Y4HrEpuL+CjkI3bqygwSC3S9gF1CP/to1Q5QulR42sFMknR9X/NNFDwmbmvAZoV4soHNhGpHCkGtqvg== dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -9377,10 +9377,10 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -react-native-svg@9.13.6: - version "9.13.6" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.6.tgz#5365fba2bc460054b90851e71f2a71006a5d373f" - integrity sha512-vjjuJhEhQCwWjqsgWyGy6/C/LIBM2REDxB40FU1PMhi8T3zQUwUHnA6M15pJKlQG8vaZyA+QnLyIVhjtujRgig== +react-native-svg@9.13.3: + version "9.13.3" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.3.tgz#6414b337d55af169ac2487ab70f3108404434446" + integrity sha512-H50b2m4jvrQ7KxKs8uYSuWecr6e5XC7BDfS7DaA96+0Owjh0C9DksI5l8SRyHnmE+emiYMPu6Qqfr9dCyKkaJQ== dependencies: css-select "^2.0.2" css-tree "^1.0.0-alpha.37" @@ -9417,10 +9417,15 @@ react-native-tooltip@marcosrdz/react-native-tooltip#master: version "5.2.1" resolved "https://codeload.github.com/marcosrdz/react-native-tooltip/tar.gz/e0e88d212b5b7f350e5eabba87f588a32e0f2590" +react-native-touch-id@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/react-native-touch-id/-/react-native-touch-id-4.4.1.tgz#8b1bb2d04c30bac36bb9696d2d723e719c4a8b08" + integrity sha512-1jTl8fC+0fxvqegy/XXTyo6vMvPhjzkoDdaqoYZx0OH8AT250NuXnNPyKktvigIcys3+2acciqOeaCall7lrvg== + react-native-udp@^2.6.1: - version "2.7.0" - resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.7.0.tgz#d04c5100fcbff343f8a2bf35a3025743d8960f93" - integrity sha512-tT+Wn0yLbdaTohXkGGor0HYgScGaASWCaCLSO1kCIUdNke7AtcOX5a5nfNLYrEjdUn7/2HRofuplyky7iJHSQA== + version "2.6.1" + resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.6.1.tgz#ce9f2479f8af6d1bb356cfee69c89cf92fdd50be" + integrity sha512-KctAXtfBjRe+rGLvms92C82MsrZUwUyODwGskY6mDPigMaDTmsKdNqLCXgWh0g6ZmB2UtOzFsbPphy36NyM3KA== dependencies: base64-js "0.0.8" events "^1.0.2" @@ -9435,7 +9440,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/bd0c37e456392090507f227b8fb90c1eb7c3d327" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/69e9f3a3891a9b4a9acd58e97ae4e6f9ebcf968d" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0" @@ -9642,9 +9647,9 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea string_decoder "~0.10.x" readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -9744,9 +9749,9 @@ redux-thunk@^2.3.0: integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== redux@^4.0.1: - version "4.0.5" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" - integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== + version "4.0.4" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796" + integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q== dependencies: loose-envify "^1.4.0" symbol-observable "^1.2.0" @@ -9839,9 +9844,9 @@ regjsgen@^0.5.0: integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== regjsparser@^0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.2.tgz#fd62c753991467d9d1ffe0a9f67f27a529024b96" - integrity sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q== + version "0.6.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.1.tgz#5b6b28c418f312ef42898dc6865ae2d4b9f0f7a2" + integrity sha512-7LutE94sz/NKSYegK+/4E77+8DipxF+Qn2Tmu362AcmsF2NYq/wx3+ObvU90TKEhjf7hQoFXo23ajjrXP7eUgg== dependencies: jsesc "~0.5.0" @@ -10184,9 +10189,9 @@ rxjs@^5.4.3: symbol-observable "1.0.1" rxjs@^6.4.0, rxjs@^6.5.3: - version "6.5.4" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" - integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== dependencies: tslib "^1.9.0" @@ -10589,9 +10594,9 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.2.1.tgz#4bd236a1fe73e8b9db475f60197c48fc041928b8" - integrity sha512-vfjS5IRaENgXtTq2Bym0ctEorYGYNHLVCVZZeL1fvkD5iBoWKMlUhF/oFBTcTn9cxry1flplyvk0QGTROafB3Q== + version "2.1.2" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.2.tgz#305d61efbb1d1ebbf24a9fffef718635054d509c" + integrity sha512-rgujHHHwf0/HCSTFbdTPJETGTgbGqVDD068Ob/wfV41u3AdU8iknSvGTDoU8vCIUeZuLnHX4JYsQ1RMd129XCQ== dependencies: btoa "^1.2.1" chalk "^3.0.0" @@ -10603,14 +10608,14 @@ source-map-explorer@^2.1.2: open "^7.0.0" source-map "^0.7.3" temp "^0.9.1" - yargs "^15.1.0" + yargs "^15.0.2" source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: - atob "^2.1.2" + atob "^2.1.1" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" @@ -10726,29 +10731,29 @@ stable@^0.1.8: integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-generator@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" - integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + version "2.0.4" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.4.tgz#027513eab2b195bbb43b9c8360ba2dd0ab54de09" + integrity sha512-ha1gosTNcgxwzo9uKTQ8zZ49aUp5FIUW58YHFxCqaAHtE0XqBg0chGFYA1MfmW//x1KWq3F4G7Ug7bJh4RiRtg== dependencies: - stackframe "^1.1.1" + stackframe "^1.1.0" stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== -stackframe@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.1.tgz#ffef0a3318b1b60c3b58564989aca5660729ec71" - integrity sha512-0PlYhdKh6AfFxRyK/v+6/k+/mMfyiEBbTM5L94D0ZytQnJ166wuwoTYLHFWGbs2dpA8Rgq763KGWmN1EQEYHRQ== +stackframe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83" + integrity sha512-Vx6W1Yvy+AM1R/ckVwcHQHV147pTPBKWCRLrXMuPrFVfvBUc3os7PR1QLIWCMhPpRg5eX9ojzbQIMLGBwyLjqg== stacktrace-gps@^3.0.3: - version "3.0.4" - resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" - integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.3.tgz#b89f84cc13bb925b96607e737b617c8715facf57" + integrity sha512-51Rr7dXkyFUKNmhY/vqZWK+EvdsfFSRiQVtgHTFlAdNIYaDD7bVh21yBHXaNWAvTD+w+QSjxHg7/v6Tz4veExA== dependencies: source-map "0.5.6" - stackframe "^1.1.1" + stackframe "^1.1.0" stacktrace-js@^2.0.0: version "2.0.1" @@ -10855,18 +10860,18 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== +string.prototype.trimleft@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== +string.prototype.trimright@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" @@ -11084,9 +11089,9 @@ superagent-proxy@^2.0.0: proxy-agent "3" superagent@^5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.3.tgz#9502db541559d3d9e7acfa30f70d1186c0faa88d" - integrity sha512-2bno1Nb4uvZPECTJ7NDYlae6Q8LLQoZZZ9Vumd346jU1UGVkNC/lQI42jHwtrqVoepyt0QxNKFty01IRKgD4CA== + version "5.1.2" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.2.tgz#b122f3a62b14c4d638612667033a7eb43c4f4d83" + integrity sha512-VwPCbi9H02qDtTbdY+e3+cK5XR0YHsJy9hmeCOXLQ8ezjq8+S1Bs4MdNRmpmf2QjDBetD7drG7/nEta7E3E6Sg== dependencies: component-emitter "^1.3.0" cookiejar "^2.1.2" @@ -11523,9 +11528,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= ua-parser-js@^0.7.18: - version "0.7.21" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" - integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ== + version "0.7.20" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" + integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== uglify-es@^3.1.9: version "3.3.9" @@ -11536,9 +11541,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.7.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a" - integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg== + version "3.7.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" + integrity sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -11897,22 +11902,22 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.11" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.11.tgz#7c0632bccc4b2b955f99f99f43d96d3eece1de42" - integrity sha512-26Qv1SFp6x3XmCqU1BRceRsSKRO3xkQa6/K8ziSRt52/LQPiw5ipSxlGVSlzIoi5LCmQVEqUajhiVEMNlFXhNw== + version "3.4.10" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.10.tgz#2ff5ff4e4f31acd160619081ca279306933aaf8f" + integrity sha512-0Uy1bgVvnTkTjPOOZUCWFmXR71YgKAGu3XE3bIi9IPwTsn5apiqulOaz1UMs2ldlrHeLgsdHGEkFJnDhxtqyVQ== dependencies: jsonc-parser "^2.2.0" - vscode-languageserver-textdocument "^1.0.0-next.5" - vscode-languageserver-types "^3.15.0-next.9" + vscode-languageserver-textdocument "^1.0.0-next.4" + vscode-languageserver-types "^3.15.0-next.6" vscode-nls "^4.1.1" - vscode-uri "^2.1.1" + vscode-uri "^2.1.0" -vscode-languageserver-textdocument@^1.0.0-next.5: +vscode-languageserver-textdocument@^1.0.0-next.4: version "1.0.0-next.5" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.5.tgz#dbb7a45dd973a19261a7c57ab9a439c40f3799ee" integrity sha512-1jp/zAidN/bF/sqPimhBX1orH5G4rzRw63k75TesukJDuxm8yW79ECStWbDSy41BHGOwSGN4M69QFvhancSr5A== -vscode-languageserver-types@^3.15.0-next.9: +vscode-languageserver-types@^3.15.0-next.6: version "3.15.0-next.9" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz#957a9d1d5998a02edf62298fb7e37d9efcc6c157" integrity sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw== @@ -11922,7 +11927,7 @@ vscode-nls@^4.1.1: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== -vscode-uri@^2.1.1: +vscode-uri@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90" integrity sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A== @@ -12158,7 +12163,7 @@ xcode@1.0.0: simple-plist "^0.2.1" uuid "3.0.1" -xcode@2.0.0: +xcode@2.0.0, xcode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.0.0.tgz#134f1f94c26fbfe8a9aaa9724bfb2772419da1a2" integrity sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw== @@ -12166,14 +12171,6 @@ xcode@2.0.0: simple-plist "^1.0.0" uuid "^3.3.2" -xcode@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.1.0.tgz#bab64a7e954bb50ca8d19da7e09531c65a43ecfe" - integrity sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ== - dependencies: - simple-plist "^1.0.0" - uuid "^3.3.2" - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -12202,9 +12199,9 @@ xmldoc@^1.1.2: sax "^1.2.1" xmldom@0.1.x: - version "0.1.31" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" - integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== + version "0.1.27" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" + integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= xmlhttprequest-ssl@~1.5.4: version "1.5.5" @@ -12350,10 +12347,10 @@ yargs@^12.0.2, yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" - integrity sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg== +yargs@^15.0.2: + version "15.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.0.2.tgz#4248bf218ef050385c4f7e14ebdf425653d13bd3" + integrity sha512-GH/X/hYt+x5hOat4LMnCqMd8r5Cv78heOMIJn1hr7QPPBqfeC6p89Y78+WB9yGDvfpCvgasfmWLzNzEioOUD9Q== dependencies: cliui "^6.0.0" decamelize "^1.2.0" From 393d92a089b92fd576397ef162afde964cf2d8cc Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 7 Jan 2020 18:07:19 -0500 Subject: [PATCH 633/636] Revert "Revert "Merge pull request #290 from rainbow-me/better-biometric-button"" This reverts commit be62888700ad5b2b4da821be92ebe2cd3d489726. --- ios/Podfile.lock | 126 ++-- package.json | 14 +- patches/react-native-keychain+4.0.3.patch | 13 + src/App.js | 15 +- src/components/OfflineBadge.js | 98 ++- src/components/animations/ScaleInAnimation.js | 2 +- src/components/animations/index.js | 2 +- src/components/asset-list/AssetList.js | 14 +- .../HoldToAuthorizeButton.js | 184 +++--- .../HoldToAuthorizeButtonIcon.js | 23 +- .../exchange/ConfirmExchangeButton.js | 30 +- src/components/gas/GasSpeedLabelPagerItem.js | 4 +- src/components/icons/BiometryIcon.js | 78 +-- src/components/icons/Icon.js | 2 + src/components/icons/svg/FaceIdIcon.js | 5 +- src/components/icons/svg/PasscodeIcon.js | 37 ++ .../qrcode-scanner/QRCodeScanner.js | 149 +++-- src/components/send/SendButton.js | 3 +- .../settings-menu/SettingsSection.js | 4 +- src/handlers/localstorage/uniswap.js | 4 +- src/hoc/index.js | 1 - src/hoc/withNetInfo.js | 23 - src/hoc/withUniswapAssets.js | 19 +- src/hooks/index.js | 5 + src/hooks/useAppState.js | 30 + src/hooks/useBiometryType.js | 50 ++ src/hooks/useClipboard.js | 26 + src/hooks/useInternetStatus.js | 27 + src/hooks/usePrevious.js | 11 + src/redux/uniswap.js | 13 +- src/references/index.js | 9 + src/screens/ImportSeedPhraseSheet.js | 2 +- src/screens/QRScannerScreen.js | 137 ++--- src/screens/TransactionConfirmationScreen.js | 34 +- src/utils/deviceUtils.js | 3 +- src/utils/haptics.js | 23 + src/utils/index.js | 1 + yarn.lock | 577 +++++++++--------- 38 files changed, 1001 insertions(+), 797 deletions(-) create mode 100644 patches/react-native-keychain+4.0.3.patch create mode 100644 src/components/icons/svg/PasscodeIcon.js delete mode 100644 src/hoc/withNetInfo.js create mode 100644 src/hooks/index.js create mode 100644 src/hooks/useAppState.js create mode 100644 src/hooks/useBiometryType.js create mode 100644 src/hooks/useClipboard.js create mode 100644 src/hooks/useInternetStatus.js create mode 100644 src/hooks/usePrevious.js create mode 100644 src/utils/haptics.js diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 3a6fed86986..5f00b27fd43 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -55,7 +55,7 @@ PODS: - FirebaseCore (~> 6.0) - GoogleUtilities/Environment (~> 6.0) - GoogleUtilities/UserDefaults (~> 6.0) - - FirebaseMessaging (4.1.9): + - FirebaseMessaging (4.1.10): - FirebaseAnalyticsInterop (~> 1.3) - FirebaseCore (~> 6.2) - FirebaseInstanceID (~> 4.1) @@ -82,26 +82,26 @@ PODS: - "GoogleUtilities/NSData+zlib (~> 6.0)" - nanopb (= 0.3.9011) - GoogleDataTransport (3.2.0) - - GoogleDataTransportCCTSupport (1.2.2): + - GoogleDataTransportCCTSupport (1.2.3): - GoogleDataTransport (~> 3.2) - nanopb (~> 0.3.901) - - GoogleUtilities/AppDelegateSwizzler (6.3.2): + - GoogleUtilities/AppDelegateSwizzler (6.4.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.3.2) - - GoogleUtilities/Logger (6.3.2): + - GoogleUtilities/Environment (6.4.0) + - GoogleUtilities/Logger (6.4.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.3.2): + - GoogleUtilities/MethodSwizzler (6.4.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.3.2): + - GoogleUtilities/Network (6.4.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.3.2)" - - GoogleUtilities/Reachability (6.3.2): + - "GoogleUtilities/NSData+zlib (6.4.0)" + - GoogleUtilities/Reachability (6.4.0): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.3.2): + - GoogleUtilities/UserDefaults (6.4.0): - GoogleUtilities/Logger - JWT (3.0.0-beta.12): - Base64 (~> 1.1.2) @@ -285,17 +285,17 @@ PODS: - React-jsinspector (1000.0.0) - react-native-blur (0.8.0): - React - - react-native-camera (3.15.0): + - react-native-camera (3.15.1): - React - - react-native-camera/RCT (= 3.15.0) - - react-native-camera/RN (= 3.15.0) - - react-native-camera/RCT (3.15.0): + - react-native-camera/RCT (= 3.15.1) + - react-native-camera/RN (= 3.15.1) + - react-native-camera/RCT (3.15.1): - React - - react-native-camera/RN (3.15.0): + - react-native-camera/RN (3.15.1): - React - react-native-mail (4.1.0): - React - - react-native-netinfo (4.7.0): + - react-native-netinfo (5.3.2): - React - react-native-randombytes (3.5.3): - React @@ -306,7 +306,7 @@ PODS: - react-native-text-input-mask (2.0.0): - React - RNInputMask - - react-native-udp (2.6.1): + - react-native-udp (2.7.0): - React - react-native-version-number (0.3.6): - React @@ -380,7 +380,7 @@ PODS: - React - RNCPushNotificationIOS (1.0.3): - React - - RNDeviceInfo (2.3.2): + - RNDeviceInfo (5.3.1): - React - RNFastImage (7.0.2): - React @@ -402,7 +402,7 @@ PODS: - RNGestureHandler (1.5.2): - React - RNInputMask (4.1.0) - - RNKeychain (4.0.1): + - RNKeychain (4.0.3): - React - RNLanguages (3.0.2): - React @@ -414,16 +414,16 @@ PODS: - React - RNScreens (1.0.0-alpha.23): - React - - RNSentry (1.2.0): + - RNSentry (1.2.1): - React - Sentry (~> 4.4.0) - RNStoreReview (0.1.5): - React - - RNSVG (9.13.3): + - RNSVG (9.13.6): - React - - SDWebImage (5.4.0): - - SDWebImage/Core (= 5.4.0) - - SDWebImage/Core (5.4.0) + - SDWebImage (5.4.1): + - SDWebImage/Core (= 5.4.1) + - SDWebImage/Core (5.4.1) - SDWebImageWebPCoder (0.2.5): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.0) @@ -437,8 +437,6 @@ PODS: - React - ToolTipMenu (5.2.1): - React - - TouchID (4.4.1): - - React - Yoga (1.14.0) DEPENDENCIES: @@ -507,7 +505,6 @@ DEPENDENCIES: - SRSRadialGradient (from `../node_modules/react-native-radial-gradient/ios`) - TcpSockets (from `../node_modules/react-native-tcp`) - ToolTipMenu (from `../node_modules/react-native-tooltip`) - - TouchID (from `../node_modules/react-native-touch-id`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -660,8 +657,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-tcp" ToolTipMenu: :path: "../node_modules/react-native-tooltip" - TouchID: - :path: "../node_modules/react-native-touch-id" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -672,10 +667,10 @@ SPEC CHECKSUMS: BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 CodePush: d2e54ad42df82a8db65b2d23d8191b950ba945e1 Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 - DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 + DoubleConversion: cde416483dac037923206447da6e1454df403714 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 9937910f2681d66c0d28631d16058aeec6b1d009 - FBReactNativeSpec: 84bac6a4bcb261924c1e19c60833d0916439dba9 + FBLazyVector: 904ace83555a7813bc9117a045dff654ae711d39 + FBReactNativeSpec: ac66550fd5331a88a825860ae4e45e058571ef73 Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -683,77 +678,76 @@ SPEC CHECKSUMS: FirebaseCoreDiagnostics: 511f4f3ed7d440bb69127e8b97c2bc8befae639e FirebaseCoreDiagnosticsInterop: e9b1b023157e3a2fc6418b5cb601e79b9af7b3a0 FirebaseInstanceID: ebd2ea79ee38db0cb5f5167b17a0d387e1cc7b6e - FirebaseMessaging: e8d71368a5c579083da02203146c953f3386d503 + FirebaseMessaging: 089b7a4991425783384acc8bcefcd78c0af913bd FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 - Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 - glog: 1f3da668190260b06b429bb211bfbee5cd790c28 + Folly: f1c65c1bdabb35617432cac9cf17d0cad310ce6f + glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 GoogleAppMeasurement: dfe55efa543e899d906309eaaac6ca26d249862f GoogleDataTransport: 8e9b210c97d55fbff306cc5468ff91b9cb32dcf5 - GoogleDataTransportCCTSupport: ef79a4728b864946a8aafdbab770d5294faf3b5f - GoogleUtilities: 547a86735c6f0ee30ad17e94df4fc21f616b71cb + GoogleDataTransportCCTSupport: 202d7cdf9c4a7d81a2bb7f7e7e1ba6faa421b1f2 + GoogleUtilities: 29bd0d8f850efbd28cff6d99e8b7da1f8d236bcf JWT: 9b5c05abbcc1a0e69c3c91e1655b3387fc7e581d libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: 8261e5489a9c6a59fc1fb2ad37966ac8c76fd674 - RCTTypeSafety: cfe8ceac14dd07464e36cc5a6db4d60c89c8d0c4 - React: 1594d3f52fc5de51b1e55a521f93d07d68b814fb - React-Core: 4d1aba76c386522959c0d3d4e51ebb0554ad015f - React-CoreModules: 3a9d2a1c2df1936927163a19fdb0f2a5a13c1d76 - React-cxxreact: 06df23866978079cfb525c68bf8b59bb52884a4e - React-jsi: a9e632da28b1168e8b41e92cc69c5c88d1af4642 - React-jsiexecutor: 8e5e9d516a76c5ebbd5fa557a371de68f7b9d2b6 - React-jsinspector: beded58f6e205bc58a38a3c57ce87443d7d20848 + RCTRequired: fc5f657b89514039fccfe826c524126538ef5da3 + RCTTypeSafety: 7860ee3c7d06cd49de0a12dde6784c925853cedf + React: 3da88a786975d0d2244b076b0696411defd3d37c + React-Core: 39042bc55d07e4fabf6588892d9eaf88dca37051 + React-CoreModules: ceae464bbadcbaf58a1031768c137dd88f339f60 + React-cxxreact: 03194eb1b9d558d6f48efa7d41a93b90318c3016 + React-jsi: 22a0960d7040824a23dff7701d7738f3c1d5807f + React-jsiexecutor: 00e5aebe98359d913d43af8cc23d5ebb17083723 + React-jsinspector: 56e72f672b35aeade701012e6e39876897546cfb react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c - react-native-camera: 52114c432860b89986c9ee4919d00a48a6ba7abb + react-native-camera: 1ba3e7f2375a6b44ae09ce9be70268e0b225bc10 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 - react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9 + react-native-netinfo: 817823a90f13ced48413875c0820df04c3aae28d react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 react-native-safe-area-context: 13004a45f3021328fdd9ee1f987c3131fb65928d react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865 react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 - react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 + react-native-udp: ff9d13e523f2b58e6bc5d4d32321ac60671b5dc9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 1c82cde015e743883cb80b6846949e0ce971d77c - React-RCTAnimation: 34328140d4295757f618aa997b0db8f7ca63f15d - React-RCTBlob: 954ec69326178e62b0425c1fc1662b046d473964 - React-RCTImage: b0d39340cb001dafbcb353d856ed3ab8ed842d2e - React-RCTLinking: 5ba5ceddfa18388cec61323f14653633d650bc1d - React-RCTNetwork: f36b6bc184f45f9c11b695ecf5dcc6bcf41c2714 - React-RCTSettings: 086ae71d112cf26d42435d3e98c8acccdfb678d6 - React-RCTText: 91ca55794c1eaf44e59ca6160fd561fec5697c49 - React-RCTVibration: 7f9ac599dfeb48f11e6ad50add4b09ac3f38366b - ReactCommon: bfd19eca47e6320353b895fa3eab70223efe6923 + React-RCTActionSheet: 48dc86f556d46f012c92fdc4fce37e2f61972a7a + React-RCTAnimation: f2b22ff8ee4a8f726cb2a2c0489dc43160a9ba78 + React-RCTBlob: e1cc220434c170cfb87972c5f9ddeca42bc859c2 + React-RCTImage: a71a7ae08498f10f025cb3859e623bc35d984ac2 + React-RCTLinking: 8cd1a2e5855917d8202dbbec645ce96a4dc56599 + React-RCTNetwork: 52edddadac17aebf35340cc890d366033bcaa497 + React-RCTSettings: 5ef91ca864871af290fc7f181a1fc8cf931023fa + React-RCTText: ad1509728a06baaf16810c807ae86fd0f94218cd + React-RCTVibration: 72d3e98346f20ac4c59649bff2a02f229048625e + ReactCommon: b3d60106340b0c5cb774de530a3ec44e99d3365e ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNCPushNotificationIOS: 83ec11fe19d4ea9e32cc339d8e7d2cc3c88f543e - RNDeviceInfo: 17e34f6dd902f08d88cbe2c0b7a01be948d43641 + RNDeviceInfo: 6f20764111df002b4484f90cbe0a861be29bcc6c RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 RNFBApp: 5b215aacc09105a1761de31b9a0eb2abcce06253 RNFBCrashlytics: 0469cb96b00904e0c9604b9636d8eeab31115b08 RNFBMessaging: be0b936394416ec5503add603f2c0a641c353063 RNGestureHandler: 946a7691e41df61e2c4b1884deab41a4cdc3afff RNInputMask: 815461ebdf396beb62cf58916c35cf6930adb991 - RNKeychain: 45dbd50d1ac4bd42c3740f76ffb135abf05746d0 + RNKeychain: f5783613aa3095af63345ddb9626a729bd4a3897 RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e RNOS: 811de7b4be8824a86a775ade934147a02edb9b5a RNReactNativeHapticFeedback: e11a4da0ce174e9f88b03cbaf5d76d94633cdee2 RNReanimated: 8b675a650fc67c87f63d4345a1b2d4a699c25e4f RNScreens: f28b48b8345f2f5f39ed6195518291515032a788 - RNSentry: b63ba6a29ee142b5c3221896be8ff6cda587e03f + RNSentry: 9b1d983b2d5d1c215ba6490348fd2a4cc23a8a9d RNStoreReview: 62d6afd7c37db711a594bbffca6b0ea3a812b7a8 - RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c - SDWebImage: 5bf6aec6481ae2a062bdc59f9d6c1d1e552090e0 + RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f + SDWebImage: 29c340dbdcef342bb13125553f4e19ce056b07a7 SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987 Sentry: 14bdd673870e8cf64932b149fad5bbbf39a9b390 SRSRadialGradient: 8fdf3adb76320500bc792390ecebc1b82aac54ec SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4 - Yoga: f013762d91dd7bfd536dedce0d6c4a52ca0401cf + Yoga: d35afc581c45e82ecabf981b93d17f02ae19c49f PODFILE CHECKSUM: e38b8f3a80d4f969b2bd4796967957156faf7531 diff --git a/package.json b/package.json index 32e2590d827..35a39cbf4ff 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "@hocs/safe-timers": "^0.4.0", "@hocs/with-view-layout-props": "^0.2.0", "@react-native-community/async-storage": "1.6.2", - "@react-native-community/blur": "^3.3.1", + "@react-native-community/blur": "^3.4.1", "@react-native-community/masked-view": "^0.1.5", - "@react-native-community/netinfo": "^4.6.0", + "@react-native-community/netinfo": "^5.0.0", "@react-native-community/push-notification-ios": "^1.0.3", "@react-native-firebase/app": "^6.2.0", "@react-native-firebase/crashlytics": "^6.2.0", @@ -84,17 +84,16 @@ "react-native-circular-progress": "^1.3.4", "react-native-code-push": "^5.6.0", "react-native-crypto": "^2.2.0", - "react-native-device-info": "^2.1.3", + "react-native-device-info": "5.3.1", "react-native-dotenv": "^0.2.0", "react-native-emoji": "1.5.0", "react-native-fast-image": "andrewschenk-linx/react-native-fast-image#fix-ios-xcode-proj", "react-native-gesture-handler": "1.5.2", "react-native-haptic-feedback": "^1.8.2", - "react-native-hooks": "^0.9.0", "react-native-indicators": "0.17.0", "react-native-ios11-devicecheck": "^0.0.3", "react-native-iphone-x-helper": "^1.2.1", - "react-native-keychain": "4.0.1", + "react-native-keychain": "4.0.3", "react-native-languages": "^3.0.0", "react-native-level-fs": "^3.0.1", "react-native-linear-gradient": "^2.5.6", @@ -106,18 +105,17 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "software-mansion/react-native-reanimated", - "react-native-redash": "8.2.2", + "react-native-redash": "^9.0.0", "react-native-safe-area-context": "^0.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", "react-native-splash-screen": "^3.2.0", "react-native-storage": "^1.0.1", "react-native-store-review": "^0.1.5", - "react-native-svg": "9.13.3", + "react-native-svg": "9.13.6", "react-native-tcp": "^3.3.2", "react-native-text-input-mask": "waqas19921/react-native-text-input-mask", "react-native-tooltip": "marcosrdz/react-native-tooltip#master", - "react-native-touch-id": "^4.4.1", "react-native-udp": "^2.6.1", "react-native-version-number": "^0.3.6", "react-navigation": "4.0.10", diff --git a/patches/react-native-keychain+4.0.3.patch b/patches/react-native-keychain+4.0.3.patch new file mode 100644 index 00000000000..7fa4f9a8ad3 --- /dev/null +++ b/patches/react-native-keychain+4.0.3.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m +index c4ad7e5..ada736b 100644 +--- a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m ++++ b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m +@@ -270,7 +270,7 @@ - (OSStatus)deleteCredentialsForServer:(NSString *)server + { + NSError *aerr = nil; + LAContext *context = [LAContext new]; +- BOOL canBeProtected = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&aerr]; ++ BOOL canBeProtected = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&aerr]; + + if (!aerr && canBeProtected) { + if (@available(iOS 11, *)) { diff --git a/src/App.js b/src/App.js index 0ade912c184..8fd49fc9325 100644 --- a/src/App.js +++ b/src/App.js @@ -16,6 +16,7 @@ import { } from 'react-native-dotenv'; // eslint-disable-next-line import/default import RNIOS11DeviceCheck from 'react-native-ios11-devicecheck'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; // eslint-disable-next-line import/no-unresolved import { useScreens } from 'react-native-screens'; import { connect, Provider } from 'react-redux'; @@ -156,12 +157,14 @@ class App extends Component { Navigation.setTopLevelNavigator(navigatorRef); render = () => ( - - - - - - + + + + + + + + ); } diff --git a/src/components/OfflineBadge.js b/src/components/OfflineBadge.js index 22a6a036465..642e1602f1f 100644 --- a/src/components/OfflineBadge.js +++ b/src/components/OfflineBadge.js @@ -1,22 +1,16 @@ -import analytics from '@segment/analytics-react-native'; -import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; +import React from 'react'; import Animated from 'react-native-reanimated'; -import { compose, onlyUpdateForKeys } from 'recompact'; +import { bin, useSpringTransition } from 'react-native-redash'; import styled from 'styled-components'; -import { withNetInfo } from '../hoc'; +import { useInternetStatus } from '../hooks'; import { colors, padding, shadow } from '../styles'; import { interpolate } from './animations'; import { Icon } from './icons'; -import { RowWithMargins } from './layout'; +import { Centered, RowWithMargins } from './layout'; import { Text } from './text'; -const { spring, Value, View } = Animated; - -const Badge = styled(RowWithMargins).attrs({ - align: 'center', - component: View, - justify: 'center', +const StyledBadge = styled(RowWithMargins).attrs({ + component: Centered, margin: 5, self: 'center', })` @@ -31,60 +25,44 @@ const Badge = styled(RowWithMargins).attrs({ const DefaultAnimationValue = 60; -class OfflineBadge extends PureComponent { - static propTypes = { - isConnected: PropTypes.bool, - }; - - static defaultProps = { - isConnected: true, - }; - - componentDidMount = () => this.runAnimation(); - - componentDidUpdate = () => this.runAnimation(); - - animation = new Value(DefaultAnimationValue); - - runAnimation = () => { - const { isConnected } = this.props; +const OfflineBadge = () => { + const isConnected = useInternetStatus(); - return spring(this.animation, { - damping: 14, - mass: 1, - overshootClamping: false, - restDisplacementThreshold: 0.001, - restSpeedThreshold: 0.001, - stiffness: 121.6, - toValue: isConnected ? DefaultAnimationValue : 0, - }).start(({ finished }) => { - if (!finished) return null; - return isConnected - ? analytics.track('Reconnected after offline') - : analytics.track('Offline / lost connection'); - }); - }; + const animation = useSpringTransition(bin(isConnected), { + damping: 14, + mass: 1, + overshootClamping: false, + restDisplacementThreshold: 0.001, + restSpeedThreshold: 0.001, + stiffness: 121.6, + }); - render = () => ( - - - - Offline - - + + + + Offline + + +
); -} +}; -export default compose( - withNetInfo, - onlyUpdateForKeys(['isConnected']) -)(OfflineBadge); +const neverRerender = () => true; +export default React.memo(OfflineBadge, neverRerender); diff --git a/src/components/animations/ScaleInAnimation.js b/src/components/animations/ScaleInAnimation.js index 0ae38f051f9..c52ce4c1cbd 100644 --- a/src/components/animations/ScaleInAnimation.js +++ b/src/components/animations/ScaleInAnimation.js @@ -8,10 +8,10 @@ import { interpolate } from './procs'; const ScaleInAnimation = ({ range, scaleTo, style, value, ...props }) => ( - isEmpty ? ( +}) => { + const insets = useSafeArea(); + + return isEmpty ? ( ); +}; AssetList.propTypes = { fetchData: PropTypes.func.isRequired, diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js index 55054e54c1b..9adce36645a 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButton.js @@ -5,18 +5,21 @@ import { State, TapGestureHandler, } from 'react-native-gesture-handler'; -import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import Animated, { Easing } from 'react-native-reanimated'; import { withProps } from 'recompact'; import styled from 'styled-components/primitives'; +import { useBiometryType, BiometryTypes } from '../../../hooks'; import { colors, padding } from '../../../styles'; +import { haptics } from '../../../utils'; import InnerBorder from '../../InnerBorder'; import { Centered } from '../../layout'; import { ShadowStack } from '../../shadow-stack'; import { Text } from '../../text'; import HoldToAuthorizeButtonIcon from './HoldToAuthorizeButtonIcon'; -const { divide, multiply, timing, Value, View } = Animated; +const { divide, multiply, proc, timing, Value } = Animated; + +const { ACTIVE, BEGAN, END } = State; const ButtonBorderRadius = 30; const ButtonHeight = 59; @@ -38,7 +41,8 @@ const ButtonShadows = { ], }; -const progressDurationMs = 500; // @christian approves +const buttonScaleDurationMs = 150; +const longPressProgressDurationMs = 500; // @christian approves const Content = styled(Centered)` ${padding(15)}; @@ -56,24 +60,21 @@ const Title = withProps({ weight: 'semibold', })(Text); -const buildAnimation = (value, options) => { - const { duration = 150, isInteraction = false, toValue } = options; - - return timing(value, { +const animate = (value, { duration = buttonScaleDurationMs, toValue }) => + timing(value, { duration, easing: Easing.inOut(Easing.ease), - isInteraction, toValue, - useNativeDriver: true, }); -}; -const calculateReverseDuration = progess => - multiply(divide(progess, 100), progressDurationMs); +const calculateReverseDuration = proc(longPressProgress => + multiply(divide(longPressProgress, 100), longPressProgressDurationMs) +); -export default class HoldToAuthorizeButton extends PureComponent { +class HoldToAuthorizeButton extends PureComponent { static propTypes = { backgroundColor: PropTypes.string, + biometryType: PropTypes.string, children: PropTypes.any, disabled: PropTypes.bool, disabledBackgroundColor: PropTypes.string, @@ -81,7 +82,6 @@ export default class HoldToAuthorizeButton extends PureComponent { isAuthorizing: PropTypes.bool, label: PropTypes.string, onLongPress: PropTypes.func.isRequired, - onPress: PropTypes.func, shadows: PropTypes.arrayOf(PropTypes.array), style: PropTypes.object, theme: PropTypes.oneOf(['light', 'dark']), @@ -103,105 +103,92 @@ export default class HoldToAuthorizeButton extends PureComponent { } }; - scale = new Value(1); - - tapHandlerState = 1; + buttonScale = new Value(1); - animation = new Value(0); + longPressProgress = new Value(0); onFinishAuthorizing = () => { - const { disabled } = this.props; - if (!disabled) { - buildAnimation(this.animation, { - duration: calculateReverseDuration(this.animation), - isInteraction: true, + if (!this.props.disabled) { + animate(this.longPressProgress, { + duration: calculateReverseDuration(this.longPressProgress), toValue: 0, }).start(() => this.setState({ isAuthorizing: false })); } }; - onTapChange = ({ nativeEvent: { state } }) => { - const { disabled, onPress } = this.props; - - this.tapHandlerState = state; - - if (state === State.BEGAN) { - if (disabled) { - ReactNativeHapticFeedback.trigger('notificationWarning'); - buildAnimation(this.scale, { toValue: 0.99 }).start(() => { - buildAnimation(this.scale, { toValue: 1 }).start(); - }); - } else { - buildAnimation(this.scale, { toValue: 0.97 }).start(); - buildAnimation(this.animation, { - duration: progressDurationMs, - toValue: 100, - }).start(); - } - } else if (!disabled && state === State.ACTIVE) { - if (onPress) { - onPress(); - } - } else if (!disabled && state === State.END) { - buildAnimation(this.scale, { toValue: 1 }).start(); - buildAnimation(this.animation, { - duration: calculateReverseDuration(this.animation), - isInteraction: true, - toValue: 0, - }).start(); + handlePress = () => { + if (this.props.onLongPress) { + this.props.onLongPress(); } }; - onLongPressChange = ({ nativeEvent }) => { - const { disabled, onLongPress } = this.props; + onLongPressChange = ({ nativeEvent: { state } }) => { + const { disabled, enableLongPress } = this.props; - if (!disabled && nativeEvent.state === State.ACTIVE) { - ReactNativeHapticFeedback.trigger('notificationSuccess'); + if (state === ACTIVE && !disabled && enableLongPress) { + haptics.notificationSuccess(); - buildAnimation(this.scale, { - isInteraction: true, + animate(this.buttonScale, { toValue: 1, }).start(() => this.setState({ isAuthorizing: true })); - if (onLongPress) { - onLongPress(); - } + this.handlePress(); } }; - renderContent = () => { - const { children, disabled, hideBiometricIcon, label } = this.props; - - const { isAuthorizing } = this.state; + onTapChange = ({ nativeEvent: { state } }) => { + const { disabled, enableLongPress } = this.props; - if (children) { - return children; + if (disabled) { + if (state === BEGAN) { + animate(this.buttonScale, { toValue: 0.99 }).start(() => { + haptics.notificationWarning(); + animate(this.buttonScale, { toValue: 1 }).start(); + }); + } + } else { + if (state === ACTIVE) { + if (!enableLongPress) { + this.handlePress(); + } + } else if (state === BEGAN) { + animate(this.buttonScale, { toValue: 0.97 }).start(); + if (enableLongPress) { + animate(this.longPressProgress, { + duration: longPressProgressDurationMs, + toValue: 100, + }).start(); + } + } else if (state === END) { + animate(this.buttonScale, { toValue: 1 }).start(); + if (enableLongPress) { + animate(this.longPressProgress, { + duration: calculateReverseDuration(this.longPressProgress), + toValue: 0, + }).start(); + } + } } - - return ( - - {!disabled && !hideBiometricIcon && ( - - )} - {isAuthorizing ? 'Authorizing' : label} - - ); }; render() { const { backgroundColor, + biometryType, + children, disabled, disabledBackgroundColor, + enableLongPress, + hideBiometricIcon, + label, shadows, style, theme, ...props } = this.props; + const { isAuthorizing } = this.state; + let bgColor = backgroundColor; if (disabled) { bgColor = disabledBackgroundColor || ButtonDisabledBgColor[theme]; @@ -210,12 +197,13 @@ export default class HoldToAuthorizeButton extends PureComponent { return ( - - {this.renderContent()} + {children || ( + + {!disabled && !hideBiometricIcon && ( + + )} + {isAuthorizing ? 'Authorizing' : label} + + )} - + ); } } + +const HoldToAuthorizeButtonWithBiometrics = ({ label, ...props }) => { + const biometryType = useBiometryType(); + const enableLongPress = + biometryType === BiometryTypes.FaceID || + biometryType === BiometryTypes.none; + + return ( + + ); +}; + +export default React.memo(HoldToAuthorizeButtonWithBiometrics); diff --git a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js index 50521a3b95e..997e436b2e5 100644 --- a/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js +++ b/src/components/buttons/hold-to-authorize/HoldToAuthorizeButtonIcon.js @@ -9,20 +9,19 @@ import { Centered } from '../../layout'; const { cond, divide, greaterThan } = Animated; -const BiometryIconSize = 31; -const IconContainer = styled(Centered)` - ${position.size(BiometryIconSize)}; - left: 19; - margin-bottom: 2; +const Container = styled(Centered)` + ${position.size(31)}; + left: 15; position: absolute; `; -const HoldToAuthorizeButtonIcon = ({ animatedValue }) => ( - - - +const HoldToAuthorizeButtonIcon = ({ animatedValue, biometryType }) => ( + + + ( > - + ); HoldToAuthorizeButtonIcon.propTypes = { animatedValue: PropTypes.object, + biometryType: PropTypes.string, }; -export default React.memo(HoldToAuthorizeButtonIcon); +const arePropsEqual = (prev, next) => prev.biometryType === next.biometryType; +export default React.memo(HoldToAuthorizeButtonIcon, arePropsEqual); diff --git a/src/components/exchange/ConfirmExchangeButton.js b/src/components/exchange/ConfirmExchangeButton.js index 111e9d12435..b64d20b55a3 100644 --- a/src/components/exchange/ConfirmExchangeButton.js +++ b/src/components/exchange/ConfirmExchangeButton.js @@ -4,6 +4,12 @@ import { colors } from '../../styles'; import { HoldToAuthorizeButton, UnlockingSpinner } from '../buttons'; import { SlippageWarningTheshold } from './SlippageWarning'; +const ConfirmExchangeButtonShadows = [ + [0, 3, 5, colors.black, 0.2], + [0, 6, 10, colors.black, 0.14], + [0, 1, 18, colors.black, 0.12], +]; + const ConfirmExchangeButton = ({ disabled, inputCurrencyName, @@ -30,27 +36,23 @@ const ConfirmExchangeButton = ({ return ( - {isUnlockingAsset ? ( - - ) : ( - undefined - )} + {isUnlockingAsset && } ); }; @@ -68,4 +70,4 @@ ConfirmExchangeButton.propTypes = { timeRemaining: PropTypes.string, }; -export default ConfirmExchangeButton; +export default React.memo(ConfirmExchangeButton); diff --git a/src/components/gas/GasSpeedLabelPagerItem.js b/src/components/gas/GasSpeedLabelPagerItem.js index 5edd195bd76..d02cf7cfbc1 100644 --- a/src/components/gas/GasSpeedLabelPagerItem.js +++ b/src/components/gas/GasSpeedLabelPagerItem.js @@ -6,7 +6,7 @@ import Animated, { Transitioning, Transition, } from 'react-native-reanimated'; -import { useToggle } from 'react-native-redash'; +import { useTimingTransition } from 'react-native-redash'; import { withProps } from 'recompact'; import { gasUtils } from '../../utils'; import { interpolate } from '../animations'; @@ -51,7 +51,7 @@ const GasSpeedLabelPagerItem = ({ label, selected, shouldAnimate }) => { const isFirst = index === 0; const isLast = index === gasUtils.GasSpeedOrder.length - 1; - const transitionVal = useToggle( + const transitionVal = useTimingTransition( !selected, duration + (isFirst ? 50 : 0), Easing.out(Easing.ease) diff --git a/src/components/icons/BiometryIcon.js b/src/components/icons/BiometryIcon.js index 4b292f7719a..7950d91770d 100644 --- a/src/components/icons/BiometryIcon.js +++ b/src/components/icons/BiometryIcon.js @@ -1,61 +1,41 @@ import PropTypes from 'prop-types'; import React from 'react'; -import TouchID from 'react-native-touch-id'; -import stylePropType from 'react-style-proptype'; -import { - compose, - lifecycle, - omitProps, - onlyUpdateForKeys, - withHandlers, - withProps, - withState, -} from 'recompact'; import { position } from '../../styles'; import { Centered } from '../layout'; import Icon from './Icon'; -const DefaultBiometryType = 'FaceID'; +const BiometryTypeStyles = { + faceid: { + ...position.sizeAsObject(27), + marginBottom: 2, + marginLeft: 4, + }, + passcode: { + height: 25, + marginBottom: 4, + marginLeft: 4, + width: 18, + }, + touchid: { + ...position.sizeAsObject(31), + marginBottom: 1, + }, +}; -const BiometryIcon = ({ isFaceID, size, style, ...props }) => ( - - - -); +const BiometryIcon = ({ biometryType, ...props }) => { + if (!biometryType || biometryType === 'none') return null; + const type = biometryType.toLowerCase(); -BiometryIcon.propTypes = { - isFaceID: PropTypes.bool, - size: PropTypes.number, - style: stylePropType, + return ( + + + + ); }; -BiometryIcon.defaultProps = { - size: 34, +BiometryIcon.propTypes = { + biometryType: PropTypes.string, }; -export default compose( - withState('biometryType', 'setBiometryType', DefaultBiometryType), - withHandlers({ - setBiometryType: ({ setBiometryType }) => biometryType => { - setBiometryType(biometryType || DefaultBiometryType); - }, - }), - lifecycle({ - componentDidMount() { - TouchID.isSupported().then(this.props.setBiometryType); - }, - }), - withProps(({ biometryType }) => ({ - isFaceID: biometryType === DefaultBiometryType, - })), - onlyUpdateForKeys(['biometryType', 'size']), - omitProps('biometryType', 'setBiometryType') -)(BiometryIcon); +const arePropsEqual = (prev, next) => prev.biometryType === next.biometryType; +export default React.memo(BiometryIcon, arePropsEqual); diff --git a/src/components/icons/Icon.js b/src/components/icons/Icon.js index 8015745bd1f..cd93193d9d7 100644 --- a/src/components/icons/Icon.js +++ b/src/components/icons/Icon.js @@ -25,6 +25,7 @@ import HandleIcon from './svg/HandleIcon'; import InboxIcon from './svg/InboxIcon'; import LockIcon from './svg/LockIcon'; import OfflineIcon from './svg/OfflineIcon'; +import PasscodeIcon from './svg/PasscodeIcon'; import ProgressIcon from './svg/ProgressIcon'; import SearchIcon from './svg/SearchIcon'; import SendIcon from './svg/SendIcon'; @@ -66,6 +67,7 @@ Icon.IconTypes = { inbox: InboxIcon, lock: LockIcon, offline: OfflineIcon, + passcode: PasscodeIcon, progress: ProgressIcon, search: SearchIcon, send: SendIcon, diff --git a/src/components/icons/svg/FaceIdIcon.js b/src/components/icons/svg/FaceIdIcon.js index bbab6d3c2a5..e8856c266b5 100644 --- a/src/components/icons/svg/FaceIdIcon.js +++ b/src/components/icons/svg/FaceIdIcon.js @@ -4,9 +4,10 @@ import Svg, { Path } from 'svgs'; import { colors } from '../../../styles'; const FaceIdIcon = ({ color, ...props }) => ( - + diff --git a/src/components/icons/svg/PasscodeIcon.js b/src/components/icons/svg/PasscodeIcon.js new file mode 100644 index 00000000000..879f179b4df --- /dev/null +++ b/src/components/icons/svg/PasscodeIcon.js @@ -0,0 +1,37 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import Svg, { Defs, G, LinearGradient, Path, Stop } from 'svgs'; +import { colors } from '../../../styles'; + +const PasscodeIcon = ({ color, ...props }) => ( + + + + + + + + + + + + + + +); + +PasscodeIcon.propTypes = { + color: PropTypes.string, +}; + +PasscodeIcon.defaultProps = { + color: colors.white, +}; + +export default PasscodeIcon; diff --git a/src/components/qrcode-scanner/QRCodeScanner.js b/src/components/qrcode-scanner/QRCodeScanner.js index f44454deeb9..bd126c2dbb0 100644 --- a/src/components/qrcode-scanner/QRCodeScanner.js +++ b/src/components/qrcode-scanner/QRCodeScanner.js @@ -1,84 +1,115 @@ import PropTypes from 'prop-types'; -import React, { PureComponent } from 'react'; -import DeviceInfo from 'react-native-device-info'; +import React, { useEffect, useRef, useState } from 'react'; import FastImage from 'react-native-fast-image'; -import stylePropType from 'react-style-proptype'; -import styled from 'styled-components/primitives'; +import { Transition, Transitioning } from 'react-native-reanimated'; import SimulatorFakeCameraImageSource from '../../assets/simulator-fake-camera-image.jpg'; +import { usePrevious } from '../../hooks'; import { colors, position } from '../../styles'; +import { isNewValueForObjectPaths } from '../../utils'; import { Centered } from '../layout'; import { ErrorText } from '../text'; import QRCodeScannerCamera from './QRCodeScannerCamera'; import QRCodeScannerCrosshair from './QRCodeScannerCrosshair'; -const Container = styled(Centered).attrs({ direction: 'column' })` - ${position.cover}; - background-color: ${colors.black}; -`; +const transition = ( + +); -export default class QRCodeScanner extends PureComponent { - static propTypes = { - contentStyles: stylePropType, - enableCamera: PropTypes.bool, - enableScanning: PropTypes.bool, - isCameraAuthorized: PropTypes.bool, - onSuccess: PropTypes.func, - showCrosshairText: PropTypes.bool, - }; +const QRCodeScanner = ({ + contentPositionBottom, + contentPositionTop, + enableCamera, + enableScanning, + isCameraAuthorized, + isEmulator, + onSuccess, + showCrosshairText, +}) => { + const ref = useRef(); + const [error, setError] = useState(null); + const [isInitialized, setInitialized] = useState(false); - state = { - error: null, - isInitialized: false, - }; - - handleCameraReady = () => this.setState({ isInitialized: true }); - - handleMountError = () => this.setState({ error: 'mounting' }); - - renderCamera = () => { - if (DeviceInfo.isEmulator()) { - return ( - - ); + const prevContentPositionBottom = usePrevious(contentPositionBottom); + useEffect(() => { + if (ref.current && contentPositionBottom !== prevContentPositionBottom) { + ref.current.animateNextTransition(); } + }, [contentPositionBottom, prevContentPositionBottom]); - return this.props.enableCamera ? ( + let cameraRenderer = null; + if (isEmulator) { + cameraRenderer = ( + + ); + } else if (enableCamera) { + cameraRenderer = ( setInitialized(true)} + onMountError={() => setError('mounting')} + onSuccess={onSuccess} /> - ) : null; - }; - - render = () => { - const { contentStyles, isCameraAuthorized, showCrosshairText } = this.props; - const { error, isInitialized } = this.state; + ); + } - const showErrorMessage = error && !isInitialized; - const showCrosshair = !error && !showErrorMessage; + const showErrorMessage = error && !isInitialized; + const showCrosshair = !error && !showErrorMessage; - return ( - - {this.renderCamera()} - {isCameraAuthorized && ( - + return ( + + {cameraRenderer} + {isCameraAuthorized && ( + + {showErrorMessage && ( )} {showCrosshair && ( )} - )} - - ); - }; -} + + )} + + ); +}; + +QRCodeScanner.propTypes = { + contentPositionBottom: PropTypes.node, + contentPositionTop: PropTypes.node, + enableCamera: PropTypes.bool, + enableScanning: PropTypes.bool, + isCameraAuthorized: PropTypes.bool, + isEmulator: PropTypes.bool, + onSuccess: PropTypes.func, + showCrosshairText: PropTypes.bool, +}; + +const arePropsEqual = (prev, next) => + !isNewValueForObjectPaths(prev, next, [ + 'contentPositionBottom', + 'enableCamera', + 'enableScanning', + 'isCameraAuthorized', + 'showCrosshairText', + ]); + +export default React.memo(QRCodeScanner, arePropsEqual); diff --git a/src/components/send/SendButton.js b/src/components/send/SendButton.js index f35a6318167..92cd8e40adb 100644 --- a/src/components/send/SendButton.js +++ b/src/components/send/SendButton.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { pure } from 'recompose'; import { HoldToAuthorizeButton } from '../buttons'; const SendButton = ({ @@ -46,4 +45,4 @@ SendButton.propTypes = { onLongPress: PropTypes.func, }; -export default pure(SendButton); +export default React.memo(SendButton); diff --git a/src/components/settings-menu/SettingsSection.js b/src/components/settings-menu/SettingsSection.js index a53b561f878..ef1a0927265 100644 --- a/src/components/settings-menu/SettingsSection.js +++ b/src/components/settings-menu/SettingsSection.js @@ -2,7 +2,7 @@ import { upperFirst } from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { InteractionManager, Linking, ScrollView } from 'react-native'; -import DeviceInfo from 'react-native-device-info'; +import { isEmulatorSync } from 'react-native-device-info'; import FastImage from 'react-native-fast-image'; import * as StoreReview from 'react-native-store-review'; import { compose, onlyUpdateForKeys, withHandlers } from 'recompact'; @@ -178,7 +178,7 @@ export default compose( const shouldDeeplinkToAppStore = count >= maxRequestCount || !StoreReview.isAvailable; - if (shouldDeeplinkToAppStore && !DeviceInfo.isEmulator()) { + if (shouldDeeplinkToAppStore && !isEmulatorSync()) { Linking.openURL(SettingsExternalURLs.review); } else { onCloseModal(); diff --git a/src/handlers/localstorage/uniswap.js b/src/handlers/localstorage/uniswap.js index 539ad21d435..b79fd9d284f 100644 --- a/src/handlers/localstorage/uniswap.js +++ b/src/handlers/localstorage/uniswap.js @@ -1,4 +1,5 @@ import { forEach } from 'lodash'; +import { DefaultUniswapFavorites } from '../../references'; import { getAccountLocal, getGlobal, @@ -22,7 +23,8 @@ const uniswapAccountLocalKeys = [ PENDING_APPROVALS, ]; -export const getUniswapFavorites = () => getGlobal(UNISWAP_FAVORITES, []); +export const getUniswapFavorites = () => + getGlobal(UNISWAP_FAVORITES, DefaultUniswapFavorites); export const saveUniswapFavorites = favorites => saveGlobal(UNISWAP_FAVORITES, favorites); diff --git a/src/hoc/index.js b/src/hoc/index.js index d6ce99cfba5..1235ba1c52c 100644 --- a/src/hoc/index.js +++ b/src/hoc/index.js @@ -17,7 +17,6 @@ export { default as withIsWalletEmpty } from './withIsWalletEmpty'; export { default as withIsWalletEthZero } from './withIsWalletEthZero'; export { default as withKeyboardHeight } from './withKeyboardHeight'; export { default as withMessageSigningScreen } from './withMessageSigningScreen'; -export { default as withNetInfo } from './withNetInfo'; export { default as withNeverRerender } from './withNeverRerender'; export { default as withOpenFamilyTabs } from './withOpenFamilyTabs'; export { default as withOpenInvestmentCards } from './withOpenInvestmentCards'; diff --git a/src/hoc/withNetInfo.js b/src/hoc/withNetInfo.js deleted file mode 100644 index 1ab24409561..00000000000 --- a/src/hoc/withNetInfo.js +++ /dev/null @@ -1,23 +0,0 @@ -import NetInfo from '@react-native-community/netinfo'; -import { compose, lifecycle, withState } from 'recompact'; - -const withNetInfo = ComponentToWrap => - compose( - withState('isConnected', 'setIsConnected', true), - lifecycle({ - componentDidMount() { - NetInfo.isConnected.addEventListener( - 'connectionChange', - this.props.setIsConnected - ); - }, - componentWillUnmount() { - NetInfo.isConnected.removeEventListener( - 'connectionChange', - this.props.setIsConnected - ); - }, - }) - )(ComponentToWrap); - -export default withNetInfo; diff --git a/src/hoc/withUniswapAssets.js b/src/hoc/withUniswapAssets.js index 298f33e31ce..ce4b9a56c92 100644 --- a/src/hoc/withUniswapAssets.js +++ b/src/hoc/withUniswapAssets.js @@ -33,9 +33,7 @@ export const includeExchangeAddress = uniswapPairs => asset => ({ ), }); -const lowerAssetName = asset => toLower(asset.name); - -const includeFavorite = asset => ({ +const appendFavoriteKey = asset => ({ ...asset, favorite: true, }); @@ -52,14 +50,17 @@ const withAssetsAvailableOnUniswap = (allAssets, uniswapPairs) => { return { assetsAvailableOnUniswap }; }; -const withSortedUniswapAssets = (unsortedUniswapAssets, favorites) => { - const sortedAssets = sortBy(values(unsortedUniswapAssets), lowerAssetName); - const [favoriteAssets, remainingAssets] = partition(sortedAssets, asset => - includes(favorites, asset.address) +const withSortedUniswapAssets = (assets, favorites) => { + const sorted = sortBy(values(assets), ({ name }) => toLower(name)); + const [favorited, notFavorited] = partition(sorted, ({ address }) => + includes(map(favorites, toLower), toLower(address)) ); - const labeledFavorites = map(favoriteAssets, includeFavorite); + return { - sortedUniswapAssets: concat(labeledFavorites, remainingAssets), + sortedUniswapAssets: concat( + map(favorited, appendFavoriteKey), + notFavorited + ), }; }; diff --git a/src/hooks/index.js b/src/hooks/index.js new file mode 100644 index 00000000000..3264f26a0c8 --- /dev/null +++ b/src/hooks/index.js @@ -0,0 +1,5 @@ +export { default as useAppState } from './useAppState'; +export { default as useClipboard } from './useClipboard'; +export { default as useInternetStatus } from './useInternetStatus'; +export { default as usePrevious } from './usePrevious'; +export { default as useBiometryType, BiometryTypes } from './useBiometryType'; diff --git a/src/hooks/useAppState.js b/src/hooks/useAppState.js new file mode 100644 index 00000000000..cbcb4685662 --- /dev/null +++ b/src/hooks/useAppState.js @@ -0,0 +1,30 @@ +import { useEffect, useState } from 'react'; +import { AppState } from 'react-native'; +import usePrevious from './usePrevious'; + +const AppStateTypes = { + active: 'active', + background: 'background', + inactive: 'inactive', +}; + +export default function useAppState() { + const [appState, setAppState] = useState(AppState.currentState); + const prevAppState = usePrevious(appState); + + function onChange(newState) { + setAppState(newState); + } + + useEffect(() => { + AppState.addEventListener('change', onChange); + return () => AppState.removeEventListener('change', onChange); + }, []); + + return { + appState, + justBecameActive: + appState === AppStateTypes.active && + prevAppState !== AppStateTypes.active, + }; +} diff --git a/src/hooks/useBiometryType.js b/src/hooks/useBiometryType.js new file mode 100644 index 00000000000..73e6a317f5b --- /dev/null +++ b/src/hooks/useBiometryType.js @@ -0,0 +1,50 @@ +import { isNil } from 'lodash'; +import { useEffect, useState } from 'react'; +import { isPinOrFingerprintSet } from 'react-native-device-info'; +import * as Keychain from 'react-native-keychain'; +import useAppState from './useAppState'; +import usePrevious from './usePrevious'; + +export const BiometryTypes = { + FaceID: 'FaceID', + none: 'none', + passcode: 'passcode', + TouchID: 'TouchID', +}; + +export default function useBiometryType() { + const { justBecameActive } = useAppState(); + const [biometryType, setBiometryType] = useState(null); + const prevBiometricType = usePrevious(biometryType); + + useEffect(() => { + let mounted = true; + + const getSupportedBiometryType = async () => { + let type = await Keychain.getSupportedBiometryType(); + + if (isNil(type)) { + // 💡️ When `getSupportedBiometryType` returns `null` it can mean either: + // A) the user has no device passcode/biometrics at all + // B) the user has gone into Settings and disabled biometrics specifically for Rainbow + type = await isPinOrFingerprintSet().then(isPinOrFingerprintSet => + isPinOrFingerprintSet ? BiometryTypes.passcode : BiometryTypes.none + ); + } + + if (mounted && type !== prevBiometricType) { + setBiometryType(type); + } + }; + + if (!biometryType || justBecameActive) { + getSupportedBiometryType(); + } + + return () => { + mounted = false; + }; + }, [biometryType, justBecameActive, prevBiometricType]); + + return biometryType; +} diff --git a/src/hooks/useClipboard.js b/src/hooks/useClipboard.js new file mode 100644 index 00000000000..bcc749245d5 --- /dev/null +++ b/src/hooks/useClipboard.js @@ -0,0 +1,26 @@ +import { useCallback, useEffect, useState } from 'react'; +import { Clipboard } from 'react-native'; +import useAppState from './useAppState'; + +export default function useClipboard() { + const { justBecameActive } = useAppState(); + const [data, updateClipboardData] = useState(''); + + async function updateClipboard() { + const content = await Clipboard.getString(); + updateClipboardData(content); + } + + useEffect(() => { + if (justBecameActive) { + updateClipboard(); + } + }, [justBecameActive]); + + const setString = useCallback(content => { + Clipboard.setString(content); + updateClipboardData(content); + }, []); + + return [data, setString]; +} diff --git a/src/hooks/useInternetStatus.js b/src/hooks/useInternetStatus.js new file mode 100644 index 00000000000..7520325cbe1 --- /dev/null +++ b/src/hooks/useInternetStatus.js @@ -0,0 +1,27 @@ +import NetInfo from '@react-native-community/netinfo'; +import analytics from '@segment/analytics-react-native'; +import { isNil } from 'lodash'; +import { useEffect, useState } from 'react'; + +export default function useInternetStatus() { + const [isInternetReachable, setIsInternetReachable] = useState(true); + + function onChange(newState) { + const { isInternetReachable: newIsInternetReachable } = newState; + if (!isNil(newIsInternetReachable)) { + setIsInternetReachable(newIsInternetReachable); + if (newIsInternetReachable) { + analytics.track('Reconnected after offline'); + } else { + analytics.track('Offline / lost connection'); + } + } + } + + useEffect(() => { + const unsubscribe = NetInfo.addEventListener(onChange); + return unsubscribe; + }, []); + + return isInternetReachable; +} diff --git a/src/hooks/usePrevious.js b/src/hooks/usePrevious.js new file mode 100644 index 00000000000..ed46581cb01 --- /dev/null +++ b/src/hooks/usePrevious.js @@ -0,0 +1,11 @@ +import { useEffect, useRef } from 'react'; + +export default function usePrevious(value) { + const ref = useRef(); + + useEffect(() => { + ref.current = value; + }, [value]); + + return ref.current; +} diff --git a/src/redux/uniswap.js b/src/redux/uniswap.js index b9f43ebc4db..00f5b61fc5e 100644 --- a/src/redux/uniswap.js +++ b/src/redux/uniswap.js @@ -36,7 +36,10 @@ import { getUniswapPairs, } from '../handlers/uniswap'; import { includeExchangeAddress } from '../hoc/withUniswapAssets'; -import { cleanUniswapAssetsFallback } from '../references'; +import { + cleanUniswapAssetsFallback, + DefaultUniswapFavorites, +} from '../references'; import { resubscribeAssets } from './explorer'; // -- Constants ------------------------------------------------------------- // @@ -218,9 +221,11 @@ export const uniswapUpdateFavorites = (assetAddress, add = true) => ( ) => { const address = toLower(assetAddress); const { favorites } = getState().uniswap; + const normalizedFavorites = map(favorites, toLower); + const updatedFavorites = add - ? uniq(concat(favorites, address)) - : without(favorites, address); + ? uniq(concat(normalizedFavorites, address)) + : without(normalizedFavorites, address); dispatch({ payload: updatedFavorites, type: UNISWAP_UPDATE_FAVORITES, @@ -333,7 +338,7 @@ export const uniswapUpdateState = () => (dispatch, getState) => // -- Reducer --------------------------------------------------------------- // export const INITIAL_UNISWAP_STATE = { allowances: {}, - favorites: [], + favorites: DefaultUniswapFavorites, fetchingUniswap: false, inputCurrency: null, inputReserve: null, diff --git a/src/references/index.js b/src/references/index.js index c72fd596d22..4206cb7ce04 100644 --- a/src/references/index.js +++ b/src/references/index.js @@ -2,6 +2,15 @@ import { mapKeys, mapValues, toLower } from 'lodash'; import tokenOverridesFallback from './token-overrides.json'; import uniswapAssetsFallback from './uniswap-pairs.json'; +export const DefaultUniswapFavorites = [ + // Ethereum + 'eth', + // DAI + '0x6b175474e89094c44da98b954eedeac495271d0f', + // SOCKS + '0x23B608675a2B2fB1890d3ABBd85c5775c51691d5', +]; + export const loweredTokenOverridesFallback = mapKeys( tokenOverridesFallback, (_, address) => toLower(address) diff --git a/src/screens/ImportSeedPhraseSheet.js b/src/screens/ImportSeedPhraseSheet.js index c87d2dd5c48..8fb508796a6 100644 --- a/src/screens/ImportSeedPhraseSheet.js +++ b/src/screens/ImportSeedPhraseSheet.js @@ -2,7 +2,6 @@ import analytics from '@segment/analytics-react-native'; import PropTypes from 'prop-types'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { KeyboardAvoidingView } from 'react-native'; -import { useClipboard } from 'react-native-hooks'; import { BorderlessButton } from 'react-native-gesture-handler'; import { getStatusBarHeight } from 'react-native-iphone-x-helper'; import { useNavigation } from 'react-navigation-hooks'; @@ -13,6 +12,7 @@ import { MultiLineInput } from '../components/inputs'; import { Centered, Column, Row, RowWithMargins } from '../components/layout'; import { LoadingOverlay } from '../components/modal'; import { Text } from '../components/text'; +import { useClipboard } from '../hooks'; import { sheetVerticalOffset } from '../navigation/transitions/effects'; import { borders, colors, padding, shadow } from '../styles'; import { isValidSeed as validateSeed } from '../helpers/validators'; diff --git a/src/screens/QRScannerScreen.js b/src/screens/QRScannerScreen.js index 0661191906f..fe89d8ad067 100644 --- a/src/screens/QRScannerScreen.js +++ b/src/screens/QRScannerScreen.js @@ -1,8 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import DeviceInfo from 'react-native-device-info'; -import { onlyUpdateForKeys } from 'recompact'; -import styled from 'styled-components/primitives'; +import { useIsEmulator } from 'react-native-device-info'; +import { useSafeArea } from 'react-native-safe-area-context'; import { BubbleSheet } from '../components/bubble-sheet'; import { Button } from '../components/buttons'; import { BackButton, Header } from '../components/header'; @@ -13,20 +12,7 @@ import { WalletConnectList, } from '../components/walletconnect-list'; import { colors, position } from '../styles'; -import { safeAreaInsetValues } from '../utils'; - -const Container = styled(Centered)` - ${position.size('100%')}; - background-color: ${colors.black}; - overflow: hidden; -`; - -const QRScannerScreenHeader = styled(Header).attrs({ - justify: 'space-between', -})` - position: absolute; - top: 0; -`; +import { isNewValueForObjectPaths } from '../utils'; const QRScannerScreen = ({ enableScanning, @@ -40,52 +26,58 @@ const QRScannerScreen = ({ walletConnectorsByDappName, walletConnectorsCount, ...props -}) => ( - - - - - {DeviceInfo.isEmulator() && ( - - )} - - { + const { result: isEmulator } = useIsEmulator(); + const insets = useSafeArea(); + + return ( + - {walletConnectorsCount ? ( - - ) : ( - - )} - - -); + +
+ + {isEmulator && ( + + )} +
+ + {walletConnectorsCount ? ( + + ) : ( + + )} + + + ); +}; QRScannerScreen.propTypes = { enableScanning: PropTypes.bool, @@ -96,20 +88,17 @@ QRScannerScreen.propTypes = { onScanSuccess: PropTypes.func, onSheetLayout: PropTypes.func, sheetHeight: PropTypes.number, - showSheet: PropTypes.bool, - showWalletConnectSheet: PropTypes.bool, walletConnectorsByDappName: PropTypes.arrayOf(PropTypes.object), walletConnectorsCount: PropTypes.number, }; -QRScannerScreen.defaultProps = { - showWalletConnectSheet: true, -}; +const arePropsEqual = (prev, next) => + !isNewValueForObjectPaths(prev, next, [ + 'enableScanning', + 'isCameraAuthorized', + 'isFocused', + 'sheetHeight', + 'walletConnectorsCount', + ]); -export default onlyUpdateForKeys([ - 'enableScanning', - 'isCameraAuthorized', - 'isFocused', - 'sheetHeight', - 'walletConnectorsCount', -])(QRScannerScreen); +export default React.memo(QRScannerScreen, arePropsEqual); diff --git a/src/screens/TransactionConfirmationScreen.js b/src/screens/TransactionConfirmationScreen.js index 49328f65bdb..f77cb8d96ec 100644 --- a/src/screens/TransactionConfirmationScreen.js +++ b/src/screens/TransactionConfirmationScreen.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; import lang from 'i18n-js'; import { Animated } from 'react-native'; -import TouchID from 'react-native-touch-id'; import styled from 'styled-components'; import { Button, HoldToAuthorizeButton } from '../components/buttons'; import { RequestVendorLogoIcon } from '../components/coin-icon'; @@ -54,21 +53,10 @@ export default class TransactionConfirmationScreen extends PureComponent { }; state = { - biometryType: null, isAuthorizing: false, sendLongPressProgress: new Animated.Value(0), }; - componentDidMount() { - TouchID.isSupported() - .then(biometryType => { - this.setState({ biometryType }); - }) - .catch(() => { - this.setState({ biometryType: 'FaceID' }); - }); - } - componentWillUnmount() { this.state.sendLongPressProgress.stopAnimation(); } @@ -109,15 +97,19 @@ export default class TransactionConfirmationScreen extends PureComponent { } }; - renderSendButton = () => ( - - ); + renderSendButton = () => { + const { method } = this.props; + const { isAuthorizing } = this.state; + const label = `Hold to ${method === SEND_TRANSACTION ? 'Send' : 'Sign'}`; + + return ( + + ); + }; requestHeader = () => { const { method } = this.props; diff --git a/src/utils/deviceUtils.js b/src/utils/deviceUtils.js index e9abf291a0c..c79d9a9197c 100644 --- a/src/utils/deviceUtils.js +++ b/src/utils/deviceUtils.js @@ -1,7 +1,6 @@ -import { pick } from 'lodash'; import { Dimensions } from 'react-native'; -const { height, width } = pick(Dimensions.get('window'), ['height', 'width']); +const { height, width } = Dimensions.get('window'); const deviceUtils = {}; diff --git a/src/utils/haptics.js b/src/utils/haptics.js new file mode 100644 index 00000000000..50bcdda95da --- /dev/null +++ b/src/utils/haptics.js @@ -0,0 +1,23 @@ +import { keys, map } from 'lodash'; +import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; +import reduceArrayToObject from './reduceArrayToObject'; + +export const HapticFeedbackTypes = { + impactHeavy: 'impactHeavy', + impactLight: 'impactLight', + impactMedium: 'impactMedium', + notificationError: 'notificationError', + notificationSuccess: 'notificationSuccess', + notificationWarning: 'notificationWarning', + selection: 'selection', +}; + +const hapticToTrigger = haptic => ({ + [haptic]: () => ReactNativeHapticFeedback.trigger(haptic), +}); + +const haptics = reduceArrayToObject( + map(keys(HapticFeedbackTypes), hapticToTrigger) +); + +export default haptics; diff --git a/src/utils/index.js b/src/utils/index.js index 1eac30d1a8b..a89fef6f8df 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -6,6 +6,7 @@ export { default as dimensionsPropType } from './dimensionsPropType'; export { default as directionPropType } from './directionPropType'; export { default as ethereumUtils } from './ethereumUtils'; export { default as gasUtils } from './gas'; +export { default as haptics } from './haptics'; export { getFirstGrapheme, initials, removeLeadingZeros } from './formatters'; export { default as isLowerCaseMatch } from './isLowerCaseMatch'; export { default as isNewValueForObjectPaths } from './isNewValueForObjectPaths'; diff --git a/yarn.lock b/yarn.lock index db673a62952..968de00b380 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,14 +10,14 @@ "@babel/highlight" "^7.0.0" "@babel/core@>=7.2.2", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.2": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.5.tgz#ae1323cd035b5160293307f50647e83f8ba62f7e" - integrity sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" + integrity sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.4" + "@babel/generator" "^7.7.7" "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.5" + "@babel/parser" "^7.7.7" "@babel/template" "^7.7.4" "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" @@ -29,10 +29,10 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.4.tgz#db651e2840ca9aa66f327dcec1dc5f5fa9611369" - integrity sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg== +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.4", "@babel/generator@^7.7.7": + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" + integrity sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ== dependencies: "@babel/types" "^7.7.4" jsesc "^2.5.1" @@ -240,10 +240,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.5": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.5.tgz#cbf45321619ac12d83363fcf9c94bb67fa646d71" - integrity sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" + integrity sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw== "@babel/plugin-external-helpers@^7.0.0": version "7.7.4" @@ -277,9 +277,9 @@ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.7.4" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz#cc57849894a5c774214178c8ab64f6334ec8af71" - integrity sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.7.tgz#9f27075004ab99be08c5c1bd653a2985813cb370" + integrity sha512-3qp9I8lelgzNedI3hrhkvhaEYree6+WHnyA/q4Dza9z7iEIs1eyhWyJnetk3jJ69RT0AT4G0UhEGwyGFJ7GUuQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.7.4" @@ -500,9 +500,9 @@ "@babel/helper-replace-supers" "^7.7.4" "@babel/plugin-transform-parameters@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz#da4555c97f39b51ac089d31c7380f03bca4075ce" - integrity sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.7.tgz#7a884b2460164dc5f194f668332736584c760007" + integrity sha512-OhGSrf9ZBrr1fw84oFXj5hgi8Nmg+E2w5L7NhnG0lPvpDtqd7dbyilM2/vR8CKbJ907RyxPh2kj6sBCSSfI9Ew== dependencies: "@babel/helper-call-delegate" "^7.7.4" "@babel/helper-get-function-arity" "^7.7.4" @@ -531,9 +531,9 @@ "@babel/plugin-syntax-jsx" "^7.7.4" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz#d91205717fae4e2f84d020cd3057ec02a10f11da" - integrity sha512-LixU4BS95ZTEAZdPaIuyg/k8FiiqN9laQ0dMHB4MlpydHY53uQdWCUrwjLr5o6ilS6fAgZey4Q14XBjl5tL6xw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.7.tgz#5cbaa7445b4a09f774029f3cc7bb448ff3122a5d" + integrity sha512-SlPjWPbva2+7/ZJbGcoqjl4LsQaLpKEzxW9hcxU7675s24JmdotJOSJ4cgAbV82W3FcZpHIGmRZIlUL8ayMvjw== dependencies: "@babel/helper-builder-react-jsx" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" @@ -604,9 +604,9 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/register@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.4.tgz#45a4956471a9df3b012b747f5781cc084ee8f128" - integrity sha512-/fmONZqL6ZMl9KJUYajetCrID6m0xmL4odX7v+Xvoxcv0DdbP/oO0TWIeLUCHqczQ6L6njDMqmqHFy2cp3FFsA== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.7.7.tgz#46910c4d1926b9c6096421b23d1f9e159c1dcee1" + integrity sha512-S2mv9a5dc2pcpg/ConlKZx/6wXaEwHeqfo7x/QbXsdCAZm+WJC1ekVvL1TVxNsedTs5y/gG63MhJTEsmwmjtiA== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.13" @@ -615,9 +615,9 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": - version "7.7.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" - integrity sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw== + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" + integrity sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA== dependencies: regenerator-runtime "^0.13.2" @@ -670,26 +670,26 @@ minimist "^1.2.0" "@emotion/is-prop-valid@^0.8.1": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz#2dda0791f0eafa12b7a0a5b39858405cc7bde983" - integrity sha512-6ZODuZSFofbxSbcxwsFz+6ioPjb0ISJRRPLZ+WIbjcU2IMU0Io+RGQjjaTgOvNQl007KICBm7zXQaYQEC1r6Bg== + version "0.8.6" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.6.tgz#4757646f0a58e9dec614c47c838e7147d88c263c" + integrity sha512-mnZMho3Sq8BfzkYYRVc8ilQTnc8U02Ytp6J1AwM6taQStZ3AhsEJBX2LzhA/LJirNCwM2VtHL3VFIZ+sNJUgUQ== dependencies: - "@emotion/memoize" "0.7.3" + "@emotion/memoize" "0.7.4" -"@emotion/memoize@0.7.3": - version "0.7.3" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78" - integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow== +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== "@emotion/stylis@^0.8.3": - version "0.8.4" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.4.tgz#6c51afdf1dd0d73666ba09d2eb6c25c220d6fe4c" - integrity sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ== + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== "@emotion/unitless@^0.7.0": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.4.tgz#a87b4b04e5ae14a88d48ebef15015f6b7d1f5677" - integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== "@ethersproject/address@^5.0.0-beta.125": version "5.0.0-beta.133" @@ -983,7 +983,7 @@ resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.6.2.tgz#a19ca7149c4dfe8216f2330e6b1ebfe2d075ef92" integrity sha512-EJGsbrHubK1mGxPjWB74AaHAd5m9I+Gg2RRPZzMK6org7QOU9WOBnIMFqoeVto3hKOaEPlk8NV74H6G34/2pZQ== -"@react-native-community/blur@^3.3.1": +"@react-native-community/blur@^3.4.1": version "3.4.1" resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-3.4.1.tgz#dec04c7d60dd6a4fa7e3af3506feefec804728d0" integrity sha512-XhbS230J7BGuoEamjPFZ5jUWDOW16y+vD0Soyq9Iv1qL8R47esGl54bnfUSMH10WhNXrQzvPxkMzap+ONHpE2w== @@ -1084,10 +1084,10 @@ resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.5.tgz#25421be6cd943a4b1660b62cfbcd45be8891462c" integrity sha512-Lj1DzfCmW0f4HnmHtEuX8Yy2f7cnUA8r5KGGUuDDGtQt1so6QJkKeUmsnLo2zYDtsF8due6hvIL06Vdo5xxuLQ== -"@react-native-community/netinfo@^4.6.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-4.7.0.tgz#7482d36836cac69d0a0ae25581f65bc472639930" - integrity sha512-a/sDB+AsLEUNmhAUlAaTYeXKyQdFGBUfatqKkX5jluBo2CB3OAuTHfm7rSjcaLB9EmG5iSq3fOTpync2E7EYTA== +"@react-native-community/netinfo@^5.0.0": + version "5.3.2" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.3.2.tgz#7b6ee417c2a905663e10de176c00eeab09bdd14c" + integrity sha512-npNcLAz6iWzwRNh+0tSFMlR+xkpSz9NWzX+5AxW40KE6qEZGWdE3dtGBKsezMdWD2Fh+6Je6P6hgUEF8xuZrbA== "@react-native-community/push-notification-ios@^1.0.3": version "1.0.3" @@ -1207,9 +1207,9 @@ tslib "^1.9.3" "@sentry/react-native@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.0.tgz#244ec5f07a4eb07d3d56e7b50fe00f479a733eb5" - integrity sha512-GPY+1dBLgx5I/eOuj+dyMO8DGSoPTatB13WpYbFouGNbx3Ni4SD6EwpU+VdJtqtqVQ0OUVMNm+w/lX4+ggmU5g== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-1.2.1.tgz#a015ed280ffa8afde3f775b91d173ad7c884e169" + integrity sha512-JE2B/pMvd7+3TFdzs03+DOdrALAHd8bAphJ8tk+nWjX7oQVJNgVn/IvnJfKxasHHBXQ2z+42Xy9n2Fqam/Gq0w== dependencies: "@sentry/browser" "^5.10.0" "@sentry/core" "^5.10.0" @@ -1460,9 +1460,9 @@ "@types/istanbul-lib-report" "*" "@types/json-schema@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" - integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== "@types/minimatch@*": version "3.0.3" @@ -1470,9 +1470,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "12.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.18.tgz#8d16634797d63c2af5bc647ce879f8de20b56469" - integrity sha512-DBkZuIMFuAfjJHiunyRc+aNvmXYNwV1IPMgGKGlwCp6zh6MKrVtmvjSWK/axWcD25KJffkXgkfvFra8ndenXAw== + version "13.1.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.4.tgz#4cfd90175a200ee9b02bd6b1cd19bc349741607e" + integrity sha512-Lue/mlp2egZJoHXZr4LndxDAd7i/7SQYhV0EjWfb/a4/OZ6tuVwMCVPiwkU5nsEipxEf7hmkSU7Em5VQ8P5NGA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1516,9 +1516,9 @@ integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== "@types/yargs@^13.0.0": - version "13.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" - integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== + version "13.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.4.tgz#53d231cebe1a540e7e13727fc1f0d13ad4a9ba3b" + integrity sha512-Ke1WmBbIkVM8bpvsNEcGgQM70XcEh/nbpxQhW7FhrsbCsXSY9BmLB1+LHtD7r9zrsOcFlLiF+a/UeJsdfw3C5A== dependencies: "@types/yargs-parser" "*" @@ -1569,37 +1569,37 @@ ethers "^4.0.28" lodash.clonedeepwith "^4.5.0" -"@walletconnect/core@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.39.tgz#43d05dbabcaeea491c0ee213ed60d2236672010f" - integrity sha512-cJSQe2Ao4okSvohNjA7Bs7Z+0BAznfVVTWBECIX/bGoSFpkAWabGY2Pn2gIYhobQMLSFpE6ZlZ4QfvlPO8HyPw== +"@walletconnect/core@^1.0.0-beta.42": + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.0.0-beta.42.tgz#cb9b098590255577571a90b9bda83a0f920020d8" + integrity sha512-Q7pDpTj2/bm7rkAbI+5/mf7SdurLXDfznjvE6jZGg8o23wsYamnkwLnqVMkqeFyUjY7bpHxWqakY813wmmlrZw== dependencies: - "@walletconnect/types" "^1.0.0-beta.39" - "@walletconnect/utils" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.42" + "@walletconnect/utils" "^1.0.0-beta.42" "@walletconnect/react-native@^1.0.0-beta.29": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.39.tgz#0db212eba9087055822a89bf73d1cebc5762639e" - integrity sha512-d/QAjL/Rp1lrJeblsHpl+Fa6HTz40A93X5l6oTV0YFAG7bZDPl+OogM337WnjZWfwcn1XaKXSwsmG1NXTQn4Yg== + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/react-native/-/react-native-1.0.0-beta.42.tgz#3e703a62d80db6f10470ecdd443a3c4025973e3f" + integrity sha512-pcgIx+d4LFjXAgI8+n60fqh5YN/YiVtGhcqdVC/9dadcV/9C0YkFYQiYAXNqXPx/FzaA0+4X8PSyEZY4P61A7g== dependencies: - "@walletconnect/core" "^1.0.0-beta.39" - "@walletconnect/types" "^1.0.0-beta.39" - "@walletconnect/utils" "^1.0.0-beta.39" + "@walletconnect/core" "^1.0.0-beta.42" + "@walletconnect/types" "^1.0.0-beta.42" + "@walletconnect/utils" "^1.0.0-beta.42" -"@walletconnect/types@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.39.tgz#e84463f32d6c450376db3d0ce56f0ece6608bfa7" - integrity sha512-YO/g1HVnFxcMNiUI9LEWEDe5uVHw8D7JzJol+bT71iXymzolnsbG32OayCJM9nHqT48Rpz1EGIno8EjW9jH2OQ== +"@walletconnect/types@^1.0.0-beta.42": + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.0.0-beta.42.tgz#1a0db31b37b7765985f78e2b0f2942407685cdcf" + integrity sha512-YBpcYdYGEacOob5VF0/8LRGz/uGynFcwoj9RIEOkDl9JqGQMaXhlZ1M48AfEp8NVQvXRF+cSc3moPDwu3+9USw== -"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.39": - version "1.0.0-beta.39" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.39.tgz#8909b9cffa3999b046ce32cbb21b8ddca97b9183" - integrity sha512-AOlhPkK+IUzGG5iDTupKdUwNW4on1aAj5NyLMMN1+htr06hqaCV8F9HeYibSen22wdSUuLXkIQNy3SR3LPcehA== +"@walletconnect/utils@^1.0.0-beta.36", "@walletconnect/utils@^1.0.0-beta.42": + version "1.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.0.0-beta.42.tgz#60304d0ed902a532ac9e535905b5a1c4c8063069" + integrity sha512-/eLcm+tEcvqlYaEaG/L7c+3uNrugZs3a30bwYUbNvlmzYWTNBzU/EV18CGavlZLc/Pb2XtPXevGtDsLlvtR7/Q== dependencies: "@ethersproject/address" "^5.0.0-beta.125" "@ethersproject/bytes" "^5.0.0-beta.126" "@ethersproject/strings" "^5.0.0-beta.125" - "@walletconnect/types" "^1.0.0-beta.39" + "@walletconnect/types" "^1.0.0-beta.42" bignumber.js "^8.1.1" "@yarnpkg/lockfile@^1.0.0", "@yarnpkg/lockfile@^1.1.0": @@ -1840,9 +1840,9 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" - integrity sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg== + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== dependencies: "@types/color-name" "^1.1.1" color-convert "^2.0.1" @@ -1929,12 +1929,13 @@ array-find-index@^1.0.1: integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-includes@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.0.tgz#48a929ef4c6bb1fa6dc4a92c9b023a261b0ca404" - integrity sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ== + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== dependencies: define-properties "^1.1.3" - es-abstract "^1.17.0-next.0" + es-abstract "^1.17.0" + is-string "^1.0.5" array-map@~0.0.0: version "0.0.0" @@ -2055,7 +2056,7 @@ asyncstorage-down@^4.2.0: ltgt "^2.1.3" tiny-queue "0.2.0" -atob@^2.1.1: +atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -2535,13 +2536,13 @@ browserify-zlib@^0.1.4: pako "~0.2.0" browserslist@^4.8.0: - version "4.8.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" - integrity sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA== + version "4.8.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.3.tgz#65802fcd77177c878e015f0e3189f2c4f627ba44" + integrity sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg== dependencies: - caniuse-lite "^1.0.30001015" + caniuse-lite "^1.0.30001017" electron-to-chromium "^1.3.322" - node-releases "^1.1.42" + node-releases "^1.1.44" bser@2.1.1: version "2.1.1" @@ -2711,10 +2712,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001015: - version "1.0.30001016" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001016.tgz#16ea48d7d6e8caf3cad3295c2d746fe38c4e7f66" - integrity sha512-yYQ2QfotceRiH4U+h1Us86WJXtVHDmy3nEKIdYPsZCYnOV5/tMgGbmoIlrMzmh2VXlproqYtVaKeGDBkMZifFA== +caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001017: + version "1.0.30001019" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001019.tgz#857e3fccaad2b2feb3f1f6d8a8f62d747ea648e1" + integrity sha512-6ljkLtF1KM5fQ+5ZN0wuyVvvebJxgJPTmScOMaFuQN2QuOzvRJnWSKfzQskQU5IOU4Gap3zasYPIinzwUjoj/g== capture-exit@^2.0.0: version "2.0.0" @@ -2992,15 +2993,13 @@ code-push@^2.0.6: yazl "^2.4.1" code-push@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.0.1.tgz#d6d48b1e112a49148b2244b0213afaf3f818645b" - integrity sha512-UgktdhS47nxtUdGB1l4D6JBnuGB20hMT7QswGj6gQgQbiTjSmOBJ0MK/09fyeYzWKjUnJBEmUud08rC7WzKFMw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/code-push/-/code-push-3.1.0.tgz#02b43b8f8cae1d8d281437aa5635c288399a48ca" + integrity sha512-SwEWx/MLEkRh/oXw4kvi8AIVzR7R2HFWKjsZwX3BWMLEudus3kekwuO2ufk9nYxHcDBZjUfao0G3HIkV9P2Cbw== dependencies: q "^1.4.1" recursive-fs "^1.1.2" - slash "3.0.0" - superagent "^5.1.0" - superagent-proxy "^2.0.0" + slash "^3.0.0" yazl "^2.4.1" collapse-white-space@^1.0.2: @@ -3103,11 +3102,11 @@ component-inherit@0.0.3: integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= compressible@~2.0.16: - version "2.0.17" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" - integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== dependencies: - mime-db ">= 1.40.0 < 2" + mime-db ">= 1.43.0 < 2" compression@^1.7.1: version "1.7.4" @@ -3438,9 +3437,9 @@ date-fns@^1.30.1: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.8.15: - version "1.8.17" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.17.tgz#53ec413f2a7b02afbea1846d61bb260fa8567cea" - integrity sha512-47VY/htqYqr9GHd7HW/h56PpQzRBSJcxIQFwqL3P20bMF/3az5c3PWdVY3LmPXFl6cQCYHL7c79b9ov+2bOBbw== + version "1.8.19" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe" + integrity sha512-7kqOoj3oQSmqbvtvGFLU5iYqies+SqUiEGNT0UtUPPxcPYgY1BrkXR0Cq2R9HYSimBXN+xHkEN4Hi399W+Ovlg== debounce@^1.2.0: version "1.2.0" @@ -3797,9 +3796,9 @@ ejs@^3.0.1: integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw== electron-to-chromium@^1.3.322: - version "1.3.322" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" - integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA== + version "1.3.327" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.327.tgz#516f28b4271727004362b4ac814494ae64d9dde7" + integrity sha512-DNMd91VtKt44LIkFtpICxAWu/GSGFLUMDM/kFINJ3Oe47OimSnbMvO3ChkUCdUyit+pRdhdCcM3+i5bpli5gqg== elliptic@6.5.2, elliptic@^6.0.0: version "6.5.2" @@ -3901,11 +3900,11 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.4.tgz#a757397dc5d9de973ac9a5d7d4e8ade7cfae9101" - integrity sha512-fZ0KkoxSjLFmhW5lHbUT3tLwy3nX1qEzMYo8koY1vrsAco53CMT1djnBSeC/wUjTEZRhZl9iRw7PaMaxfJ4wzQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== dependencies: - stackframe "^1.1.0" + stackframe "^1.1.1" errorhandler@^1.5.0: version "1.5.1" @@ -3915,22 +3914,23 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1: - version "1.17.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" - integrity sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw== + +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" + integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.4" - is-regex "^1.0.4" + is-callable "^1.1.5" + is-regex "^1.0.5" object-inspect "^1.7.0" object-keys "^1.1.1" object.assign "^4.1.0" - string.prototype.trimleft "^2.1.0" - string.prototype.trimright "^2.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -3990,9 +3990,9 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.x.x, escodegen@^1.9.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" - integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== + version "1.12.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.1.tgz#08770602a74ac34c7a90ca9229e7d51e379abc76" + integrity sha512-Q8t2YZ+0e0pc7NRVj3B4tSQ9rim1oi4Fh46k2xhJ2qOiEwhQfdjyEQddWdj7ZFaKmU+5104vn1qrcjEPWq+bgQ== dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -4192,9 +4192,9 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^6.6.0: - version "6.7.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" - integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -4288,9 +4288,9 @@ eth-contract-metadata@^1.9.3: integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA== ethers@^4.0.28, ethers@^4.0.39: - version "4.0.40" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.40.tgz#6e1963d10b5d336a13cd81b519c230cc17624653" - integrity sha512-MC9BtV7Hpq4dgFONEfanx9aU9GhhoWU270F+/wegHZXA7FR+2KXFdt36YIQYLmVY5ykUWswDxd+f9EVkIa7JOA== + version "4.0.42" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.42.tgz#7def83a1f770b84d44cf1c2dfc58b7fd29d1d45d" + integrity sha512-2gmmt5x683Xz4QwGDBVJhrdXevVAEr5fnXPGDPou2AKB+zklrirGpl0w1SHBn7Wa9hbL2z6MvP3n7k8Yss2MFg== dependencies: aes-js "3.0.0" bn.js "^4.4.0" @@ -5420,9 +5420,9 @@ husky@^2.4.0: slash "^3.0.0" i18n-js@^3.0.11: - version "3.5.0" - resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.0.tgz#e2c41e1f90405d691d33ddce260f3dff9743215e" - integrity sha512-XosH7plfEisWo5XEYxkdlwONsDVQ3sYI3ZoKXcjXdyq+9eVNIJg2h2oPsgadfqcXxpPHMVMNBgmiyW3aEJXg1g== + version "3.5.1" + resolved "https://registry.yarnpkg.com/i18n-js/-/i18n-js-3.5.1.tgz#9787450894059bec1af791123231e59898eb97c1" + integrity sha512-nJgbE5Vj9qzOQfjdVd/uoMoO8ppVaB/3LB6KOmMfD8IQ1vNNh307iHyQLK8ZnLYWkAszfPvVpYmUt1Le/RuHMQ== i18next@^17.0.3: version "17.3.1" @@ -5466,9 +5466,9 @@ image-size@^0.6.0: integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== immer@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/immer/-/immer-5.0.1.tgz#1a1184fa758f68f1b5573db840825fb5164cceca" - integrity sha512-KFHV1ivrBmPCVRhjy9oBooypnPfJ876NTrWXMNoUhXFAaWWAViVqZ4l6HxPST52qcN82qqsR38/pCGYRWP5W7w== + version "5.1.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-5.1.0.tgz#38d9eba40dbb0389b7ae7b8b99e4661df0cf89e3" + integrity sha512-t6gyFtTcokCuI0tX9KQZJQAkIjSqo/nTeJnwojfty69EzrorZbywwhZ8qNNlF+faajHeRnhOvM2F40KHLFCghQ== import-fresh@^2.0.0: version "2.0.0" @@ -5631,9 +5631,9 @@ inquirer@^6.2.0: through "^2.3.6" inquirer@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.1.tgz#13f7980eedc73c689feff3994b109c4e799c6ebb" - integrity sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw== + version "7.0.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.2.tgz#b39b205b95c9424839a1fd991d60426cf9bbc0e9" + integrity sha512-cZGvHaHwcR9E3xK9EGO5pHKELU+yaeJO7l2qGKIbqk4bCuDuAn15LCoUTS2nSkfv9JybFlnAGrOcVpCDZZOLhw== dependencies: ansi-escapes "^4.2.1" chalk "^2.4.2" @@ -5728,10 +5728,10 @@ is-buffer@^2.0.0, is-buffer@^2.0.2, is-buffer@~2.0.3: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== is-ci@^1.0.10: version "1.2.1" @@ -5762,9 +5762,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== is-decimal@^1.0.0: version "1.0.3" @@ -5916,7 +5916,7 @@ is-redirect@^1.0.0: resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= -is-regex@^1.0.4: +is-regex@^1.0.4, is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== @@ -5943,6 +5943,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -5956,9 +5961,9 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-what@^3.3.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.4.0.tgz#a9b3fe0c22f52d49efef977f640da44e65a3f866" - integrity sha512-oFdBRuSY9PocqPoUUseDXek4I+A1kWGigZGhuG+7GEkp0tRkek11adc0HbTEVsNvtojV7rp0uhf5LWtGvHzoOQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.5.0.tgz#c50b0e8f3021e0b39410c159bea43a5510d99027" + integrity sha512-00pwt/Jf7IaRh5m2Dp93Iw8LG2cd3OpDj3NrD1XPNUpAWVxPvBP296p4IiGmIU4Ur0f3f56IoIM+fS2pFYF+tQ== is-whitespace-character@^1.0.0: version "1.0.3" @@ -6086,9 +6091,9 @@ istanbul-reports@^2.2.6: handlebars "^4.1.2" iterall@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" - integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== jest-changed-files@^24.9.0: version "24.9.0" @@ -7472,10 +7477,10 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== mime-db@~1.23.0: version "1.23.0" @@ -7490,11 +7495,11 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== dependencies: - mime-db "1.42.0" + mime-db "1.43.0" mime@1.6.0: version "1.6.0" @@ -7834,10 +7839,10 @@ node-pre-gyp@*: semver "^5.3.0" tar "^4.4.2" -node-releases@^1.1.42: - version "1.1.42" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7" - integrity sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA== +node-releases@^1.1.44: + version "1.1.44" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.44.tgz#cd66438a6eb875e3eb012b6a12e48d9f4326ffd7" + integrity sha512-NwbdvJyR7nrcGrXvKAvzc5raj/NkoJudkarh2yIpJ4t0NH4aqjUDz/486P+ynIW5eokKOfzGNRdYoLfBlomruw== dependencies: semver "^6.3.0" @@ -7921,9 +7926,9 @@ npm-run-path@^2.0.0: path-key "^2.0.0" npm-run-path@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.0.tgz#d644ec1bd0569187d2a52909971023a0a58e8438" - integrity sha512-8eyAOAH+bYXFPSnNnKr3J+yoybe8O87Is5rtAQ8qRczJz1ajcsjg8l2oZqP+Ppx15Ii3S1vUTjQN2h4YO2tWWQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" @@ -8302,9 +8307,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== dependencies: p-try "^2.0.0" @@ -8598,9 +8603,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.5: - version "2.1.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5" - integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA== + version "2.2.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" + integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== pify@^2.0.0: version "2.3.0" @@ -8804,9 +8809,9 @@ postcss-value-parser@^4.0.2: integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.7: - version "7.0.25" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.25.tgz#dd2a2a753d50b13bed7a2009b4a18ac14d9db21e" - integrity sha512-NXXVvWq9icrm/TgQC0O6YVFi4StfJz46M1iNd/h6B26Nvh/HKI+q4YZtFN/EjcInZliEscO/WL10BXnc1E5nwg== + version "7.0.26" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587" + integrity sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -8954,9 +8959,9 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24, psl@^1.1.28: - version "1.6.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" - integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" + integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== public-encrypt@^4.0.0: version "4.0.3" @@ -9104,9 +9109,9 @@ react-coin-icon@0.1.13: styled-components "4.4.1" react-devtools-core@^4.0.6: - version "4.2.1" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.2.1.tgz#0122ccb8a041b0b61811425a57e9dec05125e9d8" - integrity sha512-Puo0PwkpxWZY4E0cU7lpOR6Lh5UhGoOScSdhVtvK6HK6InC6+k9ypyVHI2ar2OoBasm3wP5mJlDHcUmbmqF78w== + version "4.4.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.4.0.tgz#614cabe5f3d6fb69730dc76da10f8fa4eb033695" + integrity sha512-ayyz+clbjekj5rqTjieI/eE0xGZkgotklVnxfa4Pyk9se5+AHUAhUwMhLvK5N2+mR2PGOZkv159RDTmvgs+wZQ== dependencies: es6-symbol "^3" shell-quote "^1.6.1" @@ -9150,9 +9155,9 @@ react-native-bundle-visualizer@^2.0.1: source-map-explorer "^2.1.2" react-native-camera@^3.9.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.0.tgz#dd8c7fcf75b347e0b07c1dedeba2ba47504ff80a" - integrity sha512-GoRq2gHMvidcMCzj0AjaIbrJy5ZRE1XxLUIGN+M/Ev2r2RXGFWBToGoDvy4KZcwF3THWefVAZL1It+fT8pvxgQ== + version "3.15.1" + resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.15.1.tgz#8e4eb67cb6687b5250f849b348f0d19a01649105" + integrity sha512-xj1sljzFq8HVX22d2T945dsJdK/KFb3jaXUHEYGwMp/zz0ypIs3mY3NezdpyYpS1ioKKzdIcLrxz2VKzDCXaCg== dependencies: prop-types "^15.6.2" @@ -9197,10 +9202,10 @@ react-native-crypto@^2.2.0: public-encrypt "^4.0.0" randomfill "^1.0.3" -react-native-device-info@^2.1.3: - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-2.3.2.tgz#db2b8f135aaf2515583e367ab791dcc7d2f0d14c" - integrity sha512-ccpPuUbwhw5uYdVwN1UJp6ykMZz6U/u82HNM3oJ7O6MP8RIMlMDkHbqR4O0sDtUSuRMGiqqRzFtmOLFYeQ0ODw== +react-native-device-info@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-5.3.1.tgz#d764732c4841b6b6c2f42516e8840075717ea88a" + integrity sha512-e/fRDoah+HxItscOJTGJY8zyVKmBUdf53VWIDGLGV4VVZ0mfzIQ2uo0ULGri0vjGUYqgyqgnW3jybPSznMxKcA== react-native-dotenv@^0.2.0: version "0.2.0" @@ -9235,11 +9240,6 @@ react-native-haptic-feedback@^1.8.2: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-1.8.2.tgz#532dfcdfe2eaaaf3c30ff5dff97973ff05399fcd" integrity sha512-arY2vsQtcF6Z/HggcfASTFzXm5HLUvK08rj6xPs6b95mpUDyStxEoC2c6MCFx+GSqnpBuOQvQCf42Zp0ATnWoQ== -react-native-hooks@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/react-native-hooks/-/react-native-hooks-0.9.0.tgz#589fc2390296d9afe03327298dabcf0a1f350910" - integrity sha512-yqSAH0zxqjYHYPo6mPut3dEROoB5qMvsAbN3EK0MDQrWA5zdqmzgTEpS9/qwXaIyllk6hQbHxYnRTWq2uq4tJQ== - react-native-indicators@0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/react-native-indicators/-/react-native-indicators-0.17.0.tgz#92f95efaf5fb53be576dfe4e1980a25655a93f55" @@ -9257,10 +9257,10 @@ react-native-iphone-x-helper@^1.2.1: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== -react-native-keychain@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.1.tgz#c332f5d9aaf597255ae6ea4ca7d5c84a24684a1d" - integrity sha512-AqQp4Hib9y5DP5es5umEAhxKG7L0bA8cHNFhvlqs6oUcbUoKtXmhLDo3wzvnCF+bm8DXpGhvkU6P0LkfO0AgPQ== +react-native-keychain@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-4.0.3.tgz#38c6c0021ed697b6149d460dd5910c3c92d36ae7" + integrity sha512-mXlBcHueQ3i73GU9hc7giXJqkh+oL0f8As2H+1XWW2GovkM7xQEZNoro3DsYDIWzFW3eRoF8DmUZIGbLLEVp3Q== react-native-languages@^3.0.0: version "3.0.2" @@ -9322,12 +9322,12 @@ react-native-randombytes@^3.5.3: react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" - resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/c7d9cb4a5bb855b9bd944c19947564b8ee2152e6" + resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/1ea8cc3d8b713d4bac2529c010b035c6d1529df4" -react-native-redash@8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-8.2.2.tgz#e2944490fbd150087043cbb6b93cf804aa932313" - integrity sha512-9LYrtR/Y4HrEpuL+CjkI3bqygwSC3S9gF1CP/to1Q5QulR42sFMknR9X/NNFDwmbmvAZoV4soHNhGpHCkGtqvg== +react-native-redash@^9.0.0: + version "9.5.4" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.5.4.tgz#61871ef547c1b505e66b2fcdf1eef26db0ad6c0b" + integrity sha512-1NfBORcLESwtkDyZD0dyK/mdkr9YJ7IQ4zlxSQpqMLr/KOgNp3Hsri+cJe/dqfwRhyCPo64DSJgvFQu3kYT/kw== dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -9377,10 +9377,10 @@ react-native-store-review@^0.1.5: resolved "https://registry.yarnpkg.com/react-native-store-review/-/react-native-store-review-0.1.5.tgz#9df69786a137580748e368641698d2104519e4cf" integrity sha512-vVx7NYaQva3bGU5MdqXn4yEB+o+GPdmjqAuj7PnkepfeCS6Bi3sqniiKoXmKOKDgRTfIobBZjUkHzWeHli1+3A== -react-native-svg@9.13.3: - version "9.13.3" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.3.tgz#6414b337d55af169ac2487ab70f3108404434446" - integrity sha512-H50b2m4jvrQ7KxKs8uYSuWecr6e5XC7BDfS7DaA96+0Owjh0C9DksI5l8SRyHnmE+emiYMPu6Qqfr9dCyKkaJQ== +react-native-svg@9.13.6: + version "9.13.6" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.6.tgz#5365fba2bc460054b90851e71f2a71006a5d373f" + integrity sha512-vjjuJhEhQCwWjqsgWyGy6/C/LIBM2REDxB40FU1PMhi8T3zQUwUHnA6M15pJKlQG8vaZyA+QnLyIVhjtujRgig== dependencies: css-select "^2.0.2" css-tree "^1.0.0-alpha.37" @@ -9417,15 +9417,10 @@ react-native-tooltip@marcosrdz/react-native-tooltip#master: version "5.2.1" resolved "https://codeload.github.com/marcosrdz/react-native-tooltip/tar.gz/e0e88d212b5b7f350e5eabba87f588a32e0f2590" -react-native-touch-id@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/react-native-touch-id/-/react-native-touch-id-4.4.1.tgz#8b1bb2d04c30bac36bb9696d2d723e719c4a8b08" - integrity sha512-1jTl8fC+0fxvqegy/XXTyo6vMvPhjzkoDdaqoYZx0OH8AT250NuXnNPyKktvigIcys3+2acciqOeaCall7lrvg== - react-native-udp@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.6.1.tgz#ce9f2479f8af6d1bb356cfee69c89cf92fdd50be" - integrity sha512-KctAXtfBjRe+rGLvms92C82MsrZUwUyODwGskY6mDPigMaDTmsKdNqLCXgWh0g6ZmB2UtOzFsbPphy36NyM3KA== + version "2.7.0" + resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-2.7.0.tgz#d04c5100fcbff343f8a2bf35a3025743d8960f93" + integrity sha512-tT+Wn0yLbdaTohXkGGor0HYgScGaASWCaCLSO1kCIUdNke7AtcOX5a5nfNLYrEjdUn7/2HRofuplyky7iJHSQA== dependencies: base64-js "0.0.8" events "^1.0.2" @@ -9440,7 +9435,7 @@ react-native-version-number@^0.3.6: react-native@facebook/react-native: version "1000.0.0" - resolved "https://codeload.github.com/facebook/react-native/tar.gz/69e9f3a3891a9b4a9acd58e97ae4e6f9ebcf968d" + resolved "https://codeload.github.com/facebook/react-native/tar.gz/bd0c37e456392090507f227b8fb90c1eb7c3d327" dependencies: "@babel/runtime" "^7.0.0" "@react-native-community/cli" "^3.0.0" @@ -9647,9 +9642,9 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea string_decoder "~0.10.x" readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -9749,9 +9744,9 @@ redux-thunk@^2.3.0: integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== redux@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796" - integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q== + version "4.0.5" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" + integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== dependencies: loose-envify "^1.4.0" symbol-observable "^1.2.0" @@ -9844,9 +9839,9 @@ regjsgen@^0.5.0: integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== regjsparser@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.1.tgz#5b6b28c418f312ef42898dc6865ae2d4b9f0f7a2" - integrity sha512-7LutE94sz/NKSYegK+/4E77+8DipxF+Qn2Tmu362AcmsF2NYq/wx3+ObvU90TKEhjf7hQoFXo23ajjrXP7eUgg== + version "0.6.2" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.2.tgz#fd62c753991467d9d1ffe0a9f67f27a529024b96" + integrity sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q== dependencies: jsesc "~0.5.0" @@ -10189,9 +10184,9 @@ rxjs@^5.4.3: symbol-observable "1.0.1" rxjs@^6.4.0, rxjs@^6.5.3: - version "6.5.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" - integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== dependencies: tslib "^1.9.0" @@ -10594,9 +10589,9 @@ socks@~2.3.2: smart-buffer "^4.1.0" source-map-explorer@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.1.2.tgz#305d61efbb1d1ebbf24a9fffef718635054d509c" - integrity sha512-rgujHHHwf0/HCSTFbdTPJETGTgbGqVDD068Ob/wfV41u3AdU8iknSvGTDoU8vCIUeZuLnHX4JYsQ1RMd129XCQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.2.1.tgz#4bd236a1fe73e8b9db475f60197c48fc041928b8" + integrity sha512-vfjS5IRaENgXtTq2Bym0ctEorYGYNHLVCVZZeL1fvkD5iBoWKMlUhF/oFBTcTn9cxry1flplyvk0QGTROafB3Q== dependencies: btoa "^1.2.1" chalk "^3.0.0" @@ -10608,14 +10603,14 @@ source-map-explorer@^2.1.2: open "^7.0.0" source-map "^0.7.3" temp "^0.9.1" - yargs "^15.0.2" + yargs "^15.1.0" source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: - atob "^2.1.1" + atob "^2.1.2" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" @@ -10731,29 +10726,29 @@ stable@^0.1.8: integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-generator@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.4.tgz#027513eab2b195bbb43b9c8360ba2dd0ab54de09" - integrity sha512-ha1gosTNcgxwzo9uKTQ8zZ49aUp5FIUW58YHFxCqaAHtE0XqBg0chGFYA1MfmW//x1KWq3F4G7Ug7bJh4RiRtg== + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== dependencies: - stackframe "^1.1.0" + stackframe "^1.1.1" stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== -stackframe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83" - integrity sha512-Vx6W1Yvy+AM1R/ckVwcHQHV147pTPBKWCRLrXMuPrFVfvBUc3os7PR1QLIWCMhPpRg5eX9ojzbQIMLGBwyLjqg== +stackframe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.1.tgz#ffef0a3318b1b60c3b58564989aca5660729ec71" + integrity sha512-0PlYhdKh6AfFxRyK/v+6/k+/mMfyiEBbTM5L94D0ZytQnJ166wuwoTYLHFWGbs2dpA8Rgq763KGWmN1EQEYHRQ== stacktrace-gps@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.3.tgz#b89f84cc13bb925b96607e737b617c8715facf57" - integrity sha512-51Rr7dXkyFUKNmhY/vqZWK+EvdsfFSRiQVtgHTFlAdNIYaDD7bVh21yBHXaNWAvTD+w+QSjxHg7/v6Tz4veExA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== dependencies: source-map "0.5.6" - stackframe "^1.1.0" + stackframe "^1.1.1" stacktrace-js@^2.0.0: version "2.0.1" @@ -10860,18 +10855,18 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimleft@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" - integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" -string.prototype.trimright@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" - integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" @@ -11089,9 +11084,9 @@ superagent-proxy@^2.0.0: proxy-agent "3" superagent@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.2.tgz#b122f3a62b14c4d638612667033a7eb43c4f4d83" - integrity sha512-VwPCbi9H02qDtTbdY+e3+cK5XR0YHsJy9hmeCOXLQ8ezjq8+S1Bs4MdNRmpmf2QjDBetD7drG7/nEta7E3E6Sg== + version "5.1.3" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.1.3.tgz#9502db541559d3d9e7acfa30f70d1186c0faa88d" + integrity sha512-2bno1Nb4uvZPECTJ7NDYlae6Q8LLQoZZZ9Vumd346jU1UGVkNC/lQI42jHwtrqVoepyt0QxNKFty01IRKgD4CA== dependencies: component-emitter "^1.3.0" cookiejar "^2.1.2" @@ -11528,9 +11523,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= ua-parser-js@^0.7.18: - version "0.7.20" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" - integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== + version "0.7.21" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" + integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ== uglify-es@^3.1.9: version "3.3.9" @@ -11541,9 +11536,9 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.7.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" - integrity sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== + version "3.7.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a" + integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg== dependencies: commander "~2.20.3" source-map "~0.6.1" @@ -11902,22 +11897,22 @@ vm-browserify@0.0.4: indexof "0.0.1" vscode-json-languageservice@^3.2.1: - version "3.4.10" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.10.tgz#2ff5ff4e4f31acd160619081ca279306933aaf8f" - integrity sha512-0Uy1bgVvnTkTjPOOZUCWFmXR71YgKAGu3XE3bIi9IPwTsn5apiqulOaz1UMs2ldlrHeLgsdHGEkFJnDhxtqyVQ== + version "3.4.11" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.11.tgz#7c0632bccc4b2b955f99f99f43d96d3eece1de42" + integrity sha512-26Qv1SFp6x3XmCqU1BRceRsSKRO3xkQa6/K8ziSRt52/LQPiw5ipSxlGVSlzIoi5LCmQVEqUajhiVEMNlFXhNw== dependencies: jsonc-parser "^2.2.0" - vscode-languageserver-textdocument "^1.0.0-next.4" - vscode-languageserver-types "^3.15.0-next.6" + vscode-languageserver-textdocument "^1.0.0-next.5" + vscode-languageserver-types "^3.15.0-next.9" vscode-nls "^4.1.1" - vscode-uri "^2.1.0" + vscode-uri "^2.1.1" -vscode-languageserver-textdocument@^1.0.0-next.4: +vscode-languageserver-textdocument@^1.0.0-next.5: version "1.0.0-next.5" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.5.tgz#dbb7a45dd973a19261a7c57ab9a439c40f3799ee" integrity sha512-1jp/zAidN/bF/sqPimhBX1orH5G4rzRw63k75TesukJDuxm8yW79ECStWbDSy41BHGOwSGN4M69QFvhancSr5A== -vscode-languageserver-types@^3.15.0-next.6: +vscode-languageserver-types@^3.15.0-next.9: version "3.15.0-next.9" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz#957a9d1d5998a02edf62298fb7e37d9efcc6c157" integrity sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw== @@ -11927,7 +11922,7 @@ vscode-nls@^4.1.1: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== -vscode-uri@^2.1.0: +vscode-uri@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90" integrity sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A== @@ -12163,7 +12158,7 @@ xcode@1.0.0: simple-plist "^0.2.1" uuid "3.0.1" -xcode@2.0.0, xcode@^2.0.0: +xcode@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.0.0.tgz#134f1f94c26fbfe8a9aaa9724bfb2772419da1a2" integrity sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw== @@ -12171,6 +12166,14 @@ xcode@2.0.0, xcode@^2.0.0: simple-plist "^1.0.0" uuid "^3.3.2" +xcode@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.1.0.tgz#bab64a7e954bb50ca8d19da7e09531c65a43ecfe" + integrity sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ== + dependencies: + simple-plist "^1.0.0" + uuid "^3.3.2" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -12199,9 +12202,9 @@ xmldoc@^1.1.2: sax "^1.2.1" xmldom@0.1.x: - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" + integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== xmlhttprequest-ssl@~1.5.4: version "1.5.5" @@ -12347,10 +12350,10 @@ yargs@^12.0.2, yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^15.0.2: - version "15.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.0.2.tgz#4248bf218ef050385c4f7e14ebdf425653d13bd3" - integrity sha512-GH/X/hYt+x5hOat4LMnCqMd8r5Cv78heOMIJn1hr7QPPBqfeC6p89Y78+WB9yGDvfpCvgasfmWLzNzEioOUD9Q== +yargs@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" + integrity sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg== dependencies: cliui "^6.0.0" decamelize "^1.2.0" From 0ba0a68fcf6bbb4c69e8ed5000a100c3ac7b10c3 Mon Sep 17 00:00:00 2001 From: Michael Demarais Date: Tue, 7 Jan 2020 18:09:11 -0500 Subject: [PATCH 634/636] fix redash dep version to 9.0.0 --- ios/Podfile.lock | 44 +++++----- package.json | 2 +- yarn.lock | 204 ++++------------------------------------------- 3 files changed, 37 insertions(+), 213 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5f00b27fd43..403ceb35e25 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -669,8 +669,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: cde416483dac037923206447da6e1454df403714 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 904ace83555a7813bc9117a045dff654ae711d39 - FBReactNativeSpec: ac66550fd5331a88a825860ae4e45e058571ef73 + FBLazyVector: 9cc9518deb3185aedeec47000a65d681a976cf2c + FBReactNativeSpec: b626dd10a18ffdaa4f7bcdf0c6890f92ff9f446c Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -690,15 +690,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: fc5f657b89514039fccfe826c524126538ef5da3 - RCTTypeSafety: 7860ee3c7d06cd49de0a12dde6784c925853cedf - React: 3da88a786975d0d2244b076b0696411defd3d37c - React-Core: 39042bc55d07e4fabf6588892d9eaf88dca37051 - React-CoreModules: ceae464bbadcbaf58a1031768c137dd88f339f60 - React-cxxreact: 03194eb1b9d558d6f48efa7d41a93b90318c3016 - React-jsi: 22a0960d7040824a23dff7701d7738f3c1d5807f - React-jsiexecutor: 00e5aebe98359d913d43af8cc23d5ebb17083723 - React-jsinspector: 56e72f672b35aeade701012e6e39876897546cfb + RCTRequired: 561f5b708210ca4a99e2df35eb5629839b8c8242 + RCTTypeSafety: 70200f5965c928ba61e01d96b528cd5ebb75e082 + React: 60e9a38634da81ad52e95e9f30857aa361da41cb + React-Core: 829d02e3d1051c5e036fb44f3e151399befeee1b + React-CoreModules: 258b84d06552a8ee63dc1449e6c3ed57e71f3548 + React-cxxreact: cc51b184d54afb2b5adbe7ee90366ab993948622 + React-jsi: 7517de4f497e79cba35956eb1a1d62e9283679a3 + React-jsiexecutor: 4afd0635fa05afb028cb0b7553f87c45dd19b432 + React-jsinspector: 3ea921e5d1b541fc0f6db9817da3d8b2e3f6bf95 react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 1ba3e7f2375a6b44ae09ce9be70268e0b225bc10 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -709,16 +709,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: ff9d13e523f2b58e6bc5d4d32321ac60671b5dc9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 48dc86f556d46f012c92fdc4fce37e2f61972a7a - React-RCTAnimation: f2b22ff8ee4a8f726cb2a2c0489dc43160a9ba78 - React-RCTBlob: e1cc220434c170cfb87972c5f9ddeca42bc859c2 - React-RCTImage: a71a7ae08498f10f025cb3859e623bc35d984ac2 - React-RCTLinking: 8cd1a2e5855917d8202dbbec645ce96a4dc56599 - React-RCTNetwork: 52edddadac17aebf35340cc890d366033bcaa497 - React-RCTSettings: 5ef91ca864871af290fc7f181a1fc8cf931023fa - React-RCTText: ad1509728a06baaf16810c807ae86fd0f94218cd - React-RCTVibration: 72d3e98346f20ac4c59649bff2a02f229048625e - ReactCommon: b3d60106340b0c5cb774de530a3ec44e99d3365e + React-RCTActionSheet: 93eba44099c05811fde250346d56da113b94699e + React-RCTAnimation: 3d6d5dd3a92ce802b29b4997c8bd3ab47786e673 + React-RCTBlob: 2de18ddb285a4707f3c418c1f410583ad41cf626 + React-RCTImage: c301b29f8520dc19cc9f179ac92f529f35249327 + React-RCTLinking: 8fb308a2ca7614a045d5179758247aaaebf29239 + React-RCTNetwork: 86aaa30f5448e7347406e19d04467ae0d438f478 + React-RCTSettings: 1a7285f69b8127d9ba4df598bbf813a19ace6835 + React-RCTText: 9529312bbe556493b65c6718a6aa3b1463745588 + React-RCTVibration: 5a96eeacad1ff1bdcb82ade1918576a55b78c061 + ReactCommon: d30c9253603ca26acdce659e95dc882a439e4852 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -747,7 +747,7 @@ SPEC CHECKSUMS: SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - Yoga: d35afc581c45e82ecabf981b93d17f02ae19c49f + Yoga: 17cd3cd362cd60353073e818ef23e27ce0339bb5 PODFILE CHECKSUM: e38b8f3a80d4f969b2bd4796967957156faf7531 diff --git a/package.json b/package.json index 35a39cbf4ff..706b1d993d3 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "react-native-radial-gradient": "shkatulo/react-native-radial-gradient", "react-native-randombytes": "^3.5.3", "react-native-reanimated": "software-mansion/react-native-reanimated", - "react-native-redash": "^9.0.0", + "react-native-redash": "9.0.0", "react-native-safe-area-context": "^0.5.0", "react-native-safe-area-view": "mikedemarais/react-native-safe-area-view", "react-native-screens": "^1.0.0-alpha.23", diff --git a/yarn.lock b/yarn.lock index 968de00b380..6dba54f6c03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1617,11 +1617,6 @@ abab@^2.0.0: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -1860,19 +1855,6 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2811,11 +2793,6 @@ child-process-promise@^2.2.0: node-version "^1.0.0" promise-polyfill "^6.0.1" -chownr@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== - chroma-js@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.0.tgz#c0be48a21fe797ef8965608c1c4f911ef2da49d5" @@ -3163,11 +3140,6 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -3460,7 +3432,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@^3.1.0, debug@^3.2.6: +debug@3.2.6, debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -3581,11 +3553,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - denodeify@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" @@ -3609,11 +3576,6 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - detect-newline@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" @@ -3914,7 +3876,6 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" - es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: version "1.17.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" @@ -4854,13 +4815,6 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -4904,20 +4858,6 @@ fwd-stream@^1.0.4: dependencies: readable-stream "~1.0.26-4" -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -5230,11 +5170,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -5431,7 +5366,7 @@ i18next@^17.0.3: dependencies: "@babel/runtime" "^7.3.1" -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5443,13 +5378,6 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== -ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" - ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -7573,21 +7501,6 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -7604,7 +7517,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -7732,15 +7645,6 @@ ncp@~2.0.0: resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -7823,22 +7727,6 @@ node-notifier@^5.2.1, node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" -node-pre-gyp@*: - version "0.14.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" - integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4.4.2" - node-releases@^1.1.44: version "1.1.44" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.44.tgz#cd66438a6eb875e3eb012b6a12e48d9f4326ffd7" @@ -7851,14 +7739,6 @@ node-version@^1.0.0: resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - normalize-css-color@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/normalize-css-color/-/normalize-css-color-1.0.2.tgz#02991e97cccec6623fe573afbbf0de6a1f3e9f8d" @@ -7898,26 +7778,6 @@ normalize-svg-path@^1.0.1: dependencies: svg-arc-to-cubic-bezier "^3.0.0" -npm-bundled@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" - integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-packlist@^1.1.6: - version "1.4.7" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.7.tgz#9e954365a06b80b18111ea900945af4f88ed4848" - integrity sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -7932,16 +7792,6 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -8222,11 +8072,6 @@ ora@^3.4.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -8255,14 +8100,6 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - output-file-sync@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" @@ -9089,7 +8926,7 @@ raw-body@^2.2.0: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: +rc@^1.0.1, rc@^1.1.6: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -9324,10 +9161,10 @@ react-native-reanimated@software-mansion/react-native-reanimated: version "1.4.0" resolved "https://codeload.github.com/software-mansion/react-native-reanimated/tar.gz/1ea8cc3d8b713d4bac2529c010b035c6d1529df4" -react-native-redash@^9.0.0: - version "9.5.4" - resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.5.4.tgz#61871ef547c1b505e66b2fcdf1eef26db0ad6c0b" - integrity sha512-1NfBORcLESwtkDyZD0dyK/mdkr9YJ7IQ4zlxSQpqMLr/KOgNp3Hsri+cJe/dqfwRhyCPo64DSJgvFQu3kYT/kw== +react-native-redash@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/react-native-redash/-/react-native-redash-9.0.0.tgz#3fe5426c982a036cc4e7b2df9a94bd210ddd5750" + integrity sha512-2OV8ECpI6ruCwGA3nkhv1j3dGLUhoUVVDwgzAwOfhFrF3LglUaDhT8IG3DQFw7Q5sUuyPQY7HjLu9P0VkQ94LA== dependencies: abs-svg-path "^0.1.1" normalize-svg-path "^1.0.1" @@ -9641,7 +9478,7 @@ readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, rea isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: +readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -10083,7 +9920,7 @@ rimraf@2.6.3, rimraf@~2.6.2: dependencies: glob "^7.1.3" -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -10284,7 +10121,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -10338,7 +10175,7 @@ serve-static@^1.13.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -11213,19 +11050,6 @@ tail@^2.0.0: resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== -tar@^4.4.2: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - telnet-client@0.15.3: version "0.15.3" resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-0.15.3.tgz#99ec754e4acf6fa51dc69898f574df3c2550712e" @@ -12014,7 +11838,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@1.1.3, wide-align@^1.1.0: +wide-align@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== @@ -12264,7 +12088,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== From 9d60eb1c6a1e3dce5e54d5ccafd46c07dbf5766d Mon Sep 17 00:00:00 2001 From: osdnk Date: Tue, 7 Jan 2020 18:20:25 -0500 Subject: [PATCH 635/636] get rid of withNavigationFocusin favor of navigation.isFocused() --- src/screens/WalletScreen.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/screens/WalletScreen.js b/src/screens/WalletScreen.js index 4b890745b8f..1c9f30fd423 100644 --- a/src/screens/WalletScreen.js +++ b/src/screens/WalletScreen.js @@ -2,7 +2,7 @@ import { withSafeTimeout } from '@hocs/safe-timers'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import Animated from 'react-native-reanimated'; -import { withNavigation, withNavigationFocus } from 'react-navigation'; +import { withNavigation } from 'react-navigation'; import { compose, withProps } from 'recompact'; import { AssetList } from '../components/asset-list'; import { FabWrapper } from '../components/fab'; @@ -61,17 +61,16 @@ class WalletScreen extends Component { }; shouldComponentUpdate = nextProps => - !nextProps.isFocused - ? false - : isNewValueForObjectPaths(this.props, nextProps, [ - 'fetchingAssets', - 'fetchingUniqueTokens', - 'isEmpty', - 'isWalletEthZero', - 'language', - 'nativeCurrency', - 'sections', - ]); + nextProps.navigation.isFocused() && + isNewValueForObjectPaths(this.props, nextProps, [ + 'fetchingAssets', + 'fetchingUniqueTokens', + 'isEmpty', + 'isWalletEthZero', + 'language', + 'nativeCurrency', + 'sections', + ]); render = () => { const { @@ -118,7 +117,6 @@ export default compose( withUniswapLiquidityTokenInfo, withSafeTimeout, withNavigation, - withNavigationFocus, withIsWalletEmpty, withIsWalletEthZero, withKeyboardHeight, From 81b9c389b959f4fc1d22d339dd60353f2202872e Mon Sep 17 00:00:00 2001 From: jinchung Date: Tue, 7 Jan 2020 19:51:23 -0500 Subject: [PATCH 636/636] Cut release branch v1.2.3 --- CHANGELOG.md | 4 ++++ ios/Podfile.lock | 46 ++++++++++++++++++++++------------------------ package.json | 2 +- yarn.lock | 27 +++++++++++++-------------- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d61fe405bc6..3bcf4cbcb86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ### Removed ### Changed +## [1.2.3-1](https://github.com/rainbow-me/rainbow/releases/tag/v1.2.3-1) +### Changed +* Better biometric support +* Fix import wallet showing old wallet balances ## [1.2.2-4](https://github.com/rainbow-me/rainbow/releases/tag/v1.2.2-4) ### Added diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 403ceb35e25..761039e4af9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -334,9 +334,7 @@ PODS: - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): - - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -669,8 +667,8 @@ SPEC CHECKSUMS: Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: cde416483dac037923206447da6e1454df403714 Fabric: f988e33c97f08930a413e08123064d2e5f68d655 - FBLazyVector: 9cc9518deb3185aedeec47000a65d681a976cf2c - FBReactNativeSpec: b626dd10a18ffdaa4f7bcdf0c6890f92ff9f446c + FBLazyVector: d9c30190da16f13ea1ff3d9324dcd1fe1a9e4d4b + FBReactNativeSpec: 2e4cef565c6edc250e5dde587263ef39c6c9f88d Firebase: 458d109512200d1aca2e1b9b6cf7d68a869a4a46 FirebaseAnalytics: 45f36d9c429fc91d206283900ab75390cd05ee8a FirebaseAnalyticsInterop: d48b6ab67bcf016a05e55b71fc39c61c0cb6b7f3 @@ -690,15 +688,15 @@ SPEC CHECKSUMS: libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd Protobuf: dd1aaea7140debfe4dd0683fb8ef208e527ae153 - RCTRequired: 561f5b708210ca4a99e2df35eb5629839b8c8242 - RCTTypeSafety: 70200f5965c928ba61e01d96b528cd5ebb75e082 - React: 60e9a38634da81ad52e95e9f30857aa361da41cb - React-Core: 829d02e3d1051c5e036fb44f3e151399befeee1b - React-CoreModules: 258b84d06552a8ee63dc1449e6c3ed57e71f3548 - React-cxxreact: cc51b184d54afb2b5adbe7ee90366ab993948622 - React-jsi: 7517de4f497e79cba35956eb1a1d62e9283679a3 - React-jsiexecutor: 4afd0635fa05afb028cb0b7553f87c45dd19b432 - React-jsinspector: 3ea921e5d1b541fc0f6db9817da3d8b2e3f6bf95 + RCTRequired: e9cece38ac12ef73f95098aacb4c9477d88b58d6 + RCTTypeSafety: c00f94ca04462d6670a8333595691b634740669b + React: 7dd49950772f2c5d0bfb107e0b2079936d3f9682 + React-Core: 11cbdd3f1982d5229b9d4fbe342993c403afd619 + React-CoreModules: 543c0247210e83fc0ef65b86344cedf4a14da049 + React-cxxreact: 8194443ac133545b0c1933a4076b7f2366f3aece + React-jsi: f97b3ef8eb78e320d7a79f531adc9cc7c39194c2 + React-jsiexecutor: a3558d5053317b6fdf5a52d6ab5c4b80d8f8ed53 + React-jsinspector: 4ea920069d9ea95871bcb144636fb6ba4f3639af react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c react-native-camera: 1ba3e7f2375a6b44ae09ce9be70268e0b225bc10 react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89 @@ -709,16 +707,16 @@ SPEC CHECKSUMS: react-native-text-input-mask: 07227297075f9653315f43b0424d596423a01736 react-native-udp: ff9d13e523f2b58e6bc5d4d32321ac60671b5dc9 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f - React-RCTActionSheet: 93eba44099c05811fde250346d56da113b94699e - React-RCTAnimation: 3d6d5dd3a92ce802b29b4997c8bd3ab47786e673 - React-RCTBlob: 2de18ddb285a4707f3c418c1f410583ad41cf626 - React-RCTImage: c301b29f8520dc19cc9f179ac92f529f35249327 - React-RCTLinking: 8fb308a2ca7614a045d5179758247aaaebf29239 - React-RCTNetwork: 86aaa30f5448e7347406e19d04467ae0d438f478 - React-RCTSettings: 1a7285f69b8127d9ba4df598bbf813a19ace6835 - React-RCTText: 9529312bbe556493b65c6718a6aa3b1463745588 - React-RCTVibration: 5a96eeacad1ff1bdcb82ade1918576a55b78c061 - ReactCommon: d30c9253603ca26acdce659e95dc882a439e4852 + React-RCTActionSheet: 1c9c8f258be185eab8542ac16cbf4e2d9fe3c7d6 + React-RCTAnimation: f0fbcef774b3a265ba404103bf5c0afb15293526 + React-RCTBlob: 99abe09fb7887572ca3473b016750a56c8277f0c + React-RCTImage: 86a2b0d282dd46cf6c9b6e65567b0cb1f5d7ec69 + React-RCTLinking: 87bef2d27131eb60d3608d9bb6ace61b699aa9ae + React-RCTNetwork: 95ca86d6d46e2162aa957c58cc5d30f48a1c2a36 + React-RCTSettings: fd36d53fbdd61d74eb3b0b8f57c5804bec5b68db + React-RCTText: 46b8f9a64ab6d979567edbd51219162b85381e67 + React-RCTVibration: 1a9cfd9844cd91aa1269a22b10a9ee29cf6cf5ce + ReactCommon: d796609fd38113c37f843f813d3268909bd44a60 ReactNativePermissions: 7cfad56d13c8961cd2a1005b4955b1400c79ef3e RNAnalytics: 35a54cb740c472a0a6a3de765176b82cccc2d1ef RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f @@ -747,7 +745,7 @@ SPEC CHECKSUMS: SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 ToolTipMenu: 8ac61aded0fbc4acfe7e84a7d0c9479d15a9a382 - Yoga: 17cd3cd362cd60353073e818ef23e27ce0339bb5 + Yoga: bd064893d7d42e83f9f9e2861346fc4b1019223a PODFILE CHECKSUM: e38b8f3a80d4f969b2bd4796967957156faf7531 diff --git a/package.json b/package.json index a262f2c2fe1..9e4b276ac12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Rainbow", - "version": "1.2.2-4", + "version": "1.2.3-1", "private": true, "scripts": { "android": "react-native run-android", diff --git a/yarn.lock b/yarn.lock index 6dba54f6c03..2e0fd043868 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8936,10 +8936,10 @@ rc@^1.0.1, rc@^1.1.6: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-coin-icon@0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.13.tgz#0eb148637a7714f3b74a493b71de0bba34353634" - integrity sha512-j+6r6EcXbTbdlpJCf8DvBAvl44mXXFCdrNh5Bj9P3y4KON2brMXpNrkrN1ixrx7y87F+n55K++DERoM3XqdbJg== +react-coin-icon@0.1.14: + version "0.1.14" + resolved "https://registry.yarnpkg.com/react-coin-icon/-/react-coin-icon-0.1.14.tgz#4d919b2d60f40405bf48fd86b6b02278e7d8bbb8" + integrity sha512-UkBGfEHRJBMkoEXLnALbiD/KBBmrTTPvz2VAAvBDr2LAwDN7Izj1Yy0vXvLLBBuzznjulH1NRWMWC5b5yViRpg== dependencies: "@svgr/cli" "^4.3.0" lodash "^4.17.11" @@ -9275,25 +9275,24 @@ react-native@facebook/react-native: resolved "https://codeload.github.com/facebook/react-native/tar.gz/bd0c37e456392090507f227b8fb90c1eb7c3d327" dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0" - "@react-native-community/cli-platform-android" "^3.0.0" - "@react-native-community/cli-platform-ios" "^3.0.0" + "@react-native-community/cli" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-android" "^3.0.0-alpha.1" + "@react-native-community/cli-platform-ios" "^3.0.0-alpha.1" abort-controller "^3.0.0" - anser "^1.4.9" base64-js "^1.1.2" connect "^3.6.5" create-react-class "^15.6.3" escape-string-regexp "^1.0.5" - eslint-plugin-relay "1.4.1" + eslint-plugin-relay "1.3.12" event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermes-engine "~0.3.0" + hermes-engine "^0.2.1" invariant "^2.2.4" jsc-android "^245459.0.0" - metro-babel-register "0.57.0" - metro-react-native-babel-transformer "0.57.0" - metro-source-map "0.57.0" + metro-babel-register "0.56.3" + metro-react-native-babel-transformer "0.56.3" + metro-source-map "0.56.3" nullthrows "^1.1.1" pretty-format "^24.7.0" promise "^7.1.1" @@ -9301,7 +9300,7 @@ react-native@facebook/react-native: react-devtools-core "^4.0.6" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.17.0" + scheduler "0.16.2" stacktrace-parser "^0.1.3" use-subscription "^1.0.0" whatwg-fetch "^3.0.0"