fix(app): show guild initials until the guild icon has painted (#1932)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-24 12:48:11 +02:00
1 parent 299172c8aa
commit 919e890011
2 files changed
+8 -14

No files matched your search

@@ -313,6 +313,7 @@ export const GuildListItemPresentation = forwardRef<
[backgroundImage, draggingCursor], [backgroundImage, draggingCursor],
); );
const guildIconTarget = useMemo(() => ({borderRadius: iconBorderRadius}), [iconBorderRadius]); const guildIconTarget = useMemo(() => ({borderRadius: iconBorderRadius}), [iconBorderRadius]);
const hasPaintedIcon = backgroundImage != null;
return ( return (
<LongPressable <LongPressable
{...domProps} {...domProps}
@@ -364,7 +365,7 @@ export const GuildListItemPresentation = forwardRef<
tabIndex={-1} tabIndex={-1}
className={clsx( className={clsx(
styles.guildIcon, styles.guildIcon,
guild.icon == null && styles.guildIconNoImage, !hasPaintedIcon && styles.guildIconNoImage,
isSelected && styles.guildIconSelected, isSelected && styles.guildIconSelected,
)} )}
to={guildIconTarget} to={guildIconTarget}
@@ -374,7 +375,7 @@ export const GuildListItemPresentation = forwardRef<
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"
> >
{guild.icon == null && ( {!hasPaintedIcon && (
<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"
@@ -55,13 +55,6 @@ function resolveGuildIconBackgroundImage(iconURL: string, displayedIconURL: stri
return `url(${displayedIconURL})`; return `url(${displayedIconURL})`;
} }
function resolveInitiallyLoadedImageURL(imageURL: string): string | null {
if (ImageCacheUtils.hasImage(imageURL)) {
return imageURL;
}
return null;
}
export function useGuildListItemInteraction({ export function useGuildListItemInteraction({
guild, guild,
isDesktopLayout, isDesktopLayout,
@@ -79,16 +72,16 @@ export function useGuildListItemInteraction({
}); });
const iconURL = AvatarSourceUtils.getGuildIconURL(guild, false); const iconURL = AvatarSourceUtils.getGuildIconURL(guild, false);
const hoverIconURL = AvatarSourceUtils.getGuildIconURL(guild, true); const hoverIconURL = AvatarSourceUtils.getGuildIconURL(guild, true);
const [loadedAnimatedURL, setLoadedAnimatedURL] = useState<string | null>(() => const isAnimatableIcon = hoverIconURL !== iconURL;
resolveInitiallyLoadedImageURL(hoverIconURL), const [loadedAnimatedURL, setLoadedAnimatedURL] = useState<string | null>(null);
);
const [bottomSheetOpen, setBottomSheetOpen] = useState(false); const [bottomSheetOpen, setBottomSheetOpen] = useState(false);
useEffect(() => ImageCacheUtils.pinImage(iconURL), [iconURL]); useEffect(() => ImageCacheUtils.pinImage(iconURL), [iconURL]);
useEffect(() => { useEffect(() => {
if (!isAnimatableIcon) return;
if (!isHovering && !contextMenuOpen) return; if (!isHovering && !contextMenuOpen) return;
if (loadedAnimatedURL === hoverIconURL) return; if (loadedAnimatedURL === hoverIconURL) return;
return ImageCacheUtils.loadImage(hoverIconURL, () => setLoadedAnimatedURL(hoverIconURL)); return ImageCacheUtils.loadImage(hoverIconURL, () => setLoadedAnimatedURL(hoverIconURL));
}, [contextMenuOpen, hoverIconURL, isHovering, loadedAnimatedURL]); }, [contextMenuOpen, hoverIconURL, isAnimatableIcon, isHovering, loadedAnimatedURL]);
const handleSelect = useCallback(() => { const handleSelect = useCallback(() => {
markDirectSelection(DirectSelectionSurface.GUILD_RAIL); markDirectSelection(DirectSelectionSurface.GUILD_RAIL);
preloadChannelNow(); preloadChannelNow();
@@ -126,7 +119,7 @@ export function useGuildListItemInteraction({
if (!isSortingList && isMobileExperience) setBottomSheetOpen(true); if (!isSortingList && isMobileExperience) setBottomSheetOpen(true);
}, [isMobileExperience, isSortingList]); }, [isMobileExperience, isSortingList]);
const handleCloseBottomSheet = useCallback(() => setBottomSheetOpen(false), []); const handleCloseBottomSheet = useCallback(() => setBottomSheetOpen(false), []);
const shouldPlayAnimated = (isHovering || contextMenuOpen) && loadedAnimatedURL === hoverIconURL; const shouldPlayAnimated = isAnimatableIcon && (isHovering || contextMenuOpen) && loadedAnimatedURL === hoverIconURL;
const displayedIconURL = resolveDisplayedGuildIconURL({hoverIconURL, iconURL, shouldPlayAnimated}); const displayedIconURL = resolveDisplayedGuildIconURL({hoverIconURL, iconURL, shouldPlayAnimated});
const backgroundImage = resolveGuildIconBackgroundImage(iconURL, displayedIconURL); const backgroundImage = resolveGuildIconBackgroundImage(iconURL, displayedIconURL);
return { return {