]> Untitled Git - lemmy.git/commitdiff
Adding trending communities.
authorDessalines <tyhou13@gmx.com>
Wed, 10 Apr 2019 06:19:12 +0000 (23:19 -0700)
committerDessalines <tyhou13@gmx.com>
Wed, 10 Apr 2019 06:19:12 +0000 (23:19 -0700)
- Fixes #29
- Communities fetching now has sort and limit.

server/src/actions/community_view.rs
server/src/websocket_server/server.rs
ui/src/components/communities.tsx
ui/src/components/login.tsx
ui/src/components/main.tsx
ui/src/components/post-form.tsx
ui/src/interfaces.ts
ui/src/services/WebSocketService.ts

index 185484bf05bf925e78722e04d2aa3eaa69915838..cb89b2264390cb09dd8a620723e22df23ce318a4 100644 (file)
@@ -2,6 +2,7 @@ extern crate diesel;
 use diesel::*;
 use diesel::result::Error;
 use serde::{Deserialize, Serialize};
+use {SortType};
 
 table! {
   community_view (id) {
@@ -83,17 +84,27 @@ impl CommunityView {
     query.first::<Self>(conn)
   }
 
-  pub fn list_all(conn: &PgConnection, from_user_id: Option<i32>) -> Result<Vec<Self>, Error> {
+  pub fn list(conn: &PgConnection, from_user_id: Option<i32>, sort: SortType, limit: Option<i64>) -> Result<Vec<Self>, Error> {
     use actions::community_view::community_view::dsl::*;
     let mut query = community_view.into_boxed();
 
+
+
     // The view lets you pass a null user_id, if you're not logged in
-    if let Some(from_user_id) = from_user_id {
-      query = query.filter(user_id.eq(from_user_id))
-        .order_by((subscribed.desc(), number_of_subscribers.desc()));
-    } else {
-      query = query.filter(user_id.is_null())
-        .order_by(number_of_subscribers.desc());
+
+    match sort {
+      SortType::New => query = query.order_by(published.desc()).filter(user_id.is_null()),
+      SortType::TopAll => {
+        match from_user_id {
+          Some(from_user_id) => query = query.filter(user_id.eq(from_user_id)).order_by((subscribed.desc(), number_of_subscribers.desc())),
+          None => query = query.order_by(number_of_subscribers.desc()).filter(user_id.is_null())
+        }
+      }
+      _ => ()
+    };
+
+    if let Some(limit) = limit {
+      query = query.limit(limit);
     };
 
     query.load::<Self>(conn) 
index 42124d2d61ef50d6db5f73afcca0e7efa11d8c2f..137761ab377d318cba833dafdfa6302c56767064 100644 (file)
@@ -111,6 +111,8 @@ pub struct CommunityResponse {
 
 #[derive(Serialize, Deserialize)]
 pub struct ListCommunities {
+  sort: String,
+  limit: Option<i64>,
   auth: Option<String>
 }
 
@@ -675,7 +677,9 @@ impl Perform for ListCommunities {
       None => None
     };
 
-    let communities: Vec<CommunityView> = CommunityView::list_all(&conn, user_id).unwrap();
+    let sort = SortType::from_str(&self.sort).expect("listing sort");
+
+    let communities: Vec<CommunityView> = CommunityView::list(&conn, user_id, sort, self.limit).unwrap();
 
     // Return the jwt
     serde_json::to_string(
index 268aa11512ffb8c43cb90d067fa401662aa67878..4d2512cccd53d6671a7725b1ef4abac170e26f1b 100644 (file)
@@ -2,7 +2,7 @@ import { Component, linkEvent } from 'inferno';
 import { Link } from 'inferno-router';
 import { Subscription } from "rxjs";
 import { retryWhen, delay, take } from 'rxjs/operators';
-import { UserOperation, Community, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm } from '../interfaces';
+import { UserOperation, Community, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm, ListCommunitiesForm, SortType } from '../interfaces';
 import { WebSocketService } from '../services';
 import { msgOp } from '../utils';
 
@@ -30,7 +30,12 @@ export class Communities extends Component<any, CommunitiesState> {
         (err) => console.error(err),
         () => console.log('complete')
     );
-    WebSocketService.Instance.listCommunities();
+
+    let listCommunitiesForm: ListCommunitiesForm = {
+      sort: SortType[SortType.TopAll]
+    }
+
+    WebSocketService.Instance.listCommunities(listCommunitiesForm);
 
   }
 
index 933b08be62f35ae0cb8d7e80a7d0cc635c8f557d..2d2339f55a14c79426022c387aa6ce124806868e 100644 (file)
@@ -103,7 +103,7 @@ export class Login extends Component<any, State> {
         <div class="form-group row">
           <label class="col-sm-2 col-form-label">Email</label>
           <div class="col-sm-10">
-            <input type="email" class="form-control" value={this.state.registerForm.email} onInput={linkEvent(this, this.handleRegisterEmailChange)} minLength={3} />
+            <input type="email" class="form-control" placeholder="Optional" value={this.state.registerForm.email} onInput={linkEvent(this, this.handleRegisterEmailChange)} minLength={3} />
           </div>
         </div>
         <div class="form-group row">
index 8faf858aeb1c9a6bc40d7a0514842753e3126844..55066d0094c66bcdde9de1cb6e3fe31c752c25e0 100644 (file)
@@ -2,13 +2,14 @@ import { Component } from 'inferno';
 import { Link } from 'inferno-router';
 import { Subscription } from "rxjs";
 import { retryWhen, delay, take } from 'rxjs/operators';
-import { UserOperation, CommunityUser, GetFollowedCommunitiesResponse } from '../interfaces';
+import { UserOperation, CommunityUser, GetFollowedCommunitiesResponse, ListCommunitiesForm, ListCommunitiesResponse, Community, SortType } from '../interfaces';
 import { WebSocketService, UserService } from '../services';
 import { PostListings } from './post-listings';
 import { msgOp, repoUrl } from '../utils';
 
 interface State {
   subscribedCommunities: Array<CommunityUser>;
+  trendingCommunities: Array<Community>;
   loading: boolean;
 }
 
@@ -17,6 +18,7 @@ export class Main extends Component<any, State> {
   private subscription: Subscription;
   private emptyState: State = {
     subscribedCommunities: [],
+    trendingCommunities: [],
     loading: true
   }
 
@@ -36,6 +38,13 @@ export class Main extends Component<any, State> {
     if (UserService.Instance.loggedIn) {
       WebSocketService.Instance.getFollowedCommunities();
     }
+
+    let listCommunitiesForm: ListCommunitiesForm = {
+      sort: SortType[SortType.New],
+      limit: 8
+    }
+
+    WebSocketService.Instance.listCommunities(listCommunitiesForm);
   }
 
   componentWillUnmount() {
@@ -50,21 +59,22 @@ export class Main extends Component<any, State> {
             <PostListings />
           </div>
           <div class="col-12 col-md-4">
-            {UserService.Instance.loggedIn ?
+            {this.state.loading ? 
+            <h4><svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg></h4> : 
+            <div>
+              {this.trendingCommunities()}
+              {UserService.Instance.loggedIn ?
               <div>
-                {this.state.loading ? 
-                <h4><svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg></h4> : 
-                <div>
-                  <h4>Subscribed forums</h4>
-                  <ul class="list-unstyled"> 
-                    {this.state.subscribedCommunities.map(community =>
-                      <li><Link to={`/community/${community.community_id}`}>{community.community_name}</Link></li>
-                    )}
-                  </ul>
-                </div>
-                }
+                <h4>Subscribed forums</h4>
+                <ul class="list-inline"> 
+                  {this.state.subscribedCommunities.map(community =>
+                    <li class="list-inline-item"><Link to={`/community/${community.community_id}`}>{community.community_name}</Link></li>
+                  )}
+                </ul>
               </div> :
-            this.landing()
+                this.landing()
+              }
+            </div>
             }
           </div>
         </div>
@@ -72,6 +82,19 @@ export class Main extends Component<any, State> {
     )
   }
 
+  trendingCommunities() {
+    return (
+      <div>
+        <h4>Trending forums</h4> 
+        <ul class="list-inline"> 
+          {this.state.trendingCommunities.map(community =>
+            <li class="list-inline-item"><Link to={`/community/${community.id}`}>{community.name}</Link></li>
+          )}
+        </ul>
+      </div>
+    )
+  }
+
   landing() {
     return (
       <div>
@@ -99,6 +122,11 @@ export class Main extends Component<any, State> {
       this.state.subscribedCommunities = res.communities;
       this.state.loading = false;
       this.setState(this.state);
+    } else if (op == UserOperation.ListCommunities) {
+      let res: ListCommunitiesResponse = msg;
+      this.state.trendingCommunities = res.communities;
+      this.state.loading = false;
+      this.setState(this.state);
     }
   }
 }
index 03ace380236ae8e4492643e0b6f8748f0b1b03c0..67a3f42e082c0b60fe7f2ba3bcf27a199027d373 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, linkEvent } from 'inferno';
 import { Subscription } from "rxjs";
 import { retryWhen, delay, take } from 'rxjs/operators';
-import { PostForm as PostFormI, Post, PostResponse, UserOperation, Community, ListCommunitiesResponse } from '../interfaces';
+import { PostForm as PostFormI, Post, PostResponse, UserOperation, Community, ListCommunitiesResponse, ListCommunitiesForm, SortType } from '../interfaces';
 import { WebSocketService } from '../services';
 import { msgOp } from '../utils';
 import * as autosize from 'autosize';
@@ -56,7 +56,11 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
         () => console.log('complete')
       );
 
-    WebSocketService.Instance.listCommunities();
+      let listCommunitiesForm: ListCommunitiesForm = {
+        sort: SortType[SortType.TopAll]
+      }
+
+      WebSocketService.Instance.listCommunities(listCommunitiesForm);
   }
 
   componentDidMount() {
index 6608864798981712bb34cb018f066aa1e3b5eed0..b6139134d4e0ed80a6bf8c851c6bd2f273b601a1 100644 (file)
@@ -67,6 +67,12 @@ export interface CommunityResponse {
   community: Community;
 }
 
+export interface ListCommunitiesForm {
+  sort: string;
+  limit?: number;
+  auth?: string;
+}
+
 export interface ListCommunitiesResponse {
   op: string;
   communities: Array<Community>;
index b5efd6a7f4bca0c3dad67d3a23744b5e66050fc1..99d65adfacc0df776efc6958c8d3213f63489e8a 100644 (file)
@@ -1,5 +1,5 @@
 import { wsUri } from '../env';
-import { LoginForm, RegisterForm, UserOperation, CommunityForm, PostForm, CommentForm, CommentLikeForm, GetPostsForm, CreatePostLikeForm, FollowCommunityForm, GetUserDetailsForm } from '../interfaces';
+import { LoginForm, RegisterForm, UserOperation, CommunityForm, PostForm, CommentForm, CommentLikeForm, GetPostsForm, CreatePostLikeForm, FollowCommunityForm, GetUserDetailsForm, ListCommunitiesForm } from '../interfaces';
 import { webSocket } from 'rxjs/webSocket';
 import { Subject } from 'rxjs';
 import { retryWhen, delay, take } from 'rxjs/operators';
@@ -47,9 +47,9 @@ export class WebSocketService {
     this.subject.next(this.wsSendWrapper(UserOperation.FollowCommunity, followCommunityForm));
   }
 
-  public listCommunities() {
-    let data = {auth: UserService.Instance.auth };
-    this.subject.next(this.wsSendWrapper(UserOperation.ListCommunities, data));
+  public listCommunities(form: ListCommunitiesForm) {
+    this.setAuth(form, false);
+    this.subject.next(this.wsSendWrapper(UserOperation.ListCommunities, form));
   }
 
   public getFollowedCommunities() {