]> Untitled Git - lemmy.git/blob - ui/src/components/post-listings.tsx
Adding user details / overview page.
[lemmy.git] / ui / src / components / post-listings.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Subscription } from "rxjs";
4 import { retryWhen, delay, take } from 'rxjs/operators';
5 import { UserOperation, Community as CommunityI, Post, GetPostsForm, SortType, ListingType, GetPostsResponse, CreatePostLikeResponse, CommunityUser} from '../interfaces';
6 import { WebSocketService, UserService } from '../services';
7 import { PostListing } from './post-listing';
8 import { msgOp } from '../utils';
9
10
11 interface PostListingsProps {
12   communityId?: number;
13 }
14
15 interface PostListingsState {
16   community: CommunityI;
17   moderators: Array<CommunityUser>;
18   posts: Array<Post>;
19   sortType: SortType;
20   type_: ListingType;
21 }
22
23 export class PostListings extends Component<PostListingsProps, PostListingsState> {
24
25   private subscription: Subscription;
26   private emptyState: PostListingsState = {
27     community: {
28       id: null,
29       name: null,
30       title: null,
31       category_id: null,
32       category_name: null,
33       creator_id: null,
34       creator_name: null,
35       number_of_subscribers: null,
36       number_of_posts: null,
37       number_of_comments: null,
38       published: null
39     },
40     moderators: [],
41     posts: [],
42     sortType: SortType.Hot,
43     type_: this.props.communityId 
44     ? ListingType.Community 
45     : UserService.Instance.loggedIn
46     ? ListingType.Subscribed 
47     : ListingType.All
48   }
49
50   constructor(props: any, context: any) {
51     super(props, context);
52
53
54     this.state = this.emptyState;
55
56     this.subscription = WebSocketService.Instance.subject
57       .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
58       .subscribe(
59         (msg) => this.parseMessage(msg),
60         (err) => console.error(err),
61         () => console.log('complete')
62       );
63
64     let getPostsForm: GetPostsForm = {
65       type_: ListingType[this.state.type_],
66       community_id: this.props.communityId,
67       limit: 10,
68       sort: SortType[SortType.Hot],
69     }
70     WebSocketService.Instance.getPosts(getPostsForm);
71   }
72
73   componentWillUnmount() {
74     this.subscription.unsubscribe();
75   }
76
77   render() {
78     return (
79       <div>
80         <div>{this.selects()}</div>
81         {this.state.posts.length > 0 
82           ? this.state.posts.map(post => 
83             <PostListing post={post} showCommunity={!this.props.communityId}/>) 
84           : <div>No Listings. Subscribe to some <Link to="/communities">forums</Link>.</div>
85         }
86       </div>
87     )
88   }
89
90   selects() {
91     return (
92       <div className="mb-2">
93         <select value={this.state.sortType} onChange={linkEvent(this, this.handleSortChange)} class="custom-select w-auto">
94           <option disabled>Sort Type</option>
95           <option value={SortType.Hot}>Hot</option>
96           <option value={SortType.New}>New</option>
97           <option disabled>──────────</option>
98           <option value={SortType.TopDay}>Top Day</option>
99           <option value={SortType.TopWeek}>Week</option>
100           <option value={SortType.TopMonth}>Month</option>
101           <option value={SortType.TopYear}>Year</option>
102           <option value={SortType.TopAll}>All</option>
103         </select>
104         {!this.props.communityId && 
105           UserService.Instance.loggedIn &&
106           <select value={this.state.type_} onChange={linkEvent(this, this.handleTypeChange)} class="ml-2 custom-select w-auto">
107           <option disabled>Type</option>
108           <option value={ListingType.All}>All</option>
109           <option value={ListingType.Subscribed}>Subscribed</option>
110         </select>
111
112         }
113       </div>
114     )
115
116   }
117
118   handleSortChange(i: PostListings, event: any) {
119     i.state.sortType = Number(event.target.value);
120     i.setState(i.state);
121
122     let getPostsForm: GetPostsForm = {
123       community_id: i.state.community.id,
124       limit: 10,
125       sort: SortType[i.state.sortType],
126       type_: ListingType[ListingType.Community]
127     }
128     WebSocketService.Instance.getPosts(getPostsForm);
129   }
130
131   handleTypeChange(i: PostListings, event: any) {
132     i.state.type_ = Number(event.target.value);
133     i.setState(i.state);
134
135     let getPostsForm: GetPostsForm = {
136       limit: 10,
137       sort: SortType[i.state.sortType],
138       type_: ListingType[i.state.type_]
139     }
140     WebSocketService.Instance.getPosts(getPostsForm);
141   }
142
143   parseMessage(msg: any) {
144     console.log(msg);
145     let op: UserOperation = msgOp(msg);
146     if (msg.error) {
147       alert(msg.error);
148       return;
149     } else if (op == UserOperation.GetPosts) {
150       let res: GetPostsResponse = msg;
151       this.state.posts = res.posts;
152       this.setState(this.state);
153     } else if (op == UserOperation.CreatePostLike) {
154       let res: CreatePostLikeResponse = msg;
155       let found = this.state.posts.find(c => c.id == res.post.id);
156       found.my_vote = res.post.my_vote;
157       found.score = res.post.score;
158       found.upvotes = res.post.upvotes;
159       found.downvotes = res.post.downvotes;
160       this.setState(this.state);
161     }
162   }
163 }
164
165