Merge branch 'dev' into immediate-finds
This commit is contained in:
commit
7e1524362c
|
@ -24,19 +24,27 @@ interface Diff {
|
||||||
seconds: number;
|
seconds: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DISCORD_KT_DELAY = 1471228.928;
|
||||||
const HiddenVisually = findExportedComponent("HiddenVisually");
|
const HiddenVisually = findExportedComponent("HiddenVisually");
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "MessageLatency",
|
name: "MessageLatency",
|
||||||
description: "Displays an indicator for messages that took ≥n seconds to send",
|
description: "Displays an indicator for messages that took ≥n seconds to send",
|
||||||
authors: [Devs.arHSM],
|
authors: [Devs.arHSM],
|
||||||
|
|
||||||
settings: definePluginSettings({
|
settings: definePluginSettings({
|
||||||
latency: {
|
latency: {
|
||||||
type: OptionType.NUMBER,
|
type: OptionType.NUMBER,
|
||||||
description: "Threshold in seconds for latency indicator",
|
description: "Threshold in seconds for latency indicator",
|
||||||
default: 2
|
default: 2
|
||||||
|
},
|
||||||
|
detectDiscordKotlin: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Detect old Discord Android clients",
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "showCommunicationDisabledStyles",
|
find: "showCommunicationDisabledStyles",
|
||||||
|
@ -46,6 +54,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
stringDelta(delta: number) {
|
stringDelta(delta: number) {
|
||||||
const diff: Diff = {
|
const diff: Diff = {
|
||||||
days: Math.round(delta / (60 * 60 * 24)),
|
days: Math.round(delta / (60 * 60 * 24)),
|
||||||
|
@ -71,15 +80,25 @@ export default definePlugin({
|
||||||
);
|
);
|
||||||
}, "");
|
}, "");
|
||||||
|
|
||||||
return [ts || "0 seconds", diff.days === 17 && diff.hours === 1] as const;
|
return ts || "0 seconds";
|
||||||
},
|
},
|
||||||
|
|
||||||
latencyTooltipData(message: Message) {
|
latencyTooltipData(message: Message) {
|
||||||
|
const { latency, detectDiscordKotlin } = this.settings.store;
|
||||||
const { id, nonce } = message;
|
const { id, nonce } = message;
|
||||||
|
|
||||||
// Message wasn't received through gateway
|
// Message wasn't received through gateway
|
||||||
if (!isNonNullish(nonce)) return null;
|
if (!isNonNullish(nonce)) return null;
|
||||||
|
|
||||||
const delta = Math.round((SnowflakeUtils.extractTimestamp(id) - SnowflakeUtils.extractTimestamp(nonce)) / 1000);
|
let isDiscordKotlin = false;
|
||||||
|
let delta = Math.round((SnowflakeUtils.extractTimestamp(id) - SnowflakeUtils.extractTimestamp(nonce)) / 1000);
|
||||||
|
|
||||||
|
// Old Discord Android clients have a delay of around 17 days
|
||||||
|
// This is a workaround for that
|
||||||
|
if (-delta >= DISCORD_KT_DELAY - 86400) { // One day of padding for good measure
|
||||||
|
isDiscordKotlin = detectDiscordKotlin;
|
||||||
|
delta += DISCORD_KT_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
// Thanks dziurwa (I hate you)
|
// Thanks dziurwa (I hate you)
|
||||||
// This is when the user's clock is ahead
|
// This is when the user's clock is ahead
|
||||||
|
@ -87,15 +106,13 @@ export default definePlugin({
|
||||||
const abs = Math.abs(delta);
|
const abs = Math.abs(delta);
|
||||||
const ahead = abs !== delta;
|
const ahead = abs !== delta;
|
||||||
|
|
||||||
const [stringDelta, isSuspectedKotlinDiscord] = this.stringDelta(abs);
|
const stringDelta = abs >= latency ? this.stringDelta(abs) : null;
|
||||||
const isKotlinDiscord = ahead && isSuspectedKotlinDiscord;
|
|
||||||
|
|
||||||
// Also thanks dziurwa
|
// Also thanks dziurwa
|
||||||
// 2 minutes
|
// 2 minutes
|
||||||
const TROLL_LIMIT = 2 * 60;
|
const TROLL_LIMIT = 2 * 60;
|
||||||
const { latency } = this.settings.store;
|
|
||||||
|
|
||||||
const fill: Fill = isKotlinDiscord
|
const fill: Fill = isDiscordKotlin
|
||||||
? ["status-positive", "status-positive", "text-muted"]
|
? ["status-positive", "status-positive", "text-muted"]
|
||||||
: delta >= TROLL_LIMIT || ahead
|
: delta >= TROLL_LIMIT || ahead
|
||||||
? ["text-muted", "text-muted", "text-muted"]
|
? ["text-muted", "text-muted", "text-muted"]
|
||||||
|
@ -103,17 +120,24 @@ export default definePlugin({
|
||||||
? ["status-danger", "text-muted", "text-muted"]
|
? ["status-danger", "text-muted", "text-muted"]
|
||||||
: ["status-warning", "status-warning", "text-muted"];
|
: ["status-warning", "status-warning", "text-muted"];
|
||||||
|
|
||||||
return abs >= latency ? { delta: stringDelta, ahead, fill, isKotlinDiscord } : null;
|
return (abs >= latency || isDiscordKotlin) ? { delta: stringDelta, ahead, fill, isDiscordKotlin } : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
Tooltip() {
|
Tooltip() {
|
||||||
return ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
return ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
||||||
|
|
||||||
const d = this.latencyTooltipData(message);
|
const d = this.latencyTooltipData(message);
|
||||||
|
|
||||||
if (!isNonNullish(d)) return null;
|
if (!isNonNullish(d)) return null;
|
||||||
|
|
||||||
|
let text: string;
|
||||||
|
if (!d.delta) {
|
||||||
|
text = "User is suspected to be on an old Discord Android client";
|
||||||
|
} else {
|
||||||
|
text = (d.ahead ? `This user's clock is ${d.delta} ahead.` : `This message was sent with a delay of ${d.delta}.`) + (d.isDiscordKotlin ? " User is suspected to be on an old Discord Android client." : "");
|
||||||
|
}
|
||||||
|
|
||||||
return <Tooltip
|
return <Tooltip
|
||||||
text={d.ahead ? `This user's clock is ${d.delta} ahead. ${d.isKotlinDiscord ? "User is suspected to be on an old mobile client" : ""}` : `This message was sent with a delay of ${d.delta}.`}
|
text={text}
|
||||||
position="top"
|
position="top"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
@ -126,8 +150,9 @@ export default definePlugin({
|
||||||
</Tooltip>;
|
</Tooltip>;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
Icon({ delta, fill, props }: {
|
Icon({ delta, fill, props }: {
|
||||||
delta: string;
|
delta: string | null;
|
||||||
fill: Fill,
|
fill: Fill,
|
||||||
props: {
|
props: {
|
||||||
onClick(): void;
|
onClick(): void;
|
||||||
|
@ -147,7 +172,7 @@ export default definePlugin({
|
||||||
role="img"
|
role="img"
|
||||||
fill="none"
|
fill="none"
|
||||||
style={{ marginRight: "8px", verticalAlign: -1 }}
|
style={{ marginRight: "8px", verticalAlign: -1 }}
|
||||||
aria-label={delta}
|
aria-label={delta ?? "Old Discord Android client"}
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
|
|
@ -68,7 +68,6 @@ interface Call {
|
||||||
ringing: string[];
|
ringing: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const MuteStore = findByProps("isSuppressEveryoneEnabled");
|
|
||||||
const Notifs = findByProps("makeTextChatNotification");
|
const Notifs = findByProps("makeTextChatNotification");
|
||||||
const XSLog = new Logger("XSOverlay");
|
const XSLog = new Logger("XSOverlay");
|
||||||
|
|
||||||
|
@ -115,13 +114,13 @@ const settings = definePluginSettings({
|
||||||
},
|
},
|
||||||
timeout: {
|
timeout: {
|
||||||
type: OptionType.NUMBER,
|
type: OptionType.NUMBER,
|
||||||
description: "Notif duration (secs)",
|
description: "Notification duration (secs)",
|
||||||
default: 1.0,
|
default: 3,
|
||||||
},
|
},
|
||||||
timeoutPerCharacter: {
|
lengthBasedTimeout: {
|
||||||
type: OptionType.NUMBER,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Duration multiplier per character",
|
description: "Extend duration with message length",
|
||||||
default: 0.5
|
default: true
|
||||||
},
|
},
|
||||||
opacity: {
|
opacity: {
|
||||||
type: OptionType.SLIDER,
|
type: OptionType.SLIDER,
|
||||||
|
@ -262,12 +261,11 @@ function shouldIgnoreForChannelType(channel: Channel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendMsgNotif(titleString: string, content: string, message: Message) {
|
function sendMsgNotif(titleString: string, content: string, message: Message) {
|
||||||
const timeout = Math.max(settings.store.timeout, content.length * settings.store.timeoutPerCharacter);
|
|
||||||
fetch(`https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png?size=128`).then(response => response.arrayBuffer()).then(result => {
|
fetch(`https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png?size=128`).then(response => response.arrayBuffer()).then(result => {
|
||||||
const msgData = {
|
const msgData = {
|
||||||
messageType: 1,
|
messageType: 1,
|
||||||
index: 0,
|
index: 0,
|
||||||
timeout,
|
timeout: settings.store.lengthBasedTimeout ? calculateTimeout(content) : settings.store.timeout,
|
||||||
height: calculateHeight(content),
|
height: calculateHeight(content),
|
||||||
opacity: settings.store.opacity,
|
opacity: settings.store.opacity,
|
||||||
volume: settings.store.volume,
|
volume: settings.store.volume,
|
||||||
|
@ -286,7 +284,7 @@ function sendOtherNotif(content: string, titleString: string) {
|
||||||
const msgData = {
|
const msgData = {
|
||||||
messageType: 1,
|
messageType: 1,
|
||||||
index: 0,
|
index: 0,
|
||||||
timeout: settings.store.timeout,
|
timeout: settings.store.lengthBasedTimeout ? calculateTimeout(content) : settings.store.timeout,
|
||||||
height: calculateHeight(content),
|
height: calculateHeight(content),
|
||||||
opacity: settings.store.opacity,
|
opacity: settings.store.opacity,
|
||||||
volume: settings.store.volume,
|
volume: settings.store.volume,
|
||||||
|
@ -313,3 +311,10 @@ function calculateHeight(content: string) {
|
||||||
if (content.length <= 300) return 200;
|
if (content.length <= 300) return 200;
|
||||||
return 250;
|
return 250;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function calculateTimeout(content: string) {
|
||||||
|
if (content.length <= 100) return 3;
|
||||||
|
if (content.length <= 200) return 4;
|
||||||
|
if (content.length <= 300) return 5;
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue