mirror of
https://github.com/Vendicated/Vencord.git
synced 2025-01-10 18:06:22 +00:00
Merge branch 'main' of https://github.com/Vendicated/Vencord into Vendicated-main
This commit is contained in:
commit
64402bb5b0
17 changed files with 251 additions and 105 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.10.6",
|
"version": "1.10.7",
|
||||||
"description": "The cutest Discord client mod",
|
"description": "The cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -27,7 +27,12 @@ export async function loadLazyChunks() {
|
||||||
|
|
||||||
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
|
const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
|
||||||
|
|
||||||
|
let foundCssDebuggingLoad = false;
|
||||||
|
|
||||||
async function searchAndLoadLazyChunks(factoryCode: string) {
|
async function searchAndLoadLazyChunks(factoryCode: string) {
|
||||||
|
// Workaround to avoid loading the CSS debugging chunk which turns the app pink
|
||||||
|
const hasCssDebuggingLoad = foundCssDebuggingLoad ? false : (foundCssDebuggingLoad = factoryCode.includes(".cssDebuggingEnabled&&"));
|
||||||
|
|
||||||
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
|
||||||
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
|
const validChunkGroups = new Set<[chunkIds: number[], entryPoint: number]>();
|
||||||
|
|
||||||
|
@ -43,6 +48,16 @@ export async function loadLazyChunks() {
|
||||||
let invalidChunkGroup = false;
|
let invalidChunkGroup = false;
|
||||||
|
|
||||||
for (const id of chunkIds) {
|
for (const id of chunkIds) {
|
||||||
|
if (hasCssDebuggingLoad) {
|
||||||
|
if (chunkIds.length > 1) {
|
||||||
|
throw new Error("Found multiple chunks in factory that loads the CSS debugging chunk");
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidChunks.add(id);
|
||||||
|
invalidChunkGroup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (wreq.u(id) == null || wreq.u(id) === "undefined.js") continue;
|
if (wreq.u(id) == null || wreq.u(id) === "undefined.js") continue;
|
||||||
|
|
||||||
const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
|
const isWorkerAsset = await fetch(wreq.p + wreq.u(id))
|
||||||
|
|
|
@ -28,10 +28,18 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: 'action:"EXPAND_ROLES"',
|
find: 'action:"EXPAND_ROLES"',
|
||||||
replacement: {
|
replacement: [
|
||||||
match: /(roles:\i(?=.+?(\i)\(!0\)[,;]\i\({action:"EXPAND_ROLES"}\)).+?\[\i,\2\]=\i\.useState\()!1\)/,
|
{
|
||||||
replace: (_, rest, setExpandedRoles) => `${rest}!0)`
|
match: /(roles:\i(?=.+?(\i)\(!0\)[,;]\i\({action:"EXPAND_ROLES"}\)).+?\[\i,\2\]=\i\.useState\()!1\)/,
|
||||||
}
|
replace: (_, rest, setExpandedRoles) => `${rest}!0)`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Fix not calculating non-expanded roles because the above patch makes the default "expanded",
|
||||||
|
// which makes the collapse button never show up and calculation never occur
|
||||||
|
match: /(?<=useLayoutEffect\(\(\)=>{if\()\i/,
|
||||||
|
replace: isExpanded => "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -130,6 +130,27 @@ export default definePlugin({
|
||||||
replace: ""
|
replace: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Zustand section
|
||||||
|
{
|
||||||
|
find: "[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.",
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /&&console\.warn\("\[DEPRECATED\] Passing a vanilla store will be unsupported in a future version\. Instead use `import { useStore } from 'zustand'`\."\)/,
|
||||||
|
replace: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /console\.warn\("\[DEPRECATED\] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`\. They can be imported from 'zustand\/traditional'\. https:\/\/github\.com\/pmndrs\/zustand\/discussions\/1937"\),/,
|
||||||
|
replace: ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: "[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead.",
|
||||||
|
replacement: {
|
||||||
|
match: /console\.warn\("\[DEPRECATED\] `getStorage`, `serialize` and `deserialize` options are deprecated\. Use `storage` option instead\."\),/,
|
||||||
|
replace: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
// Patches discords generic logger function
|
// Patches discords generic logger function
|
||||||
{
|
{
|
||||||
find: "Σ:",
|
find: "Σ:",
|
||||||
|
|
|
@ -93,7 +93,7 @@ export const useAuthorizationStore = proxyLazy(() => zustandCreate(
|
||||||
} as AuthorizationState),
|
} as AuthorizationState),
|
||||||
{
|
{
|
||||||
name: "decor-auth",
|
name: "decor-auth",
|
||||||
getStorage: () => indexedDBStorage,
|
storage: indexedDBStorage,
|
||||||
partialize: state => ({ tokens: state.tokens }),
|
partialize: state => ({ tokens: state.tokens }),
|
||||||
onRehydrateStorage: () => state => state?.init()
|
onRehydrateStorage: () => state => state?.init()
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,24 +95,39 @@ export const useUsersDecorationsStore = proxyLazy(() => zustandCreate((set: any,
|
||||||
} as UsersDecorationsState)));
|
} as UsersDecorationsState)));
|
||||||
|
|
||||||
export function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | null | undefined {
|
export function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | null | undefined {
|
||||||
const [decorAvatarDecoration, setDecorAvatarDecoration] = useState<string | null>(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null);
|
try {
|
||||||
|
const [decorAvatarDecoration, setDecorAvatarDecoration] = useState<string | null>(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const destructor = useUsersDecorationsStore.subscribe(
|
const destructor = (() => {
|
||||||
state => {
|
try {
|
||||||
if (!user) return;
|
return useUsersDecorationsStore.subscribe(
|
||||||
const newDecorAvatarDecoration = state.getAsset(user.id);
|
state => {
|
||||||
if (!newDecorAvatarDecoration) return;
|
if (!user) return;
|
||||||
if (decorAvatarDecoration !== newDecorAvatarDecoration) setDecorAvatarDecoration(newDecorAvatarDecoration);
|
const newDecorAvatarDecoration = state.getAsset(user.id);
|
||||||
}
|
if (!newDecorAvatarDecoration) return;
|
||||||
);
|
if (decorAvatarDecoration !== newDecorAvatarDecoration) setDecorAvatarDecoration(newDecorAvatarDecoration);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
return () => { };
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
if (user) {
|
try {
|
||||||
const { fetch: fetchUserDecorAvatarDecoration } = useUsersDecorationsStore.getState();
|
if (user) {
|
||||||
fetchUserDecorAvatarDecoration(user.id);
|
const { fetch: fetchUserDecorAvatarDecoration } = useUsersDecorationsStore.getState();
|
||||||
}
|
fetchUserDecorAvatarDecoration(user.id);
|
||||||
return destructor;
|
}
|
||||||
}, []);
|
} catch { }
|
||||||
|
|
||||||
return decorAvatarDecoration ? { asset: decorAvatarDecoration, skuId: SKU_ID } : null;
|
return destructor;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return decorAvatarDecoration ? { asset: decorAvatarDecoration, skuId: SKU_ID } : null;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { AvatarDecorationModalPreview } from "../components";
|
||||||
const FileUpload = findComponentByCodeLazy("fileUploadInput,");
|
const FileUpload = findComponentByCodeLazy("fileUploadInput,");
|
||||||
|
|
||||||
const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE=3]="POSITIVE', {
|
const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE=3]="POSITIVE', {
|
||||||
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"),
|
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING", "INFO"),
|
||||||
HelpMessage: filters.byCode(".iconDiv")
|
HelpMessage: filters.byCode(".iconDiv")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -119,8 +119,8 @@ function CreateDecorationModal(props: ModalProps) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Forms.FormText type="description" className={Margins.bottom16}>
|
<HelpMessage messageType={HelpMessageTypes.INFO}>
|
||||||
<br />You can receive updates on your decoration's review by joining <Link
|
To receive updates on your decoration's review, join <Link
|
||||||
href={`https://discord.gg/${INVITE_KEY}`}
|
href={`https://discord.gg/${INVITE_KEY}`}
|
||||||
onClick={async e => {
|
onClick={async e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -138,8 +138,8 @@ function CreateDecorationModal(props: ModalProps) {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Decor's Discord server
|
Decor's Discord server
|
||||||
</Link>.
|
</Link> and allow direct messages.
|
||||||
</Forms.FormText>
|
</HelpMessage>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
<ModalFooter className={cl("modal-footer")}>
|
<ModalFooter className={cl("modal-footer")}>
|
||||||
|
|
|
@ -20,11 +20,11 @@ import { addPreEditListener, addPreSendListener, removePreEditListener, removePr
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies";
|
import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies";
|
||||||
import { getCurrentGuild } from "@utils/discord";
|
import { getCurrentGuild, getEmojiURL } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType, Patch } from "@utils/types";
|
import definePlugin, { OptionType, Patch } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
||||||
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, IconUtils, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
||||||
import type { Emoji } from "@webpack/types";
|
import type { Emoji } from "@webpack/types";
|
||||||
import type { Message } from "discord-types/general";
|
import type { Message } from "discord-types/general";
|
||||||
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
||||||
|
@ -920,7 +920,7 @@ export default definePlugin({
|
||||||
|
|
||||||
const emojiString = `<${emoji.animated ? "a" : ""}:${emoji.originalName || emoji.name}:${emoji.id}>`;
|
const emojiString = `<${emoji.animated ? "a" : ""}:${emoji.originalName || emoji.name}:${emoji.id}>`;
|
||||||
|
|
||||||
const url = new URL(IconUtils.getEmojiURL({ id: emoji.id, animated: emoji.animated, size: s.emojiSize }));
|
const url = new URL(getEmojiURL(emoji.id, emoji.animated, s.emojiSize));
|
||||||
url.searchParams.set("size", s.emojiSize.toString());
|
url.searchParams.set("size", s.emojiSize.toString());
|
||||||
url.searchParams.set("name", emoji.name);
|
url.searchParams.set("name", emoji.name);
|
||||||
|
|
||||||
|
@ -953,7 +953,7 @@ export default definePlugin({
|
||||||
|
|
||||||
hasBypass = true;
|
hasBypass = true;
|
||||||
|
|
||||||
const url = new URL(IconUtils.getEmojiURL({ id: emoji.id, animated: emoji.animated, size: s.emojiSize }));
|
const url = new URL(getEmojiURL(emoji.id, emoji.animated, s.emojiSize));
|
||||||
url.searchParams.set("size", s.emojiSize.toString());
|
url.searchParams.set("size", s.emojiSize.toString());
|
||||||
url.searchParams.set("name", emoji.name);
|
url.searchParams.set("name", emoji.name);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ const settings = definePluginSettings({
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "NoMosaic",
|
name: "NoMosaic",
|
||||||
authors: [Devs.AutumnVN],
|
authors: [Devs.AutumnVN],
|
||||||
description: "Removes Discord new image mosaic",
|
description: "Removes Discord image mosaic",
|
||||||
tags: ["image", "mosaic", "media"],
|
tags: ["image", "mosaic", "media"],
|
||||||
|
|
||||||
settings,
|
settings,
|
||||||
|
@ -29,8 +29,8 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: '=>"IMAGE"===',
|
find: '=>"IMAGE"===',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /=>"IMAGE"===\i\|\|"VIDEO"===\i;/,
|
match: /=>"IMAGE"===\i\|\|"VIDEO"===\i(?:\|\|("VISUAL_PLACEHOLDER"===\i))?;/,
|
||||||
replace: "=>false;"
|
replace: (_, visualPlaceholderPred) => visualPlaceholderPred != null ? `=>${visualPlaceholderPred};` : "=>false;"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,10 +30,10 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".removeMosaicItemHoverButton),",
|
find: ".removeMosaicItemHoverButton),",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.nonMediaMosaicItem\]:!(\i).{0,50}?children:\[\S,(\S)/,
|
match: /\.nonMediaMosaicItem\]:.{0,40}children:\[(?<=showDownload:(\i).+?isVisualMediaType:(\i).+?)/,
|
||||||
replace: "$&,$1&&$2&&$self.renderPiPButton(),"
|
replace: "$&$1&&$2&&$self.renderPiPButton(),"
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
renderPiPButton: ErrorBoundary.wrap(() => {
|
renderPiPButton: ErrorBoundary.wrap(() => {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { makeRange } from "@components/PluginSettings/components";
|
import { makeRange } from "@components/PluginSettings/components";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { ChannelStore, GuildMemberStore, GuildStore } from "@webpack/common";
|
import { ChannelStore, GuildMemberStore, GuildStore } from "@webpack/common";
|
||||||
|
@ -51,6 +52,12 @@ const settings = definePluginSettings({
|
||||||
description: "Show role colors in the reactors list",
|
description: "Show role colors in the reactors list",
|
||||||
restartNeeded: true
|
restartNeeded: true
|
||||||
},
|
},
|
||||||
|
pollResults: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
default: true,
|
||||||
|
description: "Show role colors in the poll results",
|
||||||
|
restartNeeded: true
|
||||||
|
},
|
||||||
colorChatMessages: {
|
colorChatMessages: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -62,14 +69,15 @@ const settings = definePluginSettings({
|
||||||
description: "Intensity of message coloring.",
|
description: "Intensity of message coloring.",
|
||||||
markers: makeRange(0, 100, 10),
|
markers: makeRange(0, 100, 10),
|
||||||
default: 30
|
default: 30
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "RoleColorEverywhere",
|
name: "RoleColorEverywhere",
|
||||||
authors: [Devs.KingFish, Devs.lewisakura, Devs.AutumnVN, Devs.Kyuuhachi],
|
authors: [Devs.KingFish, Devs.lewisakura, Devs.AutumnVN, Devs.Kyuuhachi, Devs.jamesbt365],
|
||||||
description: "Adds the top role color anywhere possible",
|
description: "Adds the top role color anywhere possible",
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
// Chat Mentions
|
// Chat Mentions
|
||||||
{
|
{
|
||||||
|
@ -77,82 +85,133 @@ export default definePlugin({
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /onContextMenu:\i,color:\i,\.\.\.\i(?=,children:)(?<=user:(\i),channel:(\i).{0,500}?)/,
|
match: /onContextMenu:\i,color:\i,\.\.\.\i(?=,children:)(?<=user:(\i),channel:(\i).{0,500}?)/,
|
||||||
replace: "$&,color:$self.getUserColor($1?.id,{channelId:$2?.id})"
|
replace: "$&,color:$self.getColorInt($1?.id,$2?.id)"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
predicate: () => settings.store.chatMentions,
|
predicate: () => settings.store.chatMentions
|
||||||
},
|
},
|
||||||
// Slate
|
// Slate
|
||||||
{
|
{
|
||||||
find: ".userTooltip,children",
|
find: ".userTooltip,children",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /let\{id:(\i),guildId:(\i)[^}]*\}.*?\.\i,{(?=children)/,
|
match: /let\{id:(\i),guildId:\i,channelId:(\i)[^}]*\}.*?\.\i,{(?=children)/,
|
||||||
replace: "$&color:$self.getUserColor($1,{guildId:$2}),"
|
replace: "$&color:$self.getColorInt($1,$2),"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
predicate: () => settings.store.chatMentions,
|
predicate: () => settings.store.chatMentions
|
||||||
},
|
},
|
||||||
|
// Member List Role Headers
|
||||||
{
|
{
|
||||||
find: 'tutorialId:"whos-online',
|
find: 'tutorialId:"whos-online',
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /null,\i," — ",\i\]/,
|
match: /null,\i," — ",\i\]/,
|
||||||
replace: "null,$self.roleGroupColor(arguments[0])]"
|
replace: "null,$self.RoleGroupColor(arguments[0])]"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
predicate: () => settings.store.memberList,
|
predicate: () => settings.store.memberList
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "#{intl::THREAD_BROWSER_PRIVATE}",
|
find: "#{intl::THREAD_BROWSER_PRIVATE}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /children:\[\i," — ",\i\]/,
|
match: /children:\[\i," — ",\i\]/,
|
||||||
replace: "children:[$self.roleGroupColor(arguments[0])]"
|
replace: "children:[$self.RoleGroupColor(arguments[0])]"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
predicate: () => settings.store.memberList,
|
predicate: () => settings.store.memberList
|
||||||
},
|
},
|
||||||
|
// Voice Users
|
||||||
{
|
{
|
||||||
find: "renderPrioritySpeaker",
|
find: "renderPrioritySpeaker(){",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /renderName\(\){.+?usernameSpeaking\]:.+?(?=children)/,
|
match: /renderName\(\){.+?usernameSpeaking\]:.+?(?=children)/,
|
||||||
replace: "$&...$self.getVoiceProps(this.props),"
|
replace: "$&style:$self.getColorStyle(this?.props?.user?.id,this?.props?.guildId),"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
predicate: () => settings.store.voiceUsers,
|
predicate: () => settings.store.voiceUsers
|
||||||
},
|
},
|
||||||
|
// Reaction List
|
||||||
{
|
{
|
||||||
find: ".reactorDefault",
|
find: ".reactorDefault",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /,onContextMenu:e=>.{0,15}\((\i),(\i),(\i)\).{0,250}tag:"strong"/,
|
match: /,onContextMenu:\i=>.{0,15}\((\i),(\i),(\i)\).{0,250}tag:"strong"/,
|
||||||
replace: "$&,style:{color:$self.getColor($2?.id,$1)}"
|
replace: "$&,style:$self.getColorStyle($2?.id,$1?.channel?.id)"
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.reactorsList,
|
predicate: () => settings.store.reactorsList,
|
||||||
},
|
},
|
||||||
|
// Poll Results
|
||||||
|
{
|
||||||
|
find: ",reactionVoteCounts",
|
||||||
|
replacement: {
|
||||||
|
match: /\.nickname,(?=children:)/,
|
||||||
|
replace: "$&style:$self.getColorStyle(arguments[0]?.user?.id,arguments[0]?.channel?.id),"
|
||||||
|
},
|
||||||
|
predicate: () => settings.store.pollResults
|
||||||
|
},
|
||||||
|
// Messages
|
||||||
{
|
{
|
||||||
find: "#{intl::MESSAGE_EDITED}",
|
find: "#{intl::MESSAGE_EDITED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=isUnsupported\]:(\i)\.isUnsupported\}\),)(?=children:\[)/,
|
match: /(?<=isUnsupported\]:(\i)\.isUnsupported\}\),)(?=children:\[)/,
|
||||||
replace: "style:{color:$self.useMessageColor($1)},"
|
replace: "style:$self.useMessageColorStyle($1),"
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.colorChatMessages,
|
predicate: () => settings.store.colorChatMessages
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
settings,
|
|
||||||
|
|
||||||
getColor(userId: string, { channelId, guildId }: { channelId?: string; guildId?: string; }) {
|
getColorString(userId: string, channelOrGuildId: string) {
|
||||||
if (!(guildId ??= ChannelStore.getChannel(channelId!)?.guild_id)) return null;
|
try {
|
||||||
return GuildMemberStore.getMember(guildId, userId)?.colorString ?? null;
|
const guildId = ChannelStore.getChannel(channelOrGuildId)?.guild_id ?? GuildStore.getGuild(channelOrGuildId)?.id;
|
||||||
|
if (guildId == null) return null;
|
||||||
|
|
||||||
|
return GuildMemberStore.getMember(guildId, userId)?.colorString ?? null;
|
||||||
|
} catch (e) {
|
||||||
|
new Logger("RoleColorEverywhere").error("Failed to get color string", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
getUserColor(userId: string, ids: { channelId?: string; guildId?: string; }) {
|
getColorInt(userId: string, channelOrGuildId: string) {
|
||||||
const colorString = this.getColor(userId, ids);
|
const colorString = this.getColorString(userId, channelOrGuildId);
|
||||||
return colorString && parseInt(colorString.slice(1), 16);
|
return colorString && parseInt(colorString.slice(1), 16);
|
||||||
},
|
},
|
||||||
|
|
||||||
roleGroupColor: ErrorBoundary.wrap(({ id, count, title, guildId, label }: { id: string; count: number; title: string; guildId: string; label: string; }) => {
|
getColorStyle(userId: string, channelOrGuildId: string) {
|
||||||
|
const colorString = this.getColorString(userId, channelOrGuildId);
|
||||||
|
|
||||||
|
return colorString && {
|
||||||
|
color: colorString
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
useMessageColor(message: any) {
|
||||||
|
try {
|
||||||
|
const { messageSaturation } = settings.use(["messageSaturation"]);
|
||||||
|
const author = useMessageAuthor(message);
|
||||||
|
|
||||||
|
if (author.colorString != null && messageSaturation !== 0) {
|
||||||
|
return `color-mix(in oklab, ${author.colorString} ${messageSaturation}%, var(--text-normal))`;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
new Logger("RoleColorEverywhere").error("Failed to get message color", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
useMessageColorStyle(message: any) {
|
||||||
|
const color = this.useMessageColor(message);
|
||||||
|
|
||||||
|
return color && {
|
||||||
|
color
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
RoleGroupColor: ErrorBoundary.wrap(({ id, count, title, guildId, label }: { id: string; count: number; title: string; guildId: string; label: string; }) => {
|
||||||
const role = GuildStore.getRole(guildId, id);
|
const role = GuildStore.getRole(guildId, id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -164,25 +223,5 @@ export default definePlugin({
|
||||||
{title ?? label} — {count}
|
{title ?? label} — {count}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}, { noop: true }),
|
}, { noop: true })
|
||||||
|
|
||||||
getVoiceProps({ user: { id: userId }, guildId }: { user: { id: string; }; guildId: string; }) {
|
|
||||||
return {
|
|
||||||
style: {
|
|
||||||
color: this.getColor(userId, { guildId })
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
useMessageColor(message: any) {
|
|
||||||
try {
|
|
||||||
const { messageSaturation } = settings.use(["messageSaturation"]);
|
|
||||||
const author = useMessageAuthor(message);
|
|
||||||
if (author.colorString !== undefined && messageSaturation !== 0)
|
|
||||||
return `color-mix(in oklab, ${author.colorString} ${messageSaturation}%, var(--text-normal))`;
|
|
||||||
} catch (e) {
|
|
||||||
console.error("[RCE] failed to get message color", e);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Vencord, a modification for Discord's desktop app
|
* Vencord, a modification for Discord's desktop app
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
import { IShikiTheme } from "@vap/shiki";
|
import { IShikiTheme } from "@vap/shiki";
|
||||||
|
|
||||||
export const SHIKI_REPO = "shikijs/shiki";
|
export const SHIKI_REPO = "shikijs/textmate-grammars-themes";
|
||||||
export const SHIKI_REPO_COMMIT = "0b28ad8ccfbf2615f2d9d38ea8255416b8ac3043";
|
export const SHIKI_REPO_COMMIT = "2d87559c7601a928b9f7e0f0dda243d2fb6d4499";
|
||||||
export const shikiRepoTheme = (name: string) => `https://raw.githubusercontent.com/${SHIKI_REPO}/${SHIKI_REPO_COMMIT}/packages/shiki/themes/${name}.json`;
|
export const shikiRepoTheme = (name: string) => `https://raw.githubusercontent.com/${SHIKI_REPO}/${SHIKI_REPO_COMMIT}/packages/tm-themes/themes/${name}.json`;
|
||||||
|
|
||||||
export const themes = {
|
export const themes = {
|
||||||
// Default
|
// Default
|
||||||
|
@ -30,33 +30,59 @@ export const themes = {
|
||||||
MaterialCandy: "https://raw.githubusercontent.com/millsp/material-candy/master/material-candy.json",
|
MaterialCandy: "https://raw.githubusercontent.com/millsp/material-candy/master/material-candy.json",
|
||||||
|
|
||||||
// More from Shiki repo
|
// More from Shiki repo
|
||||||
|
Andromeeda: shikiRepoTheme("andromeeda"),
|
||||||
|
AuroraX: shikiRepoTheme("aurora-x"),
|
||||||
|
AyuDark: shikiRepoTheme("ayu-dark"),
|
||||||
|
CatppuccinLatte: shikiRepoTheme("catppuccin-latte"),
|
||||||
|
CatppuccinFrappe: shikiRepoTheme("catppuccin-frappe"),
|
||||||
|
CatppuccinMacchiato: shikiRepoTheme("catppuccin-macchiato"),
|
||||||
|
CatppuccinMocha: shikiRepoTheme("catppuccin-mocha"),
|
||||||
DraculaSoft: shikiRepoTheme("dracula-soft"),
|
DraculaSoft: shikiRepoTheme("dracula-soft"),
|
||||||
Dracula: shikiRepoTheme("dracula"),
|
Dracula: shikiRepoTheme("dracula"),
|
||||||
|
EverforestDark: shikiRepoTheme("everforest-dark"),
|
||||||
|
EverforestLight: shikiRepoTheme("everforest-light"),
|
||||||
|
GithubDarkDefault: shikiRepoTheme("github-dark-default"),
|
||||||
GithubDarkDimmed: shikiRepoTheme("github-dark-dimmed"),
|
GithubDarkDimmed: shikiRepoTheme("github-dark-dimmed"),
|
||||||
|
GithubDarkHighContrast: shikiRepoTheme("github-dark-high-contrast"),
|
||||||
GithubDark: shikiRepoTheme("github-dark"),
|
GithubDark: shikiRepoTheme("github-dark"),
|
||||||
|
GithubLightDefault: shikiRepoTheme("github-light-default"),
|
||||||
|
GithubLightHighContrast: shikiRepoTheme("github-light-high-contrast"),
|
||||||
GithubLight: shikiRepoTheme("github-light"),
|
GithubLight: shikiRepoTheme("github-light"),
|
||||||
|
Houston: shikiRepoTheme("houston"),
|
||||||
|
KanagawaDragon: shikiRepoTheme("kanagawa-dragon"),
|
||||||
|
KanagawaLotus: shikiRepoTheme("kanagawa-lotus"),
|
||||||
|
KanagawaWave: shikiRepoTheme("kanagawa-wave"),
|
||||||
|
LaserWave: shikiRepoTheme("laserwave"),
|
||||||
LightPlus: shikiRepoTheme("light-plus"),
|
LightPlus: shikiRepoTheme("light-plus"),
|
||||||
MaterialDarker: shikiRepoTheme("material-darker"),
|
MaterialDarker: shikiRepoTheme("material-theme-darker"),
|
||||||
MaterialDefault: shikiRepoTheme("material-default"),
|
MaterialDefault: shikiRepoTheme("material-theme"),
|
||||||
MaterialLighter: shikiRepoTheme("material-lighter"),
|
MaterialLighter: shikiRepoTheme("material-theme-lighter"),
|
||||||
MaterialOcean: shikiRepoTheme("material-ocean"),
|
MaterialOcean: shikiRepoTheme("material-theme-ocean"),
|
||||||
MaterialPalenight: shikiRepoTheme("material-palenight"),
|
MaterialPalenight: shikiRepoTheme("material-theme-palenight"),
|
||||||
MinDark: shikiRepoTheme("min-dark"),
|
MinDark: shikiRepoTheme("min-dark"),
|
||||||
MinLight: shikiRepoTheme("min-light"),
|
MinLight: shikiRepoTheme("min-light"),
|
||||||
Monokai: shikiRepoTheme("monokai"),
|
Monokai: shikiRepoTheme("monokai"),
|
||||||
|
NightOwl: shikiRepoTheme("night-owl"),
|
||||||
Nord: shikiRepoTheme("nord"),
|
Nord: shikiRepoTheme("nord"),
|
||||||
OneDarkPro: shikiRepoTheme("one-dark-pro"),
|
OneDarkPro: shikiRepoTheme("one-dark-pro"),
|
||||||
|
OneLight: shikiRepoTheme("one-light"),
|
||||||
|
Plastic: shikiRepoTheme("plastic"),
|
||||||
Poimandres: shikiRepoTheme("poimandres"),
|
Poimandres: shikiRepoTheme("poimandres"),
|
||||||
|
Red: shikiRepoTheme("red"),
|
||||||
RosePineDawn: shikiRepoTheme("rose-pine-dawn"),
|
RosePineDawn: shikiRepoTheme("rose-pine-dawn"),
|
||||||
RosePineMoon: shikiRepoTheme("rose-pine-moon"),
|
RosePineMoon: shikiRepoTheme("rose-pine-moon"),
|
||||||
RosePine: shikiRepoTheme("rose-pine"),
|
RosePine: shikiRepoTheme("rose-pine"),
|
||||||
SlackDark: shikiRepoTheme("slack-dark"),
|
SlackDark: shikiRepoTheme("slack-dark"),
|
||||||
SlackOchin: shikiRepoTheme("slack-ochin"),
|
SlackOchin: shikiRepoTheme("slack-ochin"),
|
||||||
|
SnazzyLight: shikiRepoTheme("snazzy-light"),
|
||||||
SolarizedDark: shikiRepoTheme("solarized-dark"),
|
SolarizedDark: shikiRepoTheme("solarized-dark"),
|
||||||
SolarizedLight: shikiRepoTheme("solarized-light"),
|
SolarizedLight: shikiRepoTheme("solarized-light"),
|
||||||
|
Synthwave84: shikiRepoTheme("synthwave-84"),
|
||||||
|
TokyoNight: shikiRepoTheme("tokyo-night"),
|
||||||
|
Vesper: shikiRepoTheme("vesper"),
|
||||||
|
VitesseBlack: shikiRepoTheme("vitesse-black"),
|
||||||
VitesseDark: shikiRepoTheme("vitesse-dark"),
|
VitesseDark: shikiRepoTheme("vitesse-dark"),
|
||||||
VitesseLight: shikiRepoTheme("vitesse-light"),
|
VitesseLight: shikiRepoTheme("vitesse-light"),
|
||||||
CssVariables: shikiRepoTheme("css-variables"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const themeCache = new Map<string, IShikiTheme>();
|
export const themeCache = new Map<string, IShikiTheme>();
|
||||||
|
|
|
@ -209,10 +209,11 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// Group DMs top small & large icon
|
// Group DMs top small & large icon
|
||||||
{
|
{
|
||||||
find: /\.recipients\.length>=2(?!<isMultiUserDM.{0,50})/,
|
find: '["aria-hidden"],"aria-label":',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /null==\i\.icon\?.+?src:(\(0,\i\.\i\).+?\))(?=[,}])/,
|
match: /null==\i\.icon\?.+?src:(\(0,\i\.\i\).+?\))(?=[,}])/,
|
||||||
replace: (m, iconUrl) => `${m},onClick:()=>$self.openAvatar(${iconUrl})`
|
// We have to check that icon is not an unread GDM in the server bar
|
||||||
|
replace: (m, iconUrl) => `${m},onClick:()=>arguments[0]?.size!=="SIZE_48"&&$self.openAvatar(${iconUrl})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// User DMs top small icon
|
// User DMs top small icon
|
||||||
|
|
|
@ -155,6 +155,7 @@ export default definePlugin({
|
||||||
"guild-context": MakeContextCallback("Guild"),
|
"guild-context": MakeContextCallback("Guild"),
|
||||||
"channel-context": MakeContextCallback("Channel"),
|
"channel-context": MakeContextCallback("Channel"),
|
||||||
"thread-context": MakeContextCallback("Channel"),
|
"thread-context": MakeContextCallback("Channel"),
|
||||||
|
"gdm-context": MakeContextCallback("Channel"),
|
||||||
"user-context": MakeContextCallback("User")
|
"user-context": MakeContextCallback("User")
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -520,8 +520,8 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
id: 721717126523781240n,
|
id: 721717126523781240n,
|
||||||
},
|
},
|
||||||
nyx: {
|
nyx: {
|
||||||
name: "verticalsync",
|
name: "verticalsync.",
|
||||||
id: 328165170536775680n
|
id: 1207087393929171095n
|
||||||
},
|
},
|
||||||
nekohaxx: {
|
nekohaxx: {
|
||||||
name: "nekohaxx",
|
name: "nekohaxx",
|
||||||
|
@ -575,6 +575,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
name: "RamziAH",
|
name: "RamziAH",
|
||||||
id: 1279957227612147747n,
|
id: 1279957227612147747n,
|
||||||
},
|
},
|
||||||
|
SomeAspy: {
|
||||||
SomeAspy: {
|
SomeAspy: {
|
||||||
name: "SomeAspy",
|
name: "SomeAspy",
|
||||||
id: 516750892372852754n,
|
id: 516750892372852754n,
|
||||||
|
@ -583,6 +584,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
name: "lethalfluff",
|
name: "lethalfluff",
|
||||||
id: 337568120028004362n
|
id: 337568120028004362n
|
||||||
}
|
}
|
||||||
|
jamesbt365: {
|
||||||
|
name: "jamesbt365",
|
||||||
|
id: 158567567487795200n,
|
||||||
|
},
|
||||||
} satisfies Record<string, Dev>);
|
} satisfies Record<string, Dev>);
|
||||||
|
|
||||||
// iife so #__PURE__ works correctly
|
// iife so #__PURE__ works correctly
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import "./discord.css";
|
import "./discord.css";
|
||||||
|
|
||||||
import { MessageObject } from "@api/MessageEvents";
|
import { MessageObject } from "@api/MessageEvents";
|
||||||
import { ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, i18n, InviteActions, MessageActions, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
|
import { ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, i18n, IconUtils, InviteActions, MessageActions, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
|
||||||
import { Channel, Guild, Message, User } from "discord-types/general";
|
import { Channel, Guild, Message, User } from "discord-types/general";
|
||||||
import { Except } from "type-fest";
|
import { Except } from "type-fest";
|
||||||
|
|
||||||
|
@ -212,3 +212,14 @@ export async function fetchUserProfile(id: string, options?: FetchUserProfileOpt
|
||||||
export function getUniqueUsername(user: User) {
|
export function getUniqueUsername(user: User) {
|
||||||
return user.discriminator === "0" ? user.username : user.tag;
|
return user.discriminator === "0" ? user.username : user.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URL for an emoji. This function always returns a gif URL for animated emojis, instead of webp
|
||||||
|
* @param id The emoji id
|
||||||
|
* @param animated Whether the emoji is animated
|
||||||
|
* @param size The size for the emoji
|
||||||
|
*/
|
||||||
|
export function getEmojiURL(id: string, animated: boolean, size: number) {
|
||||||
|
const url = IconUtils.getEmojiURL({ id, animated, size });
|
||||||
|
return animated ? url.replace(".webp", ".gif") : url;
|
||||||
|
}
|
||||||
|
|
|
@ -163,9 +163,13 @@ waitFor(["open", "saveAccountChanges"], m => SettingsRouter = m);
|
||||||
|
|
||||||
export const PermissionsBits: t.PermissionsBits = findLazy(m => typeof m.ADMINISTRATOR === "bigint");
|
export const PermissionsBits: t.PermissionsBits = findLazy(m => typeof m.ADMINISTRATOR === "bigint");
|
||||||
|
|
||||||
export const zustandCreate = findByCodeLazy("will be removed in v4");
|
export const { zustandCreate } = mapMangledModuleLazy(["useSyncExternalStoreWithSelector:", "Object.assign", /(\i)\?(\i)\(\1\):\2/], {
|
||||||
|
zustandCreate: filters.byCode(/(\i)\?(\i)\(\1\):\2/)
|
||||||
|
});
|
||||||
|
|
||||||
export const zustandPersist = findByCodeLazy("[zustand persist middleware]");
|
export const { zustandPersist } = mapMangledModuleLazy(".onRehydrateStorage)?", {
|
||||||
|
zustandPersist: filters.byCode(/(\(\i,\i\))=>.+?\i\1/)
|
||||||
|
});
|
||||||
|
|
||||||
export const MessageActions = findByPropsLazy("editMessage", "sendMessage");
|
export const MessageActions = findByPropsLazy("editMessage", "sendMessage");
|
||||||
export const MessageCache = findByPropsLazy("clearCache", "_channelMessages");
|
export const MessageCache = findByPropsLazy("clearCache", "_channelMessages");
|
||||||
|
@ -181,7 +185,7 @@ export const ExpressionPickerStore: t.ExpressionPickerStore = mapMangledModuleLa
|
||||||
toggleExpressionPicker: filters.byCode(/getState\(\)\.activeView===\i\?\i\(\):\i\(/),
|
toggleExpressionPicker: filters.byCode(/getState\(\)\.activeView===\i\?\i\(\):\i\(/),
|
||||||
setExpressionPickerView: filters.byCode(/setState\({activeView:\i,lastActiveView:/),
|
setExpressionPickerView: filters.byCode(/setState\({activeView:\i,lastActiveView:/),
|
||||||
setSearchQuery: filters.byCode("searchQuery:"),
|
setSearchQuery: filters.byCode("searchQuery:"),
|
||||||
useExpressionPickerStore: filters.byCode("Object.is")
|
useExpressionPickerStore: filters.byCode(/\(\i,\i=\i\)=>/)
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PopoutActions: t.PopoutActions = mapMangledModuleLazy('type:"POPOUT_WINDOW_OPEN"', {
|
export const PopoutActions: t.PopoutActions = mapMangledModuleLazy('type:"POPOUT_WINDOW_OPEN"', {
|
||||||
|
|
Loading…
Reference in a new issue