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