]> Untitled Git - lemmy.git/commitdiff
Allow comment/post upvoting from other pages.
authorDessalines <tyhou13@gmx.com>
Mon, 20 Jan 2020 23:39:45 +0000 (18:39 -0500)
committerDessalines <tyhou13@gmx.com>
Mon, 20 Jan 2020 23:39:45 +0000 (18:39 -0500)
- Fixes #355
- Votes now coming back for posts and comments on search page.

server/src/api/site.rs
ui/src/components/post-listing.tsx
ui/src/components/search.tsx
ui/src/components/user.tsx
ui/src/interfaces.ts
ui/src/services/WebSocketService.ts

index a189a0308866dfc48897c111446cc46e18a20491..ce07724a38e862d0c00b6f528cf4bc0e15c5016f 100644 (file)
@@ -19,6 +19,7 @@ pub struct Search {
   sort: String,
   page: Option<i64>,
   limit: Option<i64>,
+  auth: Option<String>,
 }
 
 #[derive(Serialize, Deserialize)]
@@ -313,6 +314,17 @@ impl Perform<SearchResponse> for Oper<Search> {
   fn perform(&self, conn: &PgConnection) -> Result<SearchResponse, Error> {
     let data: &Search = &self.data;
 
+    let user_id: Option<i32> = match &data.auth {
+      Some(auth) => match Claims::decode(&auth) {
+        Ok(claims) => {
+          let user_id = claims.claims.id;
+          Some(user_id)
+        }
+        Err(_e) => None,
+      },
+      None => None,
+    };
+
     let sort = SortType::from_str(&data.sort)?;
     let type_ = SearchType::from_str(&data.type_)?;
 
@@ -330,6 +342,7 @@ impl Perform<SearchResponse> for Oper<Search> {
           .show_nsfw(true)
           .for_community_id(data.community_id)
           .search_term(data.q.to_owned())
+          .my_user_id(user_id)
           .page(data.page)
           .limit(data.limit)
           .list()?;
@@ -338,6 +351,7 @@ impl Perform<SearchResponse> for Oper<Search> {
         comments = CommentQueryBuilder::create(&conn)
           .sort(&sort)
           .search_term(data.q.to_owned())
+          .my_user_id(user_id)
           .page(data.page)
           .limit(data.limit)
           .list()?;
@@ -364,6 +378,7 @@ impl Perform<SearchResponse> for Oper<Search> {
           .show_nsfw(true)
           .for_community_id(data.community_id)
           .search_term(data.q.to_owned())
+          .my_user_id(user_id)
           .page(data.page)
           .limit(data.limit)
           .list()?;
@@ -371,6 +386,7 @@ impl Perform<SearchResponse> for Oper<Search> {
         comments = CommentQueryBuilder::create(&conn)
           .sort(&sort)
           .search_term(data.q.to_owned())
+          .my_user_id(user_id)
           .page(data.page)
           .limit(data.limit)
           .list()?;
index b1db26709710f0bbe564d080f58a5d18b4a11a9e..aab2cea582846490f7863e78de86b19b2a6d8275 100644 (file)
@@ -52,7 +52,6 @@ interface PostListingProps {
   post: Post;
   showCommunity?: boolean;
   showBody?: boolean;
-  viewOnly?: boolean;
   moderators?: Array<CommunityUser>;
   admins?: Array<UserView>;
 }
@@ -118,10 +117,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     let post = this.props.post;
     return (
       <div class="listing col-12">
-        <div
-          className={`vote-bar mr-2 float-left small text-center ${this.props
-            .viewOnly && 'no-click'}`}
-        >
+        <div className={`vote-bar mr-2 float-left small text-center`}>
           <button
             disabled={!UserService.Instance.user}
             className={`btn p-0 ${
index 70219d4e7e95a5ea3c42c24fd4ff02d36cef5c54..94bbbdb9d2c53d0234abf0ca60e32ab5ad317973 100644 (file)
@@ -12,6 +12,8 @@ import {
   SearchForm,
   SearchResponse,
   SearchType,
+  CreatePostLikeResponse,
+  CommentResponse,
 } from '../interfaces';
 import { WebSocketService } from '../services';
 import {
@@ -123,22 +125,18 @@ export class Search extends Component<any, SearchState> {
   render() {
     return (
       <div class="container">
-        <div class="row">
-          <div class="col-12">
-            <h5>
-              <T i18nKey="search">#</T>
-            </h5>
-            {this.selects()}
-            {this.searchForm()}
-            {this.state.type_ == SearchType.All && this.all()}
-            {this.state.type_ == SearchType.Comments && this.comments()}
-            {this.state.type_ == SearchType.Posts && this.posts()}
-            {this.state.type_ == SearchType.Communities && this.communities()}
-            {this.state.type_ == SearchType.Users && this.users()}
-            {this.noResults()}
-            {this.paginator()}
-          </div>
-        </div>
+        <h5>
+          <T i18nKey="search">#</T>
+        </h5>
+        {this.selects()}
+        {this.searchForm()}
+        {this.state.type_ == SearchType.All && this.all()}
+        {this.state.type_ == SearchType.Comments && this.comments()}
+        {this.state.type_ == SearchType.Posts && this.posts()}
+        {this.state.type_ == SearchType.Communities && this.communities()}
+        {this.state.type_ == SearchType.Users && this.users()}
+        {this.noResults()}
+        {this.paginator()}
       </div>
     );
   }
@@ -252,54 +250,56 @@ export class Search extends Component<any, SearchState> {
     return (
       <div>
         {combined.map(i => (
-          <div>
-            {i.type_ == 'posts' && (
-              <PostListing post={i.data as Post} showCommunity viewOnly />
-            )}
-            {i.type_ == 'comments' && (
-              <CommentNodes
-                nodes={[{ comment: i.data as Comment }]}
-                locked
-                noIndent
-              />
-            )}
-            {i.type_ == 'communities' && (
-              <div>
-                <span>
-                  <Link to={`/c/${(i.data as Community).name}`}>{`/c/${
-                    (i.data as Community).name
-                  }`}</Link>
-                </span>
-                <span>{` - ${(i.data as Community).title} - ${
-                  (i.data as Community).number_of_subscribers
-                } subscribers`}</span>
-              </div>
-            )}
-            {i.type_ == 'users' && (
-              <div>
-                <span>
-                  <Link
-                    className="text-info"
-                    to={`/u/${(i.data as UserView).name}`}
-                  >
-                    {(i.data as UserView).avatar && showAvatars() && (
-                      <img
-                        height="32"
-                        width="32"
-                        src={pictshareAvatarThumbnail(
-                          (i.data as UserView).avatar
-                        )}
-                        class="rounded-circle mr-1"
-                      />
-                    )}
-                    <span>{`/u/${(i.data as UserView).name}`}</span>
-                  </Link>
-                </span>
-                <span>{` - ${
-                  (i.data as UserView).comment_score
-                } comment karma`}</span>
-              </div>
-            )}
+          <div class="row">
+            <div class="col-12">
+              {i.type_ == 'posts' && (
+                <PostListing post={i.data as Post} showCommunity />
+              )}
+              {i.type_ == 'comments' && (
+                <CommentNodes
+                  nodes={[{ comment: i.data as Comment }]}
+                  locked
+                  noIndent
+                />
+              )}
+              {i.type_ == 'communities' && (
+                <div>
+                  <span>
+                    <Link to={`/c/${(i.data as Community).name}`}>{`/c/${
+                      (i.data as Community).name
+                    }`}</Link>
+                  </span>
+                  <span>{` - ${(i.data as Community).title} - ${
+                    (i.data as Community).number_of_subscribers
+                  } subscribers`}</span>
+                </div>
+              )}
+              {i.type_ == 'users' && (
+                <div>
+                  <span>
+                    <Link
+                      className="text-info"
+                      to={`/u/${(i.data as UserView).name}`}
+                    >
+                      {(i.data as UserView).avatar && showAvatars() && (
+                        <img
+                          height="32"
+                          width="32"
+                          src={pictshareAvatarThumbnail(
+                            (i.data as UserView).avatar
+                          )}
+                          class="rounded-circle mr-1"
+                        />
+                      )}
+                      <span>{`/u/${(i.data as UserView).name}`}</span>
+                    </Link>
+                  </span>
+                  <span>{` - ${
+                    (i.data as UserView).comment_score
+                  } comment karma`}</span>
+                </div>
+              )}
+            </div>
           </div>
         ))}
       </div>
@@ -308,55 +308,69 @@ export class Search extends Component<any, SearchState> {
 
   comments() {
     return (
-      <div>
+      <>
         {this.state.searchResponse.comments.map(comment => (
-          <CommentNodes nodes={[{ comment: comment }]} locked noIndent />
+          <div class="row">
+            <div class="col-12">
+              <CommentNodes nodes={[{ comment: comment }]} locked noIndent />
+            </div>
+          </div>
         ))}
-      </div>
+      </>
     );
   }
 
   posts() {
     return (
-      <div>
+      <>
         {this.state.searchResponse.posts.map(post => (
-          <PostListing post={post} showCommunity viewOnly />
+          <div class="row">
+            <div class="col-12">
+              <PostListing post={post} showCommunity />
+            </div>
+          </div>
         ))}
-      </div>
+      </>
     );
   }
 
   // Todo possibly create UserListing and CommunityListing
   communities() {
     return (
-      <div>
+      <>
         {this.state.searchResponse.communities.map(community => (
-          <div>
-            <span>
-              <Link to={`/c/${community.name}`}>{`/c/${community.name}`}</Link>
-            </span>
-            <span>{` - ${community.title} - ${community.number_of_subscribers} subscribers`}</span>
+          <div class="row">
+            <div class="col-12">
+              <span>
+                <Link
+                  to={`/c/${community.name}`}
+                >{`/c/${community.name}`}</Link>
+              </span>
+              <span>{` - ${community.title} - ${community.number_of_subscribers} subscribers`}</span>
+            </div>
           </div>
         ))}
-      </div>
+      </>
     );
   }
 
   users() {
     return (
-      <div>
+      <>
         {this.state.searchResponse.users.map(user => (
-          <div>
-            <span>
-              <Link
-                className="text-info"
-                to={`/u/${user.name}`}
-              >{`/u/${user.name}`}</Link>
-            </span>
-            <span>{` - ${user.comment_score} comment karma`}</span>
+          <div class="row">
+            <div class="col-12">
+              <span>
+                <Link
+                  className="text-info"
+                  to={`/u/${user.name}`}
+                >{`/u/${user.name}`}</Link>
+              </span>
+              <span>{` - ${user.comment_score} comment karma`}</span>
+            </div>
           </div>
         ))}
-      </div>
+      </>
     );
   }
 
@@ -477,6 +491,30 @@ export class Search extends Component<any, SearchState> {
       }`;
       window.scrollTo(0, 0);
       this.setState(this.state);
+    } else if (op == UserOperation.CreateCommentLike) {
+      let res: CommentResponse = msg;
+      let found: Comment = this.state.searchResponse.comments.find(
+        c => c.id === res.comment.id
+      );
+      found.score = res.comment.score;
+      found.upvotes = res.comment.upvotes;
+      found.downvotes = res.comment.downvotes;
+      if (res.comment.my_vote !== null) {
+        found.my_vote = res.comment.my_vote;
+        found.upvoteLoading = false;
+        found.downvoteLoading = false;
+      }
+      this.setState(this.state);
+    } else if (op == UserOperation.CreatePostLike) {
+      let res: CreatePostLikeResponse = msg;
+      let found = this.state.searchResponse.posts.find(
+        c => c.id == res.post.id
+      );
+      found.my_vote = res.post.my_vote;
+      found.score = res.post.score;
+      found.upvotes = res.post.upvotes;
+      found.downvotes = res.post.downvotes;
+      this.setState(this.state);
     }
   }
 }
index c95b18bb148776aa474db93a35d978bc5c0fb5ab..206fb8ff26c9a1d81d22b221c8f2a806c5777a99 100644 (file)
@@ -18,6 +18,7 @@ import {
   BanUserResponse,
   AddAdminResponse,
   DeleteAccountForm,
+  CreatePostLikeResponse,
 } from '../interfaces';
 import { WebSocketService, UserService } from '../services';
 import {
@@ -307,7 +308,6 @@ export class User extends Component<any, UserState> {
                 post={i.data as Post}
                 admins={this.state.admins}
                 showCommunity
-                viewOnly
               />
             ) : (
               <CommentNodes
@@ -340,12 +340,7 @@ export class User extends Component<any, UserState> {
     return (
       <div>
         {this.state.posts.map(post => (
-          <PostListing
-            post={post}
-            admins={this.state.admins}
-            showCommunity
-            viewOnly
-          />
+          <PostListing post={post} admins={this.state.admins} showCommunity />
         ))}
       </div>
     );
@@ -1043,6 +1038,14 @@ export class User extends Component<any, UserState> {
       found.downvotes = res.comment.downvotes;
       if (res.comment.my_vote !== null) found.my_vote = res.comment.my_vote;
       this.setState(this.state);
+    } else if (op == UserOperation.CreatePostLike) {
+      let res: CreatePostLikeResponse = msg;
+      let found = this.state.posts.find(c => c.id == res.post.id);
+      found.my_vote = res.post.my_vote;
+      found.score = res.post.score;
+      found.upvotes = res.post.upvotes;
+      found.downvotes = res.post.downvotes;
+      this.setState(this.state);
     } else if (op == UserOperation.BanUser) {
       let res: BanUserResponse = msg;
       this.state.comments
index 232d1388dd66a8be72fa2125c76715d22f894841..c21d3d264983c0bd739bd7e44c5908bd4dd69923 100644 (file)
@@ -700,6 +700,7 @@ export interface SearchForm {
   sort: string;
   page?: number;
   limit?: number;
+  auth?: string;
 }
 
 export interface SearchResponse {
index 34da585083211da549c272bf95b593829c7d9f1d..a70fb2deff2acd399abb3d53a05a4fb19a6729a7 100644 (file)
@@ -255,6 +255,7 @@ export class WebSocketService {
   }
 
   public search(form: SearchForm) {
+    this.setAuth(form, false);
     this.subject.next(this.wsSendWrapper(UserOperation.Search, form));
   }