Friday, September 20, 2024 1:34:18 AM
> settings

Customize


Authenticate

> user_settings_controller.ts
import { Controller } from "@hotwired/stimulus";
import Cookies from "universal-cookie";

// Connects to data-controller="user_settings"
export default class UserSettings extends Controller {
  static targets = [
    "fontDropdown",
    "submitPassword",
    "currentPassword",
    "newPassword",
    "confirmationPassword",
    "loginUsername",
    "loginPassword",
    "loginButton",
  ];

  declare readonly fontDropdownTarget: HTMLSelectElement;
  declare readonly submitPasswordTarget: HTMLButtonElement;
  declare readonly currentPasswordTarget: HTMLInputElement;
  declare readonly newPasswordTarget: HTMLInputElement;
  declare readonly confirmationPasswordTarget: HTMLInputElement;
  declare readonly loginUsernameTarget: HTMLInputElement;
  declare readonly loginPasswordTarget: HTMLInputElement;
  declare readonly loginButtonTarget: HTMLButtonElement;

  private declare cookies: Cookies;
  private declare availableFonts: Array<string>;
  private declare shown: boolean;
  private declare cookieName: string;

  initialize() {
    this.cookies = new Cookies(null, { path: "/" });
    this.availableFonts = JSON.parse(this.data.get("availableFonts")!);
    this.shown = false;
    this.cookieName = "reading-font";

    // Cookie default
    if (this.cookies.get(this.cookieName) == null) {
      this.cookies.set(
        this.cookieName,
        this.availableFonts[0],
        {
          sameSite: true
        }
      );
    }
  }

  connect() {
    let selectedFont = this.cookies.get(this.cookieName);
    this.fontDropdownTarget.value = selectedFont;

    // Hook the settings button outside of this controller
    this.hook();
  }

  selectFont(event) {
    let selectedFont = event.target.value;
    if (!this.availableFonts.includes(selectedFont)) return;

    this.cookies.set(this.cookieName, selectedFont);
    this.setCssFont(selectedFont);
  }

  hook() {
    let button = document.getElementById("toggle-settings");
    let settingsContainer = document.getElementById("settings-container");
    let windowsContainer = document.getElementById("windows-container");
    if (button == null || settingsContainer == null || windowsContainer == null) return;

    button.addEventListener("click", () => {
      this.shown = !this.shown;

      if (this.shown) {
        windowsContainer.classList.add("col-lg-8");
        settingsContainer.classList.remove("d-none");
      } else {
        windowsContainer.classList.remove("col-lg-8");
        settingsContainer.classList.add("d-none");
      }
    });
  }

  validatePasswords() {
    let currentValid = this.currentPasswordTarget.value.length > 0;
    let newValid = this.newPasswordTarget.value.length > 0;
    let confirmationValid = this.confirmationPasswordTarget.value.length > 0;

    this.submitPasswordTarget.disabled =
      !currentValid || !newValid || !confirmationValid;
  }

  toggleLoginWindow() {
    let loginContainer = document.getElementById("login-container");
    if (loginContainer == null) return;

    let shown = !loginContainer.classList.contains("d-none");
    if (shown) {
      loginContainer.classList.add("d-none");
    } else {
      loginContainer.classList.remove("d-none");
    }
  }

  enableLoginButton() {
    let usernameValid = this.loginUsernameTarget.value.length > 0;
    let passwordValid = this.loginPasswordTarget.value.length > 0;

    this.loginButtonTarget.disabled = !usernameValid || !passwordValid;
  }

  private setCssFont(font: string) {
    document.documentElement.style.setProperty("--reading-font", font);
  }
}
All opinions represented herein are my own
- © 2024 itsthedevman
- build 340fbb8