]> Untitled Git - lemmy.git/commitdiff
Adding a front page / fetching subscribed forums.
authorDessalines <tyhou13@gmx.com>
Fri, 5 Apr 2019 19:14:54 +0000 (12:14 -0700)
committerDessalines <tyhou13@gmx.com>
Fri, 5 Apr 2019 19:14:54 +0000 (12:14 -0700)
- Adding subscribed to post view. Fixes #25

14 files changed:
server/Cargo.lock
server/migrations/2019-03-30-212058_create_post_view/up.sql
server/src/actions/community_view.rs
server/src/actions/post_view.rs
server/src/websocket_server/server.rs
ui/src/components/communities.tsx
ui/src/components/community.tsx
ui/src/components/home.tsx
ui/src/components/main.tsx [new file with mode: 0644]
ui/src/components/post-listing.tsx
ui/src/components/post-listings.tsx [new file with mode: 0644]
ui/src/index.html
ui/src/interfaces.ts
ui/src/services/WebSocketService.ts

index 21594ccf02491a7a7af3f4bacf8772a8367c87e6..0527eae7e523c00cb0449cb7463d141dc3175247 100644 (file)
@@ -1,3 +1,5 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
 [[package]]
 name = "activitypub"
 version = "0.1.4"
index c1848631e35fe4d0980c6cd6e9ac04573448f885..79084a47e764401fac4ed6e911a98e59c254720e 100644 (file)
@@ -14,7 +14,7 @@ with all_post as
 (
   select        
   p.*,
-  (select name from user_ where p.creator_id = user_.id) creator_name,
+  (select name from user_ where p.creator_id = user_.id) as creator_name,
   (select name from community where p.community_id = community.id) as community_name,
   (select count(*) from comment where comment.post_id = p.id) as number_of_comments,
   coalesce(sum(pl.score), 0) as score,
@@ -29,7 +29,8 @@ with all_post as
 select
 ap.*,
 u.id as user_id,
-coalesce(pl.score, 0) as my_vote
+coalesce(pl.score, 0) as my_vote,
+(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed
 from user_ u
 cross join all_post ap
 left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id
@@ -39,7 +40,8 @@ union all
 select 
 ap.*,
 null as user_id,
-null as my_vote
+null as my_vote,
+null as subscribed
 from all_post ap
 ;
 
index 7eb07a162ab93ddcfc6652671134618c6bb186a1..185484bf05bf925e78722e04d2aa3eaa69915838 100644 (file)
@@ -124,3 +124,25 @@ impl CommunityModeratorView {
   }
 }
 
+#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize,QueryableByName,Clone)]
+#[table_name="community_follower_view"]
+pub struct CommunityFollowerView {
+  pub id: i32,
+  pub community_id: i32,
+  pub user_id: i32,
+  pub published: chrono::NaiveDateTime,
+  pub user_name : String,
+  pub community_name: String,
+}
+
+impl CommunityFollowerView {
+  pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
+    use actions::community_view::community_follower_view::dsl::*;
+    community_follower_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_follower_view::dsl::*;
+    community_follower_view.filter(user_id.eq(from_user_id)).load::<Self>(conn)
+  }
+}
index c48c651e39a863b0b244f70d7ac06762cc5c7793..b41a77aea810dcc28f5f533a66bededc70f7b94e 100644 (file)
@@ -33,6 +33,7 @@ table! {
     hot_rank -> Int4,
     user_id -> Nullable<Int4>,
     my_vote -> Nullable<Int4>,
+    subscribed -> Nullable<Bool>,
   }
 }
 
