1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Community, CommunityUser, FollowCommunityForm, CommunityForm as CommunityFormI, UserView } from '../interfaces';
4 import { WebSocketService, UserService } from '../services';
5 import { mdToHtml, getUnixTime } from '../utils';
6 import { CommunityForm } from './community-form';
7 import { i18n } from '../i18next';
8 import { T } from 'inferno-i18next';
10 interface SidebarProps {
12 moderators: Array<CommunityUser>;
13 admins: Array<UserView>;
16 interface SidebarState {
18 showRemoveDialog: boolean;
20 removeExpires: string;
23 export class Sidebar extends Component<SidebarProps, SidebarState> {
25 private emptyState: SidebarState = {
27 showRemoveDialog: false,
32 constructor(props: any, context: any) {
33 super(props, context);
34 this.state = this.emptyState;
35 this.handleEditCommunity = this.handleEditCommunity.bind(this);
36 this.handleEditCancel = this.handleEditCancel.bind(this);
45 community={this.props.community}
46 onEdit={this.handleEditCommunity}
47 onCancel={this.handleEditCancel} />
54 let community = this.props.community;
57 <div class="card border-secondary mb-3">
58 <div class="card-body">
60 <span>{community.title}</span>
62 <small className="ml-2 text-muted font-italic"><T i18nKey="removed">#</T></small>
65 <small className="ml-2 text-muted font-italic"><T i18nKey="deleted">#</T></small>
68 <Link className="text-muted" to={`/c/${community.name}`}>/c/{community.name}</Link>
69 <ul class="list-inline mb-1 text-muted small font-weight-bold">
72 <li className="list-inline-item">
73 <span class="pointer" onClick={linkEvent(this, this.handleEditClick)}><T i18nKey="edit">#</T></span>
76 <li className="list-inline-item">
77 <span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>
78 {!community.deleted ? i18n.t('delete') : i18n.t('restore')}
85 <li className="list-inline-item">
86 {!this.props.community.removed ?
87 <span class="pointer" onClick={linkEvent(this, this.handleModRemoveShow)}><T i18nKey="remove">#</T></span> :
88 <span class="pointer" onClick={linkEvent(this, this.handleModRemoveSubmit)}><T i18nKey="restore">#</T></span>
94 {this.state.showRemoveDialog &&
95 <form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
96 <div class="form-group row">
97 <label class="col-form-label"><T i18nKey="reason">#</T></label>
98 <input type="text" class="form-control mr-2" placeholder={i18n.t('optional')} value={this.state.removeReason} onInput={linkEvent(this, this.handleModRemoveReasonChange)} />
100 {/* TODO hold off on expires for now */}
101 {/* <div class="form-group row"> */}
102 {/* <label class="col-form-label">Expires</label> */}
103 {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */}
105 <div class="form-group row">
106 <button type="submit" class="btn btn-secondary"><T i18nKey="remove_community">#</T></button>
110 <ul class="my-1 list-inline">
111 <li className="list-inline-item"><Link className="badge badge-secondary" to="/communities">{community.category_name}</Link></li>
112 <li className="list-inline-item badge badge-secondary"><T i18nKey="number_of_subscribers" interpolation={{count: community.number_of_subscribers}}>#</T></li>
113 <li className="list-inline-item badge badge-secondary"><T i18nKey="number_of_posts" interpolation={{count: community.number_of_posts}}>#</T></li>
114 <li className="list-inline-item badge badge-secondary"><T i18nKey="number_of_comments" interpolation={{count: community.number_of_comments}}>#</T></li>
115 <li className="list-inline-item"><Link className="badge badge-secondary" to={`/modlog/community/${this.props.community.id}`}><T i18nKey="modlog">#</T></Link></li>
117 <ul class="list-inline small">
118 <li class="list-inline-item">{i18n.t('mods')}: </li>
119 {this.props.moderators.map(mod =>
120 <li class="list-inline-item"><Link class="text-info" to={`/u/${mod.user_name}`}>{mod.user_name}</Link></li>
123 <Link class={`btn btn-sm btn-secondary btn-block mb-3 ${(community.deleted || community.removed) && 'no-click'}`}
124 to={`/create_post?community=${community.name}`}><T i18nKey="create_a_post">#</T></Link>
126 {community.subscribed
127 ? <button class="btn btn-sm btn-secondary btn-block" onClick={linkEvent(community.id, this.handleUnsubscribe)}><T i18nKey="unsubscribe">#</T></button>
128 : <button class="btn btn-sm btn-secondary btn-block" onClick={linkEvent(community.id, this.handleSubscribe)}><T i18nKey="subscribe">#</T></button>
133 {community.description &&
134 <div class="card border-secondary">
135 <div class="card-body">
136 <div className="md-div" dangerouslySetInnerHTML={mdToHtml(community.description)} />
144 handleEditClick(i: Sidebar) {
145 i.state.showEdit = true;
149 handleEditCommunity() {
150 this.state.showEdit = false;
151 this.setState(this.state);
155 this.state.showEdit = false;
156 this.setState(this.state);
159 handleDeleteClick(i: Sidebar) {
160 event.preventDefault();
161 let deleteForm: CommunityFormI = {
162 name: i.props.community.name,
163 title: i.props.community.title,
164 category_id: i.props.community.category_id,
165 edit_id: i.props.community.id,
166 deleted: !i.props.community.deleted,
167 nsfw: i.props.community.nsfw,
170 WebSocketService.Instance.editCommunity(deleteForm);
173 handleUnsubscribe(communityId: number) {
174 let form: FollowCommunityForm = {
175 community_id: communityId,
178 WebSocketService.Instance.followCommunity(form);
181 handleSubscribe(communityId: number) {
182 let form: FollowCommunityForm = {
183 community_id: communityId,
186 WebSocketService.Instance.followCommunity(form);
189 private get amCreator(): boolean {
190 return this.props.community.creator_id == UserService.Instance.user.id;
193 get canMod(): boolean {
194 return UserService.Instance.user && this.props.moderators.map(m => m.user_id).includes(UserService.Instance.user.id);
197 get canAdmin(): boolean {
198 return UserService.Instance.user && this.props.admins.map(a => a.id).includes(UserService.Instance.user.id);
201 handleModRemoveShow(i: Sidebar) {
202 i.state.showRemoveDialog = true;
206 handleModRemoveReasonChange(i: Sidebar, event: any) {
207 i.state.removeReason = event.target.value;
211 handleModRemoveExpiresChange(i: Sidebar, event: any) {
212 console.log(event.target.value);
213 i.state.removeExpires = event.target.value;
217 handleModRemoveSubmit(i: Sidebar) {
218 event.preventDefault();
219 let deleteForm: CommunityFormI = {
220 name: i.props.community.name,
221 title: i.props.community.title,
222 category_id: i.props.community.category_id,
223 edit_id: i.props.community.id,
224 removed: !i.props.community.removed,
225 reason: i.state.removeReason,
226 expires: getUnixTime(i.state.removeExpires),
227 nsfw: i.props.community.nsfw,
230 WebSocketService.Instance.editCommunity(deleteForm);
232 i.state.showRemoveDialog = false;