Compare commits
No commits in common. "30748b99302edb1505173a10dd35604998006c65" and "362f12fa3d384eac6f027bc53f505bba6664f67e" have entirely different histories.
30748b9930
...
362f12fa3d
78 changed files with 558 additions and 529 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.11.4",
|
"version": "1.11.3",
|
||||||
"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": {
|
||||||
|
|
|
@ -43,21 +43,20 @@ interface DecoratorProps {
|
||||||
export type MemberListDecoratorFactory = (props: DecoratorProps) => JSX.Element | null;
|
export type MemberListDecoratorFactory = (props: DecoratorProps) => JSX.Element | null;
|
||||||
type OnlyIn = "guilds" | "dms";
|
type OnlyIn = "guilds" | "dms";
|
||||||
|
|
||||||
export const decoratorsFactories = new Map<string, { render: MemberListDecoratorFactory, onlyIn?: OnlyIn; }>();
|
export const decorators = new Map<string, { render: MemberListDecoratorFactory, onlyIn?: OnlyIn; }>();
|
||||||
|
|
||||||
export function addMemberListDecorator(identifier: string, render: MemberListDecoratorFactory, onlyIn?: OnlyIn) {
|
export function addMemberListDecorator(identifier: string, render: MemberListDecoratorFactory, onlyIn?: OnlyIn) {
|
||||||
decoratorsFactories.set(identifier, { render, onlyIn });
|
decorators.set(identifier, { render, onlyIn });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeMemberListDecorator(identifier: string) {
|
export function removeMemberListDecorator(identifier: string) {
|
||||||
decoratorsFactories.delete(identifier);
|
decorators.delete(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function __getDecorators(props: DecoratorProps): JSX.Element {
|
export function __getDecorators(props: DecoratorProps): (JSX.Element | null)[] {
|
||||||
const isInGuild = !!(props.guildId);
|
const isInGuild = !!(props.guildId);
|
||||||
|
return Array.from(
|
||||||
const decorators = Array.from(
|
decorators.entries(),
|
||||||
decoratorsFactories.entries(),
|
|
||||||
([key, { render: Decorator, onlyIn }]) => {
|
([key, { render: Decorator, onlyIn }]) => {
|
||||||
if ((onlyIn === "guilds" && !isInGuild) || (onlyIn === "dms" && isInGuild))
|
if ((onlyIn === "guilds" && !isInGuild) || (onlyIn === "dms" && isInGuild))
|
||||||
return null;
|
return null;
|
||||||
|
@ -69,10 +68,4 @@ export function __getDecorators(props: DecoratorProps): JSX.Element {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="vc-member-list-decorators-wrapper">
|
|
||||||
{decorators}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,29 +48,23 @@ export interface MessageDecorationProps {
|
||||||
}
|
}
|
||||||
export type MessageDecorationFactory = (props: MessageDecorationProps) => JSX.Element | null;
|
export type MessageDecorationFactory = (props: MessageDecorationProps) => JSX.Element | null;
|
||||||
|
|
||||||
export const decorationsFactories = new Map<string, MessageDecorationFactory>();
|
export const decorations = new Map<string, MessageDecorationFactory>();
|
||||||
|
|
||||||
export function addMessageDecoration(identifier: string, decoration: MessageDecorationFactory) {
|
export function addMessageDecoration(identifier: string, decoration: MessageDecorationFactory) {
|
||||||
decorationsFactories.set(identifier, decoration);
|
decorations.set(identifier, decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeMessageDecoration(identifier: string) {
|
export function removeMessageDecoration(identifier: string) {
|
||||||
decorationsFactories.delete(identifier);
|
decorations.delete(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function __addDecorationsToMessage(props: MessageDecorationProps): JSX.Element {
|
export function __addDecorationsToMessage(props: MessageDecorationProps): (JSX.Element | null)[] {
|
||||||
const decorations = Array.from(
|
return Array.from(
|
||||||
decorationsFactories.entries(),
|
decorations.entries(),
|
||||||
([key, Decoration]) => (
|
([key, Decoration]) => (
|
||||||
<ErrorBoundary noop message={`Failed to render ${key} Message Decoration`} key={key}>
|
<ErrorBoundary noop message={`Failed to render ${key} Message Decoration`} key={key}>
|
||||||
<Decoration {...props} />
|
<Decoration {...props} />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="vc-message-decorations-wrapper">
|
|
||||||
{decorations}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ function ReloadRequiredCard({ required }: { required: boolean; }) {
|
||||||
<Forms.FormText className={cl("dep-text")}>
|
<Forms.FormText className={cl("dep-text")}>
|
||||||
Restart now to apply new plugins and their settings
|
Restart now to apply new plugins and their settings
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
<Button onClick={() => location.reload()} className={cl("restart-button")}>
|
<Button onClick={() => location.reload()}>
|
||||||
Restart
|
Restart
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
|
@ -158,8 +158,8 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on
|
||||||
className={classes(ButtonClasses.button, cl("info-button"))}
|
className={classes(ButtonClasses.button, cl("info-button"))}
|
||||||
>
|
>
|
||||||
{plugin.options && !isObjectEmpty(plugin.options)
|
{plugin.options && !isObjectEmpty(plugin.options)
|
||||||
? <CogWheel className={cl("info-icon")} />
|
? <CogWheel />
|
||||||
: <InfoIcon className={cl("info-icon")} />}
|
: <InfoIcon />}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -63,7 +63,10 @@
|
||||||
height: 8em;
|
height: 8em;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.25em;
|
}
|
||||||
|
|
||||||
|
.vc-plugins-info-card div {
|
||||||
|
line-height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-plugins-restart-card {
|
.vc-plugins-restart-card {
|
||||||
|
@ -73,11 +76,11 @@
|
||||||
color: var(--info-warning-text);
|
color: var(--info-warning-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-plugins-restart-button {
|
.vc-plugins-restart-card button {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
background: var(--info-warning-foreground) !important;
|
background: var(--info-warning-foreground) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-plugins-info-icon:not(:hover, :focus) {
|
.vc-plugins-info-button svg:not(:hover, :focus) {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: '"sticker")',
|
find: '"sticker")',
|
||||||
replacement: {
|
replacement: {
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(\i\.isDM.+?(\i)\.push)/,
|
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(\i\.isDM.+?(\i)\.push)/,
|
||||||
replace: (m, not, children) => not
|
replace: (m, not, children) => not
|
||||||
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
|
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
|
||||||
|
|
|
@ -19,15 +19,10 @@
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
import managedStyle from "./style.css?managed";
|
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "MemberListDecoratorsAPI",
|
name: "MemberListDecoratorsAPI",
|
||||||
description: "API to add decorators to member list (both in servers and DMs)",
|
description: "API to add decorators to member list (both in servers and DMs)",
|
||||||
authors: [Devs.TheSun, Devs.Ven],
|
authors: [Devs.TheSun, Devs.Ven],
|
||||||
|
|
||||||
managedStyle,
|
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".lostPermission)",
|
find: ".lostPermission)",
|
||||||
|
@ -37,7 +32,7 @@ export default definePlugin({
|
||||||
replace: "$&vencordProps=$1,"
|
replace: "$&vencordProps=$1,"
|
||||||
}, {
|
}, {
|
||||||
match: /#{intl::GUILD_OWNER}(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
|
match: /#{intl::GUILD_OWNER}(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/,
|
||||||
replace: "$&(typeof vencordProps=='undefined'?null:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
|
replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -45,8 +40,8 @@ export default definePlugin({
|
||||||
find: "PrivateChannel.renderAvatar",
|
find: "PrivateChannel.renderAvatar",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /decorators:(\i\.isSystemDM\(\))\?(.+?):null/,
|
match: /decorators:(\i\.isSystemDM\(\))\?(.+?):null/,
|
||||||
replace: "decorators:[Vencord.Api.MemberListDecorators.__getDecorators(arguments[0]),$1?$2:null]"
|
replace: "decorators:[...Vencord.Api.MemberListDecorators.__getDecorators(arguments[0]), $1?$2:null]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
});
|
});
|
|
@ -1,11 +0,0 @@
|
||||||
.vc-member-list-decorators-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-member-list-decorators-wrapper:not(:empty) {
|
|
||||||
/* Margin to match default Discord decorators */
|
|
||||||
margin-left: 0.25em;
|
|
||||||
}
|
|
|
@ -19,22 +19,17 @@
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
import managedStyle from "./style.css?managed";
|
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "MessageDecorationsAPI",
|
name: "MessageDecorationsAPI",
|
||||||
description: "API to add decorations to messages",
|
description: "API to add decorations to messages",
|
||||||
authors: [Devs.TheSun],
|
authors: [Devs.TheSun],
|
||||||
|
|
||||||
managedStyle,
|
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: '"Message Username"',
|
find: '"Message Username"',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?}\),\i(?=\])/,
|
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?}\),\i(?=\])/,
|
||||||
replace: "$&,Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
|
replace: "$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
});
|
});
|
|
@ -1,18 +0,0 @@
|
||||||
.vc-message-decorations-wrapper {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-message-decorations-wrapper:not(:empty) {
|
|
||||||
/* Margin to match default Discord decorators */
|
|
||||||
margin-left: 0.25em;
|
|
||||||
|
|
||||||
/* Align vertically */
|
|
||||||
position: relative;
|
|
||||||
vertical-align: top;
|
|
||||||
top: 0.1rem;
|
|
||||||
height: calc(1rem + 4px);
|
|
||||||
max-height: calc(1rem + 4px)
|
|
||||||
}
|
|
|
@ -37,9 +37,12 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".handleSendMessage,onResize",
|
find: ".handleSendMessage,onResize",
|
||||||
replacement: {
|
replacement: {
|
||||||
// https://regex101.com/r/hBlXpl/1
|
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply);
|
||||||
match: /let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);(?<=\)\(({.+?})\)\.then.+?)/,
|
// Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid)
|
||||||
replace: (m, parsedMessage, channel, replyOptions, extra) => m +
|
match: /(\{openWarningPopout:.{0,100}type:this.props.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)(?<=\)\(({.+?})\)\.then.+?)/,
|
||||||
|
// props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true };
|
||||||
|
replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
|
||||||
|
`${rest1}async ${rest2}` +
|
||||||
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
|
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
|
||||||
"return{shouldClear:false,shouldRefocus:true};"
|
"return{shouldClear:false,shouldRefocus:true};"
|
||||||
}
|
}
|
||||||
|
@ -49,6 +52,7 @@ export default definePlugin({
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /let\{id:\i}=(\i),{id:\i}=(\i);return \i\.useCallback\((\i)=>\{/,
|
match: /let\{id:\i}=(\i),{id:\i}=(\i);return \i\.useCallback\((\i)=>\{/,
|
||||||
replace: (m, message, channel, event) =>
|
replace: (m, message, channel, event) =>
|
||||||
|
// the message param is shadowed by the event param, so need to alias them
|
||||||
`const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg, vcChan, ${event});`
|
`const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg, vcChan, ${event});`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,6 @@ export default definePlugin({
|
||||||
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
|
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /({(?=.+?function (\i).{0,160}(\i)=\i\.useMemo.{0,140}return \i\.useMemo\(\(\)=>\i\(\3).+?(?:function\(\){return |\(\)=>))\2/,
|
match: /({(?=.+?function (\i).{0,160}(\i)=\i\.useMemo.{0,140}return \i\.useMemo\(\(\)=>\i\(\3).+?(?:function\(\){return |\(\)=>))\2/,
|
||||||
replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
|
replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import definePlugin, { ReporterTestable } from "@utils/types";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common";
|
import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common";
|
||||||
|
|
||||||
const fetchApplicationsRPC = findByCodeLazy('"Invalid Origin"', ".application");
|
const fetchApplicationsRPC = findByCodeLazy("APPLICATION_RPC(", "Client ID");
|
||||||
|
|
||||||
async function lookupAsset(applicationId: string, key: string): Promise<string> {
|
async function lookupAsset(applicationId: string, key: string): Promise<string> {
|
||||||
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
|
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
|
||||||
|
|
|
@ -24,14 +24,14 @@ let style: HTMLStyleElement;
|
||||||
|
|
||||||
function setCss() {
|
function setCss() {
|
||||||
style.textContent = `
|
style.textContent = `
|
||||||
.vc-nsfw-img [class^=imageContainer],
|
.vc-nsfw-img [class^=imageWrapper] img,
|
||||||
.vc-nsfw-img [class^=wrapperPaused] {
|
.vc-nsfw-img [class^=wrapperPaused] video {
|
||||||
filter: blur(${Settings.plugins.BlurNSFW.blurAmount}px);
|
filter: blur(${Settings.plugins.BlurNSFW.blurAmount}px);
|
||||||
transition: filter 0.2s;
|
transition: filter 0.2s;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
filter: blur(0);
|
|
||||||
}
|
}
|
||||||
|
.vc-nsfw-img [class^=imageWrapper]:hover img,
|
||||||
|
.vc-nsfw-img [class^=wrapperPaused]:hover video {
|
||||||
|
filter: unset;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ export default definePlugin({
|
||||||
options: {
|
options: {
|
||||||
blurAmount: {
|
blurAmount: {
|
||||||
type: OptionType.NUMBER,
|
type: OptionType.NUMBER,
|
||||||
description: "Blur Amount (in pixels)",
|
description: "Blur Amount",
|
||||||
default: 10,
|
default: 10,
|
||||||
onChange: setCss
|
onChange: setCss
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
.vc-clientTheme-settings {
|
.client-theme-settings {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-clientTheme-container {
|
.client-theme-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-clientTheme-labels {
|
.client-theme-settings-labels {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-clientTheme-container [class^="swatch"] {
|
.client-theme-container > [class^="colorSwatch"] > [class^="swatch"] {
|
||||||
border: thin solid var(--background-modifier-accent) !important;
|
border: thin solid var(--background-modifier-accent) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-clientTheme-warning-text {
|
.client-theme-warning * {
|
||||||
color: var(--text-danger);
|
color: var(--text-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-clientTheme-contrast-warning {
|
.client-theme-contrast-warning {
|
||||||
background-color: var(--background-primary);
|
background-color: var(--background-primary);
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
import "./clientTheme.css";
|
import "./clientTheme.css";
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
|
@ -15,8 +14,6 @@ import definePlugin, { OptionType, StartAt } from "@utils/types";
|
||||||
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
||||||
import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
|
import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
const cl = classNameFactory("vc-clientTheme-");
|
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)");
|
const ColorPicker = findComponentByCodeLazy("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)");
|
||||||
|
|
||||||
const colorPresets = [
|
const colorPresets = [
|
||||||
|
@ -63,9 +60,9 @@ function ThemeSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cl("settings")}>
|
<div className="client-theme-settings">
|
||||||
<div className={cl("container")}>
|
<div className="client-theme-container">
|
||||||
<div className={cl("settings-labels")}>
|
<div className="client-theme-settings-labels">
|
||||||
<Forms.FormTitle tag="h3">Theme Color</Forms.FormTitle>
|
<Forms.FormTitle tag="h3">Theme Color</Forms.FormTitle>
|
||||||
<Forms.FormText>Add a color to your Discord client theme</Forms.FormText>
|
<Forms.FormText>Add a color to your Discord client theme</Forms.FormText>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,10 +76,10 @@ function ThemeSettings() {
|
||||||
{(contrastWarning || nitroThemeEnabled) && (<>
|
{(contrastWarning || nitroThemeEnabled) && (<>
|
||||||
<Forms.FormDivider className={classes(Margins.top8, Margins.bottom8)} />
|
<Forms.FormDivider className={classes(Margins.top8, Margins.bottom8)} />
|
||||||
<div className={`client-theme-contrast-warning ${contrastWarning ? (isLightTheme ? "theme-dark" : "theme-light") : ""}`}>
|
<div className={`client-theme-contrast-warning ${contrastWarning ? (isLightTheme ? "theme-dark" : "theme-light") : ""}`}>
|
||||||
<div className={cl("warning")}>
|
<div className="client-theme-warning">
|
||||||
<Forms.FormText className={cl("warning-text")}>Warning, your theme won't look good:</Forms.FormText>
|
<Forms.FormText>Warning, your theme won't look good:</Forms.FormText>
|
||||||
{contrastWarning && <Forms.FormText className={cl("warning-text")}>Selected color won't contrast well with text</Forms.FormText>}
|
{contrastWarning && <Forms.FormText>Selected color won't contrast well with text</Forms.FormText>}
|
||||||
{nitroThemeEnabled && <Forms.FormText className={cl("warning-text")}>Nitro themes aren't supported</Forms.FormText>}
|
{nitroThemeEnabled && <Forms.FormText>Nitro themes aren't supported</Forms.FormText>}
|
||||||
</div>
|
</div>
|
||||||
{(contrastWarning && fixableContrast) && <Button onClick={() => setTheme(oppositeTheme)} color={Button.Colors.RED}>Switch to {oppositeTheme} mode</Button>}
|
{(contrastWarning && fixableContrast) && <Button onClick={() => setTheme(oppositeTheme)} color={Button.Colors.RED}>Switch to {oppositeTheme} mode</Button>}
|
||||||
{(nitroThemeEnabled) && <Button onClick={() => setTheme(theme)} color={Button.Colors.RED}>Disable Nitro Theme</Button>}
|
{(nitroThemeEnabled) && <Button onClick={() => setTheme(theme)} color={Button.Colors.RED}>Disable Nitro Theme</Button>}
|
||||||
|
@ -126,7 +123,6 @@ export default definePlugin({
|
||||||
stop() {
|
stop() {
|
||||||
document.getElementById("clientThemeVars")?.remove();
|
document.getElementById("clientThemeVars")?.remove();
|
||||||
document.getElementById("clientThemeOffsets")?.remove();
|
document.getElementById("clientThemeOffsets")?.remove();
|
||||||
document.getElementById("clientThemeLightModeFixes")?.remove();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ function getEmojiMarkdown(target: Target, copyUnicode: boolean): string {
|
||||||
: `:${emojiName}:`;
|
: `:${emojiName}:`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = new URL(target.firstChild.src);
|
const extension = target?.firstChild.src.match(
|
||||||
const hasParam = url.searchParams.get("animated") === "true";
|
/https:\/\/cdn\.discordapp\.com\/emojis\/\d+\.(\w+)/
|
||||||
const isGif = url.pathname.endsWith(".gif");
|
)?.[1];
|
||||||
|
|
||||||
return `<${(hasParam || isGif) ? "a" : ""}:${emojiName.replace(/~\d+$/, "")}:${emojiId}>`;
|
return `<${extension === "gif" ? "a" : ""}:${emojiName.replace(/~\d+$/, "")}:${emojiId}>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
|
@ -55,7 +55,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
contextMenus: {
|
contextMenus: {
|
||||||
"expression-picker"(children, { target }: { target: Target; }) {
|
"expression-picker"(children, { target }: { target: Target }) {
|
||||||
if (target.dataset.type !== "emoji") return;
|
if (target.dataset.type !== "emoji") return;
|
||||||
|
|
||||||
children.push(
|
children.push(
|
||||||
|
|
|
@ -44,7 +44,6 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".selectPreviousCommandOption(",
|
find: ".selectPreviousCommandOption(",
|
||||||
replacement: {
|
replacement: {
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(?<=(\i)\.which(?:!==|===)\i\.\i.ENTER(\|\||&&)).{0,100}(\(0,\i\.\i\)\(\i\)).{0,100}(?=(?:\|\||&&)\(\i\.preventDefault)/,
|
match: /(?<=(\i)\.which(?:!==|===)\i\.\i.ENTER(\|\||&&)).{0,100}(\(0,\i\.\i\)\(\i\)).{0,100}(?=(?:\|\||&&)\(\i\.preventDefault)/,
|
||||||
replace: (_, event, condition, codeblock) => `${condition === "||" ? "!" : ""}$self.shouldSubmit(${event},${codeblock})`
|
replace: (_, event, condition, codeblock) => `${condition === "||" ? "!" : ""}$self.shouldSubmit(${event},${codeblock})`
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,6 @@ function DearrowButton({ component }: { component: Component<Props>; }) {
|
||||||
height="24px"
|
height="24px"
|
||||||
viewBox="0 0 36 36"
|
viewBox="0 0 36 36"
|
||||||
aria-label="Toggle Dearrow"
|
aria-label="Toggle Dearrow"
|
||||||
className="vc-dearrow-icon"
|
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="#1213BD"
|
fill="#1213BD"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.vc-dearrow-toggle-off .vc-dearrow-icon {
|
.vc-dearrow-toggle-off svg {
|
||||||
filter: grayscale(1);
|
filter: grayscale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,6 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Disallow the emoji for premium locked if the intention doesn't allow it
|
// Disallow the emoji for premium locked if the intention doesn't allow it
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(!)?(\i\.\i\.canUseEmojisEverywhere\(\i\))/,
|
match: /(!)?(\i\.\i\.canUseEmojisEverywhere\(\i\))/,
|
||||||
replace: (m, not) => not
|
replace: (m, not) => not
|
||||||
? `(${m}&&!${IS_BYPASSEABLE_INTENTION})`
|
? `(${m}&&!${IS_BYPASSEABLE_INTENTION})`
|
||||||
|
|
|
@ -8,7 +8,6 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findComponentByCodeLazy } from "@webpack";
|
import { findComponentByCodeLazy } from "@webpack";
|
||||||
import { UserStore, useStateFromStores } from "@webpack/common";
|
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
const UserMentionComponent = findComponentByCodeLazy(".USER_MENTION)");
|
const UserMentionComponent = findComponentByCodeLazy(".USER_MENTION)");
|
||||||
|
@ -35,19 +34,14 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
UserMentionComponent: ErrorBoundary.wrap((props: UserMentionComponentProps) => {
|
UserMentionComponent: ErrorBoundary.wrap((props: UserMentionComponentProps) => (
|
||||||
const user = useStateFromStores([UserStore], () => UserStore.getUser(props.id));
|
<UserMentionComponent
|
||||||
if (user == null) {
|
|
||||||
return props.originalComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
return <UserMentionComponent
|
|
||||||
// This seems to be constant
|
// This seems to be constant
|
||||||
className="mention"
|
className="mention"
|
||||||
userId={props.id}
|
userId={props.id}
|
||||||
channelId={props.channelId}
|
channelId={props.channelId}
|
||||||
/>;
|
/>
|
||||||
}, {
|
), {
|
||||||
fallback: ({ wrappedProps: { originalComponent } }) => originalComponent()
|
fallback: ({ wrappedProps: { originalComponent } }) => originalComponent()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,13 +17,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { disableStyle, enableStyle } from "@api/Styles";
|
||||||
import { getUserSettingLazy } from "@api/UserSettings";
|
import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findComponentByCodeLazy } from "@webpack";
|
import { findComponentByCodeLazy } from "@webpack";
|
||||||
|
|
||||||
import managedStyle from "./style.css?managed";
|
import style from "./style.css?managed";
|
||||||
|
|
||||||
const Button = findComponentByCodeLazy(".NONE,disabled:", ".PANEL_BUTTON");
|
const Button = findComponentByCodeLazy(".NONE,disabled:", ".PANEL_BUTTON");
|
||||||
|
|
||||||
|
@ -89,8 +90,6 @@ export default definePlugin({
|
||||||
dependencies: ["UserSettingsAPI"],
|
dependencies: ["UserSettingsAPI"],
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
managedStyle,
|
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
||||||
|
@ -103,4 +102,11 @@ export default definePlugin({
|
||||||
|
|
||||||
GameActivityToggleButton: ErrorBoundary.wrap(GameActivityToggleButton, { noop: true }),
|
GameActivityToggleButton: ErrorBoundary.wrap(GameActivityToggleButton, { noop: true }),
|
||||||
|
|
||||||
|
start() {
|
||||||
|
enableStyle(style);
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
disableStyle(style);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,44 +16,28 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "./styles.css";
|
|
||||||
|
|
||||||
import { get, set } from "@api/DataStore";
|
import { get, set } from "@api/DataStore";
|
||||||
import { updateMessage } from "@api/MessageUpdater";
|
|
||||||
import { migratePluginSettings } from "@api/Settings";
|
|
||||||
import { ImageInvisible, ImageVisible } from "@components/Icons";
|
import { ImageInvisible, ImageVisible } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { classes } from "@utils/misc";
|
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { ChannelStore } from "@webpack/common";
|
import { ChannelStore } from "@webpack/common";
|
||||||
import { MessageSnapshot } from "@webpack/types";
|
import { MessageSnapshot } from "@webpack/types";
|
||||||
|
|
||||||
|
let style: HTMLStyleElement;
|
||||||
|
|
||||||
const KEY = "HideAttachments_HiddenIds";
|
const KEY = "HideAttachments_HiddenIds";
|
||||||
|
|
||||||
let hiddenMessages = new Set<string>();
|
let hiddenMessages: Set<string> = new Set();
|
||||||
|
const getHiddenMessages = () => get(KEY).then(set => {
|
||||||
async function getHiddenMessages() {
|
hiddenMessages = set ?? new Set<string>();
|
||||||
hiddenMessages = await get(KEY) ?? new Set();
|
|
||||||
return hiddenMessages;
|
return hiddenMessages;
|
||||||
}
|
});
|
||||||
|
|
||||||
const saveHiddenMessages = (ids: Set<string>) => set(KEY, ids);
|
const saveHiddenMessages = (ids: Set<string>) => set(KEY, ids);
|
||||||
|
|
||||||
migratePluginSettings("HideMedia", "HideAttachments");
|
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "HideMedia",
|
name: "HideAttachments",
|
||||||
description: "Hide attachments and embeds for individual messages via hover button",
|
description: "Hide attachments and Embeds for individual messages via hover button",
|
||||||
authors: [Devs.Ven],
|
authors: [Devs.Ven],
|
||||||
dependencies: ["MessageUpdaterAPI"],
|
|
||||||
|
|
||||||
patches: [{
|
|
||||||
find: "this.renderAttachments(",
|
|
||||||
replacement: {
|
|
||||||
match: /(?<=\i=)this\.render(?:Attachments|Embeds|StickersAccessories)\((\i)\)/g,
|
|
||||||
replace: "$self.shouldHide($1?.id)?null:$&"
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
|
|
||||||
renderMessagePopoverButton(msg) {
|
renderMessagePopoverButton(msg) {
|
||||||
// @ts-ignore - discord-types lags behind discord.
|
// @ts-ignore - discord-types lags behind discord.
|
||||||
|
@ -66,42 +50,49 @@ export default definePlugin({
|
||||||
const isHidden = hiddenMessages.has(msg.id);
|
const isHidden = hiddenMessages.has(msg.id);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: isHidden ? "Show Media" : "Hide Media",
|
label: isHidden ? "Show Attachments" : "Hide Attachments",
|
||||||
icon: isHidden ? ImageVisible : ImageInvisible,
|
icon: isHidden ? ImageVisible : ImageInvisible,
|
||||||
message: msg,
|
message: msg,
|
||||||
channel: ChannelStore.getChannel(msg.channel_id),
|
channel: ChannelStore.getChannel(msg.channel_id),
|
||||||
onClick: () => this.toggleHide(msg.channel_id, msg.id)
|
onClick: () => this.toggleHide(msg.id)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
renderMessageAccessory({ message }) {
|
|
||||||
if (!this.shouldHide(message.id)) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span className={classes("vc-hideAttachments-accessory", !message.content && "vc-hideAttachments-no-content")}>
|
|
||||||
Media Hidden
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
|
style = document.createElement("style");
|
||||||
|
style.id = "VencordHideAttachments";
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
await getHiddenMessages();
|
await getHiddenMessages();
|
||||||
|
await this.buildCss();
|
||||||
},
|
},
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
|
style.remove();
|
||||||
hiddenMessages.clear();
|
hiddenMessages.clear();
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldHide(messageId: string) {
|
async buildCss() {
|
||||||
return hiddenMessages.has(messageId);
|
const elements = [...hiddenMessages].map(id => `#message-accessories-${id}`).join(",");
|
||||||
|
style.textContent = `
|
||||||
|
:is(${elements}) :is([class*="embedWrapper"], [class*="clickableSticker"]) {
|
||||||
|
/* important is not necessary, but add it to make sure bad themes won't break it */
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
:is(${elements})::after {
|
||||||
|
content: "Attachments hidden";
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
},
|
},
|
||||||
|
|
||||||
async toggleHide(channelId: string, messageId: string) {
|
async toggleHide(id: string) {
|
||||||
const ids = await getHiddenMessages();
|
const ids = await getHiddenMessages();
|
||||||
if (!ids.delete(messageId))
|
if (!ids.delete(id))
|
||||||
ids.add(messageId);
|
ids.add(id);
|
||||||
|
|
||||||
await saveHiddenMessages(ids);
|
await saveHiddenMessages(ids);
|
||||||
updateMessage(channelId, messageId);
|
await this.buildCss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
.vc-hideAttachments-accessory {
|
|
||||||
color: var(--text-muted);
|
|
||||||
margin-top: 0.5em;
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-hideAttachments-no-content {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
|
@ -195,7 +195,6 @@ export const Magnifier = ErrorBoundary.wrap<MagnifierProps>(({ instance, size: i
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
className={cl("image")}
|
|
||||||
ref={imageRef}
|
ref={imageRef}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { disableStyle, enableStyle } from "@api/Styles";
|
||||||
import { makeRange } from "@components/PluginSettings/components";
|
import { makeRange } from "@components/PluginSettings/components";
|
||||||
import { debounce } from "@shared/debounce";
|
import { debounce } from "@shared/debounce";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
|
@ -28,7 +29,7 @@ import type { Root } from "react-dom/client";
|
||||||
|
|
||||||
import { Magnifier, MagnifierProps } from "./components/Magnifier";
|
import { Magnifier, MagnifierProps } from "./components/Magnifier";
|
||||||
import { ELEMENT_ID } from "./constants";
|
import { ELEMENT_ID } from "./constants";
|
||||||
import managedStyle from "./styles.css?managed";
|
import styles from "./styles.css?managed";
|
||||||
|
|
||||||
export const settings = definePluginSettings({
|
export const settings = definePluginSettings({
|
||||||
saveZoomValues: {
|
saveZoomValues: {
|
||||||
|
@ -159,8 +160,6 @@ export default definePlugin({
|
||||||
authors: [Devs.Aria],
|
authors: [Devs.Aria],
|
||||||
tags: ["ImageUtilities"],
|
tags: ["ImageUtilities"],
|
||||||
|
|
||||||
managedStyle,
|
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".contain,SCALE_DOWN:",
|
find: ".contain,SCALE_DOWN:",
|
||||||
|
@ -253,12 +252,14 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
enableStyle(styles);
|
||||||
this.element = document.createElement("div");
|
this.element = document.createElement("div");
|
||||||
this.element.classList.add("MagnifierContainer");
|
this.element.classList.add("MagnifierContainer");
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element);
|
||||||
},
|
},
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
|
disableStyle(styles);
|
||||||
// so componenetWillUnMount gets called if Magnifier component is still alive
|
// so componenetWillUnMount gets called if Magnifier component is still alive
|
||||||
this.root && this.root.unmount();
|
this.root && this.root.unmount();
|
||||||
this.element?.remove();
|
this.element?.remove();
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-imgzoom-nearest-neighbor > .vc-imgzoom-image {
|
.vc-imgzoom-nearest-neighbor>img {
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
|
|
||||||
/* https://googlechrome.github.io/samples/image-rendering-pixelated/index.html */
|
/* https://googlechrome.github.io/samples/image-rendering-pixelated/index.html */
|
||||||
|
|
|
@ -50,9 +50,9 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "#{intl::FRIENDS_SECTION_ONLINE}",
|
find: "#{intl::FRIENDS_SECTION_ONLINE}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /,{id:(\i\.\i)\.BLOCKED,show:.+?className:(\i\.item)/,
|
match: /(\(0,\i\.jsx\)\(\i\.\i\.Item,\{id:\i\.\i)\.BLOCKED,className:([^\s]+?)\.item,children:\i\.\i\.string\(\i\.\i#{intl::BLOCKED}\)\}\)/,
|
||||||
replace: (rest, relationShipTypes, className) => `,{id:${relationShipTypes}.IMPLICIT,show:true,className:${className},content:"Implicit"}${rest}`
|
replace: "$1.IMPLICIT,className:$2.item,children:\"Implicit\"}),$&"
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
// Sections content
|
// Sections content
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,6 @@ import { addMessageDecoration, removeMessageDecoration } from "@api/MessageDecor
|
||||||
import { addMessageClickListener, addMessagePreEditListener, addMessagePreSendListener, removeMessageClickListener, removeMessagePreEditListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
import { addMessageClickListener, addMessagePreEditListener, addMessagePreSendListener, removeMessageClickListener, removeMessagePreEditListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
||||||
import { addMessagePopoverButton, removeMessagePopoverButton } from "@api/MessagePopover";
|
import { addMessagePopoverButton, removeMessagePopoverButton } from "@api/MessagePopover";
|
||||||
import { Settings, SettingsStore } from "@api/Settings";
|
import { Settings, SettingsStore } from "@api/Settings";
|
||||||
import { disableStyle, enableStyle } from "@api/Styles";
|
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { canonicalizeFind } from "@utils/patches";
|
import { canonicalizeFind } from "@utils/patches";
|
||||||
import { Patch, Plugin, PluginDef, ReporterTestable, StartAt } from "@utils/types";
|
import { Patch, Plugin, PluginDef, ReporterTestable, StartAt } from "@utils/types";
|
||||||
|
@ -255,7 +254,7 @@ export function subscribeAllPluginsFluxEvents(fluxDispatcher: typeof FluxDispatc
|
||||||
|
|
||||||
export const startPlugin = traceFunction("startPlugin", function startPlugin(p: Plugin) {
|
export const startPlugin = traceFunction("startPlugin", function startPlugin(p: Plugin) {
|
||||||
const {
|
const {
|
||||||
name, commands, contextMenus, managedStyle, userProfileBadge,
|
name, commands, contextMenus, userProfileBadge,
|
||||||
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
||||||
renderChatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton
|
renderChatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton
|
||||||
} = p;
|
} = p;
|
||||||
|
@ -299,8 +298,6 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (managedStyle) enableStyle(managedStyle);
|
|
||||||
|
|
||||||
if (userProfileBadge) addProfileBadge(userProfileBadge);
|
if (userProfileBadge) addProfileBadge(userProfileBadge);
|
||||||
|
|
||||||
if (onBeforeMessageEdit) addMessagePreEditListener(onBeforeMessageEdit);
|
if (onBeforeMessageEdit) addMessagePreEditListener(onBeforeMessageEdit);
|
||||||
|
@ -318,7 +315,7 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
||||||
|
|
||||||
export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plugin) {
|
export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plugin) {
|
||||||
const {
|
const {
|
||||||
name, commands, contextMenus, managedStyle, userProfileBadge,
|
name, commands, contextMenus, userProfileBadge,
|
||||||
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
||||||
renderChatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton
|
renderChatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton
|
||||||
} = p;
|
} = p;
|
||||||
|
@ -360,8 +357,6 @@ export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (managedStyle) disableStyle(managedStyle);
|
|
||||||
|
|
||||||
if (userProfileBadge) removeProfileBadge(userProfileBadge);
|
if (userProfileBadge) removeProfileBadge(userProfileBadge);
|
||||||
|
|
||||||
if (onBeforeMessageEdit) removeMessagePreEditListener(onBeforeMessageEdit);
|
if (onBeforeMessageEdit) removeMessagePreEditListener(onBeforeMessageEdit);
|
||||||
|
|
|
@ -23,11 +23,11 @@ import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { useMemo } from "@webpack/common";
|
import { useMemo } from "@webpack/common";
|
||||||
|
|
||||||
// Calculate a CSS color string based on the user ID
|
// Calculate a CSS color string based on the user ID
|
||||||
function calculateNameColorForUser(id?: string) {
|
function calculateNameColorForUser(id: string) {
|
||||||
const { lightness } = settings.use(["lightness"]);
|
const { lightness } = settings.use(["lightness"]);
|
||||||
const idHash = useMemo(() => id ? h64(id) : null, [id]);
|
const idHash = useMemo(() => h64(id), [id]);
|
||||||
|
|
||||||
return idHash && `hsl(${idHash % 360n}, 100%, ${lightness}%)`;
|
return `hsl(${idHash % 360n}, 100%, ${lightness}%)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
|
@ -41,25 +41,13 @@ const settings = definePluginSettings({
|
||||||
restartNeeded: true,
|
restartNeeded: true,
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
default: true
|
default: true
|
||||||
},
|
|
||||||
applyColorOnlyToUsersWithoutColor: {
|
|
||||||
description: "Apply colors only to users who don't have a predefined color",
|
|
||||||
restartNeeded: false,
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
applyColorOnlyInDms: {
|
|
||||||
description: "Apply colors only in direct messages; do not apply colors in servers.",
|
|
||||||
restartNeeded: false,
|
|
||||||
type: OptionType.BOOLEAN,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "IrcColors",
|
name: "IrcColors",
|
||||||
description: "Makes username colors in chat unique, like in IRC clients",
|
description: "Makes username colors in chat unique, like in IRC clients",
|
||||||
authors: [Devs.Grzesiek11, Devs.jamesbt365],
|
authors: [Devs.Grzesiek11],
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
|
@ -82,28 +70,16 @@ export default definePlugin({
|
||||||
|
|
||||||
calculateNameColorForMessageContext(context: any) {
|
calculateNameColorForMessageContext(context: any) {
|
||||||
const id = context?.message?.author?.id;
|
const id = context?.message?.author?.id;
|
||||||
const colorString = context?.author?.colorString;
|
if (id == null) {
|
||||||
const color = calculateNameColorForUser(id);
|
return null;
|
||||||
|
|
||||||
if (settings.store.applyColorOnlyInDms && !context?.channel?.isPrivate()) {
|
|
||||||
return colorString;
|
|
||||||
}
|
}
|
||||||
|
return calculateNameColorForUser(id);
|
||||||
return (!settings.store.applyColorOnlyToUsersWithoutColor || !colorString)
|
|
||||||
? color
|
|
||||||
: colorString;
|
|
||||||
},
|
},
|
||||||
calculateNameColorForListContext(context: any) {
|
calculateNameColorForListContext(context: any) {
|
||||||
const id = context?.user?.id;
|
const id = context?.user?.id;
|
||||||
const colorString = context?.colorString;
|
if (id == null) {
|
||||||
const color = calculateNameColorForUser(id);
|
return null;
|
||||||
|
|
||||||
if (settings.store.applyColorOnlyInDms && !context?.channel?.isPrivate()) {
|
|
||||||
return colorString;
|
|
||||||
}
|
}
|
||||||
|
return calculateNameColorForUser(id);
|
||||||
return (!settings.store.applyColorOnlyToUsersWithoutColor || !colorString)
|
|
||||||
? color
|
|
||||||
: colorString;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,24 @@
|
||||||
.messagelogger-deleted {
|
/* Message content highlighting */
|
||||||
--text-normal: var(--status-danger, #f04747);
|
.messagelogger-deleted [class*="contents"] > :is(div, h1, h2, h3, p) {
|
||||||
--interactive-normal: var(--status-danger, #f04747);
|
color: var(--status-danger, #f04747) !important;
|
||||||
--text-muted: var(--status-danger, #f04747);
|
}
|
||||||
--embed-title: var(--red-460, #be3535);
|
|
||||||
--text-link: var(--red-460, #be3535);
|
/* Markdown title highlighting */
|
||||||
--header-primary: var(--red-460, #be3535);
|
.messagelogger-deleted [class*="contents"] :is(h1, h2, h3) {
|
||||||
|
color: var(--status-danger, #f04747) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bot "thinking" text highlighting */
|
||||||
|
.messagelogger-deleted [class*="colorStandard"] {
|
||||||
|
color: var(--status-danger, #f04747) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embed highlighting */
|
||||||
|
.messagelogger-deleted article :is(div, span, h1, h2, h3, p) {
|
||||||
|
color: var(--status-danger, #f04747) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messagelogger-deleted a {
|
||||||
|
color: var(--red-460, #be3535) !important;
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,10 +442,15 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
// Attachment renderer
|
// Attachment renderer
|
||||||
find: ".removeMosaicItemHoverButton",
|
find: ".removeMosaicItemHoverButton",
|
||||||
|
group: true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /\[\i\.obscured\]:.+?,(?<=item:(\i).+?)/,
|
match: /(className:\i,item:\i),/,
|
||||||
replace: '$&"messagelogger-deleted-attachment":$1.originalItem?.deleted,'
|
replace: "$1,item: deleted,"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /\[\i\.obscured\]:.+?,/,
|
||||||
|
replace: "$& 'messagelogger-deleted-attachment': deleted,"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
.messagelogger-deleted
|
.messagelogger-deleted
|
||||||
:is(
|
:is(
|
||||||
.messagelogger-deleted-attachment,
|
video,
|
||||||
.emoji,
|
.emoji,
|
||||||
[data-type="sticker"],
|
[data-type="sticker"],
|
||||||
[class*="embedIframe"],
|
iframe,
|
||||||
[class*="embedSpotify"],
|
.messagelogger-deleted-attachment,
|
||||||
[class*="imageContainer"]
|
[class|="inlineMediaEmbed"]
|
||||||
) {
|
) {
|
||||||
filter: grayscale(1) !important;
|
filter: grayscale(1) !important;
|
||||||
transition: 150ms filter ease-in-out;
|
transition: 150ms filter ease-in-out;
|
||||||
|
@ -17,15 +17,19 @@
|
||||||
&[class*="hiddenMosaicItem_"] {
|
&[class*="hiddenMosaicItem_"] {
|
||||||
filter: grayscale(1) blur(var(--custom-message-attachment-spoiler-blur-radius, 44px)) !important;
|
filter: grayscale(1) blur(var(--custom-message-attachment-spoiler-blur-radius, 44px)) !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
.messagelogger-deleted
|
||||||
|
:is(
|
||||||
|
video,
|
||||||
|
.emoji,
|
||||||
|
[data-type="sticker"],
|
||||||
|
iframe,
|
||||||
|
.messagelogger-deleted-attachment,
|
||||||
|
[class|="inlineMediaEmbed"]
|
||||||
|
):hover {
|
||||||
filter: grayscale(0) !important;
|
filter: grayscale(0) !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.messagelogger-deleted [class*="spoilerWarning"] {
|
|
||||||
color: var(--status-danger);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .messagelogger-edited {
|
.theme-dark .messagelogger-edited {
|
||||||
filter: brightness(80%);
|
filter: brightness(80%);
|
||||||
|
|
|
@ -89,7 +89,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
// TODO(OptionType.CUSTOM Related): Remove DataStore tags migration once enough time has passed
|
// TODO: Remove DataStore tags migration once enough time has passed
|
||||||
const oldTags = await DataStore.get<Tag[]>(DATA_KEY);
|
const oldTags = await DataStore.get<Tag[]>(DATA_KEY);
|
||||||
if (oldTags != null) {
|
if (oldTags != null) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
42
src/plugins/noScreensharePreview/index.ts
Normal file
42
src/plugins/noScreensharePreview/index.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2022 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
|
const DisableStreamPreviews = getUserSettingLazy<boolean>("voiceAndVideo", "disableStreamPreviews")!;
|
||||||
|
|
||||||
|
// @TODO: Delete this plugin in the future
|
||||||
|
export default definePlugin({
|
||||||
|
name: "NoScreensharePreview",
|
||||||
|
description: "Disables screenshare previews from being sent.",
|
||||||
|
authors: [Devs.Nuckyz],
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (!DisableStreamPreviews.getSetting()) {
|
||||||
|
DisableStreamPreviews.updateSetting(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (DisableStreamPreviews.getSetting()) {
|
||||||
|
DisableStreamPreviews.updateSetting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -25,9 +25,9 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "ensureAudio(){",
|
find: "_ensureAudio(){",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?=Math\.min\(\i\.\i\.getOutputVolume\(\)\/100)/g,
|
match: /(?=Math\.min\(\i\.\i\.getOutputVolume\(\)\/100)/,
|
||||||
replace: "$self.settings.store.notificationVolume/100*"
|
replace: "$self.settings.store.notificationVolume/100*"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -100,7 +100,6 @@ export default definePlugin({
|
||||||
replace: "true"
|
replace: "true"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(!)?\(0,\i\.isDesktop\)\(\)/,
|
match: /(!)?\(0,\i\.isDesktop\)\(\)/,
|
||||||
replace: (_, not) => not ? "false" : "true"
|
replace: (_, not) => not ? "false" : "true"
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ export default definePlugin({
|
||||||
find: "#{intl::ONBOARDING_CHANNEL_THRESHOLD_WARNING}",
|
find: "#{intl::ONBOARDING_CHANNEL_THRESHOLD_WARNING}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /{(?:\i:(?:function\(\){return |\(\)=>)\i}?,?){2}}/,
|
match: /{(?:\i:(?:function\(\){return |\(\)=>)\i}?,?){2}}/,
|
||||||
replace: m => m.replaceAll(canonicalizeMatch(/(function\(\){return |\(\)=>)\i/g), "$1()=>Promise.resolve(true)")
|
replace: m => m.replaceAll(canonicalizeMatch(/(function\(\){return |\(\)=>)\i/g), "$1()=>Promise.resolve(true)")
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
|
||||||
src={user.getAvatarURL(void 0, void 0, false)}
|
src={user.getAvatarURL(void 0, void 0, false)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Text variant="text-md/normal" className={cl("modal-list-item-text")}>
|
<Text variant="text-md/normal">
|
||||||
{
|
{
|
||||||
permission.type === PermissionType.Role
|
permission.type === PermissionType.Role
|
||||||
? role?.name ?? "Unknown Role"
|
? role?.name ?? "Unknown Role"
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
background-color: var(--background-modifier-selected);
|
background-color: var(--background-modifier-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-permviewer-modal-list-item-text {
|
.vc-permviewer-modal-list-item > div {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
@ -155,7 +155,7 @@ export function moveChannel(channelId: string, direction: -1 | 1) {
|
||||||
swapElementsInArray(category.channels, a, b);
|
swapElementsInArray(category.channels, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(OptionType.CUSTOM Related): Remove DataStore PinnedDms migration once enough time has passed
|
// TODO: Remove DataStore PinnedDms migration once enough time has passed
|
||||||
async function migrateData() {
|
async function migrateData() {
|
||||||
if (Settings.plugins.PinDMs.dmSectioncollapsed != null) {
|
if (Settings.plugins.PinDMs.dmSectioncollapsed != null) {
|
||||||
settings.store.dmSectionCollapsed = Settings.plugins.PinDMs.dmSectioncollapsed;
|
settings.store.dmSectionCollapsed = Settings.plugins.PinDMs.dmSectioncollapsed;
|
||||||
|
|
|
@ -133,7 +133,7 @@ function getBadges({ userId }: BadgeUserArgs): ProfileBadge[] {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlatformIndicator = ({ user, small = false }: { user: User; small?: boolean; }) => {
|
const PlatformIndicator = ({ user, wantMargin = true, wantTopMargin = false, small = false }: { user: User; wantMargin?: boolean; wantTopMargin?: boolean; small?: boolean; }) => {
|
||||||
if (!user || user.bot) return null;
|
if (!user || user.bot) return null;
|
||||||
|
|
||||||
ensureOwnStatus(user);
|
ensureOwnStatus(user);
|
||||||
|
@ -155,7 +155,11 @@ const PlatformIndicator = ({ user, small = false }: { user: User; small?: boolea
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className="vc-platform-indicator"
|
className="vc-platform-indicator"
|
||||||
style={{ gap: "2px" }}
|
style={{
|
||||||
|
marginLeft: wantMargin ? 4 : 0,
|
||||||
|
top: wantTopMargin ? 2 : 0,
|
||||||
|
gap: 2
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{icons}
|
{icons}
|
||||||
</span>
|
</span>
|
||||||
|
@ -186,7 +190,7 @@ const indicatorLocations = {
|
||||||
description: "Inside messages",
|
description: "Inside messages",
|
||||||
onEnable: () => addMessageDecoration("platform-indicator", props =>
|
onEnable: () => addMessageDecoration("platform-indicator", props =>
|
||||||
<ErrorBoundary noop>
|
<ErrorBoundary noop>
|
||||||
<PlatformIndicator user={props.message?.author} />
|
<PlatformIndicator user={props.message?.author} wantTopMargin={true} />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
),
|
),
|
||||||
onDisable: () => removeMessageDecoration("platform-indicator")
|
onDisable: () => removeMessageDecoration("platform-indicator")
|
||||||
|
|
|
@ -39,7 +39,7 @@ function BlockedUser({ user, isBusy, setIsBusy }: { user: ReviewDBUser; isBusy:
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cl("block-modal-row")}>
|
<div className={cl("block-modal-row")}>
|
||||||
<img className={cl("block-modal-avatar")} src={user.profilePhoto} alt="" />
|
<img src={user.profilePhoto} alt="" />
|
||||||
<Forms.FormText className={cl("block-modal-username")}>{user.username}</Forms.FormText>
|
<Forms.FormText className={cl("block-modal-username")}>{user.username}</Forms.FormText>
|
||||||
<UnblockButton
|
<UnblockButton
|
||||||
onClick={isBusy ? undefined : async () => {
|
onClick={isBusy ? undefined : async () => {
|
||||||
|
|
|
@ -65,7 +65,7 @@ function Modal({ modalProps, modalKey, discordId, name, type }: { modalProps: an
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
||||||
<ModalFooter className={cl("modal-footer")}>
|
<ModalFooter className={cl("modal-footer")}>
|
||||||
<div className={cl("modal-footer-wrapper")}>
|
<div>
|
||||||
{ownReview && (
|
{ownReview && (
|
||||||
<ReviewComponent
|
<ReviewComponent
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
|
|
|
@ -16,11 +16,16 @@
|
||||||
border: 1px solid var(--profile-message-input-border-color);
|
border: 1px solid var(--profile-message-input-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-rdb-modal-footer-wrapper {
|
.vc-rdb-modal-footer > div {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 6px 16px;
|
margin: 6px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When input becomes disabled(while sending review), input adds unneccesary padding to left, this prevents it */
|
||||||
|
.vc-rdb-input > div > div {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.vc-rdb-placeholder {
|
.vc-rdb-placeholder {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -64,7 +69,7 @@
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-rdb-review-comment [class*="avatar"] {
|
.vc-rdb-review-comment img {
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +117,13 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-rdb-block-modal-avatar {
|
.vc-rdb-block-modal-row img {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 2em;
|
height: 2em;
|
||||||
width: 2em;
|
width: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-rdb-block-modal-avatar::before {
|
.vc-rdb-block-modal img::before {
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -68,16 +68,15 @@ function PickerModal({ rootProps, close }: { rootProps: ModalProps, close(): voi
|
||||||
return (
|
return (
|
||||||
<ModalRoot {...rootProps}>
|
<ModalRoot {...rootProps}>
|
||||||
<ModalHeader className={cl("modal-header")}>
|
<ModalHeader className={cl("modal-header")}>
|
||||||
<Forms.FormTitle tag="h2" className={cl("modal-title")}>
|
<Forms.FormTitle tag="h2">
|
||||||
Timestamp Picker
|
Timestamp Picker
|
||||||
</Forms.FormTitle>
|
</Forms.FormTitle>
|
||||||
|
|
||||||
<ModalCloseButton onClick={close} className={cl("modal-close-button")} />
|
<ModalCloseButton onClick={close} />
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
|
|
||||||
<ModalContent className={cl("modal-content")}>
|
<ModalContent className={cl("modal-content")}>
|
||||||
<input
|
<input
|
||||||
className={cl("date-picker")}
|
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={e => setValue(e.currentTarget.value)}
|
onChange={e => setValue(e.currentTarget.value)}
|
||||||
|
@ -87,7 +86,6 @@ function PickerModal({ rootProps, close }: { rootProps: ModalProps, close(): voi
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Forms.FormTitle>Timestamp Format</Forms.FormTitle>
|
<Forms.FormTitle>Timestamp Format</Forms.FormTitle>
|
||||||
<div className={cl("format-select")}>
|
|
||||||
<Select
|
<Select
|
||||||
options={
|
options={
|
||||||
Formats.map(m => ({
|
Formats.map(m => ({
|
||||||
|
@ -105,7 +103,6 @@ function PickerModal({ rootProps, close }: { rootProps: ModalProps, close(): voi
|
||||||
)}
|
)}
|
||||||
renderOptionValue={() => rendered}
|
renderOptionValue={() => rendered}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<Forms.FormTitle className={Margins.bottom8}>Preview</Forms.FormTitle>
|
<Forms.FormTitle className={Margins.bottom8}>Preview</Forms.FormTitle>
|
||||||
<Forms.FormText className={cl("preview-text")}>
|
<Forms.FormText className={cl("preview-text")}>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.vc-st-date-picker {
|
.vc-st-modal-content input {
|
||||||
background-color: var(--input-background);
|
background-color: var(--input-background);
|
||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
width: 95%;
|
width: 95%;
|
||||||
|
@ -12,28 +12,35 @@
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-st-format-select {
|
.vc-st-format-label,
|
||||||
margin-bottom: 1em;
|
.vc-st-format-label span {
|
||||||
|
background-color: transparent;
|
||||||
--background-modifier-accent: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-st-format-label {
|
.vc-st-modal-content [class|="select"] {
|
||||||
--background-modifier-accent: transparent;
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-st-modal-content [class|="select"] span {
|
||||||
|
background-color: var(--input-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-st-modal-header {
|
.vc-st-modal-header {
|
||||||
place-content: center space-between;
|
place-content: center space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-st-modal-title {
|
.vc-st-modal-header h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-st-modal-close-button {
|
.vc-st-modal-header button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-st-preview-text {
|
.vc-st-preview-text {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vc-st-button svg {
|
||||||
|
transform: scale(1.1) translateY(1px);
|
||||||
|
}
|
||||||
|
|
|
@ -94,7 +94,6 @@ function GuildInfoModal({ guild }: GuildProps) {
|
||||||
<div className={cl("header")}>
|
<div className={cl("header")}>
|
||||||
{iconUrl
|
{iconUrl
|
||||||
? <img
|
? <img
|
||||||
className={cl("icon")}
|
|
||||||
src={iconUrl}
|
src={iconUrl}
|
||||||
alt=""
|
alt=""
|
||||||
onClick={() => openImageModal({
|
onClick={() => openImageModal({
|
||||||
|
@ -171,7 +170,6 @@ function Owner(guildId: string, owner: User) {
|
||||||
return (
|
return (
|
||||||
<div className={cl("owner")}>
|
<div className={cl("owner")}>
|
||||||
<img
|
<img
|
||||||
className={cl("owner-avatar")}
|
|
||||||
src={ownerAvatarUrl}
|
src={ownerAvatarUrl}
|
||||||
alt=""
|
alt=""
|
||||||
onClick={() => openImageModal({
|
onClick={() => openImageModal({
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-gp-icon {
|
.vc-gp-header img {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
gap: 0.2em;
|
gap: 0.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-gp-owner-avatar {
|
.vc-gp-owner img {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -84,9 +84,9 @@ export const Code = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const codeTableRows = lines.map((line, i) => (
|
const codeTableRows = lines.map((line, i) => (
|
||||||
<tr className={cl("table-row")} key={i}>
|
<tr key={i}>
|
||||||
<td className={cl("table-cell")} style={{ color: theme.plainColor }}>{i + 1}</td>
|
<td style={{ color: theme.plainColor }}>{i + 1}</td>
|
||||||
<td className={cl("table-cell")}>{line}</td>
|
<td>{line}</td>
|
||||||
</tr>
|
</tr>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ export const Highlighter = ({
|
||||||
color: themeBase.plainColor,
|
color: themeBase.plainColor,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<code className={cl("code")}>
|
<code>
|
||||||
<Header
|
<Header
|
||||||
langName={langName}
|
langName={langName}
|
||||||
useDevIcon={useDevIcon}
|
useDevIcon={useDevIcon}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
.vc-shiki-container {
|
.shiki-container {
|
||||||
border: 4px;
|
border: 4px;
|
||||||
background-color: var(--background-secondary);
|
background-color: var(--background-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-root {
|
.shiki-root {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-root .vc-shiki-code {
|
.shiki-root code {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
@ -20,16 +20,16 @@
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-devicon {
|
.shiki-devicon {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-plain .vc-shiki-code {
|
.shiki-plain code {
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-btns {
|
.shiki-btns {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -37,25 +37,25 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-root:hover .vc-shiki-btns {
|
.shiki-root:hover .shiki-btns {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-btn {
|
.shiki-btn {
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-btn ~ .vc-shiki-btn {
|
.shiki-btn ~ .shiki-btn {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-btn:last-child {
|
.shiki-btn:last-child {
|
||||||
border-radius: 4px 0;
|
border-radius: 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-spinner-container {
|
.shiki-spinner-container {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: rgb(0 0 0 / 60%);
|
background-color: rgb(0 0 0 / 60%);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -64,11 +64,11 @@
|
||||||
inset: 0;
|
inset: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-preview {
|
.shiki-preview {
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-lang {
|
.shiki-lang {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -77,24 +77,24 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-table {
|
.shiki-table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-table-row {
|
.shiki-table tr {
|
||||||
height: 19px;
|
height: 19px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-root .vc-shiki-table-cell:first-child {
|
.shiki-root td:first-child {
|
||||||
border-right: 1px solid transparent;
|
border-right: 1px solid transparent;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shiki-root .vc-shiki-table-cell:last-child {
|
.shiki-root td:last-child {
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { resolveLang } from "../api/languages";
|
||||||
import { HighlighterProps } from "../components/Highlighter";
|
import { HighlighterProps } from "../components/Highlighter";
|
||||||
import { HljsSetting } from "../types";
|
import { HljsSetting } from "../types";
|
||||||
|
|
||||||
export const cl = classNameFactory("vc-shiki-");
|
export const cl = classNameFactory("shiki-");
|
||||||
|
|
||||||
export const shouldUseHljs = ({
|
export const shouldUseHljs = ({
|
||||||
lang,
|
lang,
|
||||||
|
|
|
@ -33,7 +33,6 @@ export function VerifiedIcon() {
|
||||||
forcedIconColor={forcedIconColor}
|
forcedIconColor={forcedIconColor}
|
||||||
size={16}
|
size={16}
|
||||||
tooltipText={getIntlMessage("CONNECTION_VERIFIED")}
|
tooltipText={getIntlMessage("CONNECTION_VERIFIED")}
|
||||||
className="vc-sc-tooltip-icon"
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ function CompactConnectionComponent({ connection, theme }: { connection: Connect
|
||||||
<span className="vc-sc-tooltip">
|
<span className="vc-sc-tooltip">
|
||||||
<span className="vc-sc-connection-name">{connection.name}</span>
|
<span className="vc-sc-connection-name">{connection.name}</span>
|
||||||
{connection.verified && <VerifiedIcon />}
|
{connection.verified && <VerifiedIcon />}
|
||||||
<TooltipIcon height={16} width={16} className="vc-sc-tooltip-icon" />
|
<TooltipIcon height={16} width={16} />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
key={connection.id}
|
key={connection.id}
|
||||||
|
|
|
@ -14,6 +14,6 @@
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-sc-tooltip-icon {
|
.vc-sc-tooltip svg {
|
||||||
min-width: 16px;
|
min-width: 16px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { classes } from "@utils/misc";
|
|
||||||
import { formatDuration } from "@utils/text";
|
import { formatDuration } from "@utils/text";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
||||||
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
|
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
|
||||||
|
@ -26,7 +25,7 @@ import type { Channel } from "discord-types/general";
|
||||||
|
|
||||||
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "../../permissionsViewer/components/RolesAndUsersPermissions";
|
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "../../permissionsViewer/components/RolesAndUsersPermissions";
|
||||||
import { sortPermissionOverwrites } from "../../permissionsViewer/utils";
|
import { sortPermissionOverwrites } from "../../permissionsViewer/utils";
|
||||||
import { cl, settings } from "..";
|
import { settings } from "..";
|
||||||
|
|
||||||
const enum SortOrderTypes {
|
const enum SortOrderTypes {
|
||||||
LATEST_ACTIVITY = 0,
|
LATEST_ACTIVITY = 0,
|
||||||
|
@ -169,19 +168,19 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
}, [channelId]);
|
}, [channelId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes(ChatScrollClasses.auto, ChatScrollClasses.customTheme, ChatScrollClasses.managedReactiveScroller)}>
|
<div className={ChatScrollClasses.auto + " " + ChatScrollClasses.customTheme + " " + ChatClasses.chatContent + " " + "shc-lock-screen-outer-container"}>
|
||||||
<div className={cl("container")}>
|
<div className="shc-lock-screen-container">
|
||||||
<img className={cl("logo")} src={HiddenChannelLogo} />
|
<img className="shc-lock-screen-logo" src={HiddenChannelLogo} />
|
||||||
|
|
||||||
<div className={cl("heading-container")}>
|
<div className="shc-lock-screen-heading-container">
|
||||||
<Text variant="heading-xxl/bold">This is a {!PermissionStore.can(PermissionsBits.VIEW_CHANNEL, channel) ? "hidden" : "locked"} {ChannelTypesToChannelNames[type]} channel</Text>
|
<Text variant="heading-xxl/bold">This is a {!PermissionStore.can(PermissionsBits.VIEW_CHANNEL, channel) ? "hidden" : "locked"} {ChannelTypesToChannelNames[type]} channel.</Text>
|
||||||
{channel.isNSFW() &&
|
{channel.isNSFW() &&
|
||||||
<Tooltip text="NSFW">
|
<Tooltip text="NSFW">
|
||||||
{({ onMouseLeave, onMouseEnter }) => (
|
{({ onMouseLeave, onMouseEnter }) => (
|
||||||
<svg
|
<svg
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
className={cl("heading-nsfw-icon")}
|
className="shc-lock-screen-heading-nsfw-icon"
|
||||||
width="32"
|
width="32"
|
||||||
height="32"
|
height="32"
|
||||||
viewBox="0 0 48 48"
|
viewBox="0 0 48 48"
|
||||||
|
@ -203,7 +202,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{channel.isForumChannel() && topic && topic.length > 0 && (
|
{channel.isForumChannel() && topic && topic.length > 0 && (
|
||||||
<div className={cl("topic-container")}>
|
<div className="shc-lock-screen-topic-container">
|
||||||
{Parser.parseTopic(topic, false, { channelId })}
|
{Parser.parseTopic(topic, false, { channelId })}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -214,6 +213,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
<Timestamp timestamp={new Date(SnowflakeUtils.extractTimestamp(lastMessageId))} />
|
<Timestamp timestamp={new Date(SnowflakeUtils.extractTimestamp(lastMessageId))} />
|
||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
|
|
||||||
{lastPinTimestamp &&
|
{lastPinTimestamp &&
|
||||||
<Text variant="text-md/normal">Last message pin: <Timestamp timestamp={new Date(lastPinTimestamp)} /></Text>
|
<Text variant="text-md/normal">Last message pin: <Timestamp timestamp={new Date(lastPinTimestamp)} /></Text>
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
<Text variant="text-md/normal">Default sort order: {SortOrderTypesToNames[defaultSortOrder]}</Text>
|
<Text variant="text-md/normal">Default sort order: {SortOrderTypesToNames[defaultSortOrder]}</Text>
|
||||||
}
|
}
|
||||||
{defaultReactionEmoji != null &&
|
{defaultReactionEmoji != null &&
|
||||||
<div className={cl("default-emoji-container")}>
|
<div className="shc-lock-screen-default-emoji-container">
|
||||||
<Text variant="text-md/normal">Default reaction emoji:</Text>
|
<Text variant="text-md/normal">Default reaction emoji:</Text>
|
||||||
{Parser.defaultRules[defaultReactionEmoji.emojiName ? "emoji" : "customEmoji"].react({
|
{Parser.defaultRules[defaultReactionEmoji.emojiName ? "emoji" : "customEmoji"].react({
|
||||||
name: defaultReactionEmoji.emojiName
|
name: defaultReactionEmoji.emojiName
|
||||||
|
@ -258,29 +258,29 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
src: defaultReactionEmoji.emojiName
|
src: defaultReactionEmoji.emojiName
|
||||||
? EmojiUtils.getURL(defaultReactionEmoji.emojiName)
|
? EmojiUtils.getURL(defaultReactionEmoji.emojiName)
|
||||||
: void 0
|
: void 0
|
||||||
}, void 0, { key: 0 })}
|
}, void 0, { key: "0" })}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{channel.hasFlag(ChannelFlags.REQUIRE_TAG) &&
|
{channel.hasFlag(ChannelFlags.REQUIRE_TAG) &&
|
||||||
<Text variant="text-md/normal">Posts on this forum require a tag to be set.</Text>
|
<Text variant="text-md/normal">Posts on this forum require a tag to be set.</Text>
|
||||||
}
|
}
|
||||||
{availableTags && availableTags.length > 0 &&
|
{availableTags && availableTags.length > 0 &&
|
||||||
<div className={cl("tags-container")}>
|
<div className="shc-lock-screen-tags-container">
|
||||||
<Text variant="text-lg/bold">Available tags:</Text>
|
<Text variant="text-lg/bold">Available tags:</Text>
|
||||||
<div className={cl("tags")}>
|
<div className="shc-lock-screen-tags">
|
||||||
{availableTags.map(tag => <TagComponent tag={tag} key={tag.id} />)}
|
{availableTags.map(tag => <TagComponent tag={tag} key={tag.id} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div className={cl("allowed-users-and-roles-container")}>
|
<div className="shc-lock-screen-allowed-users-and-roles-container">
|
||||||
<div className={cl("allowed-users-and-roles-container-title")}>
|
<div className="shc-lock-screen-allowed-users-and-roles-container-title">
|
||||||
{Vencord.Plugins.isPluginEnabled("PermissionsViewer") && (
|
{Settings.plugins.PermissionsViewer.enabled && (
|
||||||
<Tooltip text="Permission Details">
|
<Tooltip text="Permission Details">
|
||||||
{({ onMouseLeave, onMouseEnter }) => (
|
{({ onMouseLeave, onMouseEnter }) => (
|
||||||
<button
|
<button
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
className={cl("allowed-users-and-roles-container-permdetails-btn")}
|
className="shc-lock-screen-allowed-users-and-roles-container-permdetails-btn"
|
||||||
onClick={() => openRolesAndUsersPermissionsModal(permissions, GuildStore.getGuild(channel.guild_id), channel.name)}
|
onClick={() => openRolesAndUsersPermissionsModal(permissions, GuildStore.getGuild(channel.guild_id), channel.name)}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -300,7 +300,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
<button
|
<button
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
className={cl("allowed-users-and-roles-container-toggle-btn")}
|
className="shc-lock-screen-allowed-users-and-roles-container-toggle-btn"
|
||||||
onClick={() => settings.store.defaultAllowedUsersAndRolesDropdownState = !defaultAllowedUsersAndRolesDropdownState}
|
onClick={() => settings.store.defaultAllowedUsersAndRolesDropdownState = !defaultAllowedUsersAndRolesDropdownState}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
|
|
@ -19,10 +19,8 @@
|
||||||
import "./style.css";
|
import "./style.css";
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { classes } from "@utils/misc";
|
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
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";
|
||||||
|
@ -33,8 +31,6 @@ import HiddenChannelLockScreen from "./components/HiddenChannelLockScreen";
|
||||||
|
|
||||||
const ChannelListClasses = findByPropsLazy("modeMuted", "modeSelected", "unread", "icon");
|
const ChannelListClasses = findByPropsLazy("modeMuted", "modeSelected", "unread", "icon");
|
||||||
|
|
||||||
export const cl = classNameFactory("vc-shc-");
|
|
||||||
|
|
||||||
const enum ShowMode {
|
const enum ShowMode {
|
||||||
LockIcon,
|
LockIcon,
|
||||||
HiddenIconWithMutedStyle
|
HiddenIconWithMutedStyle
|
||||||
|
@ -112,7 +108,6 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Prevent Discord from trying to connect to hidden voice channels
|
// Prevent Discord from trying to connect to hidden voice channels
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(?=(\|\||&&)\i\.\i\.selectVoiceChannel\((\i)\.id\))/,
|
match: /(?=(\|\||&&)\i\.\i\.selectVoiceChannel\((\i)\.id\))/,
|
||||||
replace: (_, condition, channel) => condition === "||"
|
replace: (_, condition, channel) => condition === "||"
|
||||||
? `||$self.isHiddenChannel(${channel})`
|
? `||$self.isHiddenChannel(${channel})`
|
||||||
|
@ -129,7 +124,6 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".AUDIENCE),{isSubscriptionGated",
|
find: ".AUDIENCE),{isSubscriptionGated",
|
||||||
replacement: {
|
replacement: {
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(!)?(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/,
|
match: /(!)?(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/,
|
||||||
replace: (m, not, channel) => not
|
replace: (m, not, channel) => not
|
||||||
? `${m}&&!$self.isHiddenChannel(${channel})`
|
? `${m}&&!$self.isHiddenChannel(${channel})`
|
||||||
|
@ -183,7 +177,6 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// Make voice channels also appear as muted if they are muted
|
// Make voice channels also appear as muted if they are muted
|
||||||
{
|
{
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(?<=\.wrapper:\i\.notInteractive,)(.+?)(if\()?(\i)(?:\)return |\?)(\i\.MUTED)/,
|
match: /(?<=\.wrapper:\i\.notInteractive,)(.+?)(if\()?(\i)(?:\)return |\?)(\i\.MUTED)/,
|
||||||
replace: (_, otherClasses, isIf, isMuted, mutedClassExpression) => isIf
|
replace: (_, otherClasses, isIf, isMuted, mutedClassExpression) => isIf
|
||||||
? `${isMuted}?${mutedClassExpression}:"",${otherClasses}if(${isMuted})return ""`
|
? `${isMuted}?${mutedClassExpression}:"",${otherClasses}if(${isMuted})return ""`
|
||||||
|
@ -197,7 +190,6 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
// Make muted channels also appear as unread if hide unreads is false, using the HiddenIconWithMutedStyle and the channel is hidden
|
// Make muted channels also appear as unread if hide unreads is false, using the HiddenIconWithMutedStyle and the channel is hidden
|
||||||
predicate: () => settings.store.hideUnreads === false && settings.store.showMode === ShowMode.HiddenIconWithMutedStyle,
|
predicate: () => settings.store.hideUnreads === false && settings.store.showMode === ShowMode.HiddenIconWithMutedStyle,
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
|
||||||
match: /(?<=\.LOCKED(?:;if\(|:))(?<={channel:(\i).+?)/,
|
match: /(?<=\.LOCKED(?:;if\(|:))(?<={channel:(\i).+?)/,
|
||||||
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
||||||
},
|
},
|
||||||
|
@ -553,7 +545,7 @@ export default definePlugin({
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
<path fill="currentcolor" fillRule="evenodd" d="M17 11V7C17 4.243 14.756 2 12 2C9.242 2 7 4.243 7 7V11C5.897 11 5 11.896 5 13V20C5 21.103 5.897 22 7 22H17C18.103 22 19 21.103 19 20V13C19 11.896 18.103 11 17 11ZM12 18C11.172 18 10.5 17.328 10.5 16.5C10.5 15.672 11.172 15 12 15C12.828 15 13.5 15.672 13.5 16.5C13.5 17.328 12.828 18 12 18ZM15 11H9V7C9 5.346 10.346 4 12 4C13.654 4 15 5.346 15 7V11Z" />
|
<path className="shc-evenodd-fill-current-color" d="M17 11V7C17 4.243 14.756 2 12 2C9.242 2 7 4.243 7 7V11C5.897 11 5 11.896 5 13V20C5 21.103 5.897 22 7 22H17C18.103 22 19 21.103 19 20V13C19 11.896 18.103 11 17 11ZM12 18C11.172 18 10.5 17.328 10.5 16.5C10.5 15.672 11.172 15 12 15C12.828 15 13.5 15.672 13.5 16.5C13.5 17.328 12.828 18 12 18ZM15 11H9V7C9 5.346 10.346 4 12 4C13.654 4 15 5.346 15 7V11Z" />
|
||||||
</svg>
|
</svg>
|
||||||
), { noop: true }),
|
), { noop: true }),
|
||||||
|
|
||||||
|
@ -563,14 +555,14 @@ export default definePlugin({
|
||||||
<svg
|
<svg
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
className={classes(ChannelListClasses.icon, cl("hidden-channel-icon"))}
|
className={ChannelListClasses.icon + " " + "shc-hidden-channel-icon"}
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
<path fill="currentcolor" fillRule="evenodd" d="m19.8 22.6-4.2-4.15q-.875.275-1.762.413Q12.95 19 12 19q-3.775 0-6.725-2.087Q2.325 14.825 1 11.5q.525-1.325 1.325-2.463Q3.125 7.9 4.15 7L1.4 4.2l1.4-1.4 18.4 18.4ZM12 16q.275 0 .512-.025.238-.025.513-.1l-5.4-5.4q-.075.275-.1.513-.025.237-.025.512 0 1.875 1.312 3.188Q10.125 16 12 16Zm7.3.45-3.175-3.15q.175-.425.275-.862.1-.438.1-.938 0-1.875-1.312-3.188Q13.875 7 12 7q-.5 0-.938.1-.437.1-.862.3L7.65 4.85q1.025-.425 2.1-.638Q10.825 4 12 4q3.775 0 6.725 2.087Q21.675 8.175 23 11.5q-.575 1.475-1.512 2.738Q20.55 15.5 19.3 16.45Zm-4.625-4.6-3-3q.7-.125 1.288.112.587.238 1.012.688.425.45.613 1.038.187.587.087 1.162Z" />
|
<path className="shc-evenodd-fill-current-color" d="m19.8 22.6-4.2-4.15q-.875.275-1.762.413Q12.95 19 12 19q-3.775 0-6.725-2.087Q2.325 14.825 1 11.5q.525-1.325 1.325-2.463Q3.125 7.9 4.15 7L1.4 4.2l1.4-1.4 18.4 18.4ZM12 16q.275 0 .512-.025.238-.025.513-.1l-5.4-5.4q-.075.275-.1.513-.025.237-.025.512 0 1.875 1.312 3.188Q10.125 16 12 16Zm7.3.45-3.175-3.15q.175-.425.275-.862.1-.438.1-.938 0-1.875-1.312-3.188Q13.875 7 12 7q-.5 0-.938.1-.437.1-.862.3L7.65 4.85q1.025-.425 2.1-.638Q10.825 4 12 4q3.775 0 6.725 2.087Q21.675 8.175 23 11.5q-.575 1.475-1.512 2.738Q20.55 15.5 19.3 16.45Zm-4.625-4.6-3-3q.7-.125 1.288.112.587.238 1.012.688.425.45.613 1.038.187.587.087 1.162Z" />
|
||||||
</svg>
|
</svg>
|
||||||
)}
|
)}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
@ -1,31 +1,43 @@
|
||||||
.vc-shc-container {
|
.shc-lock-screen-outer-container {
|
||||||
|
overflow: hidden scroll;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
gap: 0.65em;
|
|
||||||
margin: 0.5em 0;
|
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-logo {
|
.shc-lock-screen-container > * {
|
||||||
width: 12em;
|
margin: 5px;
|
||||||
height: 12em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-heading-container {
|
.shc-lock-screen-logo {
|
||||||
|
width: 180px;
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-heading-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-heading-nsfw-icon {
|
.shc-lock-screen-heading-container > * {
|
||||||
|
margin: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-heading-nsfw-icon {
|
||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-topic-container {
|
.shc-lock-screen-topic-container {
|
||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
background: var(--bg-overlay-3, var(--background-secondary));
|
background: var(--bg-overlay-3, var(--background-secondary));
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -33,75 +45,91 @@
|
||||||
max-width: 70vw;
|
max-width: 70vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-default-emoji-container {
|
.shc-lock-screen-tags-container {
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
background: var(--bg-overlay-3, var(--background-secondary));
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 0.75em;
|
|
||||||
margin-left: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-shc-tags-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: var(--bg-overlay-3, var(--background-secondary));
|
background: var(--bg-overlay-3, var(--background-secondary));
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 0.75em;
|
padding: 10px;
|
||||||
gap: 0.75em;
|
|
||||||
max-width: 70vw;
|
max-width: 70vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-tags {
|
.shc-lock-screen-tags-container > * {
|
||||||
|
margin: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 0.35em;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-allowed-users-and-roles-container {
|
.shc-evenodd-fill-current-color {
|
||||||
display: flex;
|
fill-rule: evenodd;
|
||||||
flex-direction: column;
|
fill: currentcolor;
|
||||||
align-items: center;
|
|
||||||
background: var(--bg-overlay-3, var(--background-secondary));
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 0.75em;
|
|
||||||
max-width: 70vw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-shc-allowed-users-and-roles-container-title {
|
.shc-hidden-channel-icon {
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-shc-allowed-users-and-roles-container-toggle-btn {
|
|
||||||
all: unset;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--text-normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-shc-allowed-users-and-roles-container-permdetails-btn {
|
|
||||||
all: unset;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--text-normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-shc-allowed-users-and-roles-container > [class^="members"] {
|
|
||||||
margin-left: 12px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vc-shc-hidden-channel-icon {
|
|
||||||
cursor: not-allowed;
|
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-default-emoji-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-default-emoji-container > [class^="emojiContainer"] {
|
||||||
|
background: var(--bg-overlay-3, var(--background-secondary));
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 5px 6px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--bg-overlay-3, var(--background-secondary));
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
max-width: 70vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container-title {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container-toggle-btn {
|
||||||
|
all: unset;
|
||||||
|
margin-left: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container-toggle-btn > svg {
|
||||||
|
color: var(--text-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container-permdetails-btn {
|
||||||
|
all: unset;
|
||||||
|
margin-right: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container-permdetails-btn > svg {
|
||||||
|
color: var(--text-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shc-lock-screen-allowed-users-and-roles-container > [class^="members"] {
|
||||||
|
margin-left: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
import "./spotifyStyles.css";
|
import "./spotifyStyles.css";
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { ImageIcon, LinkIcon, OpenExternalIcon } from "@components/Icons";
|
import { ImageIcon, LinkIcon, OpenExternalIcon } from "@components/Icons";
|
||||||
import { debounce } from "@shared/debounce";
|
import { debounce } from "@shared/debounce";
|
||||||
|
@ -29,7 +28,7 @@ import { ContextMenuApi, FluxDispatcher, Forms, Menu, React, useEffect, useState
|
||||||
|
|
||||||
import { SpotifyStore, Track } from "./SpotifyStore";
|
import { SpotifyStore, Track } from "./SpotifyStore";
|
||||||
|
|
||||||
const cl = classNameFactory("vc-spotify-");
|
const cl = (className: string) => `vc-spotify-${className}`;
|
||||||
|
|
||||||
function msToHuman(ms: number) {
|
function msToHuman(ms: number) {
|
||||||
const minutes = ms / 1000 / 60;
|
const minutes = ms / 1000 / 60;
|
||||||
|
@ -41,7 +40,7 @@ function msToHuman(ms: number) {
|
||||||
function Svg(path: string, label: string) {
|
function Svg(path: string, label: string) {
|
||||||
return () => (
|
return () => (
|
||||||
<svg
|
<svg
|
||||||
className={cl("button-icon", label)}
|
className={classes(cl("button-icon"), cl(label))}
|
||||||
height="24"
|
height="24"
|
||||||
width="24"
|
width="24"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
@ -127,7 +126,7 @@ function Controls() {
|
||||||
return (
|
return (
|
||||||
<Flex className={cl("button-row")} style={{ gap: 0 }}>
|
<Flex className={cl("button-row")} style={{ gap: 0 }}>
|
||||||
<Button
|
<Button
|
||||||
className={classes(cl("button"), cl("shuffle"), cl(shuffle ? "shuffle-on" : "shuffle-off"))}
|
className={classes(cl("button"), cl(shuffle ? "shuffle-on" : "shuffle-off"))}
|
||||||
onClick={() => SpotifyStore.setShuffle(!shuffle)}
|
onClick={() => SpotifyStore.setShuffle(!shuffle)}
|
||||||
>
|
>
|
||||||
<Shuffle />
|
<Shuffle />
|
||||||
|
@ -144,7 +143,7 @@ function Controls() {
|
||||||
<SkipNext />
|
<SkipNext />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={classes(cl("button"), cl("repeat"), cl(repeatClassName))}
|
className={classes(cl("button"), cl(repeatClassName))}
|
||||||
onClick={() => SpotifyStore.setRepeat(nextRepeat)}
|
onClick={() => SpotifyStore.setRepeat(nextRepeat)}
|
||||||
style={{ position: "relative" }}
|
style={{ position: "relative" }}
|
||||||
>
|
>
|
||||||
|
@ -286,8 +285,7 @@ function Info({ track }: { track: Track; }) {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (coverExpanded && img)
|
if (coverExpanded && img) return (
|
||||||
return (
|
|
||||||
<div id={cl("album-expanded-wrapper")}>
|
<div id={cl("album-expanded-wrapper")}>
|
||||||
{i}
|
{i}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -30,17 +30,22 @@
|
||||||
background-color: var(--background-modifier-selected);
|
background-color: var(--background-modifier-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-spotify-button-icon {
|
.vc-spotify-button svg {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-spotify-shuffle .vc-spotify-button-icon,
|
[class*="vc-spotify-shuffle"] > svg,
|
||||||
.vc-spotify-repeat .vc-spotify-button-icon {
|
[class*="vc-spotify-repeat"] > svg {
|
||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vc-spotify-button svg path {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* .vc-spotify-button:hover {
|
/* .vc-spotify-button:hover {
|
||||||
filter: brightness(1.3);
|
filter: brightness(1.3);
|
||||||
} */
|
} */
|
||||||
|
@ -82,19 +87,12 @@
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vc-spotify-album-image {
|
#vc-spotify-info-wrapper img {
|
||||||
height: 90%;
|
height: 90%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
border-radius: 3px;
|
|
||||||
transition: filter 0.2s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#vc-spotify-album-image:hover {
|
#vc-spotify-album-expanded-wrapper img {
|
||||||
filter: brightness(1.2);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#vc-spotify-album-expanded-wrapper #vc-spotify-album-image {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
@ -139,6 +137,16 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#vc-spotify-album-image {
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: filter 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-album-image:hover {
|
||||||
|
filter: brightness(1.2);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
#vc-spotify-progress-bar {
|
#vc-spotify-progress-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
|
|
|
@ -244,7 +244,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
// TODO(OptionType.CUSTOM Related): Remove DataStore rules migrations once enough time has passed
|
// TODO: Remove DataStore rules migrations once enough time has passed
|
||||||
const oldStringRules = await DataStore.get<Rule[]>(STRING_RULES_KEY);
|
const oldStringRules = await DataStore.get<Rule[]>(STRING_RULES_KEY);
|
||||||
if (oldStringRules != null) {
|
if (oldStringRules != null) {
|
||||||
settings.store.stringRules = oldStringRules;
|
settings.store.stringRules = oldStringRules;
|
||||||
|
|
|
@ -76,7 +76,7 @@ export function TranslateModal({ rootProps }: { rootProps: ModalProps; }) {
|
||||||
return (
|
return (
|
||||||
<ModalRoot {...rootProps}>
|
<ModalRoot {...rootProps}>
|
||||||
<ModalHeader className={cl("modal-header")}>
|
<ModalHeader className={cl("modal-header")}>
|
||||||
<Forms.FormTitle tag="h2" className={cl("modal-title")}>
|
<Forms.FormTitle tag="h2">
|
||||||
Translate
|
Translate
|
||||||
</Forms.FormTitle>
|
</Forms.FormTitle>
|
||||||
<ModalCloseButton onClick={rootProps.onClose} />
|
<ModalCloseButton onClick={rootProps.onClose} />
|
||||||
|
|
|
@ -55,7 +55,7 @@ export function TranslationAccessory({ message }: { message: Message; }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className={cl("accessory")}>
|
<span className={cl("accessory")}>
|
||||||
<TranslateIcon width={16} height={16} className={cl("accessory-icon")} />
|
<TranslateIcon width={16} height={16} />
|
||||||
{Parser.parse(translation.text)}
|
{Parser.parse(translation.text)}
|
||||||
{" "}
|
{" "}
|
||||||
(translated from {translation.sourceLanguage} - <Dismiss onDismiss={() => setTranslation(undefined)} />)
|
(translated from {translation.sourceLanguage} - <Dismiss onDismiss={() => setTranslation(undefined)} />)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
place-content: center space-between;
|
place-content: center space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-trans-modal-title {
|
.vc-trans-modal-header h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-trans-accessory-icon {
|
.vc-trans-accessory svg {
|
||||||
margin-right: 0.25em;
|
margin-right: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,13 +130,15 @@ function VoiceChannelTooltip({ channel, isLocked }: VoiceChannelTooltipProps) {
|
||||||
|
|
||||||
interface VoiceChannelIndicatorProps {
|
interface VoiceChannelIndicatorProps {
|
||||||
userId: string;
|
userId: string;
|
||||||
|
isMessageIndicator?: boolean;
|
||||||
|
isProfile?: boolean;
|
||||||
isActionButton?: boolean;
|
isActionButton?: boolean;
|
||||||
shouldHighlight?: boolean;
|
shouldHighlight?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clickTimers = {} as Record<string, any>;
|
const clickTimers = {} as Record<string, any>;
|
||||||
|
|
||||||
export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId, isActionButton, shouldHighlight }: VoiceChannelIndicatorProps) => {
|
export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId, isMessageIndicator, isProfile, isActionButton, shouldHighlight }: VoiceChannelIndicatorProps) => {
|
||||||
const channelId = useStateFromStores([VoiceStateStore], () => VoiceStateStore.getVoiceStateForUser(userId)?.channelId as string | undefined);
|
const channelId = useStateFromStores([VoiceStateStore], () => VoiceStateStore.getVoiceStateForUser(userId)?.channelId as string | undefined);
|
||||||
|
|
||||||
const channel = channelId == null ? undefined : ChannelStore.getChannel(channelId);
|
const channel = channelId == null ? undefined : ChannelStore.getChannel(channelId);
|
||||||
|
@ -180,7 +182,7 @@ export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId, isActionButto
|
||||||
{props => {
|
{props => {
|
||||||
const iconProps: IconProps = {
|
const iconProps: IconProps = {
|
||||||
...props,
|
...props,
|
||||||
className: classes(isActionButton && ActionButtonClasses.actionButton, shouldHighlight && ActionButtonClasses.highlight),
|
className: classes(isMessageIndicator && cl("message-indicator"), (!isProfile && !isActionButton) && cl("speaker-margin"), isActionButton && ActionButtonClasses.actionButton, shouldHighlight && ActionButtonClasses.highlight),
|
||||||
size: isActionButton ? 20 : undefined,
|
size: isActionButton ? 20 : undefined,
|
||||||
onClick
|
onClick
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,7 +60,7 @@ export default definePlugin({
|
||||||
find: "#{intl::USER_PROFILE_LOAD_ERROR}",
|
find: "#{intl::USER_PROFILE_LOAD_ERROR}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(\.fetchError.+?\?)null/,
|
match: /(\.fetchError.+?\?)null/,
|
||||||
replace: (_, rest) => `${rest}$self.VoiceChannelIndicator({userId:arguments[0]?.userId})`
|
replace: (_, rest) => `${rest}$self.VoiceChannelIndicator({userId:arguments[0]?.userId,isProfile:true})`
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.showInUserProfileModal
|
predicate: () => settings.store.showInUserProfileModal
|
||||||
},
|
},
|
||||||
|
@ -99,7 +99,7 @@ export default definePlugin({
|
||||||
addMemberListDecorator("UserVoiceShow", ({ user }) => user == null ? null : <VoiceChannelIndicator userId={user.id} />);
|
addMemberListDecorator("UserVoiceShow", ({ user }) => user == null ? null : <VoiceChannelIndicator userId={user.id} />);
|
||||||
}
|
}
|
||||||
if (settings.store.showInMessages) {
|
if (settings.store.showInMessages) {
|
||||||
addMessageDecoration("UserVoiceShow", ({ message }) => message?.author == null ? null : <VoiceChannelIndicator userId={message.author.id} />);
|
addMessageDecoration("UserVoiceShow", ({ message }) => message?.author == null ? null : <VoiceChannelIndicator userId={message.author.id} isMessageIndicator />);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,16 @@
|
||||||
color: var(--interactive-hover);
|
color: var(--interactive-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vc-uvs-speaker-margin {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-uvs-message-indicator {
|
||||||
|
display: inline-flex;
|
||||||
|
top: 2.5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.vc-uvs-tooltip-container {
|
.vc-uvs-tooltip-container {
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
12
src/plugins/usrbg/index.css
Normal file
12
src/plugins/usrbg/index.css
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:is([class*="userProfile"], [class*="userPopout"]) [class*="bannerPremium"] {
|
||||||
|
background: center / cover no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="NonPremium"]:has([class*="bannerPremium"]) [class*="avatarPositionNormal"],
|
||||||
|
[class*="PremiumWithoutBanner"]:has([class*="bannerPremium"]) [class*="avatarPositionPremiumNoBanner"] {
|
||||||
|
top: 76px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[style*="background-image"] [class*="background_"] {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
|
@ -17,10 +17,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { enableStyle } from "@api/Styles";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
|
import style from "./index.css?managed";
|
||||||
|
|
||||||
const API_URL = "https://usrbg.is-hardly.online/users";
|
const API_URL = "https://usrbg.is-hardly.online/users";
|
||||||
|
|
||||||
interface UsrbgApiReturn {
|
interface UsrbgApiReturn {
|
||||||
|
@ -112,6 +115,8 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
|
enableStyle(style);
|
||||||
|
|
||||||
const res = await fetch(API_URL);
|
const res = await fetch(API_URL);
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
this.data = await res.json();
|
this.data = await res.json();
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
.vc-toolbox-btn,
|
.vc-toolbox-btn,
|
||||||
.vc-toolbox-icon {
|
.vc-toolbox-btn>svg {
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-toolbox-icon {
|
.vc-toolbox-btn>svg {
|
||||||
color: var(--interactive-normal);
|
color: var(--interactive-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-toolbox-btn[class*="selected"] .vc-toolbox-icon {
|
.vc-toolbox-btn[class*="selected"]>svg {
|
||||||
color: var(--interactive-active);
|
color: var(--interactive-active);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-toolbox-btn:hover .vc-toolbox-icon {
|
.vc-toolbox-btn:hover>svg {
|
||||||
color: var(--interactive-hover);
|
color: var(--interactive-hover);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ function VencordPopout(onClose: () => void) {
|
||||||
|
|
||||||
function VencordPopoutIcon(isShown: boolean) {
|
function VencordPopoutIcon(isShown: boolean) {
|
||||||
return (
|
return (
|
||||||
<svg viewBox="0 0 27 27" width={24} height={24} className="vc-toolbox-icon">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 27 27" width={24} height={24}>
|
||||||
<path fill="currentColor" d={isShown ? "M9 0h1v1h1v2h1v2h3V3h1V1h1V0h1v2h1v2h1v7h-1v-1h-3V9h1V6h-1v4h-3v1h1v-1h2v1h3v1h-1v1h-3v2h1v1h1v1h1v3h-1v4h-2v-1h-1v-4h-1v4h-1v1h-2v-4H9v-3h1v-1h1v-1h1v-2H9v-1H8v-1h3V6h-1v3h1v1H8v1H7V4h1V2h1M5 19h2v1h1v1h1v3H4v-1h2v-1H4v-2h1m15-1h2v1h1v2h-2v1h2v1h-5v-3h1v-1h1m4 3h4v1h-4" : "M0 0h7v1H6v1H5v1H4v1H3v1H2v1h5v1H0V6h1V5h1V4h1V3h1V2h1V1H0m13 2h5v1h-1v1h-1v1h-1v1h3v1h-5V7h1V6h1V5h1V4h-3m8 5h1v5h1v-1h1v1h-1v1h1v-1h1v1h-1v3h-1v1h-2v1h-1v1h1v-1h2v-1h1v2h-1v1h-2v1h-1v-1h-1v1h-6v-1h-1v-1h-1v-2h1v1h2v1h3v1h1v-1h-1v-1h-3v-1h-4v-4h1v-2h1v-1h1v-1h1v2h1v1h1v-1h1v1h-1v1h2v-2h1v-2h1v-1h1M8 14h2v1H9v4h1v2h1v1h1v1h1v1h4v1h-6v-1H5v-1H4v-5h1v-1h1v-2h2m17 3h1v3h-1v1h-1v1h-1v2h-2v-2h2v-1h1v-1h1m1 0h1v3h-1v1h-2v-1h1v-1h1"} />
|
<path fill="currentColor" d={isShown ? "M9 0h1v1h1v2h1v2h3V3h1V1h1V0h1v2h1v2h1v7h-1v-1h-3V9h1V6h-1v4h-3v1h1v-1h2v1h3v1h-1v1h-3v2h1v1h1v1h1v3h-1v4h-2v-1h-1v-4h-1v4h-1v1h-2v-4H9v-3h1v-1h1v-1h1v-2H9v-1H8v-1h3V6h-1v3h1v1H8v1H7V4h1V2h1M5 19h2v1h1v1h1v3H4v-1h2v-1H4v-2h1m15-1h2v1h1v2h-2v1h2v1h-5v-3h1v-1h1m4 3h4v1h-4" : "M0 0h7v1H6v1H5v1H4v1H3v1H2v1h5v1H0V6h1V5h1V4h1V3h1V2h1V1H0m13 2h5v1h-1v1h-1v1h-1v1h3v1h-5V7h1V6h1V5h1V4h-3m8 5h1v5h1v-1h1v1h-1v1h1v-1h1v1h-1v3h-1v1h-2v1h-1v1h1v-1h2v-1h1v2h-1v1h-2v1h-1v-1h-1v1h-6v-1h-1v-1h-1v-2h1v1h2v1h3v1h1v-1h-1v-1h-3v-1h-4v-4h1v-2h1v-1h1v-1h1v2h1v1h1v-1h1v1h-1v1h2v-2h1v-2h1v-1h1M8 14h2v1H9v4h1v2h1v1h1v1h1v1h4v1h-6v-1H5v-1H4v-5h1v-1h1v-2h2m17 3h1v3h-1v1h-1v1h-1v2h-2v-2h2v-1h1v-1h1m1 0h1v3h-1v1h-2v-1h1v-1h1"} />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vc-vmsg-modal audio {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.vc-vmsg-preview {
|
.vc-vmsg-preview {
|
||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
|
|
|
@ -150,11 +150,6 @@ export interface PluginDef {
|
||||||
|
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
|
|
||||||
/**
|
|
||||||
* Managed style to automatically enable and disable when the plugin is enabled or disabled
|
|
||||||
*/
|
|
||||||
managedStyle?: string;
|
|
||||||
|
|
||||||
userProfileBadge?: ProfileBadge;
|
userProfileBadge?: ProfileBadge;
|
||||||
|
|
||||||
onMessageClick?: MessageClickListener;
|
onMessageClick?: MessageClickListener;
|
||||||
|
|
|
@ -57,7 +57,7 @@ export const Heading = waitForComponent<t.Heading>("Heading", filters.componentB
|
||||||
export const Select = waitForComponent<t.Select>("Select", filters.componentByCode('.selectPositionTop]:"top"===', '"Escape"==='));
|
export const Select = waitForComponent<t.Select>("Select", filters.componentByCode('.selectPositionTop]:"top"===', '"Escape"==='));
|
||||||
export const SearchableSelect = waitForComponent<t.SearchableSelect>("SearchableSelect", filters.componentByCode('.selectPositionTop]:"top"===', ".multi]:"));
|
export const SearchableSelect = waitForComponent<t.SearchableSelect>("SearchableSelect", filters.componentByCode('.selectPositionTop]:"top"===', ".multi]:"));
|
||||||
export const Slider = waitForComponent<t.Slider>("Slider", filters.componentByCode('"markDash".concat('));
|
export const Slider = waitForComponent<t.Slider>("Slider", filters.componentByCode('"markDash".concat('));
|
||||||
export const Popout = waitForComponent<t.Popout>("Popout", filters.componentByCode("ref:this.ref,", "renderPopout:this.renderPopout,"));
|
export const Popout = waitForComponent<t.Popout>("Popout", filters.componentByCode("ref:this.ref,preload:"));
|
||||||
export const Dialog = waitForComponent<t.Dialog>("Dialog", filters.componentByCode('role:"dialog",tabIndex:-1'));
|
export const Dialog = waitForComponent<t.Dialog>("Dialog", filters.componentByCode('role:"dialog",tabIndex:-1'));
|
||||||
export const TabBar = waitForComponent("TabBar", filters.componentByCode("ref:this.tabBarRef,className:"));
|
export const TabBar = waitForComponent("TabBar", filters.componentByCode("ref:this.tabBarRef,className:"));
|
||||||
export const Paginator = waitForComponent<t.Paginator>("Paginator", filters.componentByCode('rel:"prev",children:'));
|
export const Paginator = waitForComponent<t.Paginator>("Paginator", filters.componentByCode('rel:"prev",children:'));
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { WebpackInstance } from "discord-types/other";
|
||||||
|
|
||||||
import { traceFunction } from "../debug/Tracer";
|
import { traceFunction } from "../debug/Tracer";
|
||||||
import { patches } from "../plugins";
|
import { patches } from "../plugins";
|
||||||
import { _initWebpack, _shouldIgnoreModule, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
|
import { _initWebpack, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
|
||||||
|
|
||||||
const logger = new Logger("WebpackInterceptor", "#8caaee");
|
const logger = new Logger("WebpackInterceptor", "#8caaee");
|
||||||
|
|
||||||
|
@ -173,9 +173,35 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
|
||||||
if (!exports) return;
|
if (!exports) return;
|
||||||
|
|
||||||
if (require.c) {
|
if (require.c) {
|
||||||
const shouldIgnoreModule = _shouldIgnoreModule(exports);
|
let shouldMakeNonEnumerable = false;
|
||||||
|
|
||||||
if (shouldIgnoreModule) {
|
nonEnumerableChecking: {
|
||||||
|
// There are (at the time of writing) 11 modules exporting the window,
|
||||||
|
// and also modules exporting DOMTokenList, which breaks webpack finding
|
||||||
|
// Make these non enumerable to improve search performance and avoid erros
|
||||||
|
if (exports === window || exports[Symbol.toStringTag] === "DOMTokenList") {
|
||||||
|
shouldMakeNonEnumerable = true;
|
||||||
|
break nonEnumerableChecking;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exports !== "object") {
|
||||||
|
break nonEnumerableChecking;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exports.default === window || exports.default?.[Symbol.toStringTag] === "DOMTokenList") {
|
||||||
|
shouldMakeNonEnumerable = true;
|
||||||
|
break nonEnumerableChecking;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const nested in exports) {
|
||||||
|
if (exports[nested] === window || exports[nested]?.[Symbol.toStringTag] === "DOMTokenList") {
|
||||||
|
shouldMakeNonEnumerable = true;
|
||||||
|
break nonEnumerableChecking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldMakeNonEnumerable) {
|
||||||
Object.defineProperty(require.c, id, {
|
Object.defineProperty(require.c, id, {
|
||||||
value: require.c[id],
|
value: require.c[id],
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
|
@ -200,16 +226,17 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
|
||||||
if (exports && filter(exports)) {
|
if (exports && filter(exports)) {
|
||||||
subscriptions.delete(filter);
|
subscriptions.delete(filter);
|
||||||
callback(exports, id);
|
callback(exports, id);
|
||||||
}
|
} else if (typeof exports === "object") {
|
||||||
|
if (exports.default && filter(exports.default)) {
|
||||||
if (typeof exports !== "object") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const exportKey in exports) {
|
|
||||||
if (exports[exportKey] && filter(exports[exportKey])) {
|
|
||||||
subscriptions.delete(filter);
|
subscriptions.delete(filter);
|
||||||
callback(exports[exportKey], id);
|
callback(exports.default, id);
|
||||||
|
} else {
|
||||||
|
for (const nested in exports) {
|
||||||
|
if (exports[nested] && filter(exports[nested])) {
|
||||||
|
subscriptions.delete(filter);
|
||||||
|
callback(exports[nested], id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -69,23 +69,17 @@ export const filters = {
|
||||||
m.constructor?.displayName === name,
|
m.constructor?.displayName === name,
|
||||||
|
|
||||||
componentByCode: (...code: CodeFilter): FilterFn => {
|
componentByCode: (...code: CodeFilter): FilterFn => {
|
||||||
const byCodeFilter = filters.byCode(...code);
|
const filter = filters.byCode(...code);
|
||||||
const filter = m => {
|
return m => {
|
||||||
let inner = m;
|
if (filter(m)) return true;
|
||||||
|
if (!m.$$typeof) return false;
|
||||||
while (inner != null) {
|
if (m.type)
|
||||||
if (byCodeFilter(inner)) return true;
|
return m.type.render
|
||||||
else if (!inner.$$typeof) return false;
|
? filter(m.type.render) // memo + forwardRef
|
||||||
else if (inner.type) inner = inner.type; // memos
|
: filter(m.type); // memo
|
||||||
else if (inner.render) inner = inner.render; // forwardRefs
|
if (m.render) return filter(m.render); // forwardRef
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
filter.$$vencordProps = [...code];
|
|
||||||
return filter;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,38 +95,6 @@ export function _initWebpack(webpackRequire: WebpackInstance) {
|
||||||
cache = webpackRequire.c;
|
cache = webpackRequire.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Credits to Zerebos for implementing this in BD, thus giving the idea for us to implement it too
|
|
||||||
const TypedArray = Object.getPrototypeOf(Int8Array);
|
|
||||||
|
|
||||||
function _shouldIgnoreValue(value: any) {
|
|
||||||
if (value == null) return true;
|
|
||||||
if (value === window) return true;
|
|
||||||
if (value === document || value === document.documentElement) return true;
|
|
||||||
if (value[Symbol.toStringTag] === "DOMTokenList") return true;
|
|
||||||
if (value instanceof TypedArray) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function _shouldIgnoreModule(exports: any) {
|
|
||||||
if (_shouldIgnoreValue(exports)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof exports !== "object") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let allNonEnumerable = true;
|
|
||||||
for (const exportKey in exports) {
|
|
||||||
if (!_shouldIgnoreValue(exports[exportKey])) {
|
|
||||||
allNonEnumerable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return allNonEnumerable;
|
|
||||||
}
|
|
||||||
|
|
||||||
let devToolsOpen = false;
|
let devToolsOpen = false;
|
||||||
if (IS_DEV && IS_DISCORD_DESKTOP) {
|
if (IS_DEV && IS_DISCORD_DESKTOP) {
|
||||||
// At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed
|
// At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed
|
||||||
|
@ -159,7 +121,7 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
|
||||||
|
|
||||||
for (const key in cache) {
|
for (const key in cache) {
|
||||||
const mod = cache[key];
|
const mod = cache[key];
|
||||||
if (!mod?.loaded || mod.exports == null) continue;
|
if (!mod.loaded || !mod?.exports) continue;
|
||||||
|
|
||||||
if (filter(mod.exports)) {
|
if (filter(mod.exports)) {
|
||||||
return isWaitFor ? [mod.exports, key] : mod.exports;
|
return isWaitFor ? [mod.exports, key] : mod.exports;
|
||||||
|
@ -167,6 +129,11 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
|
||||||
|
|
||||||
if (typeof mod.exports !== "object") continue;
|
if (typeof mod.exports !== "object") continue;
|
||||||
|
|
||||||
|
if (mod.exports.default && filter(mod.exports.default)) {
|
||||||
|
const found = mod.exports.default;
|
||||||
|
return isWaitFor ? [found, key] : found;
|
||||||
|
}
|
||||||
|
|
||||||
for (const nestedMod in mod.exports) {
|
for (const nestedMod in mod.exports) {
|
||||||
const nested = mod.exports[nestedMod];
|
const nested = mod.exports[nestedMod];
|
||||||
if (nested && filter(nested)) {
|
if (nested && filter(nested)) {
|
||||||
|
@ -189,15 +156,16 @@ export function findAll(filter: FilterFn) {
|
||||||
const ret = [] as any[];
|
const ret = [] as any[];
|
||||||
for (const key in cache) {
|
for (const key in cache) {
|
||||||
const mod = cache[key];
|
const mod = cache[key];
|
||||||
if (!mod?.loaded || mod.exports == null) continue;
|
if (!mod.loaded || !mod?.exports) continue;
|
||||||
|
|
||||||
if (filter(mod.exports))
|
if (filter(mod.exports))
|
||||||
ret.push(mod.exports);
|
ret.push(mod.exports);
|
||||||
|
else if (typeof mod.exports !== "object")
|
||||||
if (typeof mod.exports !== "object")
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const nestedMod in mod.exports) {
|
if (mod.exports.default && filter(mod.exports.default))
|
||||||
|
ret.push(mod.exports.default);
|
||||||
|
else for (const nestedMod in mod.exports) {
|
||||||
const nested = mod.exports[nestedMod];
|
const nested = mod.exports[nestedMod];
|
||||||
if (nested && filter(nested)) ret.push(nested);
|
if (nested && filter(nested)) ret.push(nested);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +204,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
|
||||||
outer:
|
outer:
|
||||||
for (const key in cache) {
|
for (const key in cache) {
|
||||||
const mod = cache[key];
|
const mod = cache[key];
|
||||||
if (!mod?.loaded || mod.exports == null) continue;
|
if (!mod.loaded || !mod?.exports) continue;
|
||||||
|
|
||||||
for (let j = 0; j < length; j++) {
|
for (let j = 0; j < length; j++) {
|
||||||
const filter = filters[j];
|
const filter = filters[j];
|
||||||
|
@ -253,6 +221,13 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
|
||||||
if (typeof mod.exports !== "object")
|
if (typeof mod.exports !== "object")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (mod.exports.default && filter(mod.exports.default)) {
|
||||||
|
results[j] = mod.exports.default;
|
||||||
|
filters[j] = undefined;
|
||||||
|
if (++found === length) break outer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (const nestedMod in mod.exports) {
|
for (const nestedMod in mod.exports) {
|
||||||
const nested = mod.exports[nestedMod];
|
const nested = mod.exports[nestedMod];
|
||||||
if (nested && filter(nested)) {
|
if (nested && filter(nested)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue