Plugin

HolyNotes

Holy Notes allows you to save messages

index.tsx
Download

Source

src/plugins/holyNotes/index.tsx
1/*
2 * FiveCord — a Discord client mod
3 * Copyright (c) 2025 FiveCord
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
7import "./style.css";
8
9import { NavContextMenuPatchCallback } from "@api/ContextMenu";
10import { DataStore } from "@api/index";
11import { addButton, removeButton } from "@api/MessagePopover";
12import ErrorBoundary from "@components/ErrorBoundary";
13import { Devs } from "@utils/constants";
14import { classes } from "@utils/misc";
15import { openModal } from "@utils/modal";
16import definePlugin from "@utils/types";
17import { findByProps, findExportedComponentLazy } from "@webpack";
18import { ChannelStore, Menu } from "@webpack/common";
19import { Message } from "discord-types/general";
20
21import { Popover as NoteButtonPopover, Popover } from "./components/icons/NoteButton";
22import { NoteModal } from "./components/modals/Notebook";
23import noteHandler, { noteHandlerCache } from "./NoteHandler";
24import { DataStoreToCache, HolyNoteStore } from "./utils";
25
26const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider");
27
28const messageContextMenuPatch: NavContextMenuPatchCallback = async (children, { message }: { message: Message; }) => {
29 children.push(
30 <Menu.MenuItem label="Add Message To" id="add-message-to-note">
31 {Object.keys(noteHandler.getAllNotes()).map((notebook: string, index: number) => (
32 <Menu.MenuItem
33 label={notebook}
34 id={notebook}
35 action={() => noteHandler.addNote(message, notebook)}
36 />
37 ))}
38 </Menu.MenuItem>
39 );
40};
41
42function ToolBarHeader() {
43 const iconClasses = findByProps("iconWrapper", "clickable");
44
45 return (
46 <ErrorBoundary noop={true}>
47 <HeaderBarIcon
48 tooltip="Holy Notes"
49 position="bottom"
50 className={classes("vc-note-button", iconClasses.iconWrapper, iconClasses.clickable)}
51 icon={e => Popover(e)}
52 onClick={() => openModal(props => <NoteModal {...props} />)}
53 />
54 </ErrorBoundary>
55 );
56}
57
58
59export default definePlugin({
60 name: "HolyNotes",
61 description: "Holy Notes allows you to save messages",
62 authors: [Devs.FiveCord],
63 dependencies: ["MessagePopoverAPI", "ChatInputButtonAPI"],
64
65 patches: [
66 {
67 find: "toolbar:function",
68 replacement: {
69 match: /(function \i\(\i\){)(.{1,200}toolbar.{1,100}mobileToolbar)/,
70 replace: "$1$self.toolbarAction(arguments[0]);$2"
71 }
72 }
73 ],
74
75 toolboxActions: {
76 async "Open Notes"() {
77 openModal(props => <NoteModal {...props} />);
78 }
79 },
80
81 contextMenus: {
82 "message": messageContextMenuPatch
83 },
84
85 toolbarAction(e) {
86 if (Array.isArray(e.toolbar))
87 return e.toolbar.push(
88 <ErrorBoundary noop={true}>
89 <ToolBarHeader />
90 </ErrorBoundary>
91 );
92
93 e.toolbar = [
94 <ErrorBoundary noop={true}>
95 <ToolBarHeader />
96 </ErrorBoundary>,
97 e.toolbar,
98 ];
99 },
100 async start() {
101 if (await DataStore.keys(HolyNoteStore).then(keys => !keys.includes("Main"))) return noteHandler.newNoteBook("Main");
102 if (!noteHandlerCache.has("Main")) await DataStoreToCache();
103
104 addButton("HolyNotes", message => {
105 return {
106 label: "Save Note",
107 icon: NoteButtonPopover,
108 message: message,
109 channel: ChannelStore.getChannel(message.channel_id),
110 onClick: () => noteHandler.addNote(message, "Main")
111
112 };
113 });
114 },
115
116 async stop() {
117 removeButton("HolyNotes");
118 }
119});
120
121