mirror of
https://github.com/Equicord/Equicord.git
synced 2025-02-20 15:18:50 -05:00
Merge remote-tracking branch 'upstream/dev'
This commit is contained in:
commit
7adcfaa735
38 changed files with 228 additions and 273 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "vencord",
|
||||
"private": "true",
|
||||
"version": "1.8.9",
|
||||
"version": "1.9.0",
|
||||
"description": "The other cutest Discord client mod",
|
||||
"homepage": "https://github.com/Equicord/Equicord#readme",
|
||||
"bugs": {
|
||||
|
|
|
@ -25,7 +25,7 @@ export async function loadLazyChunks() {
|
|||
// True if resolved, false otherwise
|
||||
const chunksSearchPromises = [] as Array<() => boolean>;
|
||||
|
||||
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("[^)]+?"\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/g);
|
||||
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
|
||||
|
||||
async function searchAndLoadLazyChunks(factoryCode: string) {
|
||||
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
||||
|
|
|
@ -83,13 +83,6 @@ export default definePlugin({
|
|||
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "useDefaultUserSettingsSections:function",
|
||||
replacement: {
|
||||
match: /(?<=useDefaultUserSettingsSections:function\(\){return )(\i)\}/,
|
||||
replace: "$self.wrapSettingsHook($1)}"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
|
||||
replacement: {
|
||||
|
|
|
@ -49,7 +49,7 @@ export default definePlugin({
|
|||
predicate: () => settings.store.domain
|
||||
},
|
||||
{
|
||||
find: "isSuspiciousDownload:",
|
||||
find: "bitbucket.org",
|
||||
replacement: {
|
||||
match: /function \i\(\i\){(?=.{0,60}\.parse\(\i\))/,
|
||||
replace: "$&return null;"
|
||||
|
|
|
@ -88,7 +88,7 @@ export default definePlugin({
|
|||
predicate: () => settings.store.disableFade
|
||||
},
|
||||
{ // Lazy-load contents
|
||||
match: /createPromise:\(\)=>([^:}]*?),webpackId:\d+,name:(?!="CollectiblesShop")"[^"]+"/g,
|
||||
match: /createPromise:\(\)=>([^:}]*?),webpackId:"?\d+"?,name:(?!="CollectiblesShop")"[^"]+"/g,
|
||||
replace: "$&,_:$1",
|
||||
predicate: () => settings.store.eagerLoad
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ export default definePlugin({
|
|||
{ // Load menu TOC eagerly
|
||||
find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format",
|
||||
replacement: {
|
||||
match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?\i\.\i\).{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/,
|
||||
match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/,
|
||||
replace: "$&(async ()=>$2)(),"
|
||||
},
|
||||
predicate: () => settings.store.eagerLoad
|
||||
|
@ -119,8 +119,8 @@ export default definePlugin({
|
|||
{ // Settings cog context menu
|
||||
find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
|
||||
replacement: {
|
||||
match: /\(0,\i.\i\)\(\)(?=\.filter\(\i=>\{let\{section:\i\}=)/,
|
||||
replace: "$self.wrapMenu($&)"
|
||||
match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/,
|
||||
replace: "$1$self.wrapMenu($2)"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Devs } from "@utils/constants";
|
|||
import { Margins } from "@utils/margins";
|
||||
import { classes } from "@utils/misc";
|
||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||
import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
||||
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
||||
import { Button, Forms, useStateFromStores } from "@webpack/common";
|
||||
|
||||
const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
||||
|
@ -30,7 +30,7 @@ function onPickColor(color: number) {
|
|||
updateColorVars(hexColor);
|
||||
}
|
||||
|
||||
const { saveClientTheme } = findByPropsLazy("saveClientTheme");
|
||||
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE",settings:{useSystemTheme:"system"===');
|
||||
|
||||
function setTheme(theme: string) {
|
||||
saveClientTheme({ theme });
|
||||
|
|
|
@ -24,20 +24,19 @@ import { closeAllModals } from "@utils/modal";
|
|||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { maybePromptToUpdate } from "@utils/updater";
|
||||
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
|
||||
import { DraftType, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
|
||||
import { DraftType, ExpressionPickerStore, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
|
||||
|
||||
const CrashHandlerLogger = new Logger("CrashHandler");
|
||||
|
||||
const { ModalStack, DraftManager, closeExpressionPicker } = proxyLazyWebpack(() => {
|
||||
const [ModalStack, DraftManager, ExpressionManager] = findBulk(
|
||||
const { ModalStack, DraftManager } = proxyLazyWebpack(() => {
|
||||
const [ModalStack, DraftManager] = findBulk(
|
||||
filters.byProps("pushLazy", "popAll"),
|
||||
filters.byProps("clearDraft", "saveDraft"),
|
||||
filters.byProps("closeExpressionPicker", "openExpressionPicker"),);
|
||||
);
|
||||
|
||||
return {
|
||||
ModalStack,
|
||||
DraftManager,
|
||||
closeExpressionPicker: ExpressionManager?.closeExpressionPicker,
|
||||
DraftManager
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -144,7 +143,7 @@ export default definePlugin({
|
|||
CrashHandlerLogger.debug("Failed to clear drafts.", err);
|
||||
}
|
||||
try {
|
||||
closeExpressionPicker();
|
||||
ExpressionPickerStore.closeExpressionPicker();
|
||||
}
|
||||
catch (err) {
|
||||
CrashHandlerLogger.debug("Failed to close expression picker.", err);
|
||||
|
|
|
@ -33,16 +33,13 @@ export default definePlugin({
|
|||
authors: [Devs.newwares],
|
||||
settings,
|
||||
patches: [
|
||||
{
|
||||
find: "IDLE_DURATION:function(){return",
|
||||
replacement: {
|
||||
match: /(IDLE_DURATION:function\(\){return )\i/,
|
||||
replace: "$1$self.getIdleTimeout()"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: 'type:"IDLE",idle:',
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=Date\.now\(\)-\i>)\i\.\i/,
|
||||
replace: "$self.getIdleTimeout()"
|
||||
},
|
||||
{
|
||||
match: /Math\.min\((\i\.\i\.getSetting\(\)\*\i\.\i\.\i\.SECOND),\i\.\i\)/,
|
||||
replace: "$1" // Decouple idle from afk (phone notifications will remain at user setting or 10 min maximum)
|
||||
|
|
|
@ -10,5 +10,5 @@ import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack";
|
|||
export const cl = classNameFactory("vc-decor-");
|
||||
export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton");
|
||||
|
||||
export const requireAvatarDecorationModal = extractAndLoadChunksLazy(["openAvatarDecorationModal:"]);
|
||||
export const requireAvatarDecorationModal = extractAndLoadChunksLazy([".COLLECTIBLES_SHOP_FULLSCREEN&&"]);
|
||||
export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Link } from "@components/Link";
|
|||
import { openInviteModal } from "@utils/discord";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
||||
import { filters, findComponentByCodeLazy, mapMangledModuleLazy } from "@webpack";
|
||||
import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common";
|
||||
|
||||
import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants";
|
||||
|
@ -19,7 +19,10 @@ import { AvatarDecorationModalPreview } from "../components";
|
|||
|
||||
const FileUpload = findComponentByCodeLazy("fileUploadInput,");
|
||||
|
||||
const { default: HelpMessage, HelpMessageTypes } = findByPropsLazy("HelpMessageTypes");
|
||||
const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE=3]="POSITIVE', {
|
||||
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"),
|
||||
HelpMessage: filters.byCode(".iconDiv")
|
||||
});
|
||||
|
||||
function useObjectURL(object: Blob | MediaSource | null) {
|
||||
const [url, setUrl] = useState<string | null>(null);
|
||||
|
|
|
@ -23,12 +23,12 @@ import { Logger } from "@utils/Logger";
|
|||
import { Margins } from "@utils/margins";
|
||||
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy, findStoreLazy } from "@webpack";
|
||||
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
||||
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||
import { Promisable } from "type-fest";
|
||||
|
||||
const StickersStore = findStoreLazy("StickersStore");
|
||||
const EmojiManager = findByPropsLazy("fetchEmoji", "uploadEmoji", "deleteEmoji");
|
||||
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
||||
|
||||
interface Sticker {
|
||||
t: "Sticker";
|
||||
|
@ -106,7 +106,7 @@ async function cloneEmoji(guildId: string, emoji: Emoji) {
|
|||
reader.readAsDataURL(data);
|
||||
});
|
||||
|
||||
return EmojiManager.uploadEmoji({
|
||||
return uploadEmoji({
|
||||
guildId,
|
||||
name: emoji.name.split("~")[0],
|
||||
image: dataUrl
|
||||
|
|
|
@ -28,7 +28,7 @@ import { Forms, React } from "@webpack/common";
|
|||
|
||||
import hideBugReport from "./hideBugReport.css?managed";
|
||||
|
||||
const KbdStyles = findByPropsLazy("key", "removeBuildOverride");
|
||||
const KbdStyles = findByPropsLazy("key", "combo");
|
||||
|
||||
const settings = definePluginSettings({
|
||||
toolbarDevMenu: {
|
||||
|
@ -106,9 +106,11 @@ export default definePlugin({
|
|||
<Forms.FormTitle tag="h3">More Information</Forms.FormTitle>
|
||||
<Forms.FormText variant="text-md/normal">
|
||||
You can open Discord's DevTools via {" "}
|
||||
<kbd className={KbdStyles.key}>{modKey}</kbd> +{" "}
|
||||
<kbd className={KbdStyles.key}>{altKey}</kbd> +{" "}
|
||||
<kbd className={KbdStyles.key}>O</kbd>{" "}
|
||||
<div className={KbdStyles.combo} style={{ display: "inline-flex" }}>
|
||||
<kbd className={KbdStyles.key}>{modKey}</kbd> +{" "}
|
||||
<kbd className={KbdStyles.key}>{altKey}</kbd> +{" "}
|
||||
<kbd className={KbdStyles.key}>O</kbd>{" "}
|
||||
</div>
|
||||
</Forms.FormText>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
@ -37,8 +37,8 @@ const StickerStore = findStoreLazy("StickersStore") as {
|
|||
};
|
||||
|
||||
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore");
|
||||
const ProtoUtils = findByPropsLazy("BINARY_READ_OPTIONS");
|
||||
const RoleSubscriptionEmojiUtils = findByPropsLazy("isUnusableRoleSubscriptionEmoji");
|
||||
|
||||
const BINARY_READ_OPTIONS = findByPropsLazy("readerFactory");
|
||||
|
||||
function searchProtoClassField(localName: string, protoClass: any) {
|
||||
const field = protoClass?.fields?.find((field: any) => field.localName === localName);
|
||||
|
@ -234,15 +234,16 @@ export default definePlugin({
|
|||
}
|
||||
]
|
||||
},
|
||||
// FIXME
|
||||
// Allows the usage of subscription-locked emojis
|
||||
{
|
||||
find: "isUnusableRoleSubscriptionEmoji:function",
|
||||
/* {
|
||||
find: ".getUserIsAdmin(",
|
||||
replacement: {
|
||||
match: /isUnusableRoleSubscriptionEmoji:function/,
|
||||
match: /(?=.+?\.getUserIsAdmin\((?<=function (\i)\(\i,\i\){.+?))(\i):function\(\){return \1}/,
|
||||
// Replace the original export with a func that always returns false and alias the original
|
||||
replace: "isUnusableRoleSubscriptionEmoji:()=>()=>false,isUnusableRoleSubscriptionEmojiOriginal:function"
|
||||
replace: "$2:()=>()=>false,isUnusableRoleSubscriptionEmojiOriginal:function(){return $1}"
|
||||
}
|
||||
},
|
||||
}, */
|
||||
// Allow stickers to be sent everywhere
|
||||
{
|
||||
find: "canUseCustomStickersEverywhere:function",
|
||||
|
@ -361,7 +362,7 @@ export default definePlugin({
|
|||
replacement: [
|
||||
{
|
||||
// Export the renderable sticker to be used in the fake nitro sticker notice
|
||||
match: /let{renderableSticker:(\i).{0,250}isGuildSticker.+?channel:\i,/,
|
||||
match: /let{renderableSticker:(\i).{0,270}sticker:\i,channel:\i,/,
|
||||
replace: (m, renderableSticker) => `${m}fakeNitroRenderableSticker:${renderableSticker},`
|
||||
},
|
||||
{
|
||||
|
@ -475,12 +476,12 @@ export default definePlugin({
|
|||
const premiumType = UserStore?.getCurrentUser()?._realPremiumType ?? UserStore?.getCurrentUser()?.premiumType ?? 0;
|
||||
if (premiumType === 2 || backgroundGradientPresetId == null) return original();
|
||||
|
||||
if (!PreloadedUserSettingsActionCreators || !AppearanceSettingsActionCreators || !ClientThemeSettingsActionsCreators || !ProtoUtils) return;
|
||||
if (!PreloadedUserSettingsActionCreators || !AppearanceSettingsActionCreators || !ClientThemeSettingsActionsCreators || !BINARY_READ_OPTIONS) return;
|
||||
|
||||
const currentAppearanceSettings = PreloadedUserSettingsActionCreators.getCurrentValue().appearance;
|
||||
|
||||
const newAppearanceProto = currentAppearanceSettings != null
|
||||
? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), ProtoUtils.BINARY_READ_OPTIONS)
|
||||
? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), BINARY_READ_OPTIONS)
|
||||
: AppearanceSettingsActionCreators.create();
|
||||
|
||||
newAppearanceProto.theme = theme;
|
||||
|
@ -819,8 +820,9 @@ export default definePlugin({
|
|||
if (e.type === 0) return true;
|
||||
if (e.available === false) return false;
|
||||
|
||||
const isUnusableRoleSubEmoji = RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji;
|
||||
if (isUnusableRoleSubEmoji(e, this.guildId)) return false;
|
||||
// FIXME
|
||||
/* const isUnusableRoleSubEmoji = isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji;
|
||||
if (isUnusableRoleSubEmoji(e, this.guildId)) return false; */
|
||||
|
||||
if (this.canUseEmotes)
|
||||
return e.guildId === this.guildId || hasExternalEmojiPerms(channelId);
|
||||
|
|
|
@ -111,7 +111,7 @@ interface ProfileModalProps {
|
|||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
||||
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>('"ProfileCustomizationPreview"');
|
||||
|
||||
const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i\("(.+?)"\).then\(\i\.bind\(\i,"(.+?)"\)\)/);
|
||||
const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i\("?(.+?)"?\).then\(\i\.bind\(\i,"?(.+?)"?\)\)/);
|
||||
|
||||
export default definePlugin({
|
||||
name: "FakeProfileThemes",
|
||||
|
|
|
@ -27,7 +27,7 @@ export default definePlugin({
|
|||
authors: [Devs.D3SOX, Devs.Nickyux],
|
||||
patches: [
|
||||
{
|
||||
find: "AVATAR_DECORATION_PADDING:",
|
||||
find: ".PREMIUM_GUILD_SUBSCRIPTION_TOOLTIP",
|
||||
replacement: {
|
||||
match: /,isOwner:(\i),/,
|
||||
replace: ",_isOwner:$1=$self.isGuildOwner(e),"
|
||||
|
|
|
@ -16,14 +16,12 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
|
||||
import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { Constants, RestAPI, UserStore } from "@webpack/common";
|
||||
|
||||
const FriendInvites = findByPropsLazy("createFriendInvite");
|
||||
const { uuid4 } = findByPropsLazy("uuid4");
|
||||
|
||||
export default definePlugin({
|
||||
name: "FriendInvites",
|
||||
|
@ -35,47 +33,9 @@ export default definePlugin({
|
|||
name: "create friend invite",
|
||||
description: "Generates a friend invite link.",
|
||||
inputType: ApplicationCommandInputType.BOT,
|
||||
options: [{
|
||||
name: "Uses",
|
||||
description: "How many uses?",
|
||||
choices: [
|
||||
{ label: "1", name: "1", value: "1" },
|
||||
{ label: "5", name: "5", value: "5" }
|
||||
],
|
||||
required: false,
|
||||
type: ApplicationCommandOptionType.INTEGER
|
||||
}],
|
||||
|
||||
execute: async (args, ctx) => {
|
||||
const uses = findOption<number>(args, "Uses", 5);
|
||||
|
||||
if (uses === 1 && !UserStore.getCurrentUser().phone)
|
||||
return sendBotMessage(ctx.channel.id, {
|
||||
content: "You need to have a phone number connected to your account to create a friend invite with 1 use!"
|
||||
});
|
||||
|
||||
let invite: any;
|
||||
if (uses === 1) {
|
||||
const random = uuid4();
|
||||
const { body: { invite_suggestions } } = await RestAPI.post({
|
||||
url: Constants.Endpoints.FRIEND_FINDER,
|
||||
body: {
|
||||
modified_contacts: {
|
||||
[random]: [1, "", ""]
|
||||
},
|
||||
phone_contact_methods_count: 1
|
||||
}
|
||||
});
|
||||
invite = await FriendInvites.createFriendInvite({
|
||||
code: invite_suggestions[0][3],
|
||||
recipient_phone_number_or_email: random,
|
||||
contact_visibility: 1,
|
||||
filter_visibilities: [],
|
||||
filtered_invite_suggestions_index: 1
|
||||
});
|
||||
} else {
|
||||
invite = await FriendInvites.createFriendInvite();
|
||||
}
|
||||
const invite = await FriendInvites.createFriendInvite();
|
||||
|
||||
sendBotMessage(ctx.channel.id, {
|
||||
content: `
|
||||
|
|
|
@ -4,21 +4,23 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { getCurrentChannel } from "@utils/discord";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { classes } from "@utils/misc";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
||||
import { Heading, React, RelationshipStore, Text } from "@webpack/common";
|
||||
|
||||
const container = findByPropsLazy("memberSinceWrapper");
|
||||
const { getCreatedAtDate } = findByPropsLazy("getCreatedAtDate");
|
||||
const clydeMoreInfo = findByPropsLazy("clydeMoreInfo");
|
||||
const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
|
||||
const locale = findByPropsLazy("getLocale");
|
||||
const lastSection = findByPropsLazy("lastSection");
|
||||
|
||||
const cl = classNameFactory("vc-friendssince-");
|
||||
|
||||
export default definePlugin({
|
||||
name: "FriendsSince",
|
||||
description: "Shows when you became friends with someone in the user popout",
|
||||
|
@ -28,7 +30,7 @@ export default definePlugin({
|
|||
{
|
||||
find: ".USER_PROFILE}};return",
|
||||
replacement: {
|
||||
match: /\i.\i,\{userId:(\i.id).{0,30}}\)/,
|
||||
match: /,{userId:(\i.id).{0,30}}\)/,
|
||||
replace: "$&,$self.friendsSince({ userId: $1 })"
|
||||
}
|
||||
},
|
||||
|
@ -36,7 +38,7 @@ export default definePlugin({
|
|||
{
|
||||
find: ".PROFILE_PANEL,",
|
||||
replacement: {
|
||||
match: /\i.\i,\{userId:([^,]+?)}\)/,
|
||||
match: /,{userId:([^,]+?)}\)/,
|
||||
replace: "$&,$self.friendsSince({ userId: $1 })"
|
||||
}
|
||||
},
|
||||
|
@ -69,7 +71,7 @@ export default definePlugin({
|
|||
|
||||
return (
|
||||
<div className={lastSection.section}>
|
||||
<Heading variant="eyebrow" className={clydeMoreInfo.title}>
|
||||
<Heading variant="eyebrow" className={cl("title")}>
|
||||
Friends Since
|
||||
</Heading>
|
||||
|
||||
|
@ -86,7 +88,7 @@ export default definePlugin({
|
|||
<path d="M3 5v-.75C3 3.56 3.56 3 4.25 3s1.24.56 1.33 1.25C6.12 8.65 9.46 12 13 12h1a8 8 0 0 1 8 8 2 2 0 0 1-2 2 .21.21 0 0 1-.2-.15 7.65 7.65 0 0 0-1.32-2.3c-.15-.2-.42-.06-.39.17l.25 2c.02.15-.1.28-.25.28H9a2 2 0 0 1-2-2v-2.22c0-1.57-.67-3.05-1.53-4.37A15.85 15.85 0 0 1 3 5Z" />
|
||||
</svg>
|
||||
)}
|
||||
<Text variant="text-sm/normal" className={classes(clydeMoreInfo.body, textClassName)}>
|
||||
<Text variant="text-sm/normal" className={classes(cl("body"), textClassName)}>
|
||||
{getCreatedAtDate(friendsSince, locale.getLocale())}
|
||||
</Text>
|
||||
</div>
|
||||
|
|
12
src/plugins/friendsSince/styles.css
Normal file
12
src/plugins/friendsSince/styles.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* copy pasted from discord */
|
||||
|
||||
.vc-friendssince-title {
|
||||
display: flex;
|
||||
font-weight: 700;
|
||||
margin-bottom: 6px
|
||||
}
|
||||
|
||||
.vc-friendssince-body {
|
||||
font-size: 14px;
|
||||
line-height: 18px
|
||||
}
|
|
@ -19,9 +19,7 @@
|
|||
import { Devs } from "@utils/constants";
|
||||
import { insertTextIntoChatInputBox } from "@utils/discord";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
|
||||
const { closeExpressionPicker } = findByPropsLazy("closeExpressionPicker");
|
||||
import { ExpressionPickerStore } from "@webpack/common";
|
||||
|
||||
export default definePlugin({
|
||||
name: "GifPaste",
|
||||
|
@ -39,7 +37,7 @@ export default definePlugin({
|
|||
handleSelect(gif?: { url: string; }) {
|
||||
if (gif) {
|
||||
insertTextIntoChatInputBox(gif.url + " ");
|
||||
closeExpressionPicker();
|
||||
ExpressionPickerStore.closeExpressionPicker();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { findLazy } from "@webpack";
|
||||
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";
|
||||
import { Channel, Message } from "discord-types/general";
|
||||
|
||||
|
@ -49,7 +49,7 @@ const settings = definePluginSettings({
|
|||
unholyMultiGreetEnabled?: boolean;
|
||||
}>();
|
||||
|
||||
const { WELCOME_STICKERS } = findByPropsLazy("WELCOME_STICKERS");
|
||||
const WELCOME_STICKERS = findLazy(m => Array.isArray(m) && m[0]?.name === "Wave");
|
||||
|
||||
function greet(channel: Channel, message: Message, stickers: string[]) {
|
||||
const options = MessageActions.getSendMessageOptionsForReply({
|
||||
|
|
|
@ -16,7 +16,8 @@ export default definePlugin({
|
|||
{
|
||||
find: "unknownUserMentionPlaceholder:",
|
||||
replacement: {
|
||||
match: /\(0,\i\.isEmbedInline\)\(\i\)/,
|
||||
// SimpleEmbedTypes.has(embed.type) && isEmbedInline(embed)
|
||||
match: /\i\.has\(\i\.type\)&&\(0,\i\.\i\)\(\i\)/,
|
||||
replace: "false",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
import { registerCommand, unregisterCommand } from "@api/Commands";
|
||||
import { addContextMenuPatch, removeContextMenuPatch } from "@api/ContextMenu";
|
||||
import { Settings } from "@api/Settings";
|
||||
import { onceDefined } from "@shared/onceDefined";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { canonicalizeFind } from "@utils/patches";
|
||||
import { Patch, Plugin, ReporterTestable, StartAt } from "@utils/types";
|
||||
|
@ -34,7 +33,7 @@ const logger = new Logger("PluginManager", "#a6d189");
|
|||
|
||||
export const PMLogger = logger;
|
||||
export const plugins = Plugins;
|
||||
export let patches = [] as Patch[];
|
||||
export const patches = [] as Patch[];
|
||||
|
||||
/** Whether we have subscribed to flux events of all the enabled plugins when FluxDispatcher was ready */
|
||||
let enabledPluginsSubscribedFlux = false;
|
||||
|
@ -43,10 +42,6 @@ const subscribedFluxEventsPlugins = new Set<string>();
|
|||
const pluginsValues = Object.values(Plugins);
|
||||
const settings = Settings.plugins;
|
||||
|
||||
const forceDisabled = new Set([
|
||||
"ShowHiddenChannels",
|
||||
"MoreUserTags"
|
||||
]);
|
||||
export function isPluginEnabled(p: string) {
|
||||
return (
|
||||
Plugins[p]?.required ||
|
||||
|
@ -127,17 +122,9 @@ for (const p of pluginsValues) {
|
|||
}
|
||||
}
|
||||
|
||||
onceDefined(window, "GLOBAL_ENV", v => {
|
||||
if (v.SENTRY_TAGS.buildId !== "366c746173a6ca0a801e9f4a4d7b6745e6de45d4") {
|
||||
patches = patches.filter(p => !forceDisabled.has(p.plugin));
|
||||
}
|
||||
});
|
||||
|
||||
export const startAllPlugins = traceFunction("startAllPlugins", function startAllPlugins(target: StartAt) {
|
||||
logger.info(`Starting plugins (stage ${target})`);
|
||||
for (const name in Plugins) {
|
||||
if (window.GLOBAL_ENV?.SENTRY_TAGS.buildId !== "366c746173a6ca0a801e9f4a4d7b6745e6de45d4" && forceDisabled.has(name)) continue;
|
||||
|
||||
if (isPluginEnabled(name) && (!IS_REPORTER || isReporterTestable(Plugins[name], ReporterTestable.Start))) {
|
||||
const p = Plugins[name];
|
||||
|
||||
|
@ -208,7 +195,7 @@ export function subscribeAllPluginsFluxEvents(fluxDispatcher: typeof FluxDispatc
|
|||
}
|
||||
|
||||
export const startPlugin = traceFunction("startPlugin", function startPlugin(p: Plugin) {
|
||||
const { name, commands, flux, contextMenus } = p;
|
||||
const { name, commands, contextMenus } = p;
|
||||
|
||||
if (p.start) {
|
||||
logger.info("Starting plugin", name);
|
||||
|
@ -254,7 +241,7 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
|||
}, p => `startPlugin ${p.name}`);
|
||||
|
||||
export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plugin) {
|
||||
const { name, commands, flux, contextMenus } = p;
|
||||
const { name, commands, contextMenus } = p;
|
||||
|
||||
if (p.stop) {
|
||||
logger.info("Stopping plugin", name);
|
||||
|
|
|
@ -10,7 +10,7 @@ import { findByPropsLazy } from "@webpack";
|
|||
|
||||
const linkRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
|
||||
|
||||
const { SlateTransforms } = findByPropsLazy("SlateTransforms");
|
||||
const SlateTransforms = findByPropsLazy("insertText", "selectCommandOption");
|
||||
|
||||
export default definePlugin({
|
||||
name: "MaskedLinkPaste",
|
||||
|
|
|
@ -21,12 +21,10 @@ import { Flex } from "@components/Flex";
|
|||
import { Devs } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy, findLazy } from "@webpack";
|
||||
import { findByCodeLazy, findLazy } from "@webpack";
|
||||
import { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip, useState } from "@webpack/common";
|
||||
import { RC } from "@webpack/types";
|
||||
import { Channel, Message, User } from "discord-types/general";
|
||||
|
||||
type PermissionName = "CREATE_INSTANT_INVITE" | "KICK_MEMBERS" | "BAN_MEMBERS" | "ADMINISTRATOR" | "MANAGE_CHANNELS" | "MANAGE_GUILD" | "CHANGE_NICKNAME" | "MANAGE_NICKNAMES" | "MANAGE_ROLES" | "MANAGE_WEBHOOKS" | "MANAGE_GUILD_EXPRESSIONS" | "CREATE_GUILD_EXPRESSIONS" | "VIEW_AUDIT_LOG" | "VIEW_CHANNEL" | "VIEW_GUILD_ANALYTICS" | "VIEW_CREATOR_MONETIZATION_ANALYTICS" | "MODERATE_MEMBERS" | "SEND_MESSAGES" | "SEND_TTS_MESSAGES" | "MANAGE_MESSAGES" | "EMBED_LINKS" | "ATTACH_FILES" | "READ_MESSAGE_HISTORY" | "MENTION_EVERYONE" | "USE_EXTERNAL_EMOJIS" | "ADD_REACTIONS" | "USE_APPLICATION_COMMANDS" | "MANAGE_THREADS" | "CREATE_PUBLIC_THREADS" | "CREATE_PRIVATE_THREADS" | "USE_EXTERNAL_STICKERS" | "SEND_MESSAGES_IN_THREADS" | "CONNECT" | "SPEAK" | "MUTE_MEMBERS" | "DEAFEN_MEMBERS" | "MOVE_MEMBERS" | "USE_VAD" | "PRIORITY_SPEAKER" | "STREAM" | "USE_EMBEDDED_ACTIVITIES" | "USE_SOUNDBOARD" | "USE_EXTERNAL_SOUNDS" | "REQUEST_TO_SPEAK" | "MANAGE_EVENTS" | "CREATE_EVENTS";
|
||||
import type { Permissions, RC } from "@webpack/types";
|
||||
import type { Channel, Guild, Message, User } from "discord-types/general";
|
||||
|
||||
interface Tag {
|
||||
// name used for identifying, must be alphanumeric + underscores
|
||||
|
@ -34,7 +32,7 @@ interface Tag {
|
|||
// name shown on the tag itself, can be anything probably; automatically uppercase'd
|
||||
displayName: string;
|
||||
description: string;
|
||||
permissions?: PermissionName[];
|
||||
permissions?: Permissions[];
|
||||
condition?(message: Message | null, user: User, channel: Channel): boolean;
|
||||
}
|
||||
|
||||
|
@ -54,10 +52,14 @@ interface TagSettings {
|
|||
[k: string]: TagSetting;
|
||||
}
|
||||
|
||||
// PermissionStore.computePermissions is not the same function and doesn't work here
|
||||
const PermissionUtil = findByPropsLazy("computePermissions", "canEveryoneRole") as {
|
||||
computePermissions({ ...args }): bigint;
|
||||
};
|
||||
// PermissionStore.computePermissions will not work here since it only gets permissions for the current user
|
||||
const computePermissions: (options: {
|
||||
user?: { id: string; } | string | null;
|
||||
context?: Guild | Channel | null;
|
||||
overwrites?: Channel["permissionOverwrites"] | null;
|
||||
checkElevated?: boolean /* = true */;
|
||||
excludeGuildPermissions?: boolean /* = false */;
|
||||
}) => bigint = findByCodeLazy(".getCurrentUser()", ".computeLurkerPermissionsAllowList()");
|
||||
|
||||
const Tag = findLazy(m => m.Types?.[0] === "BOT") as RC<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };
|
||||
|
||||
|
@ -193,7 +195,7 @@ export default definePlugin({
|
|||
patches: [
|
||||
// add tags to the tag list
|
||||
{
|
||||
find: "BotTagTypes:",
|
||||
find: ".ORIGINAL_POSTER=",
|
||||
replacement: {
|
||||
match: /\((\i)=\{\}\)\)\[(\i)\.BOT/,
|
||||
replace: "($1=$self.getTagTypes()))[$2.BOT"
|
||||
|
@ -222,7 +224,7 @@ export default definePlugin({
|
|||
},
|
||||
// in messages
|
||||
{
|
||||
find: "renderSystemTag:",
|
||||
find: ".Types.ORIGINAL_POSTER",
|
||||
replacement: {
|
||||
match: /;return\((\(null==\i\?void 0:\i\.isSystemDM\(\).+?.Types.ORIGINAL_POSTER\)),null==(\i)\)/,
|
||||
replace: ";$1;$2=$self.getTag({...arguments[0],origType:$2,location:'chat'});return $2 == null"
|
||||
|
@ -283,7 +285,7 @@ export default definePlugin({
|
|||
const guild = GuildStore.getGuild(channel?.guild_id);
|
||||
if (!guild) return [];
|
||||
|
||||
const permissions = PermissionUtil.computePermissions({ user, context: guild, overwrites: channel.permissionOverwrites });
|
||||
const permissions = computePermissions({ user, context: guild, overwrites: channel.permissionOverwrites });
|
||||
return Object.entries(PermissionsBits)
|
||||
.map(([perm, permInt]) =>
|
||||
permissions & permInt ? perm : ""
|
||||
|
@ -330,7 +332,7 @@ export default definePlugin({
|
|||
}: {
|
||||
message?: Message,
|
||||
user: User & { isClyde(): boolean; },
|
||||
channel?: Channel & { isForumPost(): boolean; },
|
||||
channel?: Channel & { isForumPost(): boolean; isMediaPost(): boolean; },
|
||||
channelId?: string;
|
||||
origType?: number;
|
||||
location: "chat" | "not-chat";
|
||||
|
@ -367,7 +369,7 @@ export default definePlugin({
|
|||
tag.permissions?.some(perm => perms.includes(perm)) ||
|
||||
(tag.condition?.(message!, user, channel))
|
||||
) {
|
||||
if (channel.isForumPost() && channel.ownerId === user.id)
|
||||
if ((channel.isForumPost() || channel.isMediaPost()) && channel.ownerId === user.id)
|
||||
type = Tag.Types[`${tag.name}-OP`];
|
||||
else if (user.bot && !isWebhook(message!, user) && !settings.dontShowBotTag)
|
||||
type = Tag.Types[`${tag.name}-BOT`];
|
||||
|
|
|
@ -19,11 +19,16 @@
|
|||
import { definePluginSettings, migratePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
|
||||
|
||||
const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings");
|
||||
const { toggleShowAllChannels } = findByPropsLazy("toggleShowAllChannels");
|
||||
const { isOptInEnabledForGuild } = findByPropsLazy("isOptInEnabledForGuild");
|
||||
const { toggleShowAllChannels } = mapMangledModuleLazy(".onboardExistingMember(", {
|
||||
toggleShowAllChannels: m => {
|
||||
const s = String(m);
|
||||
return s.length < 100 && !s.includes("onboardExistingMember") && !s.includes("getOptedInChannels");
|
||||
}
|
||||
});
|
||||
const isOptInEnabledForGuild = findByCodeLazy(".COMMUNITY)||", ".isOptInEnabled(");
|
||||
|
||||
const settings = definePluginSettings({
|
||||
guild: {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { canonicalizeMatch } from "@utils/patches";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
||||
const settings = definePluginSettings({
|
||||
|
@ -31,7 +32,7 @@ export default definePlugin({
|
|||
patches: [
|
||||
// Permission lockout, just set the check to true
|
||||
{
|
||||
find: ".showPermissionLockoutModal(",
|
||||
find: ".STAGE_CHANNEL_CANNOT_OVERWRITE_PERMISSION",
|
||||
replacement: [
|
||||
{
|
||||
match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/,
|
||||
|
@ -45,9 +46,8 @@ export default definePlugin({
|
|||
find: ".ONBOARDING_CHANNEL_THRESHOLD_WARNING",
|
||||
replacement: [
|
||||
{
|
||||
// are we java yet?
|
||||
match: /(?<=(?:isDefaultChannelThresholdMetAfterDelete|checkDefaultChannelThresholdMetAfterChannelPermissionDeny):function\(\)\{)return \i(?=\})/g,
|
||||
replace: "return () => true"
|
||||
match: /{(\i:function\(\){return \i},?){2}}/,
|
||||
replace: m => m.replaceAll(canonicalizeMatch(/return \i/g), "return ()=>Promise.resolve(true)")
|
||||
}
|
||||
],
|
||||
predicate: () => settings.store.onboarding
|
||||
|
|
|
@ -33,7 +33,7 @@ interface ColorPickerWithSwatchesProps {
|
|||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
|
||||
const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker");
|
||||
|
||||
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\).{0,50}"UserSettings"/);
|
||||
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
||||
|
||||
const cl = classNameFactory("vc-pindms-modal-");
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import definePlugin from "@utils/types";
|
|||
import { findByPropsLazy } from "@webpack";
|
||||
|
||||
const SpoilerClasses = findByPropsLazy("spoilerContent");
|
||||
const MessagesClasses = findByPropsLazy("messagesWrapper", "messages");
|
||||
const MessagesClasses = findByPropsLazy("messagesWrapper");
|
||||
|
||||
export default definePlugin({
|
||||
name: "RevealAllSpoilers",
|
||||
|
|
|
@ -28,9 +28,8 @@ import { blockUser, deleteReview, reportReview, unblockUser } from "../reviewDbA
|
|||
import { settings } from "../settings";
|
||||
import { canBlockReviewAuthor, canDeleteReview, canReportReview, cl, showToast } from "../utils";
|
||||
import { openBlockModal } from "./BlockedUserModal";
|
||||
import { BlockButton, DeleteButton, ReplyButton, ReportButton } from "./MessageButton";
|
||||
import { BlockButton, DeleteButton, ReportButton } from "./MessageButton";
|
||||
import ReviewBadge from "./ReviewBadge";
|
||||
import { ReviewsInputComponent } from "./ReviewsView";
|
||||
|
||||
export default LazyComponent(() => {
|
||||
// this is terrible, blame mantika
|
||||
|
@ -51,11 +50,8 @@ export default LazyComponent(() => {
|
|||
|
||||
const dateFormat = new Intl.DateTimeFormat();
|
||||
|
||||
return function ReviewComponent({ review, refetch, profileId, isReply = false }: { review: Review; refetch(): void; profileId: string; isReply?: boolean; }) {
|
||||
return function ReviewComponent({ review, refetch, profileId }: { review: Review; refetch(): void; profileId: string; }) {
|
||||
const [showAll, setShowAll] = useState(false);
|
||||
const [replying, setReplying] = useState(false);
|
||||
|
||||
const refresh = () => { refetch(); setReplying(false); };
|
||||
|
||||
function openModal() {
|
||||
openUserProfile(review.sender.discordID);
|
||||
|
@ -73,7 +69,7 @@ export default LazyComponent(() => {
|
|||
} else {
|
||||
deleteReview(review.id).then(res => {
|
||||
if (res) {
|
||||
refresh();
|
||||
refetch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -121,89 +117,75 @@ export default LazyComponent(() => {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classes(cl("review-container"), cozyMessage, wrapper, message, groupStart, cozy, isReply ? cl("reply") : cl("review"))} style={
|
||||
{
|
||||
marginLeft: "0px",
|
||||
paddingLeft: "52px", // wth is this
|
||||
// nobody knows anymore
|
||||
}
|
||||
}>
|
||||
{isReply && <div className={cl("reply-line")} />}
|
||||
<div className={classes(cl("review"), cozyMessage, wrapper, message, groupStart, cozy)} style={
|
||||
{
|
||||
marginLeft: "0px",
|
||||
paddingLeft: "52px", // wth is this
|
||||
// nobody knows anymore
|
||||
}
|
||||
}>
|
||||
|
||||
<>
|
||||
<img style={{ left: "0px", zIndex: 0 }}
|
||||
className={classes(avatar, clickable, cl("avatar"))}
|
||||
onClick={openModal}
|
||||
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
|
||||
/>
|
||||
<img
|
||||
className={classes(avatar, clickable)}
|
||||
onClick={openModal}
|
||||
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
|
||||
style={{ left: "0px", zIndex: 0 }}
|
||||
/>
|
||||
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
|
||||
<span
|
||||
className={classes(clickable, username)}
|
||||
style={{ color: "var(--channels-default)", fontSize: "14px" }}
|
||||
onClick={() => openModal()}
|
||||
>
|
||||
{review.sender.username}
|
||||
</span>
|
||||
|
||||
<div className={cl("white-line")} />
|
||||
|
||||
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
|
||||
<span
|
||||
className={classes(clickable, username)}
|
||||
style={{ color: "var(--channels-default)", fontSize: "14px" }}
|
||||
onClick={() => openModal()}
|
||||
>
|
||||
{review.sender.username}
|
||||
{review.type === ReviewType.System && (
|
||||
<span
|
||||
className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.px, botTag.rem)}
|
||||
style={{ marginLeft: "4px" }}>
|
||||
<span className={botTag.botText}>
|
||||
System
|
||||
</span>
|
||||
{review.type === ReviewType.System && (
|
||||
<span
|
||||
className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.botTag, botTag.px, botTag.rem)}
|
||||
style={{ marginLeft: "4px" }}>
|
||||
<span className={botTag.botText}>
|
||||
System
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isAuthorBlocked && (
|
||||
<ReviewBadge
|
||||
name="You have blocked this user"
|
||||
description="You have blocked this user"
|
||||
icon="/assets/aaee57e0090991557b66.svg"
|
||||
type={0}
|
||||
onClick={() => openBlockModal()}
|
||||
/>
|
||||
)}
|
||||
{review.sender.badges.map(badge => <ReviewBadge {...badge} />)}
|
||||
|
||||
{
|
||||
!settings.store.hideTimestamps && review.type !== ReviewType.System && (
|
||||
<Timestamp timestamp={new Date(review.timestamp * 1000)} >
|
||||
{dateFormat.format(review.timestamp * 1000)}
|
||||
</Timestamp>)
|
||||
}
|
||||
|
||||
<div className={cl("review-comment")}>
|
||||
{(review.comment.length > 200 && !showAll)
|
||||
? [Parser.parseGuildEventDescription(review.comment.substring(0, 200)), "...", <br />, (<a onClick={() => setShowAll(true)}>Read more</a>)]
|
||||
: Parser.parseGuildEventDescription(review.comment)}
|
||||
</div>
|
||||
{review.id !== 0 && (
|
||||
<div className={classes(container, isHeader, cl("buttons"))} style={{
|
||||
padding: "0px",
|
||||
}}>
|
||||
<div className={classes(buttonClasses.wrapper, buttonsInner)} >
|
||||
{canReportReview(review) && <ReportButton onClick={reportRev} />}
|
||||
{canBlockReviewAuthor(profileId, review) && <BlockButton isBlocked={isAuthorBlocked} onClick={blockReviewSender} />}
|
||||
{canDeleteReview(profileId, review) && <DeleteButton onClick={delReview} />}
|
||||
{!isReply && <ReplyButton onClick={() => setReplying(!replying)} />}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
{
|
||||
review.replies?.map(r => (
|
||||
<ReviewComponent review={r} refetch={refresh} profileId={profileId} isReply={true} />
|
||||
))
|
||||
}
|
||||
{replying && <ReviewsInputComponent repliesTo={review.id} discordId={profileId} name={review.sender.username} isAuthor={false} refetch={refresh} />}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
{isAuthorBlocked && (
|
||||
<ReviewBadge
|
||||
name="You have blocked this user"
|
||||
description="You have blocked this user"
|
||||
icon="/assets/aaee57e0090991557b66.svg"
|
||||
type={0}
|
||||
onClick={() => openBlockModal()}
|
||||
/>
|
||||
)}
|
||||
{review.sender.badges.map(badge => <ReviewBadge {...badge} />)}
|
||||
|
||||
{
|
||||
!settings.store.hideTimestamps && review.type !== ReviewType.System && (
|
||||
<Timestamp timestamp={new Date(review.timestamp * 1000)} >
|
||||
{dateFormat.format(review.timestamp * 1000)}
|
||||
</Timestamp>)
|
||||
}
|
||||
|
||||
<div className={cl("review-comment")}>
|
||||
{(review.comment.length > 200 && !showAll)
|
||||
? [Parser.parseGuildEventDescription(review.comment.substring(0, 200)), "...", <br />, (<a onClick={() => setShowAll(true)}>Read more</a>)]
|
||||
: Parser.parseGuildEventDescription(review.comment)}
|
||||
</div>
|
||||
|
||||
{review.id !== 0 && (
|
||||
<div className={classes(container, isHeader, buttons)} style={{
|
||||
padding: "0px",
|
||||
}}>
|
||||
<div className={classes(buttonClasses.wrapper, buttonsInner)} >
|
||||
{canReportReview(review) && <ReportButton onClick={reportRev} />}
|
||||
{canBlockReviewAuthor(profileId, review) && <BlockButton isBlocked={isAuthorBlocked} onClick={blockReviewSender} />}
|
||||
{canDeleteReview(profileId, review) && <DeleteButton onClick={delReview} />}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
|
@ -57,7 +57,7 @@ export default definePlugin({
|
|||
{
|
||||
find: "SUMMARIZEABLE.has",
|
||||
replacement: {
|
||||
match: /\i\.hasFeature\(.{0,10}\.SUMMARIES_ENABLED\w+?\)/g,
|
||||
match: /\i\.hasFeature\(\i\.\i\.SUMMARIES_ENABLED\w+?\)/g,
|
||||
replace: "true"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -116,14 +116,14 @@ export default definePlugin({
|
|||
},
|
||||
// Prevent Discord from trying to connect to hidden stage channels
|
||||
{
|
||||
find: ".MAX_STAGE_VOICE_USER_LIMIT})",
|
||||
find: ".AUDIENCE),{isSubscriptionGated",
|
||||
replacement: {
|
||||
match: /!(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/,
|
||||
replace: (m, channel) => `${m}&&!$self.isHiddenChannel(${channel})`
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "ChannelItemEditButton:function(){",
|
||||
find: 'tutorialId:"instant-invite"',
|
||||
replacement: [
|
||||
// Render null instead of the buttons if the channel is hidden
|
||||
...[
|
||||
|
@ -195,7 +195,7 @@ export default definePlugin({
|
|||
// Hide the new version of unreads box for hidden channels
|
||||
find: '="ChannelListUnreadsStore",',
|
||||
replacement: {
|
||||
match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i)\))/g, // Global because Discord has multiple methods like that in the same module
|
||||
match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/,
|
||||
replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`
|
||||
}
|
||||
},
|
||||
|
@ -203,15 +203,15 @@ export default definePlugin({
|
|||
// Make the old version of unreads box not visible for hidden channels
|
||||
find: "renderBottomUnread(){",
|
||||
replacement: {
|
||||
match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i\.record)\))/,
|
||||
match: /(?<=!0\))(?=&&\(0,\i\.\i\)\((\i\.record)\))/,
|
||||
replace: "&&!$self.isHiddenChannel($1)"
|
||||
}
|
||||
},
|
||||
{
|
||||
// Make the state of the old version of unreads box not include hidden channels
|
||||
find: ".useFlattenedChannelIdListWithThreads)",
|
||||
find: "ignoreRecents:!0",
|
||||
replacement: {
|
||||
match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i)\))/,
|
||||
match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/,
|
||||
replace: "&&!$self.isHiddenChannel($1)"
|
||||
}
|
||||
},
|
||||
|
@ -257,7 +257,7 @@ export default definePlugin({
|
|||
{
|
||||
find: '"alt+shift+down"',
|
||||
replacement: {
|
||||
match: /(?<=getChannel\(\i\);return null!=(\i))(?=.{0,150}?getHasImportantUnread\)\(\i\))/,
|
||||
match: /(?<=getChannel\(\i\);return null!=(\i))(?=.{0,150}?>0\)&&\(0,\i\.\i\)\(\i\))/,
|
||||
replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`
|
||||
}
|
||||
},
|
||||
|
@ -289,7 +289,7 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
// If the @everyone role has the required permissions, make the array only contain it
|
||||
match: /computePermissionsForRoles.+?.value\(\)(?<=channel:(\i).+?)/,
|
||||
match: /forceRoles:.+?.value\(\)(?<=channel:(\i).+?)/,
|
||||
replace: (m, channel) => `${m}.reduce(...$self.makeAllowedRolesReduce(${channel}.guild_id))`
|
||||
},
|
||||
{
|
||||
|
@ -422,7 +422,7 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
// Avoid filtering out hidden channels from the channel list
|
||||
match: /(?<=queryChannels\(\i\){.+?isGuildChannelType\)\((\i)\.type\))(?=&&!\i\.\i\.can\()/,
|
||||
match: /(?<=queryChannels\(\i\){.+?\)\((\i)\.type\))(?=&&!\i\.\i\.can\()/,
|
||||
replace: "&&!$self.isHiddenChannel($1)"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -64,18 +64,18 @@ export default definePlugin({
|
|||
},
|
||||
},
|
||||
{
|
||||
find: "useShouldShowInvitesDisabledNotif:",
|
||||
find: "2022-07_invites_disabled",
|
||||
predicate: () => settings.store.showInvitesPaused,
|
||||
replacement: {
|
||||
match: /\i\.\i\.can\(\i\.Permissions.MANAGE_GUILD,\i\)/,
|
||||
match: /\i\.\i\.can\(\i\.\i.MANAGE_GUILD,\i\)/,
|
||||
replace: "true",
|
||||
},
|
||||
},
|
||||
{
|
||||
find: "canAccessGuildMemberModViewWithExperiment:",
|
||||
find: /context:\i,checkElevated:!1\}\),\i\.\i.{0,200}autoTrackExposure/,
|
||||
predicate: () => settings.store.showModView,
|
||||
replacement: {
|
||||
match: /return \i\.hasAny\(\i\.computePermissions\(\{user:\i,context:\i,checkElevated:!1\}\),\i\.MemberSafetyPagePermissions\)/,
|
||||
match: /return \i\.\i\(\i\.\i\(\{user:\i,context:\i,checkElevated:!1\}\),\i\.\i\)/,
|
||||
replace: "return true",
|
||||
}
|
||||
},
|
||||
|
@ -87,28 +87,31 @@ export default definePlugin({
|
|||
replace: "{}"
|
||||
}
|
||||
},
|
||||
// remove the 200 server minimum
|
||||
{
|
||||
find: "MINIMUM_MEMBER_COUNT:",
|
||||
find: '">200"',
|
||||
predicate: () => settings.store.disableDiscoveryFilters,
|
||||
replacement: {
|
||||
match: /MINIMUM_MEMBER_COUNT:function\(\)\{return \i}/,
|
||||
replace: "MINIMUM_MEMBER_COUNT:() => \">0\""
|
||||
match: '">200"',
|
||||
replace: '">0"'
|
||||
}
|
||||
},
|
||||
// empty word filter (why would anyone search "horny" in fucking server discovery... please... why are we patching this again??)
|
||||
{
|
||||
find: "DiscoveryBannedSearchWords.includes",
|
||||
find: '"horny","fart"',
|
||||
predicate: () => settings.store.disableDisallowedDiscoveryFilters,
|
||||
replacement: {
|
||||
match: /(?<=function\(\){)(?=.{0,130}DiscoveryBannedSearchWords\.includes)/,
|
||||
replace: "return false;"
|
||||
match: /=\["egirl",.+?\]/,
|
||||
replace: "=[]"
|
||||
}
|
||||
},
|
||||
// patch request that queries if term is allowed
|
||||
{
|
||||
find: "Endpoints.GUILD_DISCOVERY_VALID_TERM",
|
||||
find: ".GUILD_DISCOVERY_VALID_TERM",
|
||||
predicate: () => settings.store.disableDisallowedDiscoveryFilters,
|
||||
all: true,
|
||||
replacement: {
|
||||
match: /\i\.HTTP\.get\(\{url:\i\.Endpoints\.GUILD_DISCOVERY_VALID_TERM,query:\{term:\i\},oldFormErrors:!0\}\);/g,
|
||||
match: /\i\.\i\.get\(\{url:\i\.\i\.GUILD_DISCOVERY_VALID_TERM,query:\{term:\i\},oldFormErrors:!0\}\);/g,
|
||||
replace: "Promise.resolve({ body: { valid: true } });"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ export default definePlugin({
|
|||
}
|
||||
},
|
||||
{
|
||||
find: ".trackEmojiSearchEmpty,200",
|
||||
find: ".EMOJI_PICKER_CONSTANTS_EMOJI_CONTAINER_PADDING_HORIZONTAL)",
|
||||
replacement: {
|
||||
match: /(\.trackEmojiSearchEmpty,200(?=.+?isBurstReaction:(\i).+?(\i===\i\.EmojiIntention.REACTION)).+?\[\2,\i\]=\i\.useState\().+?\)/,
|
||||
match: /(openPopoutType:void 0(?=.+?isBurstReaction:(\i).+?(\i===\i\.\i.REACTION)).+?\[\2,\i\]=\i\.useState\().+?\)/,
|
||||
replace: (_, rest, isBurstReactionVariable, isReactionIntention) => `${rest}$self.shouldSuperReactByDefault&&${isReactionIntention})`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { FluxDispatcher, RestAPI } from "@webpack/common";
|
||||
import { Message, User } from "discord-types/general";
|
||||
import { Channel } from "discord-types/general/index.js";
|
||||
|
@ -29,7 +29,7 @@ interface Reply {
|
|||
const fetching = new Map<string, string>();
|
||||
let ReplyStore: any;
|
||||
|
||||
const { createMessageRecord } = findByPropsLazy("createMessageRecord");
|
||||
const createMessageRecord = findByCodeLazy(".createFromServer(", ".isBlockedForMessage", "messageReference:");
|
||||
|
||||
export default definePlugin({
|
||||
name: "ValidReply",
|
||||
|
|
|
@ -27,7 +27,7 @@ import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModa
|
|||
import { useAwaiter } from "@utils/react";
|
||||
import definePlugin from "@utils/types";
|
||||
import { chooseFile } from "@utils/web";
|
||||
import { findByPropsLazy, findStoreLazy } from "@webpack";
|
||||
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
|
||||
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";
|
||||
|
||||
|
@ -37,7 +37,7 @@ import { cl } from "./utils";
|
|||
import { VoicePreview } from "./VoicePreview";
|
||||
import { VoiceRecorderWeb } from "./WebRecorder";
|
||||
|
||||
const CloudUtils = findByPropsLazy("CloudUpload");
|
||||
const CloudUpload = findLazy(m => m.prototype?.trackUploadFinished);
|
||||
const PendingReplyStore = findStoreLazy("PendingReplyStore");
|
||||
const OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel");
|
||||
|
||||
|
@ -89,9 +89,8 @@ function sendAudio(blob: Blob, meta: AudioMetadata) {
|
|||
const reply = PendingReplyStore.getPendingReply(channelId);
|
||||
if (reply) FluxDispatcher.dispatch({ type: "DELETE_PENDING_REPLY", channelId });
|
||||
|
||||
const upload = new CloudUtils.CloudUpload({
|
||||
const upload = new CloudUpload({
|
||||
file: new File([blob], "voice-message.ogg", { type: "audio/ogg; codecs=opus" }),
|
||||
isClip: false,
|
||||
isThumbnail: false,
|
||||
platform: 1,
|
||||
}, channelId, false, 0);
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
import { findLazy } from "@webpack";
|
||||
|
||||
export const UserSettingsActionCreators = {
|
||||
FrecencyUserSettingsActionCreators: findLazy(m => m.typeName?.endsWith(".FrecencyUserSettings")),
|
||||
PreloadedUserSettingsActionCreators: findLazy(m => m.typeName?.endsWith(".PreloadedUserSettings")),
|
||||
FrecencyUserSettingsActionCreators: findLazy(m => m.ProtoClass?.typeName?.endsWith(".FrecencyUserSettings")),
|
||||
PreloadedUserSettingsActionCreators: findLazy(m => m.ProtoClass?.typeName?.endsWith(".PreloadedUserSettings")),
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { canonicalizeMatch } from "@utils/patches";
|
||||
import type { Channel } from "discord-types/general";
|
||||
|
||||
import { _resolveReady, filters, findByCodeLazy, findByPropsLazy, findLazy, mapMangledModuleLazy, waitFor } from "../webpack";
|
||||
|
@ -156,3 +157,10 @@ export const UserProfileActions = findByPropsLazy("openUserProfileModal", "close
|
|||
export const InviteActions = findByPropsLazy("resolveInvite");
|
||||
|
||||
export const IconUtils: t.IconUtils = findByPropsLazy("getGuildBannerURL", "getUserAvatarURL");
|
||||
|
||||
const openExpressionPickerMatcher = canonicalizeMatch(/setState\({activeView:\i/);
|
||||
// TODO: type
|
||||
export const ExpressionPickerStore = mapMangledModuleLazy("expression-picker-last-active-view", {
|
||||
closeExpressionPicker: filters.byCode("setState({activeView:null"),
|
||||
openExpressionPicker: m => typeof m === "function" && openExpressionPickerMatcher.test(m.toString()),
|
||||
});
|
||||
|
|
|
@ -106,7 +106,7 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
|
|||
|
||||
for (const key in cache) {
|
||||
const mod = cache[key];
|
||||
if (!mod?.exports) continue;
|
||||
if (!mod.loaded || !mod?.exports) continue;
|
||||
|
||||
if (filter(mod.exports)) {
|
||||
return isWaitFor ? [mod.exports, key] : mod.exports;
|
||||
|
@ -142,7 +142,7 @@ export function findAll(filter: FilterFn) {
|
|||
const ret = [] as any[];
|
||||
for (const key in cache) {
|
||||
const mod = cache[key];
|
||||
if (!mod?.exports) continue;
|
||||
if (!mod.loaded || !mod?.exports) continue;
|
||||
|
||||
if (filter(mod.exports))
|
||||
ret.push(mod.exports);
|
||||
|
@ -190,7 +190,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
|
|||
outer:
|
||||
for (const key in cache) {
|
||||
const mod = cache[key];
|
||||
if (!mod?.exports) continue;
|
||||
if (!mod.loaded || !mod?.exports) continue;
|
||||
|
||||
for (let j = 0; j < length; j++) {
|
||||
const filter = filters[j];
|
||||
|
@ -486,7 +486,7 @@ export function mapMangledModuleLazy<S extends string>(code: string, mappers: Re
|
|||
return proxyLazy(() => mapMangledModule(code, mappers));
|
||||
}
|
||||
|
||||
export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("[^)]+?"\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/;
|
||||
export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/;
|
||||
export const ChunkIdsRegex = /\("([^"]+?)"\)/g;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue