Skip to content

Commit

Permalink
add ViewRaw plugin & MiniPopover API (#275)
Browse files Browse the repository at this point in the history
Co-authored-by: Vendicated <[email protected]>
  • Loading branch information
12944qwerty and Vendicated authored Dec 2, 2022
1 parent 06d32ae commit 4760af7
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 57 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ lerna-debug.log*
*.tsbuildinfo

src/userplugins

ExtensionCache/
settings/
69 changes: 69 additions & 0 deletions src/api/MessagePopover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2022 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import Logger from "@utils/Logger";
import { Channel, Message } from "discord-types/general";
import type { MouseEventHandler } from "react";

const logger = new Logger("MessagePopover");

export interface ButtonItem {
key?: string,
label: string,
icon: React.ComponentType<any>,
message: Message,
channel: Channel,
onClick?: MouseEventHandler<HTMLButtonElement>,
onContextMenu?: MouseEventHandler<HTMLButtonElement>;
}

export type getButtonItem = (message: Message) => ButtonItem | null;

export const buttons = new Map<string, getButtonItem>();

export function addButton(
identifier: string,
item: getButtonItem,
) {
buttons.set(identifier, item);
}

export function removeButton(identifier: string) {
buttons.delete(identifier);
}

export function _buildPopoverElements(
msg: Message,
makeButton: (item: ButtonItem) => React.ComponentType
) {
const items = [] as React.ComponentType[];

for (const [identifier, getItem] of buttons.entries()) {
try {
const item = getItem(msg);
if (item) {
item.key ??= identifier;
items.push(makeButton(item));
}
} catch (err) {
logger.error(`[${identifier}]`, err);
}
}

return items;
}
7 changes: 6 additions & 1 deletion src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import * as $Commands from "./Commands";
import * as $DataStore from "./DataStore";
import * as $MessageAccessories from "./MessageAccessories";
import * as $MessageEventsAPI from "./MessageEvents";
import * as $MessagePopover from "./MessagePopover";
import * as $Notices from "./Notices";
import * as $ServerList from "./ServerList";

Expand Down Expand Up @@ -59,6 +60,10 @@ const DataStore = $DataStore;
* An API allowing you to add custom components as message accessories
*/
const MessageAccessories = $MessageAccessories;
/**
* An API allowing you to add custom buttons in the message popover
*/
const MessagePopover = $MessagePopover;
/**
* An API allowing you to add badges to user profiles
*/
Expand All @@ -68,4 +73,4 @@ const Badges = $Badges;
*/
const ServerList = $ServerList;

export { Badges, Commands, DataStore, MessageAccessories, MessageEvents, Notices, ServerList };
export { Badges, Commands, DataStore, MessageAccessories, MessageEvents, MessagePopover, Notices, ServerList };
33 changes: 33 additions & 0 deletions src/plugins/apiMessagePopover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2022 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";

export default definePlugin({
name: "MessagePopoverAPI",
description: "API to add buttons to message popovers.",
authors: [Devs.KingFish],
patches: [{
find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
replacement: {
match: /(message:(.).{0,100}Fragment,\{children:\[)(.{0,90}renderPopout:.{0,200}message_reaction_emoji_picker.+?return (.{1,3})\(.{0,30}"add-reaction")/,
replace: "$1...Vencord.Api.MessagePopover._buildPopoverElements($2,$4),$3"
}
}],
});
46 changes: 17 additions & 29 deletions src/plugins/HideAttachments.tsx → src/plugins/hideAttachments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@
*/

import { get, set } from "@api/DataStore";
import { addButton, removeButton } from "@api/MessagePopover";
import { Devs } from "@utils/constants";
import Logger from "@utils/Logger";
import definePlugin from "@utils/types";
import { ChannelStore, FluxDispatcher } from "@webpack/common";
import { Message } from "discord-types/general";

let style: HTMLStyleElement;

Expand Down Expand Up @@ -49,13 +48,7 @@ export default definePlugin({
name: "HideAttachments",
description: "Hide attachments and Embeds for individual messages via hover button",
authors: [Devs.Ven],
patches: [{
find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
replacement: {
match: /(message:(.).{0,100}Fragment,\{children:\[)(.{0,40}renderPopout:.{0,200}message_reaction_emoji_picker.+?return (.{1,3})\(.{0,30}"add-reaction")/,
replace: "$1Vencord.Plugins.plugins.HideAttachments.renderButton($2, $4),$3"
}
}],
dependencies: ["MessagePopoverAPI"],

async start() {
style = document.createElement("style");
Expand All @@ -64,11 +57,26 @@ export default definePlugin({

await getHiddenMessages();
await this.buildCss();

addButton("HideAttachments", msg => {
if (!msg.attachments.length && !msg.embeds.length) return null;

const isHidden = hiddenMessages.has(msg.id);

return {
label: isHidden ? "Show Attachments" : "Hide Attachments",
icon: isHidden ? ImageVisible : ImageInvisible,
message: msg,
channel: ChannelStore.getChannel(msg.channel_id),
onClick: () => this.toggleHide(msg.id)
};
});
},

stop() {
style.remove();
hiddenMessages.clear();
removeButton("HideAttachments");
},

async buildCss() {
Expand All @@ -86,26 +94,6 @@ export default definePlugin({
`;
},

renderButton(msg: Message, makeItem: (data: any) => React.ComponentType) {
try {
if (!msg.attachments.length && !msg.embeds.length) return null;

const isHidden = hiddenMessages.has(msg.id);

return makeItem({
key: "HideAttachments",
label: isHidden ? "Show Attachments" : "Hide Attachments",
icon: isHidden ? ImageVisible : ImageInvisible,
message: msg,
channel: ChannelStore.getChannel(msg.channel_id),
onClick: () => this.toggleHide(msg.id)
});
} catch (err) {
new Logger("HideAttachments").error(err);
return null;
}
},

async toggleHide(id: string) {
const ids = await getHiddenMessages();
if (!ids.delete(id))
Expand Down
43 changes: 18 additions & 25 deletions src/plugins/quickMention.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,34 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import { addButton, removeButton } from "@api/MessagePopover";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findLazy } from "@webpack";
import { ChannelStore } from "@webpack/common";

const ComponentDispatch = findLazy(m => m.emitter?._events?.INSERT_TEXT);

export default definePlugin({
name: "QuickMention",
authors: [Devs.kemo],
description: "Adds a quick mention button to the message actions bar",

patches: [
{
find: "Messages.MESSAGE_UTILITIES_A11Y_LABEL",
replacement: {
match: /(null,)(.{1,3}&&!.{1,3}\?(.{1,3})\(\{key:"reply",label:.{1,10}\.Messages\.MESSAGE_ACTION_REPLY,icon:.{1,10},channel:(.+?),message:(.+?),onClick:.+?\}\))/,
replace: (m, post, og, functionName, channelVar, messageVar) => {

const functionSig =
`${functionName}({
key: "QuickMention",
label: "Mention",
icon: Vencord.Plugins.plugins.QuickMention.Icon,
channel: ${channelVar},
message: ${messageVar},
onClick: ()=> Vencord.Plugins.plugins.QuickMention.onClick(${messageVar})
})`;

return `${post}${functionSig},${og}`;
}
}
}
],
dependencies: ["MessagePopoverAPI"],

start() {
addButton("QuickMention", msg => {
return {
label: "Quick Mention",
icon: this.Icon,
message: msg,
channel: ChannelStore.getChannel(msg.channel_id),
onClick: () => ComponentDispatch.dispatchToLastSubscribed("INSERT_TEXT", { rawText: `<@${msg.author.id}> ` })
};
});
},
stop() {
removeButton("QuickMention");
},

Icon: () => (
<svg
Expand All @@ -63,6 +58,4 @@ export default definePlugin({
/>
</svg>
),

onClick: (message: any) => ComponentDispatch.dispatchToLastSubscribed("INSERT_TEXT", { rawText: `<@${message.author.id}> ` })
});
Loading

0 comments on commit 4760af7

Please sign in to comment.