]> Untitled Git - lemmy.git/blob - ui/src/components/password_change.tsx
usability features
[lemmy.git] / ui / src / components / password_change.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Subscription } from 'rxjs';
3 import { retryWhen, delay, take } from 'rxjs/operators';
4 import {
5   UserOperation,
6   LoginResponse,
7   PasswordChangeForm,
8   WebSocketJsonResponse,
9 } from '../interfaces';
10 import { WebSocketService, UserService } from '../services';
11 import { wsJsonToRes, capitalizeFirstLetter, toast } from '../utils';
12 import { i18n } from '../i18next';
13 import { T } from 'inferno-i18next';
14
15 interface State {
16   passwordChangeForm: PasswordChangeForm;
17   loading: boolean;
18 }
19
20 export class PasswordChange extends Component<any, State> {
21   private subscription: Subscription;
22
23   emptyState: State = {
24     passwordChangeForm: {
25       token: this.props.match.params.token,
26       password: undefined,
27       password_verify: undefined,
28     },
29     loading: false,
30   };
31
32   constructor(props: any, context: any) {
33     super(props, context);
34
35     this.state = this.emptyState;
36
37     this.subscription = WebSocketService.Instance.subject
38       .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
39       .subscribe(
40         msg => this.parseMessage(msg),
41         err => console.error(err),
42         () => console.log('complete')
43       );
44   }
45
46   componentWillUnmount() {
47     this.subscription.unsubscribe();
48   }
49
50   componentDidMount() {
51     document.title = `${i18n.t('password_change')} - ${
52       WebSocketService.Instance.site.name
53     }`;
54   }
55
56   render() {
57     return (
58       <div class="container">
59         <div class="row">
60           <div class="col-12 col-lg-6 offset-lg-3 mb-4">
61             <h5>
62               { i18n.t('password_change') }
63             </h5>
64             {this.passwordChangeForm()}
65           </div>
66         </div>
67       </div>
68     );
69   }
70
71   passwordChangeForm() {
72     return (
73       <form onSubmit={linkEvent(this, this.handlePasswordChangeSubmit)}>
74         <div class="form-group row">
75           <label class="col-sm-2 col-form-label">
76             <T i18nKey="new_password">#</T>
77           </label>
78           <div class="col-sm-10">
79             <input
80               type="password"
81               value={this.state.passwordChangeForm.password}
82               onInput={linkEvent(this, this.handlePasswordChange)}
83               class="form-control"
84               required
85             />
86           </div>
87         </div>
88         <div class="form-group row">
89           <label class="col-sm-2 col-form-label">
90             <T i18nKey="verify_password">#</T>
91           </label>
92           <div class="col-sm-10">
93             <input
94               type="password"
95               value={this.state.passwordChangeForm.password_verify}
96               onInput={linkEvent(this, this.handleVerifyPasswordChange)}
97               class="form-control"
98               required
99             />
100           </div>
101         </div>
102         <div class="form-group row">
103           <div class="col-sm-10">
104             <button type="submit" class="btn btn-secondary">
105               {this.state.loading ? (
106                 <svg class="icon icon-spinner spin">
107                   <use xlinkHref="#icon-spinner"></use>
108                 </svg>
109               ) : (
110                 capitalizeFirstLetter(i18n.t('save'))
111               )}
112             </button>
113           </div>
114         </div>
115       </form>
116     );
117   }
118
119   handlePasswordChange(i: PasswordChange, event: any) {
120     i.state.passwordChangeForm.password = event.target.value;
121     i.setState(i.state);
122   }
123
124   handleVerifyPasswordChange(i: PasswordChange, event: any) {
125     i.state.passwordChangeForm.password_verify = event.target.value;
126     i.setState(i.state);
127   }
128
129   handlePasswordChangeSubmit(i: PasswordChange, event: any) {
130     event.preventDefault();
131     i.state.loading = true;
132     i.setState(i.state);
133
134     WebSocketService.Instance.passwordChange(i.state.passwordChangeForm);
135   }
136
137   parseMessage(msg: WebSocketJsonResponse) {
138     let res = wsJsonToRes(msg);
139     if (msg.error) {
140       toast(i18n.t(msg.error), 'danger');
141       this.state.loading = false;
142       this.setState(this.state);
143       return;
144     } else {
145       if (res.op == UserOperation.PasswordChange) {
146         let data = res.data as LoginResponse;
147         this.state = this.emptyState;
148         this.setState(this.state);
149         UserService.Instance.login(data);
150         this.props.history.push('/');
151       }
152     }
153   }
154 }