Skip to content

Commit

Permalink
Fix pronouns loading without clicking on profile
Browse files Browse the repository at this point in the history
Fixes Vendicated#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`.
  • Loading branch information
outmaneuver committed Oct 23, 2024
1 parent e620431 commit e4a1f93
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 8 deletions.
7 changes: 7 additions & 0 deletions .devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"tasks": {
"test": "pnpm install && pnpm test",
"build": "pnpm install --frozen-lockfile && pnpm build",
"launch": "pnpm install && pnpm dev"
}
}
Empty file.
2 changes: 2 additions & 0 deletions src/api/MessageEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,5 @@ export function addClickListener(listener: ClickListener) {
export function removeClickListener(listener: ClickListener) {
return listeners.delete(listener);
}

export { addPreSendListener as MessageEvents };
9 changes: 9 additions & 0 deletions src/plugins/userMessagesPronouns/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -51,4 +53,11 @@ export default definePlugin({

PronounsChatComponentWrapper,
CompactPronounsChatComponentWrapper,

onStart() {
MessageEvents.addPreSendListener(async (channelId, messageObj, extra) => {
const userId = messageObj.author.id;
await fetchAndCachePronouns(userId);
});
}
});
47 changes: 39 additions & 8 deletions src/plugins/userMessagesPronouns/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string | undefined> {
const cache = await DataStore.get<Record<string, { pronouns: string, timestamp: number }>>(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<void> {
const cache = await DataStore.get<Record<string, { pronouns: string, timestamp: number }>>(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<string | undefined> {
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<string | undefined> {
const cachedPronouns = await getCachedPronouns(id);
if (cachedPronouns) {
return cachedPronouns;
}
return await fetchAndCachePronouns(id, useGlobalProfile);
}

export async function useFormattedPronouns(id: string, useGlobalProfile: boolean = false): Promise<string | undefined> {
const pronouns = (await useDiscordPronouns(id, useGlobalProfile))?.trim().replace(/\n+/g, "");
return settings.store.pronounsFormat === PronounsFormat.Lowercase ? pronouns?.toLowerCase() : pronouns;
}

export { fetchAndCachePronouns };

0 comments on commit e4a1f93

Please sign in to comment.