pronounDB: Update to API v2 (#2355)
Co-authored-by: vee <vendicated@riseup.net>
This commit is contained in:
parent
cc5e39c9a9
commit
b22bfc80fd
|
@ -33,7 +33,7 @@ const PRONOUN_TOOLTIP_PATCH = {
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "PronounDB",
|
name: "PronounDB",
|
||||||
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven],
|
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven, Devs.Elvyra],
|
||||||
description: "Adds pronouns to user messages using pronoundb",
|
description: "Adds pronouns to user messages using pronoundb",
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { useAwaiter } from "@utils/react";
|
||||||
import { UserProfileStore, UserStore } from "@webpack/common";
|
import { UserProfileStore, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
import { PronounCode, PronounMapping, PronounsResponse } from "./types";
|
import { CachePronouns, PronounCode, PronounMapping, PronounsResponse } from "./types";
|
||||||
|
|
||||||
type PronounsWithSource = [string | null, string];
|
type PronounsWithSource = [string | null, string];
|
||||||
const EmptyPronouns: PronounsWithSource = [null, ""];
|
const EmptyPronouns: PronounsWithSource = [null, ""];
|
||||||
|
@ -40,9 +40,9 @@ export const enum PronounSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A map of cached pronouns so the same request isn't sent twice
|
// A map of cached pronouns so the same request isn't sent twice
|
||||||
const cache: Record<string, PronounCode> = {};
|
const cache: Record<string, CachePronouns> = {};
|
||||||
// A map of ids and callbacks that should be triggered on fetch
|
// A map of ids and callbacks that should be triggered on fetch
|
||||||
const requestQueue: Record<string, ((pronouns: PronounCode) => void)[]> = {};
|
const requestQueue: Record<string, ((pronouns: string) => void)[]> = {};
|
||||||
|
|
||||||
// Executes all queued requests and calls their callbacks
|
// Executes all queued requests and calls their callbacks
|
||||||
const bulkFetch = debounce(async () => {
|
const bulkFetch = debounce(async () => {
|
||||||
|
@ -50,7 +50,7 @@ const bulkFetch = debounce(async () => {
|
||||||
const pronouns = await bulkFetchPronouns(ids);
|
const pronouns = await bulkFetchPronouns(ids);
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
// Call all callbacks for the id
|
// Call all callbacks for the id
|
||||||
requestQueue[id]?.forEach(c => c(pronouns[id]));
|
requestQueue[id]?.forEach(c => c(pronouns[id] ? extractPronouns(pronouns[id].sets) : ""));
|
||||||
delete requestQueue[id];
|
delete requestQueue[id];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -78,8 +78,8 @@ export function useFormattedPronouns(id: string, useGlobalProfile: boolean = fal
|
||||||
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)
|
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)
|
||||||
return [discordPronouns, "Discord"];
|
return [discordPronouns, "Discord"];
|
||||||
|
|
||||||
if (result && result !== "unspecified")
|
if (result && result !== PronounMapping.unspecified)
|
||||||
return [formatPronouns(result), "PronounDB"];
|
return [result, "PronounDB"];
|
||||||
|
|
||||||
return [discordPronouns, "Discord"];
|
return [discordPronouns, "Discord"];
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,9 @@ const NewLineRe = /\n+/g;
|
||||||
|
|
||||||
// Gets the cached pronouns, if you're too impatient for a promise!
|
// Gets the cached pronouns, if you're too impatient for a promise!
|
||||||
export function getCachedPronouns(id: string): string | null {
|
export function getCachedPronouns(id: string): string | null {
|
||||||
const cached = cache[id];
|
const cached = cache[id] ? extractPronouns(cache[id].sets) : undefined;
|
||||||
if (cached && cached !== "unspecified") return cached;
|
|
||||||
|
if (cached && cached !== PronounMapping.unspecified) return cached;
|
||||||
|
|
||||||
return cached || null;
|
return cached || null;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +126,7 @@ async function bulkFetchPronouns(ids: string[]): Promise<PronounsResponse> {
|
||||||
params.append("ids", ids.join(","));
|
params.append("ids", ids.join(","));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const req = await fetch("https://pronoundb.org/api/v1/lookup-bulk?" + params.toString(), {
|
const req = await fetch("https://pronoundb.org/api/v2/lookup?" + params.toString(), {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Accept": "application/json",
|
"Accept": "application/json",
|
||||||
|
@ -140,21 +141,24 @@ async function bulkFetchPronouns(ids: string[]): Promise<PronounsResponse> {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If the request errors, treat it as if no pronouns were found for all ids, and log it
|
// If the request errors, treat it as if no pronouns were found for all ids, and log it
|
||||||
console.error("PronounDB fetching failed: ", e);
|
console.error("PronounDB fetching failed: ", e);
|
||||||
const dummyPronouns = Object.fromEntries(ids.map(id => [id, "unspecified"] as const));
|
const dummyPronouns = Object.fromEntries(ids.map(id => [id, { sets: {} }] as const));
|
||||||
Object.assign(cache, dummyPronouns);
|
Object.assign(cache, dummyPronouns);
|
||||||
return dummyPronouns;
|
return dummyPronouns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatPronouns(pronouns: string): string {
|
export function extractPronouns(pronounSet?: { [locale: string]: PronounCode[] }): string {
|
||||||
|
if (!pronounSet || !pronounSet.en) return PronounMapping.unspecified;
|
||||||
|
// PronounDB returns an empty set instead of {sets: {en: ["unspecified"]}}.
|
||||||
|
const pronouns = pronounSet.en;
|
||||||
const { pronounsFormat } = Settings.plugins.PronounDB as { pronounsFormat: PronounsFormat, enabled: boolean; };
|
const { pronounsFormat } = Settings.plugins.PronounDB as { pronounsFormat: PronounsFormat, enabled: boolean; };
|
||||||
// For capitalized pronouns, just return the mapping (it is by default capitalized)
|
|
||||||
if (pronounsFormat === PronounsFormat.Capitalized) return PronounMapping[pronouns];
|
if (pronouns.length === 1) {
|
||||||
// If it is set to lowercase and a special code (any, ask, avoid), then just return the capitalized text
|
// For capitalized pronouns or special codes (any, ask, avoid), we always return the normal (capitalized) string
|
||||||
else if (
|
if (pronounsFormat === PronounsFormat.Capitalized || ["any", "ask", "avoid", "other", "unspecified"].includes(pronouns[0]))
|
||||||
pronounsFormat === PronounsFormat.Lowercase
|
return PronounMapping[pronouns[0]];
|
||||||
&& ["any", "ask", "avoid", "other"].includes(pronouns)
|
else return PronounMapping[pronouns[0]].toLowerCase();
|
||||||
) return PronounMapping[pronouns];
|
}
|
||||||
// Otherwise (lowercase and not a special code), then convert the mapping to lowercase
|
const pronounString = pronouns.map(p => p[0].toUpperCase() + p.slice(1)).join("/");
|
||||||
else return PronounMapping[pronouns].toLowerCase();
|
return pronounsFormat === PronounsFormat.Capitalized ? pronounString : pronounString.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,31 +26,29 @@ export interface UserProfilePronounsProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PronounsResponse {
|
export interface PronounsResponse {
|
||||||
[id: string]: PronounCode;
|
[id: string]: {
|
||||||
|
sets?: {
|
||||||
|
[locale: string]: PronounCode[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CachePronouns {
|
||||||
|
sets?: {
|
||||||
|
[locale: string]: PronounCode[];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PronounCode = keyof typeof PronounMapping;
|
export type PronounCode = keyof typeof PronounMapping;
|
||||||
|
|
||||||
export const PronounMapping = {
|
export const PronounMapping = {
|
||||||
hh: "He/Him",
|
he: "He/Him",
|
||||||
hi: "He/It",
|
it: "It/Its",
|
||||||
hs: "He/She",
|
she: "She/Her",
|
||||||
ht: "He/They",
|
they: "They/Them",
|
||||||
ih: "It/Him",
|
|
||||||
ii: "It/Its",
|
|
||||||
is: "It/She",
|
|
||||||
it: "It/They",
|
|
||||||
shh: "She/He",
|
|
||||||
sh: "She/Her",
|
|
||||||
si: "She/It",
|
|
||||||
st: "She/They",
|
|
||||||
th: "They/He",
|
|
||||||
ti: "They/It",
|
|
||||||
ts: "They/She",
|
|
||||||
tt: "They/Them",
|
|
||||||
any: "Any pronouns",
|
any: "Any pronouns",
|
||||||
other: "Other pronouns",
|
other: "Other pronouns",
|
||||||
ask: "Ask me my pronouns",
|
ask: "Ask me my pronouns",
|
||||||
avoid: "Avoid pronouns, use my name",
|
avoid: "Avoid pronouns, use my name",
|
||||||
unspecified: "Unspecified"
|
unspecified: "No pronouns specified.",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
Loading…
Reference in a new issue