]> Untitled Git - lemmy-ui.git/blob - src/shared/components/person/person-details.tsx
fix: Rework some vote buttons architecture
[lemmy-ui.git] / src / shared / components / person / person-details.tsx
1 import { commentsToFlatNodes } from "@utils/app";
2 import { Component } from "inferno";
3 import {
4   AddAdmin,
5   AddModToCommunity,
6   BanFromCommunity,
7   BanPerson,
8   BlockPerson,
9   CommentId,
10   CommentView,
11   CreateComment,
12   CreateCommentLike,
13   CreateCommentReport,
14   CreatePostLike,
15   CreatePostReport,
16   DeleteComment,
17   DeletePost,
18   DistinguishComment,
19   EditComment,
20   EditPost,
21   FeaturePost,
22   GetComments,
23   GetPersonDetailsResponse,
24   Language,
25   LockPost,
26   MarkCommentReplyAsRead,
27   MarkPersonMentionAsRead,
28   PersonView,
29   PostView,
30   PurgeComment,
31   PurgePerson,
32   PurgePost,
33   RemoveComment,
34   RemovePost,
35   SaveComment,
36   SavePost,
37   SortType,
38   TransferCommunity,
39 } from "lemmy-js-client";
40 import { CommentViewType, PersonDetailsView } from "../../interfaces";
41 import { setupTippy } from "../../tippy";
42 import { CommentNodes } from "../comment/comment-nodes";
43 import { Paginator } from "../common/paginator";
44 import { PostListing } from "../post/post-listing";
45
46 interface PersonDetailsProps {
47   personRes: GetPersonDetailsResponse;
48   finished: Map<CommentId, boolean | undefined>;
49   admins: PersonView[];
50   allLanguages: Language[];
51   siteLanguages: number[];
52   page: number;
53   limit: number;
54   sort: SortType;
55   enableDownvotes: boolean;
56   enableNsfw: boolean;
57   view: PersonDetailsView;
58   onPageChange(page: number): number | any;
59   onSaveComment(form: SaveComment): void;
60   onCommentReplyRead(form: MarkCommentReplyAsRead): void;
61   onPersonMentionRead(form: MarkPersonMentionAsRead): void;
62   onCreateComment(form: CreateComment): void;
63   onEditComment(form: EditComment): void;
64   onCommentVote(form: CreateCommentLike): void;
65   onBlockPerson(form: BlockPerson): void;
66   onDeleteComment(form: DeleteComment): void;
67   onRemoveComment(form: RemoveComment): void;
68   onDistinguishComment(form: DistinguishComment): void;
69   onAddModToCommunity(form: AddModToCommunity): void;
70   onAddAdmin(form: AddAdmin): void;
71   onBanPersonFromCommunity(form: BanFromCommunity): void;
72   onBanPerson(form: BanPerson): void;
73   onTransferCommunity(form: TransferCommunity): void;
74   onFetchChildren?(form: GetComments): void;
75   onCommentReport(form: CreateCommentReport): void;
76   onPurgePerson(form: PurgePerson): void;
77   onPurgeComment(form: PurgeComment): void;
78   onPostEdit(form: EditPost): void;
79   onPostVote(form: CreatePostLike): void;
80   onPostReport(form: CreatePostReport): void;
81   onLockPost(form: LockPost): void;
82   onDeletePost(form: DeletePost): void;
83   onRemovePost(form: RemovePost): void;
84   onSavePost(form: SavePost): void;
85   onFeaturePost(form: FeaturePost): void;
86   onPurgePost(form: PurgePost): void;
87 }
88
89 enum ItemEnum {
90   Comment,
91   Post,
92 }
93 type ItemType = {
94   id: number;
95   type_: ItemEnum;
96   view: CommentView | PostView;
97   published: string;
98   score: number;
99 };
100
101 export class PersonDetails extends Component<PersonDetailsProps, any> {
102   constructor(props: any, context: any) {
103     super(props, context);
104     this.handlePageChange = this.handlePageChange.bind(this);
105   }
106
107   componentDidMount() {
108     setupTippy();
109   }
110
111   render() {
112     return (
113       <div className="person-details">
114         {this.viewSelector(this.props.view)}
115
116         <Paginator page={this.props.page} onChange={this.handlePageChange} />
117       </div>
118     );
119   }
120
121   viewSelector(view: PersonDetailsView) {
122     if (
123       view === PersonDetailsView.Overview ||
124       view === PersonDetailsView.Saved
125     ) {
126       return this.overview();
127     } else if (view === PersonDetailsView.Comments) {
128       return this.comments();
129     } else if (view === PersonDetailsView.Posts) {
130       return this.posts();
131     } else {
132       return null;
133     }
134   }
135
136   renderItemType(i: ItemType) {
137     switch (i.type_) {
138       case ItemEnum.Comment: {
139         const c = i.view as CommentView;
140         return (
141           <CommentNodes
142             key={i.id}
143             nodes={[{ comment_view: c, children: [], depth: 0 }]}
144             viewType={CommentViewType.Flat}
145             finished={this.props.finished}
146             admins={this.props.admins}
147             noBorder
148             noIndent
149             showCommunity
150             showContext
151             enableDownvotes={this.props.enableDownvotes}
152             allLanguages={this.props.allLanguages}
153             siteLanguages={this.props.siteLanguages}
154             onCommentReplyRead={this.props.onCommentReplyRead}
155             onPersonMentionRead={this.props.onPersonMentionRead}
156             onCreateComment={this.props.onCreateComment}
157             onEditComment={this.props.onEditComment}
158             onCommentVote={this.props.onCommentVote}
159             onBlockPerson={this.props.onBlockPerson}
160             onSaveComment={this.props.onSaveComment}
161             onDeleteComment={this.props.onDeleteComment}
162             onRemoveComment={this.props.onRemoveComment}
163             onDistinguishComment={this.props.onDistinguishComment}
164             onAddModToCommunity={this.props.onAddModToCommunity}
165             onAddAdmin={this.props.onAddAdmin}
166             onBanPersonFromCommunity={this.props.onBanPersonFromCommunity}
167             onBanPerson={this.props.onBanPerson}
168             onTransferCommunity={this.props.onTransferCommunity}
169             onFetchChildren={this.props.onFetchChildren}
170             onCommentReport={this.props.onCommentReport}
171             onPurgePerson={this.props.onPurgePerson}
172             onPurgeComment={this.props.onPurgeComment}
173           />
174         );
175       }
176       case ItemEnum.Post: {
177         const p = i.view as PostView;
178         return (
179           <PostListing
180             key={i.id}
181             post_view={p}
182             admins={this.props.admins}
183             showCommunity
184             enableDownvotes={this.props.enableDownvotes}
185             enableNsfw={this.props.enableNsfw}
186             allLanguages={this.props.allLanguages}
187             siteLanguages={this.props.siteLanguages}
188             onPostEdit={this.props.onPostEdit}
189             onPostVote={this.props.onPostVote}
190             onPostReport={this.props.onPostReport}
191             onBlockPerson={this.props.onBlockPerson}
192             onLockPost={this.props.onLockPost}
193             onDeletePost={this.props.onDeletePost}
194             onRemovePost={this.props.onRemovePost}
195             onSavePost={this.props.onSavePost}
196             onFeaturePost={this.props.onFeaturePost}
197             onPurgePerson={this.props.onPurgePerson}
198             onPurgePost={this.props.onPurgePost}
199             onBanPersonFromCommunity={this.props.onBanPersonFromCommunity}
200             onBanPerson={this.props.onBanPerson}
201             onAddModToCommunity={this.props.onAddModToCommunity}
202             onAddAdmin={this.props.onAddAdmin}
203             onTransferCommunity={this.props.onTransferCommunity}
204           />
205         );
206       }
207       default:
208         return <div />;
209     }
210   }
211
212   overview() {
213     let id = 0;
214     const comments: ItemType[] = this.props.personRes.comments.map(r => ({
215       id: id++,
216       type_: ItemEnum.Comment,
217       view: r,
218       published: r.comment.published,
219       score: r.counts.score,
220     }));
221     const posts: ItemType[] = this.props.personRes.posts.map(r => ({
222       id: id++,
223       type_: ItemEnum.Post,
224       view: r,
225       published: r.post.published,
226       score: r.counts.score,
227     }));
228
229     const combined = [...comments, ...posts];
230
231     // Sort it
232     if (this.props.sort === "New") {
233       combined.sort((a, b) => b.published.localeCompare(a.published));
234     } else {
235       combined.sort((a, b) => Number(b.score - a.score));
236     }
237
238     return (
239       <div>
240         {combined.map(i => [
241           this.renderItemType(i),
242           <hr key={i.type_} className="my-3" />,
243         ])}
244       </div>
245     );
246   }
247
248   comments() {
249     return (
250       <div>
251         <CommentNodes
252           nodes={commentsToFlatNodes(this.props.personRes.comments)}
253           viewType={CommentViewType.Flat}
254           admins={this.props.admins}
255           finished={this.props.finished}
256           noIndent
257           showCommunity
258           showContext
259           enableDownvotes={this.props.enableDownvotes}
260           allLanguages={this.props.allLanguages}
261           siteLanguages={this.props.siteLanguages}
262           onCommentReplyRead={this.props.onCommentReplyRead}
263           onPersonMentionRead={this.props.onPersonMentionRead}
264           onCreateComment={this.props.onCreateComment}
265           onEditComment={this.props.onEditComment}
266           onCommentVote={this.props.onCommentVote}
267           onBlockPerson={this.props.onBlockPerson}
268           onSaveComment={this.props.onSaveComment}
269           onDeleteComment={this.props.onDeleteComment}
270           onRemoveComment={this.props.onRemoveComment}
271           onDistinguishComment={this.props.onDistinguishComment}
272           onAddModToCommunity={this.props.onAddModToCommunity}
273           onAddAdmin={this.props.onAddAdmin}
274           onBanPersonFromCommunity={this.props.onBanPersonFromCommunity}
275           onBanPerson={this.props.onBanPerson}
276           onTransferCommunity={this.props.onTransferCommunity}
277           onFetchChildren={this.props.onFetchChildren}
278           onCommentReport={this.props.onCommentReport}
279           onPurgePerson={this.props.onPurgePerson}
280           onPurgeComment={this.props.onPurgeComment}
281         />
282       </div>
283     );
284   }
285
286   posts() {
287     return (
288       <div>
289         {this.props.personRes.posts.map(post => (
290           <>
291             <PostListing
292               post_view={post}
293               admins={this.props.admins}
294               showCommunity
295               enableDownvotes={this.props.enableDownvotes}
296               enableNsfw={this.props.enableNsfw}
297               allLanguages={this.props.allLanguages}
298               siteLanguages={this.props.siteLanguages}
299               onPostEdit={this.props.onPostEdit}
300               onPostVote={this.props.onPostVote}
301               onPostReport={this.props.onPostReport}
302               onBlockPerson={this.props.onBlockPerson}
303               onLockPost={this.props.onLockPost}
304               onDeletePost={this.props.onDeletePost}
305               onRemovePost={this.props.onRemovePost}
306               onSavePost={this.props.onSavePost}
307               onFeaturePost={this.props.onFeaturePost}
308               onPurgePerson={this.props.onPurgePerson}
309               onPurgePost={this.props.onPurgePost}
310               onBanPersonFromCommunity={this.props.onBanPersonFromCommunity}
311               onBanPerson={this.props.onBanPerson}
312               onAddModToCommunity={this.props.onAddModToCommunity}
313               onAddAdmin={this.props.onAddAdmin}
314               onTransferCommunity={this.props.onTransferCommunity}
315             />
316             <hr className="my-3" />
317           </>
318         ))}
319       </div>
320     );
321   }
322
323   handlePageChange(val: number) {
324     this.props.onPageChange(val);
325   }
326 }