diff --git a/src/components/transaction/container/transactionContainer.js b/src/components/transaction/container/transactionContainer.js
index a6d1899b6..6cd96f355 100644
--- a/src/components/transaction/container/transactionContainer.js
+++ b/src/components/transaction/container/transactionContainer.js
@@ -1,4 +1,5 @@
import React, { PureComponent } from 'react';
+import { connect } from 'react-redux';
// Component
import TransactionView from '../view/transactionView';
@@ -21,10 +22,14 @@ class TransactionContainer extends PureComponent {
// Component Functions
render() {
- const { walletData } = this.props;
+ const { walletData, steemPerMVests } = this.props;
- return ;
+ return ;
}
}
-export default TransactionContainer;
+const mapStateToProps = state => ({
+ steemPerMVests: state.account.globalProps.steemPerMVests,
+});
+
+export default connect(mapStateToProps)(TransactionContainer);
diff --git a/src/components/transaction/view/transactionView.js b/src/components/transaction/view/transactionView.js
index 1dad7d864..60fd18572 100644
--- a/src/components/transaction/view/transactionView.js
+++ b/src/components/transaction/view/transactionView.js
@@ -36,7 +36,7 @@ class TransactionView extends PureComponent {
walletData: { transactions },
intl,
intl: { formatNumber },
- walletData,
+ steemPerMVests,
} = this.props;
return (
@@ -53,16 +53,16 @@ class TransactionView extends PureComponent {
{transactions
&& transactions.map((item, index) => {
- const transactionData = groomingTransactionData(item, walletData, formatNumber);
+ const transactionData = groomingTransactionData(item, steemPerMVests, formatNumber);
return (
{(!!transactionData.details || !!transactionData.memo) && (
({
upvotePercent: state.application.upvotePercent,
pinCode: state.account.pin,
currentAccount: state.account.currentAccount,
+ globalProps: state.account.globalProps,
});
export default connect(mapStateToProps)(UpvoteContainer);
diff --git a/src/components/upvote/view/upvoteView.js b/src/components/upvote/view/upvoteView.js
index 26159790c..d56a95331 100644
--- a/src/components/upvote/view/upvoteView.js
+++ b/src/components/upvote/view/upvoteView.js
@@ -6,12 +6,17 @@ import { injectIntl } from 'react-intl';
import { Popover, PopoverController } from 'react-native-modal-popover';
import Slider from 'react-native-slider';
+// Utils
+import parseToken from '../../../utils/parseToken';
+import { vestsToRshares } from '../../../utils/conversions';
+
// Components
import { Icon } from '../../icon';
import { PulseAnimation } from '../../animations';
import { TextButton } from '../../buttons';
+
// STEEM
-import { upvoteAmount, vote } from '../../../providers/steem/dsteem';
+import { vote } from '../../../providers/steem/dsteem';
// Styles
import styles from './upvoteStyles';
@@ -53,21 +58,22 @@ class UpvoteView extends Component {
// Component Functions
_calculateEstimatedAmount = async () => {
- const { currentAccount } = this.props;
- // Calculate total vesting shares
+ const { currentAccount, globalProps } = this.props;
+
if (currentAccount) {
const { sliderValue } = this.state;
- const totalVests = parseFloat(currentAccount.vesting_shares)
- + parseFloat(currentAccount.received_vesting_shares)
- - parseFloat(currentAccount.delegated_vesting_shares);
+ const {
+ fundRecentClaims, fundRewardBalance, base, quote,
+ } = globalProps;
- const finalVest = totalVests * 1e6;
+ const votingPower = currentAccount.voting_power;
+ const totalVests = parseToken(currentAccount.vesting_shares)
+ + parseToken(currentAccount.received_vesting_shares)
+ - parseToken(currentAccount.delegated_vesting_shares);
+ const votePct = sliderValue * 10000;
- const power = (currentAccount.voting_power * (sliderValue * 10000)) / 10000 / 50;
-
- const rshares = (power * finalVest) / 10000;
-
- const estimated = await upvoteAmount(rshares);
+ const rShares = vestsToRshares(totalVests, votingPower, votePct);
+ const estimated = (rShares / fundRecentClaims) * fundRewardBalance * (base / quote);
this.setState({
amount: estimated.toFixed(5),
@@ -252,18 +258,18 @@ class UpvoteView extends Component {
{
- closePopover();
- this._upvoteContent();
- }}
+ closePopover();
+ this._upvoteContent();
+ }}
style={styles.upvoteButton}
>
+ size={20}
+ style={[styles.upvoteIcon, { color: '#007ee5' }]}
+ active={!isLoggedIn}
+ iconType={iconType}
+ name={iconName}
+ />
{_amount}
{
- this.setState({ sliderValue: value }, () => {
- this._calculateEstimatedAmount();
- });
- }}
+ this.setState({ sliderValue: value }, () => {
+ this._calculateEstimatedAmount();
+ });
+ }}
/>
{_percent}
diff --git a/src/components/wallet/container/walletContainer.js b/src/components/wallet/container/walletContainer.js
index 4543e5f59..7c47c2b0e 100644
--- a/src/components/wallet/container/walletContainer.js
+++ b/src/components/wallet/container/walletContainer.js
@@ -47,8 +47,8 @@ class WalletContainer extends Component {
// Components functions
_getWalletData = async (selectedUser) => {
- const { setEstimatedWalletValue } = this.props;
- const walletData = await groomingWalletData(selectedUser);
+ const { setEstimatedWalletValue, globalProps } = this.props;
+ const walletData = await groomingWalletData(selectedUser, globalProps);
this.setState({ walletData });
setEstimatedWalletValue(walletData.estimatedValue);
@@ -133,6 +133,7 @@ const mapStateToProps = state => ({
currentAccount: state.account.currentAccount,
pinCode: state.account.pin,
isDarkTheme: state.application.isDarkTheme,
+ globalProps: state.account.globalProps,
});
export default injectIntl(connect(mapStateToProps)(WalletContainer));
diff --git a/src/providers/steem/dsteem.js b/src/providers/steem/dsteem.js
index f82ed366f..a74c20d6d 100644
--- a/src/providers/steem/dsteem.js
+++ b/src/providers/steem/dsteem.js
@@ -10,13 +10,12 @@ import { decryptKey } from '../../utils/crypto';
import { parsePosts, parsePost, parseComments } from '../../utils/postParser';
import { getName, getAvatar } from '../../utils/user';
import { getReputation } from '../../utils/reputation';
+import parseToken from '../../utils/parseToken';
// Constant
import AUTH_TYPE from '../../constants/authType';
const DEFAULT_SERVER = 'https://api.steemit.com';
-let rewardFund = null;
-let medianPrice = null;
let client = new Client(DEFAULT_SERVER);
const _getClient = async () => {
@@ -35,6 +34,50 @@ _getClient();
export const getDigitPinCode = pin => decryptKey(pin, Config.PIN_KEY);
+export const getDynamicGlobalProperties = () => client.database.getDynamicGlobalProperties();
+
+export const getRewardFund = () => client.database.call('get_reward_fund', ['post']);
+
+export const getFeedHistory = async () => {
+ try {
+ const feedHistory = await client.database.call('get_feed_history');
+ return feedHistory;
+ } catch (error) {
+ return error;
+ }
+};
+
+export const fetchGlobalProps = async () => {
+ let globalDynamic;
+ let feedHistory;
+ let rewardFund;
+
+ try {
+ globalDynamic = await getDynamicGlobalProperties();
+ feedHistory = await getFeedHistory();
+ rewardFund = await getRewardFund();
+ } catch (e) {
+ return;
+ }
+
+ const steemPerMVests = (parseToken(globalDynamic.total_vesting_fund_steem)
+ / parseToken(globalDynamic.total_vesting_shares))
+ * 1e6;
+ const base = parseToken(feedHistory.current_median_history.base);
+ const quote = parseToken(feedHistory.current_median_history.quote);
+ const fundRecentClaims = rewardFund.recent_claims;
+ const fundRewardBalance = parseToken(rewardFund.reward_balance);
+ const globalProps = {
+ steemPerMVests,
+ base,
+ quote,
+ fundRecentClaims,
+ fundRewardBalance,
+ };
+
+ return globalProps;
+};
+
/**
* @method getAccount get account data
* @param user username
@@ -127,22 +170,6 @@ export const getFollows = user => new Promise((resolve, reject) => {
});
});
-/**
- * @method getFollowers
- * @param user username
- * TODO: Pagination
- */
-// export const getFollowers = (user, limit = 100) => new Promise((resolve, reject) => {
-// client
-// .call('follow_api', 'get_followers', [user, '', 'blog', limit])
-// .then((result) => {
-// resolve(result);
-// })
-// .catch((err) => {
-// reject(err);
-// });
-// });
-
/**
* @method getFollowing
* @param user username
@@ -426,18 +453,12 @@ export const vote = async (currentAccount, pin, author, permlink, weight) => {
* @method upvoteAmount estimate upvote amount
*/
export const upvoteAmount = async (input) => {
- if (!rewardFund || !medianPrice) {
- rewardFund = await client.database.call('get_reward_fund', ['post']);
+ let medianPrice;
+ const rewardFund = await getRewardFund();
- await client.database
- .getCurrentMedianHistoryPrice()
- .then((res) => {
- medianPrice = res;
- })
- .catch((err) => {
- // reject(err);
- });
- }
+ await client.database.getCurrentMedianHistoryPrice().then((res) => {
+ medianPrice = res;
+ });
const estimated = (input / parseFloat(rewardFund.recent_claims))
* parseFloat(rewardFund.reward_balance)
@@ -563,24 +584,6 @@ export const delegate = (data, activeKey) => {
});
};
-export const globalProps = async () => {
- try {
- const globalProperties = await client.database.getDynamicGlobalProperties();
- return globalProperties;
- } catch (error) {
- return error;
- }
-};
-
-export const getFeedHistory = async () => {
- try {
- const feedHistory = await client.database.call('get_feed_history');
- return feedHistory;
- } catch (error) {
- return error;
- }
-};
-
export const transferToVesting = (data, activeKey) => {
const privateKey = PrivateKey.fromString(activeKey);
@@ -832,15 +835,4 @@ const getAnyPrivateKey = (local, pin) => {
}
return false;
-
- // ['postingKey', 'activeKey'].forEach((key) => {
- // console.log('key :', key);
- // console.log('pin :', pin);
- // console.log('local[key] :', local[key]);
- // if (key) {
- // const privateKey = decryptKey(local[key], pin);
- // console.log('privateKey :', privateKey);
- // return true;
- // }
- // });
};
diff --git a/src/redux/actions/accountAction.js b/src/redux/actions/accountAction.js
index 90b3dbaa7..ba9421ca6 100644
--- a/src/redux/actions/accountAction.js
+++ b/src/redux/actions/accountAction.js
@@ -1,24 +1,18 @@
-import { getUser } from '../../providers/steem/dsteem';
+import { fetchGlobalProps } from '../../providers/steem/dsteem';
import {
- FETCH_ACCOUNT_FAIL,
- FETCHING_ACCOUNT,
ADD_OTHER_ACCOUNT,
+ FETCH_ACCOUNT_FAIL,
+ REMOVE_OTHER_ACCOUNT,
+ SET_GLOBAL_PROPS,
+ SET_PIN_CODE,
UPDATE_CURRENT_ACCOUNT,
UPDATE_UNREAD_ACTIVITY_COUNT,
- REMOVE_OTHER_ACCOUNT,
- SET_PIN_CODE,
} from '../constants/constants';
-export const fetchAccountFromSteem = (username, password) => (dispatch) => {
- dispatch({ type: FETCHING_ACCOUNT });
-
- return getUser(username)
- .then(res => dispatch({
- type: UPDATE_CURRENT_ACCOUNT,
- payload: { ...res, password },
- }))
- .catch(err => dispatch({ type: FETCH_ACCOUNT_FAIL, payload: err }));
-};
+export const fetchGlobalProperties = () => dispatch => fetchGlobalProps().then(res => dispatch({
+ type: SET_GLOBAL_PROPS,
+ payload: { ...res },
+}));
export const updateCurrentAccount = data => ({
type: UPDATE_CURRENT_ACCOUNT,
@@ -49,3 +43,8 @@ export const setPinCode = data => ({
type: SET_PIN_CODE,
payload: data,
});
+
+export const setGlobalProps = data => ({
+ type: SET_GLOBAL_PROPS,
+ payload: data,
+});
diff --git a/src/redux/constants/constants.js b/src/redux/constants/constants.js
index 51cf422b5..a69f73e32 100644
--- a/src/redux/constants/constants.js
+++ b/src/redux/constants/constants.js
@@ -24,11 +24,12 @@ export const SET_UPVOTE_PERCENT = 'SET_UPVOTE_PERCENT';
// Accounts
export const ADD_OTHER_ACCOUNT = 'ADD_OTHER_ACCOUNT';
export const FETCH_ACCOUNT_FAIL = 'FETCH_ACCOUNT_FAIL';
-export const FETCHING_ACCOUNT = 'FETCHING_ACCOUNT';
export const REMOVE_OTHER_ACCOUNT = 'REMOVE_OTHER_ACCOUNT';
export const UPDATE_CURRENT_ACCOUNT = 'UPDATE_CURRENT_ACCOUNT';
export const UPDATE_UNREAD_ACTIVITY_COUNT = 'UPDATE_UNREAD_ACTIVITY_COUNT';
export const SET_PIN_CODE = 'SET_PIN_CODE';
+export const SET_GLOBAL_PROPS = 'SET_GLOBAL_PROPS';
+export const FETCH_GLOBAL_PROPS = 'FETCH_GLOBAL_PROPS';
// UI
export const IS_COLLAPSE_POST_BUTTON = 'IS_COLLAPSE_POST_BUTTON';
diff --git a/src/redux/reducers/accountReducer.js b/src/redux/reducers/accountReducer.js
index 4de63d4f3..0d8685f1b 100644
--- a/src/redux/reducers/accountReducer.js
+++ b/src/redux/reducers/accountReducer.js
@@ -7,6 +7,7 @@ import {
REMOVE_OTHER_ACCOUNT,
LOGOUT_FAIL,
SET_PIN_CODE,
+ SET_GLOBAL_PROPS,
} from '../constants/constants';
const initialState = {
@@ -29,6 +30,12 @@ export default function (state = initialState, action) {
errorMessage: null,
};
+ case SET_GLOBAL_PROPS:
+ return {
+ ...state,
+ globalProps: action.payload,
+ };
+
case FETCH_ACCOUNT_FAIL:
return {
...state,
diff --git a/src/screens/application/container/applicationContainer.js b/src/screens/application/container/applicationContainer.js
index e465ffd1d..16310eaca 100644
--- a/src/screens/application/container/applicationContainer.js
+++ b/src/screens/application/container/applicationContainer.js
@@ -5,6 +5,7 @@ import { addLocaleData } from 'react-intl';
import Config from 'react-native-config';
import AppCenter from 'appcenter';
import { NavigationActions } from 'react-navigation';
+import { bindActionCreators } from 'redux';
// Constants
import en from 'react-intl/locale-data/en';
@@ -37,6 +38,7 @@ import {
updateCurrentAccount,
updateUnreadActivityCount,
removeOtherAccount,
+ fetchGlobalProperties,
} from '../../../redux/actions/accountAction';
import {
activeApplication,
@@ -69,8 +71,11 @@ class ApplicationContainer extends Component {
componentDidMount = async () => {
BackHandler.addEventListener('hardwareBackPress', this._onBackPress);
+ this._refreshGlobalProps();
await this._getUserData();
await this._getSettings();
+
+ this.globalInterval = setInterval(this._refreshGlobalProps, 60000);
};
componentWillReceiveProps(nextProps) {
@@ -87,6 +92,7 @@ class ApplicationContainer extends Component {
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
+ clearInterval(this.globalInterval);
}
_onBackPress = () => {
@@ -100,6 +106,12 @@ class ApplicationContainer extends Component {
return true;
};
+ _refreshGlobalProps = () => {
+ const { actions } = this.props;
+
+ actions.fetchGlobalProperties();
+ };
+
_getUserData = async () => {
const { dispatch, pinCode } = this.props;
let realmData = [];
@@ -280,20 +292,25 @@ class ApplicationContainer extends Component {
}
}
-const mapStateToProps = state => ({
- // Application
- isDarkTheme: state.application.isDarkTheme,
- selectedLanguage: state.application.language,
- notificationSettings: state.application.isNotificationOpen,
- isLogingOut: state.application.isLogingOut,
- isLoggedIn: state.application.isLoggedIn,
- nav: state.nav.routes,
+export default connect(
+ state => ({
+ // Application
+ isDarkTheme: state.application.isDarkTheme,
+ selectedLanguage: state.application.language,
+ notificationSettings: state.application.isNotificationOpen,
+ isLogingOut: state.application.isLogingOut,
+ isLoggedIn: state.application.isLoggedIn,
- // Account
- unreadActivityCount: state.account.currentAccount.unread_activity_count,
- currentAccount: state.account.currentAccount,
- otherAccounts: state.account.otherAccounts,
- pinCode: state.account.pin,
-});
-
-export default connect(mapStateToProps)(ApplicationContainer);
+ // Account
+ unreadActivityCount: state.account.currentAccount.unread_activity_count,
+ currentAccount: state.account.currentAccount,
+ otherAccounts: state.account.otherAccounts,
+ pinCode: state.account.pin,
+ }),
+ (dispatch, props) => ({
+ dispatch,
+ actions: {
+ ...bindActionCreators({ fetchGlobalProperties }, dispatch),
+ },
+ }),
+)(ApplicationContainer);
\ No newline at end of file
diff --git a/src/utils/conversions.js b/src/utils/conversions.js
index 495b7a0c2..d62bfcfb2 100644
--- a/src/utils/conversions.js
+++ b/src/utils/conversions.js
@@ -1 +1,7 @@
export const vestsToSp = (vests, steemPerMVests) => (vests / 1e6) * steemPerMVests;
+
+export const vestsToRshares = (vests, votingPower, votePerc) => {
+ const vestingShares = parseInt(vests * 1e6, 10);
+ const power = (votingPower * votePerc) / 1e4 / 50 + 1;
+ return (power * vestingShares) / 1e4;
+};
diff --git a/src/utils/wallet.js b/src/utils/wallet.js
index 0cd9243ea..f9ee862a4 100644
--- a/src/utils/wallet.js
+++ b/src/utils/wallet.js
@@ -1,10 +1,11 @@
import parseDate from './parseDate';
import parseToken from './parseToken';
import { vestsToSp } from './conversions';
-import { globalProps, getState, getFeedHistory } from '../providers/steem/dsteem';
+import { getState, getFeedHistory } from '../providers/steem/dsteem';
-export const groomingTransactionData = (transaction, walletData, formatNumber) => {
- if (!transaction || !walletData) {
+
+export const groomingTransactionData = (transaction, steemPerMVests, formatNumber) => {
+ if (!transaction || !steemPerMVests) {
return [];
}
@@ -23,7 +24,7 @@ export const groomingTransactionData = (transaction, walletData, formatNumber) =
const { reward } = opData;
const { comment_author: commentAuthor, comment_permlink: commentPermlink } = opData;
- result.value = `${formatNumber(vestsToSp(parseToken(reward), walletData.steemPerMVests), {
+ result.value = `${formatNumber(vestsToSp(parseToken(reward), steemPerMVests), {
minimumFractionDigits: 3,
})} SP`;
result.details = `@${commentAuthor}/${commentPermlink}`;
@@ -41,7 +42,7 @@ export const groomingTransactionData = (transaction, walletData, formatNumber) =
sbdPayout = formatNumber(parseToken(sbdPayout), { minimumFractionDigits: 3 });
steemPayout = formatNumber(parseToken(steemPayout), { minimumFractionDigits: 3 });
vestingPayout = formatNumber(
- vestsToSp(parseToken(vestingPayout), walletData.steemPerMVests),
+ vestsToSp(parseToken(vestingPayout), steemPerMVests),
{ minimumFractionDigits: 3 },
);
@@ -59,7 +60,7 @@ export const groomingTransactionData = (transaction, walletData, formatNumber) =
rewardSdb = formatNumber(parseToken(rewardSdb), { minimumFractionDigits: 3 });
rewardSteem = formatNumber(parseToken(rewardSteem), { minimumFractionDigits: 3 });
- rewardVests = formatNumber(vestsToSp(parseToken(rewardVests), walletData.steemPerMVests), {
+ rewardVests = formatNumber(vestsToSp(parseToken(rewardVests), steemPerMVests), {
minimumFractionDigits: 3,
});
@@ -83,7 +84,7 @@ export const groomingTransactionData = (transaction, walletData, formatNumber) =
let { vesting_shares: opVestingShares } = opData;
opVestingShares = parseToken(opVestingShares);
- result.value = `${formatNumber(vestsToSp(opVestingShares, walletData.steemPerMVests), {
+ result.value = `${formatNumber(vestsToSp(opVestingShares, steemPerMVests), {
minimumFractionDigits: 3,
})} SP`;
result.icon = 'attach-money';
@@ -101,14 +102,13 @@ export const groomingTransactionData = (transaction, walletData, formatNumber) =
return result;
};
-export const groomingWalletData = async (user) => {
+export const groomingWalletData = async (user, globalProps) => {
const walletData = {};
if (!user) {
return walletData;
}
- const global = await globalProps();
const state = await getState(`/@${user.name}/transfers`);
const { accounts } = state;
@@ -133,9 +133,7 @@ export const groomingWalletData = async (user) => {
const base = parseToken(feedHistory.current_median_history.base);
const quote = parseToken(feedHistory.current_median_history.quote);
- walletData.steemPerMVests = (
- parseToken(global.total_vesting_fund_steem) / parseToken(global.total_vesting_shares)
- ) * 1e6;
+ walletData.steemPerMVests = globalProps.steemPerMVests;
walletData.estimatedValue = (
vestsToSp(walletData.vestingShares, walletData.steemPerMVests) * (base / quote)