1
0
Fork 1
mirror of https://github.com/Vendicated/Vencord.git synced 2025-01-11 02:16:23 +00:00

Setup Cache / Option to Add notes other notebooks

This commit is contained in:
Wolfie 2024-03-09 23:58:40 -04:00
parent 7522c627e8
commit 79621f67ef
No known key found for this signature in database
GPG key ID: DE384EE9BF2D909A
9 changed files with 131 additions and 72 deletions

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { findByCodeLazy, findByProps } from "@webpack"; import { findByProps } from "@webpack";
export default ({ error }: { error?: Error; } = {}) => { export default ({ error }: { error?: Error; } = {}) => {

View file

@ -4,12 +4,12 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize } from "@utils/modal"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps,ModalRoot, ModalSize } from "@utils/modal";
import { findByProps } from "@webpack"; import { findByProps } from "@webpack";
import { Button, Forms, Text, TextArea } from "@webpack/common"; import { Button, Forms, Text } from "@webpack/common";
import noteHandler from "plugins/holynotes/noteHandler"; import noteHandler from "plugins/holynotes/noteHandler";
export default ({ onClose, ...modalProps }: { onClose: () => void; }) => { export default ({ onClose, ...modalProps }: ModalProps & { onClose: () => void; }) => {
const { colorStatusGreen } = findByProps("colorStatusGreen"); const { colorStatusGreen } = findByProps("colorStatusGreen");
return ( return (

View file

@ -6,7 +6,7 @@
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { findByProps } from "@webpack"; import { findByProps } from "@webpack";
import { ContextMenuApi, Flex, Menu, React, TabBar, Text, TextInput } from "@webpack/common"; import { ContextMenuApi, Flex, Menu, React, TabBar, Text, TextInput } from "@webpack/common";
import noteHandler from "plugins/holynotes/noteHandler"; import noteHandler from "plugins/holynotes/noteHandler";
@ -14,9 +14,9 @@ import { HolyNotes } from "plugins/holynotes/types";
import HelpIcon from "../icons/HelpIcon"; import HelpIcon from "../icons/HelpIcon";
import Errors from "./Error"; import Errors from "./Error";
import HelpModal from "./HelpModal";
import ManageNotebookButton from "./ManageNotebookButton"; import ManageNotebookButton from "./ManageNotebookButton";
import { RenderMessage } from "./RenderMessage"; import { RenderMessage } from "./RenderMessage";
import HelpModal from "./HelpModal";
const renderNotebook = ({ const renderNotebook = ({
notes, notebook, updateParent, sortDirection, sortType, searchInput, closeModal notes, notebook, updateParent, sortDirection, sortType, searchInput, closeModal
@ -29,7 +29,7 @@ const renderNotebook = ({
searchInput: string; searchInput: string;
closeModal: () => void; closeModal: () => void;
}) => { }) => {
const messageArray = Object.values(notes).map((note) => ( const messageArray = Object.values(notes).map(note => (
<RenderMessage <RenderMessage
note={note} note={note}
notebook={notebook} notebook={notebook}
@ -47,46 +47,27 @@ const renderNotebook = ({
if (sortDirection) messageArray.reverse(); if (sortDirection) messageArray.reverse();
const filteredMessages = messageArray.filter((message) => const filteredMessages = messageArray.filter(message =>
message.props.note.content.toLowerCase().includes(searchInput.toLowerCase()), message.props.note.content.toLowerCase().includes(searchInput.toLowerCase()),
); );
return filteredMessages; return filteredMessages.length > 0 ? filteredMessages : <Errors />;
}; };
export const NoteModal = (props) => { export const NoteModal = (props: ModalProps & { onClose: () => void; }) => {
const [sortType, setSortType] = React.useState(true); const [sortType, setSortType] = React.useState(true);
const [searchInput, setSearch] = React.useState(""); const [searchInput, setSearch] = React.useState("");
const [sortDirection, setSortDirection] = React.useState(true); const [sortDirection, setSortDirection] = React.useState(true);
const [currentNotebook, setCurrentNotebook] = React.useState("Main"); const [currentNotebook, setCurrentNotebook] = React.useState("Main");
const [notes, setNotes] = React.useState({});
const [notebooks, setNotebooks] = React.useState([]);
const { quickSelect, quickSelectLabel, quickSelectQuick, quickSelectValue, quickSelectArrow } = findByProps("quickSelect"); const { quickSelect, quickSelectLabel, quickSelectQuick, quickSelectValue, quickSelectArrow } = findByProps("quickSelect");
const forceUpdate = React.useReducer(() => ({}), {})[1] as () => void; const forceUpdate = React.useReducer(() => ({}), {})[1] as () => void;
React.useEffect(() => {
const update = async () => {
const notes = await noteHandler.getNotes(currentNotebook);
setNotes(notes);
};
update();
}, [currentNotebook]);
React.useEffect(() => {
async function fetchNotebooks() {
console.log(await noteHandler.getNotebooks());
const notebooks = await noteHandler.getNotebooks();
setNotebooks(notebooks);
}
fetchNotebooks();
}, []);
const notes = noteHandler.getNotes(currentNotebook);
if (!notes) return <></>; if (!notes) return <></>;
return ( return (
@ -120,7 +101,7 @@ export const NoteModal = (props) => {
className={classes("vc-notebook-tabbar-bar", "vc-notebook-tabbar")} className={classes("vc-notebook-tabbar-bar", "vc-notebook-tabbar")}
selectedItem={currentNotebook} selectedItem={currentNotebook}
onItemSelect={setCurrentNotebook}> onItemSelect={setCurrentNotebook}>
{notebooks.map(notebook => ( {Object.keys(noteHandler.getAllNotes()).map(notebook => (
<TabBar.Item key={notebook} id={notebook} className={classes("vc-notebook-tabbar-bar-item", "vc-notebook-tabbar-item")}> <TabBar.Item key={notebook} id={notebook} className={classes("vc-notebook-tabbar-bar-item", "vc-notebook-tabbar-item")}>
{notebook} {notebook}
</TabBar.Item> </TabBar.Item>

View file

@ -5,14 +5,14 @@
*/ */
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize } from "@utils/modal"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps,ModalRoot, ModalSize } from "@utils/modal";
import { Button, React, Text } from "@webpack/common"; import { Button, React, Text } from "@webpack/common";
import noteHandler from "plugins/holynotes/noteHandler"; import noteHandler from "plugins/holynotes/noteHandler";
import Error from "./Error"; import Error from "./Error";
import { RenderMessage } from "./RenderMessage"; import { RenderMessage } from "./RenderMessage";
export default ({ onClose, notebook, ...props }: { onClose: () => void; notebook: string; }) => { export default ({ onClose, notebook, ...props }: ModalProps & { onClose: () => void; notebook: string; }) => {
const [notes, setNotes] = React.useState({}); const [notes, setNotes] = React.useState({});
React.useEffect(() => { React.useEffect(() => {

View file

@ -5,6 +5,7 @@
*/ */
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import { ModalProps } from "@utils/modal";
import { findByCode, findByProps } from "@webpack"; import { findByCode, findByProps } from "@webpack";
import { ContextMenuApi, FluxDispatcher, Menu, NavigationRouter, React } from "@webpack/common"; import { ContextMenuApi, FluxDispatcher, Menu, NavigationRouter, React } from "@webpack/common";
import noteHandler from "plugins/holynotes/noteHandler"; import noteHandler from "plugins/holynotes/noteHandler";
@ -111,7 +112,13 @@ export const RenderMessage = ({
); );
}; };
const NoteContextMenu = (props) => { const NoteContextMenu = (
props: ModalProps & {
updateParent?: () => void;
notebook: string;
note: HolyNotes.Note;
closeModal?: () => void;
}) => {
const { note, notebook, updateParent, closeModal } = props; const { note, notebook, updateParent, closeModal } = props;
return ( return (
@ -130,7 +137,16 @@ const NoteContextMenu = (props) => {
closeModal?.(); closeModal?.();
}} }}
/> />
</Menu.Menu>); <Menu.MenuItem
label="Delete Note"
id="delete"
action={() => {
noteHandler.deleteNote(note.id, notebook);
updateParent?.();
}}
/>
</Menu.Menu>
);
}}></div> }}></div>
); );
}; };

View file

@ -19,20 +19,31 @@
import "./style.css"; import "./style.css";
import { NavContextMenuPatchCallback } from "@api/ContextMenu"; import { NavContextMenuPatchCallback } from "@api/ContextMenu";
import { DataStore } from "@api/index";
import { addButton, removeButton } from "@api/MessagePopover"; import { addButton, removeButton } from "@api/MessagePopover";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { openModal } from "@utils/modal"; import { openModal } from "@utils/modal";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import Message from "discord-types/general"; import { Menu } from "@webpack/common";
import { Popover as NoteButtonPopover } from "./components/icons/NoteButton"; import { Popover as NoteButtonPopover } from "./components/icons/NoteButton";
import { NoteModal } from "./components/modals/Notebook"; import { NoteModal } from "./components/modals/Notebook";
import noteHandler from "./noteHandler"; import noteHandler, { noteHandlerCache } from "./noteHandler";
import { HolyNoteStore } from "./utils"; import { DataStoreToCache } from "./utils";
const messageContextMenuPatch: NavContextMenuPatchCallback = async (children, { message }: { message: Message; }) => { const messageContextMenuPatch: NavContextMenuPatchCallback = async (children, { message }: { message: Message; }) => {
children.push(
//console.log(await noteHandler.getAllNotes()); <Menu.MenuItem label="Add Messagge To" id="add-message-to-note">
{Object.keys(noteHandler.getAllNotes()).map((notebook: string, index: number) => (
<Menu.MenuItem
key={index}
label={notebook}
id={notebook}
action={() => noteHandler.addNote(message, notebook)}
/>
))}
</Menu.MenuItem>
);
}; };
@ -51,10 +62,12 @@ export default definePlugin({
contextMenus: { contextMenus: {
"message": messageContextMenuPatch "message": messageContextMenuPatch
}, },
store: HolyNoteStore,
async start() { async start() {
addButton("HolyNotes", (message) => { if (await DataStore.keys().then(keys => !keys.includes("Main"))) return noteHandler.newNoteBook("Main");
if (!noteHandlerCache.has("Main")) await DataStoreToCache();
addButton("HolyNotes", message => {
return { return {
label: "Save Note", label: "Save Note",
icon: NoteButtonPopover, icon: NoteButtonPopover,

View file

@ -5,13 +5,14 @@
*/ */
import { DataStore } from "@api/index"; import { DataStore } from "@api/index";
import { ChannelStore, Toasts, UserStore, lodash, showToast } from "@webpack/common"; import { findByCode } from "@webpack";
import { ChannelStore, lodash, Toasts, UserStore } from "@webpack/common";
import { Channel, Message } from "discord-types/general"; import { Channel, Message } from "discord-types/general";
import { Discord, HolyNotes } from "./types"; import { Discord, HolyNotes } from "./types";
import { HolyNoteStore } from "./utils"; import { saveCacheToDataStore } from "./utils";
import { findByCode } from "@webpack";
export const noteHandlerCache = new Map();
export default new (class NoteHandler { export default new (class NoteHandler {
private _formatNote(channel: Channel, message: Message): HolyNotes.Note { private _formatNote(channel: Channel, message: Message): HolyNotes.Note {
@ -38,27 +39,26 @@ export default new (class NoteHandler {
} }
public async getNotes(notebook?: string): Promise<Record<string, HolyNotes.Note>> { public getNotes(notebook?: string): Record<string, HolyNotes.Note> {
if (await DataStore.keys().then(keys => keys.includes(notebook))) { return noteHandlerCache.get(notebook);
return await DataStore.get(notebook) ?? {}; }
} else {
return this.newNoteBook(notebook).then(() => this.getNotes(notebook)); public getAllNotes(): HolyNotes.Note[] {
const data = noteHandlerCache.entries();
const notes = {};
for (const [key, value] of data) {
notes[key] = value;
} }
} return notes;
public async getAllNotes(): Promise<HolyNotes.Note[]> {
return await DataStore.entries();
}
public async getNotebooks(): Promise<string[]> {
return await DataStore.keys();
} }
public addNote = async (message: Message, notebook: string) => { public addNote = async (message: Message, notebook: string) => {
const notes = await this.getNotes(notebook); const notes = this.getNotes(notebook);
const channel = ChannelStore.getChannel(message.channel_id); const channel = ChannelStore.getChannel(message.channel_id);
const newNotes = Object.assign({ [message.id]: this._formatNote(channel, message) }, notes); const newNotes = Object.assign({ [message.id]: this._formatNote(channel, message) }, notes);
await DataStore.set(notebook, newNotes);
noteHandlerCache.set(notebook, newNotes);
saveCacheToDataStore(notebook, newNotes);
Toasts.show({ Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
@ -70,7 +70,8 @@ export default new (class NoteHandler {
public deleteNote = async (noteId: string, notebook: string) => { public deleteNote = async (noteId: string, notebook: string) => {
const notes = this.getNotes(notebook); const notes = this.getNotes(notebook);
await DataStore.set(notebook, lodash.omit(notes, noteId)); noteHandlerCache.set(notebook, lodash.omit(notes, noteId));
saveCacheToDataStore(notebook, lodash.omit(notes, noteId));
Toasts.show({ Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
@ -85,8 +86,12 @@ export default new (class NoteHandler {
newNoteBook[note.id] = note; newNoteBook[note.id] = note;
await DataStore.set(from, lodash.omit(origNotebook, note.id)); noteHandlerCache.set(from, lodash.omit(origNotebook, note.id));
await DataStore.set(to, newNoteBook); noteHandlerCache.set(to, newNoteBook);
saveCacheToDataStore(from, lodash.omit(origNotebook, note.id));
saveCacheToDataStore(to, newNoteBook);
Toasts.show({ Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
@ -96,7 +101,16 @@ export default new (class NoteHandler {
}; };
public newNoteBook = async (notebookName: string) => { public newNoteBook = async (notebookName: string) => {
if (await DataStore.keys().then(keys => keys.includes(notebookName))) { let notebookExists = false;
for (const key of noteHandlerCache.keys()) {
if (key === notebookName) {
notebookExists = true;
break;
}
}
if (notebookExists) {
Toasts.show({ Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
message: `Notebook ${notebookName} already exists.`, message: `Notebook ${notebookName} already exists.`,
@ -104,7 +118,10 @@ export default new (class NoteHandler {
}); });
return; return;
} }
await DataStore.set(notebookName, {});
noteHandlerCache.set(notebookName, {});
saveCacheToDataStore(notebookName, {} as HolyNotes.Note[]);
return Toasts.show({ return Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
message: `Successfully created ${notebookName}.`, message: `Successfully created ${notebookName}.`,
@ -113,7 +130,9 @@ export default new (class NoteHandler {
}; };
public deleteNotebook = async (notebookName: string) => { public deleteNotebook = async (notebookName: string) => {
await DataStore.del(notebookName); noteHandlerCache.delete(notebookName);
saveCacheToDataStore(notebookName);
Toasts.show({ Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
message: `Successfully deleted ${notebookName}.`, message: `Successfully deleted ${notebookName}.`,
@ -122,10 +141,12 @@ export default new (class NoteHandler {
}; };
public refreshAvatars = async () => { public refreshAvatars = async () => {
const notebooks = await this.getAllNotes(); const notebooks = this.getAllNotes();
const User = findByCode("tag", "isClyde"); const User = findByCode("tag", "isClyde");
for (const notebook in notebooks) for (const notebook in notebooks)
for (const noteId in notebooks[notebook]) { for (const noteId in notebooks[notebook]) {
const note = notebooks[notebook][noteId]; const note = notebooks[notebook][noteId];
@ -138,7 +159,11 @@ export default new (class NoteHandler {
}); });
} }
for (const notebook in notebooks) await DataStore.set(notebook, notebooks[notebook]); for (const notebook in notebooks) {
noteHandlerCache.set(notebook, notebooks[notebook]);
saveCacheToDataStore(notebook, notebooks[notebook]);
}
Toasts.show({ Toasts.show({
id: Toasts.genId(), id: Toasts.genId(),
message: "Successfully refreshed avatars.", message: "Successfully refreshed avatars.",

View file

@ -45,5 +45,3 @@ export declare namespace HolyNotes {
stickerItems: Discord.Sticker[]; stickerItems: Discord.Sticker[];
} }
} }

View file

@ -4,7 +4,33 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { createStore } from "@api/DataStore"; import { DataStore } from "@api/index";
import { noteHandlerCache } from "./noteHandler";
import { HolyNotes } from "./types";
export const HolyNoteStore = createStore("HolyNotesData", "HolyNotesStore");
export async function saveCacheToDataStore(key: string, value?: HolyNotes.Note[]) {
await DataStore.set(key, value);
}
export async function getFormatedEntries() {
const data = await DataStore.entries();
const notebooks: Record<string, HolyNotes.Note> = {};
data.forEach(function (note) {
notebooks[note[0]] = note[1];
});
return notebooks;
}
export async function DataStoreToCache() {
const data = await DataStore.entries();
data.forEach(function (note) {
noteHandlerCache.set(note[0], note[1]);
});
}