feat: setting to let the hover side menu push content again

This commit is contained in:
LukeGus committed 2026-10-15 22:00:24 -05:00
1 parent d2851982a6
commit 3a851ad189
7 files changed
+58 -4

No files matched your search

+2
View File
@@ -1674,6 +1674,8 @@
"pinAppRailDesc": "Keep the left sidebar app rail always expanded instead of expanding on hover",
"expandAppRailOnHover": "Expand App Rail on Hover",
"expandAppRailOnHoverDesc": "Allow the left sidebar app rail to expand when the pointer moves over it",
"appRailHoverPushesContent": "Push content when it expands",
"appRailHoverPushesContentDesc": "Make room for the expanded rail instead of opening it over the page. Open sessions, like remote desktop, resize each time",
"showPinAppRailButton": "Show Pin App Rail Button",
"showPinAppRailButtonDesc": "Show a button in the app rail to pin it open. Off by default.",
"settingsNavigation": "Navigation",
+2
View File
@@ -323,6 +323,8 @@ export const SETTINGS_SEARCH_INDEX: Record<string, string[]> = {
],
"appearance": [
"newUi.sidebar.userProfile.accentColorLabel",
"newUi.sidebar.userProfile.appRailHoverPushesContent",
"newUi.sidebar.userProfile.appRailHoverPushesContentDesc",
"newUi.sidebar.userProfile.colorPickerTooltip",
"newUi.sidebar.userProfile.commandPalette",
"newUi.sidebar.userProfile.commandPaletteDesc",
+13 -2
View File
@@ -159,6 +159,9 @@ export function AppRail({
const [showPinButton, setShowPinButton] = useState(() =>
readRailPreference("showPinAppRailButton"),
);
const [hoverPushes, setHoverPushes] = useState(() =>
readRailPreference("appRailHoverPushesContent"),
);
const [menuPos, setMenuPos] = useState<{ x: number; y: number } | null>(null);
const [menuTarget, setMenuTarget] = useState<MenuTarget | null>(null);
const [managing, setManaging] = useState(false);
@@ -170,8 +173,11 @@ export function AppRail({
setExpandOnHover(readRailPreference("expandAppRailOnHover"));
const showPinButtonHandler = () =>
setShowPinButton(readRailPreference("showPinAppRailButton"));
const pushHandler = () =>
setHoverPushes(readRailPreference("appRailHoverPushesContent"));
window.addEventListener("pinAppRailChanged", pinHandler);
window.addEventListener("expandAppRailOnHoverChanged", hoverHandler);
window.addEventListener("appRailHoverPushesContentChanged", pushHandler);
window.addEventListener(
"showPinAppRailButtonChanged",
showPinButtonHandler,
@@ -179,6 +185,10 @@ export function AppRail({
return () => {
window.removeEventListener("pinAppRailChanged", pinHandler);
window.removeEventListener("expandAppRailOnHoverChanged", hoverHandler);
window.removeEventListener(
"appRailHoverPushesContentChanged",
pushHandler,
);
window.removeEventListener(
"showPinAppRailButtonChanged",
showPinButtonHandler,
@@ -313,8 +323,9 @@ export function AppRail({
};
// Expanding on hover draws over the content instead of pushing it, so open
// sessions like remote desktop are not resized each time.
const takesSpace = pinned || managing;
// sessions like remote desktop are not resized each time, unless the user
// asked for the old behavior.
const takesSpace = hoverPushes ? railExpanded : pinned || managing;
return (
<div
+18
View File
@@ -553,6 +553,9 @@ export function UserProfilePanel({
const [expandAppRailOnHover, setExpandAppRailOnHover] = useState(() =>
readRailPreference("expandAppRailOnHover"),
);
const [appRailHoverPushes, setAppRailHoverPushes] = useState(() =>
readRailPreference("appRailHoverPushesContent"),
);
const [showPinAppRailButton, setShowPinAppRailButton] = useState(() =>
readRailPreference("showPinAppRailButton"),
);
@@ -1684,6 +1687,21 @@ export function UserProfilePanel({
}}
/>
</SettingRow>
<SettingRow
label={t("newUi.sidebar.userProfile.appRailHoverPushesContent")}
description={t(
"newUi.sidebar.userProfile.appRailHoverPushesContentDesc",
)}
>
<FakeSwitch
checked={appRailHoverPushes}
disabled={!expandAppRailOnHover}
onChange={(v) => {
setAppRailHoverPushes(v);
setRailPreference("appRailHoverPushesContent", v);
}}
/>
</SettingRow>
<SettingRow
label={t("newUi.sidebar.userProfile.showPinAppRailButton")}
description={t(
+11 -1
View File
@@ -1,14 +1,23 @@
import { getUserPreferences, saveUserPreferences } from "@/api/open-tabs-api";
export type RailPreference =
"pinAppRail" | "expandAppRailOnHover" | "showPinAppRailButton";
| "pinAppRail"
| "expandAppRailOnHover"
| "showPinAppRailButton"
| "appRailHoverPushesContent";
const CHANGE_EVENT: Record<RailPreference, string> = {
pinAppRail: "pinAppRailChanged",
expandAppRailOnHover: "expandAppRailOnHoverChanged",
showPinAppRailButton: "showPinAppRailButtonChanged",
appRailHoverPushesContent: "appRailHoverPushesContentChanged",
};
/** Kept on this device only; the server has no column for it. */
const LOCAL_ONLY: ReadonlySet<RailPreference> = new Set([
"appRailHoverPushesContent",
]);
// pinAppRail and showPinAppRailButton default off, expandAppRailOnHover
// defaults on, so each key needs its own read rather than a shared
// === "true" check.
@@ -28,6 +37,7 @@ export function readRailPreference(key: RailPreference): boolean {
export function setRailPreference(key: RailPreference, value: boolean): void {
localStorage.setItem(key, String(value));
window.dispatchEvent(new Event(CHANGE_EVENT[key]));
if (LOCAL_ONLY.has(key)) return;
void getUserPreferences()
.then((preferences) => {
if (preferences.storageMode === "cloud") {
+11
View File
@@ -66,6 +66,17 @@ describe("AppRail", () => {
expect(slot.style.width).toBe(collapsed);
});
it("pushes the content on hover when the user asks for it", () => {
localStorage.setItem("appRailHoverPushesContent", "true");
renderRail();
const rail = screen
.getByLabelText("common.logout")
.closest(".absolute") as HTMLElement;
const slot = rail.parentElement as HTMLElement;
fireEvent.mouseEnter(rail);
expect(slot.style.width).toBe(rail.style.width);
});
it("puts a footer item above the profile with its badge", async () => {
registerRailItem({
id: "inbox",