]> Untitled Git - lemmy-ui.git/blob - src/shared/components/person/person-details.tsx
Fix tippy on component mount. Fixes #509 (#511)
[lemmy-ui.git] / src / shared / components / person / person-details.tsx
1 import { Component } from "inferno";
2 import {
3   CommentView,
4   GetPersonDetailsResponse,
5   PersonViewSafe,
6   PostView,
7   SortType,
8 } from "lemmy-js-client";
9 import { PersonDetailsView } from "../../interfaces";
10 import { commentsToFlatNodes, setupTippy } from "../../utils";
11 import { CommentNodes } from "../comment/comment-nodes";
12 import { Paginator } from "../common/paginator";
13 import { PostListing } from "../post/post-listing";
14
15 interface PersonDetailsProps {
16   personRes: GetPersonDetailsResponse;
17   admins: PersonViewSafe[];
18   page: number;
19   limit: number;
20   sort: SortType;
21   enableDownvotes: boolean;
22   enableNsfw: boolean;
23   view: PersonDetailsView;
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 PersonDetails extends Component<PersonDetailsProps, any> {
40   constructor(props: any, context: any) {
41     super(props, context);
42     this.handlePageChange = this.handlePageChange.bind(this);
43   }
44
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
64         <Paginator page={this.props.page} onChange={this.handlePageChange} />
65       </div>
66     );
67   }
68
69   viewSelector(view: PersonDetailsView) {
70     if (
71       view === PersonDetailsView.Overview ||
72       view === PersonDetailsView.Saved
73     ) {
74       return this.overview();
75     } else if (view === PersonDetailsView.Comments) {
76       return this.comments();
77     } else if (view === PersonDetailsView.Posts) {
78       return this.posts();
79     } else {
80       return null;
81     }
82   }
83
84   renderItemType(i: ItemType) {
85     switch (i.type_) {
86       case ItemEnum.Comment: {
87         let c = i.view as CommentView;
88         return (
89           <CommentNodes
90             key={i.id}
91             nodes={[{ comment_view: c }]}
92             admins={this.props.admins}
93             noBorder
94             noIndent
95             showCommunity
96             showContext
97             enableDownvotes={this.props.enableDownvotes}
98           />
99         );
100       }
101       case ItemEnum.Post: {
102         let p = i.view as PostView;
103         return (
104           <PostListing
105             key={i.id}
106             post_view={p}
107             admins={this.props.admins}
108             showCommunity
109             enableDownvotes={this.props.enableDownvotes}
110             enableNsfw={this.props.enableNsfw}
111           />
112         );
113       }
114       default:
115         return <div />;
116     }
117   }
118
119   overview() {
120     let id = 0;
121     let comments: ItemType[] = this.props.personRes.comments.map(r => ({
122       id: id++,
123       type_: ItemEnum.Comment,
124       view: r,
125       published: r.comment.published,
126       score: r.counts.score,
127     }));
128     let posts: ItemType[] = this.props.personRes.posts.map(r => ({
129       id: id++,
130       type_: ItemEnum.Post,
131       view: r,
132       published: r.post.published,
133       score: r.counts.score,
134     }));
135
136     let combined = [...comments, ...posts];
137
138     // Sort it
139     if (this.props.sort === SortType.New) {
140       combined.sort((a, b) => b.published.localeCompare(a.published));
141     } else {
142       combined.sort((a, b) => b.score - a.score);
143     }
144
145     return (
146       <div>
147         {combined.map(i => [this.renderItemType(i), <hr class="my-3" />])}
148       </div>
149     );
150   }
151
152   comments() {
153     return (
154       <div>
155         <CommentNodes
156           nodes={commentsToFlatNodes(this.props.personRes.comments)}
157           admins={this.props.admins}
158           noIndent
159           showCommunity
160           showContext
161           enableDownvotes={this.props.enableDownvotes}
162         />
163       </div>
164     );
165   }
166
167   posts() {
168     return (
169       <div>
170         {this.props.personRes.posts.map(post => (
171           <>
172             <PostListing
173               post_view={post}
174               admins={this.props.admins}
175               showCommunity
176               enableDownvotes={this.props.enableDownvotes}
177               enableNsfw={this.props.enableNsfw}
178             />
179             <hr class="my-3" />
180           </>
181         ))}
182       </div>
183     );
184   }
185
186   handlePageChange(val: number) {
187     this.props.onPageChange(val);
188   }
189 }