]> Untitled Git - lemmy.git/blob - ui/src/components/login.tsx
Fixing rust warning.
[lemmy.git] / ui / src / components / login.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Subscription } from "rxjs";
3 import { retryWhen, delay, take } from 'rxjs/operators';
4 import { LoginForm, RegisterForm, LoginResponse, UserOperation } from '../interfaces';
5 import { WebSocketService, UserService } from '../services';
6 import { msgOp } from '../utils';
7
8 interface State {
9   loginForm: LoginForm;
10   registerForm: RegisterForm;
11   loginLoading: boolean;
12   registerLoading: boolean;
13 }
14
15
16 export class Login extends Component<any, State> {
17   private subscription: Subscription;
18
19   emptyState: State = {
20     loginForm: {
21       username_or_email: undefined,
22       password: undefined
23     },
24     registerForm: {
25       username: undefined,
26       password: undefined,
27       password_verify: undefined,
28       admin: false,
29       spam_timer: undefined,
30     },
31     loginLoading: false,
32     registerLoading: false,
33   }
34
35   constructor(props: any, context: any) {
36     super(props, context);
37
38     this.state = this.emptyState;
39
40     this.subscription = WebSocketService.Instance.subject
41     .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
42     .subscribe(
43       (msg) => this.parseMessage(msg),
44         (err) => console.error(err),
45         () => console.log("complete")
46     );
47   }
48
49   componentWillUnmount() {
50     this.subscription.unsubscribe();
51   }
52
53   componentDidMount() {
54     document.title = "Login - Lemmy";
55   }
56
57   render() {
58     return (
59       <div class="container">
60         <div class="row">
61           <div class="col-12 col-lg-6 mb-4">
62             {this.loginForm()}
63           </div>
64           <div class="col-12 col-lg-6">
65             {this.registerForm()}
66           </div>
67         </div>
68       </div>
69     )
70   }
71
72   loginForm() {
73     return (
74       <div>
75         <form onSubmit={linkEvent(this, this.handleLoginSubmit)}>
76           <h5>Login</h5>
77           <div class="form-group row">
78             <label class="col-sm-2 col-form-label">Email or Username</label>
79             <div class="col-sm-10">
80               <input type="text" class="form-control" value={this.state.loginForm.username_or_email} onInput={linkEvent(this, this.handleLoginUsernameChange)} required minLength={3} />
81             </div>
82           </div>
83           <div class="form-group row">
84             <label class="col-sm-2 col-form-label">Password</label>
85             <div class="col-sm-10">
86               <input type="password" value={this.state.loginForm.password} onInput={linkEvent(this, this.handleLoginPasswordChange)} class="form-control" required />
87             </div>
88           </div>
89           <div class="form-group row">
90             <div class="col-sm-10">
91               <button type="submit" class="btn btn-secondary">{this.state.loginLoading ? 
92               <svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg> : 'Login'}</button>
93             </div>
94           </div>
95         </form>
96         Forgot your password or deleted your account? Reset your password. TODO
97       </div>
98     );
99   }
100   registerForm() {
101     return (
102       <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
103         <h5>Sign Up</h5>
104         <div class="form-group row">
105           <label class="col-sm-2 col-form-label">Username</label>
106           <div class="col-sm-10">
107             <input type="text" class="form-control" value={this.state.registerForm.username} onInput={linkEvent(this, this.handleRegisterUsernameChange)} required minLength={3} maxLength={20} pattern="[a-zA-Z0-9_]+" />
108           </div>
109         </div>
110         <div class="form-group row">
111           <label class="col-sm-2 col-form-label">Email</label>
112           <div class="col-sm-10">
113             <input type="email" class="form-control" placeholder="Optional" value={this.state.registerForm.email} onInput={linkEvent(this, this.handleRegisterEmailChange)} minLength={3} />
114           </div>
115         </div>
116         <div class="form-group row">
117           <label class="col-sm-2 col-form-label">Password</label>
118           <div class="col-sm-10">
119             <input type="password" value={this.state.registerForm.password} onInput={linkEvent(this, this.handleRegisterPasswordChange)} class="form-control" required />
120           </div>
121         </div>
122         <div class="form-group row">
123           <label class="col-sm-2 col-form-label">Verify Password</label>
124           <div class="col-sm-10">
125             <input type="password" value={this.state.registerForm.password_verify} onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)} class="form-control" required />
126           </div>
127         </div>
128         <input type="hidden" value={this.state.registerForm.spam_timer} />
129         <div class="form-group row">
130           <div class="col-sm-10">
131             <button type="submit" class="btn btn-secondary">{this.state.registerLoading ? 
132             <svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg> : 'Sign Up'}</button>
133
134           </div>
135         </div>
136       </form>
137     );
138   }
139
140   handleLoginSubmit(i: Login, event: any) {
141     event.preventDefault();
142     i.state.loginLoading = true;
143     i.setState(i.state);
144     WebSocketService.Instance.login(i.state.loginForm);
145   }
146
147   handleLoginUsernameChange(i: Login, event: any) {
148     i.state.loginForm.username_or_email = event.target.value;
149     i.setState(i.state);
150   }
151
152   handleLoginPasswordChange(i: Login, event: any) {
153     i.state.loginForm.password = event.target.value;
154     i.setState(i.state);
155   }
156
157   handleRegisterSubmit(i: Login, event: any) {
158     event.preventDefault();
159     i.state.registerLoading = true;
160     i.setState(i.state);
161     event.preventDefault();
162
163     let endTimer = new Date().getTime();
164     let elapsed = endTimer - i.state.registerForm.spam_timer;
165
166     i.state.registerForm.spam_timer = elapsed;
167     if (elapsed > 1142) {
168       WebSocketService.Instance.register(i.state.registerForm);
169     } else {
170       window.location.href = "https://github.com/dessalines/lemmy";
171     }
172   }
173
174   handleRegisterUsernameChange(i: Login, event: any) {
175     i.state.registerForm.username = event.target.value;
176     i.state.registerForm.spam_timer = new Date().getTime();
177     i.setState(i.state);
178   }
179
180   handleRegisterEmailChange(i: Login, event: any) {
181     i.state.registerForm.email = event.target.value;
182     i.setState(i.state);
183   }
184
185   handleRegisterPasswordChange(i: Login, event: any) {
186     i.state.registerForm.password = event.target.value;
187     i.setState(i.state);
188   }
189
190   handleRegisterPasswordVerifyChange(i: Login, event: any) {
191     i.state.registerForm.password_verify = event.target.value;
192     i.setState(i.state);
193   }
194
195   parseMessage(msg: any) {
196     let op: UserOperation = msgOp(msg);
197     if (msg.error) {
198       alert(msg.error);
199       this.state = this.emptyState;
200       this.setState(this.state);
201       return;
202     } else {
203       if (op == UserOperation.Login) {
204         this.state.loginLoading = false;
205         this.state.registerLoading = false;
206         let res: LoginResponse = msg;
207         UserService.Instance.login(res);
208         this.props.history.push('/');
209       } else if (op == UserOperation.Register) {
210         this.state.loginLoading = false;
211         this.state.registerLoading = false;
212         let res: LoginResponse = msg;
213         UserService.Instance.login(res);
214         this.props.history.push('/communities');
215       }
216     }
217   }
218
219 }