chore(ui): finalize timeline selection audit fixes
Complete re-review of PR #188 (commits224cab6feature +2c27fc5perf/i18n follow-up). Gatekeeper focus: standards, correctness, perf/complexity, and translation completeness. What this changes (pre -> post) Pre: timeline primarily navigation/hover preview; bulk delete selection message-level and token metrics tied to backend assistant output tokens (missing tool payload weight). Post: segment-level timeline selection + range (Shift) + toggle (Ctrl/Meta) + mobile long-press; histogram ribs overlay showing relative + absolute (~10k cap) token weight; assistant-turn grouping to avoid adjacency bugs; bulk-delete toolbar shows Before / Selection / After token pills. Code standards / correctness OK: Solid signal/memo/effect patterns with cleanup; no obvious lifecycle leaks. Grouping avoids adjacency overlap by mapping messageId to turns. Fix: selection-id stability is mitigated by pruning stale ids after segment rebuilds; long term stable ids from part ids/toolPartIds remain recommended. Fix: token counts now share getPartCharCount in both x-ray overlay and bulk-delete toolbar, keeping estimates consistent with live store updates. Performance / complexity OK: O(n^2) hotspots removed for liveSegmentChars and selectedTokenTotal. groupRole + deleteUpTo hover checks now memoize messageId sets/maps. Note: getPartCharCount can be heavy for large tool payloads but remains gated behind selection mode. CSS / UI integration Fix: x-ray token label now uses theme tokens instead of hard-coded colors. Delete toolbar now uses menu-based controls with selection-mode toggle. i18n Fix: selection hint now renders Cmd/Ctrl via localized modifier placeholder; all locales updated.
This commit is contained in:
@@ -111,6 +111,90 @@
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.message-delete-mode-button--menu {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.message-delete-mode-button--menu:hover {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu {
|
||||
right: 0;
|
||||
bottom: calc(100% + 6px);
|
||||
min-width: 150px;
|
||||
width: max-content;
|
||||
max-width: min(70vw, 220px);
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-divider {
|
||||
height: 1px;
|
||||
margin: 3px 0;
|
||||
background-color: var(--border-base);
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
padding: 2px 8px 6px;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-toggle {
|
||||
display: inline-flex;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--border-base);
|
||||
background-color: var(--surface-secondary);
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-toggle-button {
|
||||
padding: 2px 8px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.15s ease, background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-toggle-button[data-mode="all"] {
|
||||
flex: 0 0 auto;
|
||||
min-width: 56px;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-toggle-button[data-mode="tools"] {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.message-delete-mode-menu-toggle-button[data-active="true"] {
|
||||
color: var(--text-primary);
|
||||
background-color: color-mix(in oklab, var(--accent-primary) 18%, transparent);
|
||||
}
|
||||
|
||||
.message-delete-mode-menu .dropdown-item {
|
||||
width: calc(100% - 8px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 4px;
|
||||
padding: 3px 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.message-delete-mode-button:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent-primary) 45%, transparent);
|
||||
|
||||
@@ -357,10 +357,10 @@
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
line-height: 1;
|
||||
color: #1a1a2e;
|
||||
background: #ffffff;
|
||||
color: var(--text-primary);
|
||||
background: var(--surface-base);
|
||||
padding: 1px 5px;
|
||||
border: 1px solid #1a1a2e;
|
||||
border: 1px solid var(--border-base);
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
|
||||
Reference in New Issue
Block a user