feat(profile)!: replace sidebar and add avatar navigation

Rename the global Sidebar route, UI, assets, analytics, and payment return context to Profile. Add accessible message-avatar navigation and preserve the source character across auth and logout flows.

BREAKING CHANGE: /sidebar has been removed; use /profile instead.
This commit is contained in:
2026-07-21 18:08:12 +08:00
parent 6cd3a0c2d2
commit 9deb320cf6
67 changed files with 565 additions and 256 deletions
+13 -2
View File
@@ -32,6 +32,8 @@ export interface MessageBubbleProps {
onUnlockVoiceMessage?: ChatMessageAction;
onUnlockImageMessage?: ChatMessageAction;
onOpenImage?: (displayMessageId: string) => void;
onUserAvatarClick?: () => void;
onCharacterAvatarClick?: () => void;
}
type ChatMessageAction = (
@@ -57,6 +59,8 @@ export function MessageBubble({
onUnlockVoiceMessage,
onUnlockImageMessage,
onOpenImage,
onUserAvatarClick,
onCharacterAvatarClick,
}: MessageBubbleProps) {
const avatarUrl = useUserSelector((state) => state.context.avatarUrl);
@@ -67,7 +71,10 @@ export function MessageBubble({
data-chat-message-id={displayMessageId}
aria-label="AI message"
>
<MessageAvatar isFromAI={true} />
<MessageAvatar
isFromAI={true}
onClick={onCharacterAvatarClick}
/>
<div className={styles.bubbleInlineSpacer} aria-hidden="true" />
<MessageContent
characterId={characterId}
@@ -120,7 +127,11 @@ export function MessageBubble({
onOpenImage={onOpenImage}
/>
<div className={styles.bubbleInlineSpacer} aria-hidden="true" />
<MessageAvatar isFromAI={false} userAvatarUrl={avatarUrl} />
<MessageAvatar
isFromAI={false}
userAvatarUrl={avatarUrl}
onClick={onUserAvatarClick}
/>
</div>
);
}