diff --git a/Client/tauri-client/src/components/UserBar.ts b/Client/tauri-client/src/components/UserBar.ts index 10142789..0034026f 100644 --- a/Client/tauri-client/src/components/UserBar.ts +++ b/Client/tauri-client/src/components/UserBar.ts @@ -120,19 +120,15 @@ export function createUserBar(options?: UserBarOptions): MountableComponent { }); avatarTextEl = createElement("span", {}); avatarEl.appendChild(avatarTextEl); - const statusDot = createElement("div", { - class: "status-dot", - style: - "background: var(--green); width: 10px; height: 10px; border-radius: 50%; position: absolute; bottom: 0; right: 0;", - }); - avatarEl.appendChild(statusDot); const info = createElement("div", { class: "ub-info" }); nameEl = createElement("span", { class: "ub-name", "data-testid": "user-bar-name" }); statusEl = createElement("span", { class: "ub-status" }); appendChildren(info, nameEl, statusEl); - // Status picker — anchored below username, opens upward + // Status picker — the dot itself lives in the avatar's corner (same spot + // the old plain status indicator occupied) so it doubles as the status + // display and its click target; the dropdown still opens upward from there. const statusPickerWrap = createElement("div", { class: "ub-status-picker-wrap", "data-testid": "status-picker-wrap", @@ -203,7 +199,7 @@ export function createUserBar(options?: UserBarOptions): MountableComponent { () => updatePickerDisabled(), ); - info.appendChild(statusPickerWrap); + avatarEl.appendChild(statusPickerWrap); const buttons = createElement("div", { class: "ub-controls" }); diff --git a/Client/tauri-client/src/styles/app.css b/Client/tauri-client/src/styles/app.css index 63419357..0a024017 100644 --- a/Client/tauri-client/src/styles/app.css +++ b/Client/tauri-client/src/styles/app.css @@ -657,14 +657,14 @@ color: white; cursor: pointer; } -.user-bar .status-dot { +/* The status picker's own trigger dot now lives here instead of a separate + static dot — same corner, but it's the real thing: colored per status and + clickable to open the picker. Sizing/border override lives with the rest + of the status-picker rules below. */ +.user-bar .ub-status-picker-wrap { position: absolute; bottom: -1px; right: -1px; - width: 12px; - height: 12px; - border-radius: var(--radius-circle); - border: 3px solid rgba(17, 18, 20, 0.6); } .user-bar .ub-info { flex: 1; @@ -750,6 +750,13 @@ outline: 2px solid var(--accent); outline-offset: 2px; } +/* In the user bar the dot sits on the avatar corner, not inline next to + text — bigger, with a ring so it reads against any avatar picture. */ +.user-bar .status-picker-dot { + width: 12px; + height: 12px; + border: 3px solid rgba(17, 18, 20, 0.6); +} .status-picker-option { display: flex; align-items: center; diff --git a/Client/tauri-client/tests/e2e/user-bar.spec.ts b/Client/tauri-client/tests/e2e/user-bar.spec.ts index d6d4baa9..e9731dbb 100644 --- a/Client/tauri-client/tests/e2e/user-bar.spec.ts +++ b/Client/tauri-client/tests/e2e/user-bar.spec.ts @@ -36,6 +36,13 @@ test.describe("User Bar", () => { await expect(status).toHaveText("Online"); }); + test("status picker dot sits on the avatar", async ({ page }) => { + const dot = page.locator( + "[data-testid='user-bar'] .ub-avatar [data-testid='status-picker-wrap'] .status-picker-dot", + ); + await expect(dot).toBeVisible(); + }); + test("user bar has settings button with correct label", async ({ page }) => { const controls = page.locator("[data-testid='user-bar'] .ub-controls"); await expect(controls).toBeVisible();