1 import { Component } from 'inferno';
2 import { WebSocketService, UserService } from '../services';
3 import { Subscription } from 'rxjs';
4 import { retryWhen, delay, take, last } from 'rxjs/operators';
5 import { i18n } from '../i18next';
14 WebSocketJsonResponse,
20 } from '../interfaces';
29 createPostLikeFindRes,
31 import { PostListing } from './post-listing';
32 import { CommentNodes } from './comment-nodes';
34 interface UserDetailsProps {
40 enableDownvotes: boolean;
42 view: UserDetailsView;
45 interface UserDetailsState {
46 follows: Array<CommunityUser>;
47 moderates: Array<CommunityUser>;
48 comments: Array<Comment>;
51 admins: Array<UserView>;
54 export class UserDetails extends Component<UserDetailsProps, UserDetailsState> {
55 private subscription: Subscription;
56 constructor(props: any, context: any) {
57 super(props, context);
68 this.subscription = WebSocketService.Instance.subject
69 .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
71 msg => this.parseMessage(msg),
72 err => console.error(err),
73 () => console.log('complete')
77 componentWillUnmount() {
78 this.subscription.unsubscribe();
85 componentDidUpdate(lastProps: UserDetailsProps) {
86 for (const key of Object.keys(lastProps)) {
87 if (lastProps[key] !== this.props[key]) {
96 WebSocketService.Instance.getUserDetails({
97 user_id: this.props.user_id,
98 username: this.props.username,
99 sort: this.props.sort,
100 saved_only: this.props.view === UserDetailsView.Saved,
101 page: this.props.page,
102 limit: this.props.limit,
107 return this.viewSelector(this.props.view);
110 viewSelector(view: UserDetailsView) {
111 if (view === UserDetailsView.Overview || view === UserDetailsView.Saved) {
112 return this.overview();
114 if (view === UserDetailsView.Comments) {
115 return this.comments();
117 if (view === UserDetailsView.Posts) {
123 const comments = this.state.comments.map((c: Comment) => {
124 return { type: 'comments', data: c };
126 const posts = this.state.posts.map((p: Post) => {
127 return { type: 'posts', data: p };
130 const combined: Array<{ type: string; data: Comment | Post }> = [
136 if (SortType[this.props.sort] === SortType.New) {
137 combined.sort((a, b) => b.data.published.localeCompare(a.data.published));
139 combined.sort((a, b) => b.data.score - a.data.score);
146 {i.type === 'posts' ? (
148 post={i.data as Post}
149 admins={this.state.admins}
151 enableDownvotes={this.props.enableDownvotes}
152 enableNsfw={this.props.enableNsfw}
156 nodes={[{ comment: i.data as Comment }]}
157 admins={this.state.admins}
160 enableDownvotes={this.props.enableDownvotes}
173 nodes={commentsToFlatNodes(this.state.comments)}
174 admins={this.state.admins}
177 enableDownvotes={this.props.enableDownvotes}
186 {this.state.posts.map(post => (
189 admins={this.state.admins}
191 enableDownvotes={this.props.enableDownvotes}
192 enableNsfw={this.props.enableNsfw}
199 parseMessage(msg: WebSocketJsonResponse) {
200 const res = wsJsonToRes(msg);
203 toast(i18n.t(msg.error), 'danger');
204 if (msg.error == 'couldnt_find_that_username_or_email') {
205 this.context.router.history.push('/');
208 } else if (msg.reconnect) {
209 this.fetchUserData();
210 } else if (res.op == UserOperation.GetUserDetails) {
211 const data = res.data as UserDetailsResponse;
213 comments: data.comments,
214 follows: data.follows,
215 moderates: data.moderates,
219 } else if (res.op == UserOperation.CreateCommentLike) {
220 const data = res.data as CommentResponse;
221 createCommentLikeRes(data, this.state.comments);
223 comments: this.state.comments,
225 } else if (res.op == UserOperation.EditComment) {
226 const data = res.data as CommentResponse;
227 editCommentRes(data, this.state.comments);
229 comments: this.state.comments,
231 } else if (res.op == UserOperation.CreateComment) {
232 const data = res.data as CommentResponse;
234 UserService.Instance.user &&
235 data.comment.creator_id == UserService.Instance.user.id
237 toast(i18n.t('reply_sent'));
239 } else if (res.op == UserOperation.SaveComment) {
240 const data = res.data as CommentResponse;
241 saveCommentRes(data, this.state.comments);
243 comments: this.state.comments,
245 } else if (res.op == UserOperation.CreatePostLike) {
246 const data = res.data as PostResponse;
247 createPostLikeFindRes(data, this.state.posts);
249 posts: this.state.posts,
251 } else if (res.op == UserOperation.BanUser) {
252 const data = res.data as BanUserResponse;
254 .filter(c => c.creator_id == data.user.id)
255 .forEach(c => (c.banned = data.banned));
257 .filter(c => c.creator_id == data.user.id)
258 .forEach(c => (c.banned = data.banned));
260 posts: this.state.posts,
261 comments: this.state.comments,
263 } else if (res.op == UserOperation.AddAdmin) {
264 const data = res.data as AddAdminResponse;