Compare commits
No commits in common. "84c69eaab3864cfa6f0188c531888ea5bf88561b" and "ecd91563d5de43a564bf0508f6913472a08f2b54" have entirely different histories.
84c69eaab3
...
ecd91563d5
|
@ -1,29 +1,18 @@
|
||||||
|
import {log, querySelectorAll} from "../../utilities/exports.js";
|
||||||
import {type UsernameColorsData} from "../../storage/exports.js";
|
import {type UsernameColorsData} from "../../storage/exports.js";
|
||||||
import {
|
|
||||||
log,
|
|
||||||
querySelectorAll,
|
|
||||||
getColorFromStringHash,
|
|
||||||
isColorBright,
|
|
||||||
} from "../../utilities/exports.js";
|
|
||||||
|
|
||||||
export async function runUsernameColorsFeature(
|
export function runUsernameColorsFeature(
|
||||||
data: UsernameColorsData,
|
data: UsernameColorsData,
|
||||||
anonymizeUsernamesEnabled: boolean,
|
anonymizeUsernamesEnabled: boolean,
|
||||||
randomizeUsernameColorsEnabled: boolean,
|
|
||||||
) {
|
) {
|
||||||
const count = await usernameColors(
|
const count = usernameColors(data, anonymizeUsernamesEnabled);
|
||||||
data,
|
|
||||||
anonymizeUsernamesEnabled,
|
|
||||||
randomizeUsernameColorsEnabled,
|
|
||||||
);
|
|
||||||
log(`Username Colors: Applied ${count} colors.`);
|
log(`Username Colors: Applied ${count} colors.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function usernameColors(
|
function usernameColors(
|
||||||
data: UsernameColorsData,
|
data: UsernameColorsData,
|
||||||
anonymizeUsernamesEnabled: boolean,
|
anonymizeUsernamesEnabled: boolean,
|
||||||
randomizeUsernameColorsEnabled: boolean,
|
): number {
|
||||||
): Promise<number> {
|
|
||||||
const usernameColors = new Map<string, string>();
|
const usernameColors = new Map<string, string>();
|
||||||
for (const {
|
for (const {
|
||||||
value: {color, username: usernames},
|
value: {color, username: usernames},
|
||||||
|
@ -52,20 +41,11 @@ async function usernameColors(
|
||||||
|
|
||||||
element.classList.add("trx-username-colors");
|
element.classList.add("trx-username-colors");
|
||||||
const color = usernameColors.get(target);
|
const color = usernameColors.get(target);
|
||||||
if (color !== undefined) {
|
if (color === undefined) {
|
||||||
element.style.color = color;
|
|
||||||
} else if (randomizeUsernameColorsEnabled) {
|
|
||||||
element.classList.add("trx-random-username-color");
|
|
||||||
const randomColor = await getColorFromStringHash(target);
|
|
||||||
const fontColor = isColorBright(randomColor) ? "#000" : "#FFF";
|
|
||||||
element.style.setProperty("--background-color", randomColor);
|
|
||||||
// Specifically use "--link-color" here so Tildes's link color doesn't
|
|
||||||
// override ours.
|
|
||||||
element.style.setProperty("--link-color", fontColor);
|
|
||||||
} else {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
element.style.color = color;
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,14 +95,7 @@ async function initialize() {
|
||||||
if (enabledFeatures.value.has(Feature.UsernameColors)) {
|
if (enabledFeatures.value.has(Feature.UsernameColors)) {
|
||||||
observerFeatures.push(async () => {
|
observerFeatures.push(async () => {
|
||||||
const data = await fromStorage(Feature.UsernameColors);
|
const data = await fromStorage(Feature.UsernameColors);
|
||||||
const randomizeUsernameColors = await fromStorage(
|
runUsernameColorsFeature(data, anonymizeUsernamesEnabled);
|
||||||
Data.RandomizeUsernameColors,
|
|
||||||
);
|
|
||||||
await runUsernameColorsFeature(
|
|
||||||
data,
|
|
||||||
anonymizeUsernamesEnabled,
|
|
||||||
randomizeUsernameColors.value,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import {type Value} from "@holllo/webextension-storage";
|
|
||||||
import {Component} from "preact";
|
import {Component} from "preact";
|
||||||
import {log} from "../../utilities/exports.js";
|
import {log} from "../../utilities/exports.js";
|
||||||
import {
|
import {
|
||||||
type UsernameColorsData,
|
type UsernameColorsData,
|
||||||
type UsernameColor,
|
type UsernameColor,
|
||||||
Feature,
|
Feature,
|
||||||
Data,
|
|
||||||
createValueUsernamecolor,
|
createValueUsernamecolor,
|
||||||
fromStorage,
|
fromStorage,
|
||||||
} from "../../storage/exports.js";
|
} from "../../storage/exports.js";
|
||||||
|
@ -15,7 +13,6 @@ type State = {
|
||||||
previewChecked: "off" | "foreground" | "background";
|
previewChecked: "off" | "foreground" | "background";
|
||||||
usernameColors: UsernameColorsData;
|
usernameColors: UsernameColorsData;
|
||||||
usernameColorsToRemove: UsernameColorsData;
|
usernameColorsToRemove: UsernameColorsData;
|
||||||
randomizeChecked: Value<boolean>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class UsernameColorsSetting extends Component<SettingProps, State> {
|
export class UsernameColorsSetting extends Component<SettingProps, State> {
|
||||||
|
@ -26,15 +23,11 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
|
||||||
previewChecked: "off",
|
previewChecked: "off",
|
||||||
usernameColors: undefined!,
|
usernameColors: undefined!,
|
||||||
usernameColorsToRemove: [],
|
usernameColorsToRemove: [],
|
||||||
randomizeChecked: undefined!,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
this.setState({
|
this.setState({usernameColors: await fromStorage(Feature.UsernameColors)});
|
||||||
randomizeChecked: await fromStorage(Data.RandomizeUsernameColors),
|
|
||||||
usernameColors: await fromStorage(Feature.UsernameColors),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addNewColor = async () => {
|
addNewColor = async () => {
|
||||||
|
@ -107,13 +100,6 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
|
||||||
this.setState({previewChecked});
|
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") => {
|
onInput = (event: Event, id: number, key: "color" | "username") => {
|
||||||
const colorIndex = this.state.usernameColors.findIndex(
|
const colorIndex = this.state.usernameColors.findIndex(
|
||||||
({value}) => value.id === id,
|
({value}) => value.id === id,
|
||||||
|
@ -129,7 +115,7 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {previewChecked, usernameColors, randomizeChecked} = this.state;
|
const {previewChecked, usernameColors} = this.state;
|
||||||
if (usernameColors === undefined) {
|
if (usernameColors === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -184,10 +170,6 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
|
||||||
<br />
|
<br />
|
||||||
You can enter multiple usernames separated by a comma if you want them
|
You can enter multiple usernames separated by a comma if you want them
|
||||||
to use the same color.
|
to use the same color.
|
||||||
<br />
|
|
||||||
If randomize is selected then all usernames will be given a random
|
|
||||||
background color. This will not override colors you have manually
|
|
||||||
assigned.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="username-colors-controls">
|
<div class="username-colors-controls">
|
||||||
|
@ -202,19 +184,6 @@ export class UsernameColorsSetting extends Component<SettingProps, State> {
|
||||||
<button class="button" onClick={this.saveChanges}>
|
<button class="button" onClick={this.saveChanges}>
|
||||||
Save Changes
|
Save Changes
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul class="checkbox-list">
|
|
||||||
<li>
|
|
||||||
<label>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
checked={randomizeChecked.value}
|
|
||||||
onClick={this.toggleRandomized}
|
|
||||||
/>
|
|
||||||
Randomize Username Colors
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{editors}
|
{editors}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
@import "scripts/jump-to-new-comment";
|
@import "scripts/jump-to-new-comment";
|
||||||
@import "scripts/markdown-toolbar";
|
@import "scripts/markdown-toolbar";
|
||||||
@import "scripts/user-labels";
|
@import "scripts/user-labels";
|
||||||
@import "scripts/username-colors";
|
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
@import "shared";
|
@import "shared";
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
.trx-random-username-color {
|
|
||||||
background-color: var(--background-color);
|
|
||||||
border-radius: 3px;
|
|
||||||
color: var(--link-color);
|
|
||||||
padding: 2px 3px;
|
|
||||||
}
|
|
|
@ -22,6 +22,5 @@ export enum Data {
|
||||||
EnabledFeatures = "enabled-features",
|
EnabledFeatures = "enabled-features",
|
||||||
KnownGroups = "known-groups",
|
KnownGroups = "known-groups",
|
||||||
LatestActiveFeatureTab = "latest-active-feature-tab",
|
LatestActiveFeatureTab = "latest-active-feature-tab",
|
||||||
RandomizeUsernameColors = "randomize-username-colors",
|
|
||||||
Version = "data-version",
|
Version = "data-version",
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,13 +58,6 @@ export const storageValues = {
|
||||||
value: "2.0.0",
|
value: "2.0.0",
|
||||||
storage: browser.storage.sync,
|
storage: browser.storage.sync,
|
||||||
}),
|
}),
|
||||||
[Data.RandomizeUsernameColors]: createValue({
|
|
||||||
deserialize: (input) => JSON.parse(input) as boolean,
|
|
||||||
serialize: (input) => JSON.stringify(input),
|
|
||||||
key: Data.RandomizeUsernameColors,
|
|
||||||
value: false,
|
|
||||||
storage: browser.storage.sync,
|
|
||||||
}),
|
|
||||||
[Feature.HideTopics]: collectHideTopicsData(),
|
[Feature.HideTopics]: collectHideTopicsData(),
|
||||||
[Feature.HideVotes]: createValue({
|
[Feature.HideVotes]: createValue({
|
||||||
deserialize: (input) => JSON.parse(input) as HideVotesData,
|
deserialize: (input) => JSON.parse(input) as HideVotesData,
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
import {hashSha256} from "./text.js";
|
|
||||||
|
|
||||||
/** Return a hex color based on a hash of the input string. */
|
|
||||||
export async function getColorFromStringHash(input: string): Promise<string> {
|
|
||||||
const hash = Number.parseInt(await hashSha256(input), 16);
|
|
||||||
const color = Math.abs(hash % 0xff_ff_ff).toString(16);
|
|
||||||
return `#${color}`.padEnd(7, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether a hex color is "bright". */
|
/** Returns whether a hex color is "bright". */
|
||||||
export function isColorBright(color: string): boolean {
|
export function isColorBright(color: string): boolean {
|
||||||
if (color.startsWith("#")) {
|
if (color.startsWith("#")) {
|
||||||
|
|
|
@ -16,12 +16,3 @@ export function pluralize(
|
||||||
|
|
||||||
return plural ?? singular + "s";
|
return plural ?? singular + "s";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the SHA-256 hash for a given string. */
|
|
||||||
export async function hashSha256(input: string): Promise<string> {
|
|
||||||
const uint8Input = new window.TextEncoder().encode(input);
|
|
||||||
const digest = await window.crypto.subtle.digest("SHA-256", uint8Input);
|
|
||||||
return Array.from(new window.Uint8Array(digest))
|
|
||||||
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
||||||
.join("");
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue