1 import { Component } from "inferno";
2 import { RouteComponentProps } from "inferno-router/dist/Route";
4 CreatePost as CreatePostI,
7 ListCommunitiesResponse,
8 } from "lemmy-js-client";
9 import { i18n } from "../../i18next";
10 import { InitialFetchRequest, PostFormParams } from "../../interfaces";
11 import { FirstLoadService } from "../../services/FirstLoadService";
16 } from "../../services/HttpService";
25 import { getQueryParams } from "../../utils/helpers/get-query-params";
26 import type { QueryParams } from "../../utils/types/query-params";
27 import { HtmlTags } from "../common/html-tags";
28 import { Spinner } from "../common/icon";
29 import { PostForm } from "./post-form";
31 export interface CreatePostProps {
35 function getCreatePostQueryParams() {
36 return getQueryParams<CreatePostProps>({
37 communityId: getIdFromString,
41 function fetchCommunitiesForOptions(client: WrappedLemmyHttp) {
42 return client.listCommunities({ limit: 30, sort: "TopMonth", type_: "All" });
45 interface CreatePostState {
46 siteRes: GetSiteResponse;
48 selectedCommunityChoice?: Choice;
49 initialCommunitiesRes: RequestState<ListCommunitiesResponse>;
50 isIsomorphic: boolean;
53 export class CreatePost extends Component<
54 RouteComponentProps<Record<string, never>>,
57 private isoData = setIsoData(this.context);
58 state: CreatePostState = {
59 siteRes: this.isoData.site_res,
61 initialCommunitiesRes: { state: "empty" },
65 constructor(props: RouteComponentProps<Record<string, never>>, context: any) {
66 super(props, context);
68 this.handlePostCreate = this.handlePostCreate.bind(this);
69 this.handleSelectedCommunityChange =
70 this.handleSelectedCommunityChange.bind(this);
72 // Only fetch the data if coming from another route
73 if (FirstLoadService.isFirstLoad) {
74 const [communityRes, listCommunitiesRes] = this.isoData.routeData;
76 if (communityRes?.state === "success") {
77 const communityChoice: Choice = {
78 label: communityRes.data.community_view.community.title,
79 value: communityRes.data.community_view.community.id.toString(),
84 selectedCommunityChoice: communityChoice,
91 initialCommunitiesRes: listCommunitiesRes,
97 async fetchCommunity() {
98 const { communityId } = getCreatePostQueryParams();
99 const auth = myAuth();
102 const res = await HttpService.client.getCommunity({
106 if (res.state === "success") {
108 selectedCommunityChoice: {
109 label: res.data.community_view.community.name,
110 value: res.data.community_view.community.id.toString(),
118 async componentDidMount() {
120 if (!this.state.isIsomorphic) {
121 const { communityId } = getCreatePostQueryParams();
123 const initialCommunitiesRes = await fetchCommunitiesForOptions(
128 initialCommunitiesRes,
132 communityId?.toString() !== this.state.selectedCommunityChoice?.value
134 await this.fetchCommunity();
135 } else if (!communityId) {
137 selectedCommunityChoice: undefined,
144 get documentTitle(): string {
145 return `${i18n.t("create_post")} - ${
146 this.state.siteRes.site_view.site.name
151 const { selectedCommunityChoice } = this.state;
153 const locationState = this.props.history.location.state as
158 <div className="container-lg">
160 title={this.documentTitle}
161 path={this.context.router.route.match.url}
163 {this.state.loading ? (
168 <div className="row">
169 <div className="col-12 col-lg-6 offset-lg-3 mb-4">
170 <h5>{i18n.t("create_post")}</h5>
172 onCreate={this.handlePostCreate}
173 params={locationState}
174 enableDownvotes={enableDownvotes(this.state.siteRes)}
175 enableNsfw={enableNsfw(this.state.siteRes)}
176 allLanguages={this.state.siteRes.all_languages}
177 siteLanguages={this.state.siteRes.discussion_languages}
178 selectedCommunityChoice={selectedCommunityChoice}
179 onSelectCommunity={this.handleSelectedCommunityChange}
181 this.state.initialCommunitiesRes.state === "success"
182 ? this.state.initialCommunitiesRes.data.communities
193 async updateUrl({ communityId }: Partial<CreatePostProps>) {
194 const { communityId: urlCommunityId } = getCreatePostQueryParams();
196 const locationState = this.props.history.location.state as
200 const url = new URL(location.href);
202 const newId = (communityId ?? urlCommunityId)?.toString();
204 if (newId !== undefined) {
205 url.searchParams.set("communityId", newId);
207 url.searchParams.delete("communityId");
210 history.replaceState(locationState, "", url);
212 await this.fetchCommunity();
215 handleSelectedCommunityChange(choice: Choice) {
217 communityId: getIdFromString(choice?.value),
221 async handlePostCreate(form: CreatePostI) {
222 const res = await HttpService.client.createPost(form);
224 if (res.state === "success") {
225 const postId = res.data.post_view.post.id;
226 this.props.history.replace(`/post/${postId}`);
230 static fetchInitialData({
232 query: { communityId },
234 }: InitialFetchRequest<QueryParams<CreatePostProps>>): Promise<
237 const promises: Promise<RequestState<any>>[] = [];
240 const form: GetCommunity = {
242 id: getIdFromString(communityId),
245 promises.push(client.getCommunity(form));
247 promises.push(Promise.resolve({ state: "empty" }));
250 promises.push(fetchCommunitiesForOptions(client));