Rework PronounDB -> UserMessagesPronouns
This commit is contained in:
parent
4e89352758
commit
58c3032bb2
|
@ -1,172 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a modification for Discord's desktop app
|
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { getCurrentChannel } from "@utils/discord";
|
|
||||||
import { useAwaiter } from "@utils/react";
|
|
||||||
import { findStoreLazy } from "@webpack";
|
|
||||||
import { UserProfileStore, UserStore } from "@webpack/common";
|
|
||||||
|
|
||||||
import { settings } from "./settings";
|
|
||||||
import { PronounMapping, Pronouns, PronounsCache, PronounSets, PronounsFormat, PronounSource, PronounsResponse } from "./types";
|
|
||||||
|
|
||||||
const UserSettingsAccountStore = findStoreLazy("UserSettingsAccountStore");
|
|
||||||
|
|
||||||
const EmptyPronouns = { pronouns: undefined, source: "", hasPendingPronouns: false } as const satisfies Pronouns;
|
|
||||||
|
|
||||||
type RequestCallback = (pronounSets?: PronounSets) => void;
|
|
||||||
|
|
||||||
const pronounCache: Record<string, PronounsCache> = {};
|
|
||||||
const requestQueue: Record<string, RequestCallback[]> = {};
|
|
||||||
let isProcessing = false;
|
|
||||||
|
|
||||||
async function processQueue() {
|
|
||||||
if (isProcessing) return;
|
|
||||||
isProcessing = true;
|
|
||||||
|
|
||||||
let ids = Object.keys(requestQueue);
|
|
||||||
while (ids.length > 0) {
|
|
||||||
const idsChunk = ids.splice(0, 50);
|
|
||||||
const pronouns = await bulkFetchPronouns(idsChunk);
|
|
||||||
|
|
||||||
for (const id of idsChunk) {
|
|
||||||
const callbacks = requestQueue[id];
|
|
||||||
for (const callback of callbacks) {
|
|
||||||
callback(pronouns[id]?.sets);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete requestQueue[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
ids = Object.keys(requestQueue);
|
|
||||||
await new Promise(r => setTimeout(r, 2000));
|
|
||||||
}
|
|
||||||
|
|
||||||
isProcessing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchPronouns(id: string): Promise<string | undefined> {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
if (pronounCache[id] != null) {
|
|
||||||
resolve(extractPronouns(pronounCache[id].sets));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePronouns(pronounSets?: PronounSets) {
|
|
||||||
const pronouns = extractPronouns(pronounSets);
|
|
||||||
resolve(pronouns);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestQueue[id] != null) {
|
|
||||||
requestQueue[id].push(handlePronouns);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestQueue[id] = [handlePronouns];
|
|
||||||
processQueue();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function bulkFetchPronouns(ids: string[]): Promise<PronounsResponse> {
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.append("platform", "discord");
|
|
||||||
params.append("ids", ids.join(","));
|
|
||||||
|
|
||||||
try {
|
|
||||||
const req = await fetch("https://pronoundb.org/api/v2/lookup?" + String(params), {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"Accept": "application/json",
|
|
||||||
"X-PronounDB-Source": "WebExtension/0.14.5"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!req.ok) throw new Error(`Status ${req.status}`);
|
|
||||||
const res: PronounsResponse = await req.json();
|
|
||||||
|
|
||||||
Object.assign(pronounCache, res);
|
|
||||||
return res;
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error("PronounDB request failed:", e);
|
|
||||||
const dummyPronouns: PronounsResponse = Object.fromEntries(ids.map(id => [id, { sets: {} }]));
|
|
||||||
|
|
||||||
Object.assign(pronounCache, dummyPronouns);
|
|
||||||
return dummyPronouns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractPronouns(pronounSets?: PronounSets): string | undefined {
|
|
||||||
if (pronounSets == null) return undefined;
|
|
||||||
if (pronounSets.en == null) return PronounMapping.unspecified;
|
|
||||||
|
|
||||||
const pronouns = pronounSets.en;
|
|
||||||
if (pronouns.length === 0) return PronounMapping.unspecified;
|
|
||||||
|
|
||||||
const { pronounsFormat } = settings.store;
|
|
||||||
|
|
||||||
if (pronouns.length > 1) {
|
|
||||||
const pronounString = pronouns.map(p => p[0].toUpperCase() + p.slice(1)).join("/");
|
|
||||||
return pronounsFormat === PronounsFormat.Capitalized ? pronounString : pronounString.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
const pronoun = pronouns[0];
|
|
||||||
// For capitalized pronouns or special codes (any, ask, avoid), we always return the normal (capitalized) string
|
|
||||||
if (pronounsFormat === PronounsFormat.Capitalized || ["any", "ask", "avoid", "other", "unspecified"].includes(pronoun)) {
|
|
||||||
return PronounMapping[pronoun];
|
|
||||||
} else {
|
|
||||||
return PronounMapping[pronoun].toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDiscordPronouns(id: string, useGlobalProfile: boolean = false): string | undefined {
|
|
||||||
const globalPronouns = UserProfileStore.getUserProfile(id)?.pronouns;
|
|
||||||
if (useGlobalProfile) return globalPronouns;
|
|
||||||
|
|
||||||
return UserProfileStore.getGuildMemberProfile(id, getCurrentChannel()?.guild_id)?.pronouns || globalPronouns;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useFormattedPronouns(id: string, useGlobalProfile: boolean = false): Pronouns {
|
|
||||||
const discordPronouns = getDiscordPronouns(id, useGlobalProfile)?.trim().replace(/\n+/g, "");
|
|
||||||
const hasPendingPronouns = UserSettingsAccountStore.getPendingPronouns() != null;
|
|
||||||
|
|
||||||
const [pronouns] = useAwaiter(() => fetchPronouns(id));
|
|
||||||
|
|
||||||
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns) {
|
|
||||||
return { pronouns: discordPronouns, source: "Discord", hasPendingPronouns };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pronouns != null && pronouns !== PronounMapping.unspecified) {
|
|
||||||
return { pronouns, source: "PronounDB", hasPendingPronouns };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { pronouns: discordPronouns, source: "Discord", hasPendingPronouns };
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useProfilePronouns(id: string, useGlobalProfile: boolean = false): Pronouns {
|
|
||||||
try {
|
|
||||||
const pronouns = useFormattedPronouns(id, useGlobalProfile);
|
|
||||||
|
|
||||||
if (!settings.store.showInProfile) return EmptyPronouns;
|
|
||||||
if (!settings.store.showSelf && id === UserStore.getCurrentUser()?.id) return EmptyPronouns;
|
|
||||||
|
|
||||||
return pronouns;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
return EmptyPronouns;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a modification for Discord's desktop app
|
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Link } from "@components/Link";
|
|
||||||
import { Forms, React } from "@webpack/common";
|
|
||||||
|
|
||||||
export default function PronounsAboutComponent() {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Forms.FormTitle tag="h3">More Information</Forms.FormTitle>
|
|
||||||
<Forms.FormText>To add your own pronouns, visit{" "}
|
|
||||||
<Link href="https://pronoundb.org">pronoundb.org</Link>
|
|
||||||
</Forms.FormText>
|
|
||||||
<Forms.FormDivider />
|
|
||||||
<Forms.FormText>
|
|
||||||
The two pronoun formats are lowercase and capitalized. Example:
|
|
||||||
<ul>
|
|
||||||
<li>Lowercase: they/them</li>
|
|
||||||
<li>Capitalized: They/Them</li>
|
|
||||||
</ul>
|
|
||||||
Text like "Ask me my pronouns" or "Any pronouns" will always be capitalized. <br /><br />
|
|
||||||
You can also configure whether or not to display pronouns for the current user (since you probably already know them)
|
|
||||||
</Forms.FormText>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a modification for Discord's desktop app
|
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import "./styles.css";
|
|
||||||
|
|
||||||
import { Devs } from "@utils/constants";
|
|
||||||
import definePlugin from "@utils/types";
|
|
||||||
|
|
||||||
import { useProfilePronouns } from "./api";
|
|
||||||
import PronounsAboutComponent from "./components/PronounsAboutComponent";
|
|
||||||
import { CompactPronounsChatComponentWrapper, PronounsChatComponentWrapper } from "./components/PronounsChatComponent";
|
|
||||||
import { settings } from "./settings";
|
|
||||||
|
|
||||||
export default definePlugin({
|
|
||||||
name: "PronounDB",
|
|
||||||
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven, Devs.Elvyra],
|
|
||||||
description: "Adds pronouns to user messages using pronoundb",
|
|
||||||
patches: [
|
|
||||||
{
|
|
||||||
find: "showCommunicationDisabledStyles",
|
|
||||||
replacement: [
|
|
||||||
// Add next to username (compact mode)
|
|
||||||
{
|
|
||||||
match: /("span",{id:\i,className:\i,children:\i}\))/,
|
|
||||||
replace: "$1, $self.CompactPronounsChatComponentWrapper(arguments[0])"
|
|
||||||
},
|
|
||||||
// Patch the chat timestamp element (normal mode)
|
|
||||||
{
|
|
||||||
match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/,
|
|
||||||
replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
find: ".Messages.USER_PROFILE_PRONOUNS",
|
|
||||||
group: true,
|
|
||||||
replacement: [
|
|
||||||
{
|
|
||||||
match: /\.PANEL},/,
|
|
||||||
replace: "$&{pronouns:vcPronoun,source:vcPronounSource,hasPendingPronouns:vcHasPendingPronouns}=$self.useProfilePronouns(arguments[0].user?.id),"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
match: /text:\i\.\i.Messages.USER_PROFILE_PRONOUNS/,
|
|
||||||
replace: '$&+(vcPronoun==null||vcHasPendingPronouns?"":` (${vcPronounSource})`)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
match: /(\.pronounsText.+?children:)(\i)/,
|
|
||||||
replace: "$1(vcPronoun==null||vcHasPendingPronouns)?$2:vcPronoun"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
settings,
|
|
||||||
|
|
||||||
settingsAboutComponent: PronounsAboutComponent,
|
|
||||||
|
|
||||||
// Re-export the components on the plugin object so it is easily accessible in patches
|
|
||||||
PronounsChatComponentWrapper,
|
|
||||||
CompactPronounsChatComponentWrapper,
|
|
||||||
useProfilePronouns
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
.vc-pronoundb-compact {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
[class*="compact"] .vc-pronoundb-compact {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: -2px;
|
|
||||||
margin-right: 0.25rem;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a modification for Discord's desktop app
|
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface UserProfileProps {
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserProfilePronounsProps {
|
|
||||||
currentPronouns: string | null;
|
|
||||||
hidePersonalInformation: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PronounSets = Record<string, PronounCode[]>;
|
|
||||||
export type PronounsResponse = Record<string, { sets?: PronounSets; }>;
|
|
||||||
|
|
||||||
export interface PronounsCache {
|
|
||||||
sets?: PronounSets;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PronounMapping = {
|
|
||||||
he: "He/Him",
|
|
||||||
it: "It/Its",
|
|
||||||
she: "She/Her",
|
|
||||||
they: "They/Them",
|
|
||||||
any: "Any pronouns",
|
|
||||||
other: "Other pronouns",
|
|
||||||
ask: "Ask me my pronouns",
|
|
||||||
avoid: "Avoid pronouns, use my name",
|
|
||||||
unspecified: "No pronouns specified.",
|
|
||||||
} as const satisfies Record<string, string>;
|
|
||||||
|
|
||||||
export type PronounCode = keyof typeof PronounMapping;
|
|
||||||
|
|
||||||
export interface Pronouns {
|
|
||||||
pronouns?: string;
|
|
||||||
source: string;
|
|
||||||
hasPendingPronouns: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum PronounsFormat {
|
|
||||||
Lowercase = "LOWERCASE",
|
|
||||||
Capitalized = "CAPITALIZED"
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum PronounSource {
|
|
||||||
PreferPDB,
|
|
||||||
PreferDiscord
|
|
||||||
}
|
|
|
@ -16,22 +16,22 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { UserStore } from "@webpack/common";
|
import { i18n, Tooltip, UserStore } from "@webpack/common";
|
||||||
import { Message } from "discord-types/general";
|
import { Message } from "discord-types/general";
|
||||||
|
|
||||||
import { useFormattedPronouns } from "../api";
|
import { settings } from "./settings";
|
||||||
import { settings } from "../settings";
|
import { useFormattedPronouns } from "./utils";
|
||||||
|
|
||||||
const styles: Record<string, string> = findByPropsLazy("timestampInline");
|
const styles: Record<string, string> = findByPropsLazy("timestampInline");
|
||||||
|
const MessageDisplayCompact = getUserSettingLazy("textAndImages", "messageDisplayCompact")!;
|
||||||
|
|
||||||
const AUTO_MODERATION_ACTION = 24;
|
const AUTO_MODERATION_ACTION = 24;
|
||||||
|
|
||||||
function shouldShow(message: Message): boolean {
|
function shouldShow(message: Message): boolean {
|
||||||
if (!settings.store.showInMessages)
|
|
||||||
return false;
|
|
||||||
if (message.author.bot || message.author.system || message.type === AUTO_MODERATION_ACTION)
|
if (message.author.bot || message.author.system || message.type === AUTO_MODERATION_ACTION)
|
||||||
return false;
|
return false;
|
||||||
if (!settings.store.showSelf && message.author.id === UserStore.getCurrentUser().id)
|
if (!settings.store.showSelf && message.author.id === UserStore.getCurrentUser().id)
|
||||||
|
@ -40,6 +40,21 @@ function shouldShow(message: Message): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function PronounsChatComponent({ message }: { message: Message; }) {
|
||||||
|
const pronouns = useFormattedPronouns(message.author.id);
|
||||||
|
|
||||||
|
return pronouns && (
|
||||||
|
<Tooltip text={i18n.Messages.USER_PROFILE_PRONOUNS}>
|
||||||
|
{tooltipProps => (
|
||||||
|
<span
|
||||||
|
{...tooltipProps}
|
||||||
|
className={classes(styles.timestampInline, styles.timestamp)}
|
||||||
|
>• {pronouns}</span>
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const PronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
export const PronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
||||||
return shouldShow(message)
|
return shouldShow(message)
|
||||||
? <PronounsChatComponent message={message} />
|
? <PronounsChatComponent message={message} />
|
||||||
|
@ -47,27 +62,11 @@ export const PronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { m
|
||||||
}, { noop: true });
|
}, { noop: true });
|
||||||
|
|
||||||
export const CompactPronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
export const CompactPronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
||||||
return shouldShow(message)
|
const compact = MessageDisplayCompact.useSetting();
|
||||||
? <CompactPronounsChatComponent message={message} />
|
|
||||||
: null;
|
|
||||||
}, { noop: true });
|
|
||||||
|
|
||||||
function PronounsChatComponent({ message }: { message: Message; }) {
|
if (!compact || !shouldShow(message)) {
|
||||||
const { pronouns } = useFormattedPronouns(message.author.id);
|
return null;
|
||||||
|
|
||||||
return pronouns && (
|
|
||||||
<span
|
|
||||||
className={classes(styles.timestampInline, styles.timestamp)}
|
|
||||||
>• {pronouns}</span>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CompactPronounsChatComponent = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
return <PronounsChatComponent message={message} />;
|
||||||
const { pronouns } = useFormattedPronouns(message.author.id);
|
|
||||||
|
|
||||||
return pronouns && (
|
|
||||||
<span
|
|
||||||
className={classes(styles.timestampInline, styles.timestamp, "vc-pronoundb-compact")}
|
|
||||||
>• {pronouns}</span>
|
|
||||||
);
|
|
||||||
}, { noop: true });
|
}, { noop: true });
|
5
src/plugins/userMessagesPronouns/README.md
Normal file
5
src/plugins/userMessagesPronouns/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
User Messages Pronouns
|
||||||
|
|
||||||
|
Adds pronouns to chat user messages
|
||||||
|
|
||||||
|
![](https://github.com/user-attachments/assets/34dc373d-faf4-4420-b49b-08b2647baa3b)
|
54
src/plugins/userMessagesPronouns/index.ts
Normal file
54
src/plugins/userMessagesPronouns/index.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2022 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { migratePluginSettings } from "@api/Settings";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
|
import { CompactPronounsChatComponentWrapper, PronounsChatComponentWrapper } from "./PronounsChatComponent";
|
||||||
|
import { settings } from "./settings";
|
||||||
|
|
||||||
|
migratePluginSettings("UserMessagesPronouns", "PronounDB");
|
||||||
|
export default definePlugin({
|
||||||
|
name: "UserMessagesPronouns",
|
||||||
|
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven, Devs.Elvyra],
|
||||||
|
description: "Adds pronouns to chat user messages",
|
||||||
|
settings,
|
||||||
|
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: "showCommunicationDisabledStyles",
|
||||||
|
replacement: {
|
||||||
|
// Add next to timestamp (normal mode)
|
||||||
|
match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/,
|
||||||
|
replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: '="SYSTEM_TAG"',
|
||||||
|
replacement: {
|
||||||
|
// Add next to username (compact mode)
|
||||||
|
match: /className:\i\(\)\(\i\.className(?:,\i\.clickable)?,\i\)}\),(?=\i)/g,
|
||||||
|
replace: "$&$self.CompactPronounsChatComponentWrapper(arguments[0]),"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
PronounsChatComponentWrapper,
|
||||||
|
CompactPronounsChatComponentWrapper,
|
||||||
|
});
|
|
@ -19,7 +19,10 @@
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { OptionType } from "@utils/types";
|
import { OptionType } from "@utils/types";
|
||||||
|
|
||||||
import { PronounsFormat, PronounSource } from "./types";
|
export const enum PronounsFormat {
|
||||||
|
Lowercase = "LOWERCASE",
|
||||||
|
Capitalized = "CAPITALIZED"
|
||||||
|
}
|
||||||
|
|
||||||
export const settings = definePluginSettings({
|
export const settings = definePluginSettings({
|
||||||
pronounsFormat: {
|
pronounsFormat: {
|
||||||
|
@ -37,34 +40,9 @@ export const settings = definePluginSettings({
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
pronounSource: {
|
|
||||||
type: OptionType.SELECT,
|
|
||||||
description: "Where to source pronouns from",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: "Prefer PronounDB, fall back to Discord",
|
|
||||||
value: PronounSource.PreferPDB,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Prefer Discord, fall back to PronounDB (might lead to inconsistency between pronouns in chat and profile)",
|
|
||||||
value: PronounSource.PreferDiscord
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
showSelf: {
|
showSelf: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Enable or disable showing pronouns for the current user",
|
description: "Enable or disable showing pronouns for yourself",
|
||||||
default: true
|
|
||||||
},
|
|
||||||
showInMessages: {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
description: "Show in messages",
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
showInProfile: {
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
description: "Show in profile",
|
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
});
|
});
|
35
src/plugins/userMessagesPronouns/utils.ts
Normal file
35
src/plugins/userMessagesPronouns/utils.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2022 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getCurrentChannel } from "@utils/discord";
|
||||||
|
import { UserProfileStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
|
import { PronounsFormat, settings } from "./settings";
|
||||||
|
|
||||||
|
function useDiscordPronouns(id: string, useGlobalProfile: boolean = false): string | undefined {
|
||||||
|
const globalPronouns: string | undefined = useStateFromStores([UserProfileStore], () => UserProfileStore.getUserProfile(id)?.pronouns);
|
||||||
|
const guildPronouns: string | undefined = useStateFromStores([UserProfileStore], () => UserProfileStore.getGuildMemberProfile(id, getCurrentChannel()?.getGuildId())?.pronouns);
|
||||||
|
|
||||||
|
if (useGlobalProfile) return globalPronouns;
|
||||||
|
return guildPronouns || globalPronouns;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useFormattedPronouns(id: string, useGlobalProfile: boolean = false) {
|
||||||
|
const pronouns = useDiscordPronouns(id, useGlobalProfile)?.trim().replace(/\n+/g, "");
|
||||||
|
return settings.store.pronounsFormat === PronounsFormat.Lowercase ? pronouns?.toLowerCase() : pronouns;
|
||||||
|
}
|
Loading…
Reference in a new issue