Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into better-plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Loukious committed Feb 20, 2024
2 parents 4e5a3eb + 7b96071 commit 999316d
Show file tree
Hide file tree
Showing 23 changed files with 268 additions and 182 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vencord",
"private": "true",
"version": "1.6.7",
"version": "1.6.9",
"description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": {
Expand Down
4 changes: 2 additions & 2 deletions src/api/Notifications/notificationLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Settings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { useAwaiter } from "@utils/react";
import { Alerts, Button, Forms, moment, React, Text, Timestamp, useEffect, useReducer, useState } from "@webpack/common";
import { Alerts, Button, Forms, React, Text, Timestamp, useEffect, useReducer, useState } from "@webpack/common";
import { nanoid } from "nanoid";
import type { DispatchWithoutAction } from "react";

Expand Down Expand Up @@ -129,7 +129,7 @@ function NotificationEntry({ data }: { data: PersistentNotificationData; }) {
richBody={
<div className={cl("body")}>
{data.body}
<Timestamp timestamp={moment(data.timestamp)} className={cl("timestamp")} />
<Timestamp timestamp={new Date(data.timestamp)} className={cl("timestamp")} />
</div>
}
/>
Expand Down
106 changes: 57 additions & 49 deletions src/plugins/crashHandler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import definePlugin, { OptionType } from "@utils/types";
import { maybePromptToUpdate } from "@utils/updater";
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
import { FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
import type { ReactElement } from "react";

const CrashHandlerLogger = new Logger("CrashHandler");
const { ModalStack, DraftManager, DraftType, closeExpressionPicker } = proxyLazyWebpack(() => {
Expand Down Expand Up @@ -57,13 +56,13 @@ const settings = definePluginSettings({
}
});

let crashCount: number = 0;
let lastCrashTimestamp: number = 0;
let shouldAttemptNextHandle = false;
let hasCrashedOnce = false;
let isRecovering = false;
let shouldAttemptRecover = true;

export default definePlugin({
name: "CrashHandler",
description: "Utility plugin for handling and possibly recovering from Crashes without a restart",
description: "Utility plugin for handling and possibly recovering from crashes without a restart",
authors: [Devs.Nuckyz],
enabledByDefault: true,

Expand All @@ -73,61 +72,67 @@ export default definePlugin({
{
find: ".Messages.ERRORS_UNEXPECTED_CRASH",
replacement: {
match: /(?=this\.setState\()/,
replace: "$self.handleCrash(this)||"
match: /this\.setState\((.+?)\)/,
replace: "$self.handleCrash(this,$1);"
}
}
],

handleCrash(_this: ReactElement & { forceUpdate: () => void; }) {
if (Date.now() - lastCrashTimestamp <= 1_000 && !shouldAttemptNextHandle) return true;
handleCrash(_this: any, errorState: any) {
_this.setState(errorState);

shouldAttemptNextHandle = false;
// Already recovering, prevent error which happens more than once too fast to trigger another recover
if (isRecovering) return;
isRecovering = true;

if (++crashCount > 5) {
// 1 ms timeout to avoid react breaking when re-rendering
setTimeout(() => {
try {
showNotification({
color: "#eed202",
title: "Discord has crashed!",
body: "Awn :( Discord has crashed more than five times, not attempting to recover.",
noPersist: true,
});
// Prevent a crash loop with an error that could not be handled
if (!shouldAttemptRecover) {
try {
showNotification({
color: "#eed202",
title: "Discord has crashed!",
body: "Awn :( Discord has crashed two times rapidly, not attempting to recover.",
noPersist: true
});
} catch { }

return;
}

shouldAttemptRecover = false;
// This is enough to avoid a crash loop
setTimeout(() => shouldAttemptRecover = true, 500);
} catch { }

lastCrashTimestamp = Date.now();
return false;
}

setTimeout(() => crashCount--, 60_000);

try {
if (crashCount === 1) maybePromptToUpdate("Uh oh, Discord has just crashed... but good news, there is a Vencord update available that might fix this issue! Would you like to update now?", true);
try {
if (!hasCrashedOnce) {
hasCrashedOnce = true;
maybePromptToUpdate("Uh oh, Discord has just crashed... but good news, there is a Vencord update available that might fix this issue! Would you like to update now?", true);
}
} catch { }

if (settings.store.attemptToPreventCrashes) {
this.handlePreventCrash(_this);
return true;
try {
if (settings.store.attemptToPreventCrashes) {
this.handlePreventCrash(_this);
}
} catch (err) {
CrashHandlerLogger.error("Failed to handle crash", err);
}

return false;
} catch (err) {
CrashHandlerLogger.error("Failed to handle crash", err);
return false;
} finally {
lastCrashTimestamp = Date.now();
}
}, 1);
},

handlePreventCrash(_this: ReactElement & { forceUpdate: () => void; }) {
if (Date.now() - lastCrashTimestamp >= 1_000) {
try {
showNotification({
color: "#eed202",
title: "Discord has crashed!",
body: "Attempting to recover...",
noPersist: true,
});
} catch { }
}
handlePreventCrash(_this: any) {
try {
showNotification({
color: "#eed202",
title: "Discord has crashed!",
body: "Attempting to recover...",
noPersist: true
});
} catch { }

try {
const channelId = SelectedChannelStore.getChannelId();
Expand Down Expand Up @@ -176,9 +181,12 @@ export default definePlugin({
}
}


// Set isRecovering to false before setting the state to allow us to handle the next crash error correcty, in case it happens
setImmediate(() => isRecovering = false);

try {
shouldAttemptNextHandle = true;
_this.forceUpdate();
_this.setState({ error: null, info: null });
} catch (err) {
CrashHandlerLogger.debug("Failed to update crash handler component.", err);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import { migratePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";

migratePluginSettings("DisableCallIdle", "DisableDMCallIdle");
export default definePlugin({
name: "DisableDMCallIdle",
description: "Disables automatically getting kicked from a DM voice call after 3 minutes.",
name: "DisableCallIdle",
description: "Disables automatically getting kicked from a DM voice call after 3 minutes and being moved to an AFK voice channel.",
authors: [Devs.Nuckyz],
patches: [
{
find: ".Messages.BOT_CALL_IDLE_DISCONNECT",
replacement: {
match: /(?<=function \i\(\){)(?=.{1,120}\.Messages\.BOT_CALL_IDLE_DISCONNECT)/,
match: /,?(?=this\.idleTimeout=new \i\.Timeout)/,
replace: ";return;"
}
},
{
find: "handleIdleUpdate(){",
replacement: {
match: /(?<=_initialize\(\){)/,
replace: "return;"
}
}
Expand Down
60 changes: 40 additions & 20 deletions src/plugins/fakeNitro/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const enum FakeNoticeType {
const fakeNitroEmojiRegex = /\/emojis\/(\d+?)\.(png|webp|gif)/;
const fakeNitroStickerRegex = /\/stickers\/(\d+?)\./;
const fakeNitroGifStickerRegex = /\/attachments\/\d+?\/\d+?\/(\d+?)\.gif/;
const hyperLinkRegex = /\[.+?\]\((https?:\/\/.+?)\)/;

const settings = definePluginSettings({
enableEmojiBypass: {
Expand Down Expand Up @@ -168,6 +169,11 @@ const settings = definePluginSettings({
type: OptionType.BOOLEAN,
default: true,
restartNeeded: true
},
useHyperLinks: {
description: "Whether to use hyperlinks when sending fake emojis and stickers",
type: OptionType.BOOLEAN,
default: true
}
});

Expand Down Expand Up @@ -476,13 +482,23 @@ export default definePlugin({

trimContent(content: Array<any>) {
const firstContent = content[0];
if (typeof firstContent === "string") content[0] = firstContent.trimStart();
if (content[0] === "") content.shift();
if (typeof firstContent === "string") {
content[0] = firstContent.trimStart();
content[0] || content.shift();
} else if (firstContent?.type === "span") {
firstContent.props.children = firstContent.props.children.trimStart();
firstContent.props.children || content.shift();
}

const lastIndex = content.length - 1;
const lastContent = content[lastIndex];
if (typeof lastContent === "string") content[lastIndex] = lastContent.trimEnd();
if (content[lastIndex] === "") content.pop();
if (typeof lastContent === "string") {
content[lastIndex] = lastContent.trimEnd();
content[lastIndex] || content.pop();
} else if (lastContent?.type === "span") {
lastContent.props.children = lastContent.props.children.trimEnd();
lastContent.props.children || content.pop();
}
},

clearEmptyArrayItems(array: Array<any>) {
Expand All @@ -494,7 +510,7 @@ export default definePlugin({
},

patchFakeNitroEmojisOrRemoveStickersLinks(content: Array<any>, inline: boolean) {
// If content has more than one child or it's a single ReactElement like a header or list
// If content has more than one child or it's a single ReactElement like a header, list or span
if ((content.length > 1 || typeof content[0]?.type === "string") && !settings.store.transformCompoundSentence) return content;

let nextIndex = content.length;
Expand Down Expand Up @@ -603,7 +619,7 @@ export default definePlugin({
itemsToMaybePush.push(...message.attachments.filter(attachment => attachment.content_type === "image/gif").map(attachment => attachment.url));

for (const item of itemsToMaybePush) {
if (!settings.store.transformCompoundSentence && !item.startsWith("http")) continue;
if (!settings.store.transformCompoundSentence && !item.startsWith("http") && !hyperLinkRegex.test(item)) continue;

const imgMatch = item.match(fakeNitroStickerRegex);
if (imgMatch) {
Expand Down Expand Up @@ -648,8 +664,7 @@ export default definePlugin({
case "image": {
if (
!settings.store.transformCompoundSentence
&& !contentItems.includes(embed.url!)
&& !contentItems.includes(embed.image?.proxyURL!)
&& !contentItems.some(item => item === embed.url! || item.match(hyperLinkRegex)?.[1] === embed.url!)
) return false;

if (settings.store.transformEmojis) {
Expand Down Expand Up @@ -727,7 +742,7 @@ export default definePlugin({
},

getStickerLink(stickerId: string) {
return `https://media.discordapp.net/stickers/${stickerId}.png?size=${Settings.plugins.FakeNitro.stickerSize}`;
return `https://media.discordapp.net/stickers/${stickerId}.png?size=${settings.store.stickerSize}`;
},

async sendAnimatedSticker(stickerLink: string, stickerId: string, channelId: string) {
Expand Down Expand Up @@ -824,12 +839,16 @@ export default definePlugin({
if (sticker.format_type === StickerType.GIF && link.includes(".png")) {
link = link.replace(".png", ".gif");
}

if (sticker.format_type === StickerType.APNG) {
this.sendAnimatedSticker(link, sticker.id, channelId);
return { cancel: true };
} else {
const url = new URL(link);
url.searchParams.set("name", sticker.name);

messageObj.content += `${getWordBoundary(messageObj.content, messageObj.content.length - 1)}${s.useHyperLinks ? `[${sticker.name}](${url})` : url}`;
extra.stickers!.length = 0;
messageObj.content += ` ${link}&name=${encodeURIComponent(sticker.name)}`;
}
}

Expand All @@ -842,12 +861,13 @@ export default definePlugin({
if (emoji.guildId === guildId && !emoji.animated) continue;

const emojiString = `<${emoji.animated ? "a" : ""}:${emoji.originalName || emoji.name}:${emoji.id}>`;
const url = emoji.url.replace(/\?size=\d+/, "?" + new URLSearchParams({
size: Settings.plugins.FakeNitro.emojiSize,
name: encodeURIComponent(emoji.name)
}));

const url = new URL(emoji.url);
url.searchParams.set("size", s.emojiSize.toString());
url.searchParams.set("name", emoji.name);

messageObj.content = messageObj.content.replace(emojiString, (match, offset, origStr) => {
return `${getWordBoundary(origStr, offset - 1)}${url}${getWordBoundary(origStr, offset + match.length)}`;
return `${getWordBoundary(origStr, offset - 1)}${s.useHyperLinks ? `[${emoji.name}](${url})` : url}${getWordBoundary(origStr, offset + match.length)}`;
});
}
}
Expand All @@ -869,11 +889,11 @@ export default definePlugin({
if (emoji.available !== false && canUseEmotes) return emojiStr;
if (emoji.guildId === guildId && !emoji.animated) return emojiStr;

const url = emoji.url.replace(/\?size=\d+/, "?" + new URLSearchParams({
size: Settings.plugins.FakeNitro.emojiSize,
name: encodeURIComponent(emoji.name)
}));
return `${getWordBoundary(origStr, offset - 1)}${url}${getWordBoundary(origStr, offset + emojiStr.length)}`;
const url = new URL(emoji.url);
url.searchParams.set("size", s.emojiSize.toString());
url.searchParams.set("name", emoji.name);

return `${getWordBoundary(origStr, offset - 1)}${s.useHyperLinks ? `[${emoji.name}](${url})` : url}${getWordBoundary(origStr, offset + emojiStr.length)}`;
});
});
},
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/fixYoutubeEmbeds.desktop/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ app.on("browser-window-created", (_, win) => {
frame.executeJavaScript(`
new MutationObserver(() => {
if(
document.querySelector('div.ytp-error-content-wrap-subreason a[href^="https://www.youtube.com/watch?v="]')
document.querySelector('div.ytp-error-content-wrap-subreason a[href*="www.youtube.com/watch?v="]')
) location.reload()
}).observe(document.body, { childList: true, subtree:true });
`);
Expand Down
11 changes: 6 additions & 5 deletions src/plugins/imageZoom/components/Magnifier.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,13 @@ export const Magnifier: React.FC<MagnifierProps> = ({ instance, size: initialSiz
waitFor(() => instance.state.readyState === "READY", () => {
const elem = document.getElementById(ELEMENT_ID) as HTMLDivElement;
element.current = elem;
elem.firstElementChild!.setAttribute("draggable", "false");
elem.querySelector("img,video")?.setAttribute("draggable", "false");
if (instance.props.animated) {
originalVideoElementRef.current = elem!.querySelector("video")!;
originalVideoElementRef.current.addEventListener("timeupdate", syncVideos);
setReady(true);
} else {
setReady(true);
}

setReady(true);
});
document.addEventListener("keydown", onKeyDown);
document.addEventListener("keyup", onKeyUp);
Expand All @@ -155,7 +154,9 @@ export const Magnifier: React.FC<MagnifierProps> = ({ instance, size: initialSiz

if (!ready) return null;

const box = element.current!.getBoundingClientRect();
const box = element.current?.getBoundingClientRect();

if (!box) return null;

return (
<div
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/imageZoom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export default definePlugin({
find: "handleImageLoad=",
replacement: [
{
match: /showThumbhashPlaceholder:\i,/,
match: /placeholderVersion:\i,/,
replace: "...$self.makeProps(this),$&"
},

Expand Down
Loading

0 comments on commit 999316d

Please sign in to comment.