From 558cd3ddd790cfbbd6222cc4a750cd1c40bc5f18 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 May 2026 13:28:11 +1200 Subject: [PATCH] Updated taskbar to be OS agnostic Updated task bar to use MacOS traffic lights on left when on MacOS and the regular buttons on the right when it is Windows or Linux --- frontend/css/components.css | 52 +++++++++++++++++++++++++++++++++++++ frontend/js/app.js | 42 +++++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/frontend/css/components.css b/frontend/css/components.css index ffcf13b..95b1da9 100644 --- a/frontend/css/components.css +++ b/frontend/css/components.css @@ -151,6 +151,7 @@ /* ── Toolbar ──────────────────────────────────────────────────────────────── */ .gd-toolbar { + --mac-window-controls-width: 80px; display: flex; align-items: stretch; grid-column: 1 / -1; @@ -227,6 +228,57 @@ color: #ffffff; } +.gd-toolbar-macos .gd-window-controls { + align-items: center; + gap: 8px; + width: var(--mac-window-controls-width); + padding: 0 14px; + border-left: 0; + border-right: 1px solid rgba(229, 161, 62, 0.12); +} + +.gd-toolbar-macos .gd-toolbar-left { + width: calc(320px - var(--mac-window-controls-width)); +} + +.gd-toolbar-macos .gd-window-control { + width: 12px; + height: 12px; + border-radius: 999px; + color: rgba(60, 64, 67, 0.72); +} + +.gd-toolbar-macos .gd-window-control svg { + opacity: 0; + transform: scale(0.72); + transition: opacity 0.12s ease; +} + +.gd-toolbar-macos .gd-window-controls:hover .gd-window-control svg { + opacity: 1; +} + +.gd-toolbar-macos .gd-window-close { + background: #ff5f57; +} + +.gd-toolbar-macos .gd-window-minimize { + background: #ffbd2e; +} + +.gd-toolbar-macos .gd-window-maximize { + background: #28c840; +} + +.gd-toolbar-macos .gd-window-control:hover { + color: rgba(36, 41, 47, 0.8); +} + +.gd-toolbar-macos .gd-window-close:hover { + background: #ff5f57; + color: rgba(36, 41, 47, 0.8); +} + .gd-external-actions { display: flex; align-items: center; diff --git a/frontend/js/app.js b/frontend/js/app.js index 84a3fb4..eebea1e 100644 --- a/frontend/js/app.js +++ b/frontend/js/app.js @@ -70,6 +70,16 @@ const WINDOW_MINIMIZE_ICON = ``; const WINDOW_CLOSE_ICON = ``; +function currentPlatform() { + const platform = navigator.userAgentData?.platform || navigator.platform || ""; + const userAgent = navigator.userAgent || ""; + const value = `${platform} ${userAgent}`.toLowerCase(); + + if (value.includes("mac")) return "macos"; + if (value.includes("win")) return "windows"; + return "linux"; +} + function currentTauriWindow() { const tauriWindow = window.__TAURI__?.window; if (tauriWindow?.getCurrentWindow) { @@ -211,6 +221,26 @@ function externalEditorOptionsTemplate(state) { `; } +function windowControlsTemplate(isMacos = false) { + const controls = isMacos + ? [ + { action: "close", label: "Close", icon: WINDOW_CLOSE_ICON, className: "gd-window-close" }, + { action: "minimize", label: "Minimize", icon: WINDOW_MINIMIZE_ICON, className: "gd-window-minimize" }, + { action: "maximize", label: "Maximize", icon: WINDOW_MAXIMIZE_ICON, className: "gd-window-maximize" }, + ] + : [ + { action: "minimize", label: "Minimize", icon: WINDOW_MINIMIZE_ICON, className: "gd-window-minimize" }, + { action: "maximize", label: "Maximize", icon: WINDOW_MAXIMIZE_ICON, className: "gd-window-maximize" }, + { action: "close", label: "Close", icon: WINDOW_CLOSE_ICON, className: "gd-window-close" }, + ]; + + return `
+ ${controls.map((control) => ` + + `).join("")} +
`; +} + function statusLabel(status = "") { const labels = { modified: "Modified", @@ -1160,6 +1190,9 @@ function dashboardView() { const displayRepoName = currentRepositoryName(); const displayBranchName = currentBranchName(); const hasLocalRepo = Boolean(state.selectedRepoPath); + const isMacos = currentPlatform() === "macos"; + const toolbarPlatformClass = isMacos ? "gd-toolbar-macos" : "gd-toolbar-standard"; + const windowControlsHTML = windowControlsTemplate(isMacos); // ── Repository identity ───────────────────────────────────────────────── const repoIdentity = (() => { @@ -1184,6 +1217,7 @@ function dashboardView() { // ── Toolbar ───────────────────────────────────────────────────────────── const toolbarHTML = ` + ${isMacos ? windowControlsHTML : ""}
` : ""} -
- - - -
+ ${isMacos ? "" : windowControlsHTML} `; // ── Sidebar content ───────────────────────────────────────────────────── @@ -1431,7 +1461,7 @@ function dashboardView() { // ── Assemble ───────────────────────────────────────────────────────────── appRoot.innerHTML = `
-
+
${toolbarHTML}