refactor(ux): address /code-review high findings on the fixpack
- Extract the optimistic + debounced-flush feed-priority flow into a shared useChannelPriority hook (mirrors useChannelTagActions); the manager and the channel-detail page now share it instead of two drifting copies. - NavSidebar: drop the always-true `slim` const and its dead expanded-rail branches; refresh the now-stale pinned/collapsible comments. - Remove the orphaned `navCollapsed` localStorage key (no readers/writers left after the always-slim rail). - Channel page: drop the wrapper native `title` that duplicated PriorityStepper's own Tooltip. The keyboard-focus nav-label finding needed no change: the popover platform already wires useFocus (visibleOnly), so a real Tab press shows the flyout label (verified in-browser).
This commit is contained in:
@@ -17,9 +17,9 @@ import Tooltip from "./Tooltip";
|
||||
import LanguageSwitcher from "./LanguageSwitcher";
|
||||
import { PopoverSurface, useAnchoredPopover } from "./AnchoredPopover";
|
||||
|
||||
// Primary app navigation: a collapsible left rail with icon+label entries (Design C). The
|
||||
// modules used to hide under the avatar dropdown; they now live here. Collapsed, it becomes
|
||||
// a thin icon-only rail. Account actions sit at the bottom in a popover.
|
||||
// Primary app navigation: a thin icon-only left rail. The modules used to hide under the avatar
|
||||
// dropdown; they now live here, each revealing its name in a hover/focus flyout label. Account
|
||||
// actions sit at the bottom in a popover.
|
||||
export default function NavSidebar({
|
||||
me,
|
||||
onOpenAbout,
|
||||
@@ -34,10 +34,10 @@ export default function NavSidebar({
|
||||
const { t } = useTranslation();
|
||||
const { page } = useNavigation();
|
||||
const { setPage } = useNavigationActions();
|
||||
// The rail is ALWAYS slim: a thin icon-only column flush against the left edge. There is no
|
||||
// expanded/pinned mode anymore — instead each icon reveals a floating name label on hover (a
|
||||
// rest-to-show flyout via Tooltip), so the names are one glance away without the rail ever growing.
|
||||
const slim = true;
|
||||
// The rail is ALWAYS a thin icon-only column flush against the left edge. There is no
|
||||
// expanded/pinned mode anymore — instead each icon reveals a floating name label on hover or
|
||||
// keyboard focus (a rest-to-show flyout via Tooltip), so the names are one glance away without the
|
||||
// rail ever growing.
|
||||
const [acctOpen, setAcctOpen] = useState(false);
|
||||
// The account panel holds mixed content with its own tab order (profile, account switches, two
|
||||
// actions), so it is a `dialog` popover, not a roving menu. It portals out of the nav — whose
|
||||
@@ -198,8 +198,6 @@ export default function NavSidebar({
|
||||
};
|
||||
|
||||
return (
|
||||
// Layout slot: reserves only the slim footprint when unpinned, so the expanded rail (below)
|
||||
// overlays content instead of pushing it. Pinned reserves the full width (in-flow).
|
||||
// Slim icon rail, flush against the left viewport edge (only top/bottom margin), never grows.
|
||||
// The slot is exactly the card's width so the filter tab/bar docks flush against its right edge.
|
||||
<div className="relative shrink-0 w-14">
|
||||
@@ -213,28 +211,15 @@ export default function NavSidebar({
|
||||
style={listFade.style}
|
||||
>
|
||||
{userItems.map(renderItem)}
|
||||
{systemItems.length > 0 &&
|
||||
(slim ? (
|
||||
// Collapsed rail: a short, thicker centred rule is the clearest "new section" cue
|
||||
// when there's no room for a label.
|
||||
<div className="my-2 mx-auto w-7 border-t-2 border-border" />
|
||||
) : (
|
||||
<div className="mt-4 mb-1 px-2.5 flex items-center gap-2">
|
||||
<span className="text-3xs font-semibold uppercase tracking-wider text-muted/70">
|
||||
{t("nav.adminSection")}
|
||||
</span>
|
||||
<span className="flex-1 border-t border-border" />
|
||||
</div>
|
||||
))}
|
||||
{systemItems.length > 0 && (
|
||||
// A short, thicker centred rule is the clearest "new section" cue on an icon-only rail.
|
||||
<div className="my-2 mx-auto w-7 border-t-2 border-border" />
|
||||
)}
|
||||
{systemItems.map(renderItem)}
|
||||
</div>
|
||||
|
||||
<div className="mt-2 pt-2 border-t border-border flex flex-col gap-1">
|
||||
<div
|
||||
className={`flex items-center justify-center gap-2 pb-2 mb-1 border-b border-border ${
|
||||
slim ? "flex-col" : "flex-row"
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center gap-2 pb-2 mb-1 border-b border-border">
|
||||
<LanguageSwitcher variant="rail" value={language} onChange={onChangeLanguage} />
|
||||
<button
|
||||
onClick={onOpenAbout}
|
||||
|
||||
Reference in New Issue
Block a user