import { enableDownvotes, enableNsfw, myAuth, setIsoData } from "@utils/app"; import { getIdFromString, getQueryParams } from "@utils/helpers"; import type { QueryParams } from "@utils/types"; import { Choice, RouteDataResponse } from "@utils/types"; import { Component } from "inferno"; import { RouteComponentProps } from "inferno-router/dist/Route"; import { CreatePost as CreatePostI, GetCommunity, GetCommunityResponse, GetSiteResponse, ListCommunitiesResponse, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { InitialFetchRequest, PostFormParams } from "../../interfaces"; import { FirstLoadService } from "../../services/FirstLoadService"; import { HttpService, RequestState, WrappedLemmyHttp, } from "../../services/HttpService"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; import { PostForm } from "./post-form"; export interface CreatePostProps { communityId?: number; } type CreatePostData = RouteDataResponse<{ communityResponse: GetCommunityResponse; initialCommunitiesRes: ListCommunitiesResponse; }>; function getCreatePostQueryParams() { return getQueryParams({ communityId: getIdFromString, }); } function fetchCommunitiesForOptions(client: WrappedLemmyHttp) { return client.listCommunities({ limit: 30, sort: "TopMonth", type_: "All" }); } interface CreatePostState { siteRes: GetSiteResponse; loading: boolean; selectedCommunityChoice?: Choice; initialCommunitiesRes: RequestState; isIsomorphic: boolean; } export class CreatePost extends Component< RouteComponentProps>, CreatePostState > { private isoData = setIsoData(this.context); state: CreatePostState = { siteRes: this.isoData.site_res, loading: true, initialCommunitiesRes: { state: "empty" }, isIsomorphic: false, }; constructor(props: RouteComponentProps>, context: any) { super(props, context); this.handlePostCreate = this.handlePostCreate.bind(this); this.handleSelectedCommunityChange = this.handleSelectedCommunityChange.bind(this); // Only fetch the data if coming from another route if (FirstLoadService.isFirstLoad) { const { communityResponse: communityRes, initialCommunitiesRes } = this.isoData.routeData; this.state = { ...this.state, loading: false, initialCommunitiesRes, isIsomorphic: true, }; if (communityRes?.state === "success") { const communityChoice: Choice = { label: communityRes.data.community_view.community.title, value: communityRes.data.community_view.community.id.toString(), }; this.state = { ...this.state, selectedCommunityChoice: communityChoice, }; } } } async fetchCommunity() { const { communityId } = getCreatePostQueryParams(); const auth = myAuth(); if (communityId) { const res = await HttpService.client.getCommunity({ id: communityId, auth, }); if (res.state === "success") { this.setState({ selectedCommunityChoice: { label: res.data.community_view.community.title, value: res.data.community_view.community.id.toString(), }, loading: false, }); } } } async componentDidMount() { // TODO test this if (!this.state.isIsomorphic) { const { communityId } = getCreatePostQueryParams(); const initialCommunitiesRes = await fetchCommunitiesForOptions( HttpService.client ); this.setState({ initialCommunitiesRes, }); if ( communityId?.toString() !== this.state.selectedCommunityChoice?.value ) { await this.fetchCommunity(); } else if (!communityId) { this.setState({ selectedCommunityChoice: undefined, loading: false, }); } } } get documentTitle(): string { return `${i18n.t("create_post")} - ${ this.state.siteRes.site_view.site.name }`; } render() { const { selectedCommunityChoice } = this.state; const locationState = this.props.history.location.state as | PostFormParams | undefined; return (
{this.state.loading ? (
) : (

{i18n.t("create_post")}

)}
); } async updateUrl({ communityId }: Partial) { const { communityId: urlCommunityId } = getCreatePostQueryParams(); const locationState = this.props.history.location.state as | PostFormParams | undefined; const url = new URL(location.href); const newId = (communityId ?? urlCommunityId)?.toString(); if (newId !== undefined) { url.searchParams.set("communityId", newId); } else { url.searchParams.delete("communityId"); } history.replaceState(locationState, "", url); await this.fetchCommunity(); } handleSelectedCommunityChange(choice: Choice) { this.updateUrl({ communityId: getIdFromString(choice?.value), }); } async handlePostCreate(form: CreatePostI) { const res = await HttpService.client.createPost(form); if (res.state === "success") { const postId = res.data.post_view.post.id; this.props.history.replace(`/post/${postId}`); } else { this.setState({ loading: false, }); } } static async fetchInitialData({ client, query: { communityId }, auth, }: InitialFetchRequest< QueryParams >): Promise { const data: CreatePostData = { initialCommunitiesRes: await fetchCommunitiesForOptions(client), communityResponse: { state: "empty" }, }; if (communityId) { const form: GetCommunity = { auth, id: getIdFromString(communityId), }; data.communityResponse = await client.getCommunity(form); } return data; } }