From 3da321596e0790f151f17c68dbbf8325a5c3fb5d Mon Sep 17 00:00:00 2001 From: Lambda Date: Wed, 29 Jul 2026 19:23:44 +0800 Subject: [PATCH] refactor(views): merge the Discord link into the help footer strip The footer stacked a full-width Discord row above a right-aligned help trigger, leaving the trigger's leading two-thirds empty and the promo isolated in its own band. Put both on one strip: the link takes the free leading space and `justify-end` keeps the trigger right-aligned once the link is dismissed. Footer height drops 68px -> 48px. Sharing a 224px strip leaves 128px for the label, and the external-link arrow plus the dismiss button together overflow it (label is 109px in en and 125px in zh), so the two cannot coexist at the default sidebar width. Drop the arrow rather than the dismiss button: dismissal is a user-facing capability while the arrow is only a hint the Discord mark already carries. Measured in the running app -- no locale clips at the default width. Co-authored-by: multica-agent --- packages/views/layout/app-sidebar.tsx | 7 +++++-- packages/views/layout/join-discord-card.tsx | 21 +++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/views/layout/app-sidebar.tsx b/packages/views/layout/app-sidebar.tsx index 2fb5e9677e..9393b1261e 100644 --- a/packages/views/layout/app-sidebar.tsx +++ b/packages/views/layout/app-sidebar.tsx @@ -783,8 +783,11 @@ export function AppSidebar({ topSlot, searchSlot, headerClassName, headerStyle } - -
+ {/* One utility strip: the Discord link takes the leading space the + help trigger was leaving empty. `justify-end` keeps the trigger + right-aligned once the Discord link is dismissed. */} +
+
diff --git a/packages/views/layout/join-discord-card.tsx b/packages/views/layout/join-discord-card.tsx index 8143787709..b284d2d3d0 100644 --- a/packages/views/layout/join-discord-card.tsx +++ b/packages/views/layout/join-discord-card.tsx @@ -1,22 +1,28 @@ "use client"; -import { ArrowUpRight, X } from "lucide-react"; +import { X } from "lucide-react"; import { useAuthStore } from "@multica/core/auth"; import { DISCORD_URL, DiscordIcon } from "./discord"; import { useDiscordCardDismissed } from "./use-discord-card-dismissed"; import { useT } from "../i18n"; /** - * Dismissible "Join our Discord" entry pinned to the bottom of the left - * sidebar (above the help launcher). Once dismissed it stays hidden for - * that user on this browser — see {@link useDiscordCardDismissed}. + * Dismissible "Join our Discord" entry sharing the sidebar footer strip with + * the help launcher. Once dismissed it stays hidden for that user on this + * browser — see {@link useDiscordCardDismissed}. * * Deliberately shaped as a sidebar row, not a bordered card: it matches * SidebarMenuButton metrics (h-8 / rounded-md / gap-2 / text-body) and * carries no resting border or fill. A dismissible promo is the * lowest-priority item in the sidebar, so it must not be drawn heavier than - * the navigation above it. The external-link arrow mirrors the Help menu's - * outbound items. + * the navigation above it. + * + * No external-link arrow, unlike the Help menu's outbound items: sharing one + * 224px strip with the help trigger leaves 128px for the label, and the arrow + * plus the dismiss button together overflow that in en (109px) and zh (125px). + * The dismiss affordance wins because it is a user-facing capability and the + * arrow is only a hint — the Discord mark already signals the destination. + * `flex-1 min-w-0` makes the label truncate rather than push the trigger off. */ export function JoinDiscordCard() { const { t } = useT("layout"); @@ -26,7 +32,7 @@ export function JoinDiscordCard() { if (dismissed) return null; return ( -
+
{t(($) => $.sidebar.discord_card.title)} - {/* Revealed on hover/focus so the resting row stays quiet. Coarse pointers get no hover, so keep it permanently visible there. */}