Files
NetMesh/application/state/sidePanelLiveStore.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

105 lines
3.8 KiB
TypeScript

import type { Host, TerminalSession, TerminalTheme, Workspace } from '../../types';
export type SidePanelLiveSnapshot = {
sftpActiveHost: Host | null;
activeTerminalSessionIdForSftp: string | null;
activeTerminalCwd: string | null;
activeTerminalCwdTrusted: boolean;
activeWorkspace: Workspace | undefined;
activeTerminalSessionForSystem: TerminalSession | null;
activeSystemSessionHost: Host | null;
focusedHost: Host | null;
focusedSessionId: string | null;
historySessionId: string | null;
resolvedPreviewTheme: TerminalTheme | null;
previewedOrVisibleThemeId: string | undefined;
focusedFontFamilyId: string | undefined;
focusedFontFamilyOverridden: boolean;
focusedFontSize: number | undefined;
focusedFontSizeOverridden: boolean;
focusedFontWeight: number | undefined;
focusedFontWeightOverridden: boolean;
focusedThemeOverridden: boolean;
};
const EMPTY_SNAPSHOT: SidePanelLiveSnapshot = {
sftpActiveHost: null,
activeTerminalSessionIdForSftp: null,
activeTerminalCwd: null,
activeTerminalCwdTrusted: false,
activeWorkspace: undefined,
activeTerminalSessionForSystem: null,
activeSystemSessionHost: null,
focusedHost: null,
focusedSessionId: null,
historySessionId: null,
resolvedPreviewTheme: null,
previewedOrVisibleThemeId: undefined,
focusedFontFamilyId: undefined,
focusedFontFamilyOverridden: false,
focusedFontSize: undefined,
focusedFontSizeOverridden: false,
focusedFontWeight: undefined,
focusedFontWeightOverridden: false,
focusedThemeOverridden: false,
};
export const SIDE_PANEL_INACTIVE_LIVE_SNAPSHOT = EMPTY_SNAPSHOT;
type Listener = () => void;
function liveSnapshotEqual(a: SidePanelLiveSnapshot, b: SidePanelLiveSnapshot): boolean {
return a.sftpActiveHost === b.sftpActiveHost
&& a.activeTerminalSessionIdForSftp === b.activeTerminalSessionIdForSftp
&& a.activeTerminalCwd === b.activeTerminalCwd
&& a.activeTerminalCwdTrusted === b.activeTerminalCwdTrusted
&& a.activeWorkspace === b.activeWorkspace
&& a.activeTerminalSessionForSystem === b.activeTerminalSessionForSystem
&& a.activeSystemSessionHost === b.activeSystemSessionHost
&& a.focusedHost === b.focusedHost
&& a.focusedSessionId === b.focusedSessionId
&& a.historySessionId === b.historySessionId
&& a.resolvedPreviewTheme === b.resolvedPreviewTheme
&& a.previewedOrVisibleThemeId === b.previewedOrVisibleThemeId
&& a.focusedFontFamilyId === b.focusedFontFamilyId
&& a.focusedFontFamilyOverridden === b.focusedFontFamilyOverridden
&& a.focusedFontSize === b.focusedFontSize
&& a.focusedFontSizeOverridden === b.focusedFontSizeOverridden
&& a.focusedFontWeight === b.focusedFontWeight
&& a.focusedFontWeightOverridden === b.focusedFontWeightOverridden
&& a.focusedThemeOverridden === b.focusedThemeOverridden;
}
class SidePanelLiveStore {
private snapshot: SidePanelLiveSnapshot = EMPTY_SNAPSHOT;
private listeners = new Set<Listener>();
getSnapshot = (): SidePanelLiveSnapshot => this.snapshot;
subscribe = (listener: Listener): (() => void) => {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
};
update(next: SidePanelLiveSnapshot): void {
if (liveSnapshotEqual(this.snapshot, next)) return;
this.snapshot = next;
for (const listener of this.listeners) {
listener();
}
}
}
export const sidePanelLiveStore = new SidePanelLiveStore();
const noopSubscribe = () => () => {};
export function subscribeSidePanelLiveSnapshot(enabled: boolean, listener: Listener): () => void {
if (!enabled) return noopSubscribe();
return sidePanelLiveStore.subscribe(listener);
}
export function getSidePanelLiveSnapshot(enabled: boolean): SidePanelLiveSnapshot {
return enabled ? sidePanelLiveStore.getSnapshot() : SIDE_PANEL_INACTIVE_LIVE_SNAPSHOT;
}