收口顶栏钱包快捷入口

复用 PlatformActionButton 和 PlatformIconBadge 收口创作与草稿顶栏钱包快捷入口
补强钱包快捷入口在移动端与桌面端的回归测试
更新 PlatformUiKit 收口计划和 Hermes 决策记录
This commit is contained in:
2026-06-10 16:51:40 +08:00
parent 9141540c37
commit 9a04ea55dc
4 changed files with 86 additions and 33 deletions

View File

@@ -3535,24 +3535,37 @@ test('logged in create tab shows real wallet balance beside the brand', () => {
const topbar = container.querySelector('.platform-mobile-topbar');
expect(topbar).toBeTruthy();
expect(
topbar?.querySelector('.platform-mobile-create-wallet-chip'),
within(topbar as HTMLElement).getByRole('img', {
name: / GENARRATIVE/u,
}),
).toBeTruthy();
expect(topbar?.textContent).toContain('陶泥儿');
expect(topbar?.textContent).toContain('1,234泥点');
const walletButton = within(topbar as HTMLElement).getByRole('button', {
name: /^1,234$/u,
});
expect(walletButton.className).toContain('platform-mobile-create-wallet-chip');
expect(walletButton.className).toContain('platform-action-button--accent-soft');
expect(walletButton.querySelector('.platform-icon-badge')).toBeTruthy();
});
test('create tab wallet chip opens reward code when recharge entry is hidden', async () => {
const user = userEvent.setup();
mockNarrowMobileLayout();
render(
const { container } = render(
<ProfileHomeViewHarness
activeTab="create"
profileDashboardOverrides={{ walletBalance: 70 }}
/>,
);
await user.click(screen.getByRole('button', { name: /^70$/u }));
const topbar = container.querySelector('.platform-mobile-topbar');
expect(topbar).toBeTruthy();
await user.click(
within(topbar as HTMLElement).getByRole('button', { name: /^70$/u }),
);
expect(await screen.findByPlaceholderText('输入兑换码')).toBeTruthy();
expect(mockGetRpgProfileRechargeCenter).not.toHaveBeenCalled();
@@ -3562,14 +3575,25 @@ test('create tab wallet chip opens recharge when recharge entry is enabled', asy
const user = userEvent.setup();
mockWechatDesktopLayout();
render(
const { container } = render(
<ProfileHomeViewHarness
activeTab="create"
profileDashboardOverrides={{ walletBalance: 70 }}
/>,
);
await user.click(screen.getByRole('button', { name: /^70$/u }));
const topbar = container.querySelector('.platform-desktop-topbar');
expect(topbar).toBeTruthy();
const walletButton = within(topbar as HTMLElement).getByRole('button', {
name: /^70$/u,
});
expect(walletButton.className).toContain('platform-desktop-create-wallet-chip');
expect(walletButton.className).toContain('platform-desktop-search');
expect(walletButton.className).toContain('platform-action-button--accent-soft');
expect(walletButton.querySelector('.platform-icon-badge')).toBeTruthy();
await user.click(walletButton);
expect(await screen.findByText('账户充值')).toBeTruthy();
expect(mockGetRpgProfileRechargeCenter).toHaveBeenCalledTimes(1);

View File

@@ -1118,6 +1118,48 @@ function PublicCodeSearchBar({
);
}
function TopbarWalletShortcutButton({
variant,
balanceLabel,
onClick,
}: {
variant: 'mobile' | 'desktop';
balanceLabel: string;
onClick: () => void;
}) {
const isMobile = variant === 'mobile';
return (
<PlatformActionButton
tone="accentSoft"
shape="pill"
size="xs"
onClick={onClick}
aria-label={balanceLabel}
className={[
'shrink-0 [--platform-action-accent:#b65f2c]',
isMobile
? 'platform-mobile-create-wallet-chip !gap-1.5 !px-2.5 !py-1.5'
: 'platform-desktop-create-wallet-chip platform-desktop-search !px-3 !py-2.5',
]
.filter(Boolean)
.join(' ')}
>
<PlatformIconBadge
icon={<Coins className="h-3.5 w-3.5" />}
size="xs"
tone="neutral"
className={
isMobile
? '!h-6 !w-6 !bg-[#ffe0ab] !text-[#cf7b34]'
: '!bg-[#ffe0ab] !text-[#cf7b34]'
}
/>
<span>{balanceLabel}</span>
</PlatformActionButton>
);
}
function SaveArchivePreview({
entry,
className,
@@ -7369,21 +7411,13 @@ export function RpgEntryHomeView({
</div>
) : isAuthenticated &&
(activeTab === 'create' || activeTab === 'saves') ? (
<button
type="button"
onClick={openRechargeOrRewardCodeModal}
className="platform-mobile-create-wallet-chip inline-flex shrink-0 items-center gap-1.5 rounded-full border border-[#f0cfae] bg-[#fff5eb] px-2.5 py-1.5 text-xs font-black text-[#b65f2c] shadow-[0_10px_22px_rgba(174,111,73,0.12)]"
aria-label={
<TopbarWalletShortcutButton
variant="mobile"
balanceLabel={
profileDashboardPresentation.walletBalanceWithUnitLabel
}
>
<span className="grid h-6 w-6 place-items-center rounded-full bg-[#ffe0ab] text-[#cf7b34]">
<Coins className="h-3.5 w-3.5" />
</span>
<span>
{profileDashboardPresentation.walletBalanceWithUnitLabel}
</span>
</button>
onClick={openRechargeOrRewardCodeModal}
/>
) : !isAuthenticated ? (
<PlatformActionButton
size="xs"
@@ -7540,21 +7574,13 @@ export function RpgEntryHomeView({
<div className="flex items-center gap-3">
{isAuthenticated &&
(activeTab === 'create' || activeTab === 'saves') ? (
<button
type="button"
onClick={openRechargeOrRewardCodeModal}
className="platform-desktop-create-wallet-chip platform-desktop-search inline-flex items-center gap-2 px-3 py-2.5 text-xs font-black text-[#b65f2c]"
aria-label={
<TopbarWalletShortcutButton
variant="desktop"
balanceLabel={
profileDashboardPresentation.walletBalanceWithUnitLabel
}
>
<span className="grid h-7 w-7 place-items-center rounded-full bg-[#ffe0ab] text-[#cf7b34]">
<Coins className="h-3.5 w-3.5" />
</span>
<span>
{profileDashboardPresentation.walletBalanceWithUnitLabel}
</span>
</button>
onClick={openRechargeOrRewardCodeModal}
/>
) : null}
<button
type="button"