mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
[eric] dashboard: docked APPS suppress their tether too; tiled geometry never transitions (occluded-window transitions pin at t=0 and freeze tiles); tiles + dock measures re-apply on window reveal
This commit is contained in:
@@ -271,11 +271,13 @@ const BrowserCard: React.FC<Props> = ({
|
||||
// A RO only fires on slot RESIZE; the chat tiling/untiling MOVES the slot without resizing the
|
||||
// window, so re-measure on camera writes + settle timers or the docked card lags behind.
|
||||
window.addEventListener('openswarm:canvas-pan-changed', measure);
|
||||
document.addEventListener('visibilitychange', measure);
|
||||
const timers = [60, 250, 700].map((ms) => window.setTimeout(measure, ms));
|
||||
return () => {
|
||||
ro.disconnect();
|
||||
window.removeEventListener('resize', measure);
|
||||
window.removeEventListener('openswarm:canvas-pan-changed', measure);
|
||||
document.removeEventListener('visibilitychange', measure);
|
||||
timers.forEach((tm) => window.clearTimeout(tm));
|
||||
};
|
||||
// dockParentCard x/y/w/h are re-measure triggers: the slot's client rect moves with the chat card.
|
||||
|
||||
@@ -197,11 +197,13 @@ const DashboardViewCard: React.FC<Props> = ({
|
||||
// A RO only fires on slot RESIZE; the chat tiling/untiling MOVES the slot without resizing the
|
||||
// window, so re-measure on camera writes + settle timers or the docked card lags behind.
|
||||
window.addEventListener('openswarm:canvas-pan-changed', measure);
|
||||
document.addEventListener('visibilitychange', measure);
|
||||
const timers = [60, 250, 700].map((ms) => window.setTimeout(measure, ms));
|
||||
return () => {
|
||||
ro.disconnect();
|
||||
window.removeEventListener('resize', measure);
|
||||
window.removeEventListener('openswarm:canvas-pan-changed', measure);
|
||||
document.removeEventListener('visibilitychange', measure);
|
||||
timers.forEach((tm) => window.clearTimeout(tm));
|
||||
};
|
||||
}, [dockedTo, dockParentExpanded, dockParentTiled, dockParentCard?.x, dockParentCard?.y, dockParentCard?.width, dockParentCard?.height, getCanvasState, dockParentCard]);
|
||||
|
||||
@@ -123,7 +123,7 @@ export function useTiledStyle(
|
||||
? el
|
||||
: (el.parentElement as HTMLElement | null) ?? el;
|
||||
const posProps = ['left', 'top'];
|
||||
const sizeProps = ['width', 'height', 'transform', 'transform-origin'];
|
||||
const sizeProps = ['width', 'height', 'transform', 'transform-origin', 'transition'];
|
||||
const clearAll = (): void => {
|
||||
posProps.forEach((pr) => posEl.style.removeProperty(pr));
|
||||
sizeProps.forEach((pr) => el.style.removeProperty(pr));
|
||||
@@ -142,10 +142,18 @@ export function useTiledStyle(
|
||||
el.style.setProperty('height', `${s.height}px`, 'important');
|
||||
el.style.setProperty('transform', s.transform, 'important');
|
||||
el.style.setProperty('transform-origin', s.transformOrigin, 'important');
|
||||
// Transitions OUTRANK inline important in the cascade, and in an occluded window they pin at
|
||||
// t=0 forever, freezing the tile at stale geometry. Tiled cards track the camera instantly
|
||||
// by design, so geometry must never animate here.
|
||||
el.style.setProperty('transition', 'none', 'important');
|
||||
};
|
||||
apply();
|
||||
window.addEventListener('openswarm:canvas-pan-changed', apply);
|
||||
window.addEventListener('resize', apply);
|
||||
// An occluded window freezes rAF (framer, the tracker below), so geometry set while hidden can
|
||||
// land stale; re-apply the moment the window is visible again.
|
||||
document.addEventListener('visibilitychange', apply);
|
||||
window.addEventListener('focus', apply);
|
||||
// The workspace can change size WITHOUT a window resize (chrome collapsing on fullscreen-enter,
|
||||
// a banner appearing). These inline writes OVERRIDE the class styles, so they must re-measure on
|
||||
// the same signals the React path uses or the tile keeps the pre-collapse viewport (the
|
||||
@@ -170,6 +178,8 @@ export function useTiledStyle(
|
||||
return () => {
|
||||
window.removeEventListener('openswarm:canvas-pan-changed', apply);
|
||||
window.removeEventListener('resize', apply);
|
||||
document.removeEventListener('visibilitychange', apply);
|
||||
window.removeEventListener('focus', apply);
|
||||
ro.disconnect();
|
||||
timers.forEach((tm) => window.clearTimeout(tm));
|
||||
window.cancelAnimationFrame(raf);
|
||||
|
||||
@@ -266,8 +266,8 @@ export function useTethers({
|
||||
// An "app:<output_id>" glow key targets a VIEW card (AppAgent driving an app); everything else is a browser card.
|
||||
const glowTarget = (id: string) => (id.startsWith('app:') ? viewCards[id.slice(4)] : browserCards[id]);
|
||||
for (const [browserId, { sourceId, fading, label }] of Object.entries(glowingBrowserCards)) {
|
||||
// A docked browser renders INSIDE its chat; an arrow from the chat to it points at nothing.
|
||||
if (browserCards[browserId]?.docked_to) continue;
|
||||
// A docked card (browser OR app) renders INSIDE its chat; an arrow to it points at nothing.
|
||||
if (glowTarget(browserId)?.docked_to) continue;
|
||||
if (sourceIsCollapsedChat(sourceId)) continue;
|
||||
const t = cardTether(
|
||||
glowTarget(browserId),
|
||||
|
||||
Reference in New Issue
Block a user