setHovered(true)}
+ onMouseLeave={() => setHovered(false)}
+ onContextMenu={(e) => {
+ e.preventDefault();
+ // Keep the menu on screen when right-clicking near the viewport edges
+ const MENU_W = 200;
+ const MENU_H = 180;
+ setMenuPos({
+ x: Math.min(e.clientX, window.innerWidth - MENU_W - 8),
+ y: Math.min(e.clientY, window.innerHeight - MENU_H - 8),
+ });
+ if (!(e.target as HTMLElement).closest("[data-rail-item]")) {
+ setMenuTarget(null);
+ }
+ }}
+ >
+ {onOpenPalette && (
<>
setRailPreference("pinAppRail", !pinned)}
+ onClick={onOpenPalette}
+ title={t("nav.searchEverything")}
+ aria-label={t("nav.searchEverything")}
style={btnStyle}
- title={
- pinned ? t("nav.collapseSideMenu") : t("nav.keepSideMenuOpen")
- }
- className={`${btnBase} ${pinned ? activeClass : idle}`}
+ className={`${btnBase} ${idle}`}
>
-
+
-
- {pinned ? t("nav.collapseSideMenu") : t("nav.keepSideMenuOpen")}
-
+ {t("nav.search")}
>
)}
- {footerItems.map(renderItem)}
- {footerItems.length > 0 && !isElectron() && (
-
- )}
- {/* The desktop signs in to its own local profile by itself. */}
- {!isElectron() && (
-
onLogout({ manual: true })}
- style={btnStyle}
- title={t("common.logout")}
- aria-label={t("common.logout")}
- className={`${btnBase} text-muted-foreground hover:text-destructive hover:bg-destructive/10`}
- >
-
-
-
- {t("common.logout")}
-
- )}
-
+ {!pluginsSettled
+ ? Array.from({ length: mainItems.length || 8 }, (_, i) => (
+
+
+
+ ))
+ : bands.map((band, i) => (
+
+ {i > 0 && (
+
+ )}
+ {band.items.map(renderItem)}
+
+ ))}
- {menuPos && (
-
- {menuTarget && (
+ {pluginsSettled && hiddenItems.length > 0 && (
<>
- {menuTarget.promotable && (
-
}
- onClick={() => {
- onOpenTab?.(menuTarget.id as TabType);
- setMenuPos(null);
- }}
- >
- {t("nav.openAsTab")}
-
- )}
- {menuTarget.rightDockable && (
-
}
- onClick={() => {
- onOpenInRightDock?.(menuTarget.id);
- setMenuPos(null);
- }}
- >
- {t("nav.openInRightDock")}
-
- )}
- {menuTarget.hideable && (
-
}
- onClick={() => {
- void toggleHiddenRailTab(menuTarget.id);
- setMenuPos(null);
- }}
- >
- {t("nav.hideFromRail")}
-
- )}
-
+
+
setManaging((v) => !v)}
+ aria-expanded={managing}
+ title={t("nav.hiddenCount", { count: hiddenItems.length })}
+ style={btnStyle}
+ className={`${btnBase} ${managing ? activeClass : idle}`}
+ >
+
+
+
+
+ {t("nav.hiddenCount", { count: hiddenItems.length })}
+
+
+ {managing &&
+ hiddenItems.map((item) => {
+ const Icon = item.icon;
+ return (
+
void toggleHiddenRailTab(item.id)}
+ title={t("nav.showInRail")}
+ style={btnStyle}
+ className={`${btnBase} text-muted-foreground/70 hover:text-foreground hover:bg-muted/60`}
+ >
+
+
+
+
+ {t(item.labelKey)}
+
+
+
+ );
+ })}
>
)}
-
: null}
- onClick={togglePinned}
- checked={pinned}
- >
- {t("newUi.sidebar.userProfile.pinAppRail")}
-
-
: null}
- onClick={toggleExpandOnHover}
- checked={expandOnHover}
- >
- {t("newUi.sidebar.userProfile.expandAppRailOnHover")}
-
-
-
}
- onClick={() => {
- onOpenNavigationSettings();
- setMenuPos(null);
- }}
- >
- {t("nav.openSettings")}
-
- )}
+
+
+ {showPinButton && (
+ <>
+
setRailPreference("pinAppRail", !pinned)}
+ style={btnStyle}
+ title={
+ pinned ? t("nav.collapseSideMenu") : t("nav.keepSideMenuOpen")
+ }
+ className={`${btnBase} ${pinned ? activeClass : idle}`}
+ >
+
+
+
+
+ {pinned
+ ? t("nav.collapseSideMenu")
+ : t("nav.keepSideMenuOpen")}
+
+
+
+ >
+ )}
+ {footerItems.map(renderItem)}
+ {footerItems.length > 0 && !isElectron() && (
+
+ )}
+ {/* The desktop signs in to its own local profile by itself. */}
+ {!isElectron() && (
+
onLogout({ manual: true })}
+ style={btnStyle}
+ title={t("common.logout")}
+ aria-label={t("common.logout")}
+ className={`${btnBase} text-muted-foreground hover:text-destructive hover:bg-destructive/10`}
+ >
+
+
+
+
+ {t("common.logout")}
+
+
+ )}
+
+
+
+
+
+ {username.charAt(0).toUpperCase() || "U"}
+
+
+
+ {username || t("nav.roleUser")}
+
+
+ {isAdmin ? t("nav.roleAdministrator") : t("nav.roleUser")}
+
+
+
+
+
+ {menuPos && (
+
+ {menuTarget && (
+ <>
+ {menuTarget.promotable && (
+
}
+ onClick={() => {
+ onOpenTab?.(menuTarget.id as TabType);
+ setMenuPos(null);
+ }}
+ >
+ {t("nav.openAsTab")}
+
+ )}
+ {menuTarget.rightDockable && (
+
}
+ onClick={() => {
+ onOpenInRightDock?.(menuTarget.id);
+ setMenuPos(null);
+ }}
+ >
+ {t("nav.openInRightDock")}
+
+ )}
+ {menuTarget.hideable && (
+
}
+ onClick={() => {
+ void toggleHiddenRailTab(menuTarget.id);
+ setMenuPos(null);
+ }}
+ >
+ {t("nav.hideFromRail")}
+
+ )}
+
+ >
+ )}
+
: null}
+ onClick={togglePinned}
+ checked={pinned}
+ >
+ {t("newUi.sidebar.userProfile.pinAppRail")}
+
+
: null}
+ onClick={toggleExpandOnHover}
+ checked={expandOnHover}
+ >
+ {t("newUi.sidebar.userProfile.expandAppRailOnHover")}
+
+
+
}
+ onClick={() => {
+ onOpenNavigationSettings();
+ setMenuPos(null);
+ }}
+ >
+ {t("nav.openSettings")}
+
+
+ )}
+