fix(desktop): fetch theme CSS via the local resource proxy (#3326)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-08 23:21:27 +02:00
1 parent d0b4816a5f
commit fff67ed9af
3 files changed
+7 -7

No files matched your search

@@ -8,7 +8,7 @@ import {useArboriumHighlightedHtml} from '@app/features/code_highlighting/utils/
import {COPY_CODE_DESCRIPTOR, SOMETHING_WENT_WRONG_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors'; import {COPY_CODE_DESCRIPTOR, SOMETHING_WENT_WRONG_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors';
import {Logger} from '@app/features/platform/utils/AppLogger'; import {Logger} from '@app/features/platform/utils/AppLogger';
import styles from '@app/features/theme/components/modals/ThemeAcceptModal.module.css'; import styles from '@app/features/theme/components/modals/ThemeAcceptModal.module.css';
import {buildThemeCssProxyUrl} from '@app/features/theme/utils/ThemeUtils'; import {buildThemeCssFetchUrl} from '@app/features/theme/utils/ThemeUtils';
import {Button} from '@app/features/ui/button/Button'; import {Button} from '@app/features/ui/button/Button';
import * as ModalCommands from '@app/features/ui/commands/ModalCommands'; import * as ModalCommands from '@app/features/ui/commands/ModalCommands';
import * as ToastCommands from '@app/features/ui/commands/ToastCommands'; import * as ToastCommands from '@app/features/ui/commands/ToastCommands';
@@ -56,7 +56,7 @@ export const ThemeAcceptModal = observer(function ThemeAcceptModal({themeId, run
setFetchStatus('loading'); setFetchStatus('loading');
setFetchError(null); setFetchError(null);
try { try {
const themeUrl = buildThemeCssProxyUrl(runtimeSnapshot, themeId); const themeUrl = buildThemeCssFetchUrl(runtimeSnapshot, themeId);
if (!themeUrl) { if (!themeUrl) {
throw new Error('Media endpoint not configured'); throw new Error('Media endpoint not configured');
} }
@@ -2,7 +2,7 @@
import type {RuntimeConfigSnapshot} from '@app/features/app/state/InstanceSnapshotStore'; import type {RuntimeConfigSnapshot} from '@app/features/app/state/InstanceSnapshotStore';
import {Logger} from '@app/features/platform/utils/AppLogger'; import {Logger} from '@app/features/platform/utils/AppLogger';
import {buildThemeCssProxyUrl} from '@app/features/theme/utils/ThemeUtils'; import {buildThemeCssFetchUrl} from '@app/features/theme/utils/ThemeUtils';
import {useEffect, useState} from 'react'; import {useEffect, useState} from 'react';
const logger = new Logger('useThemeExists'); const logger = new Logger('useThemeExists');
@@ -15,7 +15,7 @@ export const useThemeExists = (themeId: string, runtimeSnapshot: RuntimeConfigSn
let cancelled = false; let cancelled = false;
const checkThemeExists = async () => { const checkThemeExists = async () => {
try { try {
const themeUrl = buildThemeCssProxyUrl(runtimeSnapshot, themeId); const themeUrl = buildThemeCssFetchUrl(runtimeSnapshot, themeId);
if (themeUrl == null) throw new Error('Media endpoint not configured'); if (themeUrl == null) throw new Error('Media endpoint not configured');
const response = await fetch(themeUrl, {method: 'HEAD'}); const response = await fetch(themeUrl, {method: 'HEAD'});
if (!response.ok) throw new Error('Theme not found'); if (!response.ok) throw new Error('Theme not found');
@@ -3,7 +3,7 @@
import {type RuntimeConfigSnapshot, runtimeInstanceKey} from '@app/features/app/state/InstanceSnapshotStore'; import {type RuntimeConfigSnapshot, runtimeInstanceKey} from '@app/features/app/state/InstanceSnapshotStore';
import RuntimeConfig from '@app/features/app/state/RuntimeConfig'; import RuntimeConfig from '@app/features/app/state/RuntimeConfig';
import * as CodeLinkUtils from '@app/features/messaging/utils/CodeLinkUtils'; import * as CodeLinkUtils from '@app/features/messaging/utils/CodeLinkUtils';
import {buildMediaProxyURLForInstance} from '@app/features/messaging/utils/MediaProxyUtils'; import {wrapDesktopLocalResourceURLForInstance} from '@app/features/messaging/utils/DesktopResourceUrl';
const OFFICIAL_THEME_URL_BASES = Object.freeze([ const OFFICIAL_THEME_URL_BASES = Object.freeze([
'https://fluxer.app/theme', 'https://fluxer.app/theme',
@@ -47,12 +47,12 @@ function buildThemeCssUrl(endpoint: string | null | undefined, themeId: string):
return `${base}/themes/${themeId}.css`; return `${base}/themes/${themeId}.css`;
} }
export function buildThemeCssProxyUrl(snapshot: RuntimeConfigSnapshot, themeId: string): string | null { export function buildThemeCssFetchUrl(snapshot: RuntimeConfigSnapshot, themeId: string): string | null {
const rawUrl = buildThemeCssUrl(snapshot.mediaEndpoint, themeId); const rawUrl = buildThemeCssUrl(snapshot.mediaEndpoint, themeId);
if (!rawUrl) return null; if (!rawUrl) return null;
const instanceKey = runtimeInstanceKey(snapshot); const instanceKey = runtimeInstanceKey(snapshot);
if (instanceKey == null) { if (instanceKey == null) {
throw new Error(`Theme runtime has no usable instance key (apiEndpoint: "${snapshot.apiEndpoint}")`); throw new Error(`Theme runtime has no usable instance key (apiEndpoint: "${snapshot.apiEndpoint}")`);
} }
return buildMediaProxyURLForInstance(rawUrl, instanceKey); return wrapDesktopLocalResourceURLForInstance(rawUrl, instanceKey);
} }