]> Untitled Git - lemmy.git/blob - ui/src/components/setup.tsx
routes.api: fix get_captcha endpoint (#1135)
[lemmy.git] / ui / src / components / setup.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Helmet } from 'inferno-helmet';
3 import { Subscription } from 'rxjs';
4 import { retryWhen, delay, take } from 'rxjs/operators';
5 import {
6   RegisterForm,
7   LoginResponse,
8   UserOperation,
9   WebSocketJsonResponse,
10 } from 'lemmy-js-client';
11 import { WebSocketService, UserService } from '../services';
12 import { wsJsonToRes, toast } from '../utils';
13 import { SiteForm } from './site-form';
14 import { i18n } from '../i18next';
15
16 interface State {
17   userForm: RegisterForm;
18   doneRegisteringUser: boolean;
19   userLoading: boolean;
20 }
21
22 export class Setup extends Component<any, State> {
23   private subscription: Subscription;
24
25   private emptyState: State = {
26     userForm: {
27       username: undefined,
28       password: undefined,
29       password_verify: undefined,
30       admin: true,
31       show_nsfw: true,
32       // The first admin signup doesn't need a captcha
33       captcha_uuid: '',
34       captcha_answer: '',
35     },
36     doneRegisteringUser: false,
37     userLoading: false,
38   };
39
40   constructor(props: any, context: any) {
41     super(props, context);
42
43     this.state = this.emptyState;
44
45     this.subscription = WebSocketService.Instance.subject
46       .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
47       .subscribe(
48         msg => this.parseMessage(msg),
49         err => console.error(err),
50         () => console.log('complete')
51       );
52   }
53
54   componentWillUnmount() {
55     this.subscription.unsubscribe();
56   }
57
58   get documentTitle(): string {
59     return `${i18n.t('setup')} - Lemmy`;
60   }
61
62   render() {
63     return (
64       <div class="container">
65         <Helmet title={this.documentTitle} />
66         <div class="row">
67           <div class="col-12 offset-lg-3 col-lg-6">
68             <h3>{i18n.t('lemmy_instance_setup')}</h3>
69             {!this.state.doneRegisteringUser ? (
70               this.registerUser()
71             ) : (
72               <SiteForm />
73             )}
74           </div>
75         </div>
76       </div>
77     );
78   }
79
80   registerUser() {
81     return (
82       <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
83         <h5>{i18n.t('setup_admin')}</h5>
84         <div class="form-group row">
85           <label class="col-sm-2 col-form-label" htmlFor="username">
86             {i18n.t('username')}
87           </label>
88           <div class="col-sm-10">
89             <input
90               type="text"
91               class="form-control"
92               id="username"
93               value={this.state.userForm.username}
94               onInput={linkEvent(this, this.handleRegisterUsernameChange)}
95               required
96               minLength={3}
97               maxLength={20}
98               pattern="[a-zA-Z0-9_]+"
99             />
100           </div>
101         </div>
102         <div class="form-group row">
103           <label class="col-sm-2 col-form-label" htmlFor="email">
104             {i18n.t('email')}
105           </label>
106
107           <div class="col-sm-10">
108             <input
109               type="email"
110               id="email"
111               class="form-control"
112               placeholder={i18n.t('optional')}
113               value={this.state.userForm.email}
114               onInput={linkEvent(this, this.handleRegisterEmailChange)}
115               minLength={3}
116             />
117           </div>
118         </div>
119         <div class="form-group row">
120           <label class="col-sm-2 col-form-label" htmlFor="password">
121             {i18n.t('password')}
122           </label>
123           <div class="col-sm-10">
124             <input
125               type="password"
126               id="password"
127               value={this.state.userForm.password}
128               onInput={linkEvent(this, this.handleRegisterPasswordChange)}
129               class="form-control"
130               required
131             />
132           </div>
133         </div>
134         <div class="form-group row">
135           <label class="col-sm-2 col-form-label" htmlFor="verify-password">
136             {i18n.t('verify_password')}
137           </label>
138           <div class="col-sm-10">
139             <input
140               type="password"
141               id="verify-password"
142               value={this.state.userForm.password_verify}
143               onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
144               class="form-control"
145               required
146             />
147           </div>
148         </div>
149         <div class="form-group row">
150           <div class="col-sm-10">
151             <button type="submit" class="btn btn-secondary">
152               {this.state.userLoading ? (
153                 <svg class="icon icon-spinner spin">
154                   <use xlinkHref="#icon-spinner"></use>
155                 </svg>
156               ) : (
157                 i18n.t('sign_up')
158               )}
159             </button>
160           </div>
161         </div>
162       </form>
163     );
164   }
165
166   handleRegisterSubmit(i: Setup, event: any) {
167     event.preventDefault();
168     i.state.userLoading = true;
169     i.setState(i.state);
170     event.preventDefault();
171     WebSocketService.Instance.register(i.state.userForm);
172   }
173
174   handleRegisterUsernameChange(i: Setup, event: any) {
175     i.state.userForm.username = event.target.value;
176     i.setState(i.state);
177   }
178
179   handleRegisterEmailChange(i: Setup, event: any) {
180     i.state.userForm.email = event.target.value;
181     i.setState(i.state);
182   }
183
184   handleRegisterPasswordChange(i: Setup, event: any) {
185     i.state.userForm.password = event.target.value;
186     i.setState(i.state);
187   }
188
189   handleRegisterPasswordVerifyChange(i: Setup, event: any) {
190     i.state.userForm.password_verify = event.target.value;
191     i.setState(i.state);
192   }
193
194   parseMessage(msg: WebSocketJsonResponse) {
195     let res = wsJsonToRes(msg);
196     if (msg.error) {
197       toast(i18n.t(msg.error), 'danger');
198       this.state.userLoading = false;
199       this.setState(this.state);
200       return;
201     } else if (res.op == UserOperation.Register) {
202       let data = res.data as LoginResponse;
203       this.state.userLoading = false;
204       this.state.doneRegisteringUser = true;
205       UserService.Instance.login(data);
206       this.setState(this.state);
207     } else if (res.op == UserOperation.CreateSite) {
208       this.props.history.push('/');
209     }
210   }
211 }