Skip to content
This repository has been archived by the owner on May 7, 2021. It is now read-only.

Comments! View, Write and Post Comments! #8

Merged
merged 9 commits into from
Mar 22, 2019
5 changes: 5 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"js-cookie": "^2.2.0",
"lodash": "^4.17.11",
"log4javascript": "^1.4.15",
"marked": "^0.6.1",
"moment": "^2.23.0",
"prop-types": "^15.6.2",
"react": "^16.6.3",
Expand Down
7 changes: 7 additions & 0 deletions client/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
text-align: center;
}

body {
font-size: 1rem;
}

a {
color: var(--medium-blue)
}
a:hover {
color: var(--light-blue)
}

Expand Down
32 changes: 30 additions & 2 deletions client/src/actions/authActions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import axios from 'axios';
import Cookies from 'js-cookie';

import SteemConnect from '../utils/auth/scAPI';
import {SC_COOKIE} from '../settings';

export const REQUEST_RETURNING = 'REQUEST_RETURNING';
export const RECEIVE_RETURNING = 'RECEIVE_RETURNING';
Expand Down Expand Up @@ -80,13 +84,37 @@ export const receiveLogin = (res) => ({
* @param {function} dispatch Redux dispatch function
* @returns {function} Dispatches returned action object
*/
const fetchReturning = () => dispatch => {
const fetchReturning = () => async dispatch => {
dispatch(requestReturning());

return axios.get('/api/auth/returning', {
}).then(res => {
const accessToken = Cookies.get(SC_COOKIE);
validateToken(accessToken)
.then(valid => {
if (valid) {
dispatch(receiveReturning(res));
}
})
});



/*return axios.get('/api/auth/returning', {
}).then(res => {
dispatch(receiveReturning(res));
});
});*/
}

const validateToken = (accessToken) => {
//TODO:what happens if stemconnect is offline? test it
return new Promise((resolve, reject) => {
SteemConnect.setAccessToken(accessToken);
SteemConnect.me((err, result) => {
(!err) ? resolve(true) : reject(false);
})
resolve(true);
});
}

/**
Expand Down
181 changes: 169 additions & 12 deletions client/src/actions/steemContentActions.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//import axios from 'axios';
import axios from 'axios';
import { Client } from 'dsteem';
import Cookies from 'js-cookie';

import { getUserGroups, addPost, logger, upvote } from '../utils/fetchFunctions';
import { getUserGroups, addPost, logger } from '../utils/fetchFunctions';
import SteemConnect from '../utils/auth/scAPI';
import {SC_COOKIE} from '../settings';
import { createPostMetadata, createCommentPermlink } from '../components/pages/Kurate/helpers/postHelpers';

const client = new Client('https://hive.anyx.io/');

Expand All @@ -21,6 +21,12 @@ export const MODAL_SHOW = 'MODAL_SHOW';
export const MODAL_CLOSE = 'MODAL_CLOSE';
export const UPVOTE_START = 'UPVOTE_START';
export const UPVOTE_SUCCESS = 'UPVOTE_SUCCESS';
export const GET_COMMENTS_START = 'GET_COMMENTS_START';
export const GET_COMMENTS_SUCCESS = 'GET_COMMENTS_SUCCESS';
export const SEND_COMMENT_START = 'SEND_COMMENT_START';
export const SEND_COMMENT_SUCCESS = 'SEND_COMMENT_SUCCESS';
export const GET_COMMENT_START = 'GET_COMMENT_START';
export const GET_COMMENT_SUCCESS = 'GET_COMMENT_START';

/**
* Action creator for starting retrieval of post summary data.
Expand Down Expand Up @@ -64,6 +70,26 @@ export const detailsSuccess = (post) => ({
post,
});

/**
* Action creator for starting retrieval of comments data.
*
* @return {object} The action data
*/
export const commentsStart = () => ({
type: GET_COMMENTS_START,
});

/**
* Action creator for successful retrieval of comments data.
*
* @param {object} comments Post to display
* @return {object} The action data
*/
export const commentsSuccess = (comments) => ({
type: GET_COMMENTS_SUCCESS,
comments,
});

/**
* Action creator for successful retrieval of group data.
*
Expand Down Expand Up @@ -144,7 +170,10 @@ export const upvoteStart = (author, permlink) => ({
payload: {
author,
permlink,
voters: [],
post: {
id: 0,
active_votes: [],
},
}
});

Expand All @@ -155,15 +184,37 @@ export const upvoteStart = (author, permlink) => ({
* @param {string} permlink Permlink of post
* @return {object} The action data
*/
export const upvoteSuccess = (author, permlink, voters) => ({
export const upvoteSuccess = (author, permlink, post) => ({
type: UPVOTE_SUCCESS,
payload: {
author,
permlink,
voters,
post,
}
});

/**
* Action creator for starting to send a comment.
*
* @return {object} The action data
*/
export const sendCommentStart = () => ({
type: SEND_COMMENT_START,
});

/**
* Action creator for successfully sending a comment.
*
* @param {string} comment Comment added to post
* @param {string} parentId Id of parent post being commented on
* @return {object} The action data
*/
export const sendCommentSuccess = (comment, parentId) => ({
type: SEND_COMMENT_SUCCESS,
comment,
parentId,
});

/**
* Fetch the post details from Steem.
*
Expand Down Expand Up @@ -211,12 +262,83 @@ export const getSummaryContent = (selectedFilter, query, nextPost) => (dispatch,
export const getDetailsContent = (author, permlink) => (dispatch, getState) => {
dispatch(detailsStart());
return client.database.call('get_content', [author, permlink])
.then(result => {

.then(post => {
const {user} = getState().auth;
if (user)
dispatch(getGroupsFetch(user));

dispatch(detailsSuccess(post));
})

}

/**
* Fetch the post's comment from Steem.
*
* @param {string} author Author of post
* @param {string} permlink Permlink of post
* @returns {function} Dispatches returned action object
*/
export const getPostComments = (author, permlink) => (dispatch, getState) => {
dispatch(commentsStart());

return postCommentsRecursive(author, permlink)
.then(comments => {
dispatch(commentsSuccess(comments))
});
}

/**
* Recursively get the post's comments.
*
* @param {string} author Author of post
* @param {string} permlink Permlink of post
* @returns {function} Dispatches returned action object
*/
const postCommentsRecursive = (author, permlink) => {
return client.database.call('get_content_replies', [author, permlink])
.then(replies => Promise.all(replies.map(r => {
if (r.children > 0) {
return postCommentsRecursive(r.author, r.permlink)
.then(children => {
r.replies = children;
return r;
})
}else {
return r;
}
}))
);
}

/**
* Get a single comment.
*
* @param {string} author Author of comment
* @param {string} permlink Permlink of comment
* @returns {function} Dispatches returned action object
*/
export const getComment = (author, permlink) => {
return new Promise((resolve, reject) => {
client.database.call('get_content', [author, permlink])
.then(comment => {
resolve(comment);
});
});
}

/**
* Fetch the comments for a user from Steem.
*
* @param {string} author Author of post
* @param {string} permlink Permlink of post
* @returns {function} Dispatches returned action object
*/
export const getUserComments = (author, permlink) => (dispatch, getState) => {
dispatch(detailsStart());
//return client.database.call('get_content_replies', [author, permlink])
return client.database.getDiscussions('comments', {tag: 'krnel'})
.then(result => {
dispatch(detailsSuccess(result));
})
}
Expand Down Expand Up @@ -301,26 +423,61 @@ const addPostFetch = () => (dispatch, getState) => {
*/
export const upvotePost = (author, permlink, weight) => (dispatch, getState) => {
dispatch(upvoteStart(author, permlink));

const {
auth: {
user
},
} = getState();

const accessToken = Cookies.get(SC_COOKIE)
const accessToken = Cookies.get(SC_COOKIE);
SteemConnect.setAccessToken(accessToken);

return SteemConnect.vote(user, author, permlink, weight)
.then(res => {
client.database.call('get_active_votes', [author, permlink])
.then(voters => {
dispatch(upvoteSuccess(author, permlink, voters));
client.database.call('get_content', [author, permlink])
.then(post => {
dispatch(upvoteSuccess(author, permlink, post));
})
}).catch((err) => {
logger({level: 'error', message: {name: err.name, message: err.message, stack: err.stack}});
});
}

/**
* Uses SteemConnect to send a comment to the Steem blockchain.
*
* @param {string} parentPost Parent being commented on
* @param {string} body Comment body
* @returns {function} Dispatches returned action object
*/
export const sendComment = (parentPost, body) => (dispatch, getState) => {
dispatch(sendCommentStart());
const {
auth: {
user
},
} = getState();

const { category, id, permlink: parentPermlink, author: parentAuthor } = parentPost;

const author = user;
const permlink = createCommentPermlink(parentAuthor, parentPermlink)

const jsonMetadata = createPostMetadata(
body,
[category],
);

return SteemConnect
.comment(parentAuthor, parentPermlink, author, permlink, '', body, jsonMetadata)
.then(res => {
if (res.result.block_num) {
getComment(author, permlink)
.then(comment => {
dispatch(sendCommentSuccess(comment, id));
})
}
});
}

export default getSummaryContent;
21 changes: 2 additions & 19 deletions client/src/components/Common/DateFromNow.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
import moment from 'moment';

moment.updateLocale('en', { relativeTime: {
future: 'in %s',
past: '%s ago',
s: 'secs',
ss: '%ss',
m: 'a min',
mm: '%dm',
h: '1h',
hh: '%dh',
d: 'a day',
dd: '%dd',
M: 'month',
MM: '%dM',
y: 'year',
yy: '%dY'
}});
import {short} from '../../utils/timeFromNow';

const DateFromNow = ({ date }) => (
moment.utc(date).fromNow()
short(date)
)

export default DateFromNow;
4 changes: 2 additions & 2 deletions client/src/components/pages/Groups/GroupsCreated.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { Header, Table, Label } from "semantic-ui-react";
import moment from 'moment';

import GroupLink from '../../common/GroupLink';
import UserLink from '../../common/UserLink';
import DateFromNow from '../../common/DateFromNow';

/**
* Show the newly created groups as a table list.
Expand Down Expand Up @@ -34,7 +34,7 @@ const GroupsCreated = ({ groupsCreated}) => {
</Table.Cell>
<Table.Cell collapsing textAlign='center'>{g.posts}</Table.Cell>
<Table.Cell collapsing textAlign='center'>{g.users}</Table.Cell>
<Table.Cell collapsing textAlign='center'>{moment.utc(g.created).fromNow()}</Table.Cell>
<Table.Cell collapsing textAlign='center'><DateFromNow date={g.created} /></Table.Cell>
<Table.Cell collapsing textAlign='center'><UserLink user={g.owner} /></Table.Cell>
</Table.Row>
))
Expand Down
Loading