1 import { Component } from "inferno";
2 import { RouteComponentProps } from "inferno-router/dist/Route";
4 CreatePost as CreatePostI,
8 ListCommunitiesResponse,
9 } from "lemmy-js-client";
10 import { i18n } from "../../i18next";
11 import { InitialFetchRequest, PostFormParams } from "../../interfaces";
12 import { FirstLoadService } from "../../services/FirstLoadService";
17 } from "../../services/HttpService";
29 import { HtmlTags } from "../common/html-tags";
30 import { Spinner } from "../common/icon";
31 import { PostForm } from "./post-form";
33 export interface CreatePostProps {
37 type CreatePostData = RouteDataResponse<{
38 communityResponse?: GetCommunityResponse;
39 initialCommunitiesRes: ListCommunitiesResponse;
42 function getCreatePostQueryParams() {
43 return getQueryParams<CreatePostProps>({
44 communityId: getIdFromString,
48 function fetchCommunitiesForOptions(client: WrappedLemmyHttp) {
49 return client.listCommunities({ limit: 30, sort: "TopMonth", type_: "All" });
52 interface CreatePostState {
53 siteRes: GetSiteResponse;
55 selectedCommunityChoice?: Choice;
56 initialCommunitiesRes: RequestState<ListCommunitiesResponse>;
57 isIsomorphic: boolean;
60 export class CreatePost extends Component<
61 RouteComponentProps<Record<string, never>>,
64 private isoData = setIsoData<CreatePostData>(this.context);
65 state: CreatePostState = {
66 siteRes: this.isoData.site_res,
68 initialCommunitiesRes: { state: "empty" },
72 constructor(props: RouteComponentProps<Record<string, never>>, context: any) {
73 super(props, context);
75 this.handlePostCreate = this.handlePostCreate.bind(this);
76 this.handleSelectedCommunityChange =
77 this.handleSelectedCommunityChange.bind(this);
79 // Only fetch the data if coming from another route
80 if (FirstLoadService.isFirstLoad) {
81 const { communityResponse: communityRes, initialCommunitiesRes } =
82 this.isoData.routeData;
84 if (communityRes?.state === "success") {
85 const communityChoice: Choice = {
86 label: communityRes.data.community_view.community.title,
87 value: communityRes.data.community_view.community.id.toString(),
92 selectedCommunityChoice: communityChoice,
99 initialCommunitiesRes,
105 async fetchCommunity() {
106 const { communityId } = getCreatePostQueryParams();
107 const auth = myAuth();
110 const res = await HttpService.client.getCommunity({
114 if (res.state === "success") {
116 selectedCommunityChoice: {
117 label: res.data.community_view.community.name,
118 value: res.data.community_view.community.id.toString(),
126 async componentDidMount() {
128 if (!this.state.isIsomorphic) {
129 const { communityId } = getCreatePostQueryParams();
131 const initialCommunitiesRes = await fetchCommunitiesForOptions(
136 initialCommunitiesRes,
140 communityId?.toString() !== this.state.selectedCommunityChoice?.value
142 await this.fetchCommunity();
143 } else if (!communityId) {
145 selectedCommunityChoice: undefined,
152 get documentTitle(): string {
153 return `${i18n.t("create_post")} - ${
154 this.state.siteRes.site_view.site.name
159 const { selectedCommunityChoice } = this.state;
161 const locationState = this.props.history.location.state as
166 <div className="container-lg">
168 title={this.documentTitle}
169 path={this.context.router.route.match.url}
171 {this.state.loading ? (
176 <div className="row">
177 <div className="col-12 col-lg-6 offset-lg-3 mb-4">
178 <h5>{i18n.t("create_post")}</h5>
180 onCreate={this.handlePostCreate}
181 params={locationState}
182 enableDownvotes={enableDownvotes(this.state.siteRes)}
183 enableNsfw={enableNsfw(this.state.siteRes)}
184 allLanguages={this.state.siteRes.all_languages}
185 siteLanguages={this.state.siteRes.discussion_languages}
186 selectedCommunityChoice={selectedCommunityChoice}
187 onSelectCommunity={this.handleSelectedCommunityChange}
189 this.state.initialCommunitiesRes.state === "success"
190 ? this.state.initialCommunitiesRes.data.communities
201 async updateUrl({ communityId }: Partial<CreatePostProps>) {
202 const { communityId: urlCommunityId } = getCreatePostQueryParams();
204 const locationState = this.props.history.location.state as
208 const url = new URL(location.href);
210 const newId = (communityId ?? urlCommunityId)?.toString();
212 if (newId !== undefined) {
213 url.searchParams.set("communityId", newId);
215 url.searchParams.delete("communityId");
218 history.replaceState(locationState, "", url);
220 await this.fetchCommunity();
223 handleSelectedCommunityChange(choice: Choice) {
225 communityId: getIdFromString(choice?.value),
229 async handlePostCreate(form: CreatePostI) {
230 const res = await HttpService.client.createPost(form);
232 if (res.state === "success") {
233 const postId = res.data.post_view.post.id;
234 this.props.history.replace(`/post/${postId}`);
238 static async fetchInitialData({
240 query: { communityId },
242 }: InitialFetchRequest<
243 QueryParams<CreatePostProps>
244 >): Promise<CreatePostData> {
245 const data: CreatePostData = {
246 initialCommunitiesRes: await fetchCommunitiesForOptions(client),
250 const form: GetCommunity = {
252 id: getIdFromString(communityId),
255 data.communityResponse = await client.getCommunity(form);