diff --git a/src/components/basicUIElements/index.js b/src/components/basicUIElements/index.js index 24e7d4c93..f4ff21f63 100644 --- a/src/components/basicUIElements/index.js +++ b/src/components/basicUIElements/index.js @@ -18,6 +18,7 @@ import ProfileSummaryPlaceHolder from './view/placeHolder/profileSummaryPlaceHol import WalletDetailsPlaceHolder from './view/placeHolder/walletDetailsPlaceHolder'; import WalletUnclaimedPlaceHolder from './view/placeHolder/walletUnclaimedPlaceHolder'; import ListPlaceHolder from './view/placeHolder/listPlaceHolderView'; +import BoostPlaceHolder from './view/placeHolder/boostPlaceHolderView'; export { Card, @@ -26,6 +27,7 @@ export { LineBreak, ListItemPlaceHolder, ListPlaceHolder, + BoostPlaceHolder, NoInternetConnection, NoPost, PostCardPlaceHolder, diff --git a/src/components/basicUIElements/view/placeHolder/boostPlaceHolderStyles.js b/src/components/basicUIElements/view/placeHolder/boostPlaceHolderStyles.js new file mode 100644 index 000000000..ff16b2cfb --- /dev/null +++ b/src/components/basicUIElements/view/placeHolder/boostPlaceHolderStyles.js @@ -0,0 +1,24 @@ +import EStyleSheet from 'react-native-extended-stylesheet'; + +export default EStyleSheet.create({ + container: { + backgroundColor: '$primaryBackgroundColor', + borderColor: '$primaryLightBackground', + marginRight: 0, + marginLeft: 0, + flexDirection: 'column', + }, + paragraphWrapper: { + marginLeft: 30, + }, + line: { + flexDirection: 'row', + marginVertical: 10, + alignContent: 'center', + alignItems: 'center', + justifyContent: 'space-between', + }, + rightBox: { + marginRight: 20, + }, +}); diff --git a/src/components/basicUIElements/view/placeHolder/boostPlaceHolderView.js b/src/components/basicUIElements/view/placeHolder/boostPlaceHolderView.js new file mode 100644 index 000000000..44811e494 --- /dev/null +++ b/src/components/basicUIElements/view/placeHolder/boostPlaceHolderView.js @@ -0,0 +1,44 @@ +/* eslint-disable radix */ +import React from 'react'; +import { connect } from 'react-redux'; +import { Dimensions, View } from 'react-native'; +import times from 'lodash/times'; +import Placeholder from 'rn-placeholder'; + +import styles from './boostPlaceHolderStyles'; + +const HEIGHT = Dimensions.get('window').height; + +const BoostPlaceHolder = ({ isDarkTheme }) => { + const color = isDarkTheme ? '#2e3d51' : '#f5f5f5'; + const ratio = (HEIGHT - 300) / 50 / 1.3; + const listElements = []; + + times(parseInt(ratio), i => { + listElements.push( + + + + + + + + + , + ); + }); + + return {listElements}; +}; + +const mapStateToProps = state => ({ + isDarkTheme: state.application.isDarkTheme, +}); + +export default connect(mapStateToProps)(BoostPlaceHolder); diff --git a/src/constants/routeNames.js b/src/constants/routeNames.js index d2e1bd400..e97ae65c7 100644 --- a/src/constants/routeNames.js +++ b/src/constants/routeNames.js @@ -22,6 +22,7 @@ export default { BOOST: `Boost${SCREEN_SUFFIX}`, BOOST_POST: `BoostPost${SCREEN_SUFFIX}`, PROMOTE: `Promote${SCREEN_SUFFIX}`, + FREE_ESTM: `FreeEstm${SCREEN_SUFFIX}`, }, DRAWER: { MAIN: `Main${DRAWER_SUFFIX}`, diff --git a/src/screens/boost/container/boostContainer.js b/src/screens/boost/container/boostContainer.js index a1410e3ba..bf47e7ad1 100644 --- a/src/screens/boost/container/boostContainer.js +++ b/src/screens/boost/container/boostContainer.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { Platform, Alert } from 'react-native'; +import { withNavigation } from 'react-navigation'; import RNIap, { purchaseErrorListener, purchaseUpdatedListener } from 'react-native-iap'; import { injectIntl } from 'react-intl'; @@ -9,6 +10,7 @@ import { purchaseOrder } from '../../../providers/esteem/esteem'; import bugsnag from '../../../config/bugsnag'; // Utilities +import { default as ROUTES } from '../../../constants/routeNames'; // Component import BoostScreen from '../screen/boostScreen'; @@ -23,6 +25,8 @@ class BoostContainer extends Component { super(props); this.state = { productList: [], + isLoading: true, + isProccesing: false, }; } @@ -80,6 +84,7 @@ class BoostContainer extends Component { this.purchaseErrorSubscription = purchaseErrorListener(error => { Alert.alert('Warning', error); + bugsnag.notify(error); }); }; @@ -87,28 +92,57 @@ class BoostContainer extends Component { try { const products = await RNIap.getProducts(ITEM_SKUS); products.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)).reverse(); - this.setState({ productList: products }); + await this.setState({ productList: products }); } catch (err) { bugsnag.notify(err); + Alert.alert( + `Fetching data from server failed, please try again or notify us at info@esteem.app \n${err.message.substr( + 0, + 20, + )}`, + ); } + + await this.setState({ isLoading: false }); }; _buyItem = async sku => { - try { - RNIap.requestPurchase(sku, false); - } catch (err) { - bugsnag.notify(err, report => { - report.metadata = { - sku, - }; + const { navigation } = this.props; + + await this.setState({ isProccesing: true }); + + if (sku !== 'freePoints') { + try { + await RNIap.requestPurchase(sku, false); + } catch (err) { + bugsnag.notify(err, report => { + report.metadata = { + sku, + }; + }); + } + } else { + navigation.navigate({ + routeName: ROUTES.SCREENS.FREE_ESTM, }); } + + this.setState({ isProccesing: false }); }; render() { - const { productList } = this.state; + const { productList, isLoading, isProccesing } = this.state; + // const FREE_ESTM = { productId: 'freePoints', title: 'free estm' }; - return ; + return ( + + ); } } @@ -116,4 +150,4 @@ const mapStateToProps = state => ({ currentAccount: state.account.currentAccount, }); -export default injectIntl(connect(mapStateToProps)(BoostContainer)); +export default withNavigation(injectIntl(connect(mapStateToProps)(BoostContainer))); diff --git a/src/screens/boost/screen/boostScreen.js b/src/screens/boost/screen/boostScreen.js index 0556951bf..4ae4dd452 100644 --- a/src/screens/boost/screen/boostScreen.js +++ b/src/screens/boost/screen/boostScreen.js @@ -7,6 +7,7 @@ import get from 'lodash/get'; import { BasicHeader } from '../../../components/basicHeader'; import { MainButton } from '../../../components/mainButton'; import { Icon } from '../../../components/icon'; +import { BoostPlaceHolder } from '../../../components/basicUIElements'; // Styles import globalStyles from '../../../globalStyles'; @@ -50,7 +51,7 @@ class BoostScreen extends PureComponent { }; render() { - const { intl, buyItem, boostData } = this.props; + const { intl, buyItem, productList, isLoading, isProccesing } = this.props; const { selectedBoost } = this.state; return ( @@ -61,34 +62,40 @@ class BoostScreen extends PureComponent { })} /> - {boostData.map(item => ( - - {this._renderDeal(item)} - - buyItem(item.productId)} - height={50} - text={intl.formatMessage({ - id: 'boost.buy', - })} - isDisable={false} - isLoading={false} - > - - {this._getTitle(get(item, 'title'))} - - + {isLoading ? ( + + ) : ( + productList.map(item => ( + + {this._renderDeal(item)} + + buyItem(item.productId)} + height={50} + text={intl.formatMessage({ + id: 'boost.buy', + })} + isDisable={isProccesing} + isLoading={false} + > + + {get(item, 'title', '').toUpperCase()} + + + - - - + + - - {get(item, 'localizedPrice', 0)} + + {get(item, 'localizedPrice', null) && ( + {get(item, 'localizedPrice', 0)} + )} + - - ))} + )) + )} ); }