]> Untitled Git - lemmy.git/commitdiff
Getting community moderators
authorDessalines <tyhou13@gmx.com>
Thu, 4 Apr 2019 20:53:32 +0000 (13:53 -0700)
committerDessalines <tyhou13@gmx.com>
Thu, 4 Apr 2019 20:53:32 +0000 (13:53 -0700)
- Getting back mods with a fetch. Fixes #28

server/migrations/2019-04-03-155205_create_community_view/up.sql
server/src/actions/community_view.rs
server/src/websocket_server/server.rs
ui/src/components/communities.tsx
ui/src/components/community.tsx
ui/src/components/post.tsx
ui/src/components/sidebar.tsx
ui/src/interfaces.ts

index d26a313e40006b0f70c4b56a7b0e96578956ad0c..f2f4a76647593ef58b642dfe8d6a473535e65937 100644 (file)
@@ -9,10 +9,12 @@ from community c;
 
 create view community_moderator_view as 
 select *,
-(select name from user_ u where cm.user_id = u.id) as user_name
+(select name from user_ u where cm.user_id = u.id) as user_name,
+(select name from community c where cm.community_id = c.id) as community_name
 from community_moderator cm;
 
 create view community_follower_view as 
 select *,
-(select name from user_ u where cf.user_id = u.id) as user_name
+(select name from user_ u where cf.user_id = u.id) as user_name,
+(select name from community c where cf.community_id = c.id) as community_name
 from community_follower cf;
index 03d822abf4259cf46c39caaea31e4b212e16d707..eafda161db5b6734ff4512521f77e7033f332e1f 100644 (file)
@@ -21,6 +21,28 @@ table! {
   }
 }
 
+table! {
+  community_moderator_view (id) {
+    id -> Int4,
+    community_id -> Int4,
+    user_id -> Int4,
+    published -> Timestamp,
+    user_name -> Varchar,
+    community_name -> Varchar,
+  }
+}
+
+table! {
+  community_follower_view (id) {
+    id -> Int4,
+    community_id -> Int4,
+    user_id -> Int4,
+    published -> Timestamp,
+    user_name -> Varchar,
+    community_name -> Varchar,
+  }
+}
+
 #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize,QueryableByName,Clone)]
 #[table_name="community_view"]
 pub struct CommunityView {
@@ -51,3 +73,27 @@ impl CommunityView {
   }
 }
 
+
+#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize,QueryableByName,Clone)]
+#[table_name="community_moderator_view"]
+pub struct CommunityModeratorView {
+  pub id: i32,
+  pub community_id: i32,
+  pub user_id: i32,
+  pub published: chrono::NaiveDateTime,
+  pub user_name : String,
+  pub community_name: String,
+}
+
+impl CommunityModeratorView {
+  pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
+    use actions::community_view::community_moderator_view::dsl::*;
+    community_moderator_view.filter(community_id.eq(from_community_id)).load::<Self>(conn)
+  }
+
+  pub fn for_user(conn: &PgConnection, from_user_id: i32) -> Result<Vec<Self>, Error> {
+    use actions::community_view::community_moderator_view::dsl::*;
+    community_moderator_view.filter(user_id.eq(from_user_id)).load::<Self>(conn)
+  }
+}
+
index e5e117ef1eb1db23fcd40bfee882ed8f271909f3..4c13aadeece543769bf3144a3cda3d92836fcecd 100644 (file)
@@ -153,7 +153,8 @@ pub struct GetPostResponse {
   op: String,
   post: PostView,
   comments: Vec<CommentView>,
-  community: CommunityView
+  community: CommunityView,
+  moderators: Vec<CommunityModeratorView>
 }
 
 #[derive(Serialize, Deserialize)]
