]> Untitled Git - lemmy-ui.git/blob - src/shared/components/user-details.tsx
Running newer prettier.
[lemmy-ui.git] / src / shared / components / user-details.tsx
1 import { Component, linkEvent } from "inferno";
2 import { i18n } from "../i18next";
3 import {
4   PostView,
5   CommentView,
6   SortType,
7   GetUserDetailsResponse,
8   UserViewSafe,
9 } from "lemmy-js-client";
10 import { UserDetailsView } from "../interfaces";
11 import { commentsToFlatNodes, setupTippy } from "../utils";
12 import { PostListing } from "./post-listing";
13 import { CommentNodes } from "./comment-nodes";
14
15 interface UserDetailsProps {
16   userRes: GetUserDetailsResponse;
17   admins: UserViewSafe[];
18   page: number;
19   limit: number;
20   sort: SortType;
21   enableDownvotes: boolean;
22   enableNsfw: boolean;
23   view: UserDetailsView;
24   onPageChange(page: number): number | any;
25 }
26
27 enum ItemEnum {
28   Comment,
29   Post,
30 }
31 type ItemType = {
32   id: number;
33   type_: ItemEnum;
34   view: CommentView | PostView;
35   published: string;
36   score: number;
37 };
38
39 export class UserDetails extends Component<UserDetailsProps, any> {
40   constructor(props: any, context: any) {
41     super(props, context);
42   }
43
44   // TODO needed here?
45   componentDidMount() {
46     setupTippy();
47   }
48
49   // TODO wut?
50   // componentDidUpdate(lastProps: UserDetailsProps) {
51   //   for (const key of Object.keys(lastProps)) {
52   //     if (lastProps[key] !== this.props[key]) {
53   //       this.fetchUserData();
54   //       break;
55   //     }
56   //   }
57   // }
58
59   render() {
60     return (
61       <div>
62         {this.viewSelector(this.props.view)}
63         {this.paginator()}
64       </div>
65     );
66   }
67
68   viewSelector(view: UserDetailsView) {
69     if (view === UserDetailsView.Overview || view === UserDetailsView.Saved) {
70       return this.overview();
71     } else if (view === UserDetailsView.Comments) {
72       return this.comments();
73     } else if (view === UserDetailsView.Posts) {
74       return this.posts();
75     } else {
76       return null;
77     }
78   }
79
80   renderItemType(i: ItemType) {
81     switch (i.type_) {
82       case ItemEnum.Comment: {
83         let c = i.view as CommentView;
84         return (
85           <CommentNodes
86             key={i.id}
87             nodes={[{ comment_view: c }]}
88             admins={this.props.admins}
89             noBorder
90             noIndent
91             showCommunity
92             showContext
93             enableDownvotes={this.props.enableDownvotes}
94           />
95         );
96       }
97       case ItemEnum.Post: {
98         let p = i.view as PostView;
99         return (
100           <PostListing
101             key={i.id}
102             post_view={p}
103             admins={this.props.admins}
104             showCommunity
105             enableDownvotes={this.props.enableDownvotes}
106             enableNsfw={this.props.enableNsfw}
107           />
108         );
109       }
110       default:
111         return <div />;
112     }
113   }
114
115   overview() {
116     let id = 0;
117     let comments: ItemType[] = this.props.userRes.comments.map(r => ({
118       id: id++,
119       type_: ItemEnum.Comment,
120       view: r,
121       published: r.comment.published,
122       score: r.counts.score,
123     }));
124     let posts: ItemType[] = this.props.userRes.posts.map(r => ({
125       id: id++,
126       type_: ItemEnum.Post,
127       view: r,
128       published: r.post.published,
129       score: r.counts.score,
130     }));
131
132     let combined = [...comments, ...posts];
133
134     // Sort it
135     if (this.props.sort === SortType.New) {
136       combined.sort((a, b) => b.published.localeCompare(a.published));
137     } else {
138       combined.sort((a, b) => b.score - a.score);
139     }
140
141     return (
142       <div>
143         {combined.map(i => [this.renderItemType(i), <hr class="my-3" />])}
144       </div>
145     );
146   }
147
148   comments() {
149     return (
150       <div>
151         <CommentNodes
152           nodes={commentsToFlatNodes(this.props.userRes.comments)}
153           admins={this.props.admins}
154           noIndent
155           showCommunity
156           showContext
157           enableDownvotes={this.props.enableDownvotes}
158         />
159       </div>
160     );
161   }
162
163   posts() {
164     return (
165       <div>
166         {this.props.userRes.posts.map(post => (
167           <>
168             <PostListing
169               post_view={post}
170               admins={this.props.admins}
171               showCommunity
172               enableDownvotes={this.props.enableDownvotes}
173               enableNsfw={this.props.enableNsfw}
174             />
175             <hr class="my-3" />
176           </>
177         ))}
178       </div>
179     );
180   }
181
182   paginator() {
183     return (
184       <div class="my-2">
185         {this.props.page > 1 && (
186           <button
187             class="btn btn-secondary mr-1"
188             onClick={linkEvent(this, this.prevPage)}
189           >
190             {i18n.t("prev")}
191           </button>
192         )}
193         {this.props.userRes.comments.length + this.props.userRes.posts.length >
194           0 && (
195           <button
196             class="btn btn-secondary"
197             onClick={linkEvent(this, this.nextPage)}
198           >
199             {i18n.t("next")}
200           </button>
201         )}
202       </div>
203     );
204   }
205
206   nextPage(i: UserDetails) {
207     i.props.onPageChange(i.props.page + 1);
208   }
209
210   prevPage(i: UserDetails) {
211     i.props.onPageChange(i.props.page - 1);
212   }
213 }