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 IconButton from "../../ui/IconButton";
|
||||||
|
|
||||||
|
import { PluginSingleton } from "../../../plugins";
|
||||||
import AutoComplete, { useAutoComplete } from "../AutoComplete";
|
import AutoComplete, { useAutoComplete } from "../AutoComplete";
|
||||||
import { PermissionTooltip } from "../Tooltip";
|
import { PermissionTooltip } from "../Tooltip";
|
||||||
import FilePreview from "./bars/FilePreview";
|
import FilePreview from "./bars/FilePreview";
|
||||||
|
@ -185,8 +186,11 @@ export default function MessageBox({ channel }: Props) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const content = draft?.trim() ?? "";
|
const content = draft?.trim() ?? "";
|
||||||
if (uploadState.type === "attached") return sendFile(content);
|
const target = { content };
|
||||||
if (content.length === 0) return;
|
if (PluginSingleton.emit("Message:Send", target)) return;
|
||||||
|
|
||||||
|
if (uploadState.type === "attached") return sendFile(target.content);
|
||||||
|
if (target.content.length === 0) return;
|
||||||
|
|
||||||
stopTyping();
|
stopTyping();
|
||||||
setMessage();
|
setMessage();
|
||||||
|
@ -203,7 +207,7 @@ export default function MessageBox({ channel }: Props) {
|
||||||
channel: channel._id,
|
channel: channel._id,
|
||||||
author: client.user!._id,
|
author: client.user!._id,
|
||||||
|
|
||||||
content,
|
content: target.content,
|
||||||
replies,
|
replies,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -217,7 +221,7 @@ export default function MessageBox({ channel }: Props) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.channels.sendMessage(channel._id, {
|
await client.channels.sendMessage(channel._id, {
|
||||||
content,
|
content: target.content,
|
||||||
nonce,
|
nonce,
|
||||||
replies,
|
replies,
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { render } from "preact";
|
||||||
import { internalEmit } from "./lib/eventEmitter";
|
import { internalEmit } from "./lib/eventEmitter";
|
||||||
|
|
||||||
import { App } from "./pages/app";
|
import { App } from "./pages/app";
|
||||||
|
import "./plugins";
|
||||||
|
|
||||||
export const updateSW = registerSW({
|
export const updateSW = registerSW({
|
||||||
onNeedRefresh() {
|
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