forked from nutomic/lemmy
Add fast comment and post voting. (Doesn't wait for server return)
- Fixes #416
This commit is contained in:
parent
083fcb9c6c
commit
3f4cce99ed
2 changed files with 64 additions and 13 deletions
37
ui/src/components/comment-node.tsx
vendored
37
ui/src/components/comment-node.tsx
vendored
|
@ -47,6 +47,8 @@ interface CommentNodeState {
|
||||||
showConfirmAppointAsAdmin: boolean;
|
showConfirmAppointAsAdmin: boolean;
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
viewSource: boolean;
|
viewSource: boolean;
|
||||||
|
my_vote: number;
|
||||||
|
score: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommentNodeProps {
|
interface CommentNodeProps {
|
||||||
|
@ -76,6 +78,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
showConfirmTransferCommunity: false,
|
showConfirmTransferCommunity: false,
|
||||||
showConfirmAppointAsMod: false,
|
showConfirmAppointAsMod: false,
|
||||||
showConfirmAppointAsAdmin: false,
|
showConfirmAppointAsAdmin: false,
|
||||||
|
my_vote: this.props.node.comment.my_vote,
|
||||||
|
score: this.props.node.comment.score,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -102,7 +106,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className={`btn p-0 ${
|
className={`btn p-0 ${
|
||||||
node.comment.my_vote == 1 ? 'text-info' : 'text-muted'
|
this.state.my_vote == 1 ? 'text-info' : 'text-muted'
|
||||||
}`}
|
}`}
|
||||||
onClick={linkEvent(node, this.handleCommentLike)}
|
onClick={linkEvent(node, this.handleCommentLike)}
|
||||||
>
|
>
|
||||||
|
@ -110,13 +114,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
<use xlinkHref="#icon-arrow-up"></use>
|
<use xlinkHref="#icon-arrow-up"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div class={`font-weight-bold text-muted`}>
|
<div class={`font-weight-bold text-muted`}>{this.state.score}</div>
|
||||||
{node.comment.score}
|
|
||||||
</div>
|
|
||||||
{WebSocketService.Instance.site.enable_downvotes && (
|
{WebSocketService.Instance.site.enable_downvotes && (
|
||||||
<button
|
<button
|
||||||
className={`btn p-0 ${
|
className={`btn p-0 ${
|
||||||
node.comment.my_vote == -1 ? 'text-danger' : 'text-muted'
|
this.state.my_vote == -1 ? 'text-danger' : 'text-muted'
|
||||||
}`}
|
}`}
|
||||||
onClick={linkEvent(node, this.handleCommentDisLike)}
|
onClick={linkEvent(node, this.handleCommentDisLike)}
|
||||||
>
|
>
|
||||||
|
@ -721,19 +723,40 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCommentLike(i: CommentNodeI) {
|
handleCommentLike(i: CommentNodeI) {
|
||||||
|
this.state.my_vote = i.comment.my_vote == 1 ? 0 : 1;
|
||||||
|
let add = 1;
|
||||||
|
if (i.comment.my_vote == 1) {
|
||||||
|
add = -1;
|
||||||
|
} else if (i.comment.my_vote == -1) {
|
||||||
|
add = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.score = i.comment.score + add;
|
||||||
|
this.setState(this.state);
|
||||||
|
|
||||||
let form: CommentLikeForm = {
|
let form: CommentLikeForm = {
|
||||||
comment_id: i.comment.id,
|
comment_id: i.comment.id,
|
||||||
post_id: i.comment.post_id,
|
post_id: i.comment.post_id,
|
||||||
score: i.comment.my_vote == 1 ? 0 : 1,
|
score: this.state.my_vote,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.likeComment(form);
|
WebSocketService.Instance.likeComment(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCommentDisLike(i: CommentNodeI) {
|
handleCommentDisLike(i: CommentNodeI) {
|
||||||
|
this.state.my_vote = i.comment.my_vote == -1 ? 0 : -1;
|
||||||
|
let add = -1;
|
||||||
|
if (i.comment.my_vote == 1) {
|
||||||
|
add = -2;
|
||||||
|
} else if (i.comment.my_vote == -1) {
|
||||||
|
add = 1;
|
||||||
|
}
|
||||||
|
this.state.score = i.comment.score + add;
|
||||||
|
this.setState(this.state);
|
||||||
|
|
||||||
let form: CommentLikeForm = {
|
let form: CommentLikeForm = {
|
||||||
comment_id: i.comment.id,
|
comment_id: i.comment.id,
|
||||||
post_id: i.comment.post_id,
|
post_id: i.comment.post_id,
|
||||||
score: i.comment.my_vote == -1 ? 0 : -1,
|
score: this.state.my_vote,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.likeComment(form);
|
WebSocketService.Instance.likeComment(form);
|
||||||
}
|
}
|
||||||
|
|
40
ui/src/components/post-listing.tsx
vendored
40
ui/src/components/post-listing.tsx
vendored
|
@ -44,6 +44,8 @@ interface PostListingState {
|
||||||
showConfirmTransferCommunity: boolean;
|
showConfirmTransferCommunity: boolean;
|
||||||
imageExpanded: boolean;
|
imageExpanded: boolean;
|
||||||
viewSource: boolean;
|
viewSource: boolean;
|
||||||
|
my_vote: number;
|
||||||
|
score: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PostListingProps {
|
interface PostListingProps {
|
||||||
|
@ -68,6 +70,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
showConfirmTransferCommunity: false,
|
showConfirmTransferCommunity: false,
|
||||||
imageExpanded: false,
|
imageExpanded: false,
|
||||||
viewSource: false,
|
viewSource: false,
|
||||||
|
my_vote: this.props.post.my_vote,
|
||||||
|
score: this.props.post.score,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -108,7 +112,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className={`btn p-0 ${
|
className={`btn p-0 ${
|
||||||
post.my_vote == 1 ? 'text-info' : 'text-muted'
|
this.state.my_vote == 1 ? 'text-info' : 'text-muted'
|
||||||
}`}
|
}`}
|
||||||
onClick={linkEvent(this, this.handlePostLike)}
|
onClick={linkEvent(this, this.handlePostLike)}
|
||||||
>
|
>
|
||||||
|
@ -116,11 +120,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<use xlinkHref="#icon-arrow-up"></use>
|
<use xlinkHref="#icon-arrow-up"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div class={`font-weight-bold text-muted`}>{post.score}</div>
|
<div class={`font-weight-bold text-muted`}>{this.state.score}</div>
|
||||||
{WebSocketService.Instance.site.enable_downvotes && (
|
{WebSocketService.Instance.site.enable_downvotes && (
|
||||||
<button
|
<button
|
||||||
className={`btn p-0 ${
|
className={`btn p-0 ${
|
||||||
post.my_vote == -1 ? 'text-danger' : 'text-muted'
|
this.state.my_vote == -1 ? 'text-danger' : 'text-muted'
|
||||||
}`}
|
}`}
|
||||||
onClick={linkEvent(this, this.handlePostDisLike)}
|
onClick={linkEvent(this, this.handlePostDisLike)}
|
||||||
>
|
>
|
||||||
|
@ -642,7 +646,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
get isAdmin(): boolean {
|
get isAdmin(): boolean {
|
||||||
return (
|
return (
|
||||||
this.props.admins &&
|
this.props.admins &&
|
||||||
isMod(this.props.admins.map(a => a.id), this.props.post.creator_id)
|
isMod(
|
||||||
|
this.props.admins.map(a => a.id),
|
||||||
|
this.props.post.creator_id
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,17 +716,38 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePostLike(i: PostListing) {
|
handlePostLike(i: PostListing) {
|
||||||
|
this.state.my_vote = i.props.post.my_vote == 1 ? 0 : 1;
|
||||||
|
let add = 1;
|
||||||
|
if (i.props.post.my_vote == 1) {
|
||||||
|
add = -1;
|
||||||
|
} else if (i.props.post.my_vote == -1) {
|
||||||
|
add = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.score = i.props.post.score + add;
|
||||||
|
this.setState(this.state);
|
||||||
|
|
||||||
let form: CreatePostLikeForm = {
|
let form: CreatePostLikeForm = {
|
||||||
post_id: i.props.post.id,
|
post_id: i.props.post.id,
|
||||||
score: i.props.post.my_vote == 1 ? 0 : 1,
|
score: this.state.my_vote,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.likePost(form);
|
WebSocketService.Instance.likePost(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePostDisLike(i: PostListing) {
|
handlePostDisLike(i: PostListing) {
|
||||||
|
this.state.my_vote = i.props.post.my_vote == -1 ? 0 : -1;
|
||||||
|
let add = -1;
|
||||||
|
if (i.props.post.my_vote == 1) {
|
||||||
|
add = -2;
|
||||||
|
} else if (i.props.post.my_vote == -1) {
|
||||||
|
add = 1;
|
||||||
|
}
|
||||||
|
this.state.score = i.props.post.score + add;
|
||||||
|
this.setState(this.state);
|
||||||
|
|
||||||
let form: CreatePostLikeForm = {
|
let form: CreatePostLikeForm = {
|
||||||
post_id: i.props.post.id,
|
post_id: i.props.post.id,
|
||||||
score: i.props.post.my_vote == -1 ? 0 : -1,
|
score: this.state.my_vote,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.likePost(form);
|
WebSocketService.Instance.likePost(form);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue