Enable collectibles on mobile clients.
All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 1s

Fetch and cache the published catalog in the renderer when Electron is unavailable, then download selected CDN assets directly for Matrix upload.
This commit is contained in:
2026-08-24 19:52:50 +10:00
parent 87c9f59826
commit c34cfaf33f
2 changed files with 114 additions and 36 deletions

View File

@@ -14,8 +14,8 @@ import {
DiscordCollectibleItem,
collectibleKindLabel,
defaultPreviewAspectRatio,
fetchPublishedCollectiblesCatalog,
groupCollectibleItems,
isElectronCollectiblesAvailable,
uploadCollectibleToMatrix,
variantItemLabel,
} from '../../../utils/discordCollectibles';
@@ -347,24 +347,26 @@ export function CollectiblesSection({ collectibles, onApply }: CollectiblesSecti
const [error, setError] = useState<string>();
const [selectedByGroup, setSelectedByGroup] = useState<Record<string, string>>({});
const desktopAvailable = isElectronCollectiblesAvailable();
const loadCatalog = useCallback(async (force = false) => {
if (!desktopAvailable) return;
setCatalogLoading(true);
setCatalogError(undefined);
try {
const result = await window.electron!.discordCollectibles!.fetchCatalog(force);
if (!result?.success || !result.data?.items) {
throw new Error(result?.error || 'Failed to load Discord catalog.');
const desktopCatalog = window.electron?.discordCollectibles;
if (desktopCatalog) {
const result = await desktopCatalog.fetchCatalog(force);
if (!result?.success || !result.data?.items) {
throw new Error(result?.error || 'Failed to load collectibles catalog.');
}
setItems(result.data.items as DiscordCollectibleItem[]);
} else {
setItems(await fetchPublishedCollectiblesCatalog(force));
}
setItems(result.data.items as DiscordCollectibleItem[]);
} catch (e) {
setCatalogError(e instanceof Error ? e.message : 'Failed to load catalog.');
setItems([]);
}
setCatalogLoading(false);
}, [desktopAvailable]);
}, []);
useEffect(() => {
loadCatalog();
@@ -431,17 +433,6 @@ export function CollectiblesSection({ collectibles, onApply }: CollectiblesSecti
kind === 'avatar_decoration' && css.CollectibleGroupGridDecorations
);
if (!desktopAvailable) {
return (
<Box direction="Column" gap="200">
<Text size="T200" style={{ opacity: 0.8 }}>
Discord profile overlays are available in the Paarrot desktop app. Assets are fetched live from
Discord and uploaded to your Matrix profile when you pick one.
</Text>
</Box>
);
}
return (
<Box direction="Column" gap="300">
<Text size="T200" style={{ opacity: 0.8 }}>