forked from abner/for-legacy-web
Make the linter happy.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Plus, X, XCircle } from "@styled-icons/boxicons-regular";
|
||||
import { Plus } from "@styled-icons/boxicons-regular";
|
||||
import { Pencil } from "@styled-icons/boxicons-solid";
|
||||
import Axios, { AxiosRequestConfig } from "axios";
|
||||
|
||||
@@ -147,6 +147,7 @@ export function FileUploader(props: Props) {
|
||||
}
|
||||
|
||||
if (props.behaviour === "multi" && props.append) {
|
||||
// eslint-disable-next-line
|
||||
useEffect(() => {
|
||||
// File pasting.
|
||||
function paste(e: ClipboardEvent) {
|
||||
@@ -210,7 +211,7 @@ export function FileUploader(props: Props) {
|
||||
document.removeEventListener("dragover", dragover);
|
||||
document.removeEventListener("drop", drop);
|
||||
};
|
||||
}, [props.append]);
|
||||
}, [openScreen, props, props.append]);
|
||||
}
|
||||
|
||||
if (props.style === "icon" || props.style === "banner") {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { autorun, reaction } from "mobx";
|
||||
import { Route, Switch, useHistory, useParams } from "react-router-dom";
|
||||
import { Presence, RelationshipStatus } from "revolt-api/types/Users";
|
||||
import { SYSTEM_USER_ID } from "revolt.js";
|
||||
@@ -6,7 +5,7 @@ import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
import { useContext, useEffect } from "preact/hooks";
|
||||
import { useCallback, useContext, useEffect } from "preact/hooks";
|
||||
|
||||
import { useTranslation } from "../../lib/i18n";
|
||||
|
||||
@@ -52,191 +51,206 @@ function Notifier({ options, notifs }: Props) {
|
||||
const history = useHistory();
|
||||
const playSound = useContext(SoundContext);
|
||||
|
||||
async function message(msg: Message) {
|
||||
if (msg.author_id === client.user!._id) return;
|
||||
if (msg.channel_id === channel_id && document.hasFocus()) return;
|
||||
if (client.user!.status?.presence === Presence.Busy) return;
|
||||
if (msg.author?.relationship === RelationshipStatus.Blocked) return;
|
||||
const message = useCallback(
|
||||
async (msg: Message) => {
|
||||
if (msg.author_id === client.user!._id) return;
|
||||
if (msg.channel_id === channel_id && document.hasFocus()) return;
|
||||
if (client.user!.status?.presence === Presence.Busy) return;
|
||||
if (msg.author?.relationship === RelationshipStatus.Blocked) return;
|
||||
|
||||
const notifState = getNotificationState(notifs, msg.channel!);
|
||||
if (!shouldNotify(notifState, msg, client.user!._id)) return;
|
||||
const notifState = getNotificationState(notifs, msg.channel!);
|
||||
if (!shouldNotify(notifState, msg, client.user!._id)) return;
|
||||
|
||||
playSound("message");
|
||||
if (!showNotification) return;
|
||||
playSound("message");
|
||||
if (!showNotification) return;
|
||||
|
||||
let title;
|
||||
switch (msg.channel?.channel_type) {
|
||||
case "SavedMessages":
|
||||
return;
|
||||
case "DirectMessage":
|
||||
title = `@${msg.author?.username}`;
|
||||
break;
|
||||
case "Group":
|
||||
if (msg.author?._id === SYSTEM_USER_ID) {
|
||||
title = msg.channel.name;
|
||||
} else {
|
||||
title = `@${msg.author?.username} - ${msg.channel.name}`;
|
||||
let title;
|
||||
switch (msg.channel?.channel_type) {
|
||||
case "SavedMessages":
|
||||
return;
|
||||
case "DirectMessage":
|
||||
title = `@${msg.author?.username}`;
|
||||
break;
|
||||
case "Group":
|
||||
if (msg.author?._id === SYSTEM_USER_ID) {
|
||||
title = msg.channel.name;
|
||||
} else {
|
||||
title = `@${msg.author?.username} - ${msg.channel.name}`;
|
||||
}
|
||||
break;
|
||||
case "TextChannel":
|
||||
title = `@${msg.author?.username} (#${msg.channel.name}, ${msg.channel.server?.name})`;
|
||||
break;
|
||||
default:
|
||||
title = msg.channel?._id;
|
||||
break;
|
||||
}
|
||||
|
||||
let image;
|
||||
if (msg.attachments) {
|
||||
const imageAttachment = msg.attachments.find(
|
||||
(x) => x.metadata.type === "Image",
|
||||
);
|
||||
if (imageAttachment) {
|
||||
image = client.generateFileURL(imageAttachment, {
|
||||
max_side: 720,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "TextChannel":
|
||||
title = `@${msg.author?.username} (#${msg.channel.name}, ${msg.channel.server?.name})`;
|
||||
break;
|
||||
default:
|
||||
title = msg.channel?._id;
|
||||
break;
|
||||
}
|
||||
|
||||
let image;
|
||||
if (msg.attachments) {
|
||||
const imageAttachment = msg.attachments.find(
|
||||
(x) => x.metadata.type === "Image",
|
||||
);
|
||||
if (imageAttachment) {
|
||||
image = client.generateFileURL(imageAttachment, {
|
||||
max_side: 720,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let body, icon;
|
||||
if (typeof msg.content === "string") {
|
||||
body = client.markdownToText(msg.content);
|
||||
icon = msg.author?.generateAvatarURL({ max_side: 256 });
|
||||
} else {
|
||||
const users = client.users;
|
||||
switch (msg.content.type) {
|
||||
case "user_added":
|
||||
case "user_remove":
|
||||
{
|
||||
let user = users.get(msg.content.id);
|
||||
body = translate(
|
||||
`app.main.channel.system.${
|
||||
msg.content.type === "user_added"
|
||||
? "added_by"
|
||||
: "removed_by"
|
||||
}`,
|
||||
{
|
||||
user: user?.username,
|
||||
other_user: users.get(msg.content.by)?.username,
|
||||
},
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "user_joined":
|
||||
case "user_left":
|
||||
case "user_kicked":
|
||||
case "user_banned":
|
||||
{
|
||||
let user = users.get(msg.content.id);
|
||||
body = translate(
|
||||
`app.main.channel.system.${msg.content.type}`,
|
||||
{ user: user?.username },
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "channel_renamed":
|
||||
{
|
||||
let user = users.get(msg.content.by);
|
||||
body = translate(
|
||||
`app.main.channel.system.channel_renamed`,
|
||||
{
|
||||
user: users.get(msg.content.by)?.username,
|
||||
name: msg.content.name,
|
||||
},
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "channel_description_changed":
|
||||
case "channel_icon_changed":
|
||||
{
|
||||
let user = users.get(msg.content.by);
|
||||
body = translate(
|
||||
`app.main.channel.system.${msg.content.type}`,
|
||||
{ user: users.get(msg.content.by)?.username },
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const notif = await createNotification(title!, {
|
||||
icon,
|
||||
image,
|
||||
body,
|
||||
timestamp: decodeTime(msg._id),
|
||||
tag: msg.channel?._id,
|
||||
badge: "/assets/icons/android-chrome-512x512.png",
|
||||
silent: true,
|
||||
});
|
||||
|
||||
if (notif) {
|
||||
notif.addEventListener("click", () => {
|
||||
window.focus();
|
||||
const id = msg.channel_id;
|
||||
if (id !== channel_id) {
|
||||
const channel = client.channels.get(id);
|
||||
if (channel) {
|
||||
if (channel.channel_type === "TextChannel") {
|
||||
history.push(
|
||||
`/server/${channel.server_id}/channel/${id}`,
|
||||
let body, icon;
|
||||
if (typeof msg.content === "string") {
|
||||
body = client.markdownToText(msg.content);
|
||||
icon = msg.author?.generateAvatarURL({ max_side: 256 });
|
||||
} else {
|
||||
const users = client.users;
|
||||
switch (msg.content.type) {
|
||||
case "user_added":
|
||||
case "user_remove":
|
||||
{
|
||||
const user = users.get(msg.content.id);
|
||||
body = translate(
|
||||
`app.main.channel.system.${
|
||||
msg.content.type === "user_added"
|
||||
? "added_by"
|
||||
: "removed_by"
|
||||
}`,
|
||||
{
|
||||
user: user?.username,
|
||||
other_user: users.get(msg.content.by)
|
||||
?.username,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
history.push(`/channel/${id}`);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "user_joined":
|
||||
case "user_left":
|
||||
case "user_kicked":
|
||||
case "user_banned":
|
||||
{
|
||||
const user = users.get(msg.content.id);
|
||||
body = translate(
|
||||
`app.main.channel.system.${msg.content.type}`,
|
||||
{ user: user?.username },
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "channel_renamed":
|
||||
{
|
||||
const user = users.get(msg.content.by);
|
||||
body = translate(
|
||||
`app.main.channel.system.channel_renamed`,
|
||||
{
|
||||
user: users.get(msg.content.by)?.username,
|
||||
name: msg.content.name,
|
||||
},
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "channel_description_changed":
|
||||
case "channel_icon_changed":
|
||||
{
|
||||
const user = users.get(msg.content.by);
|
||||
body = translate(
|
||||
`app.main.channel.system.${msg.content.type}`,
|
||||
{ user: users.get(msg.content.by)?.username },
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const notif = await createNotification(title!, {
|
||||
icon,
|
||||
image,
|
||||
body,
|
||||
timestamp: decodeTime(msg._id),
|
||||
tag: msg.channel?._id,
|
||||
badge: "/assets/icons/android-chrome-512x512.png",
|
||||
silent: true,
|
||||
});
|
||||
|
||||
notifications[msg.channel_id] = notif;
|
||||
notif.addEventListener(
|
||||
"close",
|
||||
() => delete notifications[msg.channel_id],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function relationship(user: User) {
|
||||
if (client.user?.status?.presence === Presence.Busy) return;
|
||||
if (!showNotification) return;
|
||||
|
||||
let event;
|
||||
switch (user.relationship) {
|
||||
case RelationshipStatus.Incoming:
|
||||
event = translate("notifications.sent_request", {
|
||||
person: user.username,
|
||||
if (notif) {
|
||||
notif.addEventListener("click", () => {
|
||||
window.focus();
|
||||
const id = msg.channel_id;
|
||||
if (id !== channel_id) {
|
||||
const channel = client.channels.get(id);
|
||||
if (channel) {
|
||||
if (channel.channel_type === "TextChannel") {
|
||||
history.push(
|
||||
`/server/${channel.server_id}/channel/${id}`,
|
||||
);
|
||||
} else {
|
||||
history.push(`/channel/${id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case RelationshipStatus.Friend:
|
||||
event = translate("notifications.now_friends", {
|
||||
person: user.username,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const notif = await createNotification(event, {
|
||||
icon: user.generateAvatarURL({ max_side: 256 }),
|
||||
badge: "/assets/icons/android-chrome-512x512.png",
|
||||
timestamp: +new Date(),
|
||||
});
|
||||
notifications[msg.channel_id] = notif;
|
||||
notif.addEventListener(
|
||||
"close",
|
||||
() => delete notifications[msg.channel_id],
|
||||
);
|
||||
}
|
||||
},
|
||||
[
|
||||
history,
|
||||
showNotification,
|
||||
translate,
|
||||
channel_id,
|
||||
client,
|
||||
notifs,
|
||||
playSound,
|
||||
],
|
||||
);
|
||||
|
||||
notif?.addEventListener("click", () => {
|
||||
history.push(`/friends`);
|
||||
});
|
||||
}
|
||||
const relationship = useCallback(
|
||||
async (user: User) => {
|
||||
if (client.user?.status?.presence === Presence.Busy) return;
|
||||
if (!showNotification) return;
|
||||
|
||||
let event;
|
||||
switch (user.relationship) {
|
||||
case RelationshipStatus.Incoming:
|
||||
event = translate("notifications.sent_request", {
|
||||
person: user.username,
|
||||
});
|
||||
break;
|
||||
case RelationshipStatus.Friend:
|
||||
event = translate("notifications.now_friends", {
|
||||
person: user.username,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const notif = await createNotification(event, {
|
||||
icon: user.generateAvatarURL({ max_side: 256 }),
|
||||
badge: "/assets/icons/android-chrome-512x512.png",
|
||||
timestamp: +new Date(),
|
||||
});
|
||||
|
||||
notif?.addEventListener("click", () => {
|
||||
history.push(`/friends`);
|
||||
});
|
||||
},
|
||||
[client.user?.status?.presence, history, showNotification, translate],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
client.addListener("message", message);
|
||||
@@ -246,7 +260,16 @@ function Notifier({ options, notifs }: Props) {
|
||||
client.removeListener("message", message);
|
||||
client.removeListener("user/relationship", relationship);
|
||||
};
|
||||
}, [client, playSound, guild_id, channel_id, showNotification, notifs]);
|
||||
}, [
|
||||
client,
|
||||
playSound,
|
||||
guild_id,
|
||||
channel_id,
|
||||
showNotification,
|
||||
notifs,
|
||||
message,
|
||||
relationship,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
function visChange() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { openDB } from "idb";
|
||||
import { useHistory } from "react-router-dom";
|
||||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { Client } from "revolt.js";
|
||||
import { Route } from "revolt.js/dist/api/routes";
|
||||
|
||||
@@ -58,29 +57,6 @@ function Context({ auth, children }: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
let db;
|
||||
try {
|
||||
// Match sw.ts#L23
|
||||
db = await openDB("state", 3, {
|
||||
upgrade(db) {
|
||||
for (const store of [
|
||||
"channels",
|
||||
"servers",
|
||||
"users",
|
||||
"members",
|
||||
]) {
|
||||
db.createObjectStore(store, {
|
||||
keyPath: "_id",
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"Failed to open IndexedDB store, continuing without.",
|
||||
);
|
||||
}
|
||||
|
||||
const client = new Client({
|
||||
autoReconnect: false,
|
||||
apiURL: import.meta.env.VITE_API_URL,
|
||||
@@ -146,11 +122,11 @@ function Context({ auth, children }: Props) {
|
||||
ready: () =>
|
||||
operations.loggedIn() && typeof client.user !== "undefined",
|
||||
};
|
||||
}, [client, auth.active]);
|
||||
}, [client, auth.active, openScreen]);
|
||||
|
||||
useEffect(
|
||||
() => registerEvents({ operations }, setStatus, client),
|
||||
[client],
|
||||
[client, operations],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -203,6 +179,7 @@ function Context({ auth, children }: Props) {
|
||||
setStatus(ClientStatus.READY);
|
||||
}
|
||||
})();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
if (status === ClientStatus.LOADING) {
|
||||
|
||||
@@ -37,7 +37,7 @@ function StateMonitor(props: Props) {
|
||||
|
||||
client.addListener("message", add);
|
||||
return () => client.removeListener("message", add);
|
||||
}, [props.messages]);
|
||||
}, [client, props.messages]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import isEqual from "lodash.isequal";
|
||||
import { UserSettings } from "revolt-api/types/Sync";
|
||||
import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
|
||||
|
||||
import { useContext, useEffect } from "preact/hooks";
|
||||
import { useCallback, useContext, useEffect, useMemo } from "preact/hooks";
|
||||
|
||||
import { dispatch } from "../../redux";
|
||||
import { connectState } from "../../redux/connector";
|
||||
@@ -28,7 +28,7 @@ type Props = {
|
||||
notifications: Notifications;
|
||||
};
|
||||
|
||||
const lastValues: { [key in SyncKeys]?: any } = {};
|
||||
const lastValues: { [key in SyncKeys]?: unknown } = {};
|
||||
|
||||
export function mapSync(
|
||||
packet: UserSettings,
|
||||
@@ -78,31 +78,38 @@ function SyncManager(props: Props) {
|
||||
.syncFetchUnreads()
|
||||
.then((unreads) => dispatch({ type: "UNREADS_SET", unreads }));
|
||||
}
|
||||
}, [status]);
|
||||
}, [client, props.sync?.disabled, status]);
|
||||
|
||||
function syncChange(key: SyncKeys, data: any) {
|
||||
const timestamp = +new Date();
|
||||
dispatch({
|
||||
type: "SYNC_SET_REVISION",
|
||||
key,
|
||||
timestamp,
|
||||
});
|
||||
const syncChange = useCallback(
|
||||
(key: SyncKeys, data: unknown) => {
|
||||
const timestamp = +new Date();
|
||||
dispatch({
|
||||
type: "SYNC_SET_REVISION",
|
||||
key,
|
||||
timestamp,
|
||||
});
|
||||
|
||||
client.syncSetSettings(
|
||||
{
|
||||
[key]: data,
|
||||
},
|
||||
timestamp,
|
||||
);
|
||||
}
|
||||
client.syncSetSettings(
|
||||
{
|
||||
[key]: data as string,
|
||||
},
|
||||
timestamp,
|
||||
);
|
||||
},
|
||||
[client],
|
||||
);
|
||||
|
||||
const disabled = props.sync.disabled ?? [];
|
||||
const disabled = useMemo(
|
||||
() => props.sync.disabled ?? [],
|
||||
[props.sync.disabled],
|
||||
);
|
||||
for (const [key, object] of [
|
||||
["appearance", props.settings.appearance],
|
||||
["theme", props.settings.theme],
|
||||
["locale", props.locale],
|
||||
["notifications", props.notifications],
|
||||
] as [SyncKeys, any][]) {
|
||||
] as [SyncKeys, unknown][]) {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(() => {
|
||||
if (disabled.indexOf(key) === -1) {
|
||||
if (typeof lastValues[key] !== "undefined") {
|
||||
@@ -113,7 +120,7 @@ function SyncManager(props: Props) {
|
||||
}
|
||||
|
||||
lastValues[key] = object;
|
||||
}, [disabled, object]);
|
||||
}, [key, syncChange, disabled, object]);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@@ -131,7 +138,7 @@ function SyncManager(props: Props) {
|
||||
|
||||
client.addListener("packet", onPacket);
|
||||
return () => client.removeListener("packet", onPacket);
|
||||
}, [disabled, props.sync]);
|
||||
}, [client, disabled, props.sync]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { dispatch } from "../../redux";
|
||||
|
||||
import { ClientOperations, ClientStatus } from "./RevoltClient";
|
||||
|
||||
export var preventReconnect = false;
|
||||
export let preventReconnect = false;
|
||||
let preventUntil = 0;
|
||||
|
||||
export function setReconnectDisallowed(allowed: boolean) {
|
||||
@@ -34,6 +34,7 @@ export function registerEvents(
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let listeners: Record<string, (...args: any[]) => void> = {
|
||||
connecting: () =>
|
||||
operations.ready() && setStatus(ClientStatus.CONNECTING),
|
||||
@@ -74,7 +75,7 @@ export function registerEvents(
|
||||
if (import.meta.env.DEV) {
|
||||
listeners = new Proxy(listeners, {
|
||||
get:
|
||||
(target, listener, receiver) =>
|
||||
(target, listener) =>
|
||||
(...args: unknown[]) => {
|
||||
console.debug(`Calling ${listener.toString()} with`, args);
|
||||
Reflect.get(target, listener)(...args);
|
||||
@@ -87,10 +88,6 @@ export function registerEvents(
|
||||
client.addListener(listener, listeners[listener]);
|
||||
}
|
||||
|
||||
function logMutation(target: string, key: string) {
|
||||
console.log("(o) Object mutated", target, "\nChanged:", key);
|
||||
}
|
||||
|
||||
const online = () => {
|
||||
if (operations.ready()) {
|
||||
setStatus(ClientStatus.RECONNECTING);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Client } from "revolt.js";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
||||
import { Children } from "../../types/Preact";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function takeError(error: any): string {
|
||||
const type = error?.response?.data?.type;
|
||||
const id = type;
|
||||
|
||||
Reference in New Issue
Block a user