Update index.js
This commit is contained in:
parent
6c475e69be
commit
a731776639
1 changed files with 78 additions and 136 deletions
|
|
@ -1,138 +1,80 @@
|
|||
import settings from "./settings.jsx";
|
||||
import * as common from "../../common";
|
||||
import { FluxDispatcher, moment } from "@vendetta/metro/common";
|
||||
import { storage } from "@vendetta/plugin";
|
||||
import { before as patchBefore } from "@vendetta/patcher";
|
||||
import { findByProps, findByStoreName } from "@vendetta/metro";
|
||||
import { findInReactTree } from "@vendetta/utils";
|
||||
import { showToast } from "@vendetta/ui/toasts";
|
||||
import { getTranslation, massive } from "./translations.js";
|
||||
//import { dispatcherPatch } from "./patches/dispatcher.js";
|
||||
//import { contextMenuPatch } from "./patches/contextMenu.js"
|
||||
// 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";
|
||||
|
||||
common.makeDefaults(storage, {
|
||||
ignore: {
|
||||
users: [],
|
||||
channels: [],
|
||||
bots: false,
|
||||
},
|
||||
timestamps: false,
|
||||
ew: false,
|
||||
onlyTimestamps: false,
|
||||
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");
|
||||
},
|
||||
});
|
||||
let MessageStore,
|
||||
deleteable = [];
|
||||
|
||||
const patches = []
|
||||
export default {
|
||||
settings,
|
||||
onUnload() {
|
||||
for (const unpatch of patches) unpatch()
|
||||
},
|
||||
onLoad() {
|
||||
try {
|
||||
patches.push(
|
||||
patchBefore("dispatch", FluxDispatcher, (args) => {
|
||||
try {
|
||||
if (!MessageStore) MessageStore = findByStoreName("MessageStore");
|
||||
const event = args[0];
|
||||
|
||||
if (!event || event?.type !== "MESSAGE_DELETE") return;
|
||||
if (!event?.id || !event?.channelId) return;
|
||||
|
||||
const message = MessageStore.getMessage(event.channelId, event.id);
|
||||
|
||||
if (storage["ignore"]["users"].includes(message?.author?.id)) return;
|
||||
if (storage["ignore"]["bots"] && message?.author?.bot) return;
|
||||
|
||||
if (deleteable.includes(event.id)) {
|
||||
deleteable.splice(deleteable.indexOf(event.id), 1);
|
||||
return args;
|
||||
}
|
||||
deleteable.push(event.id);
|
||||
|
||||
let automodMessage = getTranslation("thisMessageWasDeleted");
|
||||
if (storage["timestamps"]) automodMessage += ` (${moment().format(storage["ew"] ? "hh:mm:ss.SS a" : "HH:mm:ss.SS")})`;
|
||||
|
||||
// overwrite the message delete event with the automod edit fail one
|
||||
args[0] = {
|
||||
type: "MESSAGE_EDIT_FAILED_AUTOMOD",
|
||||
messageData: {
|
||||
type: 1,
|
||||
message: {
|
||||
channelId: event.channelId,
|
||||
messageId: event.id,
|
||||
},
|
||||
},
|
||||
errorResponseBody: {
|
||||
code: 200000,
|
||||
message: automodMessage,
|
||||
},
|
||||
};
|
||||
return args;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert(`[Nodelete → dispatcher patch] died\n${e.stack}`);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
/* thanks fres#2400 (<@843448897737064448>) for example patch
|
||||
* add ignore user button
|
||||
*/
|
||||
const contextMenuUnpatch = patchBefore("render", findByProps("ScrollView").View, (args) => {
|
||||
try {
|
||||
const a = findInReactTree(args, (r) => r.key === ".$UserProfileOverflow");
|
||||
if (!a || !a.props || a.props.sheetKey !== "UserProfileOverflow") return;
|
||||
const props = a.props.content.props;
|
||||
const _labels = massive.optionLabels.flatMap(Object.values);
|
||||
if (props.options.some((option) => _labels.includes(option?.label))) return;
|
||||
|
||||
const focusedUserId = Object.keys(a._owner.stateNode._keyChildMapping)
|
||||
.find((str) => a._owner.stateNode._keyChildMapping[str] && str.match(/(?<=\$UserProfile)\d+/))
|
||||
?.slice?.(".$UserProfile".length);
|
||||
|
||||
const optionPosition = props.options.findLastIndex((option) => option.isDestructive);
|
||||
if (!storage["ignore"]["users"].includes(focusedUserId)) {
|
||||
props.options.splice(optionPosition + 1, 0, {
|
||||
isDestructive: true,
|
||||
label: getTranslation("optionLabels.0"), // START IGNORING
|
||||
onPress: () => {
|
||||
storage["ignore"]["users"].push(focusedUserId);
|
||||
showToast(getTranslation("toastLabels.0").replaceAll("{user}", props.header.title));
|
||||
|
||||
props.hideActionSheet();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
props.options.splice(optionPosition + 1, 0, {
|
||||
label: getTranslation("optionLabels.1"), // STOP IGNORING
|
||||
onPress: () => {
|
||||
storage["ignore"]["users"].splice(
|
||||
storage["ignore"]["users"].findIndex((userId) => userId === focusedUserId),
|
||||
1
|
||||
);
|
||||
showToast(getTranslation("toastLabels.1").replaceAll("{user}", props.header.title));
|
||||
|
||||
props.hideActionSheet();
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
let successful = false;
|
||||
try {
|
||||
successful = contextMenuUnpatch();
|
||||
} catch (_) {
|
||||
successful = false;
|
||||
}
|
||||
alert(`[NoDelete → context menu patch] failed. Patch ${successful ? "dis" : "en"}abled\n${e.stack}`);
|
||||
}
|
||||
});
|
||||
patches.push(contextMenuUnpatch);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert(`[NoDelete] dead\n${e.stack}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue