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