import { Component } from "inferno"; import { RouteComponentProps } from "inferno-router/dist/Route"; import { GetCommunity, GetCommunityResponse, GetSiteResponse, PostView, UserOperation, wsJsonToRes, wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { InitialFetchRequest, PostFormParams } from "shared/interfaces"; import { i18n } from "../../i18next"; import { WebSocketService } from "../../services"; import { Choice, QueryParams, enableDownvotes, enableNsfw, getIdFromString, getQueryParams, getQueryString, isBrowser, myAuth, setIsoData, toast, wsClient, wsSubscribe, } from "../../utils"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; import { PostForm } from "./post-form"; export interface CreatePostProps { communityId?: number; } function getCreatePostQueryParams() { return getQueryParams({ communityId: getIdFromString, }); } interface CreatePostState { siteRes: GetSiteResponse; loading: boolean; selectedCommunityChoice?: Choice; } export class CreatePost extends Component< RouteComponentProps>, CreatePostState > { private isoData = setIsoData(this.context); private subscription?: Subscription; state: CreatePostState = { siteRes: this.isoData.site_res, loading: true, }; constructor(props: RouteComponentProps>, context: any) { super(props, context); this.handlePostCreate = this.handlePostCreate.bind(this); this.handleSelectedCommunityChange = this.handleSelectedCommunityChange.bind(this); this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); // Only fetch the data if coming from another route if (this.isoData.path === this.context.router.route.match.url) { const communityRes = this.isoData.routeData[0] as | GetCommunityResponse | undefined; if (communityRes) { const communityChoice: Choice = { label: communityRes.community_view.community.name, value: communityRes.community_view.community.id.toString(), }; this.state = { ...this.state, selectedCommunityChoice: communityChoice, }; } this.state = { ...this.state, loading: false, }; } else { this.fetchCommunity(); } } fetchCommunity() { const { communityId } = getCreatePostQueryParams(); const auth = myAuth(false); if (communityId) { const form: GetCommunity = { id: communityId, auth, }; WebSocketService.Instance.send(wsClient.getCommunity(form)); } } componentDidMount(): void { const { communityId } = getCreatePostQueryParams(); if (communityId?.toString() !== this.state.selectedCommunityChoice?.value) { this.fetchCommunity(); } else if (!communityId) { this.setState({ selectedCommunityChoice: undefined, loading: false, }); } } componentWillUnmount() { if (isBrowser()) { this.subscription?.unsubscribe(); } } 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")}
)}
); } updateUrl({ communityId }: Partial) { const { communityId: urlCommunityId } = getCreatePostQueryParams(); const queryParams: QueryParams = { communityId: (communityId ?? urlCommunityId)?.toString(), }; const locationState = this.props.history.location.state as | PostFormParams | undefined; this.props.history.replace( `/create_post${getQueryString(queryParams)}`, locationState ); this.fetchCommunity(); } handleSelectedCommunityChange(choice: Choice) { this.updateUrl({ communityId: getIdFromString(choice?.value), }); } handlePostCreate(post_view: PostView) { this.props.history.replace(`/post/${post_view.post.id}`); } static fetchInitialData({ client, query: { communityId }, auth, }: InitialFetchRequest>): Promise[] { const promises: Promise[] = []; if (communityId) { const form: GetCommunity = { auth, id: getIdFromString(communityId), }; promises.push(client.getCommunity(form)); } else { promises.push(Promise.resolve()); } return promises; } parseMessage(msg: any) { const op = wsUserOp(msg); console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); return; } if (op === UserOperation.GetCommunity) { const { community_view: { community: { name, id }, }, } = wsJsonToRes(msg); this.setState({ selectedCommunityChoice: { label: name, value: id.toString() }, loading: false, }); } } }