mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-25 17:18:11 +00:00
Make every session tab speak the same drag language as a sidebar row, and keep tab focus 1:1 across the sidebar, tiles, and main: - Drag a session tile's OR the main workspace tab onto a composer to link the chat (@session chip), or onto a zone/edge to stack/split — tabDrag now returns whether it took the drag, so the workspace tab defers to the generic pane move on a fresh draft (nothing to link). - A lone tool panel (terminal/logs) dragged to its own zone keeps its header, so it stays draggable/closable instead of stranding a dead, tab-less zone. - The sidebar highlight follows the FOCUSED session (interacted tile, else the main selection) rather than only the main one. - Clicking an already-open session jumps to its tab — an open tile, or the workspace tab when it's the main session and focus sits on a tile — instead of a dead no-op reload. - Secondary (single-chat pop-out) windows boot to the default tree with no tiles and never persist their stripped-down layout back, so they can't inherit or clobber the primary window's tabs/splits. The pointer drag ghost is extracted to a shared lib/drag-ghost and the drop affordances drop their now-unused labels.
43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
/**
|
|
* A flat, pointer-following drag chip — the shared "what am I holding"
|
|
* affordance for in-app pointer drags. Plain DOM (no React) so it survives a
|
|
* pointer-capture drag without re-renders and tears down synchronously on Esc.
|
|
*
|
|
* Flat by design: a solid app surface with the dragged item's label, no
|
|
* border / radius / shadow, dimmed — it copies the real row/tab it represents
|
|
* rather than reading as a separate pill. Any pointer drag whose source does
|
|
* not stay visibly "held" can reuse this (the drag primitive in
|
|
* `pane-shell/tree/renderer/drag-session.ts`, and anything built on it).
|
|
*/
|
|
|
|
/** How far (px) the chip trails the pointer so it never sits under the cursor. */
|
|
const OFFSET_X = 14
|
|
const OFFSET_Y = 12
|
|
|
|
export interface DragGhost {
|
|
/** Reposition the chip near the current pointer point. */
|
|
moveTo(x: number, y: number): void
|
|
/** Remove the chip from the DOM. Idempotent. */
|
|
destroy(): void
|
|
}
|
|
|
|
export function createDragGhost(label: string): DragGhost {
|
|
const el = document.createElement('div')
|
|
|
|
el.textContent = label
|
|
el.style.cssText =
|
|
'position:fixed;left:0;top:0;z-index:9999;pointer-events:none;max-width:16rem;overflow:hidden;' +
|
|
'text-overflow:ellipsis;white-space:nowrap;padding:0.25rem 0.625rem;opacity:0.6;' +
|
|
'background:var(--ui-sidebar-surface-background,var(--dt-card));color:var(--ui-text-primary);' +
|
|
'font-size:0.75rem;font-weight:500;will-change:transform'
|
|
document.body.appendChild(el)
|
|
|
|
return {
|
|
moveTo(x, y) {
|
|
el.style.transform = `translate3d(${x + OFFSET_X}px, ${y + OFFSET_Y}px, 0)`
|
|
},
|
|
destroy() {
|
|
el.remove()
|
|
}
|
|
}
|
|
}
|