diff --git a/src/core/plugins/NoDelete/index.js b/src/core/plugins/NoDelete/index.js deleted file mode 100644 index 3efe0dc..0000000 --- a/src/core/plugins/NoDelete/index.js +++ /dev/null @@ -1,80 +0,0 @@ -// src/core/plugins/NoDelete/index.ts -import { defineCorePlugin } from ".."; -import { findByProps, findByStoreName } from "@metro"; -import { before } from "@lib/api/patcher"; -import { logger } from "@lib/utils/logger"; -import { FluxDispatcher } from "@metro/common"; - -type PatchCleanupFn = () => void; - -let patches: PatchCleanupFn[] = []; -let MessageStore: any = null; -let deleteable: string[] = []; - -function patchDispatcher(): PatchCleanupFn { - return before("dispatch", FluxDispatcher, (args: any[]) => { - try { - if (!MessageStore) MessageStore = findByStoreName("MessageStore"); - - const event = args[0]; - if (!event || event?.type !== "MESSAGE_DELETE") return; - if (!event?.id || !event?.channelId) return; - - // If this deletion was triggered by us, allow it through - if (deleteable.includes(event.id)) { - deleteable.splice(deleteable.indexOf(event.id), 1); - return; - } - - // Mark this message id so we don't loop - deleteable.push(event.id); - - // Replace MESSAGE_DELETE with a fake automod edit-failed event - // so the message stays visible but shows as "[deleted]" - args[0] = { - type: "MESSAGE_EDIT_FAILED_AUTOMOD", - messageData: { - type: 1, - message: { - channelId: event.channelId, - messageId: event.id, - }, - }, - errorResponseBody: { - code: 200000, - message: "[deleted]", - }, - }; - } catch (e) { - logger.error("NoDelete: dispatcher patch failed", e); - } - }); -} - -export default defineCorePlugin({ - manifest: { - id: "bunny.nodelete", - version: "1.0.0", - type: "plugin", - spec: 3, - main: "", - display: { - name: "NoDelete", - description: "Prevents messages from being deleted from your view", - authors: [{ name: "dumsane" }], - }, - }, - - start() { - patches = [patchDispatcher()].filter(Boolean); - logger.log("NoDelete: Enabled"); - }, - - stop() { - patches.forEach((p) => p?.()); - patches = []; - deleteable = []; - MessageStore = null; - logger.log("NoDelete: Disabled"); - }, -}); diff --git a/src/core/plugins/NoDelete/settings.jsx b/src/core/plugins/NoDelete/settings.jsx deleted file mode 100644 index 89c58b7..0000000 --- a/src/core/plugins/NoDelete/settings.jsx +++ /dev/null @@ -1,90 +0,0 @@ -import { React, ReactNative } from "@vendetta/metro/common"; -import { storage } from "@vendetta/plugin"; -import { useProxy } from "@vendetta/storage"; -import { showConfirmationAlert } from "@vendetta/ui/alerts"; -import { Forms } from "@vendetta/ui/components"; -import { getAssetIDByName } from "@vendetta/ui/assets"; -import { getTranslation } from "./translations.js"; -import ItemWithRemove from "../../common/ui/ItemWithRemove.jsx"; -import { findByStoreName, findByProps } from "@vendetta/metro"; -let UserStore, UncachedUserManager, Profiles; -export default (props) => { - UserStore ??= findByStoreName("UserStore"); - UncachedUserManager ??= findByProps("fetchProfile", "getUser", "setFlag"); - Profiles ??= findByProps("showUserProfile"); - async function openProfile(userId) { - const show = Profiles.showUserProfile; - - UserStore.getUser(userId) ? show({ userId }) : UncachedUserManager.getUser(userId).then(({ id }) => show({ userId: id })); - } - - useProxy(storage); - const [users, setUsers] = React.useState(storage["ignore"]["users"]); - - const handleRemoveUser = (userId) => { - const newArr = users.filter((id) => id !== userId); - storage["ignore"].users = newArr; - setUsers(newArr); - }; - const handleClearUsers = () => { - storage["ignore"].users = []; - setUsers([]); - }; - let uncached = 0; - - return ( - - - (storage.timestamps = v)} />} /> - (storage.ew = v)} />} /> - - - - - (storage["ignore"].bots = value)} />} /> - } - onPress={() => { - if (users.length !== 0) - showConfirmationAlert({ - title: getTranslation("settings.confirmClear.title"), - content: getTranslation("settings.confirmClear.description", true)?.make?.(users.length), - confirmText: getTranslation("settings.confirmClear.yes"), - cancelText: getTranslation("settings.confirmClear.no"), - confirmColor: "brand", - onConfirm: handleClearUsers, - }); - }} - /> - - {users.map((id) => { - const User = UserStore.getUser(id) ?? {}; - let pfp = User?.getAvatarURL?.(null,26)?.replace?.(/\.(gif|webp)/, ".png"); - if (!pfp) { - pfp = "https://cdn.discordapp.com/embed/avatars/1.png?size=48"; - User.username = `${id} Uncached`; - User.discriminator = "0"; - if (uncached === 0) User.username += ", press the avatar"; - uncached++; - } - - return ( - { - openProfile(id); - }} - onRemove={() => handleRemoveUser(id)} - label={User.username + (User.discriminator == 0 ? "" : `#${User.discriminator}`)} - labelRemove={getTranslation("settings.removeUserButton")} - /> - ); - })} - - - - - - ); -}; diff --git a/src/core/plugins/NoDelete/translations.js b/src/core/plugins/NoDelete/translations.js deleted file mode 100644 index 4144b7e..0000000 --- a/src/core/plugins/NoDelete/translations.js +++ /dev/null @@ -1,158 +0,0 @@ -function slavicNoun(number, $1, $2, $5) { - let n = Math.abs(number); - n %= 100; - if (n >= 5 && n <= 20) return $5; - - n %= 10; - if (n === 1) return $1; - if (n >= 2 && n <= 4) return $2; - return $5; -} -function latinNoun(number, $1, $x) { - return number === 1 ? $1 : $x; -} -export let massive = {}; -massive = { - settings: { - titles: { - settings: { - "en-GB": "Settings", - uk: "Налаштування", - ru: "Настройки", - }, - filters: { - "en-GB": "Filters", - uk: "Фільтри", - ru: "Фильтры", - }, - }, - showTimestamps: { - "en-GB": "Show the time of deletion", - uk: "Показувати час видалення", - ru: "Показывать время удаления", - }, - ewTimestampFormat: { - "en-GB": "Use 12-hour format", - uk: "Використовувати 12-годинний формат", - ru: "Использовать 12-часовой формат", - }, - youDeletedItWarning: { - "en-GB": "The messages YOU deleted - are not saved", - uk: "Повідомлення які видалили ВИ - не зберігаются", - ru: "Сообщения удаленные ВАМИ - не сохраняются", - }, - addUsersInfo: { - "en-GB": () => - `To add or remove users from the ignore list, follow these steps:\n` + - `1. open their profile\n` + - `2. press the •••\n` + - `3. press "${massive.optionLabels[0]["en-GB"]}"\n` + - `4. 🎉`, - uk: () => - `Щоб добавити когось до списку ігнорованих користувачів, виконайте ці дії:\n` + - `1. відкрите їх профіль\n` + - `2. натисніть •••\n` + - `3. натисніть "${massive.optionLabels[0]["uk"]}"\n` + - `4. 🎉`, - ru: () => - `Чтобы добавить кого-то в список игнорированных пользователей - следуйте этим шагам\n` + - `1. откройте их профиль\n` + - `2. нажмите •••\n` + - `3. нажмите "${massive.optionLabels[0]["ru"]}"\n` + - `4. 🎉`, - }, - ignoreBots: { - "en-GB": "Ignore bots", - uk: "Ігнорувати ботів", - ru: "Игнорировать ботов", - }, - clearUsersLabel: { - "en-GB": (amount) => - `You have ${amount} user${latinNoun(amount, "", "s")} in the ignored users list`, - uk: (amount) => - `Ви маєте ${amount} користувач${slavicNoun(amount, "а", "а", "ів")} у списку ігнорованих користувачів`, - ru: (amount) => - `Вы имеете ${amount} пользовател${slavicNoun(amount, "я", "я", "ей")} в списке игнорированных пользователей`, - }, - - confirmClear: { - title: { - "en-GB": "Hold on!", - uk: "Почекай-но!", - ru: "Положди-ка!", - }, - description: { - "en-GB": (amount) => - `This will remove ${amount} user${latinNoun(amount, "", "s")} from the ignored users list.\nDo you you really want to do that?`, - uk: (amount) => - `Це прибере ${amount} користувач${slavicNoun(amount, "а", "а", "ів")} зі списку ігнорованих користувачів.\nВи дійсно хочете продовжити?`, - ru: (amount) => - `Это уберет ${amount} пользовател${slavicNoun(amount, "я", "я", "ей")} из списка игнорированных пользователей.\nВы действительно хотите продолжить?`, - }, - yes: { - "en-GB": "Yes", - uk: "Так", - ru: "Да", - }, - no: { - "en-GB": "Cancel", - uk: "Відминити", - ru: "Отменить", - }, - }, - removeUserButton: { - "en-GB": "REMOVE", - uk: "ПРИБРАТИ", - ru: "УБРАТЬ", - }, - }, - optionLabels: [ - { - "en-GB": "Add to NoDelete ignored users list", - uk: "Добавити до списку ігнорованих користувачів у NoDelete", - ru: "Добавить в список игнорированных пользователей в NoDelete", - }, - { - "en-GB": "Remove from the NoDelete ignore list", - uk: "Прибрати з списку ігнорованих користувачів у NoDelete", - ru: "Убрать из списка игнорированных пользователей в NoDelete", - }, - ], - toastLabels: [ - { - "en-GB": "Added {user} to the ignored users list", - uk: "{user} добавлено до списку ігнорованих користувачів", - ru: "{user} добавлены в список игнорированных пользователей", - }, - { - "en-GB": "Removed {user} from the ignored users list", - uk: "{user} прибрано зі списку ігнорованих користувачів", - ru: "{user} убраны из списка игнорированных пользователей", - }, - ], - thisMessageWasDeleted: { - "en-GB": "This message was deleted", - uk: "Це повідомлення було видалено", - ru: "Это сообщение было удалено", - }, -}; - -export const locale = () => - vendetta.metro.findByStoreName("LocaleStore").locale; -const defaultLocale = "en-GB"; -export function getTranslation(find, fn) { - let value = massive; - - for (const key of find.split(".")) { - // biome-ignore lint/suspicious/noPrototypeBuiltins: meow - if (value?.hasOwnProperty(key)) { - value = value[key]; - } else { - value = massive; - } - } - if (value === massive) return find; - let localized = value[locale()] ?? value[defaultLocale] ?? find; - if (typeof localized === "function" && !fn) localized = localized(); - return fn ? { make: localized } : localized; -}