]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/post/create-post.tsx
Merge branch 'main' into route-data-refactor
[lemmy-ui.git] / src / shared / components / post / create-post.tsx
index 684dda2fc3b1a194a8bf67c1e9abc7c62be4dea3..bb39cdadbdab3dae9a162c0325997b43f25a34e0 100644 (file)
@@ -1,32 +1,30 @@
 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,
-  WithPromiseKeys,
+  RouteDataResponse,
   enableDownvotes,
   enableNsfw,
   getIdFromString,
   getQueryParams,
-  isBrowser,
   myAuth,
   setIsoData,
-  toast,
-  wsClient,
-  wsSubscribe,
 } from "../../utils";
 import { HtmlTags } from "../common/html-tags";
 import { Spinner } from "../common/icon";
@@ -36,9 +34,10 @@ export interface CreatePostProps {
   communityId?: number;
 }
 
-interface CreatePostData {
+type CreatePostData = RouteDataResponse<{
   communityResponse?: GetCommunityResponse;
-}
+  initialCommunitiesRes: ListCommunitiesResponse;
+}>;
 
 function getCreatePostQueryParams() {
   return getQueryParams<CreatePostProps>({
@@ -46,10 +45,16 @@ function getCreatePostQueryParams() {
   });
 }
 
+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<
@@ -57,10 +62,11 @@ export class CreatePost extends Component<
   CreatePostState
 > {
   private isoData = setIsoData<CreatePostData>(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) {
@@ -70,17 +76,15 @@ export class CreatePost extends Component<
     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 { communityResponse } = this.isoData.routeData;
+    if (FirstLoadService.isFirstLoad) {
+      const { communityResponse: communityRes, initialCommunitiesRes } =
+        this.isoData.routeData;
 
-      if (communityResponse) {
+      if (communityRes?.state === "success") {
         const communityChoice: Choice = {
-          label: communityResponse.community_view.community.title,
-          value: communityResponse.community_view.community.id.toString(),
+          label: communityRes.data.community_view.community.title,
+          value: communityRes.data.community_view.community.id.toString(),
         };
 
         this.state = {
@@ -92,42 +96,56 @@ export class CreatePost extends Component<
       this.state = {
         ...this.state,
         loading: false,
+        initialCommunitiesRes,
+        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,
+        });
+      }
     }
   }
 
@@ -167,6 +185,11 @@ export class CreatePost extends Component<
                 siteLanguages={this.state.siteRes.discussion_languages}
                 selectedCommunityChoice={selectedCommunityChoice}
                 onSelectCommunity={this.handleSelectedCommunityChange}
+                initialCommunities={
+                  this.state.initialCommunitiesRes.state === "success"
+                    ? this.state.initialCommunitiesRes.data.communities
+                    : []
+                }
               />
             </div>
           </div>
@@ -175,7 +198,7 @@ export class CreatePost extends Component<
     );
   }
 
-  updateUrl({ communityId }: Partial<CreatePostProps>) {
+  async updateUrl({ communityId }: Partial<CreatePostProps>) {
     const { communityId: urlCommunityId } = getCreatePostQueryParams();
 
     const locationState = this.props.history.location.state as
@@ -194,7 +217,7 @@ export class CreatePost extends Component<
 
     history.replaceState(locationState, "", url);
 
-    this.fetchCommunity();
+    await this.fetchCommunity();
   }
 
   handleSelectedCommunityChange(choice: Choice) {
@@ -203,18 +226,25 @@ export class CreatePost extends Component<
     });
   }
 
-  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}`);
+    }
   }
 
-  static fetchInitialData({
+  static async fetchInitialData({
     client,
     query: { communityId },
     auth,
   }: InitialFetchRequest<
     QueryParams<CreatePostProps>
-  >): WithPromiseKeys<CreatePostData> {
-    const data: WithPromiseKeys<CreatePostData> = {};
+  >): Promise<CreatePostData> {
+    const data: CreatePostData = {
+      initialCommunitiesRes: await fetchCommunitiesForOptions(client),
+    };
 
     if (communityId) {
       const form: GetCommunity = {
@@ -222,31 +252,9 @@ export class CreatePost extends Component<
         id: getIdFromString(communityId),
       };
 
-      data.communityResponse = client.getCommunity(form);
+      data.communityResponse = await client.getCommunity(form);
     }
 
     return data;
   }
-
-  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: { title, id },
-        },
-      } = wsJsonToRes<GetCommunityResponse>(msg);
-
-      this.setState({
-        selectedCommunityChoice: { label: title, value: id.toString() },
-        loading: false,
-      });
-    }
-  }
 }