fix(media): keep self-host media loading after restarts (#3283)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-08 17:28:18 +02:00
1 parent bd56174870
commit 46a356cc40
59 files changed
+1238 -499

No files matched your search

@@ -16,6 +16,7 @@ import {GuildHeaderBottomSheet} from '@app/features/guild/components/bottomsheet
import {GuildBadge} from '@app/features/guild/components/GuildBadge';
import {GuildHeaderPopout} from '@app/features/guild/components/popouts/GuildHeaderPopout';
import type {Guild} from '@app/features/guild/models/Guild';
import {useRecoveringBackgroundImageURL} from '@app/features/messaging/hooks/useImageRecovery';
import {GuildContextMenu} from '@app/features/ui/action_menu/GuildContextMenu';
import * as ContextMenuCommands from '@app/features/ui/commands/ContextMenuCommands';
import MobileLayout from '@app/features/ui/state/MobileLayout';
@@ -74,6 +75,7 @@ export const GuildHeader = observer(({guild, banner}: {guild: Guild; banner: Gui
[guild],
);
const guildNameRef = useRef<HTMLSpanElement | null>(null);
const bannerImageURL = useRecoveringBackgroundImageURL(banner.imageUrl ?? '');
const badgeVisible = resolveGuildBadgeVisible(guild.features);
const bannerPlacement = resolveSkeletonBannerPlacement(banner.hasBanner, banner.isDetached);
useSkeletonLayoutReport(() => {
@@ -98,7 +100,7 @@ export const GuildHeader = observer(({guild, banner}: {guild: Guild; banner: Gui
style={{
height: banner.bannerHeight,
y: banner.imageShift,
backgroundImage: `url(${banner.imageUrl})`,
backgroundImage: bannerImageURL == null ? undefined : `url(${bannerImageURL})`,
}}
data-flx="app.guild-header.banner-image"
/>
@@ -29,6 +29,7 @@ import GuildReadState from '@app/features/guild/state/GuildReadState';
import {getInitialsFromName, truncateInitials} from '@app/features/guild/utils/GuildInitialsUtils';
import {MENTION_COUNT_ARIA_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors';
import {isKeyboardActivationKey} from '@app/features/input/utils/KeyboardUtils';
import {useRecoveringBackgroundImageURL} from '@app/features/messaging/hooks/useImageRecovery';
import {useLocation} from '@app/features/platform/components/router/RouterReact';
import Theme from '@app/features/theme/state/Theme';
import {Edge} from '@app/features/ui/AxisOrientation';
@@ -766,8 +767,8 @@ interface MiniGuildIconProps {
}
const MiniGuildIcon = observer(({guild}: MiniGuildIconProps) => {
const iconURL = AvatarSourceUtils.getGuildIconURL(guild, false);
if (iconURL !== '') {
const iconURL = useRecoveringBackgroundImageURL(AvatarSourceUtils.getGuildIconURL(guild, false));
if (iconURL != null) {
return (
<flx-app-mini-guild-icon
className={flxElementClassName(styles.miniGuildIcon)}
@@ -6,6 +6,7 @@ import {useContextMenuHoverState} from '@app/features/app/hooks/useContextMenuHo
import {useHover} from '@app/features/app/hooks/useHover';
import type {Guild} from '@app/features/guild/models/Guild';
import {isKeyboardActivationKey} from '@app/features/input/utils/KeyboardUtils';
import {useRecoveringBackgroundImageURL} from '@app/features/messaging/hooks/useImageRecovery';
import * as ImageCacheUtils from '@app/features/messaging/utils/ImageCacheUtils';
import * as NavigationCommands from '@app/features/navigation/commands/NavigationCommands';
import {GuildContextMenu} from '@app/features/ui/action_menu/GuildContextMenu';
@@ -48,8 +49,8 @@ function resolveDisplayedGuildIconURL(query: DisplayedGuildIconURLQuery): string
return query.iconURL;
}
function resolveGuildIconBackgroundImage(iconURL: string, displayedIconURL: string): string | null {
if (iconURL.length === 0) {
function resolveGuildIconBackgroundImage(paintableIconURL: string | null, displayedIconURL: string): string | null {
if (paintableIconURL == null) {
return null;
}
return `url(${displayedIconURL})`;
@@ -75,7 +76,7 @@ export function useGuildListItemInteraction({
const isAnimatableIcon = hoverIconURL !== iconURL;
const [loadedAnimatedURL, setLoadedAnimatedURL] = useState<string | null>(null);
const [bottomSheetOpen, setBottomSheetOpen] = useState(false);
useEffect(() => ImageCacheUtils.pinImage(iconURL), [iconURL]);
const paintableIconURL = useRecoveringBackgroundImageURL(iconURL);
useEffect(() => {
if (!isAnimatableIcon) return;
if (!isHovering && !contextMenuOpen) return;
@@ -121,7 +122,7 @@ export function useGuildListItemInteraction({
const handleCloseBottomSheet = useCallback(() => setBottomSheetOpen(false), []);
const shouldPlayAnimated = isAnimatableIcon && (isHovering || contextMenuOpen) && loadedAnimatedURL === hoverIconURL;
const displayedIconURL = resolveDisplayedGuildIconURL({hoverIconURL, iconURL, shouldPlayAnimated});
const backgroundImage = resolveGuildIconBackgroundImage(iconURL, displayedIconURL);
const backgroundImage = resolveGuildIconBackgroundImage(paintableIconURL, displayedIconURL);
return {
hoverRef,
isHovering,