]> Untitled Git - lemmy.git/commitdiff
Adding loading indicators to save and mark as read. #519
authorDessalines <tyhou13@gmx.com>
Thu, 19 Mar 2020 15:45:23 +0000 (11:45 -0400)
committerDessalines <tyhou13@gmx.com>
Thu, 19 Mar 2020 15:45:23 +0000 (11:45 -0400)
ui/src/components/comment-node.tsx
ui/src/components/post-listings.tsx
ui/src/components/post.tsx
ui/src/components/private-message.tsx

index cbe58725c1fcf7c059604674404b5e8ceef6d3b6..8809c5b740853ebf32765a96de5219d85fee56f0 100644 (file)
@@ -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) {
index 5e6acc0ca3c871c5623c0e226c689c1b9501dd99..7a68a97b3e16dbb38676dc3becc5267c11d6a58a 100644 (file)
@@ -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" />
             </>
           ))
         ) : (
index 0485975a19fb137e2fce9dde71b35922bd9bff72..518f07c2567d5877fd4b2abe6ac303b61c5d13ea 100644 (file)
@@ -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'}`}
index d9ccfc80995375670de66f7bdf2c455deff08024..ef128dd4a813329047d4580a217a1042c59412ff 100644 (file)
@@ -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>