import { Component } from "inferno";
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 { WebSocketService } from "../../services";
+import { InitialFetchRequest, PostFormParams } from "../../interfaces";
+import { FirstLoadService } from "../../services/FirstLoadService";
+import {
+ HttpService,
+ RequestState,
+ WrappedLemmyHttp,
+} from "../../services/HttpService";
import {
Choice,
- QueryParams,
enableDownvotes,
enableNsfw,
getIdFromString,
- getQueryParams,
- getQueryString,
- isBrowser,
myAuth,
setIsoData,
- toast,
- wsClient,
- wsSubscribe,
} from "../../utils";
+import { getQueryParams } from "../../utils/helpers/get-query-params";
+import type { QueryParams } from "../../utils/types/query-params";
import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon";
import { PostForm } from "./post-form";
});
}
+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<
CreatePostState
> {
private isoData = setIsoData(this.context);
- private subscription?: Subscription;
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 [communityRes, listCommunitiesRes] = this.isoData.routeData;
- if (communityRes) {
+ 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 = {
this.state = {
...this.state,
loading: false,
+ initialCommunitiesRes: listCommunitiesRes,
+ isIsomorphic: true,
};
- } 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,
+ });
+ }
}
}
</h5>
) : (
<div className="row">
- <div className="col-12 col-lg-6 offset-lg-3 mb-4">
+ <div
+ id="createPostForm"
+ className="col-12 col-lg-6 offset-lg-3 mb-4"
+ >
<h5>{i18n.t("create_post")}</h5>
<PostForm
onCreate={this.handlePostCreate}
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);
- this.fetchCommunity();
+ 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) {
});
}
- 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({
client,
query: { communityId },
auth,
- }: InitialFetchRequest<QueryParams<CreatePostProps>>): Promise<any>[] {
- const promises: Promise<any>[] = [];
+ }: InitialFetchRequest<QueryParams<CreatePostProps>>): Promise<
+ RequestState<any>
+ >[] {
+ const promises: Promise<RequestState<any>>[] = [];
if (communityId) {
const form: GetCommunity = {
promises.push(client.getCommunity(form));
} else {
- promises.push(Promise.resolve());
+ promises.push(Promise.resolve({ state: "empty" }));
}
- return promises;
- }
-
- parseMessage(msg: any) {
- const op = wsUserOp(msg);
- console.log(msg);
- if (msg.error) {
- toast(i18n.t(msg.error), "danger");
- return;
- }
+ promises.push(fetchCommunitiesForOptions(client));
- if (op === UserOperation.GetCommunity) {
- const {
- community_view: {
- community: { name, id },
- },
- } = wsJsonToRes<GetCommunityResponse>(msg);
-
- this.setState({
- selectedCommunityChoice: { label: name, value: id.toString() },
- loading: false,
- });
- }
+ return promises;
}
}