From 8908a2a1f600b1cb7de9f106f9598ab5b2c8ff07 Mon Sep 17 00:00:00 2001 From: u-e Date: Wed, 12 Jun 2019 00:38:15 +0300 Subject: [PATCH 1/8] wip on comment is vote --- src/components/comments/container/commentsContainer.js | 8 ++++++-- src/providers/steem/dsteem.js | 6 +++--- src/utils/postParser.js | 8 +++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/components/comments/container/commentsContainer.js b/src/components/comments/container/commentsContainer.js index 86f8fa035..978900452 100644 --- a/src/components/comments/container/commentsContainer.js +++ b/src/components/comments/container/commentsContainer.js @@ -123,9 +123,13 @@ class CommentsContainer extends Component { }; _getComments = () => { - const { author, permlink } = this.props; + const { + author, + permlink, + currentAccount: { name }, + } = this.props; - getComments(author, permlink).then(comments => { + getComments(author, permlink, name).then(comments => { this.setState({ comments, }); diff --git a/src/providers/steem/dsteem.js b/src/providers/steem/dsteem.js index 3dd4373c7..1f6b82b19 100644 --- a/src/providers/steem/dsteem.js +++ b/src/providers/steem/dsteem.js @@ -398,16 +398,16 @@ export const deleteComment = (currentAccount, pin, permlink) => { * @param user post author * @param permlink post permlink */ -export const getComments = (user, permlink) => { +export const getComments = (user, permlink, currentUserName) => { let comments; return new Promise((resolve, reject) => { client.database .call('get_content_replies', [user, permlink]) .then(result => { - comments = parseComments(result); + comments = parseComments(result, currentUserName); }) .then(() => { - resolve(comments); + resolve(parseComments(comments, currentUserName)); }) .catch(error => { reject(error); diff --git a/src/utils/postParser.js b/src/utils/postParser.js index ec2173a33..7f5ea51b4 100644 --- a/src/utils/postParser.js +++ b/src/utils/postParser.js @@ -98,7 +98,7 @@ const postImage = (metaData, body) => { return ''; }; -export const parseComments = comments => { +export const parseComments = (comments, currentUserName) => { forEach(comments, comment => { comment.pending_payout_value = parseFloat(comment.pending_payout_value).toFixed(3); comment.vote_count = comment.active_votes.length; @@ -107,6 +107,12 @@ export const parseComments = comments => { comment.markdownBody = comment.body; comment.body = renderPostBody(comment); comment.summary = `"${postBodySummary(comment, 100, true)}"`; + + if (currentUserName) { + comment.is_voted = isVoted(comment.active_votes, currentUserName); + } else { + comment.is_voted = false; + } }); return comments; }; From 0d76c08de59ea911d827720c4df4b528c7af68aa Mon Sep 17 00:00:00 2001 From: u-e Date: Mon, 17 Jun 2019 23:43:32 +0300 Subject: [PATCH 2/8] wip on comments vote --- .../comments/container/commentsContainer.js | 25 +++--- src/providers/steem/dsteem.js | 81 +++++++++++++------ src/utils/postParser.js | 57 ++++++++----- 3 files changed, 108 insertions(+), 55 deletions(-) diff --git a/src/components/comments/container/commentsContainer.js b/src/components/comments/container/commentsContainer.js index 978900452..076f7cba9 100644 --- a/src/components/comments/container/commentsContainer.js +++ b/src/components/comments/container/commentsContainer.js @@ -5,7 +5,7 @@ import { injectIntl } from 'react-intl'; import get from 'lodash/get'; import { getComments, deleteComment } from '../../../providers/steem/dsteem'; - +import { parseComments } from '../../../utils/postParser'; // Services and Actions import { writeToClipboard } from '../../../utils/clipboard'; import { toastNotification } from '../../../redux/actions/uiAction'; @@ -56,9 +56,9 @@ class CommentsContainer extends Component { const { comments: parent } = this.state; const allPayout = c => - parseFloat(c.pending_payout_value.split(' ')[0]) + - parseFloat(c.total_payout_value.split(' ')[0]) + - parseFloat(c.curator_payout_value.split(' ')[0]); + parseFloat(get(c, 'pending_payout_value').split(' ')[0]) + + parseFloat(get(c, 'total_payout_value').split(' ')[0]) + + parseFloat(get(c, 'curator_payout_value').split(' ')[0]); const absNegative = a => a.net_rshares < 0; @@ -122,17 +122,22 @@ class CommentsContainer extends Component { return parent; }; - _getComments = () => { + _getComments = async () => { const { author, permlink, currentAccount: { name }, } = this.props; + let com; - getComments(author, permlink, name).then(comments => { - this.setState({ - comments, - }); + await getComments(author, permlink, name) + .then(async comments => { + com = comments; + }) + .catch(() => {}); + + await this.setState({ + comments: await parseComments(com, name), }); }; @@ -218,7 +223,7 @@ class CommentsContainer extends Component { isShowMoreButton={isShowMoreButton} commentNumber={commentNumber || 1} commentCount={commentCount} - comments={_comments || comments} + comments={parseComments(_comments || comments, currentAccount.name)} currentAccountUsername={currentAccount.name} handleOnEditPress={this._handleOnEditPress} handleOnReplyPress={this._handleOnReplyPress} diff --git a/src/providers/steem/dsteem.js b/src/providers/steem/dsteem.js index 77bc57fd2..915d143ba 100644 --- a/src/providers/steem/dsteem.js +++ b/src/providers/steem/dsteem.js @@ -65,13 +65,13 @@ export const fetchGlobalProps = async () => { } const steemPerMVests = - (parseToken(globalDynamic.total_vesting_fund_steem) / - parseToken(globalDynamic.total_vesting_shares)) * + (parseToken(get(globalDynamic, 'total_vesting_fund_steem')) / + parseToken(get(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 base = parseToken(get(feedHistory, 'current_median_history.base')); + const quote = parseToken(get(feedHistory, 'current_median_history.quote')); + const fundRecentClaims = get(rewardFund, 'recent_claims'); + const fundRewardBalance = parseToken(get(rewardFund, 'reward_balance')); const globalProps = { steemPerMVests, base, @@ -288,8 +288,15 @@ export const getPosts = async (by, query, user) => { } }; -export const getActiveVotes = (author, permlink) => - client.database.call('get_active_votes', [author, permlink]); +export const getActiveVotes = async (author, permlink) => { + if (!author || !permlink) return null; + + try { + return await client.database.call('get_active_votes', [author, permlink]); + } catch (error) { + return error; + } +}; export const getPostsSummary = async (by, query, currentUserName, filterNsfw) => { try { @@ -312,7 +319,7 @@ export const getPostsSummary = async (by, query, currentUserName, filterNsfw) => export const getUserComments = async query => { try { let comments = await client.database.getDiscussions('comments', query); - comments = parseComments(comments); + comments = await parseComments(comments); return comments; } catch (error) { return error; @@ -326,7 +333,7 @@ export const getRepliesByLastUpdate = async query => { query.start_permlink, query.limit, ]); - replies = parseComments(replies); + replies = await parseComments(replies); return replies; } catch (error) { return error; @@ -343,6 +350,8 @@ export const getPost = async (author, permlink, currentUserName = null) => { try { const post = await client.database.call('get_content', [author, permlink]); + const ugur = await getState(`/${post.category}/@${post.author}/${post.permlink}`); + console.log(ugur); return post ? await parsePost(post, currentUserName) : null; } catch (error) { return error; @@ -400,21 +409,43 @@ export const deleteComment = (currentAccount, pin, permlink) => { * @param user post author * @param permlink post permlink */ -export const getComments = (user, permlink, currentUserName) => { - let comments; - return new Promise((resolve, reject) => { - client.database - .call('get_content_replies', [user, permlink]) - .then(result => { - comments = parseComments(result, currentUserName); - }) - .then(() => { - resolve(parseComments(comments, currentUserName)); - }) - .catch(error => { - reject(error); - }); - }); +// export const getComments = async (user, permlink, currentUserName) => { +// return new Promise((resolve, reject) => { +// client.database +// .call('get_content_replies', [user, permlink]) +// .then(async result => { +// const comments = await parseComments(result, currentUserName); +// resolve(comments); +// }) +// .catch(error => { +// reject(error); +// }); +// }); +// }; + +// export const getComments = async (user, permlink, currentUserName) => { +// try { +// const comments = client.database.call('get_content_replies', [user, permlink]); +// const groomedComments = await parseComments(comments, currentUserName); + +// return groomedComments; +// } catch (error) { +// return error; +// } +// }; + +export const getComments = async (author, permlink, currentUserName = null) => { + try { + const post = await client.database.call('get_content_replies', [author, permlink]); + + // const ugur = await getState(`/esteem/@${author}/${permlink}`); + // console.log(post); + // console.log(ugur); + // return post ? await parseComments(post, currentUserName) : null; + return post; + } catch (error) { + return error; + } }; /** diff --git a/src/utils/postParser.js b/src/utils/postParser.js index 7f5ea51b4..374754f90 100644 --- a/src/utils/postParser.js +++ b/src/utils/postParser.js @@ -1,6 +1,12 @@ import isEmpty from 'lodash/isEmpty'; import forEach from 'lodash/forEach'; +import get from 'lodash/get'; + import { postBodySummary, renderPostBody } from '@esteemapp/esteem-render-helpers'; + +// dsteem +import { getActiveVotes } from '../providers/steem/dsteem'; + // Utils import { getReputation } from './reputation'; @@ -47,7 +53,7 @@ export const parsePost = (post, currentUserName) => { forEach(post.active_votes, value => { post.vote_perecent = value.voter === currentUserName ? value.percent : null; value.value = (value.rshares * ratio).toFixed(3); - value.reputation = getReputation(value.reputation); + value.reputation = getReputation(get(value, 'reputation')); value.percent /= 100; value.is_down_vote = Math.sign(value.percent) < 0; value.avatar = `https://steemitimages.com/u/${value.voter}/avatar/small`; @@ -57,9 +63,6 @@ export const parsePost = (post, currentUserName) => { return post; }; -const isVoted = (activeVotes, currentUserName) => - activeVotes.some(v => v.voter === currentUserName && v.percent > 0); - const postImage = (metaData, body) => { const imgTagRegex = /(]*>)/g; const markdownImageRegex = /!\[[^\]]*\]\((.*?)\s*("(?:.*[^"])")?\s*\)/g; @@ -98,21 +101,35 @@ const postImage = (metaData, body) => { return ''; }; -export const parseComments = (comments, currentUserName) => { - forEach(comments, comment => { - comment.pending_payout_value = parseFloat(comment.pending_payout_value).toFixed(3); - comment.vote_count = comment.active_votes.length; - comment.author_reputation = getReputation(comment.author_reputation); - comment.avatar = `https://steemitimages.com/u/${comment.author}/avatar/small`; - comment.markdownBody = comment.body; - comment.body = renderPostBody(comment); - comment.summary = `"${postBodySummary(comment, 100, true)}"`; +export const parseComments = (comments, currentUsername) => + !comments ? null : comments.map(comment => parseComment(comment, currentUsername)); - if (currentUserName) { - comment.is_voted = isVoted(comment.active_votes, currentUserName); - } else { - comment.is_voted = false; - } - }); - return comments; +export const parseComment = async (comment, currentUsername) => { + if (!comment) { + return null; + } + + const activeVotes = await getActiveVotes(get(comment, 'author'), get(comment, 'permlink')); + + comment.pending_payout_value = parseFloat( + get(comment, 'pending_payout_value') ? get(comment, 'pending_payout_value') : 0, + ).toFixed(3); + comment.author_reputation = getReputation(get(comment, 'author_reputation')); + comment.avatar = `https://steemitimages.com/u/${get(comment, 'author')}/avatar/small`; + comment.markdownBody = get(comment, 'body'); + comment.body = renderPostBody(comment); + comment.summary = `"${postBodySummary(comment, 100, true)}"`; + comment.active_votes = activeVotes; + comment.vote_count = activeVotes && activeVotes.length; + + if (currentUsername && activeVotes && activeVotes.length > 0) { + comment.is_voted = isVoted(activeVotes, currentUsername); + } else { + comment.is_voted = false; + } + + return comment; }; + +const isVoted = (activeVotes, currentUserName) => + activeVotes.some(v => v.voter === currentUserName && v.percent > 0); From be799c7fe98c618a727c24bf0a14aa4510a4c0de Mon Sep 17 00:00:00 2001 From: u-e Date: Tue, 18 Jun 2019 23:45:26 +0300 Subject: [PATCH 3/8] created temporary solution && updated for get --- .../UserInterfaceState.xcuserstate | Bin 39826 -> 39831 bytes .../comments/container/commentsContainer.js | 24 ++-- src/components/comments/view/commentsView.js | 6 +- .../upvote/container/upvoteContainer.js | 39 +++--- src/components/upvote/view/upvoteView.js | 19 +-- src/providers/steem/dsteem.js | 127 +++++++----------- src/screens/post/container/postContainer.js | 24 ++-- src/utils/postParser.js | 46 +++---- 8 files changed, 124 insertions(+), 161 deletions(-) diff --git a/ios/eSteem.xcworkspace/xcuserdata/ue.xcuserdatad/UserInterfaceState.xcuserstate b/ios/eSteem.xcworkspace/xcuserdata/ue.xcuserdatad/UserInterfaceState.xcuserstate index a1299563476c825d89a3fc98d17b3dc77e7a6198..3742e98af2033fe980512dae2aa9ea812762987b 100644 GIT binary patch delta 20890 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 delta 20719 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 iKY(%{yKn4)u@}c)8+)hC%? { - const keyA = a.author_reputation; - const keyB = b.author_reputation; + const keyA = get(a, 'author_reputation'); + const keyB = get(b, 'author_reputation'); if (keyA > keyB) return -1; if (keyA < keyB) return 1; @@ -107,8 +106,8 @@ class CommentsContainer extends Component { return -1; } - const keyA = Date.parse(a.created); - const keyB = Date.parse(b.created); + const keyA = Date.parse(get(a, 'created')); + const keyB = Date.parse(get(b, 'created')); if (keyA > keyB) return -1; if (keyA < keyB) return 1; @@ -128,17 +127,14 @@ class CommentsContainer extends Component { permlink, currentAccount: { name }, } = this.props; - let com; await getComments(author, permlink, name) .then(async comments => { - com = comments; + this.setState({ + comments, + }); }) .catch(() => {}); - - await this.setState({ - comments: await parseComments(com, name), - }); }; _handleOnReplyPress = item => { @@ -223,7 +219,7 @@ class CommentsContainer extends Component { isShowMoreButton={isShowMoreButton} commentNumber={commentNumber || 1} commentCount={commentCount} - comments={parseComments(_comments || comments, currentAccount.name)} + comments={_comments || comments} currentAccountUsername={currentAccount.name} handleOnEditPress={this._handleOnEditPress} handleOnReplyPress={this._handleOnReplyPress} diff --git a/src/components/comments/view/commentsView.js b/src/components/comments/view/commentsView.js index 3be5d5571..64b97f08c 100644 --- a/src/components/comments/view/commentsView.js +++ b/src/components/comments/view/commentsView.js @@ -67,7 +67,7 @@ class CommentsView extends PureComponent { mainAuthor={mainAuthor} avatarSize={avatarSize} comment={item} - commentCount={commentCount || item.children} + commentCount={commentCount || get(item.children)} commentNumber={commentNumber} handleDeleteComment={handleDeleteComment} currentAccountUsername={currentAccountUsername} @@ -76,8 +76,8 @@ class CommentsView extends PureComponent { handleOnReplyPress={handleOnReplyPress} handleOnUserPress={handleOnUserPress} isLoggedIn={isLoggedIn} - isShowMoreButton={commentNumber === 1 && item.children > 0} - voteCount={item.net_votes} + isShowMoreButton={commentNumber === 1 && get(item, 'children') > 0} + voteCount={get(item, 'vote_count')} isShowSubComments={isShowSubComments} key={item.permlink} marginLeft={marginLeft} diff --git a/src/components/upvote/container/upvoteContainer.js b/src/components/upvote/container/upvoteContainer.js index c0267b349..5e888c599 100644 --- a/src/components/upvote/container/upvoteContainer.js +++ b/src/components/upvote/container/upvoteContainer.js @@ -1,5 +1,6 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; +import get from 'lodash/get'; // Realm import { setUpvotePercent } from '../../../realm/realm'; @@ -50,31 +51,21 @@ class UpvoteContainer extends PureComponent { upvotePercent, globalProps, } = this.props; - let author; - let authorPayout; - let curationPayout; - let isDecinedPayout; - let isVoted; - let payoutDate; - let pendingPayout; - let permlink; - let promotedPayout; - let totalPayout; - if (content) { - ({ author } = content); - isVoted = content.is_voted; - totalPayout = content.total_payout; - isDecinedPayout = content.is_declined_payout; - ({ permlink } = content); - pendingPayout = parseToken(content.pending_payout_value).toFixed(3); - promotedPayout = parseToken(content.promoted).toFixed(3); - authorPayout = parseToken(content.total_payout_value).toFixed(3); - curationPayout = parseToken(content.curator_payout_value).toFixed(3); - payoutDate = getTimeFromNow( - isEmptyContentDate(content.last_payout) ? content.cashout_time : content.last_payout, - ); - } + const author = get(content, 'author'); + const isVoted = get(content, 'is_voted'); + const totalPayout = get(content, 'total_payout'); + const isDecinedPayout = get(content, 'is_declined_payout'); + const permlink = get(content, 'permlink'); + const pendingPayout = parseToken(get(content, 'pending_payout_value', 0)).toFixed(3); + const promotedPayout = parseToken(get(content, 'promoted', 0)).toFixed(3); + const authorPayout = parseToken(get(content, 'total_payout_value', 0)).toFixed(3); + const curationPayout = parseToken(get(content, 'curator_payout_value', 0)).toFixed(3); + const payoutDate = getTimeFromNow( + isEmptyContentDate(get(content, 'last_payout')) + ? get(content, 'cashout_time') + : get(content, 'last_payout'), + ); return ( { globalProperties.total_vesting_fund_steem, ); account[0].received_steem_power = await vestToSteem( - account[0].received_vesting_shares, - globalProperties.total_vesting_shares, - globalProperties.total_vesting_fund_steem, + get(account[0], 'received_vesting_shares'), + get(globalProperties, 'total_vesting_shares'), + get(globalProperties, 'total_vesting_fund_steem'), ); account[0].delegated_steem_power = await vestToSteem( - account[0].delegated_vesting_shares, - globalProperties.total_vesting_shares, - globalProperties.total_vesting_fund_steem, + get(account[0], 'delegated_vesting_shares'), + get(globalProperties, 'total_vesting_shares'), + get(globalProperties, 'total_vesting_fund_steem'), ); - account[0].about = account[0].json_metadata && JSON.parse(account[0].json_metadata); - account[0].avatar = getAvatar(account[0].about); - account[0].display_name = getName(account[0].about); + account[0].about = + get(account[0], 'json_metadata') && JSON.parse(get(account[0], 'json_metadata')); + account[0].avatar = getAvatar(get(account[0], 'about')); + account[0].display_name = getName(get(account[0], 'about')); return account[0]; } catch (error) { @@ -288,15 +289,17 @@ export const getPosts = async (by, query, user) => { } }; -export const getActiveVotes = async (author, permlink) => { - if (!author || !permlink) return null; - - try { - return await client.database.call('get_active_votes', [author, permlink]); - } catch (error) { - return error; - } -}; +export const getActiveVotes = (author, permlink) => + new Promise((resolve, reject) => { + client.database + .call('get_active_votes', [author, permlink]) + .then(result => { + resolve(result); + }) + .catch(err => { + reject(err); + }); + }); export const getPostsSummary = async (by, query, currentUserName, filterNsfw) => { try { @@ -404,45 +407,17 @@ export const deleteComment = (currentAccount, pin, permlink) => { } }; -/** - * @method getUser get user data - * @param user post author - * @param permlink post permlink - */ -// export const getComments = async (user, permlink, currentUserName) => { -// return new Promise((resolve, reject) => { -// client.database -// .call('get_content_replies', [user, permlink]) -// .then(async result => { -// const comments = await parseComments(result, currentUserName); -// resolve(comments); -// }) -// .catch(error => { -// reject(error); -// }); -// }); -// }; - -// export const getComments = async (user, permlink, currentUserName) => { -// try { -// const comments = client.database.call('get_content_replies', [user, permlink]); -// const groomedComments = await parseComments(comments, currentUserName); - -// return groomedComments; -// } catch (error) { -// return error; -// } -// }; +const wait = ms => new Promise(r => setTimeout(r, ms)); export const getComments = async (author, permlink, currentUserName = null) => { try { - const post = await client.database.call('get_content_replies', [author, permlink]); + const comments = await client.database.call('get_content_replies', [author, permlink]); - // const ugur = await getState(`/esteem/@${author}/${permlink}`); - // console.log(post); - // console.log(ugur); - // return post ? await parseComments(post, currentUserName) : null; - return post; + const groomedComments = await parseComments(comments, currentUserName); + // WORK ARROUND + await wait(comments && comments.length * 30); + + return comments ? groomedComments : null; } catch (error) { return error; } @@ -548,15 +523,15 @@ export const upvoteAmount = async input => { export const transferToken = (currentAccount, pin, data) => { const digitPinCode = getDigitPinCode(pin); - const key = getAnyPrivateKey({ activeKey: currentAccount.local.activeKey }, digitPinCode); + const key = getAnyPrivateKey({ activeKey: get(currentAccount, 'local.activeKey') }, digitPinCode); if (key) { const privateKey = PrivateKey.fromString(key); const args = { - from: data.from, - to: data.destination, - amount: data.amount, - memo: data.memo, + from: get(data, 'from'), + to: get(data, 'destination'), + amount: get(data, 'amount'), + memo: get(data, 'memo'), }; return new Promise((resolve, reject) => { @@ -564,7 +539,7 @@ export const transferToken = (currentAccount, pin, data) => { .transfer(args, privateKey) .then(result => { if (result) { - transfer(data.from, data.destination, data.ammount); + transfer(get(data, 'from'), get(data, 'destination'), get(data, 'ammount')); resolve(result); } }) @@ -579,7 +554,7 @@ export const transferToken = (currentAccount, pin, data) => { export const transferToSavings = (currentAccount, pin, data) => { const digitPinCode = getDigitPinCode(pin); - const key = getAnyPrivateKey({ activeKey: currentAccount.local.activeKey }, digitPinCode); + const key = getAnyPrivateKey({ activeKey: get(currentAccount, 'local.activeKey') }, digitPinCode); if (key) { const privateKey = PrivateKey.fromString(key); @@ -588,10 +563,10 @@ export const transferToSavings = (currentAccount, pin, data) => { [ 'transfer_to_savings', { - from: data.from, - to: data.destination, - amount: data.amount, - memo: data.memo, + from: get(data, 'from'), + to: get(data, 'destination'), + amount: get(data, 'amount'), + memo: get(data, 'memo'), }, ], ]; @@ -613,7 +588,7 @@ export const transferToSavings = (currentAccount, pin, data) => { export const transferFromSavings = (currentAccount, pin, data) => { const digitPinCode = getDigitPinCode(pin); - const key = getAnyPrivateKey({ activeKey: currentAccount.local.activeKey }, digitPinCode); + const key = getAnyPrivateKey({ activeKey: get(currentAccount, 'local.activeKey') }, digitPinCode); if (key) { const privateKey = PrivateKey.fromString(key); @@ -621,11 +596,11 @@ export const transferFromSavings = (currentAccount, pin, data) => { [ 'transfer_from_savings', { - from: data.from, - to: data.destination, - amount: data.amount, - memo: data.memo, - request_id: data.requestId, + from: get(data, 'from'), + to: get(data, 'destination'), + amount: get(data, 'amount'), + memo: get(data, 'memo'), + request_id: get(data, 'requestId'), }, ], ]; @@ -647,7 +622,7 @@ export const transferFromSavings = (currentAccount, pin, data) => { export const transferToVesting = (currentAccount, pin, data) => { const digitPinCode = getDigitPinCode(pin); - const key = getAnyPrivateKey({ activeKey: currentAccount.local.activeKey }, digitPinCode); + const key = getAnyPrivateKey({ activeKey: get(currentAccount, 'local.activeKey') }, digitPinCode); if (key) { const privateKey = PrivateKey.fromString(key); @@ -682,7 +657,7 @@ export const followUser = async (currentAccount, pin, data) => { const key = getAnyPrivateKey(currentAccount.local, digitPinCode); if (currentAccount.local.authType === AUTH_TYPE.STEEM_CONNECT) { - const token = decryptKey(currentAccount.local.accessToken, digitPinCode); + const token = decryptKey(get(currentAccount, 'local.accessToken'), digitPinCode); const api = steemConnect.Initialize({ accessToken: token, }); @@ -1013,15 +988,15 @@ const _reblog = async (account, pinCode, author, permlink) => { export const claimRewardBalance = (account, pinCode, rewardSteem, rewardSbd, rewardVests) => { const pin = getDigitPinCode(pinCode); - const key = getAnyPrivateKey(account.local, pin); + const key = getAnyPrivateKey(get(account, 'local'), pin); if (account.local.authType === AUTH_TYPE.STEEM_CONNECT) { - const token = decryptKey(account.local.accessToken, pin); + const token = decryptKey(get(account, 'local.accessToken'), pin); const api = steemConnect.Initialize({ accessToken: token, }); - return api.claimRewardBalance(account.name, rewardSteem, rewardSbd, rewardVests); + return api.claimRewardBalance(get(account, 'name'), rewardSteem, rewardSbd, rewardVests); } if (key) { @@ -1047,7 +1022,7 @@ export const claimRewardBalance = (account, pinCode, rewardSteem, rewardSbd, rew export const transferPoint = (currentAccount, pinCode, data) => { const pin = getDigitPinCode(pinCode); - const key = getActiveKey(currentAccount.local, pin); + const key = getActiveKey(get(currentAccount, 'local'), pin); const username = get(currentAccount, 'name'); const json = JSON.stringify({ diff --git a/src/screens/post/container/postContainer.js b/src/screens/post/container/postContainer.js index d71956ca4..2ee5efc9a 100644 --- a/src/screens/post/container/postContainer.js +++ b/src/screens/post/container/postContainer.js @@ -1,6 +1,8 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { withNavigation } from 'react-navigation'; +import get from 'lodash/get'; + // Services and Actions import { getPost } from '../../../providers/steem/dsteem'; @@ -29,8 +31,10 @@ class PostContainer extends Component { // Component Life Cycle Functions componentDidMount() { const { navigation } = this.props; - const { content, permlink, author, isNewPost, isHasParentPost } = - navigation.state && navigation.state.params; + const { content, permlink, author, isNewPost, isHasParentPost } = get( + navigation, + 'state.params', + ); if (isNewPost) this.setState({ isNewPost }); @@ -45,11 +49,10 @@ class PostContainer extends Component { componentWillReceiveProps(nextProps) { const { navigation } = this.props; - const { isFetch: nextIsFetch } = - nextProps.navigation.state && nextProps.navigation.state.params; + const { isFetch: nextIsFetch } = get(nextProps, 'navigation.state.params'); if (nextIsFetch) { - const { author, permlink } = navigation.state && navigation.state.params; + const { author, permlink } = get(navigation, 'state.params'); this._loadPost(author, permlink); } @@ -61,12 +64,12 @@ class PostContainer extends Component { const { currentAccount, isLoggedIn } = this.props; const { post } = this.state; - const _author = author || post.author; - const _permlink = permlink || post.permlink; + const _author = author || get(post, 'author'); + const _permlink = permlink || get(post, 'permlink'); - await getPost(_author, _permlink, isLoggedIn && currentAccount.username) + await getPost(_author, _permlink, isLoggedIn && get(currentAccount, 'username')) .then(result => { - if (result && result.id > 0) { + if (get(result, 'id', 0) > 0) { if (isParentPost) { this.setState({ parentPost: result }); } else { @@ -93,7 +96,8 @@ class PostContainer extends Component { author, } = this.state; - if (isHasParentPost && post) this._loadPost(post.parent_author, post.parent_permlink, true); + if (isHasParentPost && post) + this._loadPost(get(post, 'parent_author'), get(post, 'parent_permlink'), true); return ( { return ''; }; -export const parseComments = (comments, currentUsername) => - !comments ? null : comments.map(comment => parseComment(comment, currentUsername)); +export const parseComments = async (comments, currentUserName) => { + const _comments = await comments.map(async comment => { + const activeVotes = await getActiveVotes(get(comment, 'author'), get(comment, 'permlink')); -export const parseComment = async (comment, currentUsername) => { - if (!comment) { - return null; - } + comment.pending_payout_value = parseFloat( + get(comment, 'pending_payout_value') ? get(comment, 'pending_payout_value') : 0, + ).toFixed(3); + comment.author_reputation = getReputation(get(comment, 'author_reputation')); + comment.avatar = `https://steemitimages.com/u/${get(comment, 'author')}/avatar/small`; + comment.markdownBody = get(comment, 'body'); + comment.body = renderPostBody(comment); + comment.active_votes = activeVotes; + comment.vote_count = activeVotes && activeVotes.length; - const activeVotes = await getActiveVotes(get(comment, 'author'), get(comment, 'permlink')); + if (currentUserName && activeVotes && activeVotes.length > 0) { + comment.is_voted = isVoted(activeVotes, currentUserName); + } else { + comment.is_voted = false; + } - comment.pending_payout_value = parseFloat( - get(comment, 'pending_payout_value') ? get(comment, 'pending_payout_value') : 0, - ).toFixed(3); - comment.author_reputation = getReputation(get(comment, 'author_reputation')); - comment.avatar = `https://steemitimages.com/u/${get(comment, 'author')}/avatar/small`; - comment.markdownBody = get(comment, 'body'); - comment.body = renderPostBody(comment); - comment.summary = `"${postBodySummary(comment, 100, true)}"`; - comment.active_votes = activeVotes; - comment.vote_count = activeVotes && activeVotes.length; + return _comments; + }); - if (currentUsername && activeVotes && activeVotes.length > 0) { - comment.is_voted = isVoted(activeVotes, currentUsername); - } else { - comment.is_voted = false; - } - - return comment; + return comments; }; const isVoted = (activeVotes, currentUserName) => From 8196a564a534ebcdf18cf23f43cd40b2c7a93669 Mon Sep 17 00:00:00 2001 From: Mustafa Buyukcelebi Date: Thu, 20 Jun 2019 13:03:18 +0300 Subject: [PATCH 4/8] Removed reblog option from reblogged posts --- src/components/postCard/container/postCardContainer.js | 3 ++- src/components/postCard/view/postCardView.js | 8 ++++++-- .../postDropdown/container/postDropdownContainer.js | 4 ++-- src/components/posts/view/postsView.js | 8 +++++++- src/screens/profile/screen/profileScreen.js | 1 + 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/components/postCard/container/postCardContainer.js b/src/components/postCard/container/postCardContainer.js index 5b725d2a9..7b0f07a41 100644 --- a/src/components/postCard/container/postCardContainer.js +++ b/src/components/postCard/container/postCardContainer.js @@ -82,7 +82,7 @@ class PostCardContainer extends PureComponent { }; render() { - const { content, isHideImage, nsfw } = this.props; + const { content, isHideImage, nsfw, hideReblogOption } = this.props; const { _content } = this.state; const isNsfwPost = nsfw === '1'; @@ -96,6 +96,7 @@ class PostCardContainer extends PureComponent { content={_content || content} isHideImage={isHideImage} isNsfwPost={isNsfwPost} + hideReblogOption={hideReblogOption} /> ); } diff --git a/src/components/postCard/view/postCardView.js b/src/components/postCard/view/postCardView.js index ca7f2d397..0a7b15a26 100644 --- a/src/components/postCard/view/postCardView.js +++ b/src/components/postCard/view/postCardView.js @@ -68,7 +68,7 @@ class PostCardView extends Component { }; render() { - const { content, isHideImage, fetchPost, isNsfwPost } = this.props; + const { content, isHideImage, fetchPost, isNsfwPost, hideReblogOption } = this.props; const _image = this._getPostImage(content, isNsfwPost); const reblogedBy = content.reblogged_by && content.reblogged_by[0]; @@ -88,7 +88,11 @@ class PostCardView extends Component { reblogedBy={reblogedBy} /> - + diff --git a/src/components/postDropdown/container/postDropdownContainer.js b/src/components/postDropdown/container/postDropdownContainer.js index 8f973c348..f16e73c5a 100644 --- a/src/components/postDropdown/container/postDropdownContainer.js +++ b/src/components/postDropdown/container/postDropdownContainer.js @@ -173,10 +173,10 @@ class PostDropdownContainer extends PureComponent { }; render() { - const { intl, currentAccount, content } = this.props; + const { intl, currentAccount, content, hideReblogOption } = this.props; let _OPTIONS = OPTIONS; - if (content && content.author === currentAccount.name) { + if ((content && content.author === currentAccount.name) || hideReblogOption) { _OPTIONS = OPTIONS.filter(item => item !== 'reblog'); } diff --git a/src/components/posts/view/postsView.js b/src/components/posts/view/postsView.js index edb944429..aab1bb92a 100644 --- a/src/components/posts/view/postsView.js +++ b/src/components/posts/view/postsView.js @@ -228,6 +228,7 @@ class PostsView extends Component { isLoginDone, tag, isDarkTheme, + hideReblogOption, } = this.props; return ( @@ -262,7 +263,12 @@ class PostsView extends Component { data={posts} showsVerticalScrollIndicator={false} renderItem={({ item }) => ( - + )} keyExtractor={(post, index) => index.toString()} onEndReached={() => this._loadPosts()} diff --git a/src/screens/profile/screen/profileScreen.js b/src/screens/profile/screen/profileScreen.js index ed52da15a..d6ffc0904 100644 --- a/src/screens/profile/screen/profileScreen.js +++ b/src/screens/profile/screen/profileScreen.js @@ -206,6 +206,7 @@ class ProfileScreen extends PureComponent { tag={username} key={username} handleOnScroll={this._handleOnScroll} + hideReblogOption /> Date: Thu, 20 Jun 2019 20:19:58 +0300 Subject: [PATCH 5/8] Update commentsContainer.js --- src/components/comments/container/commentsContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/comments/container/commentsContainer.js b/src/components/comments/container/commentsContainer.js index 615646102..1c4f7d9c6 100644 --- a/src/components/comments/container/commentsContainer.js +++ b/src/components/comments/container/commentsContainer.js @@ -129,7 +129,7 @@ class CommentsContainer extends Component { } = this.props; await getComments(author, permlink, name) - .then(async comments => { + .then(comments => { this.setState({ comments, }); From 78f05872372da72f6e8029c7f969a991b564d45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?u=C4=9Fur=20erdal?= Date: Thu, 20 Jun 2019 20:21:07 +0300 Subject: [PATCH 6/8] Update dsteem.js --- src/providers/steem/dsteem.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/providers/steem/dsteem.js b/src/providers/steem/dsteem.js index 6b9962a65..991242ffc 100644 --- a/src/providers/steem/dsteem.js +++ b/src/providers/steem/dsteem.js @@ -353,8 +353,6 @@ export const getPost = async (author, permlink, currentUserName = null) => { try { const post = await client.database.call('get_content', [author, permlink]); - const ugur = await getState(`/${post.category}/@${post.author}/${post.permlink}`); - console.log(ugur); return post ? await parsePost(post, currentUserName) : null; } catch (error) { return error; From e512d124800a34acd9a1a65f9cd34be236cbee6b Mon Sep 17 00:00:00 2001 From: Mustafa Buyukcelebi Date: Fri, 21 Jun 2019 11:28:55 +0300 Subject: [PATCH 7/8] Fixed comment requirements --- .../postCard/container/postCardContainer.js | 4 ++-- src/components/postCard/view/postCardView.js | 4 ++-- .../container/postDropdownContainer.js | 4 ++-- src/components/posts/view/postsView.js | 18 +++++++++--------- src/screens/profile/screen/profileScreen.js | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/postCard/container/postCardContainer.js b/src/components/postCard/container/postCardContainer.js index 7b0f07a41..236074365 100644 --- a/src/components/postCard/container/postCardContainer.js +++ b/src/components/postCard/container/postCardContainer.js @@ -82,7 +82,7 @@ class PostCardContainer extends PureComponent { }; render() { - const { content, isHideImage, nsfw, hideReblogOption } = this.props; + const { content, isHideImage, nsfw, isHideReblogOption } = this.props; const { _content } = this.state; const isNsfwPost = nsfw === '1'; @@ -96,7 +96,7 @@ class PostCardContainer extends PureComponent { content={_content || content} isHideImage={isHideImage} isNsfwPost={isNsfwPost} - hideReblogOption={hideReblogOption} + isHideReblogOption={isHideReblogOption} /> ); } diff --git a/src/components/postCard/view/postCardView.js b/src/components/postCard/view/postCardView.js index 0a7b15a26..5d719cfba 100644 --- a/src/components/postCard/view/postCardView.js +++ b/src/components/postCard/view/postCardView.js @@ -68,7 +68,7 @@ class PostCardView extends Component { }; render() { - const { content, isHideImage, fetchPost, isNsfwPost, hideReblogOption } = this.props; + const { content, isHideImage, fetchPost, isNsfwPost, isHideReblogOption } = this.props; const _image = this._getPostImage(content, isNsfwPost); const reblogedBy = content.reblogged_by && content.reblogged_by[0]; @@ -89,7 +89,7 @@ class PostCardView extends Component { /> diff --git a/src/components/postDropdown/container/postDropdownContainer.js b/src/components/postDropdown/container/postDropdownContainer.js index f16e73c5a..45fdf0d4c 100644 --- a/src/components/postDropdown/container/postDropdownContainer.js +++ b/src/components/postDropdown/container/postDropdownContainer.js @@ -173,10 +173,10 @@ class PostDropdownContainer extends PureComponent { }; render() { - const { intl, currentAccount, content, hideReblogOption } = this.props; + const { intl, currentAccount, content, isHideReblogOption } = this.props; let _OPTIONS = OPTIONS; - if ((content && content.author === currentAccount.name) || hideReblogOption) { + if ((content && content.author === currentAccount.name) || isHideReblogOption) { _OPTIONS = OPTIONS.filter(item => item !== 'reblog'); } diff --git a/src/components/posts/view/postsView.js b/src/components/posts/view/postsView.js index aab1bb92a..ab4c38c0a 100644 --- a/src/components/posts/view/postsView.js +++ b/src/components/posts/view/postsView.js @@ -228,7 +228,7 @@ class PostsView extends Component { isLoginDone, tag, isDarkTheme, - hideReblogOption, + isHideReblogOption, } = this.props; return ( @@ -264,7 +264,7 @@ class PostsView extends Component { showsVerticalScrollIndicator={false} renderItem={({ item }) => ( this._handleOnScrollStart()} refreshControl={ + refreshing={refreshing} + onRefresh={this._handleOnRefreshPosts} + progressBackgroundColor="#357CE6" + tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'} + titleColor="#fff" + colors={['#fff']} + /> } ref={ref => { this.flatList = ref; diff --git a/src/screens/profile/screen/profileScreen.js b/src/screens/profile/screen/profileScreen.js index d6ffc0904..81115309f 100644 --- a/src/screens/profile/screen/profileScreen.js +++ b/src/screens/profile/screen/profileScreen.js @@ -206,7 +206,7 @@ class ProfileScreen extends PureComponent { tag={username} key={username} handleOnScroll={this._handleOnScroll} - hideReblogOption + isHideReblogOption /> Date: Fri, 21 Jun 2019 12:52:02 +0300 Subject: [PATCH 8/8] Fixed search issue on following page --- src/screens/follows/container/followsContainer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/screens/follows/container/followsContainer.js b/src/screens/follows/container/followsContainer.js index c7079d155..3d2b3c8ac 100644 --- a/src/screens/follows/container/followsContainer.js +++ b/src/screens/follows/container/followsContainer.js @@ -1,10 +1,8 @@ import React, { Component } from 'react'; +import get from 'lodash/get'; // Middleware -// Constants -import { default as ROUTES } from '../../../constants/routeNames'; - // Utilities // Services and Actions @@ -83,11 +81,13 @@ class FollowsContainer extends Component { }; _handleSearch = async text => { - const { users, username } = this.state; + const { users, username, isFollowingPress } = this.state; let newData; newData = users.filter(item => { - const itemName = item.follower.toUpperCase(); + const itemName = isFollowingPress + ? get(item, 'following').toUpperCase() + : get(item, 'follower').toUpperCase(); const _text = text.toUpperCase(); return itemName.indexOf(_text) > -1;