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