Merge branch 'dev' into immediate-finds

This commit is contained in:
Nuckyz 2024-05-13 23:15:16 -03:00
parent 4fc4f1cb75
commit 7d91dea822
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
17 changed files with 89 additions and 71 deletions

View file

@ -61,7 +61,7 @@ export default definePlugin({
find: ".popularApplicationCommandIds,",
replacement: {
match: /lastSection:(!?\i)}\),/,
replace: "$&$self.patchPadding($1),"
replace: "$&$self.patchPadding({lastSection:$1}),"
}
}
],
@ -81,12 +81,10 @@ export default definePlugin({
}
},
patchPadding(lastSection: any) {
if (!lastSection) return;
patchPadding: ErrorBoundary.wrap(({ lastSection }) => {
if (!lastSection) return null;
return (
<ErrorBoundary noop>
<div className={UserPopoutSectionCssClasses.lastSection}></div>
</ErrorBoundary>
<div className={UserPopoutSectionCssClasses.lastSection} ></div>
);
}
})
});

View file

@ -22,7 +22,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByProps, findExportedComponent, findStore } from "@webpack";
import { React, RestAPI, Tooltip } from "@webpack/common";
import { Constants, React, RestAPI, Tooltip } from "@webpack/common";
import { RenameButton } from "./components/RenameButton";
import { Session, SessionInfo } from "./types";
@ -168,7 +168,7 @@ export default definePlugin({
async checkNewSessions() {
const data = await RestAPI.get({
url: "/auth/sessions"
url: Constants.Endpoints.AUTH_SESSIONS
});
for (const session of data.body.user_sessions) {

View file

@ -24,7 +24,7 @@ import { Margins } from "@utils/margins";
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
import definePlugin from "@utils/types";
import { findByProps, findStore } from "@webpack";
import { EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
import { Promisable } from "type-fest";
const StickersStore = findStore("StickersStore");
@ -64,7 +64,7 @@ async function fetchSticker(id: string) {
if (cached) return cached;
const { body } = await RestAPI.get({
url: `/stickers/${id}`
url: Constants.Endpoints.STICKER(id)
});
FluxDispatcher.dispatch({
@ -83,7 +83,7 @@ async function cloneSticker(guildId: string, sticker: Sticker) {
data.append("file", await fetchBlob(getUrl(sticker)));
const { body } = await RestAPI.post({
url: `/guilds/${guildId}/stickers`,
url: Constants.Endpoints.GUILD_STICKER_PACKS(guildId),
body: data,
});
@ -322,8 +322,9 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) =
switch (favoriteableType) {
case "emoji":
const match = props.message.content.match(RegExp(`<a?:(\\w+)(?:~\\d+)?:${favoriteableId}>|https://cdn\\.discordapp\\.com/emojis/${favoriteableId}\\.`));
if (!match) return;
const name = match[1] ?? "FakeNitroEmoji";
const reaction = props.message.reactions.find(reaction => reaction.emoji.id === favoriteableId);
if (!match && !reaction) return;
const name = (match && match[1]) ?? reaction?.emoji.name ?? "FakeNitroEmoji";
return buildMenuItem("Emoji", () => ({
id: favoriteableId,

View file

@ -39,6 +39,7 @@ const StickerStore = findStore("StickersStore") as {
const UserSettingsProtoStore = findStore("UserSettingsProtoStore");
const ProtoUtils = findByProps("BINARY_READ_OPTIONS");
const RoleSubscriptionEmojiUtils = findByProps("isUnusableRoleSubscriptionEmoji");
function searchProtoClassField(localName: string, protoClass: any) {
const field = protoClass?.fields?.find((field: any) => field.localName === localName);
@ -407,6 +408,15 @@ export default definePlugin({
match: /canUseCustomNotificationSounds:function\(\i\){/,
replace: "$&return true;"
}
},
// Allows the usage of subscription-locked emojis
{
find: "isUnusableRoleSubscriptionEmoji:function",
replacement: {
match: /isUnusableRoleSubscriptionEmoji:function/,
// replace the original export with a func that always returns false and alias the original
replace: "isUnusableRoleSubscriptionEmoji:()=>()=>false,isUnusableRoleSubscriptionEmojiOriginal:function"
}
}
],
@ -803,6 +813,9 @@ export default definePlugin({
if (e.require_colons === false) return true;
if (e.available === false) return false;
const isUnusableRoleSubEmoji = RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji;
if (isUnusableRoleSubEmoji(e, this.guildId)) return false;
if (this.canUseEmotes)
return e.guildId === this.guildId || hasExternalEmojiPerms(channelId);
else

View file

@ -20,7 +20,7 @@ import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption,
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByProps } from "@webpack";
import { RestAPI, UserStore } from "@webpack/common";
import { Constants, RestAPI, UserStore } from "@webpack/common";
const FriendInvites = findByProps("createFriendInvite");
const { uuid4 } = findByProps("uuid4");
@ -58,7 +58,7 @@ export default definePlugin({
if (uses === 1) {
const random = uuid4();
const { body: { invite_suggestions } } = await RestAPI.post({
url: "/friend-finder/find-friends",
url: Constants.Endpoints.FRIEND_FINDER,
body: {
modified_contacts: {
[random]: [1, "", ""]

View file

@ -23,7 +23,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getStegCloak } from "@utils/dependencies";
import definePlugin, { OptionType } from "@utils/types";
import { ChannelStore, FluxDispatcher, RestAPI, Tooltip } from "@webpack/common";
import { ChannelStore, Constants, FluxDispatcher, RestAPI, Tooltip } from "@webpack/common";
import { Message } from "discord-types/general";
import { buildDecModal } from "./components/DecryptionModal";
@ -153,7 +153,7 @@ export default definePlugin({
// Gets the Embed of a Link
async getEmbed(url: URL): Promise<Object | {}> {
const { body } = await RestAPI.post({
url: "/unfurler/embed-urls",
url: Constants.Endpoints.UNFURL_EMBED_URLS,
body: {
urls: [url]
}

View file

@ -27,6 +27,7 @@ import { findByProps, findComponentByCode } from "@webpack";
import {
Button,
ChannelStore,
Constants,
FluxDispatcher,
GuildStore,
IconUtils,
@ -132,7 +133,7 @@ async function fetchMessage(channelID: string, messageID: string) {
messageCache.set(messageID, { fetched: false });
const res = await RestAPI.get({
url: `/channels/${channelID}/messages`,
url: Constants.Endpoints.MESSAGES(channelID),
query: {
limit: 1,
around: messageID

View file

@ -1,3 +1,3 @@
.messagelogger-deleted {
background-color: rgba(240 71 71 / 15%) !important;
background-color: hsla(var(--red-430-hsl, 0 85% 61%) / 15%) !important;
}

View file

@ -1,19 +1,19 @@
/* Message content highlighting */
.messagelogger-deleted [class*="contents"] > :is(div, h1, h2, h3, p) {
color: #f04747 !important;
color: var(--status-danger, #f04747) !important;
}
/* Bot "thinking" text highlighting */
.messagelogger-deleted [class*="colorStandard"] {
color: #f04747 !important;
color: var(--status-danger, #f04747) !important;
}
/* Embed highlighting */
.messagelogger-deleted article :is(div, span, h1, h2, h3, p) {
color: #f04747 !important;
color: var(--status-danger, #f04747) !important;
}
.messagelogger-deleted a {
color: #be3535 !important;
color: var(--red-460, #be3535) !important;
text-decoration: underline;
}

View file

@ -56,12 +56,12 @@ export default definePlugin({
find: ".UserProfileSections.USER_INFO_CONNECTIONS:",
replacement: {
match: /(?<={user:(\i),onClose:(\i)}\);)(?=case \i\.\i\.MUTUAL_FRIENDS)/,
replace: "case \"MUTUAL_GDMS\":return $self.renderMutualGDMs($1,$2);"
replace: "case \"MUTUAL_GDMS\":return $self.renderMutualGDMs({user: $1, onClose: $2});"
}
}
],
renderMutualGDMs: ErrorBoundary.wrap((user: User, onClose: () => void) => {
renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose }: { user: User, onClose: () => void; }) => {
const entries = ChannelStore.getSortedPrivateChannels().filter(c => c.isGroupDM() && c.recipients.includes(user.id)).map(c => (
<Clickable
className={ProfileListClasses.listRow}

View file

@ -20,10 +20,26 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByProps } from "@webpack";
import { GuildStore, i18n, RestAPI } from "@webpack/common";
import { Constants, GuildStore, i18n, RestAPI } from "@webpack/common";
const { InvitesDisabledExperiment } = findByProps("InvitesDisabledExperiment");
function showDisableInvites(guildId: string) {
// Once the experiment is removed, this should keep working
const { enableInvitesDisabled } = InvitesDisabledExperiment?.getCurrentConfig?.({ guildId }) ?? { enableInvitesDisabled: true };
// @ts-ignore
return enableInvitesDisabled && !GuildStore.getGuild(guildId).hasFeature("INVITES_DISABLED");
}
function disableInvites(guildId: string) {
const guild = GuildStore.getGuild(guildId);
const features = [...guild.features, "INVITES_DISABLED"];
RestAPI.patch({
url: Constants.Endpoints.GUILD(guildId),
body: { features },
});
}
export default definePlugin({
name: "PauseInvitesForever",
tags: ["DisableInvitesForever"],
@ -33,44 +49,29 @@ export default definePlugin({
patches: [
{
find: "Messages.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION",
replacement: [{
match: /children:\i\.\i\.\i\.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION/,
replace: "children: $self.renderInvitesLabel(arguments[0].guildId, setChecked)",
},
{
match: /(\i\.hasDMsDisabled\)\(\i\),\[\i,(\i)\]=\i\.useState\(\i\))/,
replace: "$1,setChecked=$2"
}]
group: true,
replacement: [
{
match: /children:\i\.\i\.\i\.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION/,
replace: "children: $self.renderInvitesLabel({guildId:arguments[0].guildId,setChecked})",
},
{
match: /(\i\.hasDMsDisabled\)\(\i\),\[\i,(\i)\]=\i\.useState\(\i\))/,
replace: "$1,setChecked=$2"
}
]
}
],
showDisableInvites(guildId: string) {
// Once the experiment is removed, this should keep working
const { enableInvitesDisabled } = InvitesDisabledExperiment?.getCurrentConfig?.({ guildId }) ?? { enableInvitesDisabled: true };
// @ts-ignore
return enableInvitesDisabled && !GuildStore.getGuild(guildId).hasFeature("INVITES_DISABLED");
},
disableInvites(guildId: string) {
const guild = GuildStore.getGuild(guildId);
const features = [...guild.features, "INVITES_DISABLED"];
RestAPI.patch({
url: `/guilds/${guild.id}`,
body: { features },
});
},
renderInvitesLabel(guildId: string, setChecked: Function) {
renderInvitesLabel: ErrorBoundary.wrap(({ guildId, setChecked }) => {
return (
<ErrorBoundary noop>
<div>
{i18n.Messages.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION}
{this.showDisableInvites(guildId) && <a role="button" onClick={() => {
setChecked(true);
this.disableInvites(guildId);
}}> Pause Indefinitely.</a>}
</div>
</ErrorBoundary>
<div>
{i18n.Messages.GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION}
{showDisableInvites(guildId) && <a role="button" onClick={() => {
setChecked(true);
disableInvites(guildId);
}}> Pause Indefinitely.</a>}
</div>
);
}
})
});

View file

@ -20,7 +20,7 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/Co
import { ImageInvisible, ImageVisible } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Menu, PermissionsBits, PermissionStore, RestAPI, UserStore } from "@webpack/common";
import { Constants, Menu, PermissionsBits, PermissionStore, RestAPI, UserStore } from "@webpack/common";
const EMBED_SUPPRESSED = 1 << 2;
@ -44,7 +44,7 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { channe
icon={isEmbedSuppressed ? ImageVisible : ImageInvisible}
action={() =>
RestAPI.patch({
url: `/channels/${channel.id}/messages/${messageId}`,
url: Constants.Endpoints.MESSAGE(channel.id, messageId),
body: { flags: isEmbedSuppressed ? flags & ~EMBED_SUPPRESSED : flags | EMBED_SUPPRESSED }
})
}

View file

@ -75,7 +75,7 @@ async function getUser(id: string) {
if (userObj)
return userObj;
const user: any = await RestAPI.get({ url: `/users/${id}` }).then(response => {
const user: any = await RestAPI.get({ url: Constants.Endpoints.USER(id) }).then(response => {
FluxDispatcher.dispatch({
type: "USER_UPDATE",
user: response.body,

View file

@ -28,7 +28,7 @@ import { useAwaiter } from "@utils/react";
import definePlugin from "@utils/types";
import { chooseFile } from "@utils/web";
import { findByProps, findStore } from "@webpack";
import { Button, Card, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
import { Button, Card, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
import { ComponentType } from "react";
import { VoiceRecorderDesktop } from "./DesktopRecorder";
@ -98,7 +98,7 @@ function sendAudio(blob: Blob, meta: AudioMetadata) {
upload.on("complete", () => {
RestAPI.post({
url: `/channels/${channelId}/messages`,
url: Constants.Endpoints.MESSAGES(channelId),
body: {
flags: 1 << 13,
channel_id: channelId,

View file

@ -23,7 +23,7 @@ import { Queue } from "@utils/Queue";
import { useForceUpdater } from "@utils/react";
import definePlugin from "@utils/types";
import { findByProps, findComponentByCode } from "@webpack";
import { ChannelStore, FluxDispatcher, React, RestAPI, Tooltip } from "@webpack/common";
import { ChannelStore, Constants, FluxDispatcher, React, RestAPI, Tooltip } from "@webpack/common";
import { CustomEmoji } from "@webpack/types";
import { Message, ReactionEmoji, User } from "discord-types/general";
@ -37,7 +37,7 @@ let reactions: Record<string, ReactionCacheEntry>;
function fetchReactions(msg: Message, emoji: ReactionEmoji, type: number) {
const key = emoji.name + (emoji.id ? `:${emoji.id}` : "");
return RestAPI.get({
url: `/channels/${msg.channel_id}/messages/${msg.id}/reactions/${key}`,
url: Constants.Endpoints.REACTIONS(msg.channel_id, msg.id, key),
query: {
limit: 100,
type

View file

@ -473,6 +473,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
ImBanana: {
name: "Im_Banana",
id: 635250116688871425n
},
xocherry: {
name: "xocherry",
id: 221288171013406720n
}
} satisfies Record<string, Dev>);

View file

@ -17,7 +17,7 @@
*/
import { MessageObject } from "@api/MessageEvents";
import { ChannelStore, ComponentDispatch, FluxDispatcher, GuildStore, InviteActions, MaskedLink, MessageActions, ModalImageClasses, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
import { ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, InviteActions, MaskedLink, MessageActions, ModalImageClasses, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
import { Guild, Message, User } from "discord-types/general";
import { ImageModal, ImageModalProps, ModalRoot, ModalSize, openModal } from "./modal";
@ -162,7 +162,7 @@ export async function fetchUserProfile(id: string, options?: FetchUserProfileOpt
FluxDispatcher.dispatch({ type: "USER_PROFILE_FETCH_START", userId: id });
const { body } = await RestAPI.get({
url: `/users/${id}/profile`,
url: Constants.Endpoints.USER_PROFILE(id),
query: {
with_mutual_guilds: false,
with_mutual_friends_count: false,