]> Untitled Git - lemmy-ui.git/blob - src/shared/components/create-post.tsx
First pass at v2_api
[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   setIsoData,
8   toast,
9   wsJsonToRes,
10   wsSubscribe,
11   wsUserOp,
12 } from '../utils';
13 import { UserService, WebSocketService } from '../services';
14 import {
15   UserOperation,
16   ListCommunitiesResponse,
17   CommunityView,
18   SiteView,
19   ListCommunities,
20   SortType,
21   PostView,
22 } from 'lemmy-js-client';
23 import { i18n } from '../i18next';
24 import { InitialFetchRequest, PostFormParams } from 'shared/interfaces';
25
26 interface CreatePostState {
27   site_view: SiteView;
28   communities: CommunityView[];
29   loading: boolean;
30 }
31
32 export class CreatePost extends Component<any, CreatePostState> {
33   private isoData = setIsoData(this.context);
34   private subscription: Subscription;
35   private emptyState: CreatePostState = {
36     site_view: this.isoData.site_res.site_view,
37     communities: [],
38     loading: true,
39   };
40
41   constructor(props: any, context: any) {
42     super(props, context);
43     this.handlePostCreate = this.handlePostCreate.bind(this);
44     this.state = this.emptyState;
45
46     if (!UserService.Instance.user && isBrowser()) {
47       toast(i18n.t('not_logged_in'), 'danger');
48       this.context.router.history.push(`/login`);
49     }
50
51     this.parseMessage = this.parseMessage.bind(this);
52     this.subscription = wsSubscribe(this.parseMessage);
53
54     // Only fetch the data if coming from another route
55     if (this.isoData.path == this.context.router.route.match.url) {
56       this.state.communities = this.isoData.routeData[0].communities;
57       this.state.loading = false;
58     } else {
59       this.refetch();
60     }
61   }
62
63   refetch() {
64     let listCommunitiesForm: ListCommunities = {
65       sort: SortType.TopAll,
66       limit: 9999,
67       auth: UserService.Instance.authField(false),
68     };
69     WebSocketService.Instance.client.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_view.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_view.site.enable_downvotes}
104                 enableNsfw={this.state.site_view.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(post_view: PostView) {
153     this.props.history.push(`/post/${post_view.post.id}`);
154   }
155
156   static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
157     let listCommunitiesForm: ListCommunities = {
158       sort: SortType.TopAll,
159       limit: 9999,
160       auth: req.auth,
161     };
162     return [req.client.listCommunities(listCommunitiesForm)];
163   }
164
165   parseMessage(msg: any) {
166     let op = wsUserOp(msg);
167     if (msg.error) {
168       toast(i18n.t(msg.error), 'danger');
169       return;
170     } else if (op == UserOperation.ListCommunities) {
171       let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
172       this.state.communities = data.communities;
173       this.state.loading = false;
174       this.setState(this.state);
175     }
176   }
177 }