[eric] desktop: orphaned fullscreen tile sealed, all chrome hides while fullscreen, native lights defer to card lights, wash is a GPU-cached texture, tile menu clamps at edges, chat embed exclusive to full view, workflows one-click zones

This commit is contained in:
ciregenz
2026-07-27 20:18:39 -07:00
parent cf37c76331
commit e2af99ea91
14 changed files with 85 additions and 20 deletions
@@ -714,6 +714,9 @@ const dashboardLayoutSlice = createSlice({
if (!liveIds.has(id)) {
state.closedCardPositions[id] = { ...state.cards[id] };
delete state.cards[id];
// A dead card must never keep owning a tile: an orphaned 'fullscreen' entry hides ALL chrome until reload.
delete state.tiledCards[id];
delete state.minimizedCards[id];
}
}
@@ -1900,8 +1903,13 @@ export const reopenLastClosed = createAsyncThunk(
);
export const selectFullscreenCardId = (state: { dashboardLayout: DashboardLayoutState }): string | null => {
const entry = Object.entries(state.dashboardLayout.tiledCards).find(([, zone]) => zone === 'fullscreen');
return entry ? entry[0] : null;
const s = state.dashboardLayout;
const entry = Object.entries(s.tiledCards).find(([, zone]) => zone === 'fullscreen');
if (!entry) return null;
const id = entry[0];
// Belt over the reducer hygiene: an entry whose card is gone (any removal path) must not hold the app in fullscreen.
const exists = id in s.cards || id in s.viewCards || id in s.browserCards || id in s.notes || id in s.workflowCards;
return exists ? id : null;
};
export default dashboardLayoutSlice.reducer;
@@ -112,15 +112,21 @@ export const { setSubscriptionStatus, markSubscriptionConnected, hideProviderHea
const EMPTY_CONNECTIONS: SubscriptionConnection[] = [];
/** Unwraps the polymorphic `providers` shape (modern object vs legacy array). */
let p_lastRows: SubscriptionConnection[] | null = null;
let p_lastFiltered: SubscriptionConnection[] | null = null;
export function selectSubscriptionConnections(
state: WithSubscriptions,
): SubscriptionConnection[] {
const providers = state.subscriptions.status?.providers;
if (!providers) return EMPTY_CONNECTIONS;
const rows = Array.isArray(providers) ? providers : (providers.connections ?? EMPTY_CONNECTIONS);
// The free-trial/Pro lane is an OpenSwarm-managed router row, not a connection the USER made; counting it made a fresh trial look "connected" (dead Connect-beat rows, premature onConnected, phantom green rings).
// The free-trial/Pro lane is an OpenSwarm-managed router row, not a connection the USER made; counting it made a fresh trial look "connected" (dead Connect-beat rows, premature onConnected, phantom green rings). Memoized per rows identity so useSelector consumers don't churn.
if (rows === p_lastRows && p_lastFiltered) return p_lastFiltered;
const filtered = rows.filter((p) => !/\(OpenSwarm-managed\)/.test(p.name ?? ''));
return filtered.length === rows.length ? rows : filtered;
p_lastRows = rows;
p_lastFiltered = filtered.length === rows.length ? rows : filtered;
return p_lastFiltered;
}
export function hasAnyActiveSubscription(state: WithSubscriptions): boolean {