mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-04 12:50:58 -05:00
Simple plugin proof of concept.
This commit is contained in:
parent
6f6020c474
commit
745ae35c6b
3 changed files with 83 additions and 4 deletions
|
@ -36,6 +36,7 @@ import { takeError } from "../../../context/revoltjs/util";
|
|||
|
||||
import IconButton from "../../ui/IconButton";
|
||||
|
||||
import { PluginSingleton } from "../../../plugins";
|
||||
import AutoComplete, { useAutoComplete } from "../AutoComplete";
|
||||
import { PermissionTooltip } from "../Tooltip";
|
||||
import FilePreview from "./bars/FilePreview";
|
||||
|
@ -185,8 +186,11 @@ export default function MessageBox({ channel }: Props) {
|
|||
return;
|
||||
|
||||
const content = draft?.trim() ?? "";
|
||||
if (uploadState.type === "attached") return sendFile(content);
|
||||
if (content.length === 0) return;
|
||||
const target = { content };
|
||||
if (PluginSingleton.emit("Message:Send", target)) return;
|
||||
|
||||
if (uploadState.type === "attached") return sendFile(target.content);
|
||||
if (target.content.length === 0) return;
|
||||
|
||||
stopTyping();
|
||||
setMessage();
|
||||
|
@ -203,7 +207,7 @@ export default function MessageBox({ channel }: Props) {
|
|||
channel: channel._id,
|
||||
author: client.user!._id,
|
||||
|
||||
content,
|
||||
content: target.content,
|
||||
replies,
|
||||
},
|
||||
});
|
||||
|
@ -217,7 +221,7 @@ export default function MessageBox({ channel }: Props) {
|
|||
|
||||
try {
|
||||
await client.channels.sendMessage(channel._id, {
|
||||
content,
|
||||
content: target.content,
|
||||
nonce,
|
||||
replies,
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import { render } from "preact";
|
|||
import { internalEmit } from "./lib/eventEmitter";
|
||||
|
||||
import { App } from "./pages/app";
|
||||
import "./plugins";
|
||||
|
||||
export const updateSW = registerSW({
|
||||
onNeedRefresh() {
|
||||
|
|
74
src/plugins/index.ts
Normal file
74
src/plugins/index.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { Children } from "../types/Preact";
|
||||
|
||||
export interface PluginEvent<T> {
|
||||
cancel: () => void;
|
||||
target: T;
|
||||
}
|
||||
|
||||
export interface PluginEvents {
|
||||
"Message:Send": (
|
||||
event: PluginEvent<{ content?: string; files?: File[] }>,
|
||||
) => void;
|
||||
"Misc:Test": (event: PluginEvent<string>) => void;
|
||||
}
|
||||
|
||||
export interface Plugin {
|
||||
render?: () => Children;
|
||||
events?: Partial<PluginEvents>;
|
||||
}
|
||||
|
||||
class Singleton {
|
||||
listeners: {
|
||||
[key in keyof PluginEvents]?: PluginEvents[key][];
|
||||
};
|
||||
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
}
|
||||
|
||||
private getListenerArray<K extends keyof PluginEvents>(
|
||||
key: K,
|
||||
): PluginEvents[K][] {
|
||||
const arr = this.listeners[key];
|
||||
if (arr) return arr as PluginEvents[K][];
|
||||
|
||||
this.listeners[key] = [];
|
||||
return this.listeners[key]! as PluginEvents[K][];
|
||||
}
|
||||
|
||||
addListener<K extends keyof PluginEvents>(key: K, fn: PluginEvents[K]) {
|
||||
this.getListenerArray(key).push(fn);
|
||||
}
|
||||
|
||||
emit<K extends keyof PluginEvents>(
|
||||
key: K,
|
||||
target: Parameters<PluginEvents[K]>[0]["target"],
|
||||
): boolean {
|
||||
let canceled = false;
|
||||
|
||||
const ev: PluginEvent<any> = {
|
||||
cancel: () => (canceled = true),
|
||||
target,
|
||||
};
|
||||
|
||||
const arr = this.getListenerArray(key);
|
||||
for (const listener of arr) {
|
||||
listener(ev);
|
||||
if (canceled) break;
|
||||
}
|
||||
|
||||
return canceled;
|
||||
}
|
||||
}
|
||||
|
||||
export const PluginSingleton = new Singleton();
|
||||
|
||||
PluginSingleton.addListener("Message:Send", (event) => {
|
||||
const { content } = event.target;
|
||||
if (content?.startsWith(";sus")) {
|
||||
event.target.content = "baka!";
|
||||
} else if (content?.startsWith(";amogus")) {
|
||||
alert("fat");
|
||||
event.cancel();
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue