Fixes and ShowHiddenChannels improvements (#634)
~ Fixes #630 ~ Fixes #618
This commit is contained in:
parent
d482d33d6f
commit
586b26d2d4
11 changed files with 147 additions and 47 deletions
|
@ -63,7 +63,10 @@ export default ErrorBoundary.wrap(function NotificationComponent({
|
||||||
<button
|
<button
|
||||||
className="vc-notification-root"
|
className="vc-notification-root"
|
||||||
style={position === "bottom-right" ? { bottom: "1rem" } : { top: "3rem" }}
|
style={position === "bottom-right" ? { bottom: "1rem" } : { top: "3rem" }}
|
||||||
onClick={onClick}
|
onClick={() => {
|
||||||
|
onClose!();
|
||||||
|
onClick?.();
|
||||||
|
}}
|
||||||
onContextMenu={e => {
|
onContextMenu={e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -78,7 +81,7 @@ export default ErrorBoundary.wrap(function NotificationComponent({
|
||||||
<div className="vc-notification-header">
|
<div className="vc-notification-header">
|
||||||
<h2 className="vc-notification-title">{title}</h2>
|
<h2 className="vc-notification-title">{title}</h2>
|
||||||
<button
|
<button
|
||||||
style={{ all: "unset", cursor: "pointer" }}
|
className="vc-notification-close-btn"
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -86,7 +89,6 @@ export default ErrorBoundary.wrap(function NotificationComponent({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
className="vc-notification-close-btn"
|
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-notification-close-btn {
|
.vc-notification-close-btn {
|
||||||
|
all: unset;
|
||||||
|
cursor: pointer;
|
||||||
color: var(--interactive-normal);
|
color: var(--interactive-normal);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
transition: opacity 0.2s ease-in-out, color 0.2s ease-in-out;
|
transition: opacity 0.2s ease-in-out, color 0.2s ease-in-out;
|
||||||
|
|
|
@ -42,6 +42,7 @@ const settings = definePluginSettings({
|
||||||
});
|
});
|
||||||
|
|
||||||
let crashCount: number = 0;
|
let crashCount: number = 0;
|
||||||
|
let lastCrashTimestamp: number = 0;
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "CrashHandler",
|
name: "CrashHandler",
|
||||||
|
@ -80,6 +81,7 @@ export default definePlugin({
|
||||||
});
|
});
|
||||||
} catch { }
|
} catch { }
|
||||||
|
|
||||||
|
lastCrashTimestamp = Date.now();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +99,13 @@ export default definePlugin({
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
CrashHandlerLogger.error("Failed to handle crash", err);
|
CrashHandlerLogger.error("Failed to handle crash", err);
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
lastCrashTimestamp = Date.now();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handlePreventCrash(_this: ReactElement & { forceUpdate: () => void; }) {
|
handlePreventCrash(_this: ReactElement & { forceUpdate: () => void; }) {
|
||||||
|
if (Date.now() - lastCrashTimestamp >= 1_000) {
|
||||||
try {
|
try {
|
||||||
showNotification({
|
showNotification({
|
||||||
color: "#eed202",
|
color: "#eed202",
|
||||||
|
@ -108,6 +113,7 @@ export default definePlugin({
|
||||||
body: "Attempting to recover...",
|
body: "Attempting to recover...",
|
||||||
});
|
});
|
||||||
} catch { }
|
} catch { }
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" });
|
FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" });
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
|
|
||||||
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
||||||
import { showNotification } from "@api/Notifications";
|
import { showNotification } from "@api/Notifications";
|
||||||
|
import { definePluginSettings } from "@api/settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import Logger from "@utils/Logger";
|
import Logger from "@utils/Logger";
|
||||||
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
|
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { filters, findAll, search } from "@webpack";
|
import { filters, findAll, search } from "@webpack";
|
||||||
import { Menu } from "@webpack/common";
|
import { Menu } from "@webpack/common";
|
||||||
|
|
||||||
|
@ -65,6 +66,14 @@ interface FindData {
|
||||||
args: Array<StringNode | FunctionNode>;
|
args: Array<StringNode | FunctionNode>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
notifyOnAutoConnect: {
|
||||||
|
description: "Wheter to notify when Dev Companion has automatically connected.",
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function parseNode(node: Node) {
|
function parseNode(node: Node) {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case "string":
|
case "string":
|
||||||
|
@ -91,7 +100,7 @@ function initWs(isManual = false) {
|
||||||
|
|
||||||
logger.info("Connected to WebSocket");
|
logger.info("Connected to WebSocket");
|
||||||
|
|
||||||
showNotification({
|
(settings.store.notifyOnAutoConnect || isManual) && showNotification({
|
||||||
title: "Dev Companion Connected",
|
title: "Dev Companion Connected",
|
||||||
body: "Connected to WebSocket"
|
body: "Connected to WebSocket"
|
||||||
});
|
});
|
||||||
|
@ -241,6 +250,7 @@ export default definePlugin({
|
||||||
description: "Dev Companion Plugin",
|
description: "Dev Companion Plugin",
|
||||||
authors: [Devs.Ven],
|
authors: [Devs.Ven],
|
||||||
dependencies: ["ContextMenuAPI"],
|
dependencies: ["ContextMenuAPI"],
|
||||||
|
settings,
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
initWs();
|
initWs();
|
||||||
|
|
|
@ -188,7 +188,7 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) =
|
||||||
const src = itemHref ?? itemSrc;
|
const src = itemHref ?? itemSrc;
|
||||||
const isAnimated = new URL(src).pathname.endsWith(".gif");
|
const isAnimated = new URL(src).pathname.endsWith(".gif");
|
||||||
|
|
||||||
const group = findGroupChildrenByChildId("save-image", children);
|
const group = findGroupChildrenByChildId("copy-link", children);
|
||||||
if (group && !group.some(child => child?.props?.id === "emote-cloner")) {
|
if (group && !group.some(child => child?.props?.id === "emote-cloner")) {
|
||||||
group.push((
|
group.push((
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
|
|
|
@ -87,12 +87,12 @@ export default definePlugin({
|
||||||
replace: (_, intention) => `,fakeNitroIntention=${intention}`
|
replace: (_, intention) => `,fakeNitroIntention=${intention}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /(?<=\.(?:canUseEmojisEverywhere|canUseAnimatedEmojis)\(\i)(?=\))/g,
|
match: /\.(?:canUseEmojisEverywhere|canUseAnimatedEmojis)\(\i(?=\))/g,
|
||||||
replace: ',typeof fakeNitroIntention!=="undefined"?fakeNitroIntention:void 0'
|
replace: '$&,typeof fakeNitroIntention!=="undefined"?fakeNitroIntention:void 0'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /(?<=&&!\i&&)!(\i)(?=\)return \i\.\i\.DISALLOW_EXTERNAL;)/,
|
match: /(&&!\i&&!)(\i)(?=\)return \i\.\i\.DISALLOW_EXTERNAL;)/,
|
||||||
replace: (_, canUseExternal) => `(!${canUseExternal}&&(typeof fakeNitroIntention==="undefined"||![${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)))`
|
replace: (_, rest, canUseExternal) => `${rest}(!${canUseExternal}&&(typeof fakeNitroIntention==="undefined"||![${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)))`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -100,16 +100,16 @@ export default definePlugin({
|
||||||
find: "canUseAnimatedEmojis:function",
|
find: "canUseAnimatedEmojis:function",
|
||||||
predicate: () => Settings.plugins.FakeNitro.enableEmojiBypass === true,
|
predicate: () => Settings.plugins.FakeNitro.enableEmojiBypass === true,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=(?:canUseEmojisEverywhere|canUseAnimatedEmojis):function\(\i)\){(.+?\))/g,
|
match: /((?:canUseEmojisEverywhere|canUseAnimatedEmojis):function\(\i)\){(.+?\))/g,
|
||||||
replace: (_, premiumCheck) => `,fakeNitroIntention){${premiumCheck}||fakeNitroIntention==null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`
|
replace: (_, rest, premiumCheck) => `${rest},fakeNitroIntention){${premiumCheck}||fakeNitroIntention==null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "canUseStickersEverywhere:function",
|
find: "canUseStickersEverywhere:function",
|
||||||
predicate: () => Settings.plugins.FakeNitro.enableStickerBypass === true,
|
predicate: () => Settings.plugins.FakeNitro.enableStickerBypass === true,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=canUseStickersEverywhere:function\(\i\){)/,
|
match: /canUseStickersEverywhere:function\(\i\){/,
|
||||||
replace: "return true;"
|
replace: "$&return true;"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -129,8 +129,8 @@ export default definePlugin({
|
||||||
"canStreamMidQuality"
|
"canStreamMidQuality"
|
||||||
].map(func => {
|
].map(func => {
|
||||||
return {
|
return {
|
||||||
match: new RegExp(`(?<=${func}:function\\(\\i\\){)`),
|
match: new RegExp(`${func}:function\\(\\i\\){`),
|
||||||
replace: "return true;"
|
replace: "$&return true;"
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -145,8 +145,8 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "canUseClientThemes:function",
|
find: "canUseClientThemes:function",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=canUseClientThemes:function\(\i\){)/,
|
match: /canUseClientThemes:function\(\i\){/,
|
||||||
replace: "return true;"
|
replace: "$&return true;"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -42,7 +42,7 @@ const imageContextMenuPatch: NavContextMenuPatchCallback = (children, props) =>
|
||||||
|
|
||||||
const src = itemHref ?? itemSrc;
|
const src = itemHref ?? itemSrc;
|
||||||
|
|
||||||
const group = findGroupChildrenByChildId("save-image", children);
|
const group = findGroupChildrenByChildId("copy-link", children);
|
||||||
if (group && !group.some(child => child?.props?.id === "search-image")) {
|
if (group && !group.some(child => child?.props?.id === "search-image")) {
|
||||||
group.push((
|
group.push((
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
|
|
|
@ -20,10 +20,12 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { LazyComponent } from "@utils/misc";
|
import { LazyComponent } from "@utils/misc";
|
||||||
import { formatDuration } from "@utils/text";
|
import { formatDuration } from "@utils/text";
|
||||||
import { find, findByPropsLazy } from "@webpack";
|
import { find, findByPropsLazy } from "@webpack";
|
||||||
import { FluxDispatcher, GuildMemberStore, GuildStore, moment, Parser, SnowflakeUtils, Text, Timestamp, Tooltip } from "@webpack/common";
|
import { FluxDispatcher, GuildMemberStore, GuildStore, moment, Parser, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip } from "@webpack/common";
|
||||||
import { Channel } from "discord-types/general";
|
import type { Channel } from "discord-types/general";
|
||||||
import type { ComponentType } from "react";
|
import type { ComponentType } from "react";
|
||||||
|
|
||||||
|
import { VIEW_CHANNEL } from "..";
|
||||||
|
|
||||||
|
|
||||||
enum SortOrderTypes {
|
enum SortOrderTypes {
|
||||||
LATEST_ACTIVITY = 0,
|
LATEST_ACTIVITY = 0,
|
||||||
|
@ -167,7 +169,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
<img className="shc-lock-screen-logo" src={HiddenChannelLogo} />
|
<img className="shc-lock-screen-logo" src={HiddenChannelLogo} />
|
||||||
|
|
||||||
<div className="shc-lock-screen-heading-container">
|
<div className="shc-lock-screen-heading-container">
|
||||||
<Text variant="heading-xxl/bold">This is a hidden {ChannelTypesToChannelNames[type]} channel.</Text>
|
<Text variant="heading-xxl/bold">This is a {!PermissionStore.can(VIEW_CHANNEL, channel) ? "hidden" : "locked"} {ChannelTypesToChannelNames[type]} channel.</Text>
|
||||||
{channel.isNSFW() &&
|
{channel.isNSFW() &&
|
||||||
<Tooltip text="NSFW">
|
<Tooltip text="NSFW">
|
||||||
{({ onMouseLeave, onMouseEnter }) => (
|
{({ onMouseLeave, onMouseEnter }) => (
|
||||||
|
|
|
@ -21,6 +21,7 @@ import "./style.css";
|
||||||
import { definePluginSettings } from "@api/settings";
|
import { definePluginSettings } from "@api/settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { ChannelStore, PermissionStore, Tooltip } from "@webpack/common";
|
import { ChannelStore, PermissionStore, Tooltip } from "@webpack/common";
|
||||||
|
@ -30,7 +31,8 @@ import HiddenChannelLockScreen, { setChannelBeginHeaderComponent, setEmojiCompon
|
||||||
|
|
||||||
const ChannelListClasses = findByPropsLazy("channelName", "subtitle", "modeMuted", "iconContainer");
|
const ChannelListClasses = findByPropsLazy("channelName", "subtitle", "modeMuted", "iconContainer");
|
||||||
|
|
||||||
const VIEW_CHANNEL = 1n << 10n;
|
export const VIEW_CHANNEL = 1n << 10n;
|
||||||
|
const CONNECT = 1n << 20n;
|
||||||
|
|
||||||
enum ShowMode {
|
enum ShowMode {
|
||||||
LockIcon,
|
LockIcon,
|
||||||
|
@ -99,14 +101,14 @@ export default definePlugin({
|
||||||
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Make Discord think we are connected to a voice channel so it shows us inside it
|
// Prevent Discord from trying to connect to hidden channels
|
||||||
match: /(?=\|\|\i\.default\.selectVoiceChannel\((\i)\.id\))/,
|
match: /(?=\|\|\i\.default\.selectVoiceChannel\((\i)\.id\))/,
|
||||||
replace: (_, channel) => `||$self.isHiddenChannel(${channel})`
|
replace: (_, channel) => `||$self.isHiddenChannel(${channel})`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Make Discord think we are connected to a voice channel so it shows us inside it
|
// Make Discord show inside the channel if clicking on a hidden or locked channel
|
||||||
match: /(?<=\|\|\i\.default\.selectVoiceChannel\((\i)\.id\);!__OVERLAY__&&\()/,
|
match: /(?<=\|\|\i\.default\.selectVoiceChannel\((\i)\.id\);!__OVERLAY__&&\()/,
|
||||||
replace: (_, channel) => `$self.isHiddenChannel(${channel})||`
|
replace: (_, channel) => `$self.isHiddenChannel(${channel},true)||`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -249,9 +251,49 @@ export default definePlugin({
|
||||||
replace: (m, component) => `${m}$self.setChannelBeginHeaderComponent(${component});`
|
replace: (m, component) => `${m}$self.setChannelBeginHeaderComponent(${component});`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Patch the header to only return allowed users and roles if it's a hidden channel (Like when it's used on the HiddenChannelLockScreen)
|
// Change the role permission check to CONNECT if the channel is locked
|
||||||
|
match: /ADMINISTRATOR\)\|\|(?=(.+?\((\i),\i\.\i\.)VIEW_CHANNEL)/,
|
||||||
|
replace: (m, permCheck, channel) => `${m}!Vencord.Webpack.Common.PermissionStore.can(${CONNECT}n,${channel})?${permCheck}CONNECT):`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Change the permissionOverwrite check to CONNECT if the channel is locked
|
||||||
|
match: /permissionOverwrites\[.+?\?(\i):.+?\i=(?=(.+?)VIEW_CHANNEL)/,
|
||||||
|
replace: (m, channel, permCheck) => `${m}!Vencord.Webpack.Common.PermissionStore.can(${CONNECT}n,${channel})?${permCheck}CONNECT):`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Patch the header to only return allowed users and roles if it's a hidden channel or locked channel (Like when it's used on the HiddenChannelLockScreen)
|
||||||
match: /MANAGE_ROLES.{0,60}?return(?=\(.+?(\(0,\i\.jsxs\)\("div",{className:\i\(\)\.members.+?guildId:(\i)\.guild_id.+?roleColor.+?]}\)))/,
|
match: /MANAGE_ROLES.{0,60}?return(?=\(.+?(\(0,\i\.jsxs\)\("div",{className:\i\(\)\.members.+?guildId:(\i)\.guild_id.+?roleColor.+?]}\)))/,
|
||||||
replace: (m, component, channel) => `${m} $self.isHiddenChannel(${channel})?${component}:`
|
replace: (m, component, channel) => {
|
||||||
|
// Export the channel for the users allowed component patch
|
||||||
|
component = component.replace(canonicalizeMatch(/(?<=users:\i)/), `,channel:${channel}`);
|
||||||
|
|
||||||
|
return `${m} $self.isHiddenChannel(${channel},true)?${component}:`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: "().avatars),children",
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
// Create a variable for the channel prop
|
||||||
|
match: /=(\i)\.maxUsers,/,
|
||||||
|
replace: (m, props) => `${m}channel=${props}.channel,`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Make Discord always render the plus button if the component is used inside the HiddenChannelLockScreen
|
||||||
|
match: /\i>0(?=&&.{0,60}renderPopout)/,
|
||||||
|
replace: m => `($self.isHiddenChannel(typeof channel!=="undefined"?channel:void 0,true)?true:${m})`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Prevent Discord from overwriting the last children with the plus button if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen
|
||||||
|
match: /(?<=\.value\(\),(\i)=.+?length-)1(?=\]=.{0,60}renderPopout)/,
|
||||||
|
replace: (_, amount) => `($self.isHiddenChannel(typeof channel!=="undefined"?channel:void 0,true)&&${amount}<=0?0:1)`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Show only the plus text without overflowed children amount if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen
|
||||||
|
match: /(?<="\+",)(\i)\+1/,
|
||||||
|
replace: (m, amount) => `$self.isHiddenChannel(typeof channel!=="undefined"?channel:void 0,true)&&${amount}<=0?"":${m}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -261,22 +303,22 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
// Remove the divider and the open chat button for the HiddenChannelLockScreen
|
// Remove the divider and the open chat button for the HiddenChannelLockScreen
|
||||||
match: /"more-options-popout"\)\);if\((?<=function \i\((\i)\).+?)/,
|
match: /"more-options-popout"\)\);if\((?<=function \i\((\i)\).+?)/,
|
||||||
replace: (m, props) => `${m}(!$self.isHiddenChannel(${props}.channel)||${props}.inCall)&&`
|
replace: (m, props) => `${m}!${props}.inCall&&$self.isHiddenChannel(${props}.channel,true)){}else if(`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Render our HiddenChannelLockScreen component instead of the main voice channel component
|
// Render our HiddenChannelLockScreen component instead of the main voice channel component
|
||||||
match: /this\.renderVoiceChannelEffects.+?children:(?<=renderContent=function.+?)/,
|
match: /this\.renderVoiceChannelEffects.+?children:(?<=renderContent=function.+?)/,
|
||||||
replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel)?$self.HiddenChannelLockScreen(this.props.channel):"
|
replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?$self.HiddenChannelLockScreen(this.props.channel):"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Disable gradients for the HiddenChannelLockScreen of voice channels
|
// Disable gradients for the HiddenChannelLockScreen of voice channels
|
||||||
match: /this\.renderVoiceChannelEffects.+?disableGradients:(?<=renderContent=function.+?)/,
|
match: /this\.renderVoiceChannelEffects.+?disableGradients:(?<=renderContent=function.+?)/,
|
||||||
replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel)||"
|
replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)||"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Disable useless components for the HiddenChannelLockScreen of voice channels
|
// Disable useless components for the HiddenChannelLockScreen of voice channels
|
||||||
match: /(?:{|,)render(?!Header|ExternalHeader).{0,30}?:(?<=renderContent=function.+?)(?!void)/g,
|
match: /(?:{|,)render(?!Header|ExternalHeader).{0,30}?:(?<=renderContent=function.+?)(?!void)/g,
|
||||||
replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel)?null:"
|
replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?null:"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -338,10 +380,25 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: '.displayName="GuildChannelStore"',
|
find: '.displayName="GuildChannelStore"',
|
||||||
replacement: {
|
replacement: [
|
||||||
// Make GuildChannelStore contain hidden channels for users in voice channels to appear in the guild tooltip
|
{
|
||||||
|
// Make GuildChannelStore contain hidden channels
|
||||||
match: /isChannelGated\(.+?\)(?=\|\|)/,
|
match: /isChannelGated\(.+?\)(?=\|\|)/,
|
||||||
replace: m => `${m}||true`
|
replace: m => `${m}||true`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Filter hidden channels from GuildChannelStore.getChannels unless told otherwise
|
||||||
|
match: /(?<=getChannels=function\(\i)\).+?(?=return (\i)})/,
|
||||||
|
replace: (rest, channels) => `,shouldIncludeHidden=false${rest}${channels}=$self.resolveGuildChannels(${channels},shouldIncludeHidden);`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: ".Messages.FORM_LABEL_MUTED",
|
||||||
|
replacement: {
|
||||||
|
// Make GuildChannelStore.getChannels return hidden channels
|
||||||
|
match: /(?<=getChannels\(\i)(?=\))/,
|
||||||
|
replace: ",true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -349,13 +406,33 @@ export default definePlugin({
|
||||||
setEmojiComponent,
|
setEmojiComponent,
|
||||||
setChannelBeginHeaderComponent,
|
setChannelBeginHeaderComponent,
|
||||||
|
|
||||||
isHiddenChannel(channel: Channel & { channelId?: string; }) {
|
isHiddenChannel(channel: Channel & { channelId?: string; }, checkConnect = false) {
|
||||||
if (!channel) return false;
|
if (!channel) return false;
|
||||||
|
|
||||||
if (channel.channelId) channel = ChannelStore.getChannel(channel.channelId);
|
if (channel.channelId) channel = ChannelStore.getChannel(channel.channelId);
|
||||||
if (!channel || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return false;
|
if (!channel || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return false;
|
||||||
|
|
||||||
return !PermissionStore.can(VIEW_CHANNEL, channel);
|
return !PermissionStore.can(VIEW_CHANNEL, channel) || checkConnect && !PermissionStore.can(CONNECT, channel);
|
||||||
|
},
|
||||||
|
|
||||||
|
resolveGuildChannels(channels: Record<string | number, Array<{ channel: Channel; comparator: number; }> | string | number>, shouldIncludeHidden: boolean) {
|
||||||
|
if (shouldIncludeHidden) return channels;
|
||||||
|
|
||||||
|
const res = {};
|
||||||
|
for (const [key, maybeObjChannels] of Object.entries(channels)) {
|
||||||
|
if (!Array.isArray(maybeObjChannels)) {
|
||||||
|
res[key] = maybeObjChannels;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
res[key] ??= [];
|
||||||
|
|
||||||
|
for (const objChannel of maybeObjChannels) {
|
||||||
|
if (objChannel.channel.id === null || !this.isHiddenChannel(objChannel.channel)) res[key].push(objChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
HiddenChannelLockScreen: (channel: any) => <HiddenChannelLockScreen channel={channel} />,
|
HiddenChannelLockScreen: (channel: any) => <HiddenChannelLockScreen channel={channel} />,
|
||||||
|
|
|
@ -103,4 +103,5 @@
|
||||||
.shc-lock-screen-allowed-users-and-roles-container > [class^="members"] {
|
.shc-lock-screen-allowed-users-and-roles-container > [class^="members"] {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,10 @@ export default definePlugin({
|
||||||
find: '.displayName="MediaEngineStore"',
|
find: '.displayName="MediaEngineStore"',
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(?<=\.settings\.audioContextSettings.+?)(\i\[\i\])=(\i\.volume)(.+?setLocalVolume\(\i,).+?\)/,
|
match: /(\.settings\.audioContextSettings.+?)(\i\[\i\])=(\i\.volume)(.+?setLocalVolume\(\i,).+?\)/,
|
||||||
replace: (_, localVolume, syncVolume, rest) => ""
|
replace: (_, rest1, localVolume, syncVolume, rest2) => rest1
|
||||||
+ `(${localVolume}>200?void 0:${localVolume}=${syncVolume})`
|
+ `(${localVolume}>200?void 0:${localVolume}=${syncVolume})`
|
||||||
+ rest
|
+ rest2
|
||||||
+ `${localVolume}??${syncVolume})`
|
+ `${localVolume}??${syncVolume})`
|
||||||
}
|
}
|
||||||
]
|
]
|
Loading…
Reference in a new issue