mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-10 11:47:43 +02:00
[eric] dashboard: scroll-focus set on any card press + non-card scrollables (menus/dropdowns) scroll natively; fresh chat scrollable on spawn
This commit is contained in:
@@ -265,10 +265,10 @@ export function useCanvasControls(zoomSensitivity: number = 50, contentBounds?:
|
||||
}
|
||||
|
||||
if (cls === 'scrollable' && !isModifierWheel) {
|
||||
// Google Maps model: plain scroll zooms the canvas over ANY card (chat, app, scheduled task) UNLESS you've clicked INTO that card to read it. So a scrollable child only eats the wheel when its card is the scroll-focused one; otherwise fall through to canvas zoom.
|
||||
// Google Maps model: plain scroll zooms the canvas over a CARD (chat, scheduled task) UNLESS you've clicked INTO it. Only a card that isn't scroll-focused diverts to zoom; non-card scrollable UI (dropdowns, menus, nested panels) always scrolls natively, and a focused card scrolls its content.
|
||||
const cardEl = target.closest('[data-select-id]');
|
||||
const cardId = cardEl?.getAttribute('data-select-id') ?? null;
|
||||
if (!cardId || cardId !== getScrollFocusedCard()) {
|
||||
if (cardId && cardId !== getScrollFocusedCard()) {
|
||||
target = target.parentElement;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -53,8 +53,6 @@ export function useDashboardInteractions({
|
||||
|
||||
selection.selectCard(id, type, false);
|
||||
dispatch(bringToFront({ id, type }));
|
||||
// Clicking INTO a card focuses it for scrolling: plain wheel now reads its content instead of zooming the canvas (Google Maps model). Clicking blank canvas clears it (below).
|
||||
setScrollFocusedCard(id);
|
||||
|
||||
// The Workflows window is an app you click around inside, not a card you re-center every tap. Single-click only raises + selects it; double-click still zoom-to-fits (handleCardDoubleClick). Without this, clicking any button inside it yanked the canvas into a re-zoom.
|
||||
if (type === 'workflows-hub' || type === 'workflows-monitor') return;
|
||||
@@ -93,6 +91,8 @@ export function useDashboardInteractions({
|
||||
|
||||
const handleBringToFront = useCallback((id: string, type: CardType) => {
|
||||
dispatch(bringToFront({ id, type }));
|
||||
// Pressing ANY part of a card (header, body, composer) focuses it for scrolling, so its content scrolls instead of the canvas zooming (Google Maps model). Fires via onPointerDownCapture on every card, so a click into a chat's composer focuses it even though the body swallows the bubble. Cleared on blank-canvas press.
|
||||
setScrollFocusedCard(id);
|
||||
}, [dispatch]);
|
||||
|
||||
// A click INSIDE a webview's page never reaches the host DOM; BrowserCard forwards the guest's app-clicked IPC as this event. Select + raise only, no camera fit: you're clicking around inside the page, re-framing the canvas every tap would be hostile (same carve-out as the Workflows window).
|
||||
@@ -112,7 +112,7 @@ export function useDashboardInteractions({
|
||||
if (agentDriven) return;
|
||||
selection.selectCard(browserId, 'browser', false);
|
||||
dispatch(bringToFront({ id: browserId, type: 'browser' }));
|
||||
// Clicking inside a browser's page focuses it: plain wheel now scrolls the page instead of zooming the canvas.
|
||||
// In-guest clicks never reach the host capture handler, so mark the browser focused here, mainly to UN-focus any chat so scroll over other cards behaves right (the browser's own page scroll/zoom is native regardless).
|
||||
setScrollFocusedCard(browserId);
|
||||
};
|
||||
window.addEventListener('openswarm:browser-guest-select', onGuestSelect);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import type { CardPosition } from '@/shared/state/dashboardLayoutSlice';
|
||||
import { setScrollFocusedCard } from '@/shared/cardScrollFocus';
|
||||
import type { useDashboardSelection } from './useDashboardSelection';
|
||||
|
||||
type Selection = ReturnType<typeof useDashboardSelection>;
|
||||
@@ -45,6 +46,8 @@ export function useDashboardUiState(selection: Selection, cards: Record<string,
|
||||
if (!cards[pendingSelectSessionId]) return;
|
||||
setPendingSelectSessionId(null);
|
||||
selection.selectCard(pendingSelectSessionId, 'agent', false);
|
||||
// A freshly spawned chat is the active one: focus it for scrolling so its transcript scrolls immediately (Google Maps gate) instead of zooming the canvas until the user clicks it.
|
||||
setScrollFocusedCard(pendingSelectSessionId);
|
||||
}, [pendingSelectSessionId, cards, selection]);
|
||||
|
||||
const spawnOriginsRef = useRef<Record<string, SpawnOrigin>>({});
|
||||
|
||||
Reference in New Issue
Block a user