mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-07 01:15:28 +00:00
156 lines
3.7 KiB
TypeScript
156 lines
3.7 KiB
TypeScript
import { Client, Message } from "revolt.js/dist";
|
|
import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
|
|
|
|
import { StateUpdater } from "preact/hooks";
|
|
|
|
import { dispatch } from "../../redux";
|
|
|
|
import { ClientOperations, ClientStatus } from "./RevoltClient";
|
|
|
|
export var preventReconnect = false;
|
|
let preventUntil = 0;
|
|
|
|
export function setReconnectDisallowed(allowed: boolean) {
|
|
preventReconnect = allowed;
|
|
}
|
|
|
|
export function registerEvents(
|
|
{ operations }: { operations: ClientOperations },
|
|
setStatus: StateUpdater<ClientStatus>,
|
|
client: Client,
|
|
) {
|
|
function attemptReconnect() {
|
|
if (preventReconnect) return;
|
|
function reconnect() {
|
|
preventUntil = +new Date() + 2000;
|
|
client.websocket.connect().catch((err) => console.error(err));
|
|
}
|
|
|
|
if (+new Date() > preventUntil) {
|
|
setTimeout(reconnect, 2000);
|
|
} else {
|
|
reconnect();
|
|
}
|
|
}
|
|
|
|
let listeners: Record<string, (...args: any[]) => void> = {
|
|
connecting: () =>
|
|
operations.ready() && setStatus(ClientStatus.CONNECTING),
|
|
|
|
dropped: () => {
|
|
if (operations.ready()) {
|
|
setStatus(ClientStatus.DISCONNECTED);
|
|
attemptReconnect();
|
|
}
|
|
},
|
|
|
|
packet: (packet: ClientboundNotification) => {
|
|
switch (packet.type) {
|
|
case "ChannelStartTyping": {
|
|
if (packet.user === client.user?._id) return;
|
|
dispatch({
|
|
type: "TYPING_START",
|
|
channel: packet.id,
|
|
user: packet.user,
|
|
});
|
|
break;
|
|
}
|
|
case "ChannelStopTyping": {
|
|
if (packet.user === client.user?._id) return;
|
|
dispatch({
|
|
type: "TYPING_STOP",
|
|
channel: packet.id,
|
|
user: packet.user,
|
|
});
|
|
break;
|
|
}
|
|
case "ChannelAck": {
|
|
dispatch({
|
|
type: "UNREADS_MARK_READ",
|
|
channel: packet.id,
|
|
message: packet.message_id,
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
|
|
message: (message: Message) => {
|
|
if (message.mentions?.includes(client.user!._id)) {
|
|
dispatch({
|
|
type: "UNREADS_MENTION",
|
|
channel: message.channel,
|
|
message: message._id,
|
|
});
|
|
}
|
|
},
|
|
|
|
ready: () => setStatus(ClientStatus.ONLINE),
|
|
};
|
|
|
|
if (import.meta.env.DEV) {
|
|
listeners = new Proxy(listeners, {
|
|
get:
|
|
(target, listener, receiver) =>
|
|
(...args: unknown[]) => {
|
|
console.debug(`Calling ${listener.toString()} with`, args);
|
|
Reflect.get(target, listener)(...args);
|
|
},
|
|
});
|
|
}
|
|
|
|
// TODO: clean this a bit and properly handle types
|
|
for (const listener in listeners) {
|
|
client.addListener(listener, listeners[listener]);
|
|
}
|
|
|
|
function logMutation(target: string, key: string) {
|
|
console.log("(o) Object mutated", target, "\nChanged:", key);
|
|
}
|
|
|
|
if (import.meta.env.DEV) {
|
|
client.users.addListener("mutation", logMutation);
|
|
client.servers.addListener("mutation", logMutation);
|
|
client.channels.addListener("mutation", logMutation);
|
|
client.servers.members.addListener("mutation", logMutation);
|
|
}
|
|
|
|
const online = () => {
|
|
if (operations.ready()) {
|
|
setStatus(ClientStatus.RECONNECTING);
|
|
setReconnectDisallowed(false);
|
|
attemptReconnect();
|
|
}
|
|
};
|
|
|
|
const offline = () => {
|
|
if (operations.ready()) {
|
|
setReconnectDisallowed(true);
|
|
client.websocket.disconnect();
|
|
setStatus(ClientStatus.OFFLINE);
|
|
}
|
|
};
|
|
|
|
window.addEventListener("online", online);
|
|
window.addEventListener("offline", offline);
|
|
|
|
return () => {
|
|
for (const listener in listeners) {
|
|
client.removeListener(
|
|
listener,
|
|
listeners[listener as keyof typeof listeners],
|
|
);
|
|
}
|
|
|
|
if (import.meta.env.DEV) {
|
|
client.users.removeListener("mutation", logMutation);
|
|
client.servers.removeListener("mutation", logMutation);
|
|
client.channels.removeListener("mutation", logMutation);
|
|
client.servers.members.removeListener("mutation", logMutation);
|
|
}
|
|
|
|
window.removeEventListener("online", online);
|
|
window.removeEventListener("offline", offline);
|
|
};
|
|
}
|