diff --git a/package.json b/package.json index d5e653b08..5a2fcfd4d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "equicord", "private": "true", - "version": "1.13.8.2", + "version": "1.13.9", "description": "The other cutest Discord client mod", "homepage": "https://github.com/Equicord/Equicord#readme", "bugs": { @@ -121,4 +121,4 @@ "engines": { "node": ">=18" } -} +} \ No newline at end of file diff --git a/packages/discord-types/src/components.d.ts b/packages/discord-types/src/components.d.ts index 29e90eab6..4fb634a12 100644 --- a/packages/discord-types/src/components.d.ts +++ b/packages/discord-types/src/components.d.ts @@ -318,14 +318,6 @@ export type Slider = ComponentClass>; -// TODO - type maybe idk probably not that useful other than the constants -export type Flex = ComponentType> & { - Align: Record<"START" | "END" | "CENTER" | "STRETCH" | "BASELINE", string>; - Direction: Record<"VERTICAL" | "HORIZONTAL" | "HORIZONTAL_REVERSE", string>; - Justify: Record<"START" | "END" | "CENTER" | "BETWEEN" | "AROUND", string>; - Wrap: Record<"NO_WRAP" | "WRAP" | "WRAP_REVERSE", string>; -}; - declare enum PopoutAnimation { NONE = "1", TRANSLATE = "2", diff --git a/src/api/Notifications/styles.css b/src/api/Notifications/styles.css index e62836bfd..5ced23678 100644 --- a/src/api/Notifications/styles.css +++ b/src/api/Notifications/styles.css @@ -47,13 +47,13 @@ .vc-notification-close-btn { all: unset; cursor: pointer; - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); opacity: 0.5; transition: opacity 0.2s ease-in-out, color 0.2s ease-in-out; } .vc-notification-close-btn:hover { - color: var(--interactive-icon-hover, var(--interactive-hover)); + color: var(--interactive-icon-hover); opacity: 1; } @@ -137,5 +137,5 @@ .vc-notification-log-danger-btn { color: var(--white-500); - background-color: var(--redesign-button-danger-background, var(--button-danger-background)); -} + background-color: var(--redesign-button-danger-background); +} \ No newline at end of file diff --git a/src/api/PluginManager.ts b/src/api/PluginManager.ts index 07fa1c986..4b42aae11 100644 --- a/src/api/PluginManager.ts +++ b/src/api/PluginManager.ts @@ -100,6 +100,10 @@ function isReporterTestable(p: Plugin, part: ReporterTestable) { : (p.reporterTestable & part) === part; } +export function pluginRequiresRestart(p: Plugin) { + return p.requiresRestart !== false && (p.requiresRestart || !!p.patches?.length); +} + export const startAllPlugins = traceFunction("startAllPlugins", function startAllPlugins(target: StartAt) { logger.info(`Starting plugins (stage ${target})`); for (const name in Plugins) { @@ -128,7 +132,7 @@ export function startDependenciesRecursive(p: Plugin) { settings[d].enabled = true; dep.isDependency = true; - if (dep.patches) { + if (pluginRequiresRestart(dep)) { logger.warn(`Enabling dependency ${d} requires restart.`); restartNeeded = true; return; diff --git a/src/components/Button.css b/src/components/Button.css index 334e1b5ab..6f70510b5 100644 --- a/src/components/Button.css +++ b/src/components/Button.css @@ -10,7 +10,7 @@ text-align: start; transition: 50ms ease-in; transition-property: background-color, color, border-color, opacity; - background: var(--control-secondary-background-default, var(--control-background-secondary-default)); + background: var(--control-secondary-background-default); color: var(--text-default); white-space: nowrap; @@ -26,7 +26,7 @@ &:focus-visible { /* stylelint-disable-next-line custom-property-pattern */ - box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--border-focus, var(--focus-primary, #00b0f4))); + box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--border-focus, #00b0f4)); } } @@ -63,84 +63,84 @@ } .vc-btn-primary { - background-color: var(--control-primary-background-default, var(--control-background-primary-default)); - border-color: var(--control-primary-border-default, var(--control-border-primary-default)); - color: var(--control-primary-text-default, var(--control-text-primary-default)); + background-color: var(--control-primary-background-default); + border-color: var(--control-primary-border-default); + color: var(--control-primary-text-default); &:hover { - background-color: var(--control-primary-background-hover, var(--control-background-primary-hover)); - border-color: var(--control-primary-border-hover, var(--control-border-primary-hover)); - color: var(--control-primary-text-hover, var(--control-text-primary-hover)); + background-color: var(--control-primary-background-hover); + border-color: var(--control-primary-border-hover); + color: var(--control-primary-text-hover); } } .vc-btn-secondary, .vc-btn-link { - background-color: var(--control-secondary-background-default, var(--control-background-secondary-default)); - border-color: var(--control-secondary-border-default, var(--control-border-secondary-default)); - color: var(--control-secondary-text-default, var(--control-text-secondary-default)); + background-color: var(--control-secondary-background-default); + border-color: var(--control-secondary-border-default); + color: var(--control-secondary-text-default); &:hover { - background-color: var(--control-secondary-background-hover, var(--control-background-secondary-hover)); - border-color: var(--control-secondary-border-hover, var(--control-border-secondary-hover)); - color: var(--control-secondary-text-hover, var(--control-text-secondary-hover)); + background-color: var(--control-secondary-background-hover); + border-color: var(--control-secondary-border-hover); + color: var(--control-secondary-text-hover); } } .vc-btn-dangerPrimary { - background-color: var(--control-critical-primary-background-default, var(--control-background-critical-primary-default)); - border-color: var(--control-critical-primary-border-default, var(--control-border-critical-primary-default)); - color: var(--control-critical-primary-text-default, var(--control-text-critical-primary-default)); + background-color: var(--control-critical-primary-background-default); + border-color: var(--control-critical-primary-border-default); + color: var(--control-critical-primary-text-default); &:hover { - background-color: var(--control-critical-primary-background-hover, var(--control-background-critical-primary-hover)); - border-color: var(--control-critical-primary-border-hover, var(--control-border-critical-primary-hover)); - color: var(--control-critical-primary-text-hover, var(--control-text-critical-primary-hover)); + background-color: var(--control-critical-primary-background-hover); + border-color: var(--control-critical-primary-border-hover); + color: var(--control-critical-primary-text-hover); } } .vc-btn-dangerSecondary { - background-color: var(--control-critical-secondary-background-default, var(--control-background-critical-secondary-default)); - border-color: var(--control-critical-secondary-border-default, var(--control-border-critical-secondary-default)); - color: var(--control-critical-secondary-text-default, var(--control-text-critical-secondary-default)); + background-color: var(--control-critical-secondary-background-default); + border-color: var(--control-critical-secondary-border-default); + color: var(--control-critical-secondary-text-default); &:hover { - background-color: var(--control-critical-secondary-background-hover, var(--control-background-critical-secondary-hover)); - border-color: var(--control-critical-secondary-border-hover, var(--control-border-critical-secondary-hover)); - color: var(--control-critical-secondary-text-hover, var(--control-text-critical-secondary-hover)); + background-color: var(--control-critical-secondary-background-hover); + border-color: var(--control-critical-secondary-border-hover); + color: var(--control-critical-secondary-text-hover); } } .vc-btn-overlayPrimary { - background-color: var(--control-overlay-primary-background-default, var(--control-background-overlay-primary-default)); - border-color: var(--control-overlay-primary-border-default, var(--control-border-overlay-primary-default)); - color: var(--control-overlay-primary-text-default, var(--control-text-overlay-primary-default)); + background-color: var(--control-overlay-primary-background-default); + border-color: var(--control-overlay-primary-border-default); + color: var(--control-overlay-primary-text-default); &:hover { - background-color: var(--control-overlay-primary-background-hover, var(--control-background-overlay-primary-hover)); - border-color: var(--control-overlay-primary-border-hover, var(--control-border-overlay-primary-hover)); - color: var(--control-overlay-primary-text-hover, var(--control-text-overlay-primary-hover)); + background-color: var(--control-overlay-primary-background-hover); + border-color: var(--control-overlay-primary-border-hover); + color: var(--control-overlay-primary-text-hover); } } .vc-btn-positive { - background-color: var(--redesign-button-positive-background, var(--button-positive-background)); + background-color: var(--redesign-button-positive-background); color: var(--white); &:hover { - background-color: var(--redesign-button-positive-pressed-background, var(--button-positive-background-hover)); + background-color: var(--redesign-button-positive-pressed-background); } } .vc-btn-none { background-color: transparent; border-color: transparent; - color: var(--control-icon-only-icon-default, var(--control-icon-icon-only-default)); + color: var(--control-icon-only-icon-default); &:hover { - background-color: var(--control-icon-only-background-hover, var(--control-background-icon-only-hover)); - border-color: var(--control-icon-only-border-hover, var(--control-border-icon-only-hover)); - color: var(--control-icon-only-icon-hover, var(--control-icon-icon-only-hover)); + background-color: var(--control-icon-only-background-hover); + border-color: var(--control-icon-only-border-hover); + color: var(--control-icon-only-icon-hover); } } @@ -177,7 +177,7 @@ &:focus-visible { /* stylelint-disable-next-line custom-property-pattern */ - box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--border-focus, var(--focus-primary, #00b0f4))); + box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--border-focus, #00b0f4)); } } @@ -190,7 +190,7 @@ } .vc-text-btn-danger { - color: var(--text-feedback-critical, var(--text-feedback-critical)); + color: var(--text-feedback-critical); } .vc-text-btn-link { diff --git a/src/components/Card.css b/src/components/Card.css index 59ff8baa8..97e36ed84 100644 --- a/src/components/Card.css +++ b/src/components/Card.css @@ -1,5 +1,5 @@ .vc-card-base { - background: var(--card-background-default, var(--card-primary-bg)); + background: var(--card-background-default); border-radius: var(--radius-sm, 8px) } @@ -8,11 +8,11 @@ } .vc-card-warning { - border: 1px solid var(--icon-status-idle, var(--info-warning-foreground)); + border: 1px solid var(--icon-status-idle); } .vc-card-danger { - border: 1px solid var(--icon-status-dnd, var(--info-danger-foreground)); + border: 1px solid var(--icon-status-dnd); } .vc-card-defaultPadding { diff --git a/src/components/Switch.css b/src/components/Switch.css index 186724f46..cb23a892f 100644 --- a/src/components/Switch.css +++ b/src/components/Switch.css @@ -15,7 +15,7 @@ .vc-switch-checked { background: var(--brand-500); - border-color: var(--control-primary-border-default, var(--control-border-primary-default)); + border-color: var(--control-primary-border-default); } .vc-switch-disabled { @@ -25,7 +25,7 @@ .vc-switch-focusVisible { /* stylelint-disable-next-line custom-property-pattern */ - box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--border-focus, var(--focus-primary, #00b0f4))); + box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--border-focus, #00b0f4)); } .vc-switch-slider { diff --git a/src/components/settings/AddonCard.css b/src/components/settings/AddonCard.css index fb97c427f..ec0f7b326 100644 --- a/src/components/settings/AddonCard.css +++ b/src/components/settings/AddonCard.css @@ -1,6 +1,6 @@ .vc-addon-card { - background-color: var(--card-background-default, var(--card-primary-bg)); - color: var(--interactive-icon-active, var(--interactive-active)); + background-color: var(--card-background-default); + color: var(--interactive-icon-active); border: 1px solid var(--border-subtle); border-radius: 8px; display: block; diff --git a/src/components/settings/QuickAction.css b/src/components/settings/QuickAction.css index 3b809375c..ad7a7d7f5 100644 --- a/src/components/settings/QuickAction.css +++ b/src/components/settings/QuickAction.css @@ -14,7 +14,7 @@ .vc-settings-quickActions-pill { all: unset; - background: var(--redesign-button-secondary-background, var(--button-secondary-background)); + background: var(--redesign-button-secondary-background); color: var(--text-default); display: flex; align-items: center; @@ -29,13 +29,13 @@ } .vc-settings-quickActions-pill:hover { - background: var(--redesign-button-secondary-pressed-background, var(--button-secondary-background-hover)); + background: var(--redesign-button-secondary-pressed-background); transform: translateY(-1px); box-shadow: var(--elevation-high); } .vc-settings-quickActions-pill:focus-visible { - outline: 2px solid var(--border-focus, var(--focus-primary)); + outline: 2px solid var(--border-focus); outline-offset: 2px; } diff --git a/src/components/settings/tabs/patchHelper/FullPatchInput.tsx b/src/components/settings/tabs/patchHelper/FullPatchInput.tsx index a0b952833..3943dac3a 100644 --- a/src/components/settings/tabs/patchHelper/FullPatchInput.tsx +++ b/src/components/settings/tabs/patchHelper/FullPatchInput.tsx @@ -74,7 +74,7 @@ export function FullPatchInput({ setFind, setParsedFind, setMatch, setReplacemen onChange={setPatch} onBlur={update} /> - {error !== "" && {error}} + {error !== "" && {error}} ); } diff --git a/src/components/settings/tabs/patchHelper/PatchPreview.tsx b/src/components/settings/tabs/patchHelper/PatchPreview.tsx index 9d2bd6fe7..00f7f0597 100644 --- a/src/components/settings/tabs/patchHelper/PatchPreview.tsx +++ b/src/components/settings/tabs/patchHelper/PatchPreview.tsx @@ -142,7 +142,7 @@ export function PatchPreview({ module, match, replacement, setReplacementError } )} {compileResult && ( - + {compileResult[1]} )} diff --git a/src/components/settings/tabs/plugins/PluginCard.tsx b/src/components/settings/tabs/plugins/PluginCard.tsx index 1e4248853..e9275c376 100644 --- a/src/components/settings/tabs/plugins/PluginCard.tsx +++ b/src/components/settings/tabs/plugins/PluginCard.tsx @@ -5,7 +5,7 @@ */ import { showNotice } from "@api/Notices"; -import { isPluginEnabled, startDependenciesRecursive, startPlugin, stopPlugin } from "@api/PluginManager"; +import { isPluginEnabled, pluginRequiresRestart, startDependenciesRecursive, startPlugin, stopPlugin } from "@api/PluginManager"; import { classNameFactory } from "@api/Styles"; import { CogWheel, InfoIcon } from "@components/Icons"; import { AddonCard } from "@components/settings/AddonCard"; @@ -61,8 +61,8 @@ export function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, on } } - // if the plugin has patches, dont use stopPlugin/startPlugin. Wait for restart to apply changes. - if (plugin.patches?.length) { + // if the plugin requires a restart, don't use stopPlugin/startPlugin. Wait for restart to apply changes. + if (pluginRequiresRestart(plugin)) { settings.enabled = !wasEnabled; onRestartNeeded(plugin.name, "enabled"); return; diff --git a/src/components/settings/tabs/plugins/UIElements.css b/src/components/settings/tabs/plugins/UIElements.css index c205abc29..30db51dbd 100644 --- a/src/components/settings/tabs/plugins/UIElements.css +++ b/src/components/settings/tabs/plugins/UIElements.css @@ -1,13 +1,13 @@ .vc-plugin-ui-elements-button { display: flex; align-items: center; - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); margin-top: 0.5em; cursor: pointer; &:hover { - background-color: var(--background-mod-subtle, var(--background-modifier-hover)); - color: var(--interactive-icon-hover, var(--interactive-hover)); + background-color: var(--background-mod-subtle); + color: var(--interactive-icon-hover); } } diff --git a/src/components/settings/tabs/plugins/components/styles.css b/src/components/settings/tabs/plugins/components/styles.css index 6ec96e537..52da69841 100644 --- a/src/components/settings/tabs/plugins/components/styles.css +++ b/src/components/settings/tabs/plugins/components/styles.css @@ -31,5 +31,5 @@ } .vc-plugins-setting-error { - color: var(--text-feedback-critical, var(--text-danger, #FF5C5C)); -} + color: var(--text-feedback-critical, #FF5C5C); +} \ No newline at end of file diff --git a/src/components/settings/tabs/plugins/styles.css b/src/components/settings/tabs/plugins/styles.css index 608592c59..f2c8a38f3 100644 --- a/src/components/settings/tabs/plugins/styles.css +++ b/src/components/settings/tabs/plugins/styles.css @@ -29,16 +29,16 @@ padding: 0; background: transparent; margin-right: 8px; - color: var(--icon-muted, var(--icon-secondary)); + color: var(--icon-muted); transition: background-color .2s ease; &:hover { - color: var(--interactive-icon-hover, var(--interactive-hover)) + color: var(--interactive-icon-hover) } } .vc-plugins-settings-button:hover { - color: var(--interactive-icon-hover, var(--interactive-hover)); + color: var(--interactive-icon-hover); } .vc-plugins-filter-controls { @@ -78,9 +78,8 @@ .vc-plugins-restart-card { padding: 1em; - background: var(--icon-status-idle, var(--info-warning-foreground)) !important; - border: 1px solid var(--icon-status-idle, var(--info-warning-foreground)) !important; - ; + background: var(--icon-status-idle) !important; + border: 1px solid var(--icon-status-idle) !important; color: var(--text-status-idle); } diff --git a/src/components/settings/tabs/styles.css b/src/components/settings/tabs/styles.css index d046318fa..83003366c 100644 --- a/src/components/settings/tabs/styles.css +++ b/src/components/settings/tabs/styles.css @@ -49,7 +49,7 @@ display: inline-block !important; color: var(--text-default) !important; padding: 0.5em 1em; - border: 1px solid var(--input-border-default, var(--input-border)); + border: 1px solid var(--input-border-default); max-height: unset; background-color: transparent; box-sizing: border-box; @@ -76,7 +76,7 @@ .vc-cloud-erase-data-danger-btn { color: var(--white-500); - background-color: var(--redesign-button-danger-background, var(--button-danger-background)); + background-color: var(--redesign-button-danger-background); } .vc-settings-modal { diff --git a/src/equicordplugins/equicordToolbox/styles.css b/src/equicordplugins/equicordToolbox/styles.css index 72b343edc..60991923d 100644 --- a/src/equicordplugins/equicordToolbox/styles.css +++ b/src/equicordplugins/equicordToolbox/styles.css @@ -4,13 +4,13 @@ } .vc-toolbox-icon { - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); } .vc-toolbox-btn[class*="selected"] .vc-toolbox-icon { - color: var(--interactive-icon-active, var(--interactive-active)); + color: var(--interactive-icon-active); } .vc-toolbox-btn:hover .vc-toolbox-icon { - color: var(--interactive-icon-hover, var(--interactive-hover)); + color: var(--interactive-icon-hover); } \ No newline at end of file diff --git a/src/equicordplugins/musicControls/spotify/spotifyStyles.css b/src/equicordplugins/musicControls/spotify/spotifyStyles.css index 4470ec201..74dd7a499 100644 --- a/src/equicordplugins/musicControls/spotify/spotifyStyles.css +++ b/src/equicordplugins/musicControls/spotify/spotifyStyles.css @@ -16,7 +16,7 @@ margin: 0 2px; border-radius: var(--radius-sm); background: none; - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); padding: 0; width: 32px; height: 32px; @@ -26,8 +26,8 @@ } .vc-spotify-button:hover { - color: var(--interactive-icon-hover, var(--interactive-hover)); - background-color: var(--background-mod-strong, var(--background-modifier-selected)); + color: var(--interactive-icon-hover); + background-color: var(--background-mod-strong); } .vc-spotify-button-icon { @@ -171,7 +171,7 @@ } #vc-spotify-progress-bar > [class^="slider"] [class^="barFill"] { - background-color: var(--interactive-icon-active, var(--interactive-active)); + background-color: var(--interactive-icon-active); } #vc-spotify-progress-bar > [class^="slider"]:hover [class^="barFill"] { @@ -184,9 +184,9 @@ width: 16px !important; margin-top: calc(17px/-2 + var(--bar-offset)/2); margin-left: -0.5px; - background-color: var(--interactive-icon-active, var(--interactive-active)); - border-color: var(--interactive-icon-default, var(--interactive-normal)); - color: var(--interactive-icon-default, var(--interactive-normal)); + background-color: var(--interactive-icon-active); + border-color: var(--interactive-icon-default); + color: var(--interactive-icon-default); opacity: 0; transition: opacity 0.1s; } diff --git a/src/plugins/betterSessions/index.tsx b/src/plugins/betterSessions/index.tsx index f83925a3e..496db8842 100644 --- a/src/plugins/betterSessions/index.tsx +++ b/src/plugins/betterSessions/index.tsx @@ -140,7 +140,7 @@ export default definePlugin({ overflow: "hidden", borderRadius: "50%", - backgroundColor: "var(--interactive-icon-default, var(--interactive-normal))", + backgroundColor: "var(--interactive-icon-default)", color: "var(--background-base-lower)", }} > diff --git a/src/plugins/clientTheme/clientTheme.css b/src/plugins/clientTheme/clientTheme.css index a0607efb0..9c185bc0c 100644 --- a/src/plugins/clientTheme/clientTheme.css +++ b/src/plugins/clientTheme/clientTheme.css @@ -16,7 +16,7 @@ } .vc-clientTheme-container [class^="swatch"] { - border: thin solid var(--input-border-default, var(--input-border)) !important; + border: thin solid var(--input-border-default) !important; } .vc-clientTheme-buttons-container { diff --git a/src/plugins/copyFileContents/style.css b/src/plugins/copyFileContents/style.css index 4ad026754..818652539 100644 --- a/src/plugins/copyFileContents/style.css +++ b/src/plugins/copyFileContents/style.css @@ -1,9 +1,9 @@ .vc-cfc-button { - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); cursor: pointer; padding-left: 4px; } .vc-cfc-button:hover { - color: var(--interactive-icon-hover, var(--interactive-hover)); + color: var(--interactive-icon-hover); } \ No newline at end of file diff --git a/src/plugins/customRPC/index.tsx b/src/plugins/customRPC/index.tsx index f3dbbffc3..c522eb38f 100644 --- a/src/plugins/customRPC/index.tsx +++ b/src/plugins/customRPC/index.tsx @@ -217,17 +217,20 @@ export default definePlugin({ description: "Add a fully customisable Rich Presence (Game status) to your Discord profile", authors: [Devs.captain, Devs.AutumnVN, Devs.nin0dev], dependencies: ["UserSettingsAPI"], - start: setRpc, - stop: () => setRpc(true), + // This plugin's patch is not important for functionality, so don't require a restart + requiresRestart: false, settings, + start: setRpc, + stop: () => setRpc(true), + + // Discord hides buttons on your own Rich Presence for some reason. This patch disables that behaviour patches: [ { - find: ".party?(0", - all: true, + find: ".buttons.length)>=1", replacement: { - match: /\i\.id===\i\.id\?null:/, - replace: "" + match: /.getId\(\)===\i.id/, + replace: "$& && false" } } ], @@ -278,7 +281,7 @@ export default definePlugin({ -
+
{activity && + + {getCreatedAtDate(friendsSince, locale.getLocale())} + + + ); + } + return ( -
- { - isSidebar ? ( +
+
+
+ {!!getCurrentChannel()?.guild_id && ( + + )} {getCreatedAtDate(friendsSince, locale.getLocale())} - ) : ( -
-
- {!!getCurrentChannel()?.guild_id && ( - - )} - - {getCreatedAtDate(friendsSince, locale.getLocale())} - -
-
- ) - } +
+
); }, { noop: true }), diff --git a/src/plugins/friendsSince/styles.css b/src/plugins/friendsSince/styles.css new file mode 100644 index 000000000..0e404c1b6 --- /dev/null +++ b/src/plugins/friendsSince/styles.css @@ -0,0 +1,3 @@ +.vc-friendsSince-profile-section { + gap: 4px; +} \ No newline at end of file diff --git a/src/plugins/ignoreActivities/index.tsx b/src/plugins/ignoreActivities/index.tsx index 33f23dc79..d0d776f9c 100644 --- a/src/plugins/ignoreActivities/index.tsx +++ b/src/plugins/ignoreActivities/index.tsx @@ -66,7 +66,7 @@ function ToggleActivityComponent(activity: IgnoredActivity, isPlaying = false) { const { ignoredActivities } = s; if (ignoredActivities.some(act => act.id === activity.id)) return ToggleIconOff(activity, "var(--status-danger)"); - return ToggleIconOn(activity, isPlaying ? "var(--green-300)" : "var(--interactive-icon-default, var(--interactive-normal))"); + return ToggleIconOn(activity, isPlaying ? "var(--green-300)" : "var(--interactive-icon-default)"); } function handleActivityToggle(e: React.MouseEvent, activity: IgnoredActivity) { diff --git a/src/plugins/memberCount/style.css b/src/plugins/memberCount/style.css index fcb4cf0c8..6eb7efa14 100644 --- a/src/plugins/memberCount/style.css +++ b/src/plugins/memberCount/style.css @@ -47,7 +47,7 @@ .vc-membercount-total-count { fill: none; - stroke: var(--icon-status-offline, var(--status-offline)); + stroke: var(--icon-status-offline); stroke-width: 4px; width: 15px; height: 15px; diff --git a/src/plugins/messageLogger/deleteStyleText.css b/src/plugins/messageLogger/deleteStyleText.css index 82cf6ae94..e12261b70 100644 --- a/src/plugins/messageLogger/deleteStyleText.css +++ b/src/plugins/messageLogger/deleteStyleText.css @@ -1,6 +1,6 @@ .messagelogger-deleted { --text-default: var(--status-danger, #f04747); - --interactive-icon-default: var(--interactive-normal, var(--status-danger, #f04747)); + --interactive-icon-default: var(--status-danger, #f04747); --text-muted: var(--status-danger, #f04747); --embed-title: var(--red-460, #be3535); --text-link: var(--red-460, #be3535); diff --git a/src/plugins/permissionsViewer/styles.css b/src/plugins/permissionsViewer/styles.css index fff85b739..c4b4c0943 100644 --- a/src/plugins/permissionsViewer/styles.css +++ b/src/plugins/permissionsViewer/styles.css @@ -66,11 +66,11 @@ } .vc-permviewer-modal-list-item:hover { - background-color: var(--background-mod-subtle, var(--background-modifier-hover)); + background-color: var(--background-mod-subtle); } .vc-permviewer-modal-list-item-active { - background-color: var(--background-mod-strong, var(--background-modifier-selected)); + background-color: var(--background-mod-strong); } .vc-permviewer-modal-list-item-text { @@ -100,7 +100,7 @@ .vc-permviewer-modal-divider { width: 2px; - background-color: var(--background-mod-normal, var(--background-modifier-active)); + background-color: var(--background-mod-normal); } .vc-permviewer-modal-perms { @@ -114,7 +114,7 @@ align-items: center; gap: 5px; padding: 10px 2px 10px 10px; - border-bottom: 2px solid var(--background-mod-normal, var(--background-modifier-active)); + border-bottom: 2px solid var(--background-mod-normal); } .vc-permviewer-modal-perms-item:last-child { @@ -122,7 +122,7 @@ } .vc-permviewer-modal-perms-item-icon { - border: 1px solid var(--background-mod-strong, var(--background-modifier-selected)); + border: 1px solid var(--background-mod-strong); width: 24px; height: 24px; } @@ -135,13 +135,13 @@ } .vc-permviewer-modal-perms-item .vc-info-icon:hover { - color: var(--interactive-icon-active, var(--interactive-active)); + color: var(--interactive-icon-active); } /* copy pasted from discord cause impossible to webpack find */ .vc-permviewer-role-button { border-radius: var(--radius-sm); - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); border: 1px solid var(--user-profile-border); /* stylelint-disable-next-line value-no-vendor-prefix */ width: -moz-fit-content; diff --git a/src/plugins/pictureInPicture/styles.css b/src/plugins/pictureInPicture/styles.css index f88f26754..ec008e1f4 100644 --- a/src/plugins/pictureInPicture/styles.css +++ b/src/plugins/pictureInPicture/styles.css @@ -1,8 +1,8 @@ .vc-pip-button { - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); } .vc-pip-button:hover { - background-color: var(--background-mod-subtle, var(--background-modifier-hover)); - color: var(--interactive-icon-hover, var(--interactive-hover)); -} + background-color: var(--background-mod-subtle); + color: var(--interactive-icon-hover); +} \ No newline at end of file diff --git a/src/plugins/pinDms/styles.css b/src/plugins/pinDms/styles.css index faea19a3f..00af59cca 100644 --- a/src/plugins/pinDms/styles.css +++ b/src/plugins/pinDms/styles.css @@ -28,7 +28,7 @@ .vc-pindms-collapse-icon { width: 16px; height: 16px; - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); transform: rotate(90deg) } diff --git a/src/plugins/plainFolderIcon/style.css b/src/plugins/plainFolderIcon/style.css index d8c7f6dc5..9b14be933 100644 --- a/src/plugins/plainFolderIcon/style.css +++ b/src/plugins/plainFolderIcon/style.css @@ -6,5 +6,5 @@ transform: translateZ(0); /* The new icons are fully transparent. Add a sane default to match the old behavior */ - background-color: color-mix(in oklab, var(--custom-folder-color, var(--badge-background-default, var(--bg-brand))) 40%, transparent); + background-color: color-mix(in oklab, var(--custom-folder-color, var(--badge-background-default)) 40%, transparent); } \ No newline at end of file diff --git a/src/plugins/readAllNotificationsButton/style.css b/src/plugins/readAllNotificationsButton/style.css index 213b57189..1d1fe185a 100644 --- a/src/plugins/readAllNotificationsButton/style.css +++ b/src/plugins/readAllNotificationsButton/style.css @@ -1,5 +1,5 @@ .vc-ranb-button { - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); padding: 0 0.5em; width: 100%; font-size: 14px; @@ -8,5 +8,5 @@ } .vc-ranb-button:hover { - color: var(--interactive-icon-active, var(--interactive-active)); -} + color: var(--interactive-icon-active); +} \ No newline at end of file diff --git a/src/plugins/reviewDB/style.css b/src/plugins/reviewDB/style.css index 0d8711a0b..47156cf1c 100644 --- a/src/plugins/reviewDB/style.css +++ b/src/plugins/reviewDB/style.css @@ -41,7 +41,7 @@ .vc-rdb-modal-footer .vc-rdb-input { margin-bottom: 0; - background: var(--input-background-default, var(--input-background)); + background: var(--input-background-default); } .vc-rdb-modal-footer [class|="pageControlContainer"] { @@ -63,7 +63,7 @@ } .vc-rdb-review:hover { - background: var(--message-background-hover, var(--background-message-hover)) !important; + background: var(--message-background-hover) !important; border-radius: 8px; } diff --git a/src/plugins/sendTimestamps/styles.css b/src/plugins/sendTimestamps/styles.css index 08d119b81..0cdc02983 100644 --- a/src/plugins/sendTimestamps/styles.css +++ b/src/plugins/sendTimestamps/styles.css @@ -1,11 +1,11 @@ .vc-st-date-picker { - background-color: var(--input-background-default, var(--input-background)); + background-color: var(--input-background-default); color: var(--text-default); width: 95%; padding: 8px 8px 8px 12px; margin: 1em 0; outline: none; - border: 1px solid var(--input-background-default, var(--input-background)); + border: 1px solid var(--input-background-default); border-radius: 4px; font-weight: 500; font-style: inherit; diff --git a/src/plugins/serverInfo/styles.css b/src/plugins/serverInfo/styles.css index 63193bdec..98b16e7f8 100644 --- a/src/plugins/serverInfo/styles.css +++ b/src/plugins/serverInfo/styles.css @@ -48,7 +48,7 @@ .vc-gp-tab { border-bottom: 2px solid transparent; - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); cursor: pointer; line-height: 14px; } @@ -58,7 +58,7 @@ } .vc-gp-tab:where(.vc-gp-selected, :hover, :focus) { - border-bottom-color: var(--interactive-icon-active, var(--interactive-active)); + border-bottom-color: var(--interactive-icon-active); } .vc-gp-info { @@ -165,5 +165,5 @@ } .vc-gp-scroller [class^="listRow"]:hover { - background-color: var(--background-mod-subtle, var(--background-modifier-hover)); -} + background-color: var(--background-mod-subtle); +} \ No newline at end of file diff --git a/src/plugins/textReplace/index.tsx b/src/plugins/textReplace/index.tsx index acb74ab7c..e22bcf1c8 100644 --- a/src/plugins/textReplace/index.tsx +++ b/src/plugins/textReplace/index.tsx @@ -95,7 +95,7 @@ function renderFindError(find: string) { return null; } catch (e) { return ( - + {String(e)} ); diff --git a/src/plugins/userVoiceShow/style.css b/src/plugins/userVoiceShow/style.css index 0546bd522..fd908bc88 100644 --- a/src/plugins/userVoiceShow/style.css +++ b/src/plugins/userVoiceShow/style.css @@ -1,5 +1,5 @@ .vc-uvs-speaker { - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); display: flex; align-items: center; justify-content: center; @@ -10,7 +10,7 @@ } .vc-uvs-clickable:hover { - color: var(--interactive-icon-hover, var(--interactive-hover)); + color: var(--interactive-icon-hover); } .vc-uvs-profile-speaker { diff --git a/src/plugins/voiceDownload/style.css b/src/plugins/voiceDownload/style.css index 1c4a82027..4e1379e21 100644 --- a/src/plugins/voiceDownload/style.css +++ b/src/plugins/voiceDownload/style.css @@ -1,12 +1,12 @@ .vc-voice-download { width: 24px; height: 24px; - color: var(--interactive-icon-default, var(--interactive-normal)); + color: var(--interactive-icon-default); margin-left: 12px; cursor: pointer; position: relative; } .vc-voice-download:hover { - color: var(--interactive-icon-active, var(--interactive-active)); -} + color: var(--interactive-icon-active); +} \ No newline at end of file diff --git a/src/plugins/voiceMessages/styles.css b/src/plugins/voiceMessages/styles.css index cb3933ce3..5736a3378 100644 --- a/src/plugins/voiceMessages/styles.css +++ b/src/plugins/voiceMessages/styles.css @@ -21,7 +21,7 @@ } .vc-vmsg-preview-indicator { - background: var(--redesign-button-secondary-background, var(--button-secondary-background)); + background: var(--redesign-button-secondary-background); width: 16px; height: 16px; border-radius: 50%; @@ -50,5 +50,5 @@ } .vc-vmsg-error { - color: var(--text-feedback-critical, var(--text-danger, #FF5C5C)); -} + color: var(--text-feedback-critical, #FF5C5C); +} \ No newline at end of file diff --git a/src/utils/discord.tsx b/src/utils/discord.tsx index ca79fc77a..fa1d3e41b 100644 --- a/src/utils/discord.tsx +++ b/src/utils/discord.tsx @@ -22,21 +22,19 @@ import { ChannelActionCreators, ChannelStore, ComponentDispatch, Constants, Flux import { Except } from "type-fest"; import { copyToClipboard } from "./clipboard"; -import { runtimeHashMessageKey, runtimeHashMessageKeyLegacy } from "./intlHash"; +import { runtimeHashMessageKey } from "./intlHash"; import { Logger } from "./Logger"; import { MediaModalItem, MediaModalProps, openMediaModal } from "./modal"; const IntlManagerLogger = new Logger("IntlManager"); -// TODO: remove legacy hashing function once Discord ships new one everywhere for a while - /** * Get an internationalized message from a non hashed key * @param key The plain message key * @param values The values to interpolate, if it's a rich message */ export function getIntlMessage(key: string, values?: Record): any { - return getIntlMessageFromHash(runtimeHashMessageKey(key), values, key) || getIntlMessageFromHash(runtimeHashMessageKeyLegacy(key), values, key); + return getIntlMessageFromHash(runtimeHashMessageKey(key), values, key); } /** diff --git a/src/utils/intlHash.ts b/src/utils/intlHash.ts index b66cd4d82..ac80d1368 100644 --- a/src/utils/intlHash.ts +++ b/src/utils/intlHash.ts @@ -50,18 +50,3 @@ export function runtimeHashMessageKey(key: string): string { BASE64_TABLE[((bytes[3] & 0x03) << 4) | (bytes[4] >> 4)], ].join(""); } - -// Old variant for compatibility -// TODO: remove once Discord shipped new one everywhere for a while -export function runtimeHashMessageKeyLegacy(key: string): string { - const hash = h64(key, 0); - const bytes = numberToBytes(hash); - return [ - BASE64_TABLE[bytes[0] >> 2], - BASE64_TABLE[((bytes[0] & 0x03) << 4) | (bytes[1] >> 4)], - BASE64_TABLE[((bytes[1] & 0x0f) << 2) | (bytes[2] >> 6)], - BASE64_TABLE[bytes[2] & 0x3f], - BASE64_TABLE[bytes[3] >> 2], - BASE64_TABLE[((bytes[3] & 0x03) << 4) | (bytes[3] >> 4)], - ].join(""); -} diff --git a/src/utils/patches.ts b/src/utils/patches.ts index ea22bf2d4..2716003e0 100644 --- a/src/utils/patches.ts +++ b/src/utils/patches.ts @@ -16,68 +16,36 @@ * along with this program. If not, see . */ -import { runtimeHashMessageKey, runtimeHashMessageKeyLegacy } from "./intlHash"; +import { runtimeHashMessageKey } from "./intlHash"; import { Patch, PatchReplacement, ReplaceFn } from "./types"; -// TODO: remove legacy hashing function once Discord ships new one everywhere for a while - -// @ts-expect-error "RegExp.escape" is very new and not yet in DOM types -const escapeRegex = RegExp.escape || ((s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")); - -export function getReplacement(isString: boolean, hashed: string, hash: boolean = false) { - const hasSpecialChars = !Number.isNaN(Number(hashed[0])) || hashed.includes("+") || hashed.includes("/"); - - if (hash) return hashed; - - if (hasSpecialChars) { - return isString - ? `["${hashed}"]` - : String.raw`(?:\["${hashed}"\])`.replaceAll("+", "\\+"); - } - - return isString ? `.${hashed}` : String.raw`(?:\.${hashed})`; -} - -function getCompatReplacement(key: string) { - const hashed = getReplacement(false, runtimeHashMessageKey(key)); - const legacyHashed = getReplacement(false, runtimeHashMessageKeyLegacy(key)); - return String.raw`(?:${hashed}|${legacyHashed})`; -} - -function canonicalizeMatchCompatString(str: string) { - let result = ""; - let lastIndex = 0; - const re = /#{intl::([\w$+/]*)(?:::(\w+))?}/g; - for (const match of str.matchAll(re)) { - result += escapeRegex(str.slice(lastIndex, match.index)); - result += match[2] === "raw" ? getReplacement(false, match[1]) : match[2] === "hash" ? getReplacement(false, runtimeHashMessageKey(match[1]), true) : getCompatReplacement(match[1]); - lastIndex = (match.index ?? 0) + match[0].length; - } - result += escapeRegex(str.slice(lastIndex)); - return new RegExp(result); -} - -export function canonicalizeMatch(match: T): T extends RegExp ? RegExp : string | RegExp { - if (typeof match === "string") { - return canonicalizeMatchCompatString(match) as any; - } - +export function canonicalizeMatch(match: T): T { let partialCanon = typeof match === "string" ? match : match.source; partialCanon = partialCanon.replaceAll(/#{intl::([\w$+/]*)(?:::(\w+))?}/g, (_, key, modifier) => { - if (modifier === "raw") return getReplacement(false, key); - if (modifier === "hash") return getReplacement(false, runtimeHashMessageKey(key), true); - return getCompatReplacement(key); + const hashed = modifier === "raw" ? key : runtimeHashMessageKey(key); + if (modifier === "hash") return hashed; + + const isString = typeof match === "string"; + const hasSpecialChars = !Number.isNaN(Number(hashed[0])) || hashed.includes("+") || hashed.includes("/"); + + if (hasSpecialChars) { + return isString + ? `["${hashed}"]` + : String.raw`(?:\["${hashed}"\])`.replaceAll("+", "\\+"); + } + + return isString ? `.${hashed}` : String.raw`(?:\.${hashed})`; }); if (typeof match === "string") { - return partialCanon as any; + return partialCanon as T; } const canonSource = partialCanon.replaceAll("\\i", String.raw`(?:[A-Za-z_$][\w$]*)`); const canonRegex = new RegExp(canonSource, match.flags); canonRegex.toString = match.toString.bind(match); - return canonRegex as any; + return canonRegex as T; } export function canonicalizeReplace(replace: T, pluginPath: string): T { diff --git a/src/utils/types.ts b/src/utils/types.ts index de87f5c7a..ecf26618b 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -129,6 +129,10 @@ export interface PluginDef { * Whether this plugin should be enabled by default, but can be disabled */ enabledByDefault?: boolean; + /** + * Whether enabling or disabling this plugin requires a restart. Defaults to true if the plugin has patches. + */ + requiresRestart?: boolean; /** * When to call the start() method * @default StartAt.WebpackReady diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index 0c7473133..46bc56d12 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -221,8 +221,7 @@ export const DisplayProfileUtils: t.DisplayProfileUtils = mapMangledModuleLazy(/ export const DateUtils: t.DateUtils = mapMangledModuleLazy("millisecondsInUnit:", { calendarFormat: filters.byCode("sameElse"), dateFormat: filters.byCode('":'), - // TODO: the +? are for compat with the old version - Remove them once no longer needed - isSameDay: filters.byCode(/Math\.abs\(\+?\i-\+?\i\)/), + isSameDay: filters.byCode(/Math\.abs\(\i-\i\)/), diffAsUnits: filters.byCode("days:0", "millisecondsInUnit") });