Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
thororen1234 2026-01-28 18:35:13 -05:00
commit 9fc100fa9b
No known key found for this signature in database
29 changed files with 206 additions and 69 deletions

View file

@ -5,7 +5,7 @@ export class AuthenticationStore extends FluxStore {
* Gets the id of the current user * Gets the id of the current user
*/ */
getId(): string; getId(): string;
getSessionId(): string;
// This Store has a lot more methods related to everything Auth, but they really should // This Store has a lot more methods related to everything Auth, but they really should
// not be needed, so they are not typed // not be needed, so they are not typed
} }

View file

@ -136,6 +136,6 @@
} }
.vc-notification-log-danger-btn { .vc-notification-log-danger-btn {
color: var(--white-500); color: var(--control-critical-primary-text-default);
background-color: var(--status-danger); background-color: var(--control-critical-primary-background-default);
} }

View file

@ -144,11 +144,11 @@
} }
.vc-btn-positive { .vc-btn-positive {
background-color: var(--status-positive-background); background-color: var(--control-connected-background-default, var(--green-430));
color: var(--white); color: var(--white);
&:hover { &:hover {
background-color: var(--redesign-button-positive-pressed-background, var(--green-460)); background-color: var(--control-connected-background-hover, var(--green-460));
} }
} }

View file

@ -14,8 +14,8 @@
.vc-settings-quickActions-pill { .vc-settings-quickActions-pill {
all: unset; all: unset;
background: var(--channeltextarea-background); background: var(--control-secondary-background-default);
color: var(--text-default); color: var(--control-secondary-text-default, var(--text-default));
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -29,7 +29,7 @@
} }
.vc-settings-quickActions-pill:hover { .vc-settings-quickActions-pill:hover {
background: var(--redesign-button-tertiary-pressed-background); background: var(--control-secondary-background-hover);
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: var(--elevation-high); box-shadow: var(--elevation-high);
} }

View file

@ -54,3 +54,11 @@
gap: 4px; gap: 4px;
color: var(--text-feedback-critical); color: var(--text-feedback-critical);
} }
.vc-settings-modal-content {
padding-bottom: 24px;
}
.vc-plugin-modal-info {
align-items: center;
}

View file

@ -78,7 +78,8 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
const pluginSettings = useSettings([`plugins.${plugin.name}.*`]).plugins[plugin.name]; const pluginSettings = useSettings([`plugins.${plugin.name}.*`]).plugins[plugin.name];
const hasSettings = Boolean(pluginSettings && plugin.options && !isObjectEmpty(plugin.options)); const hasSettings = Boolean(pluginSettings && plugin.options && !isObjectEmpty(plugin.options));
const [authors, setAuthors] = useState<Partial<User>[]>([]); // prefill dummy user to avoid layout shift
const [authors, setAuthors] = useState<Partial<User>[]>(() => [makeDummyUser({ username: "Loading...", id: "-1465912127305809920" })]);
useEffect(() => { useEffect(() => {
(async () => { (async () => {
@ -178,7 +179,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
</div> </div>
</ModalHeader> </ModalHeader>
<ModalContent className={Margins.bottom16}> <ModalContent className={"vc-settings-modal-content"}>
<section> <section>
<BaseText size="lg" weight="semibold" color="text-strong" className={Margins.bottom8}>Authors</BaseText> <BaseText size="lg" weight="semibold" color="text-strong" className={Margins.bottom8}>Authors</BaseText>
<div style={{ width: "fit-content" }}> <div style={{ width: "fit-content" }}>

View file

@ -55,13 +55,7 @@ function Section(props: {
}) { }) {
const { buttonMap, description, title, settings } = props; const { buttonMap, description, title, settings } = props;
return ( const switches = Array.from(buttonMap, ([name, { icon }]) => {
<section>
<BaseText tag="h3" size="xl" weight="bold">{title}</BaseText>
<Paragraph size="sm" className={classes(Margins.top8, Margins.bottom20)}>{description}</Paragraph>
<div className={cl("switches")}>
{Array.from(buttonMap, ([name, { icon }]) => {
const Icon = icon ?? PlaceholderIcon; const Icon = icon ?? PlaceholderIcon;
return ( return (
<Paragraph size="md" weight="semibold" key={name} className={cl("switches-row")}> <Paragraph size="md" weight="semibold" key={name} className={cl("switches-row")}>
@ -76,7 +70,20 @@ function Section(props: {
/> />
</Paragraph> </Paragraph>
); );
})} });
return (
<section>
<BaseText tag="h3" size="xl" weight="bold">{title}</BaseText>
<Paragraph size="sm" className={classes(Margins.top8, Margins.bottom20)}>{description}</Paragraph>
<div className={cl("switches")}>
{switches.length === 0 && (
<Paragraph weight="medium" className={cl("switches-row")} style={{ color: "var(--text-muted)" }}>
Buttons of enabled plugins will appear here.
</Paragraph>
)}
{switches}
</div> </div>
</section> </section>
); );

View file

@ -17,7 +17,7 @@
*/ */
import { PluginOptionString } from "@utils/types"; import { PluginOptionString } from "@utils/types";
import { React, TextInput, useState } from "@webpack/common"; import { React, TextArea, TextInput, useState } from "@webpack/common";
import { resolveError, SettingProps, SettingsSection } from "./Common"; import { resolveError, SettingProps, SettingsSection } from "./Common";
@ -38,7 +38,14 @@ export function TextSetting({ option, pluginSettings, definedSettings, id, onCha
return ( return (
<SettingsSection name={id} description={option.description} error={error}> <SettingsSection name={id} description={option.description} error={error}>
<TextInput {option.multiline
? <TextArea
placeholder={option.placeholder ?? "Enter a value"}
value={state}
onChange={handleChange}
disabled={option.disabled?.call(definedSettings) ?? false}
{...option.componentProps} />
: <TextInput
type="text" type="text"
placeholder={option.placeholder ?? "Enter a value"} placeholder={option.placeholder ?? "Enter a value"}
value={state} value={state}
@ -47,6 +54,7 @@ export function TextSetting({ option, pluginSettings, definedSettings, id, onCha
disabled={option.disabled?.call(definedSettings) ?? false} disabled={option.disabled?.call(definedSettings) ?? false}
{...option.componentProps} {...option.componentProps}
/> />
}
</SettingsSection> </SettingsSection>
); );
} }

View file

@ -76,8 +76,8 @@
} }
.vc-cloud-erase-data-danger-btn { .vc-cloud-erase-data-danger-btn {
color: var(--white-500); color: var(--control-critical-primary-text-default);
background-color: var(--status-danger); background-color: var(--control-critical-primary-background-default);
} }
.vc-cloud-icon-with-button { .vc-cloud-icon-with-button {

View file

@ -16,8 +16,8 @@ export default definePlugin({
{ {
find: '"sticker")', find: '"sticker")',
replacement: { replacement: {
match: /let (\i)=\(0,\i\.chain\).{0,150}?;(?=return 0===\1\.length)/, match: /0===(\i)\.length(?=.{0,25}?\(0,\i\.jsxs?\)\(.{0,75}?children:\1)/,
replace: "$&Vencord.Api.ChatButtons._injectButtons($1,arguments[0]);" replace: "(Vencord.Api.ChatButtons._injectButtons($1,arguments[0]),$&)"
} }
} }
] ]

View file

@ -83,8 +83,9 @@ const settings = definePluginSettings({
}, },
whitelistedLoggers: { whitelistedLoggers: {
type: OptionType.STRING, type: OptionType.STRING,
description: "Semi colon separated list of loggers to allow even if others are hidden", description: "Semicolon (;) separated list of loggers to allow even if others are hidden",
default: "GatewaySocket; Routing/Utils", default: "GatewaySocket; Routing/Utils",
multiline: true,
onChange(newVal: string) { onChange(newVal: string) {
logAllow.clear(); logAllow.clear();
newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow)); newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));

View file

@ -27,7 +27,7 @@ export default definePlugin({
{ {
find: "#{intl::PREVIEW_BYTES_LEFT}", find: "#{intl::PREVIEW_BYTES_LEFT}",
replacement: { replacement: {
match: /url:\i,fileName:\i,fileSize:\i}\),(?=.{0,25}setLanguage:)(?<=fileContents:(\i),bytesLeft:(\i).+?)/g, match: /fileName:\i,fileSize:\i}\),(?=.{0,75}?setLanguage:)(?<=fileContents:(\i),bytesLeft:(\i).+?)/g,
replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2})," replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2}),"
} }
} }

View file

@ -76,6 +76,13 @@ export default definePlugin({
], ],
handleCrash(_this: any, errorState: any) { handleCrash(_this: any, errorState: any) {
if (IS_DEV) {
try {
if (errorState?.info && "componentStack" in errorState.info) {
console.error("Component Stack:", errorState.info.componentStack);
}
} catch { }
}
_this.setState(errorState); _this.setState(errorState);
// Already recovering, prevent error which happens more than once too fast to trigger another recover // Already recovering, prevent error which happens more than once too fast to trigger another recover

View file

@ -1,6 +1,6 @@
.vc-decor-danger-btn { .vc-decor-danger-btn {
color: var(--white-500); color: var(--control-critical-primary-text-default);
background-color: var(--status-danger); background-color: var(--control-critical-primary-background-default);
} }
.vc-decor-change-decoration-modal-content { .vc-decor-change-decoration-modal-content {

View file

@ -13,7 +13,7 @@ import { Paragraph } from "@components/Paragraph";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { Button, RunningGameStore, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "@webpack/common"; import { Button, RunningGameStore, showToast, TextArea, Toasts, Tooltip, useEffect, useState } from "@webpack/common";
const enum ActivitiesTypes { const enum ActivitiesTypes {
Game, Game,
@ -133,7 +133,7 @@ function IdsListComponent(props: { setValue: (value: string) => void; }) {
<section> <section>
<HeadingSecondary>Filter List</HeadingSecondary> <HeadingSecondary>Filter List</HeadingSecondary>
<Paragraph className={Margins.bottom8}>Comma separated list of activity IDs to filter (Useful for filtering specific RPC activities and CustomRPC</Paragraph> <Paragraph className={Margins.bottom8}>Comma separated list of activity IDs to filter (Useful for filtering specific RPC activities and CustomRPC</Paragraph>
<TextInput <TextArea
type="text" type="text"
value={idsList} value={idsList}
onChange={handleChange} onChange={handleChange}

View file

@ -21,7 +21,7 @@ import { definePluginSettings } from "@api/Settings";
import { debounce } from "@shared/debounce"; import { debounce } from "@shared/debounce";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import definePlugin, { makeRange, OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { createRoot, Menu } from "@webpack/common"; import { createRoot, Menu } from "@webpack/common";
import { JSX } from "react"; import { JSX } from "react";
import type { Root } from "react-dom/client"; import type { Root } from "react-dom/client";
@ -58,14 +58,14 @@ export const settings = definePluginSettings({
zoom: { zoom: {
description: "Zoom of the lens", description: "Zoom of the lens",
type: OptionType.SLIDER, type: OptionType.SLIDER,
markers: makeRange(1, 50, 4), markers: [1, 5, 10, 20, 30, 40, 50],
default: 2, default: 2,
stickToMarkers: false, stickToMarkers: false,
}, },
size: { size: {
description: "Radius / Size of the lens", description: "Radius / Size of the lens",
type: OptionType.SLIDER, type: OptionType.SLIDER,
markers: makeRange(50, 1000, 50), markers: [50, 100, 250, 500, 750, 1000],
default: 100, default: 100,
stickToMarkers: false, stickToMarkers: false,
}, },
@ -73,7 +73,7 @@ export const settings = definePluginSettings({
zoomSpeed: { zoomSpeed: {
description: "How fast the zoom / lens size changes", description: "How fast the zoom / lens size changes",
type: OptionType.SLIDER, type: OptionType.SLIDER,
markers: makeRange(0.1, 5, 0.2), markers: [0.1, 0.5, 1, 2, 3, 4, 5],
default: 0.5, default: 0.5,
stickToMarkers: false, stickToMarkers: false,
}, },

View file

@ -45,6 +45,7 @@ const settings = definePluginSettings({
description: "Additional custom quotes to possibly appear, separated by the below delimiter", description: "Additional custom quotes to possibly appear, separated by the below delimiter",
type: OptionType.STRING, type: OptionType.STRING,
default: "", default: "",
multiline: true
}, },
additionalQuotesDelimiter: { additionalQuotesDelimiter: {
description: "Delimiter for additional quotes", description: "Delimiter for additional quotes",

View file

@ -115,7 +115,8 @@ const settings = definePluginSettings({
idList: { idList: {
description: "Guild/channel/user IDs to blacklist or whitelist (separate with comma)", description: "Guild/channel/user IDs to blacklist or whitelist (separate with comma)",
type: OptionType.STRING, type: OptionType.STRING,
default: "" default: "",
multiline: true,
}, },
clearMessageCache: { clearMessageCache: {
type: OptionType.COMPONENT, type: OptionType.COMPONENT,

View file

@ -367,16 +367,19 @@ const settings = definePluginSettings({
type: OptionType.STRING, type: OptionType.STRING,
description: "Comma-separated list of user IDs to ignore", description: "Comma-separated list of user IDs to ignore",
default: "", default: "",
multiline: true,
}, },
ignoreChannels: { ignoreChannels: {
type: OptionType.STRING, type: OptionType.STRING,
description: "Comma-separated list of channel IDs to ignore", description: "Comma-separated list of channel IDs to ignore",
default: "", default: "",
multiline: true,
}, },
ignoreGuilds: { ignoreGuilds: {
type: OptionType.STRING, type: OptionType.STRING,
description: "Comma-separated list of guild IDs to ignore", description: "Comma-separated list of guild IDs to ignore",
default: "", default: "",
multiline: true,
}, },
showEditDiffs: { showEditDiffs: {
type: OptionType.BOOLEAN, type: OptionType.BOOLEAN,

View file

@ -25,15 +25,17 @@ import { ChannelStore, GuildMemberStore } from "@webpack/common";
const settings = definePluginSettings({ const settings = definePluginSettings({
userList: { userList: {
description: description:
"List of users to allow or exempt pings for (separated by commas or spaces)", "List of user ids to allow or exempt pings for (separated by commas or spaces)",
type: OptionType.STRING, type: OptionType.STRING,
default: "1234567890123445,1234567890123445", default: "1234567890123445,1234567890123445",
multiline: true
}, },
roleList: { roleList: {
description: description:
"List of roles to allow or exempt pings for (separated by commas or spaces)", "List of role ids to allow or exempt pings for (separated by commas or spaces)",
type: OptionType.STRING, type: OptionType.STRING,
default: "1234567890123445,1234567890123445", default: "1234567890123445,1234567890123445",
multiline: true
}, },
shouldPingListed: { shouldPingListed: {
description: "Behaviour", description: "Behaviour",

View file

@ -17,8 +17,9 @@
*/ */
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Button } from "@components/Button";
import { openInviteModal } from "@utils/discord";
import { OptionType } from "@utils/types"; import { OptionType } from "@utils/types";
import { Button } from "@webpack/common";
import { authorize, getToken } from "./auth"; import { authorize, getToken } from "./auth";
import { openBlockModal } from "./components/BlockedUserModal"; import { openBlockModal } from "./components/BlockedUserModal";
@ -60,14 +61,15 @@ export const settings = definePluginSettings({
<Button onClick={openBlockModal}>Manage Blocked Users</Button> <Button onClick={openBlockModal}>Manage Blocked Users</Button>
<Button <Button
color={Button.Colors.GREEN} variant="positive"
onClick={() => { onClick={() => {
VencordNative.native.openExternal("https://github.com/sponsors/mantikafasi"); VencordNative.native.openExternal("https://github.com/sponsors/mantikafasi");
}} }}
> >
Support ReviewDB development Support ReviewDB development
</Button> </Button>
<Button onClick={async () => {
<Button variant="link" onClick={async () => {
let url = "https://reviewdb.mantikafasi.dev"; let url = "https://reviewdb.mantikafasi.dev";
const token = await getToken(); const token = await getToken();
if (token) if (token)
@ -78,9 +80,7 @@ export const settings = definePluginSettings({
ReviewDB website ReviewDB website
</Button> </Button>
<Button onClick={() => { <Button variant="link" onClick={() => openInviteModal("eWPBSbvznt")}>
VencordNative.native.openExternal("https://discord.gg/eWPBSbvznt");
}}>
ReviewDB Support Server ReviewDB Support Server
</Button> </Button>
</div > </div >

View file

@ -166,7 +166,7 @@ export default definePlugin({
patches: [ patches: [
{ {
find: "UserProfilePopoutBody", find: /\.POPOUT,onClose:\i}\),nicknameIcons:.+?\.isProvisional/,
replacement: { replacement: {
match: /userId:\i\.id,guild:\i\}\)(?=])/, match: /userId:\i\.id,guild:\i\}\)(?=])/,
replace: "$&,$self.profilePopoutComponent(arguments[0])" replace: "$&,$self.profilePopoutComponent(arguments[0])"

View file

@ -27,7 +27,7 @@ export default definePlugin({
authors: [Devs.Megu], authors: [Devs.Megu],
patches: [{ patches: [{
find: "#{intl::ACTIVITY_SETTINGS}", find: ".SEARCH_NO_RESULTS&&0===",
replacement: [ replacement: [
{ {
match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+\)\)\}\))(?=\)\})/, match: /(?<=}\)([,;])(\i\.settings)\.forEach.+?(\i)\.push.+\)\)\}\))(?=\)\})/,

View file

@ -173,39 +173,132 @@ export const GoogleLanguages = {
export const DeeplLanguages = { export const DeeplLanguages = {
"": "Detect language", "": "Detect language",
"ace": "Acehnese",
"af": "Afrikaans",
"sq": "Albanian",
"ar": "Arabic", "ar": "Arabic",
"an": "Aragonese",
"hy": "Armenian",
"as": "Assamese",
"ay": "Aymara",
"az": "Azerbaijani",
"ba": "Bashkir",
"eu": "Basque",
"be": "Belarusian",
"bn": "Bengali",
"bho": "Bhojpuri",
"bs": "Bosnian",
"br": "Breton",
"bg": "Bulgarian", "bg": "Bulgarian",
"my": "Burmese",
"yue": "Cantonese",
"ca": "Catalan",
"ceb": "Cebuano",
"zh-hans": "Chinese (Simplified)", "zh-hans": "Chinese (Simplified)",
"zh-hant": "Chinese (Traditional)", "zh-hant": "Chinese (Traditional)",
"hr": "Croatian",
"cs": "Czech", "cs": "Czech",
"da": "Danish", "da": "Danish",
"prs": "Dari",
"nl": "Dutch", "nl": "Dutch",
"en-us": "English (American)", "en-us": "English (American)",
"en-gb": "English (British)", "en-gb": "English (British)",
"eo": "Esperanto",
"et": "Estonian", "et": "Estonian",
"fi": "Finnish", "fi": "Finnish",
"fr": "French", "fr": "French",
"gl": "Galician",
"ka": "Georgian",
"de": "German", "de": "German",
"el": "Greek", "el": "Greek",
"gn": "Guarani",
"gu": "Gujarati",
"ht": "Haitian Creole",
"ha": "Hausa",
"he": "Hebrew",
"hi": "Hindi",
"hu": "Hungarian", "hu": "Hungarian",
"is": "Icelandic",
"ig": "Igbo",
"id": "Indonesian", "id": "Indonesian",
"ga": "Irish",
"it": "Italian", "it": "Italian",
"ja": "Japanese", "ja": "Japanese",
"ko": "Korean", "jv": "Javanese",
"pam": "Kapampangan",
"kk": "Kazakh",
"kmr": "Kurdish (Kurmanji)",
"ckb": "Kurdish (Sorani)",
"ky": "Kyrgyz",
"lo": "Lao",
"la": "Latin",
"lv": "Latvian", "lv": "Latvian",
"ln": "Lingala",
"lt": "Lithuanian", "lt": "Lithuanian",
"nb": "Norwegian", "lmo": "Lombard",
"lb": "Luxembourgish",
"mk": "Macedonian",
"mai": "Maithili",
"mg": "Malagasy",
"ms": "Malay",
"ml": "Malayalam",
"mt": "Maltese",
"mi": "Maori",
"mr": "Marathi",
"mn": "Mongolian",
"ne": "Nepali",
"nb": "Norwegian (Bokmål)",
"oc": "Occitan",
"om": "Oromo",
"pag": "Pangasinan",
"ps": "Pashto",
"fa": "Persian",
"pl": "Polish", "pl": "Polish",
"pt-br": "Portuguese (Brazilian)", "pt-br": "Portuguese (Brazilian)",
"pt-pt": "Portuguese (European)", "pt-pt": "Portuguese (European)",
"pa": "Punjabi",
"qu": "Quechua",
"ro": "Romanian", "ro": "Romanian",
"ru": "Russian", "ru": "Russian",
"sm": "Samoan",
"sa": "Sanskrit",
"gd": "Scottish Gaelic",
"sr": "Serbian",
"st": "Sesotho",
"sn": "Shona",
"scn": "Sicilian",
"sd": "Sindhi",
"si": "Sinhala",
"sk": "Slovak", "sk": "Slovak",
"sl": "Slovenian", "sl": "Slovenian",
"so": "Somali",
"es": "Spanish", "es": "Spanish",
"es-419": "Spanish (Latin American)",
"su": "Sundanese",
"sw": "Swahili",
"sv": "Swedish", "sv": "Swedish",
"tl": "Tagalog",
"tg": "Tajik",
"ta": "Tamil",
"tt": "Tatar",
"te": "Telugu",
"th": "Thai",
"ti": "Tigrinya",
"ts": "Tsonga",
"tn": "Tswana",
"tr": "Turkish", "tr": "Turkish",
"uk": "Ukrainian" "tk": "Turkmen",
"uk": "Ukrainian",
"ur": "Urdu",
"ug": "Uyghur",
"uz": "Uzbek",
"vi": "Vietnamese",
"cy": "Welsh",
"wo": "Wolof",
"xh": "Xhosa",
"yi": "Yiddish",
"yo": "Yoruba",
"zu": "Zulu"
} as const; } as const;
export function deeplLanguageToGoogleLanguage(language: string) { export function deeplLanguageToGoogleLanguage(language: string) {

View file

@ -24,7 +24,7 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { wordsToTitle } from "@utils/text"; import { wordsToTitle } from "@utils/text";
import definePlugin, { ReporterTestable } from "@utils/types"; import definePlugin, { ReporterTestable } from "@utils/types";
import { Button, ChannelStore, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore, VoiceStateStore } from "@webpack/common"; import { AuthenticationStore, Button, ChannelStore, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore, VoiceStateStore } from "@webpack/common";
import { ReactElement } from "react"; import { ReactElement } from "react";
import { getCurrentVoice, settings } from "./settings"; import { getCurrentVoice, settings } from "./settings";
@ -37,6 +37,7 @@ interface VoiceStateChangeEvent {
mute: boolean; mute: boolean;
selfDeaf: boolean; selfDeaf: boolean;
selfMute: boolean; selfMute: boolean;
sessionId: string;
} }
// Mute/Deaf for other people than you is commented out, because otherwise someone can spam it and it will be annoying // Mute/Deaf for other people than you is commented out, because otherwise someone can spam it and it will be annoying
@ -157,6 +158,7 @@ export default definePlugin({
for (const state of voiceStates) { for (const state of voiceStates) {
const { userId, channelId, oldChannelId } = state; const { userId, channelId, oldChannelId } = state;
const isMe = userId === myId; const isMe = userId === myId;
if (isMe && state.sessionId !== AuthenticationStore.getSessionId()) continue;
if (!isMe) { if (!isMe) {
if (!myChanId) continue; if (!myChanId) continue;
if (channelId !== myChanId && oldChannelId !== myChanId) continue; if (channelId !== myChanId && oldChannelId !== myChanId) continue;

View file

@ -35,7 +35,7 @@ import definePlugin, { OptionType } from "@utils/types";
import { chooseFile } from "@utils/web"; import { chooseFile } from "@utils/web";
import { CloudUpload } from "@vencord/discord-types"; import { CloudUpload } from "@vencord/discord-types";
import { CloudUploadPlatform } from "@vencord/discord-types/enums"; import { CloudUploadPlatform } from "@vencord/discord-types/enums";
import { findCssClassesLazy, findLazy, findStoreLazy } from "@webpack"; import { findLazy, findStoreLazy } from "@webpack";
import { Button, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common"; import { Button, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
import { VoiceRecorderDesktop } from "./components/DesktopRecorder"; import { VoiceRecorderDesktop } from "./components/DesktopRecorder";
@ -58,7 +58,6 @@ const EMPTY_META: AudioMetadata = {
const CloudUploadConstructor = findLazy(m => m.prototype?.trackUploadFinished) as typeof CloudUpload; const CloudUploadConstructor = findLazy(m => m.prototype?.trackUploadFinished) as typeof CloudUpload;
const PendingReplyStore = findStoreLazy("PendingReplyStore"); const PendingReplyStore = findStoreLazy("PendingReplyStore");
const OptionClasses = findCssClassesLazy("optionName", "optionIcon", "optionLabel");
export const cl = classNameFactory("vc-vmsg-"); export const cl = classNameFactory("vc-vmsg-");

View file

@ -21,7 +21,7 @@
} }
.vc-vmsg-preview-indicator { .vc-vmsg-preview-indicator {
background: var(--channeltextarea-background); background: var(--control-secondary-background-default);
width: 16px; width: 16px;
height: 16px; height: 16px;
border-radius: 50%; border-radius: 50%;

View file

@ -309,6 +309,8 @@ interface IsValid<T, D = unknown> {
export interface PluginSettingStringDef { export interface PluginSettingStringDef {
type: OptionType.STRING; type: OptionType.STRING;
default?: string; default?: string;
/** Whether to use a multiline text area */
multiline?: boolean;
} }
export interface PluginSettingNumberDef { export interface PluginSettingNumberDef {
type: OptionType.NUMBER; type: OptionType.NUMBER;

View file

@ -599,6 +599,8 @@ export function findCssClasses<S extends string>(...classes: S[]): Record<S, str
if (!res) { if (!res) {
handleModuleNotFound("findCssClasses", ...classes); handleModuleNotFound("findCssClasses", ...classes);
if (IS_REPORTER) return null as any;
return {} as Record<S, string>; return {} as Record<S, string>;
} }