import {type Value} from "@holllo/webextension-storage"; import {Component} from "preact"; import {log} from "../../utilities/exports.js"; import { type UsernameColorsData, type UsernameColor, Feature, Data, createValueUsernamecolor, fromStorage, } from "../../storage/exports.js"; import {Setting, type SettingProps} from "./index.js"; type State = { previewChecked: "off" | "foreground" | "background"; usernameColors: UsernameColorsData; usernameColorsToRemove: UsernameColorsData; randomizeChecked: Value; }; export class UsernameColorsSetting extends Component { constructor(props: SettingProps) { super(props); this.state = { previewChecked: "off", usernameColors: undefined!, usernameColorsToRemove: [], randomizeChecked: undefined!, }; } async componentDidMount() { this.setState({ randomizeChecked: await fromStorage(Data.RandomizeUsernameColors), usernameColors: await fromStorage(Feature.UsernameColors), }); } addNewColor = async () => { let id = 1; if (this.state.usernameColors.length > 0) { id = this.state.usernameColors.sort((a, b) => b.value.id - a.value.id)[0] .value.id + 1; } const newColor = await createValueUsernamecolor({ color: "", id, username: "", }); this.state.usernameColors.push(newColor); this.setState({ usernameColors: this.state.usernameColors, }); }; removeColor = async (targetId: number) => { const targetIndex = this.state.usernameColors.findIndex( ({value}) => value.id === targetId, ); const usernameColorsToRemove = this.state.usernameColorsToRemove; usernameColorsToRemove.push( ...this.state.usernameColors.splice(targetIndex, 1), ); this.setState({ usernameColors: this.state.usernameColors, usernameColorsToRemove, }); }; saveChanges = async () => { for (const usernameColor of this.state.usernameColorsToRemove) { await usernameColor.remove(); } for (const usernameColor of this.state.usernameColors) { await usernameColor.save(); } this.setState({usernameColorsToRemove: []}); }; togglePreview = async () => { let {previewChecked} = this.state; // eslint-disable-next-line default-case switch (previewChecked) { case "off": { previewChecked = "foreground"; break; } case "foreground": { previewChecked = "background"; break; } case "background": { previewChecked = "off"; break; } } this.setState({previewChecked}); }; toggleRandomized = async () => { const randomizeChecked = this.state.randomizeChecked; randomizeChecked.value = !randomizeChecked.value; await randomizeChecked.save(); this.setState({randomizeChecked}); }; onInput = (event: Event, id: number, key: "color" | "username") => { const colorIndex = this.state.usernameColors.findIndex( ({value}) => value.id === id, ); if (colorIndex === -1) { log(`Tried to edit unknown UsernameColor ID: ${id}`); return; } const newValue = (event.target as HTMLInputElement).value; this.state.usernameColors[colorIndex].value[key] = newValue; this.setState({usernameColors: this.state.usernameColors}); }; render() { const {previewChecked, usernameColors, randomizeChecked} = this.state; if (usernameColors === undefined) { return; } usernameColors.sort((a, b) => a.value.id - b.value.id); const editors = usernameColors.map(({value: {color, id, username}}) => { const style: Record = {}; if (previewChecked === "background") { style.backgroundColor = color; } else if (previewChecked === "foreground") { style.color = color; } const usernameHandler = (event: Event) => { this.onInput(event, id, "username"); }; const colorHandler = (event: Event) => { this.onInput(event, id, "color"); }; const removeHandler = async () => { await this.removeColor(id); }; return (
); }); return (

Assign custom colors to usernames.
You can enter multiple usernames separated by a comma if you want them to use the same color.
If randomize is selected then all usernames will be given a random background color. This will not override colors you have manually assigned.

{editors}
); } }