]> Untitled Git - lemmy-ui.git/blob - src/shared/components/create-post.tsx
Merge remote-tracking branch 'origin/drone-ci' into drone-ci-dess
[lemmy-ui.git] / src / shared / components / create-post.tsx
1 import { Component } from 'inferno';
2 import { Subscription } from 'rxjs';
3 import { PostForm } from './post-form';
4 import { HtmlTags } from './html-tags';
5 import {
6   authField,
7   isBrowser,
8   setIsoData,
9   setOptionalAuth,
10   toast,
11   wsClient,
12   wsJsonToRes,
13   wsSubscribe,
14   wsUserOp,
15 } from '../utils';
16 import { UserService, WebSocketService } from '../services';
17 import {
18   UserOperation,
19   ListCommunitiesResponse,
20   CommunityView,
21   SiteView,
22   ListCommunities,
23   SortType,
24   PostView,
25 } from 'lemmy-js-client';
26 import { i18n } from '../i18next';
27 import { InitialFetchRequest, PostFormParams } from 'shared/interfaces';
28
29 interface CreatePostState {
30   site_view: SiteView;
31   communities: CommunityView[];
32   loading: boolean;
33 }
34
35 export class CreatePost extends Component<any, CreatePostState> {
36   private isoData = setIsoData(this.context);
37   private subscription: Subscription;
38   private emptyState: CreatePostState = {
39     site_view: this.isoData.site_res.site_view,
40     communities: [],
41     loading: true,
42   };
43
44   constructor(props: any, context: any) {
45     super(props, context);
46     this.handlePostCreate = this.handlePostCreate.bind(this);
47     this.state = this.emptyState;
48
49     if (!UserService.Instance.user && isBrowser()) {
50       toast(i18n.t('not_logged_in'), 'danger');
51       this.context.router.history.push(`/login`);
52     }
53
54     this.parseMessage = this.parseMessage.bind(this);
55     this.subscription = wsSubscribe(this.parseMessage);
56
57     // Only fetch the data if coming from another route
58     if (this.isoData.path == this.context.router.route.match.url) {
59       this.state.communities = this.isoData.routeData[0].communities;
60       this.state.loading = false;
61     } else {
62       this.refetch();
63     }
64   }
65
66   refetch() {
67     let listCommunitiesForm: ListCommunities = {
68       sort: SortType.TopAll,
69       limit: 9999,
70       auth: authField(false),
71     };
72     WebSocketService.Instance.send(
73       wsClient.listCommunities(listCommunitiesForm)
74     );
75   }
76
77   componentWillUnmount() {
78     if (isBrowser()) {
79       this.subscription.unsubscribe();
80     }
81   }
82
83   get documentTitle(): string {
84     return `${i18n.t('create_post')} - ${this.state.site_view.site.name}`;
85   }
86
87   render() {
88     return (
89       <div class="container">
90         <HtmlTags
91           title={this.documentTitle}
92           path={this.context.router.route.match.url}
93         />
94         {this.state.loading ? (
95           <h5>
96             <svg class="icon icon-spinner spin">
97               <use xlinkHref="#icon-spinner"></use>
98             </svg>
99           </h5>
100         ) : (
101           <div class="row">
102             <div class="col-12 col-lg-6 offset-lg-3 mb-4">
103               <h5>{i18n.t('create_post')}</h5>
104               <PostForm
105                 communities={this.state.communities}
106                 onCreate={this.handlePostCreate}
107                 params={this.params}
108                 enableDownvotes={this.state.site_view.site.enable_downvotes}
109                 enableNsfw={this.state.site_view.site.enable_nsfw}
110               />
111             </div>
112           </div>
113         )}
114       </div>
115     );
116   }
117
118   get params(): PostFormParams {
119     let urlParams = new URLSearchParams(this.props.location.search);
120     let params: PostFormParams = {
121       name: urlParams.get('title'),
122       community_name: urlParams.get('community_name') || this.prevCommunityName,
123       community_id: urlParams.get('community_id')
124         ? Number(urlParams.get('community_id')) || this.prevCommunityId
125         : null,
126       body: urlParams.get('body'),
127       url: urlParams.get('url'),
128     };
129
130     return params;
131   }
132
133   get prevCommunityName(): string {
134     if (this.props.match.params.name) {
135       return this.props.match.params.name;
136     } else if (this.props.location.state) {
137       let lastLocation = this.props.location.state.prevPath;
138       if (lastLocation.includes('/c/')) {
139         return lastLocation.split('/c/')[1];
140       }
141     }
142     return null;
143   }
144
145   get prevCommunityId(): number {
146     if (this.props.match.params.id) {
147       return this.props.match.params.id;
148     } else if (this.props.location.state) {
149       let lastLocation = this.props.location.state.prevPath;
150       if (lastLocation.includes('/community/')) {
151         return Number(lastLocation.split('/community/')[1]);
152       }
153     }
154     return null;
155   }
156
157   handlePostCreate(post_view: PostView) {
158     this.props.history.push(`/post/${post_view.post.id}`);
159   }
160
161   static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
162     let listCommunitiesForm: ListCommunities = {
163       sort: SortType.TopAll,
164       limit: 9999,
165     };
166     setOptionalAuth(listCommunitiesForm, req.auth);
167     return [req.client.listCommunities(listCommunitiesForm)];
168   }
169
170   parseMessage(msg: any) {
171     let op = wsUserOp(msg);
172     if (msg.error) {
173       toast(i18n.t(msg.error), 'danger');
174       return;
175     } else if (op == UserOperation.ListCommunities) {
176       let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
177       this.state.communities = data.communities;
178       this.state.loading = false;
179       this.setState(this.state);
180     }
181   }
182 }