import {Component, render, type JSX} from "preact"; import {type Value} from "@holllo/webextension-storage"; import { initializeGlobals, isValidTildesUsername, log, } from "../utilities/exports.js"; import { type UserLabelsData, type UserLabel, fromStorage, Feature, createValueUserLabel, saveUserLabels, } from "../storage/common.js"; import "../scss/index.scss"; import "../scss/user-label-editor.scss"; window.addEventListener("load", async () => { initializeGlobals(); const userLabels = await fromStorage(Feature.UserLabels); render(, document.body); }); type Props = { userLabels: UserLabelsData; }; type State = { hasUnsavedChanges: boolean; newLabelUsername: string; userLabels: UserLabelsData; }; class App extends Component { constructor(props: Props) { super(props); this.state = { hasUnsavedChanges: false, newLabelUsername: "", userLabels: props.userLabels, }; } addNewLabel = async () => { const {newLabelUsername, userLabels} = this.state; if (!isValidTildesUsername(newLabelUsername)) { return; } const existingUserLabel = userLabels.find( ({value: {username}}) => username.toLowerCase() === newLabelUsername.toLowerCase(), ); let id = 1; if (userLabels.length > 0) { id = userLabels.sort((a, b) => b.value.id - a.value.id)[0].value.id + 1; } userLabels.push( await createValueUserLabel({ color: "#ff00ff", id, priority: 0, text: "New Label", username: existingUserLabel?.value.username ?? newLabelUsername, }), ); this.setState({userLabels}); }; onNewUsernameInput = (event: Event) => { const username = (event.target as HTMLInputElement).value; this.setState({newLabelUsername: username}); }; editUserLabel = (event: Event, targetId: number, key: keyof UserLabel) => { const index = this.state.userLabels.findIndex( ({value: {id}}) => id === targetId, ); if (index === -1) { log(`Tried to edit UserLabel with unknown ID: ${targetId}`); return; } const newValue = (event.target as HTMLInputElement).value; // eslint-disable-next-line unicorn/prefer-ternary if (key === "id" || key === "priority") { this.state.userLabels[index].value[key] = Number(newValue); } else { this.state.userLabels[index].value[key] = newValue; } this.setState({ hasUnsavedChanges: true, userLabels: this.state.userLabels, }); }; removeUserLabel = (targetId: number) => { const userLabels = this.state.userLabels.filter( ({value: {id}}) => id !== targetId, ); this.setState({ hasUnsavedChanges: true, userLabels, }); }; saveUserLabels = () => { this.props.userLabels = this.state.userLabels; void saveUserLabels(this.props.userLabels); this.setState({hasUnsavedChanges: false}); }; render() { const {hasUnsavedChanges, newLabelUsername, userLabels} = this.state; userLabels.sort((a, b) => a.value.username.localeCompare(b.value.username)); const labelGroups = new Map(); for (const label of userLabels) { const username = label.value.username.toLowerCase(); const group = labelGroups.get(username) ?? []; group.push(label.value); labelGroups.set(username, group); } const labels: JSX.Element[] = []; for (const [username, group] of labelGroups) { group.sort((a, b) => a.priority === b.priority ? a.text.localeCompare(b.text) : b.priority - a.priority, ); const labelPreviews: JSX.Element[] = group.map(({color, text}) => ( {text} )); group.sort((a, b) => a.id - b.id); const userLabels: JSX.Element[] = []; for (const [index, label] of group.entries()) { const textHandler = (event: Event) => { this.editUserLabel(event, label.id, "text"); }; const colorHandler = (event: Event) => { this.editUserLabel(event, label.id, "color"); }; const priorityHandler = (event: Event) => { this.editUserLabel(event, label.id, "priority"); }; const removeHandler = () => { this.removeUserLabel(label.id); }; userLabels.push(
  • {index === 0 ? : undefined}
    {index === 0 ? : undefined}
    {index === 0 ? : undefined}
    {index === 0 ? : undefined}
  • , ); } labels.push(

    {username} {labelPreviews}

      {userLabels}
    , ); } return ( <>

    To add a new label, enter the username for who you'd like to add the label for, then press the Add New Label button.
    Changes are not automatically saved!
    If there are any unsaved changes an asterisk will appear in the Save All Changes button. To undo all unsaved changes simply refresh the page.

    {labels}
    ); } }