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