]> Untitled Git - lemmy-ui.git/blob - src/shared/components/person/password-change.tsx
Merge branch 'fix/notif_new_fetch_bug' of https://github.com/ernestwisniewski/lemmy...
[lemmy-ui.git] / src / shared / components / person / password-change.tsx
1 import { None } from "@sniptt/monads";
2 import { Component, linkEvent } from "inferno";
3 import {
4   GetSiteResponse,
5   LoginResponse,
6   PasswordChange as PasswordChangeForm,
7   UserOperation,
8   wsJsonToRes,
9   wsUserOp,
10 } from "lemmy-js-client";
11 import { Subscription } from "rxjs";
12 import { i18n } from "../../i18next";
13 import { UserService, WebSocketService } from "../../services";
14 import {
15   capitalizeFirstLetter,
16   isBrowser,
17   setIsoData,
18   toast,
19   wsClient,
20   wsSubscribe,
21 } from "../../utils";
22 import { HtmlTags } from "../common/html-tags";
23 import { Spinner } from "../common/icon";
24
25 interface State {
26   passwordChangeForm: PasswordChangeForm;
27   loading: boolean;
28   siteRes: GetSiteResponse;
29 }
30
31 export class PasswordChange extends Component<any, State> {
32   private isoData = setIsoData(this.context);
33   private subscription: Subscription;
34
35   emptyState: State = {
36     passwordChangeForm: new PasswordChangeForm({
37       token: this.props.match.params.token,
38       password: undefined,
39       password_verify: undefined,
40     }),
41     loading: false,
42     siteRes: this.isoData.site_res,
43   };
44
45   constructor(props: any, context: any) {
46     super(props, context);
47
48     this.state = this.emptyState;
49
50     this.parseMessage = this.parseMessage.bind(this);
51     this.subscription = wsSubscribe(this.parseMessage);
52   }
53
54   componentWillUnmount() {
55     if (isBrowser()) {
56       this.subscription.unsubscribe();
57     }
58   }
59
60   get documentTitle(): string {
61     return this.state.siteRes.site_view.match({
62       some: siteView => `${i18n.t("password_change")} - ${siteView.site.name}`,
63       none: "",
64     });
65   }
66
67   render() {
68     return (
69       <div class="container">
70         <HtmlTags
71           title={this.documentTitle}
72           path={this.context.router.route.match.url}
73           description={None}
74           image={None}
75         />
76         <div class="row">
77           <div class="col-12 col-lg-6 offset-lg-3 mb-4">
78             <h5>{i18n.t("password_change")}</h5>
79             {this.passwordChangeForm()}
80           </div>
81         </div>
82       </div>
83     );
84   }
85
86   passwordChangeForm() {
87     return (
88       <form onSubmit={linkEvent(this, this.handlePasswordChangeSubmit)}>
89         <div class="form-group row">
90           <label class="col-sm-2 col-form-label" htmlFor="new-password">
91             {i18n.t("new_password")}
92           </label>
93           <div class="col-sm-10">
94             <input
95               id="new-password"
96               type="password"
97               value={this.state.passwordChangeForm.password}
98               onInput={linkEvent(this, this.handlePasswordChange)}
99               class="form-control"
100               required
101               maxLength={60}
102             />
103           </div>
104         </div>
105         <div class="form-group row">
106           <label class="col-sm-2 col-form-label" htmlFor="verify-password">
107             {i18n.t("verify_password")}
108           </label>
109           <div class="col-sm-10">
110             <input
111               id="verify-password"
112               type="password"
113               value={this.state.passwordChangeForm.password_verify}
114               onInput={linkEvent(this, this.handleVerifyPasswordChange)}
115               class="form-control"
116               required
117               maxLength={60}
118             />
119           </div>
120         </div>
121         <div class="form-group row">
122           <div class="col-sm-10">
123             <button type="submit" class="btn btn-secondary">
124               {this.state.loading ? (
125                 <Spinner />
126               ) : (
127                 capitalizeFirstLetter(i18n.t("save"))
128               )}
129             </button>
130           </div>
131         </div>
132       </form>
133     );
134   }
135
136   handlePasswordChange(i: PasswordChange, event: any) {
137     i.state.passwordChangeForm.password = event.target.value;
138     i.setState(i.state);
139   }
140
141   handleVerifyPasswordChange(i: PasswordChange, event: any) {
142     i.state.passwordChangeForm.password_verify = event.target.value;
143     i.setState(i.state);
144   }
145
146   handlePasswordChangeSubmit(i: PasswordChange, event: any) {
147     event.preventDefault();
148     i.state.loading = true;
149     i.setState(i.state);
150
151     WebSocketService.Instance.send(
152       wsClient.passwordChange(i.state.passwordChangeForm)
153     );
154   }
155
156   parseMessage(msg: any) {
157     let op = wsUserOp(msg);
158     console.log(msg);
159     if (msg.error) {
160       toast(i18n.t(msg.error), "danger");
161       this.state.loading = false;
162       this.setState(this.state);
163       return;
164     } else if (op == UserOperation.PasswordChange) {
165       let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
166       this.state = this.emptyState;
167       this.setState(this.state);
168       UserService.Instance.login(data);
169       this.props.history.push("/");
170     }
171   }
172 }