summaryrefslogtreecommitdiffstats
path: root/ui/src
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2020-03-19 11:45:23 -0400
committerDessalines <tyhou13@gmx.com>2020-03-19 11:45:23 -0400
commit47dd8acf54bf648fd374aac2fa611ca008919284 (patch)
tree881ebde1fdf9f755e3cf4426b95eb730d136534d /ui/src
parented00fe46e2109060f86a88d306a2da2203387b97 (diff)
Adding loading indicators to save and mark as read. #519
Diffstat (limited to 'ui/src')
-rw-r--r--ui/src/components/comment-node.tsx109
-rw-r--r--ui/src/components/post-listings.tsx3
-rw-r--r--ui/src/components/post.tsx2
-rw-r--r--ui/src/components/private-message.tsx44
4 files changed, 95 insertions, 63 deletions
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index cbe58725..8809c5b7 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -56,6 +56,8 @@ interface CommentNodeState {
upvotes: number;
downvotes: number;
borderColor: string;
+ readLoading: boolean;
+ saveLoading: boolean;
}
interface CommentNodeProps {
@@ -97,6 +99,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
borderColor: this.props.node.comment.depth
? colorList[this.props.node.comment.depth % colorList.length]
: colorList[0],
+ readLoading: false,
+ saveLoading: false,
};
constructor(props: any, context: any) {
@@ -113,6 +117,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
this.state.upvotes = nextProps.node.comment.upvotes;
this.state.downvotes = nextProps.node.comment.downvotes;
this.state.score = nextProps.node.comment.score;
+ this.state.readLoading = false;
+ this.state.saveLoading = false;
this.setState(this.state);
}
@@ -255,12 +261,16 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
: i18n.t('mark_as_read')
}
>
- <svg
- class={`icon icon-inline ${node.comment.read &&
- 'text-success'}`}
- >
- <use xlinkHref="#icon-check"></use>
- </svg>
+ {this.state.readLoading ? (
+ this.loadingIcon
+ ) : (
+ <svg
+ class={`icon icon-inline ${node.comment.read &&
+ 'text-success'}`}
+ >
+ <use xlinkHref="#icon-check"></use>
+ </svg>
+ )}
</button>
</li>
)}
@@ -308,25 +318,37 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
<li className="list-inline-item">
<button
class="btn btn-link btn-sm btn-animate text-muted"
- onClick={linkEvent(this, this.handleReplyClick)}
- data-tippy-content={i18n.t('reply')}
+ onClick={linkEvent(this, this.handleSaveCommentClick)}
+ data-tippy-content={
+ node.comment.saved
+ ? i18n.t('unsave')
+ : i18n.t('save')
+ }
>
- <svg class="icon icon-inline">
- <use xlinkHref="#icon-reply1"></use>
- </svg>
+ {this.state.saveLoading ? (
+ this.loadingIcon
+ ) : (
+ <svg
+ class={`icon icon-inline ${node.comment.saved &&
+ 'text-warning'}`}
+ >
+ <use xlinkHref="#icon-star"></use>
+ </svg>
+ )}
</button>
</li>
<li className="list-inline-item">
- <Link
- className="btn btn-link btn-sm btn-animate text-muted"
- to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}
- title={i18n.t('link')}
+ <button
+ class="btn btn-link btn-sm btn-animate text-muted"
+ onClick={linkEvent(this, this.handleReplyClick)}
+ data-tippy-content={i18n.t('reply')}
>
<svg class="icon icon-inline">
- <use xlinkHref="#icon-link"></use>
+ <use xlinkHref="#icon-reply1"></use>
</svg>
- </Link>
+ </button>
</li>
+ {this.props.markable && this.linkBtn}
{!this.state.showAdvanced ? (
<li className="list-inline-item">
<button
@@ -354,27 +376,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
</Link>
</li>
)}
- <li className="list-inline-item">
- <button
- class="btn btn-link btn-sm btn-animate text-muted"
- onClick={linkEvent(
- this,
- this.handleSaveCommentClick
- )}
- data-tippy-content={
- node.comment.saved
- ? i18n.t('unsave')
- : i18n.t('save')
- }
- >
- <svg
- class={`icon icon-inline ${node.comment.saved &&
- 'text-warning'}`}
- >
- <use xlinkHref="#icon-star"></use>
- </svg>
- </button>
- </li>
+ {!this.props.markable && this.linkBtn}
<li className="list-inline-item">
<button
className="btn btn-link btn-sm btn-animate text-muted"
@@ -756,6 +758,31 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
);
}
+ get linkBtn() {
+ let node = this.props.node;
+ return (
+ <li className="list-inline-item">
+ <Link
+ className="btn btn-link btn-sm btn-animate text-muted"
+ to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}
+ title={i18n.t('link')}
+ >
+ <svg class="icon icon-inline">
+ <use xlinkHref="#icon-link"></use>
+ </svg>
+ </Link>
+ </li>
+ );
+ }
+
+ get loadingIcon() {
+ return (
+ <svg class="icon icon-spinner spin">
+ <use xlinkHref="#icon-spinner"></use>
+ </svg>
+ );
+ }
+
get myComment(): boolean {
return (
UserService.Instance.user &&
@@ -875,6 +902,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
};
WebSocketService.Instance.saveComment(form);
+
+ i.state.saveLoading = true;
+ i.setState(this.state);
}
handleReplyCancel() {
@@ -987,6 +1017,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
};
WebSocketService.Instance.editComment(form);
}
+
+ i.state.readLoading = true;
+ i.setState(this.state);
}
handleModBanFromCommunityShow(i: CommentNode) {
diff --git a/ui/src/components/post-listings.tsx b/ui/src/components/post-listings.tsx
index 5e6acc0c..7a68a97b 100644
--- a/ui/src/components/post-listings.tsx
+++ b/ui/src/components/post-listings.tsx
@@ -28,8 +28,7 @@ export class PostListings extends Component<PostListingsProps, any> {
post={post}
showCommunity={this.props.showCommunity}
/>
- <hr class="d-md-none my-2" />
- <div class="d-none d-md-block my-2"></div>
+ <hr class="my-2" />
</>
))
) : (
diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx
index 0485975a..518f07c2 100644
--- a/ui/src/components/post.tsx
+++ b/ui/src/components/post.tsx
@@ -211,7 +211,7 @@ export class Post extends Component<any, PostState> {
sortRadios() {
return (
- <div class="btn-group btn-group-toggle">
+ <div class="btn-group btn-group-toggle mb-2">
<label
className={`btn btn-sm btn-secondary pointer ${this.state
.commentSort === CommentSortType.Hot && 'active'}`}
diff --git a/ui/src/components/private-message.tsx b/ui/src/components/private-message.tsx
index d9ccfc80..ef128dd4 100644
--- a/ui/src/components/private-message.tsx
+++ b/ui/src/components/private-message.tsx
@@ -55,7 +55,7 @@ export class PrivateMessage extends Component<
render() {
let message = this.props.privateMessage;
return (
- <div class="mb-2">
+ <div class="border-top border-light">
<div>
<ul class="list-inline mb-0 text-muted small">
<li className="list-inline-item">
@@ -129,12 +129,12 @@ export class PrivateMessage extends Component<
dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
/>
)}
- <ul class="list-inline mb-1 text-muted h5 font-weight-bold">
+ <ul class="list-inline mb-0 text-muted font-weight-bold">
{!this.mine && (
<>
- <li className="list-inline-item-action">
- <span
- class="pointer"
+ <li className="list-inline-item">
+ <button
+ class="btn btn-link btn-sm btn-animate text-muted"
onClick={linkEvent(this, this.handleMarkRead)}
data-tippy-content={
message.read
@@ -148,37 +148,37 @@ export class PrivateMessage extends Component<
>
<use xlinkHref="#icon-check"></use>
</svg>
- </span>
+ </button>
</li>
- <li className="list-inline-item-action">
- <span
- class="pointer"
+ <li className="list-inline-item">
+ <button
+ class="btn btn-link btn-sm btn-animate text-muted"
onClick={linkEvent(this, this.handleReplyClick)}
data-tippy-content={i18n.t('reply')}
>
<svg class="icon icon-inline">
<use xlinkHref="#icon-reply1"></use>
</svg>
- </span>
+ </button>
</li>
</>
)}
{this.mine && (
<>
- <li className="list-inline-item-action">
- <span
- class="pointer"
+ <li className="list-inline-item">
+ <button
+ class="btn btn-link btn-sm btn-animate text-muted"
onClick={linkEvent(this, this.handleEditClick)}
data-tippy-content={i18n.t('edit')}
>
<svg class="icon icon-inline">
<use xlinkHref="#icon-edit"></use>
</svg>
- </span>
+ </button>
</li>
- <li className="list-inline-item-action">
- <span
- class="pointer"
+ <li className="list-inline-item">
+ <button
+ class="btn btn-link btn-sm btn-animate text-muted"
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
!message.deleted
@@ -192,13 +192,13 @@ export class PrivateMessage extends Component<
>
<use xlinkHref="#icon-trash"></use>
</svg>
- </span>
+ </button>
</li>
</>
)}
- <li className="list-inline-item-action">
- <span
- className="pointer"
+ <li className="list-inline-item">
+ <button
+ class="btn btn-link btn-sm btn-animate text-muted"
onClick={linkEvent(this, this.handleViewSource)}
data-tippy-content={i18n.t('view_source')}
>
@@ -208,7 +208,7 @@ export class PrivateMessage extends Component<
>
<use xlinkHref="#icon-file-text"></use>
</svg>
- </span>
+ </button>
</li>
</ul>
</div>