@@ -57,6 +58,7 @@ pub struct PostView {
   pub hot_rank: i32,
   pub user_id: Option<i32>,
   pub my_vote: Option<i32>,
+  pub subscribed: Option<bool>,
 }
 
 impl PostView {
@@ -71,6 +73,13 @@ impl PostView {
       query = query.filter(community_id.eq(from_community_id));
     };
 
+    match type_ {
+      ListingType::Subscribed  => {
+        query = query.filter(subscribed.eq(true));
+      },
+      _ => {}
+    };
+
     // 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));
index fe7cd0e66286c6575a8a9a0cb664fe999a673c9b..6aae4f2fdbebc477946ffc3a0deca060df44cf4d 100644 (file)
@@ -22,7 +22,7 @@ use actions::community_view::*;
 
 #[derive(EnumString,ToString,Debug)]
 pub enum UserOperation {
-  Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, EditCommunity, FollowCommunity
+  Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, EditCommunity, FollowCommunity, GetFollowedCommunities
 }
 
 #[derive(Serialize, Deserialize)]
@@ -261,6 +261,18 @@ pub struct FollowCommunity {
   auth: String
 }
 
+#[derive(Serialize, Deserialize)]
+pub struct GetFollowedCommunities {
+  auth: String
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct GetFollowedCommunitiesResponse {
+  op: String,
+  communities: Vec<CommunityFollowerView>
+}
+
+
 /// `ChatServer` manages chat rooms and responsible for coordinating chat
 /// session. implementation is super primitive
 pub struct ChatServer {
@@ -450,6 +462,10 @@ impl Handler<StandardMessage> for ChatServer {
         let follow_community: FollowCommunity = serde_json::from_str(&data.to_string()).unwrap();
         follow_community.perform(self, msg.id)
       },
+      UserOperation::GetFollowedCommunities => {
+        let followed_communities: GetFollowedCommunities = serde_json::from_str(&data.to_string()).unwrap();
+        followed_communities.perform(self, msg.id)
+      },
       _ => {
         let e = ErrorMessage { 
           op: "Unknown".to_string(),
@@ -1081,8 +1097,6 @@ impl Perform for GetPosts {
 
     let conn = establish_connection();
 
-    println!("{:?}", self.auth);
-
     let user_id: Option<i32> = match &self.auth {
       Some(auth) => {
         match Claims::decode(&auth) {
@@ -1367,6 +1381,36 @@ impl Perform for FollowCommunity {
   }
 }
 
+impl Perform for GetFollowedCommunities {
+  fn op_type(&self) -> UserOperation {
+    UserOperation::GetFollowedCommunities
+  }
+
+  fn perform(&self, _chat: &mut ChatServer, _addr: usize) -> String {
+
+    let conn = establish_connection();
+
+    let claims = match Claims::decode(&self.auth) {
+      Ok(claims) => claims.claims,
+      Err(_e) => {
+        return self.error("Not logged in.");
+      }
+    };
+
+    let user_id = claims.id;
+
+    let communities: Vec<CommunityFollowerView> = CommunityFollowerView::for_user(&conn, user_id).unwrap();
+
+    // Return the jwt
+    serde_json::to_string(
+      &GetFollowedCommunitiesResponse {
+        op: self.op_type().to_string(),
+        communities: communities
+      }
+      )
+      .unwrap()
+  }
+}
 
 // impl Handler<Login> for ChatServer {
 
index e8158a3655af7b2b68fdb21792890a30a613585d..c3cde177419bbf1e937ebac0b9f6ec8f3b240896 100644 (file)
@@ -42,8 +42,8 @@ export class Communities extends Component<any, CommunitiesState> {
       <div class="container-fluid">
         <h4>Communities</h4>
         <div class="table-responsive">
-          <table id="community_table" class="table table-sm table-hover" data-sortable>
-            <thead>
+          <table id="community_table" class="table table-sm table-hover">
+            <thead class="pointer">
               <tr>
                 <th>Name</th>
                 <th>Title</th>
index 726055ba736a5da0590eb4a8e6c7b6df6b494781..0d6d353df622e14e26d3f41fe831de1c9aa174d0 100644 (file)
@@ -5,15 +5,14 @@ import { retryWhen, delay, take } from 'rxjs/operators';
 import { UserOperation, Community as CommunityI, GetCommunityResponse, 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';
+import { PostListings } from './post-listings';
 import { Sidebar } from './sidebar';
 import { msgOp, mdToHtml } from '../utils';
 
 interface State {
   community: CommunityI;
+  communityId: number;
   moderators: Array<CommunityUser>;
-  posts: Array<Post>;
-  sortType: ListingSortType;
 }
 
 export class Community extends Component<any, State> {
@@ -34,8 +33,7 @@ export class Community extends Component<any, State> {
       published: null
     },
     moderators: [],
-    posts: [],
-    sortType: ListingSortType.Hot,
+    communityId: Number(this.props.match.params.id)
   }
 
   constructor(props, context) {
@@ -51,16 +49,7 @@ export class Community extends Component<any, State> {
         () => console.log('complete')
       );
 
-    let communityId = Number(this.props.match.params.id);
-    WebSocketService.Instance.getCommunity(communityId);
-
-    let getPostsForm: GetPostsForm = {
-      community_id: communityId,
-      limit: 10,
-      sort: ListingSortType[ListingSortType.Hot],
-      type_: ListingType[ListingType.Community]
-    }
-    WebSocketService.Instance.getPosts(getPostsForm);
+    WebSocketService.Instance.getCommunity(this.state.communityId);
   }
 
   componentWillUnmount() {
@@ -73,12 +62,7 @@ export class Community extends Component<any, State> {
         <div class="row">
           <div class="col-12 col-lg-9">
             <h4>/f/{this.state.community.name}</h4>
-            <div>{this.selects()}</div>
-            {this.state.posts.length > 0 
-              ? this.state.posts.map(post => 
-                <PostListing post={post} />) 
-              : <div>no listings</div>
-            }
+            <PostListings communityId={this.state.communityId} />
           </div>
           <div class="col-12 col-lg-3">
             <Sidebar community={this.state.community} moderators={this.state.moderators} />
@@ -88,37 +72,6 @@ export class Community extends Component<any, State> {
     )
   }
 
-  selects() {
-    return (
-      <div className="mb-2">
-        <select value={this.state.sortType} onChange={linkEvent(this, this.handleSortChange)} class="custom-select w-auto">
-          <option disabled>Sort Type</option>
-          <option value={ListingSortType.Hot}>Hot</option>
-          <option value={ListingSortType.New}>New</option>
-          <option disabled>──────────</option>
-          <option value={ListingSortType.TopDay}>Top Day</option>
-          <option value={ListingSortType.TopWeek}>Week</option>
-          <option value={ListingSortType.TopMonth}>Month</option>
-          <option value={ListingSortType.TopYear}>Year</option>
-          <option value={ListingSortType.TopAll}>All</option>
-        </select>
-      </div>
-    )
-
-  }
-
-  handleSortChange(i: Community, event) {
-    i.state.sortType = Number(event.target.value);
-    i.setState(i.state);
-
-    let getPostsForm: GetPostsForm = {
-      community_id: i.state.community.id,
-      limit: 10,
-      sort: ListingSortType[i.state.sortType],
-      type_: ListingType[ListingType.Community]
-    }
-    WebSocketService.Instance.getPosts(getPostsForm);
-  }
 
   parseMessage(msg: any) {
     console.log(msg);
@@ -131,18 +84,6 @@ export class Community extends Component<any, State> {
       this.state.community = res.community;
       this.state.moderators = res.moderators;
       this.setState(this.state);
-    }  else if (op == UserOperation.GetPosts) {
-      let res: GetPostsResponse = msg;
-      this.state.posts = res.posts;
-      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.EditCommunity) {
       let res: CommunityResponse = msg;
       this.state.community = res.community;
@@ -156,4 +97,3 @@ export class Community extends Component<any, State> {
   }
 }
 
-
index 07cb94f5a4b86b33b6eb5a8f20e212de57ae3b7b..356534f75036b778de763cfda442b4e5d2f8b4e2 100644 (file)
@@ -1,13 +1,12 @@
 import { Component } from 'inferno';
 import { repoUrl } from '../utils';
+import { Main } from './main';
 
 export class Home extends Component<any, any> {
 
   render() {
     return (
-      <div class="container">
-        hola this is me.
-      </div>
+      <Main />
     )
   }
 
diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx
new file mode 100644 (file)
index 0000000..b7b0a56
--- /dev/null
@@ -0,0 +1,85 @@
+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, GetCommunityResponse, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse, CommunityUser, GetFollowedCommunitiesResponse } from '../interfaces';
+import { WebSocketService, UserService } from '../services';
+import { MomentTime } from './moment-time';
+import { PostListings } from './post-listings';
+import { Sidebar } from './sidebar';
+import { msgOp, mdToHtml } from '../utils';
+
+interface State {
+  subscribedCommunities: Array<CommunityUser>;
+}
+
+export class Main extends Component<any, State> {
+
+  private subscription: Subscription;
+  private emptyState: State = {
+    subscribedCommunities: []
+  }
+
+  constructor(props, context) {
+    super(props, context);
+
+    this.state = this.emptyState;
+
+    this.subscription = WebSocketService.Instance.subject
+      .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
+      .subscribe(
+        (msg) => this.parseMessage(msg),
+        (err) => console.error(err),
+        () => console.log('complete')
+      );
+
+    if (UserService.Instance.loggedIn) {
+      WebSocketService.Instance.getFollowedCommunities();
+    }
+  }
+
+  componentWillUnmount() {
+    this.subscription.unsubscribe();
+  }
+
+  render() {
+    return (
+      <div class="container">
+        <div class="row">
+          <div class="col-12 col-lg-9">
+            <PostListings />
+          </div>
+          <div class="col-12 col-lg-3">
+            <h4>A Landing message</h4>
+            {UserService.Instance.loggedIn &&
+              <div>
+                <hr />
+                <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>
+            }
+          </div>
+        </div>
+      </div>
+    )
+  }
+
+
+  parseMessage(msg: any) {
+    console.log(msg);
+    let op: UserOperation = msgOp(msg);
+    if (msg.error) {
+      alert(msg.error);
+      return;
+    } else if (op == UserOperation.GetFollowedCommunities) {
+      let res: GetFollowedCommunitiesResponse = msg;
+      this.state.subscribedCommunities = res.communities;
+      this.setState(this.state);
+    }
+  }
+}
+
index 516baad32e340d0cb6bec66bc19180ad762a8b2d..c5052efb40cceae58653451e5b95b79bc8be4446 100644 (file)
@@ -59,8 +59,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         </div>
         <div className="ml-4">
           {post.url 
-            ? <h4 className="mb-0">
-            <a className="text-white" href={post.url}>{post.name}</a>
+            ? <div className="mb-0">
+            <h4 className="d-inline"><a className="text-white" href={post.url}>{post.name}</a></h4>
             <small><a className="ml-2 text-muted font-italic" href={post.url}>{(new URL(post.url)).hostname}</a></small>
             { !this.state.iframeExpanded
               ? <span class="pointer ml-2 text-muted small" title="Expand here" onClick={linkEvent(this, this.handleIframeExpandClick)}>+</span>
@@ -72,7 +72,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
                 </div>
               </span>
             }
-          </h4
+          </div
             : <h4 className="mb-0"><Link className="text-white" to={`/post/${post.id}`}>{post.name}</Link></h4>
           }
         </div>
@@ -80,7 +80,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           <ul class="list-inline mb-0 text-muted small">
             <li className="list-inline-item">
               <span>by </span>
-              <a href={post.creator_id.toString()}>{post.creator_name}</a>
+              <Link to={`/user/${post.creator_id}`}>{post.creator_name}</Link>
               {this.props.showCommunity && 
                 <span>
                   <span> to </span>
diff --git a/ui/src/components/post-listings.tsx b/ui/src/components/post-listings.tsx
new file mode 100644 (file)
index 0000000..fcc41cf
--- /dev/null
@@ -0,0 +1,167 @@
+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, GetCommunityResponse, 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';
+import { Sidebar } from './sidebar';
+import { msgOp, mdToHtml } from '../utils';
+
+
+interface PostListingsProps {
+  communityId?: number;
+}
+
+interface PostListingsState {
+  community: CommunityI;
+  moderators: Array<CommunityUser>;
+  posts: Array<Post>;
+  sortType: ListingSortType;
+  type_: ListingType;
+}
+
+export class PostListings extends Component<PostListingsProps, PostListingsState> {
+
+  private subscription: Subscription;
+  private emptyState: PostListingsState = {
+    community: {
+      id: null,
+      name: null,
+      title: null,
+      category_id: null,
+      category_name: null,
+      creator_id: null,
+      creator_name: null,
+      number_of_subscribers: null,
+      number_of_posts: null,
+      number_of_comments: null,
+      published: null
+    },
+    moderators: [],
+    posts: [],
+    sortType: ListingSortType.Hot,
+    type_: this.props.communityId 
+    ? ListingType.Community 
+    : UserService.Instance.loggedIn
+    ? ListingType.Subscribed 
+    : ListingType.All
+  }
+
+  constructor(props, context) {
+    super(props, context);
+
+
+    this.state = this.emptyState;
+
+    this.subscription = WebSocketService.Instance.subject
+      .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
+      .subscribe(
+        (msg) => this.parseMessage(msg),
+        (err) => console.error(err),
+        () => console.log('complete')
+      );
+
+    let getPostsForm: GetPostsForm = {
+      type_: ListingType[this.state.type_],
+      community_id: this.props.communityId,
+      limit: 10,
+      sort: ListingSortType[ListingSortType.Hot],
+    }
+    WebSocketService.Instance.getPosts(getPostsForm);
+  }
+
+  componentWillUnmount() {
+    this.subscription.unsubscribe();
+  }
+
+  render() {
+    return (
+      <div>
+        <div>{this.selects()}</div>
+        {this.state.posts.length > 0 
+          ? this.state.posts.map(post => 
+            <PostListing post={post} showCommunity={!this.props.communityId}/>) 
+          : <div>No Listings</div>
+        }
+      </div>
+    )
+  }
+
+  selects() {
+    return (
+      <div className="mb-2">
+        <select value={this.state.sortType} onChange={linkEvent(this, this.handleSortChange)} class="custom-select w-auto">
+          <option disabled>Sort Type</option>
+          <option value={ListingSortType.Hot}>Hot</option>
+          <option value={ListingSortType.New}>New</option>
+          <option disabled>──────────</option>
+          <option value={ListingSortType.TopDay}>Top Day</option>
+          <option value={ListingSortType.TopWeek}>Week</option>
+          <option value={ListingSortType.TopMonth}>Month</option>
+          <option value={ListingSortType.TopYear}>Year</option>
+          <option value={ListingSortType.TopAll}>All</option>
+        </select>
+        {!this.props.communityId && 
+          UserService.Instance.loggedIn &&
+          <select value={this.state.type_} onChange={linkEvent(this, this.handleTypeChange)} class="ml-2 custom-select w-auto">
+          <option disabled>Type</option>
+          <option value={ListingType.All}>All</option>
+          <option value={ListingType.Subscribed}>Subscribed</option>
+        </select>
+
+        }
+      </div>
+    )
+
+  }
+
+  handleSortChange(i: PostListings, event) {
+    i.state.sortType = Number(event.target.value);
+    i.setState(i.state);
+
+    let getPostsForm: GetPostsForm = {
+      community_id: i.state.community.id,
+      limit: 10,
+      sort: ListingSortType[i.state.sortType],
+      type_: ListingType[ListingType.Community]
+    }
+    WebSocketService.Instance.getPosts(getPostsForm);
+  }
+
+  handleTypeChange(i: PostListings, event) {
+    i.state.type_ = Number(event.target.value);
+    i.setState(i.state);
+
+    let getPostsForm: GetPostsForm = {
+      limit: 10,
+      sort: ListingSortType[i.state.sortType],
+      type_: ListingType[i.state.type_]
+    }
+    WebSocketService.Instance.getPosts(getPostsForm);
+  }
+
+  parseMessage(msg: any) {
+    console.log(msg);
+    let op: UserOperation = msgOp(msg);
+    if (msg.error) {
+      alert(msg.error);
+      return;
+    } else if (op == UserOperation.GetPosts) {
+      let res: GetPostsResponse = msg;
+      this.state.posts = res.posts;
+      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);
+    }
+  }
+}
+
+
index 8b6fccf2408b123b3298f519f554fa5a4da41c22..2b79ac1ce056c81298f94d1c937feb01cfb7f105 100644 (file)
@@ -10,7 +10,7 @@
   <link rel="stylesheet" href="https://bootswatch.com/4/darkly/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/balloon-css/0.5.0/balloon.min.css">
   <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,400i,700,800" rel="stylesheet"> 
-  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/sortable/0.8.0/css/sortable-theme-minimal.min.css" />
+  <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/sortable/0.8.0/css/sortable-theme-minimal.min.css" /> -->
   <script src="https://cdnjs.cloudflare.com/ajax/libs/sortable/0.8.0/js/sortable.min.js"></script>
 </head>
 
index f8007cbaf7b9e969652b9d4d531f025d878b3f6b..6d314c6217d61e98ed5c16b9d056411480eb4920 100644 (file)
@@ -1,5 +1,5 @@
 export enum UserOperation {
-  Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, EditCommunity, FollowCommunity
+  Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, EditCommunity, FollowCommunity, GetFollowedCommunities
 }
 
 export interface User {
@@ -179,6 +179,11 @@ export interface FollowCommunityForm {
   auth?: string;
 }
 
+export interface GetFollowedCommunitiesResponse {
+  op: string;
+  communities: Array<CommunityUser>;
+}
+
 export interface LoginForm {
   username_or_email: string;
   password: string;
index c8cc95570b6e366729ce99c229f704e1c7a39a8e..79f6750abc1b075229be573abd9201f37f9acf53 100644 (file)
@@ -52,6 +52,11 @@ export class WebSocketService {
     this.subject.next(this.wsSendWrapper(UserOperation.ListCommunities, data));
   }
 
+  public getFollowedCommunities() {
+    let data = {auth: UserService.Instance.auth };
+    this.subject.next(this.wsSendWrapper(UserOperation.GetFollowedCommunities, data));
+  }
+
   public listCategories() {
     this.subject.next(this.wsSendWrapper(UserOperation.ListCategories, undefined));
   }