created spin game components move to comp for product line

This commit is contained in:
ue 2019-10-05 17:57:07 +03:00
parent bbe32e051e
commit 476b337e0f
14 changed files with 236 additions and 236 deletions

View File

@ -50,6 +50,7 @@ import Logo from './logo/logo';
import PostButton from './postButton/postButtonView'; import PostButton from './postButton/postButtonView';
import ProfileEditForm from './profileEditForm/profileEditFormView'; import ProfileEditForm from './profileEditForm/profileEditFormView';
import ScaleSlider from './scaleSlider/scaleSliderView'; import ScaleSlider from './scaleSlider/scaleSliderView';
import { ProductItemLine } from './productItemLine/productItemLineView';
// View // View
import { Comment } from './comment'; import { Comment } from './comment';
@ -66,7 +67,7 @@ import { WalletDetails } from './walletDetails';
import PostBoost from './postBoost/postBoostView'; import PostBoost from './postBoost/postBoostView';
import Profile from './profile/profileView'; import Profile from './profile/profileView';
import Promote from './promote/promoteView'; import Promote from './promote/promoteView';
import SpinGame from './spinGame/spinGameView'; import { SpinGame } from './spinGame/spinGameView';
// Basic UI Elements // Basic UI Elements
import { import {
@ -147,6 +148,7 @@ export {
PostListItem, PostListItem,
PostPlaceHolder, PostPlaceHolder,
Posts, Posts,
ProductItemLine,
Profile, Profile,
ProfileEditForm, ProfileEditForm,
ProfileSummary, ProfileSummary,

View File

@ -26,7 +26,7 @@ export default EStyleSheet.create({
alignSelf: 'center', alignSelf: 'center',
fontSize: 14, fontSize: 14,
paddingLeft: 10, paddingLeft: 10,
paddingRight: 20, paddingRight: 10,
}, },
secondText: { secondText: {
fontWeight: 'bold', fontWeight: 'bold',

View File

@ -41,7 +41,9 @@ class MainButton extends Component {
_handleOnPress = () => { _handleOnPress = () => {
const { onPress } = this.props; const { onPress } = this.props;
if (onPress) onPress(); if (onPress) {
onPress();
}
}; };
_getBody = () => { _getBody = () => {
@ -57,12 +59,14 @@ class MainButton extends Component {
{source ? ( {source ? (
<Image source={source} style={styles.image} resizeMode="contain" /> <Image source={source} style={styles.image} resizeMode="contain" />
) : ( ) : (
<Icon iconName && (
iconType={iconType || 'MaterialIcons'} <Icon
color={iconColor} iconType={iconType || 'MaterialIcons'}
name={iconName} color={iconColor}
style={styles.icon} name={iconName}
/> style={styles.icon}
/>
)
)} )}
<Text style={styles.text}> <Text style={styles.text}>
{text} {text}
@ -92,7 +96,7 @@ class MainButton extends Component {
<View style={wrapperStyle}> <View style={wrapperStyle}>
<TouchableOpacity <TouchableOpacity
disabled={isLoading || isDisable} disabled={isLoading || isDisable}
onPress={() => this._handleOnPress()} onPress={this._handleOnPress}
style={[ style={[
styles.touchable, styles.touchable,
isDisable && styles.disableTouchable, isDisable && styles.disableTouchable,

View File

@ -1,10 +1,11 @@
import EStyleSheet from 'react-native-extended-stylesheet'; import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({ export default EStyleSheet.create({
wrapper: { buttonWrapper: {
minWidth: '$deviceWidth / 2.4',
flexDirection: 'row',
justifyContent: 'flex-end',
flex: 1, flex: 1,
position: 'absolute',
top: '$deviceHeight / 3',
}, },
boostLine: { boostLine: {
flexDirection: 'row', flexDirection: 'row',
@ -14,16 +15,12 @@ export default EStyleSheet.create({
button: { button: {
marginVertical: 12, marginVertical: 12,
paddingHorizontal: 18, paddingHorizontal: 18,
justifyContent: 'center',
alignItems: 'center',
}, },
buttonContent: { buttonContent: {
flexDirection: 'row', flexDirection: 'row',
}, },
buttonWrapper: {
minWidth: '$deviceWidth / 2.4',
flexDirection: 'row',
justifyContent: 'flex-end',
flex: 1,
},
buttonText: { buttonText: {
color: '$pureWhite', color: '$pureWhite',
fontSize: 14, fontSize: 14,

View File

@ -0,0 +1,59 @@
import React from 'react';
import { View, Text } from 'react-native';
import get from 'lodash/get';
import { useIntl } from 'react-intl';
// Components
import { MainButton, Icon } from '..';
import styles from './productItemLineStyles';
// TODO: move to translation
const DEALS = { '9999points': 'BEST DEAL!', '4999points': 'POPULAR!' };
const ProductItemLineView = ({ disabled, handleOnButtonPress, product, title }) => {
const intl = useIntl();
return (
<View style={styles.boostLine} key={get(product, 'productId')}>
{_renderDeal(product)}
<View style={styles.buttonWrapper}>
<MainButton
style={styles.button}
onPress={() => handleOnButtonPress(get(product, 'productId'))}
height={50}
isDisable={disabled}
isLoading={false}
>
<View style={styles.buttonContent}>
<Text style={styles.buttonText}>{title}</Text>
<View style={styles.buttonIconWrapper}>
<Icon name="add" iconType="MaterialIcons" color="#357ce6" size={23} />
</View>
</View>
</MainButton>
</View>
<View style={styles.priceWrapper}>
{get(product, 'localizedPrice', null) && (
<Text style={styles.priceText}>{get(product, 'localizedPrice', 0)}</Text>
)}
</View>
</View>
);
};
const _renderDeal = item => {
if (DEALS[item.productId]) {
return (
<View style={styles.descriptionWrapper}>
<Text style={styles.description}>{DEALS[item.productId]}</Text>
<View style={styles.triangle} />
</View>
);
}
return null;
};
export { ProductItemLineView as ProductItemLine };

View File

@ -29,40 +29,11 @@ export default EStyleSheet.create({
position: 'absolute', position: 'absolute',
width: '$deviceWidth', width: '$deviceWidth',
height: 320, height: 320,
left: -120, left: -150,
top: -8, top: 20,
right: 0, right: 0,
zIndex: 999, zIndex: 999,
}, },
buttonContent: {
flexDirection: 'row',
},
buttonWrapper: {
minWidth: '$deviceWidth / 2.4',
flexDirection: 'row',
justifyContent: 'flex-end',
flex: 1,
},
buttonText: {
color: '$pureWhite',
fontSize: 14,
fontWeight: 'bold',
alignSelf: 'center',
minWidth: 70,
textAlign: 'center',
},
buttonIconWrapper: {
backgroundColor: '$pureWhite',
borderRadius: 20,
width: 24,
height: 24,
},
button: {
marginVertical: 12,
paddingHorizontal: 18,
marginTop: 50,
},
descriptionWrapper: { descriptionWrapper: {
backgroundColor: '$primaryDarkBlue', backgroundColor: '$primaryDarkBlue',
width: 75, width: 75,
@ -95,4 +66,19 @@ export default EStyleSheet.create({
position: 'absolute', position: 'absolute',
left: -22, left: -22,
}, },
productWrapper: {
flex: 0.8,
alignItems: 'center',
},
spinButton: {
width: 150,
justifyContent: 'center',
alignItems: 'center',
},
nextDate: {
marginTop: 50,
color: '$primaryDarkGray',
fontSize: 16,
fontWeight: '600',
},
}); });

View File

@ -1,116 +1,100 @@
import React, { PureComponent, Fragment } from 'react'; import React, { useState, Fragment } from 'react';
import { injectIntl } from 'react-intl';
import { Image, Text, View } from 'react-native'; import { Image, Text, View } from 'react-native';
import get from 'lodash/get'; import moment from 'moment';
import { useIntl } from 'react-intl';
// Components // Components
import { BoostIndicatorAnimation, MainButton, Icon, BasicHeader } from '..'; import { BoostIndicatorAnimation, MainButton, BasicHeader, ProductItemLine } from '..';
import ESTM_TAGS from '../../assets/estmTags.png'; import ESTM_TAGS from '../../assets/estmTags.png';
// Styles // Styles
import styles from './spinGameStyles'; import styles from './spinGameStyles';
class SpinGameView extends PureComponent { const SpinGameView = ({
/* Props gameRight,
* ------------------------------------------------ score,
* @prop { type } name - Description.... isLoading,
*/ spinProduct,
isProcessing,
buyItem,
nextDate,
startGame,
}) => {
const intl = useIntl();
const [isSpinning, setIsSpinning] = useState(false);
constructor(props) { const _handleOnSpinPress = () => {
super(props);
this.state = {
isSpinning: false,
};
}
componentDidMount() {
const { getItems } = this.props;
getItems(['499spins']);
}
_handleOnSpinPress = () => {
const { startGame } = this.props;
startGame('spin'); startGame('spin');
this.setState({ this.setState({
isSpinning: true, isSpinning: true,
}); });
setTimeout(() => { this.spinTimeout = setTimeout(() => {
this.setState({ isSpinning: false }); clearTimeout(this.spinTimeout);
}, 8000); setIsSpinning(false);
}, 8 * 1000);
}; };
_buySpinRight = () => { return (
alert('buy me'); <Fragment>
}; <BasicHeader title={intl.formatMessage({ id: 'free_estm.title' })} />
<View style={styles.container}>
<View style={styles.textWrapper}>
{!isSpinning && !isLoading && (
<Fragment>
<Text style={styles.count}>{gameRight}</Text>
<Text style={styles.countDesc}>
{intl.formatMessage({ id: 'free_estm.spin_right' })}
</Text>
</Fragment>
)}
</View>
<View style={styles.spinnerWrapper}>
{!isSpinning && !isLoading && gameRight > 0 && (
<Image source={ESTM_TAGS} style={styles.backgroundTags} />
)}
<BoostIndicatorAnimation key={gameRight} isSpinning={isSpinning} />
render() { {!isSpinning && score > 0 && (
const { intl, gameRight, score, isLoading, spinProduct } = this.props; <View style={styles.descriptionWrapper}>
const { isSpinning } = this.state;
return (
<Fragment>
<BasicHeader title={intl.formatMessage({ id: 'free_estm.title' })} />
<View style={styles.container}>
<View style={styles.textWrapper}>
{!isSpinning && !isLoading && (
<Fragment> <Fragment>
<Text style={styles.count}>{gameRight}</Text> <Text style={styles.description}>{`${score} ESTM`}</Text>
<Text style={styles.countDesc}>Spin Left</Text> <View style={styles.triangle} />
</Fragment> </Fragment>
)} </View>
</View> )}
<View style={styles.spinnerWrapper}> </View>
{!isSpinning && !isLoading && gameRight > 0 && ( <View style={styles.productWrapper}>
<Image source={ESTM_TAGS} style={styles.backgroundTags} /> {!isSpinning && !isLoading && (
)} <Fragment>
<BoostIndicatorAnimation key={gameRight} isSpinning={isSpinning} /> {gameRight > 0 ? (
<MainButton
{!isSpinning && score > 0 && ( style={styles.spinButton}
<View style={styles.descriptionWrapper}> onPress={_handleOnSpinPress}
text={intl.formatMessage({ id: 'free_estm.button' })}
/>
) : (
<Fragment> <Fragment>
<Text style={styles.description}>{`${score} ESTM`}</Text> {spinProduct.map(product => (
<View style={styles.triangle} /> <ProductItemLine
</Fragment> product={product}
</View> title={intl.formatMessage({ id: 'free_estm.get_spin' })}
)} disabled={isProcessing}
handleOnButtonPress={id => buyItem(id)}
<View style={{ flex: 1 }}> />
{!isSpinning && !isLoading && ( ))}
<Fragment> <Text style={styles.nextDate}>{`${intl.formatMessage({
<MainButton id: 'free_estm.timer_text',
style={styles.button} })} ${moment(moment(nextDate).diff(moment())).format('H:m')}`}</Text>
onPress={gameRight > 0 ? this._handleOnSpinPress : this._buySpinRight}
>
<View style={styles.buttonContent}>
<Text style={styles.buttonText}>
{intl.formatMessage({
id: gameRight > 0 ? 'free_estm.button' : 'free_estm.get_spin',
})}
</Text>
{gameRight <= 0 && (
<View style={styles.buttonIconWrapper}>
<Icon name="add" iconType="MaterialIcons" color="#357ce6" size={23} />
</View>
)}
</View>
</MainButton>
<View style={styles.priceWrapper}>
{get(spinProduct, 'localizedPrice', null) && (
<Text style={styles.priceText}>{get(spinProduct, 'localizedPrice', 0)}</Text>
)}
</View>
</Fragment> </Fragment>
)} )}
</View> </Fragment>
</View> )}
</View> </View>
</Fragment> </View>
); </Fragment>
} );
} };
export default injectIntl(SpinGameView); export { SpinGameView as SpinGame };

View File

@ -336,7 +336,8 @@
"free_estm": { "free_estm": {
"title": "Free ESTM", "title": "Free ESTM",
"button": "SPIN & WIN", "button": "SPIN & WIN",
"get_spin": "5 SPIN", "get_spin": "5 SPINS",
"spin_right": "Spin Left",
"timer_text": "Next free spin in" "timer_text": "Next free spin in"
}, },
"promote": { "promote": {

View File

@ -48,6 +48,7 @@ class InAppPurchaseContainer extends Component {
const { const {
currentAccount: { name }, currentAccount: { name },
intl, intl,
fetchData,
} = this.props; } = this.props;
this.purchaseUpdateSubscription = purchaseUpdatedListener(purchase => { this.purchaseUpdateSubscription = purchaseUpdatedListener(purchase => {
@ -70,6 +71,10 @@ class InAppPurchaseContainer extends Component {
RNIap.consumePurchaseAndroid(token); RNIap.consumePurchaseAndroid(token);
} }
this.setState({ isProcessing: false }); this.setState({ isProcessing: false });
if (fetchData) {
fetchData();
}
}) })
.catch(err => .catch(err =>
bugsnag.notify(err, report => { bugsnag.notify(err, report => {
@ -157,7 +162,7 @@ class InAppPurchaseContainer extends Component {
isLoading, isLoading,
isProcessing, isProcessing,
getItems: this._getItems, getItems: this._getItems,
spinProduct: productList.filter(item => item.productId === '499spins'), spinProduct: productList.filter(item => item.productId.includes('spins')),
}) })
); );
} }

View File

@ -22,6 +22,11 @@ class RedeemContainer extends Component {
// Component Life Cycle Functions // Component Life Cycle Functions
async componentDidMount() { async componentDidMount() {
this._statusCheck();
}
// Component Functions
_statusCheck = async () => {
const { username } = this.props; const { username } = this.props;
await gameStatusCheck(username, 'spin') await gameStatusCheck(username, 'spin')
@ -37,9 +42,7 @@ class RedeemContainer extends Component {
Alert.alert(get(err, 'message') || err.toString()); Alert.alert(get(err, 'message') || err.toString());
} }
}); });
} };
// Component Functions
_startGame = async type => { _startGame = async type => {
const { username } = this.props; const { username } = this.props;

View File

@ -1,39 +1,22 @@
import React, { Fragment } from 'react'; import React from 'react';
import { View, Text, Platform } from 'react-native'; import { View, Platform } from 'react-native';
import get from 'lodash/get'; import get from 'lodash/get';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
// Components // Components
import { BasicHeader, Icon, MainButton, BoostPlaceHolder } from '../../../components'; import { BasicHeader, BoostPlaceHolder, ProductItemLine } from '../../../components';
// Container // Container
import { InAppPurchaseContainer } from '../../../containers'; import { InAppPurchaseContainer } from '../../../containers';
// Styles // Styles
import globalStyles from '../../../globalStyles'; import globalStyles from '../../../globalStyles';
import styles from './boostScreenStyles';
const DEALS = { '9999points': 'BEST DEAL!', '4999points': 'POPULAR!' };
const ITEM_SKUS = Platform.select({ const ITEM_SKUS = Platform.select({
ios: ['099points', '199points', '499points', '999points', '4999points', '9999points'], ios: ['099points', '199points', '499points', '999points', '4999points', '9999points'],
android: ['099points', '199points', '499points', '999points', '4999points', '9999points'], android: ['099points', '199points', '499points', '999points', '4999points', '9999points'],
}); });
const _renderDeal = item => {
if (DEALS[item.productId]) {
return (
<View style={styles.descriptionWrapper}>
<Fragment>
<Text style={styles.description}>{DEALS[item.productId]}</Text>
<View style={styles.triangle} />
</Fragment>
</View>
);
}
return null;
};
const _getTitle = title => { const _getTitle = title => {
let _title = title.toUpperCase(); let _title = title.toUpperCase();
@ -61,35 +44,14 @@ const BoostScreen = () => {
{isLoading ? ( {isLoading ? (
<BoostPlaceHolder /> <BoostPlaceHolder />
) : ( ) : (
productList.map(item => ( productList.map(product => (
<View style={styles.boostLine} key={get(item, 'productId')}> <ProductItemLine
{_renderDeal(item)} isLoading={isLoading}
<View style={styles.buttonWrapper}> disabled={isProcessing}
<MainButton product={product}
style={styles.button} title={_getTitle(get(product, 'title'))}
onPress={() => buyItem(item.productId)} handleOnButtonPress={id => buyItem(id)}
height={50} />
text={intl.formatMessage({
id: 'boost.buy',
})}
isDisable={isProcessing}
isLoading={false}
>
<View style={styles.buttonContent}>
<Text style={styles.buttonText}>{_getTitle(get(item, 'title'))}</Text>
<View style={styles.buttonIconWrapper}>
<Icon name="add" iconType="MaterialIcons" color="#357ce6" size={23} />
</View>
</View>
</MainButton>
</View>
<View style={styles.priceWrapper}>
{get(item, 'localizedPrice', null) && (
<Text style={styles.priceText}>{get(item, 'localizedPrice', 0)}</Text>
)}
</View>
</View>
)) ))
)} )}
</View> </View>

View File

@ -11,6 +11,7 @@ import { Points } from './points';
import { Post } from './post'; import { Post } from './post';
import { SearchResult } from './searchResult'; import { SearchResult } from './searchResult';
import { Settings } from './settings'; import { Settings } from './settings';
import { SpinGame } from './spinGame/screen/spinGameScreen';
import Boost from './boost/screen/boostScreen'; import Boost from './boost/screen/boostScreen';
import Profile from './profile/screen/profileScreen'; import Profile from './profile/screen/profileScreen';
import ProfileEdit from './profileEdit/screen/profileEditScreen'; import ProfileEdit from './profileEdit/screen/profileEditScreen';
@ -18,7 +19,6 @@ import Reblogs from './reblogs';
import Redeem from './redeem/screen/redeemScreen'; import Redeem from './redeem/screen/redeemScreen';
import SteemConnect from './steem-connect/steemConnect'; import SteemConnect from './steem-connect/steemConnect';
import Transfer from './transfer'; import Transfer from './transfer';
import SpinGame from './spinGame/screen/spinGameScreen';
import Voters from './voters'; import Voters from './voters';
export { export {

View File

@ -1,43 +1,32 @@
import React, { PureComponent } from 'react'; import React from 'react';
// Container // Container
import { SpinGameContainer, InAppPurchaseContainer } from '../../../containers'; import { SpinGameContainer, InAppPurchaseContainer } from '../../../containers';
import { SpinGame } from '../../../components'; import { SpinGame } from '../../../components';
class FreeEstmScreen extends PureComponent { const SpinGameScreen = () => {
/* Props return (
* ------------------------------------------------ <SpinGameContainer>
* @prop { type } name - Description.... {({ startGame, score, gameRight, nextDate, isLoading, statusCheck }) => (
*/ <InAppPurchaseContainer fetchData={statusCheck} skus={['499spins']}>
{({ buyItem, getItems, spinProduct, isProcessing }) => (
<SpinGame
buyItem={buyItem}
isLoading={isLoading}
score={score}
startGame={startGame}
gameRight={gameRight}
nextDate={nextDate}
getItems={getItems}
isProcessing={isProcessing}
spinProduct={spinProduct}
/>
)}
</InAppPurchaseContainer>
)}
</SpinGameContainer>
);
};
constructor(props) { export { SpinGameScreen as SpinGame };
super(props);
this.state = {};
}
render() {
return (
<SpinGameContainer>
{({ startGame, score, gameRight, nextDate, isLoading }) => (
<InAppPurchaseContainer skus={['499spins']}>
{({ buyItem, getItems, spinProduct }) => (
<SpinGame
buyItem={buyItem}
isLoading={isLoading}
score={score}
startGames={startGame}
gameRight={gameRight}
nextDate={nextDate}
getItems={getItems}
spinProduct={spinProduct[0]}
/>
)}
</InAppPurchaseContainer>
)}
</SpinGameContainer>
);
}
}
export default FreeEstmScreen;

View File

@ -12,15 +12,21 @@ const THIS_MONTH = moment()
.startOf('day'); .startOf('day');
export const getTimeFromNow = (value, isWithoutUtc) => { export const getTimeFromNow = (value, isWithoutUtc) => {
if (!value) return null; if (!value) {
return null;
}
if (isWithoutUtc) return moment(value).fromNow(); if (isWithoutUtc) {
return moment(value).fromNow();
}
return moment.utc(value).fromNow(); return moment.utc(value).fromNow();
}; };
export const getFormatedCreatedDate = value => { export const getFormatedCreatedDate = value => {
if (!value) return null; if (!value) {
return null;
}
return moment(value).format('DD MMM, YYYY'); return moment(value).format('DD MMM, YYYY');
}; };
@ -36,7 +42,9 @@ export const isThisWeek = value => moment(value).isSameOrAfter(THIS_WEEK);
export const isThisMonth = value => moment(value).isSameOrAfter(THIS_MONTH); export const isThisMonth = value => moment(value).isSameOrAfter(THIS_MONTH);
export const isEmptyContentDate = value => { export const isEmptyContentDate = value => {
if (!value) return false; if (!value) {
return false;
}
return parseInt(value.split('-')[0], 10) < 1980; return parseInt(value.split('-')[0], 10) < 1980;
}; };