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
126 lines
4.7 KiB
TypeScript
126 lines
4.7 KiB
TypeScript
import { fromEditorTabId, isEditorTabId } from "../state/activeTabStore";
|
|
|
|
import { applyCustomAccentToTerminalTheme, resolveHostTerminalThemeId } from "../../domain/terminalAppearance";
|
|
import type {
|
|
ResolvedAppearance,
|
|
TerminalAppearanceHostScope,
|
|
} from "../../domain/terminalAppearanceRuntime";
|
|
import { collectSessionIds } from "../../domain/workspace";
|
|
import type { EditorTabChrome } from "../state/editorTabStore";
|
|
import type { LogView } from "../state/logViewState";
|
|
import type { Host, TerminalSession, TerminalTheme, Workspace } from "../../types";
|
|
import { resolveWorkspaceTargetSessionFromMap } from "./workTabSurface";
|
|
|
|
export type ResolveActiveChromeThemeInput = {
|
|
accentMode: "theme" | "custom";
|
|
activeTabId: string;
|
|
currentTerminalTheme: TerminalTheme;
|
|
customAccent: string;
|
|
editorTabs: readonly EditorTabChrome[];
|
|
followAppTerminalTheme: boolean;
|
|
hostById: ReadonlyMap<string, Host>;
|
|
logViews: readonly LogView[];
|
|
resolveSessionAppearance?: (hostScope: TerminalAppearanceHostScope) => ResolvedAppearance;
|
|
sessionById: ReadonlyMap<string, TerminalSession>;
|
|
themeById: ReadonlyMap<string, TerminalTheme>;
|
|
workspaceById: ReadonlyMap<string, Workspace>;
|
|
};
|
|
|
|
export function isActiveChromeThemeResolvable({
|
|
activeTabId,
|
|
editorTabs,
|
|
logViews,
|
|
sessionById,
|
|
workspaceById,
|
|
}: Pick<
|
|
ResolveActiveChromeThemeInput,
|
|
"activeTabId" | "editorTabs" | "logViews" | "sessionById" | "workspaceById"
|
|
>): boolean {
|
|
if (activeTabId === "vault" || activeTabId === "sftp") return true;
|
|
if (isEditorTabId(activeTabId)) {
|
|
return editorTabs.some((tab) => tab.id === fromEditorTabId(activeTabId));
|
|
}
|
|
if (logViews.some((item) => item.id === activeTabId)) return true;
|
|
if (workspaceById.has(activeTabId)) return true;
|
|
if (sessionById.has(activeTabId)) return true;
|
|
return false;
|
|
}
|
|
|
|
export function resolveActiveChromeTheme({
|
|
accentMode,
|
|
activeTabId,
|
|
currentTerminalTheme,
|
|
customAccent,
|
|
editorTabs,
|
|
followAppTerminalTheme,
|
|
hostById,
|
|
logViews,
|
|
resolveSessionAppearance,
|
|
sessionById,
|
|
themeById,
|
|
workspaceById,
|
|
}: ResolveActiveChromeThemeInput): TerminalTheme | null {
|
|
if (activeTabId === "vault" || activeTabId === "sftp") return null;
|
|
|
|
const resolveHostScope = (hostId: string): TerminalAppearanceHostScope => {
|
|
const host = hostById.get(hostId) ?? null;
|
|
return { host, isEphemeral: !host || !hostById.has(host.id) };
|
|
};
|
|
|
|
const resolveHostTheme = (hostId: string): TerminalTheme => {
|
|
if (followAppTerminalTheme) {
|
|
return applyCustomAccentToTerminalTheme(currentTerminalTheme, accentMode, customAccent);
|
|
}
|
|
if (resolveSessionAppearance) {
|
|
return resolveSessionAppearance(resolveHostScope(hostId)).theme;
|
|
}
|
|
const host = hostById.get(hostId) ?? null;
|
|
const themeId = resolveHostTerminalThemeId(host, currentTerminalTheme.id);
|
|
const baseTheme = themeById.get(themeId) ?? currentTerminalTheme;
|
|
return applyCustomAccentToTerminalTheme(baseTheme, accentMode, customAccent);
|
|
};
|
|
|
|
const resolveSessionTheme = (session: TerminalSession): TerminalTheme => resolveHostTheme(session.hostId);
|
|
|
|
if (isEditorTabId(activeTabId)) {
|
|
const editorTabId = fromEditorTabId(activeTabId);
|
|
const editorTab = editorTabs.find((tab) => tab.id === editorTabId);
|
|
if (!editorTab) return null;
|
|
return resolveHostTheme(editorTab.hostId);
|
|
}
|
|
|
|
const logView = logViews.find((item) => item.id === activeTabId);
|
|
if (logView) {
|
|
const explicitThemeId = logView.log.themeId;
|
|
const base = explicitThemeId ? themeById.get(explicitThemeId) ?? currentTerminalTheme : currentTerminalTheme;
|
|
return applyCustomAccentToTerminalTheme(base, accentMode, customAccent);
|
|
}
|
|
|
|
const workspace = workspaceById.get(activeTabId);
|
|
if (workspace) {
|
|
if (followAppTerminalTheme) {
|
|
return applyCustomAccentToTerminalTheme(currentTerminalTheme, accentMode, customAccent);
|
|
}
|
|
|
|
if (workspace.viewMode === "focus") {
|
|
const focusedSession = resolveWorkspaceTargetSessionFromMap(workspace, sessionById);
|
|
return focusedSession ? resolveSessionTheme(focusedSession) : null;
|
|
}
|
|
|
|
const workspaceSessions = collectSessionIds(workspace.root)
|
|
.map((id) => sessionById.get(id))
|
|
.filter(Boolean) as TerminalSession[];
|
|
if (workspaceSessions.length === 0) return null;
|
|
|
|
const firstTheme = resolveSessionTheme(workspaceSessions[0]);
|
|
const allSame = workspaceSessions.every((session) => resolveSessionTheme(session).id === firstTheme.id);
|
|
if (allSame) return firstTheme;
|
|
|
|
const focusedSession = resolveWorkspaceTargetSessionFromMap(workspace, sessionById);
|
|
return focusedSession ? resolveSessionTheme(focusedSession) : null;
|
|
}
|
|
|
|
const session = sessionById.get(activeTabId);
|
|
return session ? resolveSessionTheme(session) : null;
|
|
}
|