-
+
{({ onMouseLeave, onMouseEnter }) => (
{
updateNote(userId, userNotes);
refreshNotesData();
@@ -157,10 +188,11 @@ export default LazyComponent(() => React.memo(({ userId, userNotes: userNotesArg
className={cl("user-actions-delete")}
size={Button.Sizes.NONE}
color={Button.Colors.RED}
+ style={{ width: "32px", height: "32px" }}
onClick={() => {
Alerts.show({
title: "Delete Notes",
- body: `Are you sure you want to delete notes for ${pending ? userId : `${userInfo!.globalName} (${userId})`}?`,
+ body: `Are you sure you want to delete notes for ${pending ? userId : `${userCache!.globalName} (${userId})`}?`,
confirmColor: Button.Colors.RED,
confirmText: "Delete",
cancelText: "Cancel",
@@ -183,6 +215,7 @@ export default LazyComponent(() => React.memo(({ userId, userNotes: userNotesArg
className={cl("user-actions-refresh")}
size={Button.Sizes.NONE}
color={Button.Colors.LINK}
+ style={{ width: "32px", height: "32px" }}
onClick={() => setUserNotes(userNotesArg)}
onMouseLeave={onMouseLeave}
onMouseEnter={onMouseEnter}
@@ -197,6 +230,7 @@ export default LazyComponent(() => React.memo(({ userId, userNotes: userNotesArg
className={cl("user-actions-popup")}
size={Button.Sizes.NONE}
color={Button.Colors.PRIMARY}
+ style={{ width: "32px", height: "32px" }}
onClick={async () => {
openUserProfile(userId);
}}
@@ -211,4 +245,4 @@ export default LazyComponent(() => React.memo(({ userId, userNotes: userNotesArg
);
-}));
+};
diff --git a/src/plugins/notesSearcher/data.ts b/src/plugins/notesSearcher/data.ts
index 396171e12..0811b0b2f 100644
--- a/src/plugins/notesSearcher/data.ts
+++ b/src/plugins/notesSearcher/data.ts
@@ -4,11 +4,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, useState } from "@webpack/common";
+import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, UserUtils } from "@webpack/common";
import { waitForStore } from "webpack/common/internal";
-import { refreshNotesData } from "./components/NotesDataModal";
-import * as t from "./noteStore";
+import { refreshNotesData, refreshUsersCache } from "./components/NotesDataModal";
+import * as t from "./types";
let NoteStore: t.NoteStore;
@@ -25,71 +25,55 @@ export const onNoteUpdate = () => {
export const updateNote = (userId: string, note: string | null) => {
RestAPI.put({
url: Constants.Endpoints.NOTE(userId),
- body: { note },
+ body: { note: note !== "" ? note : null },
oldFormErrors: true
});
};
-export const usersCache = new Map
();
+export const usersCache: t.UsersCache = new Map();
-type Dispatch = ReturnType>[1];
+export const onUserUpdate = ({ user }: { user: t.User; }) => {
+ if (!getNotes()[user.id]) return;
-const states: {
- setRunning?: Dispatch;
- setCacheStatus?: Dispatch,
-} = {};
+ // doesn't have .getAvatarURL
+ const userFromStore = UserStore.getUser(user.id);
-export const setupStates = ({
- setRunning,
- setCacheStatus,
-}: {
- setRunning: Dispatch,
- setCacheStatus: Dispatch,
-}) => {
- states.setRunning = setRunning;
- states.setCacheStatus = setCacheStatus;
+ if (!userFromStore) return;
+
+ cacheUser(userFromStore);
};
-let isRunning = false;
+const fetchUser = async (userId: string) => {
+ for (let _ = 0; _ < 5; _++) {
+ try {
+ return await UserUtils.getUser(userId);
+ } catch (error: any) {
+ const wait = error?.body?.retry_after;
-export const getRunning = () => {
- return isRunning;
+ if (!wait) return;
+
+ await new Promise(resolve => setTimeout(resolve, wait * 1000 + 100));
+ }
+ }
};
-let cacheProcessNeedStop = false;
-
-export const stopCacheProcess = () => {
- cacheProcessNeedStop = true;
+const cacheUser = (user: t.User) => {
+ usersCache.set(user.id, {
+ id: user.id,
+ globalName: user.globalName ?? user.username,
+ username: user.username,
+ avatar: user.getAvatarURL(void 0, void 0, false),
+ });
};
-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);
-
- onlyMissing || usersCache.clear();
-
+export const cacheUsers = async () => {
const toRequest: string[] = [];
for (const userId of Object.keys(getNotes())) {
const user = UserStore.getUser(userId);
if (user) {
- usersCache.set(user.id, {
- globalName: (user as any).globalName,
- username: user.username,
- });
+ cacheUser(user);
continue;
}
@@ -97,12 +81,9 @@ export const cacheUsers = async (onlyMissing = false) => {
}
if (usersCache.size >= Object.keys(getNotes()).length) {
- stop();
return;
}
- states.setCacheStatus?.(usersCache.size);
-
const sentNonce = SnowflakeUtils.fromTimestamp(Date.now());
const allGuildIds = Object.keys(GuildStore.getGuilds());
@@ -112,35 +93,49 @@ export const cacheUsers = async (onlyMissing = false) => {
const callback = async ({ chunks }) => {
for (const chunk of chunks) {
- if (cacheProcessNeedStop) {
- stop();
- FluxDispatcher.unsubscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
- break;
- }
-
- const { nonce, members } = chunk;
+ const { nonce, members }: {
+ nonce: string;
+ members: {
+ user: t.User;
+ }[];
+ } = chunk;
if (nonce !== sentNonce) {
return;
}
- members.forEach(member => {
- if (processed.has(member.user.id)) return;
+ members.forEach(({ user }) => {
+ if (processed.has(user.id)) return;
- processed.add(member.user.id);
+ processed.add(user.id);
- usersCache.set(member.user.id, {
- globalName: (member as any).globalName,
- username: member.username,
- });
+ cacheUser(UserStore.getUser(user.id));
});
- states.setCacheStatus?.(usersCache.size);
+ refreshUsersCache();
if (--count === 0) {
- allChunksCached = true;
- stop();
FluxDispatcher.unsubscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
+
+ const userIds = Object.keys(getNotes());
+
+ if (usersCache.size !== userIds.length) {
+
+ for (const userId of userIds) {
+ if (usersCache.has(userId)) continue;
+
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ const user = await fetchUser(userId);
+
+ if (user) {
+ cacheUser(user);
+ refreshUsersCache();
+ }
+ }
+
+ } else
+ refreshUsersCache();
}
}
};
diff --git a/src/plugins/notesSearcher/index.tsx b/src/plugins/notesSearcher/index.tsx
index dec79248d..6f7b33a11 100644
--- a/src/plugins/notesSearcher/index.tsx
+++ b/src/plugins/notesSearcher/index.tsx
@@ -12,9 +12,9 @@ import definePlugin from "@utils/types";
import { FluxDispatcher } from "@webpack/common";
import { OpenNotesDataButton } from "./components/NotesDataButton";
-import { getNotes, onNoteUpdate } from "./data";
-import { Notes } from "./noteStore";
-import settings from "./settings";
+import { getNotes, onNoteUpdate, onUserUpdate } from "./data";
+import settings from "./settings";
+import { Notes } from "./types";
export default definePlugin({
name: "NotesSearcher",
@@ -83,9 +83,11 @@ export default definePlugin({
start: async () => {
FluxDispatcher.subscribe("USER_NOTE_UPDATE", onNoteUpdate);
+ FluxDispatcher.subscribe("USER_UPDATE", onUserUpdate);
},
stop: () => {
FluxDispatcher.unsubscribe("USER_NOTE_UPDATE", onNoteUpdate);
+ FluxDispatcher.unsubscribe("USER_UPDATE", onUserUpdate);
},
ready: ({ notes }: { notes: { [userId: string]: string; }; }) => {
diff --git a/src/plugins/notesSearcher/styles.css b/src/plugins/notesSearcher/styles.css
index 4f4d905df..ba66200f1 100644
--- a/src/plugins/notesSearcher/styles.css
+++ b/src/plugins/notesSearcher/styles.css
@@ -1,18 +1,7 @@
-/* Part of Cache Popout Data. css linter is awesome */
-.vc-notes-searcher-modal-cache-status svg,
-.vc-notes-searcher-modal-cache-status div,
-.vc-notes-searcher-modal-cache-status div span,
-.vc-notes-searcher-modal-cache-status div span::after {
- width: 40px;
- height: 40px;
-}
-
-/* Open "Notes Data" toolbox button */
.vc-notes-searcher-toolbox-button svg {
color: var(--interactive-normal);
}
-/* Part of Notes Modal Data. css linter is awesome */
.vc-notes-searcher-modal-user-actions * svg {
width: 32px !important;
height: 32px !important;
@@ -23,7 +12,6 @@
color: var(--interactive-active);
}
-/* Notes Data Modal */
.vc-notes-searcher-modal-root {
min-height: 75vh;
max-height: 75vh;
@@ -31,33 +19,11 @@
max-width: 70vw;
}
-.vc-notes-searcher-modal-header-text {
- white-space: nowrap;
- width: fit-content;
- margin-right: 16px;
-}
-
.vc-notes-searcher-modal-header-input {
width: 100%;
margin-right: 16px;
}
-.vc-notes-searcher-modal-header-user-type {
- min-width: 160px;
- margin-right: 16px;
-}
-
-.vc-notes-searcher-modal-header-cache {
- width: fit-content;
- height: 100%;
- margin-right: 16px;
-}
-
-.vc-notes-searcher-modal-content-container {
- overflow: hidden;
- height: 100%;
-}
-
.vc-notes-searcher-modal-content {
padding-bottom: 16px;
height: 100%;
@@ -67,44 +33,10 @@
display: none;
}
-.vc-notes-searcher-modal-content-inner {
- padding-top: 16px;
- height: fit-content;
-}
-
-.vc-notes-searcher-modal-user-actions * {
- width: 32px;
- height: 32px;
-}
-
.vc-notes-searcher-modal-content-inner > *:not(:last-child) {
margin-bottom: 8px;
}
-.vc-notes-searcher-modal-load-more {
- margin-top: 16px;
- width: 100%;
- height: 32px;
-}
-
-.vc-notes-searcher-modal-no-notes {
- display: grid;
- place-content: center;
- height: 100%;
-}
-
-.vc-notes-searcher-modal-user {
- width: 100%;
- height: 80px;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- background-color: var(--background-secondary);
- border-radius: 12px;
- box-sizing: border-box;
-}
-
.vc-notes-searcher-modal-user:hover:not(
:has(
.vc-notes-searcher-modal-user-text-area:hover,
@@ -119,40 +51,6 @@
margin: 12px;
}
-.vc-notes-searcher-modal-user-info {
- min-width: 50px;
- max-width: 275px;
- width: 100%;
-}
-
-.vc-notes-searcher-modal-user-info > div {
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
-}
-
-.vc-notes-searcher-modal-user-info-globalname {
- color: #fff;
-}
-
-.vc-notes-searcher-modal-user-info-username {
- color: #d3d3d3;
-}
-
-.vc-notes-searcher-modal-user-info-id {
- color: #989898;
-}
-
-.vc-notes-searcher-modal-user-notes-container {
- display: grid;
- grid-template-columns: calc(100% - 86px) min-content;
- align-items: center;
- justify-content: flex-end;
- flex-grow: 1;
- padding-right: 8px;
- gap: 8px;
-}
-
.vc-notes-searcher-modal-user-actions * div:has(svg) {
width: 32px !important;
height: 32px !important;
@@ -170,35 +68,6 @@ div:has(.vc-notes-searcher-modal-user-text-area) {
height: 100%;
}
-.vc-notes-searcher-modal-user-actions {
- display: grid;
- grid-template-columns: auto auto;
- grid-template-rows: auto auto;
- gap: 3px;
- aspect-ratio: 1 / 1;
- height: auto;
- box-sizing: border-box;
- overflow: visible !important;
-}
-
-/* Loading Spinner */
-.vc-notes-searcher-modal-spinner-container {
- width: 56px;
- height: 56px;
- margin: 12px;
-}
-
-.vc-notes-searcher-modal-spinner {
- width: 56px;
- height: 56px;
- border: 5px solid #fff;
- border-radius: 50%;
- display: inline-block;
- box-sizing: border-box;
- position: relative;
- animation: vc-notes-searcher-pulse 1s linear infinite;
-}
-
.vc-notes-searcher-modal-spinner::after {
content: "";
position: absolute;
@@ -236,51 +105,3 @@ div:has(.vc-notes-searcher-modal-user-text-area) {
transform: scale(1.1);
}
}
-
-.vc-notes-searcher-modal-cache-container {
- width: 25vw;
- background-color: var(--modal-background);
- border-radius: 4px;
- padding: 12px;
- box-shadow: var(--legacy-elevation-border), var(--legacy-elevation-high);
-}
-
-.vc-notes-searcher-modal-cache-header {
- margin-bottom: 12px;
-}
-
-.vc-notes-searcher-modal-cache-footer {
- margin-top: 12px;
- border-radius: 4px;
- background-color: #00ff404a;
- border: 1px solid #2fd334;
- padding: 8px;
-}
-
-.vc-notes-searcher-modal-cache-container > div:nth-child(2) {
- display: grid;
- grid-template-columns: min-content auto;
-}
-
-.vc-notes-searcher-modal-cache-buttons {
- width: fit-content;
- display: grid;
- row-gap: 6px;
-}
-
-.vc-notes-searcher-modal-cache-buttons > button {
- height: 32px;
-}
-
-.vc-notes-searcher-modal-cache-status {
- display: grid;
- align-items: center;
- color: var(--text-normal);
- font-size: 16px;
- text-align: center;
- padding: 0 12px;
-}
-
-.vc-notes-searcher-modal-cache-status :nth-child(1) {
- margin: 0 auto;
-}
diff --git a/src/plugins/notesSearcher/types.d.ts b/src/plugins/notesSearcher/types.d.ts
new file mode 100644
index 000000000..4506b0d34
--- /dev/null
+++ b/src/plugins/notesSearcher/types.d.ts
@@ -0,0 +1,37 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { FluxStore } from "@webpack/types";
+import { User as User$1 } from "discord-types/general";
+
+export type Note = {
+ loading: boolean;
+ note: string;
+};
+
+export type Notes = {
+ [userId: string]: Note;
+};
+
+export class NoteStore extends FluxStore {
+ getNotes(): Notes;
+ getNote(userId: string): Note;
+}
+
+export type User = User$1 & {
+ globalName?: string;
+};
+
+export type Dispatch = ReturnType>[1];
+
+export type UserCache = {
+ id: string;
+ globalName?: string;
+ username: string;
+ avatar: string;
+};
+
+export type UsersCache = Map;
From 71e3a5cc99175b3f3fd904aee248a3fc7fd343c0 Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Mon, 24 Jun 2024 22:05:11 +0300
Subject: [PATCH 14/27] Delete
src/plugins/notesSearcher/components/CachePopout.tsx
---
.../notesSearcher/components/CachePopout.tsx | 110 ------------------
1 file changed, 110 deletions(-)
delete mode 100644 src/plugins/notesSearcher/components/CachePopout.tsx
diff --git a/src/plugins/notesSearcher/components/CachePopout.tsx b/src/plugins/notesSearcher/components/CachePopout.tsx
deleted file mode 100644
index edc158ed9..000000000
--- a/src/plugins/notesSearcher/components/CachePopout.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { classNameFactory } from "@api/Styles";
-import { LazyComponent } from "@utils/lazyReact";
-import { Button, Popout, React, Text, useState } from "@webpack/common";
-
-import { allChunksCached, cacheUsers, getNotes, getRunning, setupStates, stopCacheProcess, usersCache } from "../data";
-import { CrossIcon, ProblemIcon, SuccessIcon } from "./Icons";
-import { LoadingSpinner } from "./LoadingSpinner";
-
-const cl = classNameFactory("vc-notes-searcher-modal-");
-
-export default LazyComponent(() => React.memo(() => {
- const [shouldShow, setShouldShow] = useState(false);
-
- return (
- setShouldShow(false)}
- renderPopout={() => {
- const [isRunning, setRunning] = useState(getRunning);
- const [cacheStatus, setCacheStatus] = useState(usersCache.size);
-
- setupStates({
- setRunning,
- setCacheStatus,
- });
-
- const notesLength = Object.keys(getNotes()).length;
-
- return
-
- Fetch the profile of all users to filter notes by global name or username
-
-
-
- cacheUsers()}
- >
- {
- cacheStatus === 10 ? "Cache Users" : "Re-Cache Users"
- }
-
- = notesLength}
- onClick={() => cacheUsers(true)}
- >
- Cache Missing Users
-
- {
- stopCacheProcess();
- }}
- >
- Stop
-
-
-
- {
- isRunning ?
- : cacheStatus >= notesLength ?
- : cacheStatus === 0 ?
- :
- }
- {
- cacheStatus >= notesLength ? "Users are cached 👍"
- : cacheStatus === 0 ? "Users aren't cached 😔"
- : allChunksCached ? `Not all users are cached due to no mutual guilds ${cacheStatus}/${notesLength}`
- : `${cacheStatus}/${notesLength}`
- }
-
-
-
- You can turn on caching of all users on startup in plugin settings
-
-
;
- }}
- >
- {
- (_, { isShown }) =>
- setShouldShow(!isShown)}
- >
- Cache
-
- }
-
- );
-}));
From fec2638fd5881ead26a253aa54e945582c1a440f Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Mon, 24 Jun 2024 22:45:31 +0300
Subject: [PATCH 15/27] Delete src/plugins/notesSearcher/noteStore.d.ts
---
src/plugins/notesSearcher/noteStore.d.ts | 21 ---------------------
1 file changed, 21 deletions(-)
delete mode 100644 src/plugins/notesSearcher/noteStore.d.ts
diff --git a/src/plugins/notesSearcher/noteStore.d.ts b/src/plugins/notesSearcher/noteStore.d.ts
deleted file mode 100644
index 3be94904d..000000000
--- a/src/plugins/notesSearcher/noteStore.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-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;
-}
From 381dd6e43809750e8f34f3cfcd5527f2040fec60 Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Tue, 9 Jul 2024 05:19:15 +0300
Subject: [PATCH 16/27] Update index.tsx
---
src/plugins/notesSearcher/index.tsx | 55 ++++++++++++++---------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/src/plugins/notesSearcher/index.tsx b/src/plugins/notesSearcher/index.tsx
index 6f7b33a11..7710f9e79 100644
--- a/src/plugins/notesSearcher/index.tsx
+++ b/src/plugins/notesSearcher/index.tsx
@@ -1,19 +1,19 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import "./styles.css";
-
-import ErrorBoundary from "@components/ErrorBoundary";
-import { Devs } from "@utils/constants";
-import definePlugin from "@utils/types";
-import { FluxDispatcher } from "@webpack/common";
-
-import { OpenNotesDataButton } from "./components/NotesDataButton";
-import { getNotes, onNoteUpdate, onUserUpdate } from "./data";
-import settings from "./settings";
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import "./styles.css";
+
+import ErrorBoundary from "@components/ErrorBoundary";
+import { Devs } from "@utils/constants";
+import definePlugin from "@utils/types";
+import { FluxDispatcher } from "@webpack/common";
+
+import { OpenNotesDataButton } from "./components/NotesDataButton";
+import { getNotes, onNoteUpdate, onUserUpdate } from "./data";
+import settings from "./settings";
import { Notes } from "./types";
export default definePlugin({
@@ -31,18 +31,17 @@ export default definePlugin({
},
{
find: '="NoteStore",',
- replacement: {
- match: /getNote\(\i\){return (\i)/,
- replace: "getNotes(){return $1}$&",
- },
- },
- // not sure it won't break anything but should be fine
- {
- find: '="NoteStore",',
- replacement: {
- match: /CONNECTION_OPEN:_,OVERLAY_INITIALIZE:_,/,
- replace: "",
- },
+ replacement: [
+ {
+ match: /getNote\(\i\){return (\i)/,
+ replace: "getNotes(){return $1}$&",
+ },
+ // not sure it won't break anything but should be fine
+ {
+ match: /CONNECTION_OPEN:\i,OVERLAY_INITIALIZE:\i,/,
+ replace: "",
+ },
+ ],
},
{
find: ".REQUEST_GUILD_MEMBERS",
From d0db4aa63490fc783e9d0bc05fff9c62aee7e037 Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Tue, 9 Jul 2024 05:20:54 +0300
Subject: [PATCH 17/27] header fix
---
src/plugins/notesSearcher/index.tsx | 248 ++++++++++++++--------------
1 file changed, 124 insertions(+), 124 deletions(-)
diff --git a/src/plugins/notesSearcher/index.tsx b/src/plugins/notesSearcher/index.tsx
index 7710f9e79..64305e492 100644
--- a/src/plugins/notesSearcher/index.tsx
+++ b/src/plugins/notesSearcher/index.tsx
@@ -1,124 +1,124 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import "./styles.css";
-
-import ErrorBoundary from "@components/ErrorBoundary";
-import { Devs } from "@utils/constants";
-import definePlugin from "@utils/types";
-import { FluxDispatcher } from "@webpack/common";
-
-import { OpenNotesDataButton } from "./components/NotesDataButton";
-import { getNotes, onNoteUpdate, onUserUpdate } from "./data";
-import settings from "./settings";
-import { Notes } from "./types";
-
-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",
- authors: [Devs.Vishnya],
- settings,
- patches: [
- {
- find: "toolbar:function",
- replacement: {
- match: /(function \i\(\i\){)(.{1,200}toolbar.{1,100}mobileToolbar)/,
- replace: "$1$self.addToolBarButton(arguments[0]);$2",
- },
- },
- {
- find: '="NoteStore",',
- replacement: [
- {
- match: /getNote\(\i\){return (\i)/,
- replace: "getNotes(){return $1}$&",
- },
- // not sure it won't break anything but should be fine
- {
- match: /CONNECTION_OPEN:\i,OVERLAY_INITIALIZE:\i,/,
- replace: "",
- },
- ],
- },
- {
- find: ".REQUEST_GUILD_MEMBERS",
- replacement: {
- match: /\.send\(8,{(?!nonce)/,
- replace: "$&nonce:arguments[1].nonce,",
- },
- },
- {
- find: "GUILD_MEMBERS_REQUEST:",
- replacement: {
- match: /presences:!!(\i)\.presences(?!,nonce)/,
- replace: "$&,nonce:$1.nonce",
- },
- },
- {
- find: ".not_found",
- replacement: {
- match: /notFound:(\i)\.not_found(?!,nonce)/,
- replace: "$&,nonce:$1.nonce",
- },
- },
- {
- find: "[IDENTIFY]",
- replacement: {
- match: /capabilities:(\i\.\i),/,
- replace: "capabilities:$1&~1,",
- },
- },
- {
- find: "_handleDispatch",
- replacement: {
- match: /let \i=(\i).session_id;/,
- replace: "$&$self.ready($1);",
- },
- },
- ],
-
- start: async () => {
- FluxDispatcher.subscribe("USER_NOTE_UPDATE", onNoteUpdate);
- FluxDispatcher.subscribe("USER_UPDATE", onUserUpdate);
- },
- stop: () => {
- FluxDispatcher.unsubscribe("USER_NOTE_UPDATE", onNoteUpdate);
- FluxDispatcher.unsubscribe("USER_UPDATE", onUserUpdate);
- },
-
- ready: ({ notes }: { notes: { [userId: string]: string; }; }) => {
- const notesFromStore = getNotes();
-
- for (const userId of Object.keys(notesFromStore)) {
- delete notesFromStore[userId];
- }
-
- 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; }) => {
- if (Array.isArray(children.toolbar))
- return children.toolbar.push(
-
-
-
- );
-
- children.toolbar = [
-
-
- ,
- children.toolbar,
- ];
- },
-});
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import "./styles.css";
+
+import ErrorBoundary from "@components/ErrorBoundary";
+import { Devs } from "@utils/constants";
+import definePlugin from "@utils/types";
+import { FluxDispatcher } from "@webpack/common";
+
+import { OpenNotesDataButton } from "./components/NotesDataButton";
+import { getNotes, onNoteUpdate, onUserUpdate } from "./data";
+import settings from "./settings";
+import { Notes } from "./types";
+
+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",
+ authors: [Devs.Vishnya],
+ settings,
+ patches: [
+ {
+ find: "toolbar:function",
+ replacement: {
+ match: /(function \i\(\i\){)(.{1,200}toolbar.{1,100}mobileToolbar)/,
+ replace: "$1$self.addToolBarButton(arguments[0]);$2",
+ },
+ },
+ {
+ find: '="NoteStore",',
+ replacement: [
+ {
+ match: /getNote\(\i\){return (\i)/,
+ replace: "getNotes(){return $1}$&",
+ },
+ // not sure it won't break anything but should be fine
+ {
+ match: /CONNECTION_OPEN:\i,OVERLAY_INITIALIZE:\i,/,
+ replace: "",
+ },
+ ],
+ },
+ {
+ find: ".REQUEST_GUILD_MEMBERS",
+ replacement: {
+ match: /\.send\(8,{(?!nonce)/,
+ replace: "$&nonce:arguments[1].nonce,",
+ },
+ },
+ {
+ find: "GUILD_MEMBERS_REQUEST:",
+ replacement: {
+ match: /presences:!!(\i)\.presences(?!,nonce)/,
+ replace: "$&,nonce:$1.nonce",
+ },
+ },
+ {
+ find: ".not_found",
+ replacement: {
+ match: /notFound:(\i)\.not_found(?!,nonce)/,
+ replace: "$&,nonce:$1.nonce",
+ },
+ },
+ {
+ find: "[IDENTIFY]",
+ replacement: {
+ match: /capabilities:(\i\.\i),/,
+ replace: "capabilities:$1&~1,",
+ },
+ },
+ {
+ find: "_handleDispatch",
+ replacement: {
+ match: /let \i=(\i).session_id;/,
+ replace: "$&$self.ready($1);",
+ },
+ },
+ ],
+
+ start: async () => {
+ FluxDispatcher.subscribe("USER_NOTE_UPDATE", onNoteUpdate);
+ FluxDispatcher.subscribe("USER_UPDATE", onUserUpdate);
+ },
+ stop: () => {
+ FluxDispatcher.unsubscribe("USER_NOTE_UPDATE", onNoteUpdate);
+ FluxDispatcher.unsubscribe("USER_UPDATE", onUserUpdate);
+ },
+
+ ready: ({ notes }: { notes: { [userId: string]: string; }; }) => {
+ const notesFromStore = getNotes();
+
+ for (const userId of Object.keys(notesFromStore)) {
+ delete notesFromStore[userId];
+ }
+
+ 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; }) => {
+ if (Array.isArray(children.toolbar))
+ return children.toolbar.push(
+
+
+
+ );
+
+ children.toolbar = [
+
+
+ ,
+ children.toolbar,
+ ];
+ },
+});
From 7bb0bc47007ca3ec44534fc5b6eacfe5c70f77d6 Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Fri, 12 Jul 2024 07:42:38 +0300
Subject: [PATCH 18/27] Update
src/plugins/notesSearcher/components/NotesDataRow.tsx
Co-authored-by: dolfies
---
.../notesSearcher/components/NotesDataRow.tsx | 30 +++++++++----------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataRow.tsx b/src/plugins/notesSearcher/components/NotesDataRow.tsx
index e10e73600..69f7d983c 100644
--- a/src/plugins/notesSearcher/components/NotesDataRow.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataRow.tsx
@@ -1,17 +1,17 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { classNameFactory } from "@api/Styles";
-import { openPrivateChannel, openUserProfile } from "@utils/discord";
-import { copyWithToast } from "@utils/misc";
-import { Alerts, Avatar, Button, ContextMenuApi, Menu, React, Text, TextArea, Tooltip, useState } from "@webpack/common";
-
-import { updateNote } from "../data";
-import { UsersCache } from "../types";
-import { DeleteIcon, PopupIcon, RefreshIcon, SaveIcon } from "./Icons";
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { classNameFactory } from "@api/Styles";
+import { openPrivateChannel, openUserProfile } from "@utils/discord";
+import { copyWithToast } from "@utils/misc";
+import { Alerts, Avatar, Button, ContextMenuApi, Menu, React, Text, TextArea, Tooltip, useState } from "@webpack/common";
+
+import { updateNote } from "../data";
+import { UsersCache } from "../types";
+import { DeleteIcon, PopupIcon, RefreshIcon, SaveIcon } from "./Icons";
import { LoadingSpinner } from "./LoadingSpinner";
const cl = classNameFactory("vc-notes-searcher-modal-");
@@ -30,7 +30,7 @@ export default ({ userId, userNotes: userNotesArg, refreshNotesData, usersCache
id: userId,
globalName: "Loading...",
username: "Loading...",
- avatar: "https://discord.com/assets/0048cbfdd0b3ef186d22.png",
+ avatar: "https://cdn.discordapp.com/embed/avatars/4.png",
};
const [userNotes, setUserNotes] = useState(userNotesArg);
From f866808e233a94f00a8f7bd4d5eb303c389786b2 Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Fri, 12 Jul 2024 07:43:10 +0300
Subject: [PATCH 19/27] Update src/plugins/notesSearcher/data.ts
Co-authored-by: dolfies
---
src/plugins/notesSearcher/data.ts | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/plugins/notesSearcher/data.ts b/src/plugins/notesSearcher/data.ts
index 0811b0b2f..33c680c2e 100644
--- a/src/plugins/notesSearcher/data.ts
+++ b/src/plugins/notesSearcher/data.ts
@@ -1,13 +1,13 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, UserUtils } from "@webpack/common";
-import { waitForStore } from "webpack/common/internal";
-
-import { refreshNotesData, refreshUsersCache } from "./components/NotesDataModal";
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, UserUtils } from "@webpack/common";
+import { waitForStore } from "webpack/common/internal";
+
+import { refreshNotesData, refreshUsersCache } from "./components/NotesDataModal";
import * as t from "./types";
let NoteStore: t.NoteStore;
@@ -25,7 +25,7 @@ export const onNoteUpdate = () => {
export const updateNote = (userId: string, note: string | null) => {
RestAPI.put({
url: Constants.Endpoints.NOTE(userId),
- body: { note: note !== "" ? note : null },
+ body: { note: note },
oldFormErrors: true
});
};
From 4fae539fa4717caed37e3a23f74cd5c9560625fe Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Fri, 12 Jul 2024 07:47:48 +0300
Subject: [PATCH 20/27] Update
src/plugins/notesSearcher/components/NotesDataModal.tsx
Co-authored-by: dolfies
---
.../components/NotesDataModal.tsx | 26 +++++++++----------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataModal.tsx b/src/plugins/notesSearcher/components/NotesDataModal.tsx
index 96cc25142..b2cc47f9a 100644
--- a/src/plugins/notesSearcher/components/NotesDataModal.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataModal.tsx
@@ -1,17 +1,17 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { classNameFactory } from "@api/Styles";
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { classNameFactory } from "@api/Styles";
import {
closeModal, ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, openModal
-} from "@utils/modal";
-import { LazyComponent } from "@utils/react";
-import { Button, React, RelationshipStore, Select, Text, TextInput, useCallback, useMemo, useReducer, useState } from "@webpack/common";
-
-import { cacheUsers, getNotes, usersCache as usersCache$1 } from "../data";
+} from "@utils/modal";
+import { LazyComponent } from "@utils/react";
+import { Button, React, RelationshipStore, Select, Text, TextInput, useCallback, useMemo, useReducer, useState } from "@webpack/common";
+
+import { cacheUsers, getNotes, usersCache as usersCache$1 } from "../data";
import NotesDataRow from "./NotesDataRow";
const cl = classNameFactory("vc-notes-searcher-modal-");
@@ -98,7 +98,7 @@ export function NotesDataModal({ modalProps, close }: {
return (
- Notes Data
+ User Notes
Date: Fri, 12 Jul 2024 07:49:40 +0300
Subject: [PATCH 21/27] Update
src/plugins/notesSearcher/components/NotesDataModal.tsx
Co-authored-by: dolfies
---
src/plugins/notesSearcher/components/NotesDataModal.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataModal.tsx b/src/plugins/notesSearcher/components/NotesDataModal.tsx
index b2cc47f9a..bd2104fe0 100644
--- a/src/plugins/notesSearcher/components/NotesDataModal.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataModal.tsx
@@ -99,7 +99,7 @@ export function NotesDataModal({ modalProps, close }: {
User Notes
-
+
Date: Fri, 12 Jul 2024 07:51:37 +0300
Subject: [PATCH 22/27] Update
src/plugins/notesSearcher/components/NotesDataRow.tsx
Co-authored-by: dolfies
---
src/plugins/notesSearcher/components/NotesDataRow.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataRow.tsx b/src/plugins/notesSearcher/components/NotesDataRow.tsx
index 69f7d983c..90dfb73a9 100644
--- a/src/plugins/notesSearcher/components/NotesDataRow.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataRow.tsx
@@ -95,7 +95,7 @@ export default ({ userId, userNotes: userNotesArg, refreshNotesData, usersCache
}
copyWithToast(userNotes)}
/>
From 16d349e6eda8de99a9275ecd3987a3e5ce4ee2de Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Fri, 12 Jul 2024 07:51:45 +0300
Subject: [PATCH 23/27] Update
src/plugins/notesSearcher/components/NotesDataRow.tsx
Co-authored-by: dolfies
---
src/plugins/notesSearcher/components/NotesDataRow.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataRow.tsx b/src/plugins/notesSearcher/components/NotesDataRow.tsx
index 90dfb73a9..9f7e52561 100644
--- a/src/plugins/notesSearcher/components/NotesDataRow.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataRow.tsx
@@ -77,7 +77,7 @@ export default ({ userId, userNotes: userNotesArg, refreshNotesData, usersCache
<>
copyWithToast(userCache!.globalName ?? userCache!.username)}
/>
Date: Fri, 12 Jul 2024 07:51:59 +0300
Subject: [PATCH 24/27] Update
src/plugins/notesSearcher/components/NotesDataButton.tsx
Co-authored-by: dolfies
---
.../components/NotesDataButton.tsx | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataButton.tsx b/src/plugins/notesSearcher/components/NotesDataButton.tsx
index 42c8e62d9..de638c412 100644
--- a/src/plugins/notesSearcher/components/NotesDataButton.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataButton.tsx
@@ -1,14 +1,14 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { LazyComponent } from "@utils/react";
-import { findExportedComponentLazy } from "@webpack";
-import { React } from "@webpack/common";
-
-import { NotesDataIcon } from "./Icons";
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { LazyComponent } from "@utils/react";
+import { findExportedComponentLazy } from "@webpack";
+import { React } from "@webpack/common";
+
+import { NotesDataIcon } from "./Icons";
import { openNotesDataModal } from "./NotesDataModal";
const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider");
@@ -18,7 +18,7 @@ export const OpenNotesDataButton = LazyComponent(() => React.memo(() => {
openNotesDataModal()}
- tooltip={"Open Notes Data"}
+ tooltip={"View Notes"}
icon={NotesDataIcon}
/>
);
From b0daabdf71d48944280338c1a33dd0dbec1422ae Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Fri, 12 Jul 2024 08:00:52 +0300
Subject: [PATCH 25/27] apply css only only if plugin enabled
---
src/plugins/notesSearcher/index.tsx | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/plugins/notesSearcher/index.tsx b/src/plugins/notesSearcher/index.tsx
index 64305e492..947001d28 100644
--- a/src/plugins/notesSearcher/index.tsx
+++ b/src/plugins/notesSearcher/index.tsx
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import "./styles.css";
+import { disableStyle, enableStyle } from "@api/Styles";
+import styles from "./styles.css?managed";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
@@ -83,10 +84,14 @@ export default definePlugin({
start: async () => {
FluxDispatcher.subscribe("USER_NOTE_UPDATE", onNoteUpdate);
FluxDispatcher.subscribe("USER_UPDATE", onUserUpdate);
+
+ enableStyle(styles);
},
stop: () => {
FluxDispatcher.unsubscribe("USER_NOTE_UPDATE", onNoteUpdate);
FluxDispatcher.unsubscribe("USER_UPDATE", onUserUpdate);
+
+ disableStyle(styles);
},
ready: ({ notes }: { notes: { [userId: string]: string; }; }) => {
From e41fed63726593ce9ca88a64a372e64985b48c92 Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Fri, 12 Jul 2024 08:06:22 +0300
Subject: [PATCH 26/27] lint fix
---
.../components/NotesDataButton.tsx | 50 +-
.../components/NotesDataModal.tsx | 434 +++++++--------
.../notesSearcher/components/NotesDataRow.tsx | 496 +++++++++---------
src/plugins/notesSearcher/data.ts | 306 +++++------
src/plugins/notesSearcher/index.tsx | 3 +-
src/plugins/notesSearcher/styles.css | 214 ++++----
6 files changed, 751 insertions(+), 752 deletions(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataButton.tsx b/src/plugins/notesSearcher/components/NotesDataButton.tsx
index de638c412..758dd0d8a 100644
--- a/src/plugins/notesSearcher/components/NotesDataButton.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataButton.tsx
@@ -1,25 +1,25 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { LazyComponent } from "@utils/react";
-import { findExportedComponentLazy } from "@webpack";
-import { React } from "@webpack/common";
-
-import { NotesDataIcon } from "./Icons";
-import { openNotesDataModal } from "./NotesDataModal";
-
-const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider");
-
-export const OpenNotesDataButton = LazyComponent(() => React.memo(() => {
- return (
- openNotesDataModal()}
- tooltip={"View Notes"}
- icon={NotesDataIcon}
- />
- );
-}));
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { LazyComponent } from "@utils/react";
+import { findExportedComponentLazy } from "@webpack";
+import { React } from "@webpack/common";
+
+import { NotesDataIcon } from "./Icons";
+import { openNotesDataModal } from "./NotesDataModal";
+
+const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider");
+
+export const OpenNotesDataButton = LazyComponent(() => React.memo(() => {
+ return (
+ openNotesDataModal()}
+ tooltip={"View Notes"}
+ icon={NotesDataIcon}
+ />
+ );
+}));
diff --git a/src/plugins/notesSearcher/components/NotesDataModal.tsx b/src/plugins/notesSearcher/components/NotesDataModal.tsx
index bd2104fe0..0b9561a10 100644
--- a/src/plugins/notesSearcher/components/NotesDataModal.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataModal.tsx
@@ -1,217 +1,217 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { classNameFactory } from "@api/Styles";
-import {
- closeModal, ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, openModal
-} from "@utils/modal";
-import { LazyComponent } from "@utils/react";
-import { Button, React, RelationshipStore, Select, Text, TextInput, useCallback, useMemo, useReducer, useState } from "@webpack/common";
-
-import { cacheUsers, getNotes, usersCache as usersCache$1 } from "../data";
-import NotesDataRow from "./NotesDataRow";
-
-const cl = classNameFactory("vc-notes-searcher-modal-");
-
-const enum SearchStatus {
- ALL,
- FRIENDS,
- BLOCKED,
-}
-
-const filterUser = (query: string, userId: string, userNotes: string) => {
- if (query === "" || userId.includes(query)) return true;
-
- query = query.toLowerCase();
-
- const user = usersCache$1.get(userId);
-
- return user && (
- user.globalName?.toLowerCase().includes(query) || user.username.toLowerCase().includes(query)
- ) || userNotes.toLowerCase().includes(query);
-};
-
-// looks like a shit but I don't know better way to do it
-// P.S. using `getNotes()` as deps for useMemo won't work due to object init outside of component
-let RefreshNotesDataEx: () => void | undefined;
-
-export const refreshNotesData = () => {
- if (!RefreshNotesDataEx) return;
-
- RefreshNotesDataEx();
-};
-
-export function NotesDataModal({ modalProps, close }: {
- modalProps: ModalProps;
- close(): void;
-}) {
- const [searchValue, setSearchValue] = useState({ query: "", status: SearchStatus.ALL });
-
- const onSearch = (query: string) => setSearchValue(prev => ({ ...prev, query }));
- const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));
-
- const [usersNotesData, refreshNotesData] = useReducer(() => {
- return Object.entries(getNotes())
- .map<[string, string]>(([userId, { note }]) => [userId, note])
- .filter((([_, note]) => note !== ""));
- },
- Object.entries(getNotes())
- .map<[string, string]>(([userId, { note }]) => [userId, note])
- .filter((([_, note]) => note !== ""))
- );
-
- RefreshNotesDataEx = refreshNotesData;
-
- const filteredNotes = useMemo(() => {
- const { query, status } = searchValue;
-
- if (query === "" && status === SearchStatus.ALL) {
- return usersNotesData;
- }
-
- return usersNotesData
- .filter(([userId, userNotes]) => {
- switch (status) {
- case SearchStatus.FRIENDS:
- return RelationshipStore.isFriend(userId) && filterUser(query, userId, userNotes);
- case SearchStatus.BLOCKED:
- return RelationshipStore.isBlocked(userId) && filterUser(query, userId, userNotes);
- default:
- return filterUser(query, userId, userNotes);
- }
- });
- }, [usersNotesData, searchValue]);
-
- const [visibleNotesNum, setVisibleNotesNum] = useState(10);
-
- const loadMore = useCallback(() => {
- setVisibleNotesNum(prevNum => prevNum + 10);
- }, []);
-
- const visibleNotes = filteredNotes.slice(0, visibleNotesNum);
-
- const canLoadMore = visibleNotesNum < filteredNotes.length;
-
- return (
-
-
- User Notes
-
-
- v === searchValue.status}
- closeOnSelect={true}
- />
-
-
-
-
- {
- modalProps.transitionState === 1 &&
-
- {
- !visibleNotes.length ? : (
-
- )
- }
-
- }
-
-
- );
-}
-
-// looks like a shit but I don't know better way to do it
-// P.S. using `usersCache` as deps for useMemo won't work due to object init outside of component
-let RefreshUsersCacheEx: () => void | undefined;
-
-export const refreshUsersCache = () => {
- if (!RefreshUsersCacheEx) return;
-
- RefreshUsersCacheEx();
-};
-
-const NotesDataContent = ({ visibleNotes, canLoadMore, loadMore, refreshNotesData }: {
- visibleNotes: [string, string][];
- canLoadMore: boolean;
- loadMore(): void;
- refreshNotesData(): void;
-}) => {
- if (!visibleNotes.length)
- return ;
-
- const [usersCache, refreshUsersCache] = useReducer(() => {
- return new Map(usersCache$1);
- }, usersCache$1);
-
- RefreshUsersCacheEx = refreshUsersCache;
-
- return (
-
- {
- visibleNotes
- .map(([userId, userNotes]) => {
- return (
-
- );
- })
- }
- {
- canLoadMore &&
- loadMore()}
- >
- Load More
-
- }
-
- );
-};
-
-const NoNotes = LazyComponent(() => React.memo(() => (
-
-
- No Notes.
-
-
-)));
-
-let fistTimeOpen = true;
-
-export const openNotesDataModal = async () => {
- if (fistTimeOpen) {
- cacheUsers();
- fistTimeOpen = false;
- }
-
- const key = openModal(modalProps => (
- closeModal(key)}
- />
- ));
-};
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { classNameFactory } from "@api/Styles";
+import {
+ closeModal, ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, openModal
+} from "@utils/modal";
+import { LazyComponent } from "@utils/react";
+import { Button, React, RelationshipStore, Select, Text, TextInput, useCallback, useMemo, useReducer, useState } from "@webpack/common";
+
+import { cacheUsers, getNotes, usersCache as usersCache$1 } from "../data";
+import NotesDataRow from "./NotesDataRow";
+
+const cl = classNameFactory("vc-notes-searcher-modal-");
+
+const enum SearchStatus {
+ ALL,
+ FRIENDS,
+ BLOCKED,
+}
+
+const filterUser = (query: string, userId: string, userNotes: string) => {
+ if (query === "" || userId.includes(query)) return true;
+
+ query = query.toLowerCase();
+
+ const user = usersCache$1.get(userId);
+
+ return user && (
+ user.globalName?.toLowerCase().includes(query) || user.username.toLowerCase().includes(query)
+ ) || userNotes.toLowerCase().includes(query);
+};
+
+// looks like a shit but I don't know better way to do it
+// P.S. using `getNotes()` as deps for useMemo won't work due to object init outside of component
+let RefreshNotesDataEx: () => void | undefined;
+
+export const refreshNotesData = () => {
+ if (!RefreshNotesDataEx) return;
+
+ RefreshNotesDataEx();
+};
+
+export function NotesDataModal({ modalProps, close }: {
+ modalProps: ModalProps;
+ close(): void;
+}) {
+ const [searchValue, setSearchValue] = useState({ query: "", status: SearchStatus.ALL });
+
+ const onSearch = (query: string) => setSearchValue(prev => ({ ...prev, query }));
+ const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));
+
+ const [usersNotesData, refreshNotesData] = useReducer(() => {
+ return Object.entries(getNotes())
+ .map<[string, string]>(([userId, { note }]) => [userId, note])
+ .filter((([_, note]) => note !== ""));
+ },
+ Object.entries(getNotes())
+ .map<[string, string]>(([userId, { note }]) => [userId, note])
+ .filter((([_, note]) => note !== ""))
+ );
+
+ RefreshNotesDataEx = refreshNotesData;
+
+ const filteredNotes = useMemo(() => {
+ const { query, status } = searchValue;
+
+ if (query === "" && status === SearchStatus.ALL) {
+ return usersNotesData;
+ }
+
+ return usersNotesData
+ .filter(([userId, userNotes]) => {
+ switch (status) {
+ case SearchStatus.FRIENDS:
+ return RelationshipStore.isFriend(userId) && filterUser(query, userId, userNotes);
+ case SearchStatus.BLOCKED:
+ return RelationshipStore.isBlocked(userId) && filterUser(query, userId, userNotes);
+ default:
+ return filterUser(query, userId, userNotes);
+ }
+ });
+ }, [usersNotesData, searchValue]);
+
+ const [visibleNotesNum, setVisibleNotesNum] = useState(10);
+
+ const loadMore = useCallback(() => {
+ setVisibleNotesNum(prevNum => prevNum + 10);
+ }, []);
+
+ const visibleNotes = filteredNotes.slice(0, visibleNotesNum);
+
+ const canLoadMore = visibleNotesNum < filteredNotes.length;
+
+ return (
+
+
+ User Notes
+
+
+ v === searchValue.status}
+ closeOnSelect={true}
+ />
+
+
+
+
+ {
+ modalProps.transitionState === 1 &&
+
+ {
+ !visibleNotes.length ? : (
+
+ )
+ }
+
+ }
+
+
+ );
+}
+
+// looks like a shit but I don't know better way to do it
+// P.S. using `usersCache` as deps for useMemo won't work due to object init outside of component
+let RefreshUsersCacheEx: () => void | undefined;
+
+export const refreshUsersCache = () => {
+ if (!RefreshUsersCacheEx) return;
+
+ RefreshUsersCacheEx();
+};
+
+const NotesDataContent = ({ visibleNotes, canLoadMore, loadMore, refreshNotesData }: {
+ visibleNotes: [string, string][];
+ canLoadMore: boolean;
+ loadMore(): void;
+ refreshNotesData(): void;
+}) => {
+ if (!visibleNotes.length)
+ return ;
+
+ const [usersCache, refreshUsersCache] = useReducer(() => {
+ return new Map(usersCache$1);
+ }, usersCache$1);
+
+ RefreshUsersCacheEx = refreshUsersCache;
+
+ return (
+
+ {
+ visibleNotes
+ .map(([userId, userNotes]) => {
+ return (
+
+ );
+ })
+ }
+ {
+ canLoadMore &&
+ loadMore()}
+ >
+ Load More
+
+ }
+
+ );
+};
+
+const NoNotes = LazyComponent(() => React.memo(() => (
+
+
+ No Notes.
+
+
+)));
+
+let fistTimeOpen = true;
+
+export const openNotesDataModal = async () => {
+ if (fistTimeOpen) {
+ cacheUsers();
+ fistTimeOpen = false;
+ }
+
+ const key = openModal(modalProps => (
+ closeModal(key)}
+ />
+ ));
+};
diff --git a/src/plugins/notesSearcher/components/NotesDataRow.tsx b/src/plugins/notesSearcher/components/NotesDataRow.tsx
index 9f7e52561..9271959d0 100644
--- a/src/plugins/notesSearcher/components/NotesDataRow.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataRow.tsx
@@ -1,248 +1,248 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { classNameFactory } from "@api/Styles";
-import { openPrivateChannel, openUserProfile } from "@utils/discord";
-import { copyWithToast } from "@utils/misc";
-import { Alerts, Avatar, Button, ContextMenuApi, Menu, React, Text, TextArea, Tooltip, useState } from "@webpack/common";
-
-import { updateNote } from "../data";
-import { UsersCache } from "../types";
-import { DeleteIcon, PopupIcon, RefreshIcon, SaveIcon } from "./Icons";
-import { LoadingSpinner } from "./LoadingSpinner";
-
-const cl = classNameFactory("vc-notes-searcher-modal-");
-
-export default ({ userId, userNotes: userNotesArg, refreshNotesData, usersCache }: {
- userId: string;
- userNotes: string;
- refreshNotesData(): void;
- usersCache: UsersCache;
-}) => {
- let userCache = usersCache.get(userId);
-
- const pending = !userCache;
-
- userCache ??= {
- id: userId,
- globalName: "Loading...",
- username: "Loading...",
- avatar: "https://cdn.discordapp.com/embed/avatars/4.png",
- };
-
- const [userNotes, setUserNotes] = useState(userNotesArg);
-
- return (
- {
- ContextMenuApi.openContextMenu(event, () =>
-
- openUserProfile(userId)}
- />
- openPrivateChannel(userId)}
- />
- copyWithToast(userCache!.id)}
- />
- {
- !pending &&
- (
- <>
- copyWithToast(userCache!.globalName ?? userCache!.username)}
- />
- copyWithToast(userCache!.username)}
- />
- copyWithToast(userCache!.avatar)}
- />
- >
- )
- }
- copyWithToast(userNotes)}
- />
-
- );
- }}
- >
- {
- pending ?
:
-
- }
-
- {userCache.globalName}
- {userCache.username}
- {userCache.id}
-
-
-
-
-
- {({ onMouseLeave, onMouseEnter }) => (
- {
- updateNote(userId, userNotes);
- refreshNotesData();
- }}
- onMouseLeave={onMouseLeave}
- onMouseEnter={onMouseEnter}
- >
-
-
- )}
-
-
- {({ onMouseLeave, onMouseEnter }) => (
- {
- Alerts.show({
- title: "Delete Notes",
- body: `Are you sure you want to delete notes for ${pending ? userId : `${userCache!.globalName} (${userId})`}?`,
- confirmColor: Button.Colors.RED,
- confirmText: "Delete",
- cancelText: "Cancel",
- onConfirm: () => {
- updateNote(userId, "");
- refreshNotesData();
- },
- });
- }}
- onMouseLeave={onMouseLeave}
- onMouseEnter={onMouseEnter}
- >
-
-
- )}
-
-
- {({ onMouseLeave, onMouseEnter }) => (
- setUserNotes(userNotesArg)}
- onMouseLeave={onMouseLeave}
- onMouseEnter={onMouseEnter}
- >
-
-
- )}
-
-
- {({ onMouseLeave, onMouseEnter }) => (
- {
- openUserProfile(userId);
- }}
- onMouseLeave={onMouseLeave}
- onMouseEnter={onMouseEnter}
- >
-
-
- )}
-
-
-
-
- );
-};
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { classNameFactory } from "@api/Styles";
+import { openPrivateChannel, openUserProfile } from "@utils/discord";
+import { copyWithToast } from "@utils/misc";
+import { Alerts, Avatar, Button, ContextMenuApi, Menu, React, Text, TextArea, Tooltip, useState } from "@webpack/common";
+
+import { updateNote } from "../data";
+import { UsersCache } from "../types";
+import { DeleteIcon, PopupIcon, RefreshIcon, SaveIcon } from "./Icons";
+import { LoadingSpinner } from "./LoadingSpinner";
+
+const cl = classNameFactory("vc-notes-searcher-modal-");
+
+export default ({ userId, userNotes: userNotesArg, refreshNotesData, usersCache }: {
+ userId: string;
+ userNotes: string;
+ refreshNotesData(): void;
+ usersCache: UsersCache;
+}) => {
+ let userCache = usersCache.get(userId);
+
+ const pending = !userCache;
+
+ userCache ??= {
+ id: userId,
+ globalName: "Loading...",
+ username: "Loading...",
+ avatar: "https://cdn.discordapp.com/embed/avatars/4.png",
+ };
+
+ const [userNotes, setUserNotes] = useState(userNotesArg);
+
+ return (
+ {
+ ContextMenuApi.openContextMenu(event, () =>
+
+ openUserProfile(userId)}
+ />
+ openPrivateChannel(userId)}
+ />
+ copyWithToast(userCache!.id)}
+ />
+ {
+ !pending &&
+ (
+ <>
+ copyWithToast(userCache!.globalName ?? userCache!.username)}
+ />
+ copyWithToast(userCache!.username)}
+ />
+ copyWithToast(userCache!.avatar)}
+ />
+ >
+ )
+ }
+ copyWithToast(userNotes)}
+ />
+
+ );
+ }}
+ >
+ {
+ pending ?
:
+
+ }
+
+ {userCache.globalName}
+ {userCache.username}
+ {userCache.id}
+
+
+
+
+
+ {({ onMouseLeave, onMouseEnter }) => (
+ {
+ updateNote(userId, userNotes);
+ refreshNotesData();
+ }}
+ onMouseLeave={onMouseLeave}
+ onMouseEnter={onMouseEnter}
+ >
+
+
+ )}
+
+
+ {({ onMouseLeave, onMouseEnter }) => (
+ {
+ Alerts.show({
+ title: "Delete Notes",
+ body: `Are you sure you want to delete notes for ${pending ? userId : `${userCache!.globalName} (${userId})`}?`,
+ confirmColor: Button.Colors.RED,
+ confirmText: "Delete",
+ cancelText: "Cancel",
+ onConfirm: () => {
+ updateNote(userId, "");
+ refreshNotesData();
+ },
+ });
+ }}
+ onMouseLeave={onMouseLeave}
+ onMouseEnter={onMouseEnter}
+ >
+
+
+ )}
+
+
+ {({ onMouseLeave, onMouseEnter }) => (
+ setUserNotes(userNotesArg)}
+ onMouseLeave={onMouseLeave}
+ onMouseEnter={onMouseEnter}
+ >
+
+
+ )}
+
+
+ {({ onMouseLeave, onMouseEnter }) => (
+ {
+ openUserProfile(userId);
+ }}
+ onMouseLeave={onMouseLeave}
+ onMouseEnter={onMouseEnter}
+ >
+
+
+ )}
+
+
+
+
+ );
+};
diff --git a/src/plugins/notesSearcher/data.ts b/src/plugins/notesSearcher/data.ts
index 33c680c2e..5180989f7 100644
--- a/src/plugins/notesSearcher/data.ts
+++ b/src/plugins/notesSearcher/data.ts
@@ -1,153 +1,153 @@
-/*
- * Vencord, a Discord client mod
- * Copyright (c) 2024 Vendicated and contributors
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, UserUtils } from "@webpack/common";
-import { waitForStore } from "webpack/common/internal";
-
-import { refreshNotesData, refreshUsersCache } from "./components/NotesDataModal";
-import * as t from "./types";
-
-let NoteStore: t.NoteStore;
-
-waitForStore("NoteStore", s => NoteStore = s);
-
-export const getNotes = () => {
- return NoteStore.getNotes();
-};
-
-export const onNoteUpdate = () => {
- refreshNotesData();
-};
-
-export const updateNote = (userId: string, note: string | null) => {
- RestAPI.put({
- url: Constants.Endpoints.NOTE(userId),
- body: { note: note },
- oldFormErrors: true
- });
-};
-
-export const usersCache: t.UsersCache = new Map();
-
-export const onUserUpdate = ({ user }: { user: t.User; }) => {
- if (!getNotes()[user.id]) return;
-
- // doesn't have .getAvatarURL
- const userFromStore = UserStore.getUser(user.id);
-
- if (!userFromStore) return;
-
- cacheUser(userFromStore);
-};
-
-const fetchUser = async (userId: string) => {
- for (let _ = 0; _ < 5; _++) {
- try {
- return await UserUtils.getUser(userId);
- } catch (error: any) {
- const wait = error?.body?.retry_after;
-
- if (!wait) return;
-
- await new Promise(resolve => setTimeout(resolve, wait * 1000 + 100));
- }
- }
-};
-
-const cacheUser = (user: t.User) => {
- usersCache.set(user.id, {
- id: user.id,
- globalName: user.globalName ?? user.username,
- username: user.username,
- avatar: user.getAvatarURL(void 0, void 0, false),
- });
-};
-
-export const cacheUsers = async () => {
- const toRequest: string[] = [];
-
- for (const userId of Object.keys(getNotes())) {
- const user = UserStore.getUser(userId);
-
- if (user) {
- cacheUser(user);
- continue;
- }
-
- toRequest.push(userId);
- }
-
- if (usersCache.size >= Object.keys(getNotes()).length) {
- return;
- }
-
- const sentNonce = SnowflakeUtils.fromTimestamp(Date.now());
-
- const allGuildIds = Object.keys(GuildStore.getGuilds());
- let count = allGuildIds.length * Math.ceil(toRequest.length / 100);
-
- const processed = new Set();
-
- const callback = async ({ chunks }) => {
- for (const chunk of chunks) {
- const { nonce, members }: {
- nonce: string;
- members: {
- user: t.User;
- }[];
- } = chunk;
-
- if (nonce !== sentNonce) {
- return;
- }
-
- members.forEach(({ user }) => {
- if (processed.has(user.id)) return;
-
- processed.add(user.id);
-
- cacheUser(UserStore.getUser(user.id));
- });
-
- refreshUsersCache();
-
- if (--count === 0) {
- FluxDispatcher.unsubscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
-
- const userIds = Object.keys(getNotes());
-
- if (usersCache.size !== userIds.length) {
-
- for (const userId of userIds) {
- if (usersCache.has(userId)) continue;
-
- await new Promise(resolve => setTimeout(resolve, 1000));
-
- const user = await fetchUser(userId);
-
- if (user) {
- cacheUser(user);
- refreshUsersCache();
- }
- }
-
- } else
- refreshUsersCache();
- }
- }
- };
-
- FluxDispatcher.subscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
-
- for (let i = 0; i < toRequest.length; i += 100) {
- FluxDispatcher.dispatch({
- type: "GUILD_MEMBERS_REQUEST",
- guildIds: allGuildIds,
- userIds: toRequest.slice(i, i + 100),
- nonce: sentNonce,
- });
- }
-};
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { Constants, FluxDispatcher, GuildStore, RestAPI, SnowflakeUtils, UserStore, UserUtils } from "@webpack/common";
+import { waitForStore } from "webpack/common/internal";
+
+import { refreshNotesData, refreshUsersCache } from "./components/NotesDataModal";
+import * as t from "./types";
+
+let NoteStore: t.NoteStore;
+
+waitForStore("NoteStore", s => NoteStore = s);
+
+export const getNotes = () => {
+ return NoteStore.getNotes();
+};
+
+export const onNoteUpdate = () => {
+ refreshNotesData();
+};
+
+export const updateNote = (userId: string, note: string | null) => {
+ RestAPI.put({
+ url: Constants.Endpoints.NOTE(userId),
+ body: { note: note },
+ oldFormErrors: true
+ });
+};
+
+export const usersCache: t.UsersCache = new Map();
+
+export const onUserUpdate = ({ user }: { user: t.User; }) => {
+ if (!getNotes()[user.id]) return;
+
+ // doesn't have .getAvatarURL
+ const userFromStore = UserStore.getUser(user.id);
+
+ if (!userFromStore) return;
+
+ cacheUser(userFromStore);
+};
+
+const fetchUser = async (userId: string) => {
+ for (let _ = 0; _ < 5; _++) {
+ try {
+ return await UserUtils.getUser(userId);
+ } catch (error: any) {
+ const wait = error?.body?.retry_after;
+
+ if (!wait) return;
+
+ await new Promise(resolve => setTimeout(resolve, wait * 1000 + 100));
+ }
+ }
+};
+
+const cacheUser = (user: t.User) => {
+ usersCache.set(user.id, {
+ id: user.id,
+ globalName: user.globalName ?? user.username,
+ username: user.username,
+ avatar: user.getAvatarURL(void 0, void 0, false),
+ });
+};
+
+export const cacheUsers = async () => {
+ const toRequest: string[] = [];
+
+ for (const userId of Object.keys(getNotes())) {
+ const user = UserStore.getUser(userId);
+
+ if (user) {
+ cacheUser(user);
+ continue;
+ }
+
+ toRequest.push(userId);
+ }
+
+ if (usersCache.size >= Object.keys(getNotes()).length) {
+ return;
+ }
+
+ const sentNonce = SnowflakeUtils.fromTimestamp(Date.now());
+
+ const allGuildIds = Object.keys(GuildStore.getGuilds());
+ let count = allGuildIds.length * Math.ceil(toRequest.length / 100);
+
+ const processed = new Set();
+
+ const callback = async ({ chunks }) => {
+ for (const chunk of chunks) {
+ const { nonce, members }: {
+ nonce: string;
+ members: {
+ user: t.User;
+ }[];
+ } = chunk;
+
+ if (nonce !== sentNonce) {
+ return;
+ }
+
+ members.forEach(({ user }) => {
+ if (processed.has(user.id)) return;
+
+ processed.add(user.id);
+
+ cacheUser(UserStore.getUser(user.id));
+ });
+
+ refreshUsersCache();
+
+ if (--count === 0) {
+ FluxDispatcher.unsubscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
+
+ const userIds = Object.keys(getNotes());
+
+ if (usersCache.size !== userIds.length) {
+
+ for (const userId of userIds) {
+ if (usersCache.has(userId)) continue;
+
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ const user = await fetchUser(userId);
+
+ if (user) {
+ cacheUser(user);
+ refreshUsersCache();
+ }
+ }
+
+ } else
+ refreshUsersCache();
+ }
+ }
+ };
+
+ FluxDispatcher.subscribe("GUILD_MEMBERS_CHUNK_BATCH", callback);
+
+ for (let i = 0; i < toRequest.length; i += 100) {
+ FluxDispatcher.dispatch({
+ type: "GUILD_MEMBERS_REQUEST",
+ guildIds: allGuildIds,
+ userIds: toRequest.slice(i, i + 100),
+ nonce: sentNonce,
+ });
+ }
+};
diff --git a/src/plugins/notesSearcher/index.tsx b/src/plugins/notesSearcher/index.tsx
index 947001d28..d894227b1 100644
--- a/src/plugins/notesSearcher/index.tsx
+++ b/src/plugins/notesSearcher/index.tsx
@@ -5,8 +5,6 @@
*/
import { disableStyle, enableStyle } from "@api/Styles";
-import styles from "./styles.css?managed";
-
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
@@ -15,6 +13,7 @@ import { FluxDispatcher } from "@webpack/common";
import { OpenNotesDataButton } from "./components/NotesDataButton";
import { getNotes, onNoteUpdate, onUserUpdate } from "./data";
import settings from "./settings";
+import styles from "./styles.css?managed";
import { Notes } from "./types";
export default definePlugin({
diff --git a/src/plugins/notesSearcher/styles.css b/src/plugins/notesSearcher/styles.css
index ba66200f1..155caf219 100644
--- a/src/plugins/notesSearcher/styles.css
+++ b/src/plugins/notesSearcher/styles.css
@@ -1,107 +1,107 @@
-.vc-notes-searcher-toolbox-button svg {
- color: var(--interactive-normal);
-}
-
-.vc-notes-searcher-modal-user-actions * svg {
- width: 32px !important;
- height: 32px !important;
-}
-
-.vc-notes-searcher-toolbox-button:hover svg,
-.vc-notes-searcher-toolbox-button[class*="selected"] svg {
- color: var(--interactive-active);
-}
-
-.vc-notes-searcher-modal-root {
- min-height: 75vh;
- max-height: 75vh;
- min-width: 70vw;
- max-width: 70vw;
-}
-
-.vc-notes-searcher-modal-header-input {
- width: 100%;
- margin-right: 16px;
-}
-
-.vc-notes-searcher-modal-content {
- padding-bottom: 16px;
- height: 100%;
-}
-
-.vc-notes-searcher-modal-content div[aria-hidden="true"] {
- display: none;
-}
-
-.vc-notes-searcher-modal-content-inner > *:not(:last-child) {
- margin-bottom: 8px;
-}
-
-.vc-notes-searcher-modal-user:hover:not(
-:has(
- .vc-notes-searcher-modal-user-text-area:hover,
- .vc-notes-searcher-modal-user-actions:hover
-)
-) {
- background-color: var(--background-secondary-alt);
-}
-
-.vc-notes-searcher-modal-user-avatar {
- aspect-ratio: 1 / 1;
- margin: 12px;
-}
-
-.vc-notes-searcher-modal-user-actions * div:has(svg) {
- width: 32px !important;
- height: 32px !important;
- overflow: visible !important;
-}
-
-.vc-notes-searcher-modal-user-notes-container
-*
-div:has(.vc-notes-searcher-modal-user-text-area) {
- height: 67px;
-}
-
-.vc-notes-searcher-modal-user-text-area {
- width: 100%;
- height: 100%;
-}
-
-.vc-notes-searcher-modal-spinner::after {
- content: "";
- position: absolute;
- width: 56px;
- height: 56px;
- border: 5px solid #fff;
- border-radius: 50%;
- display: inline-block;
- box-sizing: border-box;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- animation: vc-notes-searcher-scale-up 1s linear infinite;
-}
-
-@keyframes vc-notes-searcher-scale-up {
- 0% {
- transform: translate(-50%, -50%) scale(0);
- }
-
- 60%,
- 100% {
- transform: translate(-50%, -50%) scale(1);
- }
-}
-
-@keyframes vc-notes-searcher-pulse {
- 0%,
- 60%,
- 100% {
- transform: scale(0.9);
- }
-
- 80% {
- transform: scale(1.1);
- }
-}
+.vc-notes-searcher-toolbox-button svg {
+ color: var(--interactive-normal);
+}
+
+.vc-notes-searcher-modal-user-actions * svg {
+ width: 32px !important;
+ height: 32px !important;
+}
+
+.vc-notes-searcher-toolbox-button:hover svg,
+.vc-notes-searcher-toolbox-button[class*="selected"] svg {
+ color: var(--interactive-active);
+}
+
+.vc-notes-searcher-modal-root {
+ min-height: 75vh;
+ max-height: 75vh;
+ min-width: 70vw;
+ max-width: 70vw;
+}
+
+.vc-notes-searcher-modal-header-input {
+ width: 100%;
+ margin-right: 16px;
+}
+
+.vc-notes-searcher-modal-content {
+ padding-bottom: 16px;
+ height: 100%;
+}
+
+.vc-notes-searcher-modal-content div[aria-hidden="true"] {
+ display: none;
+}
+
+.vc-notes-searcher-modal-content-inner > *:not(:last-child) {
+ margin-bottom: 8px;
+}
+
+.vc-notes-searcher-modal-user:hover:not(
+:has(
+ .vc-notes-searcher-modal-user-text-area:hover,
+ .vc-notes-searcher-modal-user-actions:hover
+)
+) {
+ background-color: var(--background-secondary-alt);
+}
+
+.vc-notes-searcher-modal-user-avatar {
+ aspect-ratio: 1 / 1;
+ margin: 12px;
+}
+
+.vc-notes-searcher-modal-user-actions * div:has(svg) {
+ width: 32px !important;
+ height: 32px !important;
+ overflow: visible !important;
+}
+
+.vc-notes-searcher-modal-user-notes-container
+*
+div:has(.vc-notes-searcher-modal-user-text-area) {
+ height: 67px;
+}
+
+.vc-notes-searcher-modal-user-text-area {
+ width: 100%;
+ height: 100%;
+}
+
+.vc-notes-searcher-modal-spinner::after {
+ content: "";
+ position: absolute;
+ width: 56px;
+ height: 56px;
+ border: 5px solid #fff;
+ border-radius: 50%;
+ display: inline-block;
+ box-sizing: border-box;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ animation: vc-notes-searcher-scale-up 1s linear infinite;
+}
+
+@keyframes vc-notes-searcher-scale-up {
+ 0% {
+ transform: translate(-50%, -50%) scale(0);
+ }
+
+ 60%,
+ 100% {
+ transform: translate(-50%, -50%) scale(1);
+ }
+}
+
+@keyframes vc-notes-searcher-pulse {
+ 0%,
+ 60%,
+ 100% {
+ transform: scale(0.9);
+ }
+
+ 80% {
+ transform: scale(1.1);
+ }
+}
From 4d1cf661f5c041d7b401d474215fdb782bd539ee Mon Sep 17 00:00:00 2001
From: vishnyanetchereshnya
<151846235+vishnyanetchereshnya@users.noreply.github.com>
Date: Sun, 14 Jul 2024 16:59:05 +0300
Subject: [PATCH 27/27] bugfix
---
src/plugins/notesSearcher/components/NotesDataModal.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/plugins/notesSearcher/components/NotesDataModal.tsx b/src/plugins/notesSearcher/components/NotesDataModal.tsx
index 0b9561a10..f82a58bce 100644
--- a/src/plugins/notesSearcher/components/NotesDataModal.tsx
+++ b/src/plugins/notesSearcher/components/NotesDataModal.tsx
@@ -56,11 +56,11 @@ export function NotesDataModal({ modalProps, close }: {
const [usersNotesData, refreshNotesData] = useReducer(() => {
return Object.entries(getNotes())
.map<[string, string]>(([userId, { note }]) => [userId, note])
- .filter((([_, note]) => note !== ""));
+ .filter((([_, note]) => note && note !== ""));
},
Object.entries(getNotes())
.map<[string, string]>(([userId, { note }]) => [userId, note])
- .filter((([_, note]) => note !== ""))
+ .filter((([_, note]) => note && note !== ""))
);
RefreshNotesDataEx = refreshNotesData;