diff --git a/src/plugins/clickableRoleDot.ts b/src/plugins/clickableRoleDot.ts new file mode 100644 index 0000000..63ad84e --- /dev/null +++ b/src/plugins/clickableRoleDot.ts @@ -0,0 +1,31 @@ +import definePlugin from "../utils/types"; +import { Toasts } from '../webpack/common'; + +export default definePlugin({ + name: "ClickableRoleDot", + author: "Vendicated", + description: + "Makes RoleDots (Accessibility Feature) copy colour to clipboard on click", + patches: [ + { + find: "M0 4C0 1.79086 1.79086 0 4 0H16C18.2091 0 20 1.79086 20 4V16C20 18.2091 18.2091 20 16 20H4C1.79086 20 0 18.2091 0 16V4Z", + replacement: { + match: /(viewBox:"0 0 20 20")/, + replace: "$1,onClick:()=>Vencord.Plugins.plugins.ClickableRoleDot.copyToClipBoard(e.color)", + }, + }, + ], + + copyToClipBoard(color: string) { + DiscordNative.clipboard.copy(color); + Toasts.show({ + message: "Copied to Clipboard!", + type: Toasts.Type.SUCCESS, + id: Toasts.genId(), + options: { + duration: 1000, + position: Toasts.Position.BOTTOM + } + }); + } +}); diff --git a/src/webpack/common.tsx b/src/webpack/common.tsx index f3cb018..6e93e27 100644 --- a/src/webpack/common.tsx +++ b/src/webpack/common.tsx @@ -7,11 +7,50 @@ import type Other from "discord-types/other"; export let FluxDispatcher: Other.FluxDispatcher; export let React: typeof import("react"); export let UserStore: Stores.UserStore; -export let Forms: any = {}; +export const Forms: any = {}; export let Button: any; export let Switch: any; export let Tooltip: Components.Tooltip; +const ToastType = { + MESSAGE: 0, + SUCCESS: 1, + FAILURE: 2, + CUSTOM: 3 +}; +const ToastPosition = { + TOP: 0, + BOTTOM: 1 +}; + +export const Toasts = { + Type: ToastType, + Position: ToastPosition, + // what's less likely than getting 0 from Math.random()? Getting it twice in a row + genId: () => (Math.random() || Math.random()).toString(36).slice(2) +} as { + Type: typeof ToastType, + Position: typeof ToastPosition; + genId(): string; + show(data: { + message: string, + id: string, + /** + * Toasts.Type + */ + type: number, + options?: { + /** + * Toasts.Position + */ + position?: number; + component?: React.ReactNode, + duration?: number; + }; + }): void; + pop(): void; +}; + waitFor("useState", m => React = m); waitFor(["dispatch", "subscribe"], m => { FluxDispatcher = m; @@ -35,3 +74,7 @@ waitFor(m => { const s = m.toString(); return s.length < 200 && s.includes("divider"); }, m => Forms.FormDivider = m); + +// This is the same module but this is easier +waitFor(filters.byCode("currentToast?"), m => Toasts.show = m); +waitFor(filters.byCode("currentToast:null"), m => Toasts.pop = m); diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts index b8f10e4..64e2310 100644 --- a/src/webpack/webpack.ts +++ b/src/webpack/webpack.ts @@ -18,7 +18,7 @@ export const filters = { if (!s.includes(c)) return false; } return true; - } + }, }; export const subscriptions = new Map();