mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-17 23:27:41 +02:00
[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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user