From 97e203c3ed3cfcb22de100fd986f6435b9654c46 Mon Sep 17 00:00:00 2001 From: Etorix <92535668+EtorixDev@users.noreply.github.com> Date: Wed, 26 Aug 2026 08:16:15 -0700 Subject: [PATCH] SMYN: Remove has selectors. (#1325) * Fix. * Fixes. * Fixes. --- src/plugins/showMeYourName/index.tsx | 59 +++++++++++++++++++++++----- src/plugins/showMeYourName/style.css | 20 +++++++--- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/plugins/showMeYourName/index.tsx b/src/plugins/showMeYourName/index.tsx index a12d9a21a..b4e27e874 100644 --- a/src/plugins/showMeYourName/index.tsx +++ b/src/plugins/showMeYourName/index.tsx @@ -469,6 +469,30 @@ function shouldAnimateNameEffects(isHovered: boolean, isEffectVisible = true): b return isHovered || (isEffectVisible && settings.store.alwaysAnimateEffects); } +function isNativeGradientGlowActive( + styles: DisplayNameStyles | null | undefined, + animate: boolean, +): boolean { + return AccessibilityStore.displayNameStylesEnabled + && animate + && styles?.effectId === DisplayNameEffects.GRADIENT + && settings.store.gradientGlow + && !AccessibilityStore.useReducedMotion; +} + +function getNativeGradientGlowOverflowClassName( + styles: DisplayNameStyles | null | undefined, + effectDisplayType: number, + className: string, +): string { + return SMYNC(className, { + "smyn-native-gradient-glow-overflow": isNativeGradientGlowActive( + styles, + effectDisplayType === DisplayNameEffectDisplayTypes.ANIMATED, + ), + }); +} + function getDisplayNameEffectClassName( styles: DisplayNameStyles | null | undefined, effectDisplayType: number, @@ -476,18 +500,22 @@ function getDisplayNameEffectClassName( const useGradientAnimationOverride = needsGradientAnimationOverride(styles) && effectDisplayType === DisplayNameEffectDisplayTypes.ANIMATED && !AccessibilityStore.useReducedMotion; + const nativeGradientGlowActive = isNativeGradientGlowActive( + styles, + effectDisplayType === DisplayNameEffectDisplayTypes.ANIMATED, + ); return [ "smyn-native-effect", useGradientAnimationOverride && "smyn-native-gradient-animated", styles?.effectId === DisplayNameEffects.GRADIENT && settings.store.gradientGlow && "smyn-native-gradient-glow", - useGradientAnimationOverride && styles?.effectId === DisplayNameEffects.GRADIENT && settings.store.gradientGlow && "smyn-native-gradient-glow-active", + nativeGradientGlowActive && "smyn-native-gradient-glow-active", styles?.effectId === DisplayNameEffects.POP && "smyn-native-pop", styles?.effectId === DisplayNameEffects.GUMMY && "smyn-native-gummy", styles?.effectId === DisplayNameEffects.GUMMY - && effectDisplayType === DisplayNameEffectDisplayTypes.ANIMATED - && !AccessibilityStore.useReducedMotion - && "smyn-native-gummy-animated", + && effectDisplayType === DisplayNameEffectDisplayTypes.ANIMATED + && !AccessibilityStore.useReducedMotion + && "smyn-native-gummy-animated", ].filter(Boolean).join(" "); } @@ -755,6 +783,7 @@ function renderUsername( const shouldAnimatePrimaryGradient = shouldShowGradientGlow && !AccessibilityStore.useReducedMotion; const shouldAnimateSecondaryEffects = shouldShowHoverEffects && animateEffects && !ignoreEffects; const shouldShowSecondaryDisplayNameEffect = shouldShowDisplayNameEffect && !ignoreEffects; + const nativeGradientGlowActive = isNativeGradientGlowActive(authorDisplayNameStyles, shouldShowHoverEffects); const firstDataText = mentionSymbol + first.name; const secondDataText = second && shouldAnimateSecondaryEffects ? second.name : ""; @@ -799,7 +828,7 @@ function renderUsername( ...topLevelStyle, ...(shouldShowDisplayNameEffect ? {} : topRoleStyle?.normal.original || {}) }} - className="smyn-container" + className={SMYNC("smyn-container", { "smyn-native-gradient-glow-overflow": nativeGradientGlowActive })} > {mentionSymbol && {mentionSymbol}} {( @@ -1294,12 +1323,21 @@ export default definePlugin({ ], }, { - // Set Discord's existing friends-row hover state on pointer entry. + // Set and expose Discord's existing friends-row hover state. find: "handleMouseEnter=()=>{let{isFocused:", - replacement: { - match: /(?<=handleMouseEnter=\(\)=>\{let\{isFocused:\i,isActive:\i,onOtherHover:\i}=this.props,\{isContextMenuActive:\i}=this.state;this.setState\(\{hovered:)\i(?=}\),)/, - replace: "!0" - }, + group: true, + replacement: [ + { + // Treat pointer entry as hover even when the row does not have keyboard focus. + match: /(?<=handleMouseEnter=\(\)=>\{let\{isFocused:\i,isActive:\i,onOtherHover:\i}=this.props,\{isContextMenuActive:\i}=this.state;this.setState\(\{hovered:)\i(?=}\),)/, + replace: "!0" + }, + { + // Mark the active gradient row so its native glow can animate without :has(). + match: /(?<=let\{role:\i,\.\.\.\i\}=\i,)(\i)=(\i\(\)\(\i,\i\.\i,null!=\i\?\{\[\i\]:\i\|\|\i\}:null,\{\[\i\.\i\]:\i\|\|\i\}\))(?=;return null!=\i\?)/, + replace: "$1=$self.getNativeGradientGlowOverflowClassName(this.props.user.displayNameStyles,$self.getDisplayNameEffectDisplayType(this.state.hovered||this.props.isActive||this.state.isContextMenuActive,$self.settings.store.styleFriendsList),$2)" + } + ], }, { // Preserve display name styles when SMYN replaces the friends-list name. @@ -1510,6 +1548,7 @@ export default definePlugin({ getActiveNowNameElement, getDisplayNameEffectClassName, getDisplayNameEffectDisplayType, + getNativeGradientGlowOverflowClassName, shouldAnimateNameEffects, getTypingMemberListProfilesReactionsVoiceNameText, getTypingMemberListProfilesReactionsVoiceNameElement diff --git a/src/plugins/showMeYourName/style.css b/src/plugins/showMeYourName/style.css index 02dc4fe66..736487d18 100644 --- a/src/plugins/showMeYourName/style.css +++ b/src/plugins/showMeYourName/style.css @@ -54,7 +54,8 @@ font-weight: 500; } -.smyn-native-gradient-animated > [data-username-with-effects] { +.smyn-native-gradient-animated > [data-username-with-effects], +:where(.smyn-native-gradient-glow-overflow) .smyn-native-gradient-glow > [data-username-with-effects] { animation: smyn-animation var(--smyn-gradient-duration, 1.5s) linear infinite; background-image: linear-gradient(to right, var(--custom-display-name-styles-gradient-stops), var(--custom-display-name-styles-main-color) 100%) !important; background-size: 100px auto !important; @@ -75,14 +76,21 @@ } .smyn-native-gradient-glow-active > [data-username-with-effects], -:where(span, div):has(> .smyn-native-gradient-glow-active), -:where(span, div):has(> * > .smyn-native-gradient-glow-active), -:where(span, div):has(> * > * > .smyn-native-gradient-glow-active) { +.smyn-native-gradient-glow-overflow, +.smyn-native-gradient-glow-overflow > .smyn-name-group, +.smyn-native-gradient-glow-overflow > .smyn-name-group > .smyn-name, +.smyn-native-gradient-glow-overflow :where( + [class^="text_"], + [class*=" text_"], + [class^="username_"], + [class*=" username_"] +) { overflow: visible; } -.smyn-native-gradient-glow-active > [data-username-with-effects]::after { - opacity: .7; +.smyn-native-gradient-glow-active > [data-username-with-effects]::after, +:where(.smyn-native-gradient-glow-overflow) .smyn-native-gradient-glow > [data-username-with-effects]::after { + opacity: .7 !important; transition: opacity .1s ease-in-out; }