mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-02 14:28:59 +02:00
[eric] canvas: drags flag canvas interaction, idle-canvas drags skip tether work, the toolbar selector stops minting arrays
This commit is contained in:
@@ -20,6 +20,9 @@ import { useElementSelection } from '@/app/components/editor/ElementSelectionCon
|
||||
import { ClaudeTokens } from '@/shared/styles/claudeTokens';
|
||||
import { ComposerPlusMenu, ActiveTogglePills, PlusMenuItem } from './ComposerPlusMenu';
|
||||
|
||||
// Stable empty: minting [] inside the selector re-rendered the toolbar on every store commit.
|
||||
const EMPTY_MCPS: string[] = [];
|
||||
|
||||
interface Props {
|
||||
c: ClaudeTokens;
|
||||
elementSelection: ReturnType<typeof useElementSelection>;
|
||||
@@ -48,7 +51,7 @@ export const ToolbarActions: React.FC<Props> = ({
|
||||
// Lazy-load the skills list the first time the menu could need it; cheap and cached in the slice.
|
||||
const skills = useAppSelector((s) => s.skills.items);
|
||||
const skillsLoaded = useAppSelector((s) => s.skills.loaded);
|
||||
const activeMcps = useAppSelector((s) => (sessionId ? s.agents.sessions[sessionId]?.active_mcps : undefined) ?? []);
|
||||
const activeMcps = useAppSelector((s) => (sessionId ? s.agents.sessions[sessionId]?.active_mcps : undefined) ?? EMPTY_MCPS);
|
||||
React.useEffect(() => { if (!skillsLoaded) dispatch(fetchSkills()); }, [skillsLoaded, dispatch]);
|
||||
// Every composer action collapses into one "+" so the bar reads empty at rest; active toggles
|
||||
// (web search, selecting) still surface as a pill so their state stays visible. New capabilities
|
||||
|
||||
@@ -9,7 +9,12 @@ import TetherLayer from './TetherLayer';
|
||||
// whole dashboard tree (the ENG-88 input delay).
|
||||
const TetherLayerHost: React.FC<{ inputs: TetherInputs; c: ClaudeTokens }> = ({ inputs, c }) => {
|
||||
const [liveDrag, setLiveDrag] = useState<LiveDragInfo | null>(null);
|
||||
useEffect(() => subscribeLiveDrag(setLiveDrag), []);
|
||||
// Tethers only exist while something glows; on an idle canvas a drag frame should cost zero React work, so don't even subscribe.
|
||||
const hasTethers = Object.keys(inputs.glowingAgentCards).length > 0 || Object.keys(inputs.glowingBrowserCards).length > 0;
|
||||
useEffect(() => {
|
||||
if (!hasTethers) { setLiveDrag(null); return undefined; }
|
||||
return subscribeLiveDrag(setLiveDrag);
|
||||
}, [hasTethers]);
|
||||
const tethers = useTethers(inputs, liveDrag);
|
||||
return <TetherLayer tethers={tethers} c={c} />;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { moveCards } from '@/shared/state/dashboardLayoutSlice';
|
||||
import type { CardType, useDashboardSelection } from '../state/useDashboardSelection';
|
||||
import type { CanvasActions } from './useCanvasControls';
|
||||
import { publishLiveDrag } from './liveDragChannel';
|
||||
import { setCanvasInteractionActive } from '@/shared/canvasInteractionState';
|
||||
|
||||
type Selection = ReturnType<typeof useDashboardSelection>;
|
||||
|
||||
@@ -98,6 +99,8 @@ export function useCardDrag({
|
||||
}
|
||||
// Arm the webview shield on the first real MOVE, not on pointerdown: a plain click also arms the drag machinery, and shielding then made the click-to-focus camera fit skip (it saw a "drag in progress"), so focusing a card took two clicks. On a real drag the shield still goes up before the pointer travels, so the webview neutralization + no-nudge + release-over-webview fixes all hold. Idempotent add.
|
||||
document.body.classList.add('dashboard-marquee-active');
|
||||
// Card drags count as canvas interaction: without this, a mid-drag transcript resize re-rendered the whole controller per change (the ResizeObserver bail never engaged).
|
||||
setCanvasInteractionActive(true);
|
||||
// Start edge panning only once actual dragging begins; a live frame handle means the loop is already running.
|
||||
if (edgePanFrameRef.current === null) {
|
||||
edgePanFrameRef.current = requestAnimationFrame(tickEdgePan);
|
||||
@@ -116,6 +119,7 @@ export function useCardDrag({
|
||||
canvasActions.commit();
|
||||
activeDragCardRef.current = null;
|
||||
document.body.classList.remove('dashboard-marquee-active');
|
||||
setCanvasInteractionActive(false);
|
||||
isMultiDragRef.current = false;
|
||||
setMultiDragDelta(null);
|
||||
publishLiveDrag(null);
|
||||
|
||||
Reference in New Issue
Block a user