From 97de01af36d8a9d5a224281027b525f1a53a745c Mon Sep 17 00:00:00 2001 From: Jack Matthews Date: Sun, 5 Feb 2023 17:36:00 -0500 Subject: [PATCH] Add importing rules from a message --- src/index.ts | 4 +- src/patches/MessageLongPressActionSheet.tsx | 61 +++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/patches/MessageLongPressActionSheet.tsx diff --git a/src/index.ts b/src/index.ts index e449f74..7339ade 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { storage } from "@vendetta/plugin"; +import patchMessageLongPressActionSheet from "./patches/MessageLongPressActionSheet"; import patchSendMessage from "./patches/sendMessage"; import Settings from "./ui/pages/Settings"; @@ -8,7 +9,8 @@ export default { onLoad: () => { storage.rules ??= []; patches = [ - patchSendMessage() + patchSendMessage(), + patchMessageLongPressActionSheet() ]; }, onUnload: () => { diff --git a/src/patches/MessageLongPressActionSheet.tsx b/src/patches/MessageLongPressActionSheet.tsx new file mode 100644 index 0000000..3646537 --- /dev/null +++ b/src/patches/MessageLongPressActionSheet.tsx @@ -0,0 +1,61 @@ +import { findByDisplayName, findByProps } from "@vendetta/metro"; +import { after } from "@vendetta/patcher"; +import { storage } from "@vendetta/plugin"; +import { getAssetIDByName } from "@vendetta/ui/assets"; +import { Forms } from "@vendetta/ui/components"; +import { showToast } from "@vendetta/ui/toasts"; + +const LazyActionSheet = findByProps("openLazy", "hideActionSheet"); + +// Components +const { FormRow } = Forms; +const MessageLongPressActionSheet = findByProps("EmojiRow"); +const Icon = findByDisplayName("Icon"); + +const JSON_CODEBLOCK_PATTERN = /^```(?:json)\n([\s\S]*?)```$/gm + +const Download = getAssetIDByName("ic_download_24px"); + +export default function patchMessageLongPressActionSheet() { + return after("default", MessageLongPressActionSheet, ([{ message }], res) => { + // Get rules from message + const rules = message.content.match(JSON_CODEBLOCK_PATTERN)?.map((rule: string) => { + // Remove codeblock stuff + return rule.slice(7, rule.length - 3); + }).map((rule: string) => { + // Turn into a object + try { + return JSON.parse(rule); + } catch { + return undefined; + }; + // Filter out undefined + }).filter((rule) => rule).filter((rule) => + // Check it's a valid rule + typeof rule.name == "string" && rule.name && + typeof rule.match == "string" && typeof rule.replace == "string" && + typeof rule.flags == "string" && typeof rule.regex == "boolean" + ); + + // Don't add anything if we have no importable rules + if (!rules || rules.length == 0) return; + + let buttons = res?.props?.children?.props?.children?.props?.children[1]; + + for (const rule of rules) { + const importRuleCallback = () => { + storage.rules.push(rule); + showToast(`Imported rule ${rule.name}`, Download); + LazyActionSheet.hideActionSheet(); + }; + + const importRuleButton = (} + label={`Import ${rule.name}`} + onPress={importRuleCallback} + />); + + buttons.unshift(importRuleButton); + } + }); +};