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