fix(app): restore the guild list item hover tooltip (#1687)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-16 23:04:55 +02:00
1 parent 8a14281b87
commit 40da982f57
1 file changed
+65 -29
@@ -8,6 +8,7 @@ import type {GuildListIndicatorBarTarget} from '@app/features/app/components/lay
import type {GuildListItemDragAndDrop} from '@app/features/app/components/layout/sidebar_nav/UseGuildListItemDragAndDrop'; import type {GuildListItemDragAndDrop} from '@app/features/app/components/layout/sidebar_nav/UseGuildListItemDragAndDrop';
import {VoiceBadge, type VoiceBadgeActivity} from '@app/features/app/components/layout/sidebar_nav/VoiceBadge'; import {VoiceBadge, type VoiceBadgeActivity} from '@app/features/app/components/layout/sidebar_nav/VoiceBadge';
import {DropPlacement} from '@app/features/app/components/layout/types/DndTypes'; import {DropPlacement} from '@app/features/app/components/layout/types/DndTypes';
import {useMergeRefs} from '@app/features/app/hooks/useMergeRefs';
import type {Guild} from '@app/features/guild/models/Guild'; import type {Guild} from '@app/features/guild/models/Guild';
import Guilds from '@app/features/guild/state/Guilds'; import Guilds from '@app/features/guild/state/Guilds';
import { import {
@@ -27,7 +28,7 @@ import {GuildFeatures} from '@fluxer/constants/src/GuildConstants';
import {ExclamationMarkIcon, PauseIcon} from '@phosphor-icons/react'; import {ExclamationMarkIcon, PauseIcon} from '@phosphor-icons/react';
import {clsx} from 'clsx'; import {clsx} from 'clsx';
import type React from 'react'; import type React from 'react';
import {useMemo} from 'react'; import {forwardRef, useMemo} from 'react';
import invariant from 'tiny-invariant'; import invariant from 'tiny-invariant';
const GuildListItemIcon = createAnimeFlxElement('flx-app-guild-list-item-icon'); const GuildListItemIcon = createAnimeFlxElement('flx-app-guild-list-item-icon');
@@ -267,42 +268,77 @@ export interface GuildListItemPresentationProps {
readonly onLongPress: () => void; readonly onLongPress: () => void;
} }
export function GuildListItemPresentation(props: GuildListItemPresentationProps) { type GuildListItemPresentationDomProps = Omit<
const rawInitials = getInitialsFromName(props.guild.name); React.HTMLAttributes<HTMLElement>,
'onClick' | 'onContextMenu' | 'onKeyDown'
>;
export const GuildListItemPresentation = forwardRef<
HTMLElement,
GuildListItemPresentationProps & GuildListItemPresentationDomProps
>(function GuildListItemPresentation(
{
backgroundImage,
canManageGuild,
contextMenuOpen,
dragAndDrop,
focusRingTargetRef,
guild,
guildARIALabel,
hasVoiceActivity,
iconBorderRadius,
indicatorTarget,
isSelected,
isSortingList,
mentionCount,
onClick,
onContextMenu,
onKeyDown,
onLongPress,
showGuildIndicator,
surfaceRef,
voiceBadgeActivity,
...domProps
},
forwardedRef,
) {
const rootRef = useMergeRefs([surfaceRef, forwardedRef]);
const rawInitials = getInitialsFromName(guild.name);
const initialsLength = resolveInitialsLength(rawInitials); const initialsLength = resolveInitialsLength(rawInitials);
const dropIndicator = resolveDropIndicator(props.dragAndDrop); const dropIndicator = resolveDropIndicator(dragAndDrop);
const motion = resolveGuildListItemMotion(Accessibility.useReducedMotion); const motion = resolveGuildListItemMotion(Accessibility.useReducedMotion);
const draggingCursor = resolveDraggingCursor(props.dragAndDrop); const draggingCursor = resolveDraggingCursor(dragAndDrop);
const guildIconStyle = useMemo( const guildIconStyle = useMemo(
() => resolveGuildIconStyle(props.backgroundImage, draggingCursor), () => resolveGuildIconStyle(backgroundImage, draggingCursor),
[props.backgroundImage, draggingCursor], [backgroundImage, draggingCursor],
); );
const guildIconTarget = useMemo(() => ({borderRadius: props.iconBorderRadius}), [props.iconBorderRadius]); const guildIconTarget = useMemo(() => ({borderRadius: iconBorderRadius}), [iconBorderRadius]);
return ( return (
<LongPressable <LongPressable
{...domProps}
className={clsx( className={clsx(
styles.guildListItem, styles.guildListItem,
styles.guildListReorderTarget, styles.guildListReorderTarget,
props.contextMenuOpen && styles.contextMenuHover, contextMenuOpen && styles.contextMenuHover,
dropIndicator === Edge.TOP && styles.dropIndicatorTop, dropIndicator === Edge.TOP && styles.dropIndicatorTop,
dropIndicator === Edge.BOTTOM && styles.dropIndicatorBottom, dropIndicator === Edge.BOTTOM && styles.dropIndicatorBottom,
dropIndicator === DropPlacement.COMBINE && styles.dropIndicatorCombine, dropIndicator === DropPlacement.COMBINE && styles.dropIndicatorCombine,
)} )}
aria-label={props.guildARIALabel} aria-label={guildARIALabel}
onClick={props.onClick} onClick={onClick}
onContextMenu={props.onContextMenu} onContextMenu={onContextMenu}
onKeyDown={props.onKeyDown} onKeyDown={onKeyDown}
ref={props.surfaceRef} ref={rootRef}
role="button" role="button"
tabIndex={0} tabIndex={0}
data-guild-list-focus-item="true" data-guild-list-focus-item="true"
onLongPress={props.onLongPress} onLongPress={onLongPress}
disabled={false} disabled={false}
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-list-item.click" data-flx="app.sidebar-nav.guild-list-item-presentation.guild-list-item.click"
{...ariaCurrentPage(props.isSelected)} {...ariaCurrentPage(isSelected)}
> >
<AnimePresence data-flx="app.sidebar-nav.guild-list-item-presentation.anime-presence"> <AnimePresence data-flx="app.sidebar-nav.guild-list-item-presentation.anime-presence">
{!props.isSortingList && props.showGuildIndicator && ( {!isSortingList && showGuildIndicator && (
<flx-app-guild-list-item-indicator <flx-app-guild-list-item-indicator
className={flxElementClassName(styles.guildIndicator)} className={flxElementClassName(styles.guildIndicator)}
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-indicator" data-flx="app.sidebar-nav.guild-list-item-presentation.guild-indicator"
@@ -310,7 +346,7 @@ export function GuildListItemPresentation(props: GuildListItemPresentationProps)
<AnimeSpan <AnimeSpan
className={styles.guildIndicatorBar} className={styles.guildIndicatorBar}
from={false} from={false}
to={props.indicatorTarget} to={indicatorTarget}
leave={motion.indicatorLeave} leave={motion.indicatorLeave}
tween={{duration: motion.indicatorTweenDuration, ease: [0.25, 0.1, 0.25, 1]}} tween={{duration: motion.indicatorTweenDuration, ease: [0.25, 0.1, 0.25, 1]}}
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-indicator-bar" data-flx="app.sidebar-nav.guild-list-item-presentation.guild-indicator-bar"
@@ -323,12 +359,12 @@ export function GuildListItemPresentation(props: GuildListItemPresentationProps)
data-flx="app.sidebar-nav.guild-list-item-presentation.relative" data-flx="app.sidebar-nav.guild-list-item-presentation.relative"
> >
<GuildListItemIcon <GuildListItemIcon
ref={props.focusRingTargetRef} ref={focusRingTargetRef}
tabIndex={-1} tabIndex={-1}
className={clsx( className={clsx(
styles.guildIcon, styles.guildIcon,
props.guild.icon == null && styles.guildIconNoImage, guild.icon == null && styles.guildIconNoImage,
props.isSelected && styles.guildIconSelected, isSelected && styles.guildIconSelected,
)} )}
to={guildIconTarget} to={guildIconTarget}
from={false} from={false}
@@ -337,7 +373,7 @@ export function GuildListItemPresentation(props: GuildListItemPresentationProps)
style={guildIconStyle} style={guildIconStyle}
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-icon" data-flx="app.sidebar-nav.guild-list-item-presentation.guild-icon"
> >
{props.guild.icon == null && ( {guild.icon == null && (
<span <span
className={styles.guildIconInitials} className={styles.guildIconInitials}
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-icon-initials" data-flx="app.sidebar-nav.guild-list-item-presentation.guild-icon-initials"
@@ -347,15 +383,15 @@ export function GuildListItemPresentation(props: GuildListItemPresentationProps)
)} )}
</GuildListItemIcon> </GuildListItemIcon>
<GuildListItemBadges <GuildListItemBadges
guild={props.guild} guild={guild}
mentionCount={props.mentionCount} mentionCount={mentionCount}
canManageGuild={props.canManageGuild} canManageGuild={canManageGuild}
hasVoiceActivity={props.hasVoiceActivity} hasVoiceActivity={hasVoiceActivity}
voiceBadgeActivity={props.voiceBadgeActivity} voiceBadgeActivity={voiceBadgeActivity}
data-flx="app.sidebar-nav.guild-list-item-presentation.guild-list-item-badges" data-flx="app.sidebar-nav.guild-list-item-presentation.guild-list-item-badges"
/> />
</flx-app-guild-list-item-frame> </flx-app-guild-list-item-frame>
{renderCombinePreview(props.guild, props.dragAndDrop, dropIndicator)} {renderCombinePreview(guild, dragAndDrop, dropIndicator)}
</LongPressable> </LongPressable>
); );
} });