]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/home/setup.tsx
fix toaster upon user settings change (#1802)
[lemmy-ui.git] / src / shared / components / home / setup.tsx
index 8da196ca403426ecdad178d6e742144ee25a3e8d..f4bdb5551d6deb48dc74af2224eea158e4f83579 100644 (file)
@@ -1,85 +1,81 @@
-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 { setIsoData, toast, wsClient } from "../../utils";
+import { I18NextService, UserService } from "../../services";
+import { HttpService, RequestState } from "../../services/HttpService";
 import { Spinner } from "../common/icon";
 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 className="container-lg">
+      <div className="home-setup container-lg">
         <Helmet title={this.documentTitle} />
         <div className="row">
           <div className="col-12 offset-lg-3 col-lg-6">
-            <h3>{i18n.t("lemmy_instance_setup")}</h3>
+            <h1 className="h4 mb-4">
+              {I18NextService.i18n.t("lemmy_instance_setup")}
+            </h1>
             {!this.state.doneRegisteringUser ? (
               this.registerUser()
             ) : (
-              <SiteForm siteRes={this.state.siteRes} showLocal />
+              <SiteForm
+                showLocal
+                onSaveSite={this.handleCreateSite}
+                siteRes={this.state.siteRes}
+                themeList={this.state.themeList}
+                loading={false}
+              />
             )}
           </div>
         </div>
@@ -90,17 +86,17 @@ export class Setup extends Component<any, State> {
   registerUser() {
     return (
       <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
-        <h5>{i18n.t("setup_admin")}</h5>
-        <div className="form-group row">
+        <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">
-            {i18n.t("username")}
+            {I18NextService.i18n.t("username")}
           </label>
           <div className="col-sm-10">
             <input
               type="text"
               className="form-control"
               id="username"
-              value={this.state.userForm.username}
+              value={this.state.form.username}
               onInput={linkEvent(this, this.handleRegisterUsernameChange)}
               required
               minLength={3}
@@ -108,9 +104,9 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div className="form-group row">
+        <div className="mb-3 row">
           <label className="col-sm-2 col-form-label" htmlFor="email">
-            {i18n.t("email")}
+            {I18NextService.i18n.t("email")}
           </label>
 
           <div className="col-sm-10">
@@ -118,22 +114,22 @@ export class Setup extends Component<any, State> {
               type="email"
               id="email"
               className="form-control"
-              placeholder={i18n.t("optional")}
-              value={toUndefined(this.state.userForm.email)}
+              placeholder={I18NextService.i18n.t("optional")}
+              value={this.state.form.email}
               onInput={linkEvent(this, this.handleRegisterEmailChange)}
               minLength={3}
             />
           </div>
         </div>
-        <div className="form-group row">
+        <div className="mb-3 row">
           <label className="col-sm-2 col-form-label" htmlFor="password">
-            {i18n.t("password")}
+            {I18NextService.i18n.t("password")}
           </label>
           <div className="col-sm-10">
             <input
               type="password"
               id="password"
-              value={this.state.userForm.password}
+              value={this.state.form.password}
               onInput={linkEvent(this, this.handleRegisterPasswordChange)}
               className="form-control"
               required
@@ -143,15 +139,15 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div className="form-group row">
+        <div className="mb-3 row">
           <label className="col-sm-2 col-form-label" htmlFor="verify-password">
-            {i18n.t("verify_password")}
+            {I18NextService.i18n.t("verify_password")}
           </label>
           <div className="col-sm-10">
             <input
               type="password"
               id="verify-password"
-              value={this.state.userForm.password_verify}
+              value={this.state.form.password_verify}
               onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
               className="form-control"
               required
@@ -161,10 +157,14 @@ export class Setup extends Component<any, State> {
             />
           </div>
         </div>
-        <div className="form-group row">
+        <div className="mb-3 row">
           <div className="col-sm-10">
             <button type="submit" className="btn btn-secondary">
-              {this.state.userLoading ? <Spinner /> : i18n.t("sign_up")}
+              {this.state.registerRes.state == "loading" ? (
+                <Spinner />
+              ) : (
+                I18NextService.i18n.t("sign_up")
+              )}
             </button>
           </div>
         </div>
@@ -172,45 +172,71 @@ export class Setup extends Component<any, State> {
     );
   }
 
-  handleRegisterSubmit(i: Setup, event: any) {
-    event.preventDefault();
-    i.setState({ userLoading: true });
+  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.setState({ userLoading: false });
-      return;
-    } else if (op == UserOperation.Register) {
-      let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
-      this.setState({ userLoading: false });
-      UserService.Instance.login(data);
-    } else if (op == UserOperation.CreateSite) {
-      window.location.href = "/";
-    }
-  }
 }