-import { None, Some } from "@sniptt/monads";
+import { fetchThemeList, setIsoData } from "@utils/app";
import { Component, linkEvent } from "inferno";
import { Helmet } from "inferno-helmet";
import {
+ CreateSite,
+ GetSiteResponse,
LoginResponse,
Register,
- toUndefined,
- UserOperation,
- wsJsonToRes,
- wsUserOp,
} from "lemmy-js-client";
-import { Subscription } from "rxjs";
-import { delay, retryWhen, take } from "rxjs/operators";
-import { i18n } from "../../i18next";
-import { UserService, WebSocketService } from "../../services";
-import { toast, wsClient } from "../../utils";
+import { I18NextService, UserService } from "../../services";
+import { HttpService, RequestState } from "../../services/HttpService";
import { Spinner } from "../common/icon";
+import PasswordInput from "../common/password-input";
import { SiteForm } from "./site-form";
interface State {
- userForm: Register;
+ form: {
+ username?: string;
+ email?: string;
+ password?: string;
+ password_verify?: string;
+ show_nsfw: boolean;
+ captcha_uuid?: string;
+ captcha_answer?: string;
+ honeypot?: string;
+ answer?: string;
+ };
doneRegisteringUser: boolean;
- userLoading: boolean;
+ registerRes: RequestState<LoginResponse>;
+ themeList: string[];
+ siteRes: GetSiteResponse;
}
export class Setup extends Component<any, State> {
- private subscription: Subscription;
+ private isoData = setIsoData(this.context);
- private emptyState: State = {
- userForm: new Register({
- username: undefined,
- password: undefined,
- password_verify: undefined,
+ state: State = {
+ registerRes: { state: "empty" },
+ themeList: [],
+ form: {
show_nsfw: true,
- // The first admin signup doesn't need a captcha
- captcha_uuid: None,
- captcha_answer: None,
- email: None,
- honeypot: None,
- answer: None,
- }),
- doneRegisteringUser: UserService.Instance.myUserInfo.isSome(),
- userLoading: false,
+ },
+ doneRegisteringUser: !!UserService.Instance.myUserInfo,
+ siteRes: this.isoData.site_res,
};
constructor(props: any, context: any) {
super(props, context);
- this.state = this.emptyState;
-
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log("complete")
- );
+ this.handleCreateSite = this.handleCreateSite.bind(this);
}
- componentWillUnmount() {
- this.subscription.unsubscribe();
+ async componentDidMount() {
+ this.setState({ themeList: await fetchThemeList() });
}
get documentTitle(): string {
- return `${i18n.t("setup")} - Lemmy`;
+ return `${I18NextService.i18n.t("setup")} - Lemmy`;
}
render() {
return (
- <div class="container">
+ <div className="home-setup container-lg">
<Helmet title={this.documentTitle} />
- <div class="row">
- <div class="col-12 offset-lg-3 col-lg-6">
- <h3>{i18n.t("lemmy_instance_setup")}</h3>
+ <div className="row">
+ <div className="col-12 offset-lg-3 col-lg-6">
+ <h1 className="h4 mb-4">
+ {I18NextService.i18n.t("lemmy_instance_setup")}
+ </h1>
{!this.state.doneRegisteringUser ? (
this.registerUser()
) : (
- <SiteForm site={None} showLocal />
+ <SiteForm
+ showLocal
+ onSaveSite={this.handleCreateSite}
+ siteRes={this.state.siteRes}
+ themeList={this.state.themeList}
+ loading={false}
+ />
)}
</div>
</div>
registerUser() {
return (
<form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
- <h5>{i18n.t("setup_admin")}</h5>
- <div class="form-group row">
- <label class="col-sm-2 col-form-label" htmlFor="username">
- {i18n.t("username")}
+ <h2 className="h5 mb-3">{I18NextService.i18n.t("setup_admin")}</h2>
+ <div className="mb-3 row">
+ <label className="col-sm-2 col-form-label" htmlFor="username">
+ {I18NextService.i18n.t("username")}
</label>
- <div class="col-sm-10">
+ <div className="col-sm-10">
<input
type="text"
- class="form-control"
+ className="form-control"
id="username"
- value={this.state.userForm.username}
+ value={this.state.form.username}
onInput={linkEvent(this, this.handleRegisterUsernameChange)}
required
minLength={3}
/>
</div>
</div>
- <div class="form-group row">
- <label class="col-sm-2 col-form-label" htmlFor="email">
- {i18n.t("email")}
+ <div className="mb-3 row">
+ <label className="col-sm-2 col-form-label" htmlFor="email">
+ {I18NextService.i18n.t("email")}
</label>
- <div class="col-sm-10">
+ <div className="col-sm-10">
<input
type="email"
id="email"
- class="form-control"
- placeholder={i18n.t("optional")}
- value={toUndefined(this.state.userForm.email)}
+ className="form-control"
+ placeholder={I18NextService.i18n.t("optional")}
+ value={this.state.form.email}
onInput={linkEvent(this, this.handleRegisterEmailChange)}
minLength={3}
/>
</div>
</div>
- <div class="form-group row">
- <label class="col-sm-2 col-form-label" htmlFor="password">
- {i18n.t("password")}
- </label>
- <div class="col-sm-10">
- <input
- type="password"
- id="password"
- value={this.state.userForm.password}
- onInput={linkEvent(this, this.handleRegisterPasswordChange)}
- class="form-control"
- required
- autoComplete="new-password"
- minLength={10}
- maxLength={60}
- />
- </div>
+ <div className="mb-3">
+ <PasswordInput
+ id="password"
+ value={this.state.form.password}
+ onInput={linkEvent(this, this.handleRegisterPasswordChange)}
+ label={I18NextService.i18n.t("password")}
+ />
</div>
- <div class="form-group row">
- <label class="col-sm-2 col-form-label" htmlFor="verify-password">
- {i18n.t("verify_password")}
- </label>
- <div class="col-sm-10">
- <input
- type="password"
- id="verify-password"
- value={this.state.userForm.password_verify}
- onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
- class="form-control"
- required
- autoComplete="new-password"
- minLength={10}
- maxLength={60}
- />
- </div>
+ <div className="mb-3">
+ <PasswordInput
+ id="verify-password"
+ value={this.state.form.password_verify}
+ onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
+ label={I18NextService.i18n.t("verify_password")}
+ />
</div>
- <div class="form-group row">
- <div class="col-sm-10">
- <button type="submit" class="btn btn-secondary">
- {this.state.userLoading ? <Spinner /> : i18n.t("sign_up")}
+ <div className="mb-3 row">
+ <div className="col-sm-10">
+ <button type="submit" className="btn btn-secondary">
+ {this.state.registerRes.state == "loading" ? (
+ <Spinner />
+ ) : (
+ I18NextService.i18n.t("sign_up")
+ )}
</button>
</div>
</div>
);
}
- handleRegisterSubmit(i: Setup, event: any) {
- event.preventDefault();
- i.state.userLoading = true;
- i.setState(i.state);
+ async handleRegisterSubmit(i: Setup, event: any) {
event.preventDefault();
- WebSocketService.Instance.send(wsClient.register(i.state.userForm));
+ i.setState({ registerRes: { state: "loading" } });
+ const {
+ username,
+ password_verify,
+ password,
+ email,
+ show_nsfw,
+ captcha_uuid,
+ captcha_answer,
+ honeypot,
+ answer,
+ } = i.state.form;
+
+ if (username && password && password_verify) {
+ const form: Register = {
+ username,
+ password,
+ password_verify,
+ email,
+ show_nsfw,
+ captcha_uuid,
+ captcha_answer,
+ honeypot,
+ answer,
+ };
+ i.setState({
+ registerRes: await HttpService.client.register(form),
+ });
+
+ if (i.state.registerRes.state == "success") {
+ const data = i.state.registerRes.data;
+
+ UserService.Instance.login({ res: data });
+ i.setState({ doneRegisteringUser: true });
+ }
+ }
+ }
+
+ async handleCreateSite(form: CreateSite) {
+ const createRes = await HttpService.client.createSite(form);
+ if (createRes.state === "success") {
+ this.props.history.replace("/");
+ location.reload();
+ }
}
handleRegisterUsernameChange(i: Setup, event: any) {
- i.state.userForm.username = event.target.value;
+ i.state.form.username = event.target.value.trim();
i.setState(i.state);
}
handleRegisterEmailChange(i: Setup, event: any) {
- i.state.userForm.email = Some(event.target.value);
+ i.state.form.email = event.target.value;
i.setState(i.state);
}
handleRegisterPasswordChange(i: Setup, event: any) {
- i.state.userForm.password = event.target.value;
+ i.state.form.password = event.target.value;
i.setState(i.state);
}
handleRegisterPasswordVerifyChange(i: Setup, event: any) {
- i.state.userForm.password_verify = event.target.value;
+ i.state.form.password_verify = event.target.value;
i.setState(i.state);
}
-
- parseMessage(msg: any) {
- let op = wsUserOp(msg);
- if (msg.error) {
- toast(i18n.t(msg.error), "danger");
- this.state.userLoading = false;
- this.setState(this.state);
- return;
- } else if (op == UserOperation.Register) {
- let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
- this.state.userLoading = false;
- UserService.Instance.login(data);
- this.setState(this.state);
- } else if (op == UserOperation.CreateSite) {
- window.location.href = "/";
- }
- }
}