import { Component } from "inferno";
-import { Redirect } from "inferno-router";
import { RouteComponentProps } from "inferno-router/dist/Route";
import {
+ CreatePost as CreatePostI,
GetCommunity,
GetCommunityResponse,
GetSiteResponse,
- PostView,
- UserOperation,
- wsJsonToRes,
- wsUserOp,
+ ListCommunitiesResponse,
} from "lemmy-js-client";
-import { Subscription } from "rxjs";
-import { InitialFetchRequest, PostFormParams } from "shared/interfaces";
import { i18n } from "../../i18next";
-import { UserService, WebSocketService } from "../../services";
+import { InitialFetchRequest, PostFormParams } from "../../interfaces";
+import { FirstLoadService } from "../../services/FirstLoadService";
+import {
+ HttpService,
+ RequestState,
+ WrappedLemmyHttp,
+} from "../../services/HttpService";
import {
Choice,
+ QueryParams,
+ RouteDataResponse,
enableDownvotes,
enableNsfw,
getIdFromString,
getQueryParams,
- getQueryString,
- isBrowser,
myAuth,
- QueryParams,
setIsoData,
- toast,
- wsClient,
- wsSubscribe,
} from "../../utils";
import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon";
communityId?: number;
}
+type CreatePostData = RouteDataResponse<{
+ communityResponse: GetCommunityResponse;
+ initialCommunitiesRes: ListCommunitiesResponse;
+}>;
+
function getCreatePostQueryParams() {
return getQueryParams<CreatePostProps>({
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<ListCommunitiesResponse>;
+ isIsomorphic: boolean;
}
export class CreatePost extends Component<
RouteComponentProps<Record<string, never>>,
CreatePostState
> {
- private isoData = setIsoData(this.context);
- private subscription?: Subscription;
+ private isoData = setIsoData<CreatePostData>(this.context);
state: CreatePostState = {
siteRes: this.isoData.site_res,
loading: true,
+ initialCommunitiesRes: { state: "empty" },
+ isIsomorphic: false,
};
constructor(props: RouteComponentProps<Record<string, never>>, context: any) {
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 (FirstLoadService.isFirstLoad) {
+ const { communityResponse: communityRes, initialCommunitiesRes } =
+ this.isoData.routeData;
- if (communityRes) {
+ this.state = {
+ ...this.state,
+ loading: false,
+ initialCommunitiesRes,
+ isIsomorphic: true,
+ };
+
+ if (communityRes?.state === "success") {
const communityChoice: Choice = {
- label: communityRes.community_view.community.name,
- value: communityRes.community_view.community.id.toString(),
+ label: communityRes.data.community_view.community.title,
+ value: communityRes.data.community_view.community.id.toString(),
};
this.state = {
selectedCommunityChoice: communityChoice,
};
}
-
- this.state = {
- ...this.state,
- loading: false,
- };
- } else {
- this.fetchCommunity();
}
}
- fetchCommunity() {
+ async fetchCommunity() {
const { communityId } = getCreatePostQueryParams();
- const auth = myAuth(false);
+ const auth = myAuth();
if (communityId) {
- const form: GetCommunity = {
+ const res = await HttpService.client.getCommunity({
id: communityId,
auth,
- };
-
- WebSocketService.Instance.send(wsClient.getCommunity(form));
+ });
+ if (res.state === "success") {
+ this.setState({
+ selectedCommunityChoice: {
+ label: res.data.community_view.community.name,
+ value: res.data.community_view.community.id.toString(),
+ },
+ loading: false,
+ });
+ }
}
}
- componentDidMount(): void {
- const { communityId } = getCreatePostQueryParams();
+ async componentDidMount() {
+ // TODO test this
+ if (!this.state.isIsomorphic) {
+ const { communityId } = getCreatePostQueryParams();
+
+ const initialCommunitiesRes = await fetchCommunitiesForOptions(
+ HttpService.client
+ );
- if (communityId?.toString() !== this.state.selectedCommunityChoice?.value) {
- this.fetchCommunity();
- } else if (!communityId) {
this.setState({
- selectedCommunityChoice: undefined,
- loading: false,
+ initialCommunitiesRes,
});
- }
- }
- componentWillUnmount() {
- if (isBrowser()) {
- this.subscription?.unsubscribe();
+ if (
+ communityId?.toString() !== this.state.selectedCommunityChoice?.value
+ ) {
+ await this.fetchCommunity();
+ } else if (!communityId) {
+ this.setState({
+ selectedCommunityChoice: undefined,
+ loading: false,
+ });
+ }
}
}
return (
<div className="container-lg">
- {!UserService.Instance.myUserInfo && <Redirect to="/login" />}
<HtmlTags
title={this.documentTitle}
path={this.context.router.route.match.url}
siteLanguages={this.state.siteRes.discussion_languages}
selectedCommunityChoice={selectedCommunityChoice}
onSelectCommunity={this.handleSelectedCommunityChange}
+ initialCommunities={
+ this.state.initialCommunitiesRes.state === "success"
+ ? this.state.initialCommunitiesRes.data.communities
+ : []
+ }
/>
</div>
</div>
);
}
- updateUrl({ communityId }: Partial<CreatePostProps>) {
+ async updateUrl({ communityId }: Partial<CreatePostProps>) {
const { communityId: urlCommunityId } = getCreatePostQueryParams();
- const queryParams: QueryParams<CreatePostProps> = {
- communityId: (communityId ?? urlCommunityId)?.toString(),
- };
-
const locationState = this.props.history.location.state as
| PostFormParams
| undefined;
- this.props.history.replace(
- `/create_post${getQueryString(queryParams)}`,
- locationState
- );
+ const url = new URL(location.href);
+
+ const newId = (communityId ?? urlCommunityId)?.toString();
+
+ if (newId !== undefined) {
+ url.searchParams.set("communityId", newId);
+ } else {
+ url.searchParams.delete("communityId");
+ }
- this.fetchCommunity();
+ history.replaceState(locationState, "", url);
+
+ await this.fetchCommunity();
}
handleSelectedCommunityChange(choice: Choice) {
});
}
- handlePostCreate(post_view: PostView) {
- this.props.history.replace(`/post/${post_view.post.id}`);
+ 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 fetchInitialData({
+ static async fetchInitialData({
client,
query: { communityId },
auth,
- }: InitialFetchRequest<QueryParams<CreatePostProps>>): Promise<any>[] {
- const promises: Promise<any>[] = [];
+ }: InitialFetchRequest<
+ QueryParams<CreatePostProps>
+ >): Promise<CreatePostData> {
+ const data: CreatePostData = {
+ initialCommunitiesRes: await fetchCommunitiesForOptions(client),
+ communityResponse: { state: "empty" },
+ };
if (communityId) {
const form: GetCommunity = {
id: getIdFromString(communityId),
};
- promises.push(client.getCommunity(form));
- } else {
- promises.push(Promise.resolve());
+ data.communityResponse = await client.getCommunity(form);
}
- 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<GetCommunityResponse>(msg);
-
- this.setState({
- selectedCommunityChoice: { label: name, value: id.toString() },
- loading: false,
- });
- }
+ return data;
}
}