mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-11-10 16:21:22 +00:00
Stop AppView from re-subscribing to activeTabId so shell composition no longer rebuilds on every top-tab click; move plugin keybindings and host editor surface visibility into leaf subscribers. Patch session-restore activeTabId without re-serializing every session on tab switches, defer chrome theme CSS work with fingerprint short-circuit + rAF, let terminal workspace chrome read active workspace from the live store, apply TopTabs presentation per tab, and keep hibernate wake chunked/idle with leaner focus scheduling.
81 lines
3.3 KiB
TypeScript
81 lines
3.3 KiB
TypeScript
import { isActiveChromeThemeResolvable, resolveActiveChromeTheme } from '../app/activeChromeTheme';
|
|
import { clearTopTabsChromeThemeVars } from '../app/topTabsChromeTheme';
|
|
import type { TerminalAppearanceHostScope, ResolvedAppearance } from '../../domain/terminalAppearanceRuntime';
|
|
import type { Host, TerminalSession, TerminalTheme, Workspace } from '../../types';
|
|
import { activeTabStore } from './activeTabStore';
|
|
import type { EditorTabChrome } from './editorTabStore';
|
|
import type { LogView } from './logViewState';
|
|
import { syncActiveChromeTheme, themeFingerprint } from './useActiveChromeTheme';
|
|
|
|
export type ActiveChromeThemeDeps = {
|
|
accentMode: 'theme' | 'custom';
|
|
applyAppTheme: () => void;
|
|
currentTerminalTheme: TerminalTheme;
|
|
customAccent: string;
|
|
editorTabs: readonly EditorTabChrome[];
|
|
followAppTerminalTheme: boolean;
|
|
hostById: Map<string, Host>;
|
|
logViews: readonly LogView[];
|
|
resolveSessionAppearance?: (hostScope: TerminalAppearanceHostScope) => ResolvedAppearance;
|
|
sessionById: Map<string, TerminalSession>;
|
|
themeById: Map<string, TerminalTheme>;
|
|
workspaceById: Map<string, Workspace>;
|
|
};
|
|
|
|
let depsRef: ActiveChromeThemeDeps | null = null;
|
|
let pendingRafId: number | null = null;
|
|
let pendingActiveTabId: string | null = null;
|
|
|
|
export function updateActiveChromeThemeDeps(deps: ActiveChromeThemeDeps): void {
|
|
depsRef = deps;
|
|
}
|
|
|
|
/**
|
|
* Apply chrome theme for a tab. Short-circuits when the resolved theme
|
|
* fingerprint matches the already-applied chrome fingerprint so rapid tab
|
|
* clicks do not force style work. Tab switches always use instant mode via
|
|
* syncActiveChromeTheme (no view transitions).
|
|
*/
|
|
export function applyChromeThemeForTab(activeTabId: string): void {
|
|
if (!depsRef || typeof document === 'undefined') return;
|
|
if (activeTabId === 'vault' || activeTabId === 'sftp') {
|
|
clearTopTabsChromeThemeVars();
|
|
}
|
|
// Non-terminal tabs: React chrome effect clears overlay theme. Do not force
|
|
// a full style reset here on every vault/sftp click.
|
|
if (!isActiveChromeThemeResolvable({ ...depsRef, activeTabId })) return;
|
|
const activeTheme = resolveActiveChromeTheme({ ...depsRef, activeTabId });
|
|
// Fingerprint short-circuit is also inside syncActiveChromeTheme; check here
|
|
// so we avoid even building transition work when the theme is unchanged.
|
|
if (activeTheme) {
|
|
const nextFp = themeFingerprint(activeTheme);
|
|
const applied = document.documentElement.dataset.activeChromeTheme ?? null;
|
|
if (nextFp === applied) return;
|
|
}
|
|
syncActiveChromeTheme(activeTheme, depsRef.applyAppTheme);
|
|
}
|
|
|
|
/**
|
|
* Schedule chrome theme apply on the next animation frame so click handlers
|
|
* and React commit are not blocked by :root CSS rewrites.
|
|
*/
|
|
export function notifyActiveChromeThemeForTab(activeTabId: string): void {
|
|
pendingActiveTabId = activeTabId;
|
|
if (typeof document === 'undefined') {
|
|
applyChromeThemeForTab(activeTabId);
|
|
return;
|
|
}
|
|
if (pendingRafId !== null) return;
|
|
const schedule = typeof requestAnimationFrame === 'function'
|
|
? requestAnimationFrame
|
|
: (cb: FrameRequestCallback) => window.setTimeout(() => cb(0), 0) as unknown as number;
|
|
pendingRafId = schedule(() => {
|
|
pendingRafId = null;
|
|
const tabId = pendingActiveTabId;
|
|
pendingActiveTabId = null;
|
|
if (tabId != null) applyChromeThemeForTab(tabId);
|
|
});
|
|
}
|
|
|
|
activeTabStore.subscribeSync(notifyActiveChromeThemeForTab);
|