Merge branch 'main' of https://www.coastalcommits.com/CoastalCommitsArchival/github.com-Vendicated-Vencord
This commit is contained in:
commit
35a15effc8
24 changed files with 211 additions and 56 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "vencord",
|
||||
"private": "true",
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.5",
|
||||
"description": "The cutest Discord client mod",
|
||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||
"bugs": {
|
||||
|
|
|
@ -315,7 +315,6 @@ export default function PluginSettings() {
|
|||
<TextInput autoFocus value={searchValue.value} placeholder="Search for a plugin..." onChange={onSearch} className={Margins.bottom20} />
|
||||
<div className={InputStyles.inputWrapper}>
|
||||
<Select
|
||||
className={InputStyles.inputDefault}
|
||||
options={[
|
||||
{ label: "Show All", value: SearchStatus.ALL, default: true },
|
||||
{ label: "Show Enabled", value: SearchStatus.ENABLED },
|
||||
|
|
|
@ -28,7 +28,7 @@ const VENCORD_SRC_DIR = join(__dirname, "..");
|
|||
|
||||
const execFile = promisify(cpExecFile);
|
||||
|
||||
const isFlatpak = process.platform === "linux" && Boolean(process.env.FLATPAK_ID?.includes("discordapp") || process.env.FLATPAK_ID?.includes("Discord"));
|
||||
const isFlatpak = process.platform === "linux" && !!process.env.FLATPAK_ID;
|
||||
|
||||
if (process.platform === "darwin") process.env.PATH = `/usr/local/bin:${process.env.PATH}`;
|
||||
|
||||
|
@ -60,7 +60,8 @@ async function calculateGitChanges() {
|
|||
return commits ? commits.split("\n").map(line => {
|
||||
const [author, hash, ...rest] = line.split("/");
|
||||
return {
|
||||
hash, author, message: rest.join("/")
|
||||
hash, author,
|
||||
message: rest.join("/").split("\n")[0]
|
||||
};
|
||||
}) : [];
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ async function calculateGitChanges() {
|
|||
// github api only sends the long sha
|
||||
hash: c.sha.slice(0, 7),
|
||||
author: c.author.login,
|
||||
message: c.commit.message.substring(c.commit.message.indexOf("\n") + 1)
|
||||
message: c.commit.message.split("\n")[0]
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ const StickerExt = [, "png", "png", "json", "gif"] as const;
|
|||
|
||||
function getUrl(data: Data) {
|
||||
if (data.t === "Emoji")
|
||||
return `${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/emojis/${data.id}.${data.isAnimated ? "gif" : "png"}`;
|
||||
return `${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/emojis/${data.id}.${data.isAnimated ? "gif" : "png"}?size=4096&lossless=true`;
|
||||
|
||||
return `${window.GLOBAL_ENV.MEDIA_PROXY_ENDPOINT}/stickers/${data.id}.${StickerExt[data.format_type]}`;
|
||||
return `${window.GLOBAL_ENV.MEDIA_PROXY_ENDPOINT}/stickers/${data.id}.${StickerExt[data.format_type]}?size=4096&lossless=true`;
|
||||
}
|
||||
|
||||
async function fetchSticker(id: string) {
|
||||
|
@ -130,7 +130,8 @@ function getGuildCandidates(data: Data) {
|
|||
|
||||
let count = 0;
|
||||
for (const emoji of emojis)
|
||||
if (emoji.animated === isAnimated) count++;
|
||||
if (emoji.animated === isAnimated && !emoji.managed)
|
||||
count++;
|
||||
return count < emojiSlots;
|
||||
}).sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import { Logger } from "@utils/Logger";
|
|||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
||||
import { Alerts, ChannelStore, EmojiStore, FluxDispatcher, Forms, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
||||
import type { CustomEmoji } from "@webpack/types";
|
||||
import type { Message } from "discord-types/general";
|
||||
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
||||
import type { ReactElement, ReactNode } from "react";
|
||||
|
@ -784,6 +785,16 @@ export default definePlugin({
|
|||
UploadHandler.promptToUpload([file], ChannelStore.getChannel(channelId), DRAFT_TYPE);
|
||||
},
|
||||
|
||||
canUseEmote(e: CustomEmoji, channelId: string) {
|
||||
if (e.require_colons === false) return true;
|
||||
if (e.available === false) return false;
|
||||
|
||||
if (this.canUseEmotes)
|
||||
return e.guildId === this.guildId || hasExternalEmojiPerms(channelId);
|
||||
else
|
||||
return !e.animated && e.guildId === this.guildId;
|
||||
},
|
||||
|
||||
start() {
|
||||
const s = settings.store;
|
||||
|
||||
|
@ -882,12 +893,8 @@ export default definePlugin({
|
|||
}
|
||||
|
||||
if (s.enableEmojiBypass) {
|
||||
const canUseEmotes = this.canUseEmotes && hasExternalEmojiPerms(channelId);
|
||||
|
||||
for (const emoji of messageObj.validNonShortcutEmojis) {
|
||||
if (!emoji.require_colons) continue;
|
||||
if (emoji.available !== false && canUseEmotes) continue;
|
||||
if (emoji.guildId === guildId && !emoji.animated) continue;
|
||||
if (this.canUseEmote(emoji, channelId)) continue;
|
||||
|
||||
hasBypass = true;
|
||||
|
||||
|
@ -917,18 +924,12 @@ export default definePlugin({
|
|||
this.preEdit = addPreEditListener(async (channelId, __, messageObj) => {
|
||||
if (!s.enableEmojiBypass) return;
|
||||
|
||||
const { guildId } = this;
|
||||
|
||||
let hasBypass = false;
|
||||
|
||||
const canUseEmotes = this.canUseEmotes && hasExternalEmojiPerms(channelId);
|
||||
|
||||
messageObj.content = messageObj.content.replace(/(?<!\\)<a?:(?:\w+):(\d+)>/ig, (emojiStr, emojiId, offset, origStr) => {
|
||||
const emoji = EmojiStore.getCustomEmojiById(emojiId);
|
||||
if (emoji == null) return emojiStr;
|
||||
if (!emoji.require_colons) return emojiStr;
|
||||
if (emoji.available !== false && canUseEmotes) return emojiStr;
|
||||
if (emoji.guildId === guildId && !emoji.animated) return emojiStr;
|
||||
if (this.canUseEmote(emoji, channelId)) return emojiStr;
|
||||
|
||||
hasBypass = true;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { getCurrentChannel } from "@utils/discord";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { React, RelationshipStore } from "@webpack/common";
|
||||
|
@ -49,6 +50,18 @@ export default definePlugin({
|
|||
</Heading>
|
||||
|
||||
<div className={container.memberSinceContainer}>
|
||||
{!!getCurrentChannel()?.guild_id && (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="var(--interactive-normal)"
|
||||
>
|
||||
<path d="M13 10a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z" />
|
||||
<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={clydeMoreInfo.body}>
|
||||
{getCreatedAtDate(friendsSince, locale.getLocale())}
|
||||
</Text>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { addAccessory } from "@api/MessageAccessories";
|
||||
import { addAccessory, removeAccessory } from "@api/MessageAccessories";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants.js";
|
||||
|
@ -389,4 +389,8 @@ export default definePlugin({
|
|||
);
|
||||
}, 4 /* just above rich embeds */);
|
||||
},
|
||||
|
||||
stop() {
|
||||
removeAccessory("messageLinkEmbed");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -45,7 +45,7 @@ export default definePlugin({
|
|||
|
||||
patches: [
|
||||
{
|
||||
find: ".Messages.USER_PROFILE_MODAL", // Note: the module is lazy-loaded
|
||||
find: ".Messages.MUTUAL_GUILDS_WITH_END_COUNT", // Note: the module is lazy-loaded
|
||||
replacement: {
|
||||
match: /(?<=\.tabBarItem.{0,50}MUTUAL_GUILDS.+?}\),)(?=.+?(\(0,\i\.jsxs?\)\(.{0,100}id:))/,
|
||||
replace: '(arguments[0].user.bot||arguments[0].isCurrentUser)?null:$1"MUTUAL_GDMS",children:"Mutual Groups"}),'
|
||||
|
|
|
@ -11,21 +11,15 @@ import definePlugin, { OptionType } from "@utils/types";
|
|||
|
||||
import style from "./styles.css?managed";
|
||||
|
||||
const MAX_WIDTH = 550;
|
||||
const MAX_HEIGHT = 350;
|
||||
|
||||
const settings = definePluginSettings({
|
||||
inlineVideo: {
|
||||
description: "Play videos without carousel modal",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
restartNeeded: true
|
||||
},
|
||||
mediaLayoutType: {
|
||||
description: "Choose media layout type",
|
||||
type: OptionType.SELECT,
|
||||
restartNeeded: true,
|
||||
options: [
|
||||
{ label: "STATIC, render loading image but image isn't resposive, no problem unless discord window width is too small", value: "STATIC", default: true },
|
||||
{ label: "RESPONSIVE, image is responsive but not render loading image, cause messages shift when loaded", value: "RESPONSIVE" },
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -42,7 +36,7 @@ export default definePlugin({
|
|||
find: ".oneByTwoLayoutThreeGrid",
|
||||
replacement: [{
|
||||
match: /mediaLayoutType:\i\.\i\.MOSAIC/,
|
||||
replace: "mediaLayoutType:$self.mediaLayoutType()",
|
||||
replace: "mediaLayoutType:'RESPONSIVE'",
|
||||
},
|
||||
{
|
||||
match: /null!==\(\i=\i\.get\(\i\)\)&&void 0!==\i\?\i:"INVALID"/,
|
||||
|
@ -59,15 +53,43 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
find: "Messages.REMOVE_ATTACHMENT_TOOLTIP_TEXT",
|
||||
replacement: {
|
||||
replacement: [{
|
||||
match: /\i===\i\.\i\.MOSAIC/,
|
||||
replace: "true"
|
||||
},
|
||||
{
|
||||
match: /\i!==\i\.\i\.MOSAIC/,
|
||||
replace: "false"
|
||||
}]
|
||||
},
|
||||
{
|
||||
find: ".messageAttachment,",
|
||||
replacement: {
|
||||
match: /\{width:\i,height:\i\}=(\i).*?(?=className:\i\(\)\(\i\.messageAttachment,)/,
|
||||
replace: "$&style:$self.style($1),"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
mediaLayoutType() {
|
||||
return settings.store.mediaLayoutType;
|
||||
style({ width, height }) {
|
||||
if (!width || !height) return {};
|
||||
|
||||
if (width > MAX_WIDTH || height > MAX_HEIGHT) {
|
||||
if (width / height > MAX_WIDTH / MAX_HEIGHT) {
|
||||
height = Math.ceil(MAX_WIDTH / (width / height));
|
||||
width = MAX_WIDTH;
|
||||
} else {
|
||||
width = Math.ceil(MAX_HEIGHT * (width / height));
|
||||
height = MAX_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
maxWidth: width,
|
||||
width: "100%",
|
||||
aspectRatio: `${width} / ${height}`
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
start() {
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
[class^="nonMediaAttachmentsContainer_"] [class*="messageAttachment_"] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[class^="nonMediaAttachmentsContainer_"],
|
||||
[class^="nonMediaAttachmentItem_"]:has([class^="messageAttachment_"][style^="max-width"]) {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Settings } from "@api/Settings";
|
|||
import { UserStore } from "@webpack/common";
|
||||
|
||||
import { DEFAULT_COLOR } from "./constants";
|
||||
import { forceUpdate } from "./index";
|
||||
import { forceUpdate, PinOrder, PrivateChannelSortStore, settings } from "./index";
|
||||
|
||||
export interface Category {
|
||||
id: string;
|
||||
|
@ -106,7 +106,12 @@ export function categoryLen() {
|
|||
}
|
||||
|
||||
export function getAllUncollapsedChannels() {
|
||||
return categories.filter(c => !c.collapsed).map(c => c.channels).flat();
|
||||
if (settings.store.pinOrder === PinOrder.LastMessage) {
|
||||
const sortedChannels = PrivateChannelSortStore.getPrivateChannelIds();
|
||||
return categories.filter(c => !c.collapsed).flatMap(c => sortedChannels.filter(channel => c.channels.includes(channel)));
|
||||
}
|
||||
|
||||
return categories.filter(c => !c.collapsed).flatMap(c => c.channels);
|
||||
}
|
||||
|
||||
export function getSections() {
|
||||
|
|
|
@ -29,7 +29,7 @@ interface ChannelComponentProps {
|
|||
|
||||
const headerClasses = findByPropsLazy("privateChannelsHeaderContainer");
|
||||
|
||||
const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
|
||||
export const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
|
||||
|
||||
export let instance: any;
|
||||
export const forceUpdate = () => instance?.props?._forceUpdate?.();
|
||||
|
@ -236,7 +236,7 @@ export default definePlugin({
|
|||
const category = categories[categoryIndex - 1];
|
||||
if (!category) return false;
|
||||
|
||||
return category.collapsed && this.instance.props.selectedChannelId !== category.channels[channelIndex];
|
||||
return category.collapsed && this.instance.props.selectedChannelId !== this.getCategoryChannels(category)[channelIndex];
|
||||
},
|
||||
|
||||
getScrollOffset(channelId: string, rowHeight: number, padding: number, preRenderedChildren: number, originalOffset: number) {
|
||||
|
|
|
@ -89,8 +89,8 @@ export default definePlugin({
|
|||
{
|
||||
find: "61eef9_2",
|
||||
replacement: {
|
||||
match: /(?<=getMutableGuildChannelsForGuild\(\i\)\);)(?=if\(null==\i\|\|)/,
|
||||
replace: "if($self.useForceServerHome())return false;"
|
||||
match: /getMutableGuildChannelsForGuild\(\i\);return\(0,\i\.useStateFromStores\).+?\]\)(?=}function)/,
|
||||
replace: m => `${m}&&!$self.useForceServerHome()`
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -71,7 +71,7 @@ export const settings = definePluginSettings({
|
|||
</Button>
|
||||
|
||||
<Button onClick={async () => {
|
||||
let url = "https://reviewdb.mantikafasi.dev/";
|
||||
let url = "https://reviewdb.mantikafasi.dev";
|
||||
const token = await getToken();
|
||||
if (token)
|
||||
url += "/api/redirect?token=" + encodeURIComponent(token);
|
||||
|
|
|
@ -452,7 +452,7 @@ export default definePlugin({
|
|||
{
|
||||
// Filter hidden channels from GuildChannelStore.getChannels unless told otherwise
|
||||
match: /(?<=getChannels\(\i)(\){.+?)return (.+?)}/,
|
||||
replace: (_, rest, channels) => `,shouldIncludeHidden${rest}return $self.resolveGuildChannels(${channels},shouldIncludeHidden??false);}`
|
||||
replace: (_, rest, channels) => `,shouldIncludeHidden${rest}return $self.resolveGuildChannels(${channels},shouldIncludeHidden??arguments[0]==="@favorites");}`
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
*/
|
||||
|
||||
import { Devs } from "@utils/constants";
|
||||
import { LazyComponent } from "@utils/react";
|
||||
import definePlugin from "@utils/types";
|
||||
|
||||
import StartupTimingPage from "./StartupTimingPage";
|
||||
|
||||
export default definePlugin({
|
||||
name: "StartupTimings",
|
||||
description: "Adds Startup Timings to the Settings menu",
|
||||
|
@ -31,5 +32,5 @@ export default definePlugin({
|
|||
replace: '{section:"StartupTimings",label:"Startup Timings",element:$self.StartupTimingPage},$&'
|
||||
}
|
||||
}],
|
||||
StartupTimingPage: LazyComponent(() => require("./StartupTimingPage").default)
|
||||
StartupTimingPage
|
||||
});
|
||||
|
|
|
@ -16,20 +16,28 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import "./style.css";
|
||||
|
||||
import { definePluginSettings, Settings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findExportedComponentLazy, findStoreLazy } from "@webpack";
|
||||
import { findComponentByCodeLazy, findExportedComponentLazy, findStoreLazy } from "@webpack";
|
||||
import { ChannelStore, GuildMemberStore, i18n, RelationshipStore, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
|
||||
|
||||
import { buildSeveralUsers } from "../typingTweaks";
|
||||
|
||||
const ThreeDots = findExportedComponentLazy("Dots", "AnimatedDots");
|
||||
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
|
||||
|
||||
const TypingStore = findStoreLazy("TypingStore");
|
||||
const UserGuildSettingsStore = findStoreLazy("UserGuildSettingsStore");
|
||||
|
||||
const enum IndicatorMode {
|
||||
Dots = 1 << 0,
|
||||
Avatars = 1 << 1
|
||||
}
|
||||
|
||||
function getDisplayName(guildId: string, userId: string) {
|
||||
const user = UserStore.getUser(userId);
|
||||
return GuildMemberStore.getNick(guildId, userId) ?? (user as any).globalName ?? user.username;
|
||||
|
@ -90,11 +98,24 @@ function TypingIndicator({ channelId }: { channelId: string; }) {
|
|||
return (
|
||||
<Tooltip text={tooltipText!}>
|
||||
{props => (
|
||||
<div
|
||||
{...props}
|
||||
style={{ marginLeft: 6, height: 16, display: "flex", alignItems: "center", zIndex: 0, cursor: "pointer" }}
|
||||
>
|
||||
<ThreeDots dotRadius={3} themed={true} />
|
||||
<div className="vc-typing-indicator" {...props}>
|
||||
{((settings.store.indicatorMode & IndicatorMode.Avatars) === IndicatorMode.Avatars) && (
|
||||
<UserSummaryItem
|
||||
users={typingUsersArray.map(id => UserStore.getUser(id))}
|
||||
guildId={guildId}
|
||||
renderIcon={false}
|
||||
max={3}
|
||||
showDefaultAvatarsForNullUsers
|
||||
showUserPopout
|
||||
size={16}
|
||||
className="vc-typing-indicator-avatars"
|
||||
/>
|
||||
)}
|
||||
{((settings.store.indicatorMode & IndicatorMode.Dots) === IndicatorMode.Dots) && (
|
||||
<div className="vc-typing-indicator-dots">
|
||||
<ThreeDots dotRadius={3} themed={true} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Tooltip>
|
||||
|
@ -119,13 +140,22 @@ const settings = definePluginSettings({
|
|||
type: OptionType.BOOLEAN,
|
||||
description: "Whether to show the typing indicator for blocked users.",
|
||||
default: false
|
||||
},
|
||||
indicatorMode: {
|
||||
type: OptionType.SELECT,
|
||||
description: "How should the indicator be displayed?",
|
||||
options: [
|
||||
{ label: "Avatars and animated dots", value: IndicatorMode.Dots | IndicatorMode.Avatars, default: true },
|
||||
{ label: "Animated dots", value: IndicatorMode.Dots },
|
||||
{ label: "Avatars", value: IndicatorMode.Avatars },
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "TypingIndicator",
|
||||
description: "Adds an indicator if someone is typing on a channel.",
|
||||
authors: [Devs.Nuckyz, Devs.fawn],
|
||||
authors: [Devs.Nuckyz, Devs.fawn, Devs.Sqaaakoi],
|
||||
settings,
|
||||
|
||||
patches: [
|
||||
|
|
18
src/plugins/typingIndicator/style.css
Normal file
18
src/plugins/typingIndicator/style.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
.vc-typing-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.vc-typing-indicator-avatars {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.vc-typing-indicator-dots {
|
||||
margin-left: 6px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 0;
|
||||
cursor: pointer;
|
||||
}
|
5
src/plugins/unlockedAvatarZoom/README.md
Normal file
5
src/plugins/unlockedAvatarZoom/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# UnlockedAvatarZoom
|
||||
|
||||
Allows you to zoom in further in the image crop tool when changing your avatar
|
||||
|
||||
![](https://raw.githubusercontent.com/Vencord/plugin-assets/main/UnlockedAvatarZoom/demo.avif)
|
35
src/plugins/unlockedAvatarZoom/index.ts
Normal file
35
src/plugins/unlockedAvatarZoom/index.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { makeRange } from "@components/PluginSettings/components";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
||||
const settings = definePluginSettings({
|
||||
zoomMultiplier: {
|
||||
type: OptionType.SLIDER,
|
||||
description: "Zoom multiplier",
|
||||
markers: makeRange(2, 16),
|
||||
default: 4,
|
||||
},
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "UnlockedAvatarZoom",
|
||||
description: "Allows you to zoom in further in the image crop tool when changing your avatar",
|
||||
authors: [Devs.nakoyasha],
|
||||
settings,
|
||||
patches: [
|
||||
{
|
||||
find: ".Messages.AVATAR_UPLOAD_EDIT_MEDIA",
|
||||
replacement: {
|
||||
match: /maxValue:\d/,
|
||||
replace: "maxValue:$self.settings.store.zoomMultiplier",
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
|
@ -104,7 +104,7 @@ export default definePlugin({
|
|||
},
|
||||
// below username
|
||||
{
|
||||
find: ".USER_PROFILE_MODAL",
|
||||
find: ".Messages.MUTUAL_GUILDS_WITH_END_COUNT", // Lazy-loaded
|
||||
replacement: {
|
||||
match: /\.body.+?displayProfile:\i}\),/,
|
||||
replace: "$&$self.patchModal(arguments[0]),",
|
||||
|
|
|
@ -155,7 +155,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
|||
},
|
||||
kemo: {
|
||||
name: "kemo",
|
||||
id: 299693897859465228n
|
||||
id: 715746190813298788n
|
||||
},
|
||||
dzshn: {
|
||||
name: "dzshn",
|
||||
|
@ -425,6 +425,18 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
|||
newwares: {
|
||||
name: "newwares",
|
||||
id: 421405303951851520n
|
||||
},
|
||||
nakoyasha: {
|
||||
name: "nakoyasha",
|
||||
id: 222069018507345921n
|
||||
},
|
||||
Sqaaakoi: {
|
||||
name: "Sqaaakoi",
|
||||
id: 259558259491340288n
|
||||
},
|
||||
Byron: {
|
||||
name: "byeoon",
|
||||
id: 1167275288036655133n
|
||||
}
|
||||
} satisfies Record<string, Dev>);
|
||||
|
||||
|
|
|
@ -116,8 +116,11 @@ export function proxyLazy<T>(factory: () => T, attempts = 5, isChild = false): T
|
|||
attempts,
|
||||
true
|
||||
);
|
||||
|
||||
return Reflect.get(target[kGET](), p, receiver);
|
||||
const lazyTarget = target[kGET]();
|
||||
if (typeof lazyTarget === "object" || typeof lazyTarget === "function") {
|
||||
return Reflect.get(lazyTarget, p, receiver);
|
||||
}
|
||||
throw new Error("proxyLazy called on a primitive value");
|
||||
}
|
||||
}) as any;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue