flat comments
This commit is contained in:
parent
31178c761f
commit
99c85a2ff7
9 changed files with 542 additions and 591 deletions
|
@ -1,15 +1,14 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { doCommentCreate, makeSelectClaimForUri, selectMyActiveChannelUri } from 'lbry-redux';
|
import { doCommentCreate, makeSelectClaimForUri } from 'lbry-redux';
|
||||||
import CommentCreate from './view';
|
import { CommentCreate } from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
channelUri: selectMyActiveChannelUri(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
createComment: params => dispatch(doCommentCreate(params)),
|
createComment: (comment, claimId, channel) => dispatch(doCommentCreate(comment, claimId, channel)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
|
|
@ -3,91 +3,82 @@ import React from 'react';
|
||||||
import { FormField, Form } from 'component/common/form';
|
import { FormField, Form } from 'component/common/form';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import ChannelSection from 'component/selectChannel';
|
import ChannelSection from 'component/selectChannel';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { COMMENT_ACKNOWLEDGED, COMMENT_ACKNOWLEDGED_TRUE } from 'constants/settings';
|
||||||
import { usePersistedState } from 'util/use-persisted-state';
|
import { usePersistedState } from 'util/use-persisted-state';
|
||||||
|
|
||||||
// props:
|
// props:
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
channelUri: string,
|
claim: StreamClaim,
|
||||||
createComment: params => {},
|
createComment: (string, string, string) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommentCreate extends React.PureComponent<Props> {
|
export function CommentCreate(props: Props) {
|
||||||
constructor(props: Props) {
|
const { createComment, claim } = props;
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
message: '',
|
|
||||||
};
|
|
||||||
// set state or props for comment form
|
|
||||||
(this: any).handleCommentChange = this.handleCommentChange.bind(this);
|
|
||||||
(this: any).handleChannelChange = this.handleChannelChange.bind(this);
|
|
||||||
(this: any).handleSubmit = this.handleSubmit.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCommentChange(event) {
|
|
||||||
this.setState({ message: event.target.value });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleChannelChange(channelUri) {
|
|
||||||
this.setState({ channelUri: channelUri });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit() {
|
|
||||||
// const { createComment, claim, channelUri } = this.props;
|
|
||||||
const { channelUri, claim } = this.props; // eslint-disable-line react/prop-types
|
|
||||||
console.log('claim', claim);
|
|
||||||
|
|
||||||
const { claim_id: claimId } = claim;
|
const { claim_id: claimId } = claim;
|
||||||
const { message } = this.state;
|
const [commentValue, setCommentValue] = usePersistedState(`comment-${claimId}`, '');
|
||||||
let cmt = { message, channelId: parseURI(channelUri).claimId, claimId };
|
const [commentAck, setCommentAck] = usePersistedState(COMMENT_ACKNOWLEDGED, 'no');
|
||||||
|
const [channel, setChannel] = usePersistedState('COMMENT_CHANNEL', 'anonymous');
|
||||||
|
|
||||||
console.log('CMT', cmt);
|
function handleCommentChange(event) {
|
||||||
console.log('PURI', claimId);
|
setCommentValue(event.target.value);
|
||||||
console.log('PURI', parseURI(channelUri));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
function handleChannelChange(channel) {
|
||||||
const { channelUri } = this.props;
|
setChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCommentAck(event) {
|
||||||
|
setCommentAck(COMMENT_ACKNOWLEDGED_TRUE);
|
||||||
|
}
|
||||||
|
function handleSubmit() {
|
||||||
|
if (channel !== 'new' && commentValue.length) createComment(commentValue, claimId, channel);
|
||||||
|
setCommentValue('');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="card card--section">
|
|
||||||
{!acksComments && (
|
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="media__title">
|
{commentAck !== COMMENT_ACKNOWLEDGED_TRUE && (
|
||||||
<TruncatedText text={channelName || uri} lines={1} />
|
<section className="card card--section">
|
||||||
|
<div className="card__content">
|
||||||
|
<div className="media__title">About comments..</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="media__subtitle">
|
<div className="card__content">
|
||||||
{totalItems > 0 && (
|
<div className="media__subtitle">Seriously, don't comment.</div>
|
||||||
<span>
|
|
||||||
{totalItems} {totalItems === 1 ? 'publish' : 'publishes'}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{!isResolvingUri && !totalItems && <span>This is an empty channel.</span>}
|
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
<div className="card__content">
|
||||||
|
<Button button="primary" onClick={handleCommentAck} label={__('Got it!')} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
)}
|
)}
|
||||||
<Form onSubmit={this.handleSubmit}>
|
{commentAck === COMMENT_ACKNOWLEDGED_TRUE && (
|
||||||
|
<section className="card card--section">
|
||||||
|
<Form onSubmit={handleSubmit}>
|
||||||
|
<div className="card__content">
|
||||||
|
<ChannelSection channel={channel} onChannelChange={handleChannelChange} />
|
||||||
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<FormField
|
<FormField
|
||||||
|
disabled={channel === 'new'}
|
||||||
type="textarea"
|
type="textarea"
|
||||||
name="content_description"
|
name="content_description"
|
||||||
label={__('Text')}
|
label={__('Text')}
|
||||||
placeholder={__('Your comment')}
|
placeholder={__('Your comment')}
|
||||||
value={this.state.message}
|
value={commentValue}
|
||||||
onChange={this.handleCommentChange}
|
onChange={handleCommentChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__actions--between">
|
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<ChannelSection channel={channelUri} />
|
<Button
|
||||||
</div>
|
button="primary"
|
||||||
<Button button="primary" type="submit" label={__('Post')} />
|
disabled={channel === 'new' || !commentValue.length}
|
||||||
|
type="submit"
|
||||||
|
label={__('Post')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</section>
|
</section>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CommentCreate;
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
||||||
import relativeDate from 'tiny-relative-date';
|
import relativeDate from 'tiny-relative-date';
|
||||||
|
|
||||||
type CommentListProps = {
|
type CommentListProps = {
|
||||||
comments: {},
|
comments: Array<any>,
|
||||||
fetchList: string => void,
|
fetchList: string => void,
|
||||||
uri: string,
|
uri: string,
|
||||||
isLoading: boolean,
|
isLoading: boolean,
|
||||||
|
@ -23,7 +23,7 @@ class CommentList extends React.PureComponent<CommentListProps> {
|
||||||
this.fetchComments(this.props);
|
this.fetchComments(this.props);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchComments = (props: Props) => {
|
fetchComments = (props: CommentListProps) => {
|
||||||
const { fetchList, uri } = props;
|
const { fetchList, uri } = props;
|
||||||
fetchList(uri);
|
fetchList(uri);
|
||||||
};
|
};
|
||||||
|
@ -36,22 +36,23 @@ class CommentList extends React.PureComponent<CommentListProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<section>
|
||||||
<ul className="comments">
|
<ul className="comments">
|
||||||
{comments['comments'].map(comment => {
|
{comments.map(comment => {
|
||||||
console.log(comment.message);
|
|
||||||
return (
|
return (
|
||||||
<Comment
|
<Comment
|
||||||
author={comment.author}
|
author={comment.channel_name}
|
||||||
claimId={comment.claim_id}
|
claimId={comment.channel_id}
|
||||||
commentId={comment.comment_id}
|
commentId={comment.comment_id}
|
||||||
key={comment.author + comment.comment_id}
|
key={comment.channel_id + comment.comment_id}
|
||||||
message={comment.message}
|
message={comment.comment}
|
||||||
parentId={comment.parent_id}
|
parentId={comment.parent_id || null}
|
||||||
timePosted={comment.time_posted}
|
timePosted={comment.timestamp * 1000}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,20 +62,22 @@ class Comment extends React.PureComponent<CommentProps> {
|
||||||
return (
|
return (
|
||||||
<li className={this.props.parentId ? 'comment reply' : 'comment'}>
|
<li className={this.props.parentId ? 'comment reply' : 'comment'}>
|
||||||
<div className="comment__meta card__actions--between">
|
<div className="comment__meta card__actions--between">
|
||||||
<strong>{this.props.author}</strong>
|
{this.props.author && <strong>{this.props.author}</strong>}
|
||||||
|
{!this.props.author && <strong>Anonymous</strong>}
|
||||||
|
|
||||||
<time dateTime={this.props.timePosted}>{relativeDate(this.props.timePosted)}</time>
|
<time dateTime={this.props.timePosted}>{relativeDate(this.props.timePosted)}</time>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="comment__content">{this.props.message}</div>
|
<div className="comment__content">{this.props.message}</div>
|
||||||
|
{/* The following is for adding threaded replies, upvoting and downvoting */}
|
||||||
|
{/* <div className="comment__actions card__actions--between"> */}
|
||||||
|
{/* <button className={'button button--primary'}>Reply</button> */}
|
||||||
|
|
||||||
<div className="comment__actions card__actions--between">
|
{/* <span className="comment__actions-wrap"> */}
|
||||||
<button className={'button button--primary'}>Reply</button>
|
{/* <button className="comment__action upvote">Up</button> */}
|
||||||
|
{/* <button className="comment__action downvote">Down</button> */}
|
||||||
<span className="comment__actions-wrap">
|
{/* </span> */}
|
||||||
<button className="comment__action upvote">Up</button>
|
{/* </div> */}
|
||||||
<button className="comment__action downvote">Down</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ class FileViewer extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleAutoplay(this.props);
|
this.handleAutoplay(this.props);
|
||||||
window.addEventListener('keydown', this.handleKeyDown);
|
// window.addEventListener('keydown', this.handleKeyDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prev: Props) {
|
componentDidUpdate(prev: Props) {
|
||||||
|
|
|
@ -331,7 +331,6 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
|
|
||||||
const shortUri = buildURI({ contentName: name });
|
const shortUri = buildURI({ contentName: name });
|
||||||
|
|
||||||
console.log('URI', uri);
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{IS_WEB && <UnsupportedOnWeb />}
|
{IS_WEB && <UnsupportedOnWeb />}
|
||||||
|
|
|
@ -4,23 +4,19 @@ import {
|
||||||
selectBalance,
|
selectBalance,
|
||||||
selectMyChannelClaims,
|
selectMyChannelClaims,
|
||||||
selectFetchingMyChannels,
|
selectFetchingMyChannels,
|
||||||
selectMyActiveChannelUri,
|
|
||||||
doFetchChannelListMine,
|
doFetchChannelListMine,
|
||||||
doCreateChannel,
|
doCreateChannel,
|
||||||
doSetMyActiveChannelUri,
|
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
channels: selectMyChannelClaims(state),
|
channels: selectMyChannelClaims(state),
|
||||||
fetchingChannels: selectFetchingMyChannels(state),
|
fetchingChannels: selectFetchingMyChannels(state),
|
||||||
balance: selectBalance(state),
|
balance: selectBalance(state),
|
||||||
activeChannelUri: selectMyActiveChannelUri(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)),
|
createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)),
|
||||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||||
setMyActiveChannelUri: activeChannelUri => dispatch(doSetMyActiveChannelUri(activeChannelUri)),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
|
|
@ -7,16 +7,13 @@ import Button from 'component/button';
|
||||||
import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
|
import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
channelUri: string,
|
|
||||||
channel: string, // currently selected channel
|
channel: string, // currently selected channel
|
||||||
channels: Array<{ name: string }>,
|
channels: Array<{ name: string }>,
|
||||||
balance: number,
|
balance: number,
|
||||||
onChannelChange?: string => void,
|
onChannelChange: string => void,
|
||||||
createChannel: (string, number) => Promise<any>,
|
createChannel: (string, number) => Promise<any>,
|
||||||
fetchChannelListMine: () => void,
|
fetchChannelListMine: () => void,
|
||||||
fetchingChannels: boolean,
|
fetchingChannels: boolean,
|
||||||
activeChannelUri: string,
|
|
||||||
setMyActiveChannelUri: string => void,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -56,27 +53,18 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChannelChangeProxy(channelUri) {
|
|
||||||
const { onChannelChange } = this.props;
|
|
||||||
if (onChannelChange) {
|
|
||||||
onChannelChange(channelUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleChannelChange(event: SyntheticInputEvent<*>) {
|
handleChannelChange(event: SyntheticInputEvent<*>) {
|
||||||
const { setMyActiveChannelUri } = this.props;
|
const { onChannelChange } = this.props;
|
||||||
const { newChannelBid } = this.state;
|
const { newChannelBid } = this.state;
|
||||||
const channelUri = event.target.value;
|
const channel = event.target.value;
|
||||||
console.log('HCC', channelUri);
|
|
||||||
|
|
||||||
if (channelUri === CHANNEL_NEW) {
|
if (channel === CHANNEL_NEW) {
|
||||||
this.setState({ addingChannel: true });
|
this.setState({ addingChannel: true });
|
||||||
this.onChannelChangeProxy(channelUri);
|
onChannelChange(channel);
|
||||||
this.handleNewChannelBidChange(newChannelBid);
|
this.handleNewChannelBidChange(newChannelBid);
|
||||||
} else {
|
} else {
|
||||||
this.setState({ addingChannel: false });
|
this.setState({ addingChannel: false });
|
||||||
setMyActiveChannelUri(channelUri);
|
onChannelChange(channel);
|
||||||
this.onChannelChangeProxy(channelUri);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +104,7 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCreateChannelClick() {
|
handleCreateChannelClick() {
|
||||||
const { balance, createChannel } = this.props;
|
const { balance, createChannel, onChannelChange } = this.props;
|
||||||
const { newChannelBid, newChannelName } = this.state;
|
const { newChannelBid, newChannelName } = this.state;
|
||||||
|
|
||||||
const channelName = `@${newChannelName}`;
|
const channelName = `@${newChannelName}`;
|
||||||
|
@ -135,7 +123,8 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
||||||
creatingChannel: false,
|
creatingChannel: false,
|
||||||
addingChannel: false,
|
addingChannel: false,
|
||||||
});
|
});
|
||||||
this.onChannelChangeProxy(channelName);
|
|
||||||
|
onChannelChange(channelName);
|
||||||
};
|
};
|
||||||
|
|
||||||
const failure = () => {
|
const failure = () => {
|
||||||
|
@ -149,7 +138,7 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const channelUri = this.state.addingChannel ? 'new' : this.props.channelUri;
|
const channel = this.state.addingChannel ? 'new' : this.props.channel;
|
||||||
const { fetchingChannels, channels = [] } = this.props;
|
const { fetchingChannels, channels = [] } = this.props;
|
||||||
const {
|
const {
|
||||||
newChannelName,
|
newChannelName,
|
||||||
|
@ -168,10 +157,10 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
||||||
<BusyIndicator message="Updating channels" />
|
<BusyIndicator message="Updating channels" />
|
||||||
) : (
|
) : (
|
||||||
<fieldset-section>
|
<fieldset-section>
|
||||||
<FormField name="channel" type="select" onChange={this.handleChannelChange} value={channelUri}>
|
<FormField name="channel" type="select" onChange={this.handleChannelChange} value={channel}>
|
||||||
<option value={CHANNEL_ANONYMOUS}>{__('Anonymous')}</option>
|
<option value={CHANNEL_ANONYMOUS}>{__('Anonymous')}</option>
|
||||||
{channels.map(({ name, permanent_url: channelUri }) => (
|
{channels.map(({ name }) => (
|
||||||
<option key={name} value={channelUri}>
|
<option key={name} value={name}>
|
||||||
{name}
|
{name}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -16,3 +16,5 @@ export const AUTOPLAY = 'autoplay';
|
||||||
export const RESULT_COUNT = 'resultCount';
|
export const RESULT_COUNT = 'resultCount';
|
||||||
export const OS_NOTIFICATIONS_ENABLED = 'osNotificationsEnabled';
|
export const OS_NOTIFICATIONS_ENABLED = 'osNotificationsEnabled';
|
||||||
export const AUTO_DOWNLOAD = 'autoDownload';
|
export const AUTO_DOWNLOAD = 'autoDownload';
|
||||||
|
export const COMMENT_ACKNOWLEDGED = 'comment_acknowledged';
|
||||||
|
export const COMMENT_ACKNOWLEDGED_TRUE = 'comment_acknowledged_true';
|
||||||
|
|
Loading…
Reference in a new issue