]> Untitled Git - lemmy.git/blob - ui/src/components/setup.tsx
First pass at fixing UI to work with new websocketresponses.
[lemmy.git] / ui / src / components / setup.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Subscription } from 'rxjs';
3 import { retryWhen, delay, take } from 'rxjs/operators';
4 import { RegisterForm, LoginResponse, UserOperation } from '../interfaces';
5 import { WebSocketService, UserService } from '../services';
6 import { wsJsonToRes } from '../utils';
7 import { SiteForm } from './site-form';
8 import { i18n } from '../i18next';
9 import { T } from 'inferno-i18next';
10
11 interface State {
12   userForm: RegisterForm;
13   doneRegisteringUser: boolean;
14   userLoading: boolean;
15 }
16
17 export class Setup extends Component<any, State> {
18   private subscription: Subscription;
19
20   private emptyState: State = {
21     userForm: {
22       username: undefined,
23       password: undefined,
24       password_verify: undefined,
25       admin: true,
26       show_nsfw: true,
27     },
28     doneRegisteringUser: false,
29     userLoading: 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('setup')} - Lemmy`;
52   }
53
54   render() {
55     return (
56       <div class="container">
57         <div class="row">
58           <div class="col-12 offset-lg-3 col-lg-6">
59             <h3>
60               <T i18nKey="lemmy_instance_setup">#</T>
61             </h3>
62             {!this.state.doneRegisteringUser ? (
63               this.registerUser()
64             ) : (
65               <SiteForm />
66             )}
67           </div>
68         </div>
69       </div>
70     );
71   }
72
73   registerUser() {
74     return (
75       <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
76         <h5>
77           <T i18nKey="setup_admin">#</T>
78         </h5>
79         <div class="form-group row">
80           <label class="col-sm-2 col-form-label">
81             <T i18nKey="username">#</T>
82           </label>
83           <div class="col-sm-10">
84             <input
85               type="text"
86               class="form-control"
87               value={this.state.userForm.username}
88               onInput={linkEvent(this, this.handleRegisterUsernameChange)}
89               required
90               minLength={3}
91               maxLength={20}
92               pattern="[a-zA-Z0-9_]+"
93             />
94           </div>
95         </div>
96         <div class="form-group row">
97           <label class="col-sm-2 col-form-label">
98             <T i18nKey="email">#</T>
99           </label>
100           <div class="col-sm-10">
101             <input
102               type="email"
103               class="form-control"
104               placeholder={i18n.t('optional')}
105               value={this.state.userForm.email}
106               onInput={linkEvent(this, this.handleRegisterEmailChange)}
107               minLength={3}
108             />
109           </div>
110         </div>
111         <div class="form-group row">
112           <label class="col-sm-2 col-form-label">
113             <T i18nKey="password">#</T>
114           </label>
115           <div class="col-sm-10">
116             <input
117               type="password"
118               value={this.state.userForm.password}
119               onInput={linkEvent(this, this.handleRegisterPasswordChange)}
120               class="form-control"
121               required
122             />
123           </div>
124         </div>
125         <div class="form-group row">
126           <label class="col-sm-2 col-form-label">
127             <T i18nKey="verify_password">#</T>
128           </label>
129           <div class="col-sm-10">
130             <input
131               type="password"
132               value={this.state.userForm.password_verify}
133               onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
134               class="form-control"
135               required
136             />
137           </div>
138         </div>
139         <div class="form-group row">
140           <div class="col-sm-10">
141             <button type="submit" class="btn btn-secondary">
142               {this.state.userLoading ? (
143                 <svg class="icon icon-spinner spin">
144                   <use xlinkHref="#icon-spinner"></use>
145                 </svg>
146               ) : (
147                 i18n.t('sign_up')
148               )}
149             </button>
150           </div>
151         </div>
152       </form>
153     );
154   }
155
156   handleRegisterSubmit(i: Setup, event: any) {
157     event.preventDefault();
158     i.state.userLoading = true;
159     i.setState(i.state);
160     event.preventDefault();
161     WebSocketService.Instance.register(i.state.userForm);
162   }
163
164   handleRegisterUsernameChange(i: Setup, event: any) {
165     i.state.userForm.username = event.target.value;
166     i.setState(i.state);
167   }
168
169   handleRegisterEmailChange(i: Setup, event: any) {
170     i.state.userForm.email = event.target.value;
171     i.setState(i.state);
172   }
173
174   handleRegisterPasswordChange(i: Setup, event: any) {
175     i.state.userForm.password = event.target.value;
176     i.setState(i.state);
177   }
178
179   handleRegisterPasswordVerifyChange(i: Setup, event: any) {
180     i.state.userForm.password_verify = event.target.value;
181     i.setState(i.state);
182   }
183
184   parseMessage(msg: any) {
185     let res = wsJsonToRes(msg);
186     if (res.error) {
187       alert(i18n.t(res.error));
188       this.state.userLoading = false;
189       this.setState(this.state);
190       return;
191     } else if (res.op == UserOperation.Register) {
192       let data = res.data as LoginResponse;
193       this.state.userLoading = false;
194       this.state.doneRegisteringUser = true;
195       UserService.Instance.login(data);
196       this.setState(this.state);
197     } else if (res.op == UserOperation.CreateSite) {
198       this.props.history.push('/');
199     }
200   }
201 }