Add Discord collectibles to profiles, messages, and settings.
All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 1s

Integrate profile effects, nameplates, and avatar decorations with live catalog browsing, Matrix profile storage, and rendering across user heroes, DMs, messages, and the sidebar avatar.
This commit is contained in:
2026-08-24 00:54:48 +10:00
parent 6cb1e14632
commit 0cbc5d9a1c
25 changed files with 2473 additions and 174 deletions

View File

@@ -11,6 +11,9 @@ import { nameInitials } from '../../../utils/common';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
import { Settings } from '../../../features/settings';
import { useUserProfile } from '../../../hooks/useUserProfile';
import { useOtherUserCollectibles } from '../../../hooks/useUserCollectibles';
import { pickAvatarDecorationUrl } from '../../../utils/collectibleAssets';
import * as avatarDecorationCss from '../../../styles/AvatarDecoration.css';
import { Modal500 } from '../../../components/Modal500';
import { AccountSwitcher } from '../../../components/account-switcher';
import { stopPropagation } from '../../../utils/keyboard';
@@ -34,6 +37,8 @@ export function SettingsTab() {
const avatarUrl = profile.avatarUrl && userId
? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
: undefined;
const { assetUrls } = useOtherUserCollectibles(userId ?? '');
const avatarDecorationUrl = pickAvatarDecorationUrl(assetUrls);
const openSettings = () => setSettings(true);
const closeSettings = () => setSettings(false);
@@ -46,16 +51,27 @@ export function SettingsTab() {
return (
<SidebarItem active={settings}>
<SidebarAvatar
as="button"
<SidebarAvatar
as="button"
onClick={openSettings}
onContextMenu={handleContextMenu}
style={{ overflow: 'visible' }}
>
<UserAvatar
userId={userId ?? ''}
src={avatarUrl}
renderFallback={() => <Text size="H4">{nameInitials(displayName)}</Text>}
/>
<div className={avatarDecorationCss.SidebarAvatarStack}>
<UserAvatar
userId={userId ?? ''}
src={avatarUrl}
renderFallback={() => <Text size="H4">{nameInitials(displayName)}</Text>}
/>
{avatarDecorationUrl && (
<img
className={avatarDecorationCss.AvatarDecorationOverlay}
src={avatarDecorationUrl}
alt=""
draggable={false}
/>
)}
</div>
</SidebarAvatar>
<PopOut