]> Untitled Git - lemmy-ui.git/blob - src/shared/components/private_message/create-private-message.tsx
Fix server-side rendering after first load.
[lemmy-ui.git] / src / shared / components / private_message / create-private-message.tsx
1 import { getRecipientIdFromProps, myAuth, setIsoData } from "@utils/app";
2 import { isBrowser } from "@utils/browser";
3 import { RouteDataResponse } from "@utils/types";
4 import { Component } from "inferno";
5 import {
6   CreatePrivateMessage as CreatePrivateMessageI,
7   GetPersonDetails,
8   GetPersonDetailsResponse,
9   GetSiteResponse,
10 } from "lemmy-js-client";
11 import { InitialFetchRequest } from "../../interfaces";
12 import { FirstLoadService, I18NextService } from "../../services";
13 import { HttpService, RequestState } from "../../services/HttpService";
14 import { toast } from "../../toast";
15 import { HtmlTags } from "../common/html-tags";
16 import { Spinner } from "../common/icon";
17 import { PrivateMessageForm } from "./private-message-form";
18
19 type CreatePrivateMessageData = RouteDataResponse<{
20   recipientDetailsResponse: GetPersonDetailsResponse;
21 }>;
22
23 interface CreatePrivateMessageState {
24   siteRes: GetSiteResponse;
25   recipientRes: RequestState<GetPersonDetailsResponse>;
26   recipientId: number;
27   isIsomorphic: boolean;
28 }
29
30 export class CreatePrivateMessage extends Component<
31   any,
32   CreatePrivateMessageState
33 > {
34   private isoData = setIsoData<CreatePrivateMessageData>(this.context);
35   state: CreatePrivateMessageState = {
36     siteRes: this.isoData.site_res,
37     recipientRes: { state: "empty" },
38     recipientId: getRecipientIdFromProps(this.props),
39     isIsomorphic: false,
40   };
41
42   constructor(props: any, context: any) {
43     super(props, context);
44     this.handlePrivateMessageCreate =
45       this.handlePrivateMessageCreate.bind(this);
46
47     // Only fetch the data if coming from another route
48     if (!isBrowser() || FirstLoadService.isFirstLoad) {
49       this.state = {
50         ...this.state,
51         recipientRes: this.isoData.routeData.recipientDetailsResponse,
52         isIsomorphic: true,
53       };
54     }
55   }
56
57   async componentDidMount() {
58     if (!this.state.isIsomorphic) {
59       await this.fetchPersonDetails();
60     }
61   }
62
63   static async fetchInitialData({
64     client,
65     path,
66     auth,
67   }: InitialFetchRequest): Promise<CreatePrivateMessageData> {
68     const person_id = Number(path.split("/").pop());
69
70     const form: GetPersonDetails = {
71       person_id,
72       sort: "New",
73       saved_only: false,
74       auth,
75     };
76
77     return {
78       recipientDetailsResponse: await client.getPersonDetails(form),
79     };
80   }
81
82   async fetchPersonDetails() {
83     this.setState({
84       recipientRes: { state: "loading" },
85     });
86
87     this.setState({
88       recipientRes: await HttpService.client.getPersonDetails({
89         person_id: this.state.recipientId,
90         sort: "New",
91         saved_only: false,
92         auth: myAuth(),
93       }),
94     });
95   }
96
97   get documentTitle(): string {
98     if (this.state.recipientRes.state == "success") {
99       const name_ = this.state.recipientRes.data.person_view.person.name;
100       return `${I18NextService.i18n.t("create_private_message")} - ${name_}`;
101     } else {
102       return "";
103     }
104   }
105
106   renderRecipientRes() {
107     switch (this.state.recipientRes.state) {
108       case "loading":
109         return (
110           <h5>
111             <Spinner large />
112           </h5>
113         );
114       case "success": {
115         const res = this.state.recipientRes.data;
116         return (
117           <div className="row">
118             <div className="col-12 col-lg-6 offset-lg-3 mb-4">
119               <h1 className="h4">
120                 {I18NextService.i18n.t("create_private_message")}
121               </h1>
122               <PrivateMessageForm
123                 onCreate={this.handlePrivateMessageCreate}
124                 recipient={res.person_view.person}
125               />
126             </div>
127           </div>
128         );
129       }
130     }
131   }
132
133   render() {
134     return (
135       <div className="create-private-message container-lg">
136         <HtmlTags
137           title={this.documentTitle}
138           path={this.context.router.route.match.url}
139         />
140         {this.renderRecipientRes()}
141       </div>
142     );
143   }
144
145   async handlePrivateMessageCreate(form: CreatePrivateMessageI) {
146     const res = await HttpService.client.createPrivateMessage(form);
147
148     if (res.state == "success") {
149       toast(I18NextService.i18n.t("message_sent"));
150
151       // Navigate to the front
152       this.context.router.history.push("/");
153     }
154   }
155 }