@@ -179,7 +180,8 @@ pub struct GetCommunity {
 #[derive(Serialize, Deserialize)]
 pub struct GetCommunityResponse {
   op: String,
-  community: CommunityView
+  community: CommunityView,
+  moderators: Vec<CommunityModeratorView>
 }
 
 #[derive(Serialize, Deserialize)]
@@ -762,13 +764,16 @@ impl Perform for GetPost {
 
     let community = CommunityView::read(&conn, post_view.community_id).unwrap();
 
+    let moderators = CommunityModeratorView::for_community(&conn, post_view.community_id).unwrap();
+
     // Return the jwt
     serde_json::to_string(
       &GetPostResponse {
         op: self.op_type().to_string(),
         post: post_view,
         comments: comments,
-        community: community
+        community: community,
+        moderators: moderators
       }
       )
       .unwrap()
@@ -791,11 +796,20 @@ impl Perform for GetCommunity {
       }
     };
 
+
+    let moderators = match CommunityModeratorView::for_community(&conn, self.id) {
+      Ok(moderators) => moderators,
+      Err(_e) => {
+        return self.error("Couldn't find Community");
+      }
+    };
+
     // Return the jwt
     serde_json::to_string(
       &GetCommunityResponse {
         op: self.op_type().to_string(),
-        community: community_view
+        community: community_view,
+        moderators: moderators
       }
       )
       .unwrap()
index 411aebe164eb746fc3f151bc3fdd9270d01384d7..921ef157fb249fc52a8470741764fb80e1c0748d 100644 (file)
@@ -32,6 +32,7 @@ export class Communities extends Component<any, CommunitiesState> {
   render() {
     return (
       <div class="container-fluid">
+        <h4>Communities</h4>
         <div class="table-responsive">
           <table class="table table-sm table-hover" data-sortable>
             <thead>
index 820db90d6df4005bf640113f0d9598640e52d8e2..5505e01d6c409dbdf86a110c696cddfe94fb7517 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 as CommunityI, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse} from '../interfaces';
+import { UserOperation, Community as CommunityI, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse, CommunityUser} from '../interfaces';
 import { WebSocketService, UserService } from '../services';
 import { MomentTime } from './moment-time';
 import { PostListing } from './post-listing';
@@ -11,6 +11,7 @@ import { msgOp, mdToHtml } from '../utils';
 
 interface State {
   community: CommunityI;
+  moderators: Array<CommunityUser>;
   posts: Array<Post>;
   sortType: ListingSortType;
 }
@@ -29,8 +30,10 @@ export class Community extends Component<any, State> {
       creator_name: null,
       number_of_subscribers: null,
       number_of_posts: null,
+      number_of_comments: null,
       published: null
     },
+    moderators: [],
     posts: [],
     sortType: ListingSortType.Hot,
   }
@@ -78,7 +81,7 @@ export class Community extends Component<any, State> {
             }
           </div>
           <div class="col-12 col-sm-2 col-lg-3">
-            <Sidebar community={this.state.community} />
+            <Sidebar community={this.state.community} moderators={this.state.moderators} />
           </div>
         </div>
       </div>
@@ -126,6 +129,7 @@ export class Community extends Component<any, State> {
     } else if (op == UserOperation.GetCommunity) {
       let res: CommunityResponse = msg;
       this.state.community = res.community;
+      this.state.moderators = res.moderators;
       this.setState(this.state);
     }  else if (op == UserOperation.GetPosts) {
       let res: GetPostsResponse = msg;
index 457b286e00acc5c7f71a6e6f8d161aa4d090ef93..f36ad97965882f567322244244e62acdf22167f0 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, Post as PostI, GetPostResponse, PostResponse, Comment, CommentForm as CommentFormI, CommentResponse, CommentLikeForm, CommentSortType, CreatePostLikeResponse } from '../interfaces';
+import { UserOperation, Community, Post as PostI, GetPostResponse, PostResponse, Comment, CommentForm as CommentFormI, CommentResponse, CommentLikeForm, CommentSortType, CreatePostLikeResponse, CommunityUser } from '../interfaces';
 import { WebSocketService, UserService } from '../services';
 import { msgOp, hotRank,mdToHtml } from '../utils';
 import { MomentTime } from './moment-time';
@@ -20,6 +20,7 @@ interface PostState {
   comments: Array<Comment>;
   commentSort: CommentSortType;
   community: Community;
+  moderators: Array<CommunityUser>;
 }
 
 export class Post extends Component<any, PostState> {
@@ -30,6 +31,7 @@ export class Post extends Component<any, PostState> {
     comments: [],
     commentSort: CommentSortType.Hot,
     community: null,
+    moderators: []
   }
 
   constructor(props, context) {
@@ -118,7 +120,7 @@ export class Post extends Component<any, PostState> {
   sidebar() {
     return ( 
       <div class="sticky-top">
-        <Sidebar community={this.state.community} />
+        <Sidebar community={this.state.community} moderators={this.state.moderators} />
       </div>
     );
   }
@@ -188,6 +190,7 @@ export class Post extends Component<any, PostState> {
       this.state.post = res.post;
       this.state.comments = res.comments;
       this.state.community = res.community;
+      this.state.moderators = res.moderators;
       this.setState(this.state);
     } else if (op == UserOperation.CreateComment) {
       let res: CommentResponse = msg;
index c8e80de62d98c0149f41f30e84275a6da6ecb7e5..e8a2f41060ddfddb1bcd403987c00e3edd4668df 100644 (file)
@@ -1,9 +1,11 @@
 import { Component, linkEvent } from 'inferno';
-import { Community } from '../interfaces';
+import { Link } from 'inferno-router';
+import { Community, CommunityUser } from '../interfaces';
 import { mdToHtml } from '../utils';
 
 interface SidebarProps {
   community: Community;
+  moderators: Array<CommunityUser>;
 }
 
 interface SidebarState {
@@ -22,14 +24,23 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
       <div>
         <h4>{community.title}</h4>
         <ul class="list-inline">
-          <li className="list-inline-item badge badge-light">{community.category_name}</li>
+          <li className="list-inline-item"><Link className="badge badge-light" to="/communities">{community.category_name}</Link></li>
           <li className="list-inline-item badge badge-light">{community.number_of_subscribers} Subscribers</li>
           <li className="list-inline-item badge badge-light">{community.number_of_posts} Posts</li>
           <li className="list-inline-item badge badge-light">{community.number_of_comments} Comments</li>
         </ul>
         <div><button type="button" class="btn btn-secondary mb-2">Subscribe</button></div>
+        {community.description && 
+          <div>
+            <hr />
+            <div className="md-div" dangerouslySetInnerHTML={mdToHtml(community.description)} />
+          </div>
+        }
         <hr />
-        {community.description && <div className="md-div" dangerouslySetInnerHTML={mdToHtml(community.description)} />}
+        <h5>Moderators</h5>
+        {this.props.moderators.map(mod =>
+          <Link to={`/user/${mod.user_id}`}>{mod.user_name}</Link>
+        )}
       </div>
     );
   }
index 7edcbd8eb7decd8cb78be1fd53e2bbc2f3e3c3cc..f202f7ac5dd385d1d725e854c1c326cb6fc44172 100644 (file)
@@ -8,6 +8,15 @@ export interface User {
   username: string;
 }
 
+export interface CommunityUser {
+  id: number;
+  user_id: number;
+  user_name: string;
+  community_id: number;
+  community_name: string;
+  published: string;
+}
+
 export interface Community {
   id: number;
   name: string;
@@ -35,6 +44,7 @@ export interface CommunityForm {
 export interface CommunityResponse {
   op: string;
   community: Community;
+  moderators: Array<CommunityUser>;
 }
 
 export interface ListCommunitiesResponse {
@@ -82,6 +92,7 @@ export interface GetPostResponse {
   post: Post;
   comments: Array<Comment>;
   community: Community;
+  moderators: Array<CommunityUser>;
 }
 
 export interface PostResponse {