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, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm } from '../interfaces';
6 import { WebSocketService } from '../services';
7 import { msgOp } from '../utils';
9 declare const Sortable: any;
11 interface CommunitiesState {
12 communities: Array<Community>;
16 export class Communities extends Component<any, CommunitiesState> {
17 private subscription: Subscription;
18 private emptyState: CommunitiesState = {
23 constructor(props: any, context: any) {
24 super(props, context);
25 this.state = this.emptyState;
26 this.subscription = WebSocketService.Instance.subject
27 .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
29 (msg) => this.parseMessage(msg),
30 (err) => console.error(err),
31 () => console.log('complete')
33 WebSocketService.Instance.listCommunities();
37 componentWillUnmount() {
38 this.subscription.unsubscribe();
42 let table = document.querySelector('#community_table');
43 Sortable.initTable(table);
48 <div class="container">
50 <h4 class=""><svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg></h4> :
53 <div class="table-responsive">
54 <table id="community_table" class="table table-sm table-hover">
55 <thead class="pointer">
60 <th class="text-right">Subscribers</th>
61 <th class="text-right">Posts</th>
62 <th class="text-right">Comments</th>
67 {this.state.communities.map(community =>
69 <td><Link to={`/community/${community.id}`}>{community.name}</Link></td>
70 <td>{community.title}</td>
71 <td>{community.category_name}</td>
72 <td class="text-right">{community.number_of_subscribers}</td>
73 <td class="text-right">{community.number_of_posts}</td>
74 <td class="text-right">{community.number_of_comments}</td>
75 <td class="text-right">
76 {community.subscribed ?
77 <button class="btn btn-sm btn-secondary" onClick={linkEvent(community.id, this.handleUnsubscribe)}>Unsubscribe</button> :
78 <button class="btn btn-sm btn-secondary" onClick={linkEvent(community.id, this.handleSubscribe)}>Subscribe</button>
92 handleUnsubscribe(communityId: number) {
93 let form: FollowCommunityForm = {
94 community_id: communityId,
97 WebSocketService.Instance.followCommunity(form);
101 handleSubscribe(communityId: number) {
102 let form: FollowCommunityForm = {
103 community_id: communityId,
106 WebSocketService.Instance.followCommunity(form);
109 parseMessage(msg: any) {
111 let op: UserOperation = msgOp(msg);
115 } else if (op == UserOperation.ListCommunities) {
116 let res: ListCommunitiesResponse = msg;
117 this.state.communities = res.communities;
118 this.state.communities.sort((a, b) => b.number_of_subscribers - a.number_of_subscribers);
119 this.state.loading = false;
120 this.setState(this.state);
121 } else if (op == UserOperation.FollowCommunity) {
122 let res: CommunityResponse = msg;
123 let found = this.state.communities.find(c => c.id == res.community.id);
124 found.subscribed = res.community.subscribed;
125 found.number_of_subscribers = res.community.number_of_subscribers;
126 this.setState(this.state);