From e4a1f93817d5f065c334e70d003c5d585cde9e49 Mon Sep 17 00:00:00 2001 From: outmaneuver <72673084+outmaneuver@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:38:15 +0300 Subject: [PATCH] Fix pronouns loading without clicking on profile Fixes #2967 Implement a caching mechanism for pronouns to load them without the need to click on the user's profile. * **Caching Mechanism**: - Implement caching using `DataStore` in `src/plugins/userMessagesPronouns/utils.ts`. - Add functions to get, set, and fetch pronouns with caching. - Modify `useDiscordPronouns` to check the cache before fetching pronouns. - Export `fetchAndCachePronouns` function. * **PronounsChatComponent**: - Update `PronounsChatComponent` in `src/plugins/userMessagesPronouns/PronounsChatComponent.tsx` to use cached pronouns if available. * **Message Events**: - Add logic in `src/plugins/userMessagesPronouns/index.ts` to fetch and cache pronouns when a user sends a message. - Add export for `MessageEvents` in `src/api/MessageEvents.ts`. --- .devcontainer.json | 7 ++++ _tmp_4127_1bd18adbaf507b266b21cde17e1e7412 | 0 src/api/MessageEvents.ts | 2 + src/plugins/userMessagesPronouns/index.ts | 9 +++++ src/plugins/userMessagesPronouns/utils.ts | 47 ++++++++++++++++++---- 5 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 .devcontainer.json create mode 100644 _tmp_4127_1bd18adbaf507b266b21cde17e1e7412 diff --git a/.devcontainer.json b/.devcontainer.json new file mode 100644 index 00000000000..4c1bf722179 --- /dev/null +++ b/.devcontainer.json @@ -0,0 +1,7 @@ +{ + "tasks": { + "test": "pnpm install && pnpm test", + "build": "pnpm install --frozen-lockfile && pnpm build", + "launch": "pnpm install && pnpm dev" + } +} \ No newline at end of file diff --git a/_tmp_4127_1bd18adbaf507b266b21cde17e1e7412 b/_tmp_4127_1bd18adbaf507b266b21cde17e1e7412 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/api/MessageEvents.ts b/src/api/MessageEvents.ts index d6eba748f48..634b52f6967 100644 --- a/src/api/MessageEvents.ts +++ b/src/api/MessageEvents.ts @@ -155,3 +155,5 @@ export function addClickListener(listener: ClickListener) { export function removeClickListener(listener: ClickListener) { return listeners.delete(listener); } + +export { addPreSendListener as MessageEvents }; diff --git a/src/plugins/userMessagesPronouns/index.ts b/src/plugins/userMessagesPronouns/index.ts index 27b162b90d8..83e3ac0015f 100644 --- a/src/plugins/userMessagesPronouns/index.ts +++ b/src/plugins/userMessagesPronouns/index.ts @@ -19,6 +19,8 @@ import { migratePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; +import { MessageEvents } from "@api/MessageEvents"; +import { fetchAndCachePronouns } from "./utils"; import { CompactPronounsChatComponentWrapper, PronounsChatComponentWrapper } from "./PronounsChatComponent"; import { settings } from "./settings"; @@ -51,4 +53,11 @@ export default definePlugin({ PronounsChatComponentWrapper, CompactPronounsChatComponentWrapper, + + onStart() { + MessageEvents.addPreSendListener(async (channelId, messageObj, extra) => { + const userId = messageObj.author.id; + await fetchAndCachePronouns(userId); + }); + } }); diff --git a/src/plugins/userMessagesPronouns/utils.ts b/src/plugins/userMessagesPronouns/utils.ts index 18a22772119..147f7cbd67f 100644 --- a/src/plugins/userMessagesPronouns/utils.ts +++ b/src/plugins/userMessagesPronouns/utils.ts @@ -17,19 +17,50 @@ */ import { getCurrentChannel } from "@utils/discord"; -import { UserProfileStore, useStateFromStores } from "@webpack/common"; +import { UserProfileStore } from "@webpack/common"; +import * as DataStore from "@api/DataStore"; 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); +const PRONOUNS_CACHE_KEY = "pronounsCache"; - if (useGlobalProfile) return globalPronouns; - return guildPronouns || globalPronouns; +async function getCachedPronouns(id: string): Promise { + const cache = await DataStore.get>(PRONOUNS_CACHE_KEY) || {}; + const entry = cache[id]; + if (entry && (Date.now() - entry.timestamp) < 24 * 60 * 60 * 1000) { // 24 hours cache expiry + return entry.pronouns; + } + return undefined; } -export function useFormattedPronouns(id: string, useGlobalProfile: boolean = false) { - const pronouns = useDiscordPronouns(id, useGlobalProfile)?.trim().replace(/\n+/g, ""); +async function setCachedPronouns(id: string, pronouns: string): Promise { + const cache = await DataStore.get>(PRONOUNS_CACHE_KEY) || {}; + cache[id] = { pronouns, timestamp: Date.now() }; + await DataStore.set(PRONOUNS_CACHE_KEY, cache); +} + +async function fetchAndCachePronouns(id: string, useGlobalProfile: boolean = false): Promise { + const globalPronouns: string | undefined = UserProfileStore.getUserProfile(id)?.pronouns; + const guildPronouns: string | undefined = UserProfileStore.getGuildMemberProfile(id, getCurrentChannel()?.getGuildId())?.pronouns; + + const pronouns = useGlobalProfile ? globalPronouns : guildPronouns || globalPronouns; + if (pronouns) { + await setCachedPronouns(id, pronouns); + } + return pronouns; +} + +async function useDiscordPronouns(id: string, useGlobalProfile: boolean = false): Promise { + const cachedPronouns = await getCachedPronouns(id); + if (cachedPronouns) { + return cachedPronouns; + } + return await fetchAndCachePronouns(id, useGlobalProfile); +} + +export async function useFormattedPronouns(id: string, useGlobalProfile: boolean = false): Promise { + const pronouns = (await useDiscordPronouns(id, useGlobalProfile))?.trim().replace(/\n+/g, ""); return settings.store.pronounsFormat === PronounsFormat.Lowercase ? pronouns?.toLowerCase() : pronouns; } + +export { fetchAndCachePronouns };