From 91d939e21e536777aa32f8a938fc578cba952ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sun, 27 Sep 2026 13:38:40 -0400 Subject: [PATCH] =?UTF-8?q?Account=20=C2=B7=20Profile=20and=20access:=20a?= =?UTF-8?q?=20key's=20ends=20stay=20whole,=20keys=20drawn=20literally?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A key's name gives way before its ends, which keep their width. The ends and a new secret draw through typography::literal. Tests show this device listing first and the name field emptying after Create. Co-Authored-By: Claude Opus 5.5 --- TASKS.md | 1 + src/account/keys.rs | 18 +++++++++--------- src/account/sessions.rs | 2 ++ src/account/tests/access.rs | 25 ++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/TASKS.md b/TASKS.md index 19ff431..8c01ac2 100644 --- a/TASKS.md +++ b/TASKS.md @@ -404,3 +404,4 @@ Per-component lines live in `tasks/`. Tags there: | T35 | 3 | PASS | | | T36a | 1 | FAIL | Sign in waiting for a password and resting while busy, Create account waiting for a name, the other providers resting, and Send again resting while busy untested | | T36a | 2 | PASS | | +| T36b | 1 | FAIL | a long key name hid its ends at 280px; the secret and ends skipped typography::literal; this device's place first and the name clearing after Create untested | diff --git a/src/account/keys.rs b/src/account/keys.rs index 2ddc807..0a33a58 100644 --- a/src/account/keys.rs +++ b/src/account/keys.rs @@ -12,7 +12,7 @@ use crate::{ forms::{Enter, Input}, primitives::Severity, theme::{ActiveTheme, ControlSize, TextSize}, - typography::Ellipsis, + typography::{Ellipsis, literal}, }; type OnKey = Rc; @@ -114,7 +114,7 @@ impl RenderOnce for ApiKeyManager { .gap_2() .child( div().flex().child( - div() + literal(div()) .flex_1() .min_w_0() .font_family(mono.clone()) @@ -154,19 +154,19 @@ impl RenderOnce for ApiKeyManager { div() .flex() .gap_2() - .child( - div() - .flex_none() - .font_weight(FontWeight::MEDIUM) - .child(each.name.clone()), - ) .child( div() .flex_1() .min_w_0() + .font_weight(FontWeight::MEDIUM) + .child(Ellipsis::new(each.name.clone())), + ) + .child( + literal(div()) + .flex_none() .font_family(mono.clone()) .text_color(theme.colors.fg_muted) - .child(Ellipsis::new(each.hint.clone())), + .child(each.hint.clone()), ), ) .child( diff --git a/src/account/sessions.rs b/src/account/sessions.rs index 1775c8e..ccf935a 100644 --- a/src/account/sessions.rs +++ b/src/account/sessions.rs @@ -93,7 +93,9 @@ impl RenderOnce for SessionList { .into_any_element() } }; + let tag = format!("session-{}", session.key); div() + .debug_selector(move || tag) .flex() .items_center() .gap_3() diff --git a/src/account/tests/access.rs b/src/account/tests/access.rs index a1fb200..63b3b6c 100644 --- a/src/account/tests/access.rs +++ b/src/account/tests/access.rs @@ -104,6 +104,17 @@ fn a_key_is_made_by_name_revoked_on_the_second_press_and_its_secret_dismissed( write("Deploys", cx); tap("enter", cx); assert_eq!(said(&host, cx), ["revoke ci", "make Deploys"]); + cx.executor() + .advance_clock(std::time::Duration::from_secs(10)); + settle(cx); + tab(2, cx); + tap("space", cx); + tap("space", cx); + assert_eq!( + said(&host, cx), + ["revoke ci", "make Deploys", "revoke ci"], + "the name field emptied, so Create rests and the second stop is Revoke" + ); host.update(cx, |bench, cx| { bench.sent = true; cx.notify(); @@ -111,7 +122,10 @@ fn a_key_is_made_by_name_revoked_on_the_second_press_and_its_secret_dismissed( settle(cx); tab(2, cx); tap("space", cx); - assert_eq!(said(&host, cx), ["revoke ci", "make Deploys", "done"]); + assert_eq!( + said(&host, cx), + ["revoke ci", "make Deploys", "revoke ci", "done"] + ); } fn profile() -> Profile { @@ -223,3 +237,12 @@ fn this_device_alone_offers_no_sign_out(cx: &mut TestAppContext) { tap("space", cx); assert!(said(&host, cx).is_empty()); } + +/// The phone comes first in what the owner hands over, this device second; this device lists first. +#[gpui::test] +fn this_device_lists_first(cx: &mut TestAppContext) { + let (_, cx) = bench(sessions, cx); + let here = cx.debug_bounds("session-mac").expect("this device"); + let phone = cx.debug_bounds("session-phone").expect("the phone"); + assert!(here.top() < phone.top(), "{here:?} over {phone:?}"); +}