This commit is contained in:
vishnyanetchereshnya 2024-06-21 13:17:25 +03:00 committed by GitHub
parent 8c26c493f0
commit e4fa9320d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 42 additions and 72 deletions

View file

@ -8,7 +8,7 @@ import { classNameFactory } from "@api/Styles";
import { LazyComponent } from "@utils/lazyReact";
import { Button, Popout, React, Text, useState } from "@webpack/common";
import { cacheUsers, getNotes, getRunning, setupStates, stopCacheProcess, usersCache } from "../data";
import { allChunksCached, cacheUsers, getNotes, getRunning, setupStates, stopCacheProcess, usersCache } from "../data";
import { CrossIcon, ProblemIcon, SuccessIcon } from "./Icons";
import { LoadingSpinner } from "./LoadingSpinner";
@ -83,13 +83,11 @@ export default LazyComponent(() => React.memo(() => {
{
cacheStatus >= notesLength ? "Users are cached 👍"
: cacheStatus === 0 ? "Users aren't cached 😔"
: `${cacheStatus}/${notesLength}`
: allChunksCached ? `Not all users are cached due to no mutual guilds ${cacheStatus}/${notesLength}`
: `${cacheStatus}/${notesLength}`
}
</div>
</div>
<Text className={cl("cache-warning")} variant="text-md/normal">
Please note that during this process Discord may not properly load some content, such as messages, images or user profiles
</Text>
<Text className={cl("cache-footer")} variant="text-md/normal">
You can turn on caching of all users on startup in plugin settings
</Text>

View file

@ -54,8 +54,8 @@ export function NotesDataModal({ modalProps, close }: {
const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));
const [usersNotesData, refreshNotesData] = useReducer(() => {
return Object.entries(getNotes());
}, Object.entries(getNotes()));
return Object.entries(getNotes()).map(([userId, { note }]) => [userId, note]) as [string, string][];
}, Object.entries(getNotes()).map(([userId, { note }]) => [userId, note]) as [string, string][]);
RefreshNotesDataEx = refreshNotesData;

View file

@ -8,7 +8,7 @@ import { classNameFactory } from "@api/Styles";
import { openPrivateChannel, openUserProfile } from "@utils/discord";
import { copyWithToast } from "@utils/misc";
import { LazyComponent, useAwaiter } from "@utils/react";
import { Alerts, Avatar, Button, ContextMenuApi, Menu, React, Text, TextArea, Tooltip, UserUtils, useState } from "@webpack/common";
import { Alerts, Avatar, Button, ContextMenuApi, Menu, React, Text, TextArea, Tooltip, UserStore, UserUtils, useState } from "@webpack/common";
import { updateNote, usersCache } from "../data";
import { DeleteIcon, PopupIcon, RefreshIcon, SaveIcon } from "./Icons";
@ -29,7 +29,7 @@ export default LazyComponent(() => React.memo(({ userId, userNotes: userNotesArg
refreshNotesData(): void;
}) => {
const awaitedResult = useAwaiter(async () => {
const user = await UserUtils.getUser(userId);
const user = UserStore.getUser(userId) || await UserUtils.getUser(userId);
usersCache.set(userId, {
globalName: (user as any).globalName ?? user.username,
@ -50,7 +50,7 @@ export default LazyComponent(() => React.memo(({ userId, userNotes: userNotesArg
userInfo ??= {
id: userId,
globalName: pending ? "Loading..." : "Unable to load",
username: pending ? "Loading..." : "Unable to load",
username: pending ? "Loading..." : "No mutual guilds",
avatar: "https://discord.com/assets/0048cbfdd0b3ef186d22.png",
} as const;

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, UserUtils, useState } from "@webpack/common";
import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, useState } from "@webpack/common";
import { waitForStore } from "webpack/common/internal";
import { refreshNotesData } from "./components/NotesDataModal";
@ -35,20 +35,6 @@ export const usersCache = new Map<string, {
username: string;
}>();
const fetchUser = async (userId: string) => {
for (let _ = 0; _ < 10; _++) {
try {
return await UserUtils.getUser(userId);
} catch (error: any) {
const wait = error?.body?.retry_after;
if (!wait) break;
await new Promise(resolve => setTimeout(resolve, wait * 1000 + 50));
}
}
};
type Dispatch = ReturnType<typeof useState<any>>[1];
const states: {
@ -83,8 +69,11 @@ const stop = () => {
cacheProcessNeedStop = false;
isRunning = false;
states.setRunning?.(false);
states.setCacheStatus?.(usersCache.size);
};
export let allChunksCached = false;
export const cacheUsers = async (onlyMissing = false) => {
isRunning = true;
states.setRunning?.(true);
@ -109,7 +98,6 @@ export const cacheUsers = async (onlyMissing = false) => {
if (usersCache.size >= Object.keys(getNotes()).length) {
stop();
states.setCacheStatus?.(usersCache.size);
return;
}
@ -141,38 +129,17 @@ export const cacheUsers = async (onlyMissing = false) => {
processed.add(member.user.id);
usersCache.set(member.id, {
usersCache.set(member.user.id, {
globalName: (member as any).globalName,
username: member.username,
});
states.setCacheStatus?.(usersCache.size);
});
states.setCacheStatus?.(usersCache.size);
if (--count === 0) {
const userIds = Object.keys(getNotes());
if (usersCache.size !== userIds.length) {
for (const userId of userIds) {
if (cacheProcessNeedStop) {
stop();
FluxDispatcher.unsubscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
break;
}
const user = await fetchUser(userId);
if (user) {
usersCache.set(user.id, {
globalName: (user as any).globalName,
username: user.username,
});
states.setCacheStatus?.(usersCache.size);
}
}
}
console.log(usersCache.size);
allChunksCached = true;
stop();
FluxDispatcher.unsubscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
}

View file

@ -15,7 +15,7 @@ import { OpenNotesDataButton } from "./components/NotesDataButton";
import { getNotes, onNoteUpdate } from "./data";
import { Notes } from "./noteStore";
import settings from "./settings";
export default definePlugin({
name: "NotesSearcher",
description: "Allows you to open a modal with all of your notes and search through them by user ID, note text, and username",
@ -88,14 +88,21 @@ export default definePlugin({
FluxDispatcher.unsubscribe("USER_NOTE_UPDATE", onNoteUpdate);
},
ready: ({ notes }: { notes: Notes; }) => {
ready: ({ notes }: { notes: { [userId: string]: string; }; }) => {
const notesFromStore = getNotes();
for (const userId of Object.keys(notesFromStore)) {
delete notesFromStore[userId];
}
Object.assign(notesFromStore, notes);
Object.assign(notesFromStore, Object.entries(notes).reduce((newNotes, [userId, note]) => {
newNotes[userId] = {
note,
loading: false,
};
return newNotes;
}, {} as Notes));
},
addToolBarButton: (children: { toolbar: React.ReactNode[] | React.ReactNode; }) => {

View file

@ -4,11 +4,18 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { FluxStore } from "@webpack/types";
export type Notes = { [userId: string]: string; };
export class NoteStore extends FluxStore {
getNotes(): Notes;
getNote(userId: string): string | null;
import { FluxStore } from "@webpack/types";
export type Note = {
loading: boolean;
note: string;
};
export type Notes = {
[userId: string]: Note;
};
export class NoteStore extends FluxStore {
getNotes(): Notes;
getNote(userId: string): Note;
}

View file

@ -249,14 +249,6 @@ div:has(.vc-notes-searcher-modal-user-text-area) {
margin-bottom: 12px;
}
.vc-notes-searcher-modal-cache-warning {
margin-top: 12px;
border-radius: 4px;
background-color: #e7828430;
border: 1px solid #e78284;
padding: 8px;
}
.vc-notes-searcher-modal-cache-footer {
margin-top: 12px;
border-radius: 4px;
@ -284,8 +276,7 @@ div:has(.vc-notes-searcher-modal-user-text-area) {
display: grid;
align-items: center;
color: var(--text-normal);
font-size: 20px;
line-height: 24px;
font-size: 16px;
text-align: center;
padding: 0 12px;
}