Merge pull request #268 from esteemapp/bugfix/186

Bugfix/186
This commit is contained in:
uğur erdal 2018-12-19 14:57:18 +03:00 committed by GitHub
commit ab0fb9e158
15 changed files with 300 additions and 290 deletions

View File

@ -2,6 +2,6 @@ import React from 'react';
import { View } from 'react-native';
import styles from './grayWrapperStyles';
const GrayWrapper = ({ children }) => <View style={styles.wrapper}>{children}</View>;
const GrayWrapper = ({ children, isGray }) => (isGray ? <View style={styles.wrapper}>{children}</View> : children);
export default GrayWrapper;

View File

@ -55,6 +55,8 @@ export default EStyleSheet.create({
color: '$primaryBlue',
fontSize: 14,
fontWeight: '600',
maxWidth: '$deviceWidth / 2.5',
textAlign: 'center',
},
thinText: {
fontSize: 14,

View File

@ -1,64 +1,79 @@
import React from 'react';
import { View, Text } from 'react-native';
import { GrayWrapper } from '../..';
import IconComp from '../../../icon';
import { Icon } from '../../../icon';
import { CollapsibleCard } from '../../../collapsibleCard';
import styles from './walletLineItemStyles';
const WalletLineItem = ({
text,
textColor,
iconName,
iconType,
rightText,
rightTextColor,
isBoldText,
isThin,
isCircleIcon,
circleIconColor,
description,
fitContent,
iconName,
iconType,
isBlackText,
isBoldText,
isCircleIcon,
isThin,
rightText,
rightTextColor,
text,
textColor,
index,
}) => (
<View style={[styles.container, fitContent && styles.fitContent]}>
<View style={styles.iconTextWrapper}>
{iconName && (
<View
style={[
styles.iconWrapper,
isCircleIcon && styles.circleIcon,
circleIconColor && { backgroundColor: circleIconColor },
]}
>
<IconComp style={styles.icon} name={iconName} iconType={iconType} />
<GrayWrapper isGray={index % 2 === 0}>
<View style={[styles.container, fitContent && styles.fitContent]}>
<View style={styles.iconTextWrapper}>
{iconName && (
<View
style={[
styles.iconWrapper,
isCircleIcon && styles.circleIcon,
circleIconColor && { backgroundColor: circleIconColor },
]}
>
<Icon style={styles.icon} name={iconName} iconType={iconType} />
</View>
)}
<View>
{text && (
<View>
<Text
style={[
styles.text,
!iconName && styles.onlyText,
rightText && styles.longText,
isBlackText && styles.blackText,
textColor && { color: textColor },
isBoldText && { fontWeight: 'bold' },
isThin && styles.thinText,
]}
>
{text}
</Text>
</View>
)}
{description && (
<Text style={[styles.description, !iconName && styles.onlyText]}>{description}</Text>
)}
</View>
</View>
{rightText && (
<View style={styles.rightTextWrapper}>
<Text
style={[
styles.rightText,
rightTextColor ? { color: rightTextColor } : !text && styles.onlyRightText,
]}
>
{rightText}
</Text>
</View>
)}
<View>
<Text
style={[
styles.text,
!iconName && styles.onlyText,
rightText && styles.longText,
textColor && { color: textColor },
isBoldText && { fontWeight: 'bold' },
isThin && styles.thinText,
]}
>
{text}
</Text>
{description && <Text style={styles.description}>{description}</Text>}
</View>
</View>
<View style={styles.rightTextWrapper}>
<Text
style={[
styles.rightText,
rightTextColor ? { color: rightTextColor } : !text && styles.onlyRightText,
]}
>
{rightText}
</Text>
</View>
</View>
</GrayWrapper>
);
export default WalletLineItem;

View File

@ -11,12 +11,12 @@ import styles from './collapsibleCardStyles';
class CollapsibleCardView extends Component {
/* Props
* ------------------------------------------------
* @prop { type } expanded - For is collapsible open or close declaration prop.
* @prop { type } children - Render include children
* @prop { type } title - Collapsible title.
*
*/
* ------------------------------------------------
* @prop { type } expanded - For is collapsible open or close declaration prop.
* @prop { type } children - Render include children
* @prop { type } title - Collapsible title.
*
*/
anime = {
height: new Animated.Value(),
expanded: false,
@ -70,6 +70,7 @@ class CollapsibleCardView extends Component {
fitContent,
isTitleCenter,
style,
noContainer,
} = this.props;
const { expanded } = this.state;
@ -96,7 +97,7 @@ class CollapsibleCardView extends Component {
style={[styles.content, { height: this.anime.height }]}
onLayout={e => this._initContentHeight(e)}
>
<View style={[!fitContent && styles.contentBody]}>{children}</View>
<View style={[!fitContent && !noContainer && styles.contentBody]}>{children}</View>
</Animated.View>
</View>
);

View File

@ -1,22 +1,14 @@
import React, { Component } from 'react';
// import { connect } from 'react-redux';
// Services and Actions
// Middleware
// Constants
// Utilities
// Component
import { TransactionView } from '..';
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
/**
* Props Name Description Value
* @props --> intl Function for language support function
* @props --> walletData User wallet data object
*
*/
class TransactionContainer extends Component {
constructor(props) {
@ -29,15 +21,10 @@ class TransactionContainer extends Component {
// Component Functions
render() {
// eslint-disable-next-line
//const {} = this.props;
const { intl, walletData } = this.props;
return <TransactionView {...this.props} />;
return <TransactionView intl={intl} walletData={walletData} />;
}
}
// const mapStateToProps = state => ({
// user: state.user.user,
// });
export default TransactionContainer;

View File

@ -1,21 +1,19 @@
import React, { Component } from 'react';
import { View } from 'react-native';
import React, { Component, Fragment } from 'react';
import { injectIntl } from 'react-intl';
// Utilities
import parseToken from '../../../utils/parseToken';
import parseDate from '../../../utils/parseDate';
import { vestsToSp } from '../../../utils/conversions';
import { getTransactionData } from '../../../utils/wallet';
// Components
import { FilterBar } from '../../filterBar';
import { GrayWrapper, WalletLineItem, Card } from '../../basicUIElements';
// import { FilterBar } from '../../filterBar';
import { WalletLineItem, Card } from '../../basicUIElements';
import { CollapsibleCard } from '../../collapsibleCard';
class TransactionView extends Component {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
@ -27,100 +25,16 @@ class TransactionView extends Component {
// Component Functions
_handleOnDropdownSelect = () => {};
_getTransactionData = (transaction) => {
const { walletData, intl: { formatNumber } } = this.props;
const result = {};
// eslint-disable-next-line
result.opName = transaction[1].op[0];
const opData = transaction[1].op[1];
const { timestamp } = transaction[1];
result.transDate = parseDate(timestamp);
result.icon = 'local-activity';
switch (result.opName) {
case 'curation_reward':
const { reward } = opData;
const { comment_author: commentAuthor, comment_permlink: commentPermlink } = opData;
result.value = `${formatNumber(vestsToSp(parseToken(reward), walletData.steemPerMVests), { minimumFractionDigits: 3 })} SP`;
result.details = `@${commentAuthor}/${commentPermlink}`;
break;
case 'author_reward':
case 'comment_benefactor_reward':
let {
sbd_payout: sbdPayout,
steem_payout: steemPayout,
vesting_payout: vestingPayout,
} = opData;
const { author, permlink } = opData;
sbdPayout = formatNumber(parseToken(sbdPayout), { minimumFractionDigits: 3 });
steemPayout = formatNumber(parseToken(steemPayout), { minimumFractionDigits: 3 });
vestingPayout = formatNumber(vestsToSp(parseToken(vestingPayout), walletData.steemPerMVests), { minimumFractionDigits: 3 });
result.value = `${sbdPayout > 0 ? `${sbdPayout} SBD` : ''} ${
steemPayout > 0 ? `${steemPayout} steemPayout` : ''
} ${vestingPayout > 0 ? `${vestingPayout} SP` : ''}`;
result.details = `@${author}/${permlink}`;
if (result.opName === 'comment_benefactor_reward') {
result.icon = 'comment';
}
break;
case 'claim_reward_balance':
let {
reward_sbd: rewardSdb,
reward_steem: rewardSteem,
reward_vests: rewardVests,
} = opData;
rewardSdb = formatNumber(parseToken(rewardSdb), { minimumFractionDigits: 3 });
rewardSteem = formatNumber(parseToken(rewardSteem), { minimumFractionDigits: 3 });
rewardVests = formatNumber(vestsToSp(parseToken(rewardVests), walletData.steemPerMVests), { minimumFractionDigits: 3 });
result.value = `${rewardSdb > 0 ? `${rewardSdb} SBD` : ''} ${
rewardSteem > 0 ? `${rewardSteem} STEEM` : ''
} ${rewardVests > 0 ? `${rewardVests} SP` : ''}`;
break;
case 'transfer':
case 'transfer_to_vesting':
const {
amount, memo, from, to,
} = opData;
result.value = `${amount}`;
result.icon = 'compare-arrows';
// details = <span>{memo} <br/><br/> <strong>@{from}</strong> -&gt; <strong>@{to}</strong></span>;
break;
case 'withdraw_vesting':
const { acc } = opData;
let { vesting_shares: opVestingShares } = opData;
opVestingShares = parseToken(opVestingShares);
result.value = `${formatNumber(vestsToSp(opVestingShares, walletData.steemPerMVests), { minimumFractionDigits: 3 })} SP`;
result.icon = 'money';
// details = <span><strong>@{acc}</strong></span>;
break;
case 'fill_order':
const { current_pays: currentPays, open_pays: openPays } = opData;
result.value = `${currentPays} = ${openPays}`;
result.icon = 'reorder';
break;
default:
break;
}
return result;
};
render() {
const { walletData: { transactions }, intl } = this.props;
const {
walletData: { transactions },
intl,
intl: { formatNumber },
walletData,
} = this.props;
return (
<View>
<Fragment>
{/* this feature not implemented yet */}
{/* <FilterBar
dropdownIconName="md-arrow-dropdown"
@ -129,50 +43,50 @@ class TransactionView extends Component {
onDropdownSelect={() => this._handleOnDropdownSelect()}
rightIconName="ios-lock"
iconSize={16}
if (index % 2 === 0) {
/> */}
<Card>
{transactions
&& transactions.map((item, index) => {
const transactionData = this._getTransactionData(item);
if (index % 2 === 0) {
return (
<WalletLineItem
text={intl.formatMessage({
id: `wallet.${transactionData.opName}`,
})}
description={intl.formatRelative(transactionData.transDate)}
isCircleIcon
isThin
circleIconColor="white"
textColor="#3c4449"
iconName={transactionData.icon}
iconType="MaterialIcons"
rightText={transactionData.value}
tightTextColor="red"
/>
);
}
const transactionData = getTransactionData(item, walletData, formatNumber);
return (
<GrayWrapper>
<WalletLineItem
text={intl.formatMessage({
id: `wallet.${transactionData.opName}`,
})}
description={intl.formatRelative(transactionData.transDate)}
isCircleIcon
isThin
circleIconColor="white"
textColor="#3c4449"
iconName={transactionData.icon}
iconType="MaterialIcons"
rightText={transactionData.value}
tightTextColor="red"
/>
</GrayWrapper>
<CollapsibleCard
noBorder
noContainer
key={index}
titleComponent={(
<WalletLineItem
key={index}
index={index}
text={intl.formatMessage({
id: `wallet.${transactionData.opName}`,
})}
description={intl.formatRelative(transactionData.transDate)}
isCircleIcon
isThin
circleIconColor="white"
isBlackText
iconName={transactionData.icon}
iconType="MaterialIcons"
rightText={transactionData.value}
/>
)}
>
{(!!transactionData.details || !!transactionData.memo) && (
<WalletLineItem
key={index}
text={!!transactionData.details && transactionData.details}
isBlackText
isThin
description={!!transactionData.memo && transactionData.memo}
/>
)}
</CollapsibleCard>
);
})}
</Card>
</View>
</Fragment>
);
}
}

View File

@ -1,9 +1,6 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
paddingBottom: 20,
},
// First collabsible component
mainButton: {
marginBottom: 12,

View File

@ -9,7 +9,7 @@ import { MainButton } from '../../mainButton';
import { CollapsibleCard } from '../../collapsibleCard';
import { WalletDetails } from '../../walletDetails';
import { Transaction } from '../../transaction';
import { WalletDetailsPlaceHolder, WalletUnclaimedPlaceHolder } from '../../basicUIElements';
import { WalletDetailsPlaceHolder } from '../../basicUIElements';
// Styles
import styles from './walletStyles';
@ -45,61 +45,57 @@ class WalletView extends Component {
render() {
const {
walletData, intl, selectedUsername, currentAccountUsername,
currentAccountUsername, intl, selectedUsername, walletData,
} = this.props;
return (
<View style={styles.container}>
<ScrollView style={styles.scrollView}>
{!walletData ? (
<Fragment>
<WalletUnclaimedPlaceHolder />
<WalletDetailsPlaceHolder />
</Fragment>
) : (
<Fragment>
{walletData.hasUnclaimedRewards && (
<CollapsibleCard
titleColor="#788187"
isBoldTitle
defaultTitle={intl.formatMessage({
id: 'profile.unclaimed_rewards',
})}
expanded
style={{ marginBottom: 0 }}
>
{currentAccountUsername === selectedUsername ? (
<MainButton
style={styles.mainButton}
height={50}
onPress={this._handleOnPressLogin}
>
<View style={styles.mainButtonWrapper}>
{this._getUnclaimedText(walletData)}
<View style={styles.mainIconWrapper}>
<Ionicons name="md-add" color="#357ce6" size={23} />
</View>
</View>
</MainButton>
) : (
this._getUnclaimedText(walletData, true)
)}
</CollapsibleCard>
)}
<ScrollView style={styles.scrollView}>
{!walletData ? (
<Fragment>
<WalletDetailsPlaceHolder />
</Fragment>
) : (
<Fragment>
{walletData.hasUnclaimedRewards && (
<CollapsibleCard
titleColor="#788187"
title={intl.formatMessage({
id: 'profile.wallet_details',
isBoldTitle
defaultTitle={intl.formatMessage({
id: 'profile.unclaimed_rewards',
})}
expanded
>
<WalletDetails intl={intl} walletData={walletData} />
{currentAccountUsername === selectedUsername ? (
<MainButton
style={styles.mainButton}
height={50}
onPress={this._handleOnPressLogin}
>
<View style={styles.mainButtonWrapper}>
{this._getUnclaimedText(walletData)}
<View style={styles.mainIconWrapper}>
<Ionicons name="md-add" color="#357ce6" size={23} />
</View>
</View>
</MainButton>
) : (
this._getUnclaimedText(walletData, true)
)}
</CollapsibleCard>
<Transaction intl={intl} walletData={walletData} />
</Fragment>
)}
</ScrollView>
</View>
)}
<CollapsibleCard
titleColor="#788187"
title={intl.formatMessage({
id: 'profile.wallet_details',
})}
expanded
>
<WalletDetails intl={intl} walletData={walletData} />
</CollapsibleCard>
<Transaction intl={intl} walletData={walletData} />
</Fragment>
)}
</ScrollView>
);
}
}

View File

@ -1,22 +1,14 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
// Services and Actions
// Middleware
// Constants
// Utilities
// Component
import { WalletDetailsView } from '..';
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
/**
* Props Name Description Value
* @props --> intl Function for language support function
* @props --> walletData User wallet data object
*
*/
class WalletContainer extends Component {
constructor(props) {
@ -29,14 +21,10 @@ class WalletContainer extends Component {
// Component Functions
render() {
// const {} = this.props;
const { intl, walletData } = this.props;
return <WalletDetailsView {...this.props} />;
return <WalletDetailsView intl={intl} walletData={walletData} />;
}
}
// const mapStateToProps = state => ({
// // user: state.user.user,
// });
export default WalletContainer;

View File

@ -4,4 +4,7 @@ export default EStyleSheet.create({
container: {
paddingBottom: 8,
},
blackText: {
color: '$primaryBlack',
},
});

View File

@ -34,7 +34,7 @@ class WalletDetailsView extends Component {
<View style={styles.container}>
<WalletLineItem
text="Steem"
textColor="#3c4449"
isBlackText
iconName="ios-information-circle-outline"
rightText={`${Math.round(walletData.balance * 1000) / 1000} STEEM`}
isBoldText
@ -44,7 +44,7 @@ class WalletDetailsView extends Component {
text={intl.formatMessage({
id: 'profile.steem_power',
})}
textColor="#3c4449"
isBlackText
iconName="ios-information-circle-outline"
rightText={`${Math.round(
vestsToSp(walletData.vestingShares, walletData.steemPerMVests) * 1000,
@ -80,7 +80,7 @@ class WalletDetailsView extends Component {
text={intl.formatMessage({
id: 'profile.steem_dollars',
})}
textColor="#3c4449"
isBlackText
iconName="ios-information-circle-outline"
rightText={`$${Math.round(walletData.sbdBalance * 1000) / 1000}`}
isBoldText
@ -90,7 +90,7 @@ class WalletDetailsView extends Component {
text={intl.formatMessage({
id: 'profile.savings',
})}
textColor="#3c4449"
isBlackText
iconName="ios-information-circle-outline"
rightText={`${Math.round(walletData.savingBalance * 1000) / 1000} STEEM`}
isBoldText
@ -99,7 +99,11 @@ class WalletDetailsView extends Component {
</GrayWrapper>
{walletData.showPowerDown && (
<WalletLineItem
text={`Next power down is in ${walletData.nextVestingWithdrawal} day`}
text={`${intl.formatMessage({
id: 'profile.next_power_text',
})} ${walletData.nextVestingWithdrawal} ${intl.formatMessage({
id: 'profile.day',
})}`}
textColor="#788187"
iconName="ios-information-circle-outline"
/>

View File

@ -49,6 +49,7 @@
"steem_power": "Steem Power",
"next_power_text": "Next power down is in",
"days": "days",
"day": "day",
"steem_dollars": "Steem Dollars",
"savings": "Savings"
},

View File

@ -48,7 +48,8 @@
"voting_power": "Oylama güçü",
"steem_power": "Steem Güçü",
"next_power_text": "İleriki güç",
"days": "days içinde düşecek",
"days": "gün içinde düşecek",
"day": "gün içinde düşecek",
"steem_dollars": "Steem Dolar",
"savings": "Biriktir"
},

View File

@ -110,7 +110,7 @@ class PinCodeContainer extends Component {
};
setUserDataWithPinCode(pinData).then((response) => {
const _currentAccount = currentAccount;
_currentAccount.local = response[0];
_currentAccount.local = response;
dispatch(updateCurrentAccount({ ..._currentAccount }));

101
src/utils/wallet.js Normal file
View File

@ -0,0 +1,101 @@
import parseToken from './parseToken';
import parseDate from './parseDate';
import { vestsToSp } from './conversions';
export const getTransactionData = (transaction, walletData, formatNumber) => {
if (!transaction || !walletData) {
return [];
}
const result = {};
// eslint-disable-next-line
result.opName = transaction[1].op[0];
const opData = transaction[1].op[1];
const { timestamp } = transaction[1];
result.transDate = parseDate(timestamp);
result.icon = 'local-activity';
switch (result.opName) {
case 'curation_reward':
const { reward } = opData;
const { comment_author: commentAuthor, comment_permlink: commentPermlink } = opData;
result.value = `${formatNumber(vestsToSp(parseToken(reward), walletData.steemPerMVests), {
minimumFractionDigits: 3,
})} SP`;
result.details = `@${commentAuthor}/${commentPermlink}`;
break;
case 'author_reward':
case 'comment_benefactor_reward':
let {
sbd_payout: sbdPayout,
steem_payout: steemPayout,
vesting_payout: vestingPayout,
} = opData;
const { author, permlink } = opData;
sbdPayout = formatNumber(parseToken(sbdPayout), { minimumFractionDigits: 3 });
steemPayout = formatNumber(parseToken(steemPayout), { minimumFractionDigits: 3 });
vestingPayout = formatNumber(
vestsToSp(parseToken(vestingPayout), walletData.steemPerMVests),
{ minimumFractionDigits: 3 },
);
result.value = `${sbdPayout > 0 ? `${sbdPayout} SBD` : ''} ${
steemPayout > 0 ? `${steemPayout} steemPayout` : ''
} ${vestingPayout > 0 ? `${vestingPayout} SP` : ''}`;
result.details = `@${author}/${permlink}`;
if (result.opName === 'comment_benefactor_reward') {
result.icon = 'comment';
}
break;
case 'claim_reward_balance':
let { reward_sbd: rewardSdb, reward_steem: rewardSteem, reward_vests: rewardVests } = opData;
rewardSdb = formatNumber(parseToken(rewardSdb), { minimumFractionDigits: 3 });
rewardSteem = formatNumber(parseToken(rewardSteem), { minimumFractionDigits: 3 });
rewardVests = formatNumber(vestsToSp(parseToken(rewardVests), walletData.steemPerMVests), {
minimumFractionDigits: 3,
});
result.value = `${rewardSdb > 0 ? `${rewardSdb} SBD` : ''} ${
rewardSteem > 0 ? `${rewardSteem} STEEM` : ''
} ${rewardVests > 0 ? `${rewardVests} SP` : ''}`;
break;
case 'transfer':
case 'transfer_to_vesting':
const {
amount, memo, from, to,
} = opData;
result.value = `${amount}`;
result.icon = 'compare-arrows';
result.details = `@${from} to @${to}`;
result.memo = memo;
break;
case 'withdraw_vesting':
const { acc } = opData;
let { vesting_shares: opVestingShares } = opData;
opVestingShares = parseToken(opVestingShares);
result.value = `${formatNumber(vestsToSp(opVestingShares, walletData.steemPerMVests), {
minimumFractionDigits: 3,
})} SP`;
result.icon = 'money';
result.details = `@${acc}`;
break;
case 'fill_order':
const { current_pays: currentPays, open_pays: openPays } = opData;
result.value = `${currentPays} = ${openPays}`;
result.icon = 'reorder';
break;
default:
break;
}
return result;
};