diff --git a/package.json b/package.json index c3167a0bd..797b97589 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,8 @@ "electron-log": "^2.2.12", "electron-updater": "^4.0.6", "express": "^4.16.4", - "keytar": "^4.4.1" + "keytar": "^4.4.1", + "tiny-relative-date": "^1.3.0" }, "devDependencies": { "@babel/core": "^7.0.0", @@ -122,7 +123,7 @@ "jsmediatags": "^3.8.1", "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", - "lbry-redux": "lbryio/lbry-redux#3c862e72b36e620155b9c968be9b2bcbd9e0580c", + "lbry-redux": "lbryio/lbry-redux#141593500693a93db74c62ef5a9fe67b43896603", "lbryinc": "lbryio/lbryinc#43d382d9b74d396a581a74d87e4c53105e04f845", "lint-staged": "^7.0.2", "localforage": "^1.7.1", @@ -148,7 +149,7 @@ "react-dom": "^16.8.2", "react-feather": "^1.0.8", "react-ga": "^2.5.7", - "react-hot-loader": "^4.7.2", + "react-hot-loader": "^4.11.1", "react-modal": "^3.1.7", "react-paginate": "^5.2.1", "react-pose": "^4.0.5", diff --git a/src/ui/component/comment/index.js b/src/ui/component/comment/index.js new file mode 100644 index 000000000..ec92bc310 --- /dev/null +++ b/src/ui/component/comment/index.js @@ -0,0 +1,7 @@ +import { connect } from 'react-redux'; +import Comment from './view'; + +export default connect( + null, + null +)(Comment); diff --git a/src/ui/component/comment/view.jsx b/src/ui/component/comment/view.jsx new file mode 100644 index 000000000..096f35642 --- /dev/null +++ b/src/ui/component/comment/view.jsx @@ -0,0 +1,36 @@ +// @flow +import React from 'react'; +import relativeDate from 'tiny-relative-date'; + +type Props = { + author: string, + message: string, + timePosted: number, +}; + +function Comment(props: Props) { + const { author, timePosted, message } = props; + + return ( +
  • +
    + {author || __('Anonymous')} + + +
    + +

    {message}

    + {/* The following is for adding threaded replies, upvoting and downvoting */} + {/*
    */} + {/* */} + + {/* */} + {/* */} + {/* */} + {/* */} + {/*
    */} +
  • + ); +} + +export default Comment; diff --git a/src/ui/component/commentCreate/index.js b/src/ui/component/commentCreate/index.js new file mode 100644 index 000000000..cda850b38 --- /dev/null +++ b/src/ui/component/commentCreate/index.js @@ -0,0 +1,17 @@ +import { connect } from 'react-redux'; + +import { doCommentCreate, makeSelectClaimForUri } from 'lbry-redux'; +import { CommentCreate } from './view'; + +const select = (state, props) => ({ + claim: makeSelectClaimForUri(props.uri)(state), +}); + +const perform = dispatch => ({ + createComment: (comment, claimId, channel) => dispatch(doCommentCreate(comment, claimId, channel)), +}); + +export default connect( + select, + perform +)(CommentCreate); diff --git a/src/ui/component/commentCreate/view.jsx b/src/ui/component/commentCreate/view.jsx new file mode 100644 index 000000000..f0da4d393 --- /dev/null +++ b/src/ui/component/commentCreate/view.jsx @@ -0,0 +1,83 @@ +// @flow +import { CHANNEL_NEW } from 'constants/claim'; +import React from 'react'; +import { FormField, Form } from 'component/common/form'; +import Button from 'component/button'; +import ChannelSection from 'component/selectChannel'; +import usePersistedState from 'util/use-persisted-state'; + +type Props = { + uri: string, + claim: StreamClaim, + createComment: (string, string, string) => void, +}; + +export function CommentCreate(props: Props) { + const { createComment, claim } = props; + const { claim_id: claimId } = claim; + const [commentValue, setCommentValue] = usePersistedState(`comment-${claimId}`, ''); + const [commentAck, setCommentAck] = usePersistedState('comment-acknowledge', false); + const [channel, setChannel] = usePersistedState('comment-channel', 'anonymous'); + + function handleCommentChange(event) { + setCommentValue(event.target.value); + } + + function handleChannelChange(channel) { + setChannel(channel); + } + + function handleCommentAck(event) { + setCommentAck(true); + } + function handleSubmit() { + if (channel !== CHANNEL_NEW && commentValue.length) createComment(commentValue, claimId, channel); + setCommentValue(''); + } + + return ( + + {commentAck !== true && ( +
    +
    +
    About comments..
    +
    +
    +
    I acknowledge something.
    +
    +
    +
    +
    + )} + {commentAck === true && ( +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + )} +
    + ); +} diff --git a/src/ui/component/commentsList/index.js b/src/ui/component/commentsList/index.js new file mode 100644 index 000000000..324fe767b --- /dev/null +++ b/src/ui/component/commentsList/index.js @@ -0,0 +1,16 @@ +import { connect } from 'react-redux'; +import { makeSelectCommentsForUri, doCommentList } from 'lbry-redux'; +import CommentsList from './view'; + +const select = (state, props) => ({ + comments: makeSelectCommentsForUri(props.uri)(state), +}); + +const perform = dispatch => ({ + fetchComments: uri => dispatch(doCommentList(uri)), +}); + +export default connect( + select, + perform +)(CommentsList); diff --git a/src/ui/component/commentsList/view.jsx b/src/ui/component/commentsList/view.jsx new file mode 100644 index 000000000..bc4cfbaa7 --- /dev/null +++ b/src/ui/component/commentsList/view.jsx @@ -0,0 +1,38 @@ +// @flow +import React, { useEffect } from 'react'; +import Comment from 'component/comment'; + +type Props = { + comments: Array, + fetchComments: string => void, + uri: string, +}; + +function CommentList(props: Props) { + const { fetchComments, uri, comments } = props; + + useEffect(() => { + fetchComments(uri); + }, [fetchComments, uri]); + + return ( + + ); +} + +export default CommentList; diff --git a/src/ui/component/common/form-components/form-field.jsx b/src/ui/component/common/form-components/form-field.jsx index 17deb99ca..37a9e55e2 100644 --- a/src/ui/component/common/form-components/form-field.jsx +++ b/src/ui/component/common/form-components/form-field.jsx @@ -154,6 +154,7 @@ export class FormField extends React.PureComponent { } else if (type === 'textarea') { input = ( +