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