[KnackSteem] - Comments, Upvote, Delete, Refactor-Fun

in #utopian-io6 years ago (edited)

The new PR is about showing comments correctly, being able to upvote and delete comments and a lot of other things. This PR includes some refactoring, which is the base for the upcoming edit and reply functionality.

Repository & Pull Request

https://github.com/knacksteem/knacksteem.org
https://github.com/knacksteem/knacksteem.org/pull/10

About knacksteem.org

"Do you have any talent? If yes! then KnackSteem is for you."
"Rewards people with talents, it can be any talent, anything you know how to do best is highly welcome on the platform."

Technology Stack

JavaScript ES6+ with Babel
React + Redux
Ant Design

Changes / New Features

  • Implement upvote function with Steem Connect.
  • Implement delete function with Steem Connect.
  • Show links for reply/edit/delete conditionally.
  • Show filled upvote icon if upvoted by yourself.
  • Show correct number of comments and upvotes.
  • Make comments visible in the article detail page.
  • Show payout value on all articles and comments.
  • Switch from HTML preview to Markdown preview with ReactMarkdown.
  • Delete function for unvoted/uncommented posts.
  • Refactor Editor to be a separate component.
  • Lots of bugfixes and refactors.

Edit and reply are not fully implemented yet. There is an edit action already, but I am waiting for the backend to provide an edit route. I believe it´s being implemented as we speak though :)

Screenshots

Article List

screen1.png

Article Detail

screen2.png

Details

The new Editor component can now be used anywhere, before it was implemented directly in the route for new contributions. That route is just a stateless function with a few lines now:

/**
 * Route for adding a new article/contribution with rich text editor
 */
const NewContribution = () => {
  return (
    <div className="editor">
      <Content>
        <Editor isComment={false} isEdit={false} />
      </Content>
    </div>
  );
};

(containers/NewContribution/index.js)

The component needs those props in order to show tags (there are no tags for comments) and to know if the article is a new one or if the Editor needs to be prefilled for updating. We could omit the props for new contributions because they are set to their defaults, but it´s good to set them anyway:

Editor.propTypes = {
  dispatch: PropTypes.func,
  articles: PropTypes.object,
  isComment: PropTypes.bool,
  isEdit: PropTypes.bool,
  articleData: PropTypes.object
};

Editor.defaultProps = {
  isComment: false,
  isEdit: false
};

(components/Editor/index.js)

Comments needed to be loaded recursively, this was solved with two React components. One for holding the comments in general, it´s a simple stateless function again:

const Comments = ({data, onUpvoteSuccess}) => {
  return (
    <div>
      {data.map((elem) => {
        return (
          <SingleComment key={elem.permlink} data={elem} onUpvoteSuccess={onUpvoteSuccess} />
        );
      })}
    </div>
  );
};

(components/Comments/index.js)

The second component is more interesting, it holds one single comment and all its replies - replies are using the exact same component again, and so on.

class SingleComment extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isEditMode: false
    };
  }
  render() {
    const {data, onUpvoteSuccess} = this.props;

    return (
      <div className="ant-list-item comment">
        <div>
          <Avatar src={data.authorImage} className="comment-avatar" />
          <span>{data.author} ({data.authorReputation})</span>
          <ReactMarkdown source={data.description} />
          <ArticleMetaBottom data={data} onUpdate={onUpvoteSuccess} isComment />
        </div>
        <div className="replies">
          {data.replies.map((elem) => {
            return (
              <SingleComment key={elem.permlink} data={elem} isReply onUpvoteSuccess={onUpvoteSuccess} />
            );
          })}
        </div>
      </div>
    );
  }
}

(components/Comments/SingleComment.js)

As you can see, there is a state variable called "isEditMode", it will later be used to show the new Editor component. The "isReply" prop is not in use right now. Maybe we need to know if it´s a reply comment or a direct comment of the parent article sooner or later, who knows.

Deleting and upvoting is done with a redux action, both actions return a promise so we can react when they are finished. We don´t need to use the backend for this, it´s all just Steem Connect. Deleting was a bit tricky, because there does not seem to be a delete API. No problem with the broadcast API though:

/**
 * delete article or comment
 * @param permlink permalink of the article of comment
 */
export const deleteElement = (permlink) => {
  return async (dispatch, getState) => {
    const store = getState();

    let api = sc2.Initialize({
      app: 'knacksteem.app',
      callbackURL: Config.SteemConnect.callbackURL,
      accessToken: store.user.accessToken,
      scope: Config.SteemConnect.scope
    });

    //use broadcast operation to delete comment
    return await api.broadcast([
      ['delete_comment', {
        'author': store.user.username,
        'permlink': permlink
      }]
    ]);
  };
};

(actions/articles.js)

Voting is easier, and right now we just upvote with 100% weight - there are plans to implement something cool for the weight selection :)

/**
 * upvote article or comment
 * @param author author of the article or comment
 * @param permlink permalink of the article of comment
 * @param weight weight of the upvote (10000 is 100%)
 */
export const upvoteElement = (author, permlink, weight) => {
  return async (dispatch, getState) => {
    const store = getState();

    let api = sc2.Initialize({
      app: 'knacksteem.app',
      callbackURL: Config.SteemConnect.callbackURL,
      accessToken: store.user.accessToken,
      scope: Config.SteemConnect.scope
    });

    return await api.vote(store.user.username, author, permlink, weight);
  };
};

(actions/articles.js)

Roadmap

  • Implement reply and edit functionality for comments and articles.
  • User route/list for moderative actions.
  • Bugfixing
  • ...

How to contribute?
Talk to @knowledges (or me) :)


My GitHub Account: https://github.com/ateufel

Sort:  

Hey @luschn
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Thank you for your contribution. Again a great contribution.
Liked the way of commits and nice comments.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

G’day mate! and I Upvoted you :) !
:
“When you are suffering from sexual starvation, a spank or even a hug seems like a porn scene.” ====> Mokokoma Mokhonoana

Congratulations @luschn! You have completed the following achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Do not miss the last post from @steemitboard:
SteemitBoard World Cup Contest - The results, the winners and the prizes

Do you like SteemitBoard's project? Then Vote for its witness and get one more award!

Coin Marketplace

STEEM 0.19
TRX 0.15
JST 0.029
BTC 63931.73
ETH 2663.43
USDT 1.00
SBD 2.84