Merge branch 'master' of github.com:esteemapp/esteem-mobile into bugfix/login

This commit is contained in:
Mustafa Buyukcelebi 2019-08-13 11:41:45 +03:00
commit cf4077dec1
23 changed files with 429 additions and 242 deletions

View File

@ -43,7 +43,7 @@
"lodash": "^4.17.13",
"moment": "^2.22.2",
"react": "16.8.3",
"react-intl": "^2.7.2",
"react-intl": "^3.1.6",
"react-native": "0.59.8",
"react-native-actionsheet": "^2.4.2",
"react-native-autocomplete-input": "^4.1.0",

View File

@ -150,7 +150,6 @@ class BasicHeaderView extends Component {
{rightIconName && !isHasSearch && (
<IconButton
style={styles.rightIcon}
size={25}
onPress={() => handleRightIconPress()}
iconStyle={styles.rightIcon}
@ -173,7 +172,6 @@ class BasicHeaderView extends Component {
{isHasSearch && (
<IconButton
style={styles.rightIcon}
size={22}
onPress={() => this._handleSearchButtonPress()}
iconStyle={styles.rightIcon}

View File

@ -51,9 +51,11 @@ class CommentsContainer extends Component {
// Component Functions
_shortComments = sortOrder => {
_shortComments = (sortOrder, comments) => {
const { comments: parent } = this.state;
const sortedComments = comments || parent;
const allPayout = c =>
parseFloat(get(c, 'pending_payout_value').split(' ')[0]) +
parseFloat(get(c, 'total_payout_value').split(' ')[0]) +
@ -116,23 +118,31 @@ class CommentsContainer extends Component {
},
};
parent.sort(sortOrders[sortOrder]);
sortedComments.sort(sortOrders[sortOrder]);
return parent;
return sortedComments;
};
_getComments = async () => {
const {
author,
permlink,
selectedFilter,
currentAccount: { name },
} = this.props;
await getComments(author, permlink, name)
.then(comments => {
if (selectedFilter && selectedFilter !== 'TRENDING') {
const sortComments = this._shortComments(selectedFilter, comments);
this.setState({
comments: sortComments,
});
} else {
this.setState({
comments,
});
}
})
.catch(() => {});
};

View File

@ -69,6 +69,18 @@ class PostCardContainer extends PureComponent {
});
};
_handleOnReblogsPress = reblogs => {
const { navigation, content } = this.props;
navigation.navigate({
routeName: ROUTES.SCREENS.REBLOGS,
params: {
reblogs,
},
key: content.permlink,
});
};
_fetchPost = async () => {
const { currentAccount, content } = this.props;
@ -92,6 +104,7 @@ class PostCardContainer extends PureComponent {
handleOnUserPress={this._handleOnUserPress}
handleOnContentPress={this._handleOnContentPress}
handleOnVotersPress={this._handleOnVotersPress}
handleOnReblogsPress={this._handleOnReblogsPress}
fetchPost={this._fetchPost}
content={_content || content}
isHideImage={isHideImage}

View File

@ -66,7 +66,15 @@ class PostCardView extends Component {
_handleOnVotersPress = () => {
const { handleOnVotersPress, content } = this.props;
handleOnVotersPress(content.active_votes);
handleOnVotersPress(get(content, 'active_votes'));
};
_handleOnReblogsPress = () => {
const { handleOnReblogsPress, content } = this.props;
if (content.reblogs.length > 0) {
handleOnReblogsPress(get(content, 'reblogs'));
}
};
_getPostImage = (content, isNsfwPost) => {
@ -135,6 +143,7 @@ class PostCardView extends Component {
iconType="MaterialIcons"
isClickable
text={get(content, 'vote_count', 0)}
onPress={this._handleOnVotersPress}
/>
</TouchableOpacity>
</View>
@ -145,6 +154,7 @@ class PostCardView extends Component {
iconType="MaterialIcons"
isClickable
text={get(content, 'reblogCount', 0)}
onPress={this._handleOnReblogsPress}
/>
<TextWithIcon
iconName="comment"

View File

@ -47,10 +47,24 @@ class PostDisplayContainer extends Component {
activeVotes,
},
// TODO: make unic
key: post.permlink + Math.random(),
key: post.permlink + activeVotes.length,
});
};
_handleOnReblogsPress = reblogs => {
const { navigation, post } = this.props;
if (reblogs.length > 0) {
navigation.navigate({
routeName: ROUTES.SCREENS.REBLOGS,
params: {
reblogs,
},
key: post.permlink + reblogs.length,
});
}
};
_handleOnReplyPress = () => {
const { post, navigation } = this.props;
@ -123,6 +137,7 @@ class PostDisplayContainer extends Component {
handleOnRemovePress={this._handleDeleteComment}
handleOnReplyPress={this._handleOnReplyPress}
handleOnVotersPress={this._handleOnVotersPress}
handleOnReblogsPress={this._handleOnReblogsPress}
isLoggedIn={isLoggedIn}
isNewPost={isNewPost}
isPostUnavailable={isPostUnavailable}

View File

@ -71,6 +71,7 @@ class PostDisplayView extends PureComponent {
handleOnEditPress,
handleOnReplyPress,
handleOnVotersPress,
handleOnReblogsPress,
isLoggedIn,
post,
} = this.props;
@ -101,6 +102,7 @@ class PostDisplayView extends PureComponent {
iconStyle={styles.barIcons}
iconType="MaterialIcons"
isClickable
onPress={() => handleOnReblogsPress && handleOnReblogsPress(get(post, 'reblogs'))}
text={get(post, 'reblogCount', 0)}
textMarginLeft={20}
/>

View File

@ -53,6 +53,10 @@ class PostsContainer extends PureComponent {
pageType,
selectedOptionIndex,
tag,
isLoginDone,
isLoggedIn,
isDarkTheme,
nsfw,
} = this.props;
const { promotedPosts } = this.state;
@ -74,6 +78,10 @@ class PostsContainer extends PureComponent {
selectedOptionIndex={selectedOptionIndex}
setFeedPosts={this._setFeedPosts}
tag={tag}
isLoginDone={isLoginDone}
isLoggedIn={isLoggedIn}
isDarkTheme={isDarkTheme}
nsfw={nsfw}
/>
);
}

View File

@ -364,12 +364,7 @@ class PostsView extends Component {
initialNumToRender={10}
ListFooterComponent={this._renderFooter}
onScroll={this._handleOnScroll}
ListEmptyComponent={
<Fragment>
<PostCardPlaceHolder />
<PostCardPlaceHolder />
</Fragment>
}
ListEmptyComponent={this._renderEmptyContent}
refreshControl={
<RefreshControl
refreshing={refreshing}

View File

@ -326,5 +326,13 @@
},
"boostPost": {
"title": "Boost"
},
"voters_dropdown": {
"rewards": "REWARDS",
"percent": "PERCENT",
"time": "TIME"
},
"reblog": {
"title": "Reblog Info"
}
}

View File

@ -23,6 +23,7 @@ export default {
BOOST_POST: `BoostPost${SCREEN_SUFFIX}`,
PROMOTE: `Promote${SCREEN_SUFFIX}`,
FREE_ESTM: `FreeEstm${SCREEN_SUFFIX}`,
REBLOGS: `Reblogs${SCREEN_SUFFIX}`,
},
DRAWER: {
MAIN: `Main${DRAWER_SUFFIX}`,

View File

@ -0,0 +1,88 @@
import { PureComponent } from 'react';
import { isBefore } from '../utils/time';
import ROUTES from '../constants/routeNames';
class AccountListContainer extends PureComponent {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
this.state = {
data: props.data,
filterResult: null,
};
}
// Component Life Cycles
// Component Functions
_handleSearch = (searchText, key) => {
const { data } = this.state;
const newData = data.filter(item => {
const itemName = item[key].toUpperCase();
const _text = searchText.toUpperCase();
return itemName.indexOf(_text) > -1;
});
this.setState({ filterResult: newData });
};
_handleOnVotersDropdownSelect = index => {
const { data } = this.state;
const _data = data;
switch (index) {
case '0':
_data.sort((a, b) => Number(b.value) - Number(a.value));
break;
case '1':
_data.sort((a, b) => b.percent - a.percent);
break;
case '2':
_data.sort((a, b) => (isBefore(a.time, b.time) ? 1 : -1));
break;
default:
break;
}
this.setState({ filterResult: _data });
};
_handleOnUserPress = username => {
const { navigation } = this.props;
navigation.navigate({
routeName: ROUTES.SCREENS.PROFILE,
params: {
username,
},
key: username,
});
};
render() {
const { data, filterResult } = this.state;
const { children } = this.props;
return (
children &&
children({
data,
filterResult,
handleOnVotersDropdownSelect: this._handleOnVotersDropdownSelect,
handleSearch: this._handleSearch,
handleOnUserPress: this._handleOnUserPress,
})
);
}
}
export default AccountListContainer;

View File

@ -1,19 +1,7 @@
import React from 'react';
import { Provider, connect } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { IntlProvider, addLocaleData } from 'react-intl';
import en from 'react-intl/locale-data/en';
import id from 'react-intl/locale-data/id';
import ru from 'react-intl/locale-data/ru';
import de from 'react-intl/locale-data/de';
import it from 'react-intl/locale-data/it';
import hu from 'react-intl/locale-data/hu';
import tr from 'react-intl/locale-data/tr';
import ko from 'react-intl/locale-data/ko';
import lt from 'react-intl/locale-data/lt';
import pt from 'react-intl/locale-data/pt';
import fa from 'react-intl/locale-data/fa';
import { IntlProvider } from 'react-intl';
import { flattenMessages } from './utils/flattenMessages';
import messages from './config/locales';
@ -21,8 +9,6 @@ import messages from './config/locales';
import Application from './screens/application';
import { store, persistor } from './redux/store/store';
addLocaleData([...en, ...ru, ...de, ...id, ...it, ...hu, ...tr, ...ko, ...pt, ...lt, ...fa]);
const _renderApp = ({ locale }) => (
<PersistGate loading={null} persistor={persistor}>
<IntlProvider locale={locale} messages={flattenMessages(messages[locale])}>

View File

@ -24,6 +24,7 @@ import {
Boost,
Promote,
BoostPost,
Reblogs,
} from '../screens';
// Components
@ -126,6 +127,12 @@ const stackNavigatior = createStackNavigator(
header: () => null,
},
},
[ROUTES.SCREENS.REBLOGS]: {
screen: Reblogs,
navigationOptions: {
header: () => null,
},
},
},
{
headerMode: 'none',

View File

@ -67,6 +67,14 @@ import { encryptKey } from '../../../utils/crypto';
import darkTheme from '../../../themes/darkTheme';
import lightTheme from '../../../themes/lightTheme';
// Workaround
let previousAppState = 'background';
export const setPreviousAppState = () => {
setTimeout(() => {
previousAppState = AppState.currentState;
}, 2000);
};
class ApplicationContainer extends Component {
constructor(props) {
super(props);
@ -98,6 +106,7 @@ class ApplicationContainer extends Component {
});
AppState.addEventListener('change', this._handleAppStateChange);
setPreviousAppState();
this._createPushListener();
};
@ -268,7 +277,7 @@ class ApplicationContainer extends Component {
}
}
});
setPreviousAppState();
this.setState({ appState: nextAppState });
};
@ -303,6 +312,7 @@ class ApplicationContainer extends Component {
Push.setListener({
onPushNotificationReceived(pushNotification) {
if (previousAppState !== 'active') {
const push = get(pushNotification, 'customProperties');
const type = get(push, 'type', '');
const permlink1 = get(push, 'permlink1', '');
@ -318,6 +328,13 @@ class ApplicationContainer extends Component {
switch (type) {
case 'vote':
case 'unvote':
params = {
author: get(push, 'target', ''),
permlink: fullPermlink,
};
key = fullPermlink;
routeName = ROUTES.SCREENS.POST;
break;
case 'mention':
params = {
author: get(push, 'source', ''),
@ -372,6 +389,7 @@ class ApplicationContainer extends Component {
action: NavigationActions.navigate({ routeName }),
});
dispatch(navigateAction);
}
},
});
};

View File

@ -13,11 +13,12 @@ import { Post } from './post';
import { Profile } from './profile';
import { SearchResult } from './searchResult';
import { Settings } from './settings';
import { Voters } from './voters';
import Voters from './voters';
import BoostPost from './boostPost/screen/boostPostScreen';
import Promote from './promote/screen/promoteScreen';
import SteemConnect from './steem-connect/steemConnect';
import Transfer from './transfer';
import Reblogs from './reblogs';
export {
Bookmarks,
@ -40,4 +41,5 @@ export {
SteemConnect,
Transfer,
Voters,
Reblogs,
};

View File

@ -0,0 +1 @@
export { default } from './screen/reblogScreen';

View File

@ -0,0 +1,59 @@
import React from 'react';
import { View, FlatList } from 'react-native';
import { useIntl } from 'react-intl';
// Constants
// Components
import { BasicHeader } from '../../../components/basicHeader';
import { UserListItem } from '../../../components/basicUIElements';
import AccountListContainer from '../../../containers/accountListContainer';
// Utils
import globalStyles from '../../../globalStyles';
import { getTimeFromNow } from '../../../utils/time';
const renderUserListItem = (item, index, handleOnUserPress) => {
return (
<UserListItem
index={index}
username={item.account}
description={getTimeFromNow(item.timestamp)}
handleOnPress={() => handleOnUserPress(item.account)}
isClickable
/>
);
};
const ReblogScreen = ({ navigation }) => {
const intl = useIntl();
const headerTitle = intl.formatMessage({
id: 'reblog.title',
});
const activeVotes =
navigation.state && navigation.state.params && navigation.state.params.reblogs;
return (
<AccountListContainer data={activeVotes} navigation={navigation}>
{({ data, filterResult, handleSearch, handleOnUserPress }) => (
<View style={globalStyles.container}>
<BasicHeader
title={`${headerTitle} (${data && data.length})`}
isHasSearch
handleOnSearch={text => handleSearch(text, 'account')}
/>
<FlatList
data={filterResult || data}
keyExtractor={item => item.account}
removeClippedSubviews={false}
renderItem={({ item, index }) => renderUserListItem(item, index, handleOnUserPress)}
/>
</View>
)}
</AccountListContainer>
);
};
export default ReblogScreen;

View File

@ -1,31 +0,0 @@
import React, { PureComponent } from 'react';
// Component
import VotersScreen from '../screen/votersScreen';
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class VotersContainer extends PureComponent {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycle Functions
// Component Functions
render() {
const { navigation } = this.props;
const activeVotes =
navigation.state && navigation.state.params && navigation.state.params.activeVotes;
return <VotersScreen votes={activeVotes} {...this.props} />;
}
}
export default VotersContainer;

View File

@ -1,5 +1,4 @@
import VotersScreen from './screen/votersScreen';
import Voters from './container/votersContainer';
export { Voters, VotersScreen };
export default Voters;
export { VotersScreen };
export default VotersScreen;

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import React from 'react';
import { View } from 'react-native';
import { injectIntl } from 'react-intl';
import { useIntl } from 'react-intl';
// Constants
@ -9,90 +9,46 @@ import { BasicHeader } from '../../../components/basicHeader';
import { FilterBar } from '../../../components/filterBar';
import { VotersDisplay } from '../../../components/votersDisplay';
import AccountListContainer from '../../../containers/accountListContainer';
// Utils
import { isBefore } from '../../../utils/time';
import globalStyles from '../../../globalStyles';
class VotersScreen extends PureComponent {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
const filterOptions = ['rewards', 'percent', 'time'];
constructor(props) {
super(props);
this.state = {
data: props.votes,
filterResult: null,
isRenderRequire: false,
};
}
// Component Life Cycles
// Component Functions
_handleOnDropdownSelect = index => {
const { data } = this.state;
const _data = data;
switch (index) {
case '0':
_data.sort((a, b) => Number(b.value) - Number(a.value));
break;
case '1':
_data.sort((a, b) => b.percent - a.percent);
break;
case '2':
_data.sort((a, b) => (isBefore(a.time, b.time) ? 1 : -1));
break;
default:
break;
}
this.setState({ filterResult: _data, isRenderRequire: true }, () =>
this.setState({ isRenderRequire: false }),
);
};
_handleRightIconPress = () => {};
_handleSearch = text => {
const { data } = this.state;
const newData = data.filter(item => {
const itemName = item.voter.toUpperCase();
const _text = text.toUpperCase();
return itemName.indexOf(_text) > -1;
});
this.setState({ filterResult: newData });
};
render() {
const { data, filterResult, isRenderRequire } = this.state;
const { intl } = this.props;
const VotersScreen = ({ navigation }) => {
const intl = useIntl();
const headerTitle = intl.formatMessage({
id: 'voters.voters_info',
});
const activeVotes =
navigation.state && navigation.state.params && navigation.state.params.activeVotes;
return (
<AccountListContainer data={activeVotes}>
{({ data, filterResult, handleOnVotersDropdownSelect, handleSearch }) => (
<View style={globalStyles.container}>
<BasicHeader
title={`${headerTitle} (${data && data.length})`}
isHasSearch
handleOnSearch={this._handleSearch}
handleOnSearch={text => handleSearch(text, 'voter')}
/>
<FilterBar
dropdownIconName="arrow-drop-down"
options={['REWARDS', 'PERCENT', 'TIME']}
defaultText="REWARDS"
onDropdownSelect={this._handleOnDropdownSelect}
options={filterOptions.map(item =>
intl.formatMessage({
id: `voters_dropdown.${item}`,
}),
)}
defaultText={intl.formatMessage({ id: `voters_dropdown.${filterOptions[0]}` })}
onDropdownSelect={handleOnVotersDropdownSelect}
/>
{!isRenderRequire && <VotersDisplay key={Math.random()} votes={filterResult || data} />}
<VotersDisplay votes={filterResult || data} />
</View>
)}
</AccountListContainer>
);
}
}
};
export default injectIntl(VotersScreen);
export default VotersScreen;

View File

@ -67,8 +67,8 @@ export const parsePost = async (post, currentUserName, isPromoted) => {
});
}
const postReblogs = await getPostReblogs(post);
post.reblogCount = postReblogs.length;
post.reblogs = await getPostReblogs(post);
post.reblogCount = get(post, 'reblogs', []).length;
return post;
};

100
yarn.lock
View File

@ -1110,6 +1110,11 @@
url "^0.11.0"
xmldom "^0.1.27"
"@formatjs/intl-relativetimeformat@^2.6.2":
version "2.6.2"
resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-2.6.2.tgz#0429e9b3bdaef8907223b1f01cee78f07b229ac9"
integrity sha512-JD6O2yCF2NuefU3+R7va6WmeetvajWO/ab0s4xjGpxnIMu6p9dtjTQfAhW2+NG+4Dc8MYKYo1wbJ8j02mZ1stw==
"@jest/console@^24.7.1":
version "24.7.1"
resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545"
@ -1346,6 +1351,19 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/hoist-non-react-statics@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/invariant@^2.2.30":
version "2.2.30"
resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.30.tgz#20efa342807606ada5483731a8137cb1561e5fe9"
integrity sha512-98fB+yo7imSD2F7PF7GIpELNgtLNgo5wjivu0W5V4jx+KVVJxo6p/qN4zdzSTBWy4/sN3pPyXwnhRSD28QX+ag==
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
@ -1371,11 +1389,19 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.49.tgz#f331afc5efed0796798e5591d6e0ece636969b7b"
integrity sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w==
"@types/prop-types@^15.5.5":
"@types/prop-types@*", "@types/prop-types@^15.5.5":
version "15.7.1"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==
"@types/react@*", "@types/react@^16.0.0":
version "16.9.1"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.1.tgz#862c83b4c9d5cd116e42fd9a4f3694843cd2c051"
integrity sha512-jGM2x8F7m7/r+81N/BOaUKVwbC5Cdw6ExlWEUpr77XPwVeNvAppnPEnMMLMfxRDYL8FPEX8MHjwtD2NQMJ0yyQ==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"
"@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"
@ -2736,6 +2762,11 @@ cssstyle@^1.0.0:
dependencies:
cssom "0.3.x"
csstype@^2.2.0:
version "2.6.6"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41"
integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==
currency-symbol-map@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/currency-symbol-map/-/currency-symbol-map-4.0.4.tgz#3cfba625974dd3f86822d327ecbd10248695e95e"
@ -4654,29 +4685,28 @@ inquirer@^6.2.2:
strip-ansi "^5.1.0"
through "^2.3.6"
intl-format-cache@^2.0.5:
version "2.2.9"
resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-2.2.9.tgz#fb560de20c549cda20b569cf1ffb6dc62b5b93b4"
integrity sha512-Zv/u8wRpekckv0cLkwpVdABYST4hZNTDaX7reFetrYTJwxExR2VyTqQm+l0WmL0Qo8Mjb9Tf33qnfj0T7pjxdQ==
intl-format-cache@^4.1.9:
version "4.1.9"
resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-4.1.9.tgz#16108dbde7c13013f02411bf7bdeb82c3dc17991"
integrity sha512-DoXRZJ7JtQsgGQDlaRkqn6KfW8B/ivBsQ17JB1kt78qHfojRIpnpbA66Ahgaj/kS5v/+gl83rLlnwdXrFY2LCw==
intl-messageformat-parser@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU=
intl-locales-supported@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/intl-locales-supported/-/intl-locales-supported-1.4.4.tgz#0f2320f295de1a217de4037ede5a5f3a3ebc2320"
integrity sha512-dm8tjMFfy6Y+MStEBqzslnV0LTmoEAOGSnZchlKcuyOd9LlxKT8MKLOhq0KqGSRPvWfDRTs94UYTvESw5d+YYA==
intl-messageformat@^2.0.0, intl-messageformat@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc"
integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=
intl-messageformat-parser@^3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-3.0.6.tgz#668ffb4ff19a6bde073244c66c202fe70047aa97"
integrity sha512-2giAavgG1JSJooXyB0wTotuKBqk8lVz7y8ZdtR+WPlfVZv88TyIuZ85ES89cuF30H68UFqkSswpDXmwCh8X+ig==
intl-messageformat@^6.1.3:
version "6.1.3"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-6.1.3.tgz#7ff13cfcf3a7919db6d95f4d58de8f717df0e214"
integrity sha512-zz2OqVRVaAjdxm1eB+YPZrlejEFxYkZXU89phvlTijKZzceAF5FtosSXgi1mMUvfFbqe2EsTI3oNW2tnoKVtcQ==
dependencies:
intl-messageformat-parser "1.4.0"
intl-relativeformat@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.2.0.tgz#6aca95d019ec8d30b6c5653b6629f9983ea5b6c5"
integrity sha512-4bV/7kSKaPEmu6ArxXf9xjv1ny74Zkwuey8Pm01NH4zggPP7JHwg2STk8Y3JdspCKRDriwIyLRfEXnj2ZLr4Bw==
dependencies:
intl-messageformat "^2.0.0"
intl-format-cache "^4.1.9"
intl-messageformat-parser "^3.0.6"
intl@^1.2.5:
version "1.2.5"
@ -7581,16 +7611,23 @@ react-devtools-core@^3.6.0:
shell-quote "^1.6.1"
ws "^3.3.1"
react-intl@^2.7.2:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.9.0.tgz#c97c5d17d4718f1575fdbd5a769f96018a3b1843"
integrity sha512-27jnDlb/d2A7mSJwrbOBnUgD+rPep+abmoJE511Tf8BnoONIAUehy/U1zZCHGO17mnOwMWxqN4qC0nW11cD6rA==
react-intl@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-3.1.6.tgz#e41b9fba7bd26c9c83fdae81fb599ac3fdd1c819"
integrity sha512-SAqHT9ZI78kwvCaDT8jyCAaPxqheZhRI0vzisIXVGEzzxDXQbxG+2aWWUZvWEHnkCZNwLDr+uK2vLwgeXzLbbw==
dependencies:
"@formatjs/intl-relativetimeformat" "^2.6.2"
"@types/hoist-non-react-statics" "^3.3.1"
"@types/invariant" "^2.2.30"
"@types/react" "^16.0.0"
hoist-non-react-statics "^3.3.0"
intl-format-cache "^2.0.5"
intl-messageformat "^2.1.0"
intl-relativeformat "^2.1.0"
intl-format-cache "^4.1.9"
intl-locales-supported "^1.4.4"
intl-messageformat "^6.1.3"
intl-messageformat-parser "^3.0.6"
invariant "^2.1.1"
react "^16.3.0"
shallow-equal "^1.1.0"
react-is@^16.5.2, 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:
version "16.8.6"
@ -7974,7 +8011,7 @@ react-transform-hmr@^1.0.4:
global "^4.3.0"
react-proxy "^1.1.7"
react@16.8.3:
react@16.8.3, react@^16.3.0:
version "16.8.3"
resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9"
integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA==
@ -8629,6 +8666,11 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1"
safe-buffer "^5.0.1"
shallow-equal@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.0.tgz#fd828d2029ff4e19569db7e19e535e94e2d1f5cc"
integrity sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"