Files
tutti/apps/desktop/src/main/desktopHostPreferencesEventStream.ts
T
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

86 lines
2.9 KiB
TypeScript

import {
createTuttidEventStreamClient,
type TuttidEventStreamClient
} from "@tutti-os/client-tuttid-ts";
import type { DesktopThemeSource } from "../shared/theme/index.ts";
import type { DesktopHostPreferencesState } from "./desktopHostPreferences.ts";
import type { DesktopLogger } from "./logging.ts";
import type { AppUpdateService } from "./update/appUpdateService.ts";
import {
resolveDesktopBusinessEventStreamUrl,
type DesktopDaemonEndpoint
} from "./transport/paths.ts";
export interface DesktopHostPreferencesEventStream {
dispose(): void;
}
export interface DesktopHostPreferencesEventStreamDependencies {
applyThemeSource: (source: DesktopThemeSource) => unknown;
eventStreamClient: TuttidEventStreamClient;
logger: DesktopLogger;
preferences: DesktopHostPreferencesState;
updateService?: Pick<AppUpdateService, "configure">;
syncWindowBackgroundColors: () => void;
}
export function createDesktopHostPreferencesEventStreamClient(
endpoint: DesktopDaemonEndpoint
): TuttidEventStreamClient {
return createTuttidEventStreamClient({
resolveUrl: () => resolveDesktopBusinessEventStreamUrl(endpoint)
});
}
export function connectDesktopHostPreferencesEventStream(
deps: DesktopHostPreferencesEventStreamDependencies
): DesktopHostPreferencesEventStream {
const unsubscribe = deps.eventStreamClient.subscribe(
"preferences.desktop.updated",
(event) => {
const nextPreferences = event.payload.preferences;
const themeSourceChanged =
deps.preferences.getThemeSource() !== nextPreferences.themeSource;
// Composer defaults and other non-update prefs also publish this event.
// Only reconfigure the updater when channel/policy actually change, so
// permission-mode switches do not flash "Checking for updates".
const updatePreferencesChanged =
deps.preferences.getUpdateChannel() !== nextPreferences.updateChannel ||
deps.preferences.getUpdatePolicy() !== nextPreferences.updatePolicy;
deps.preferences.syncAuthoritative(nextPreferences);
if (updatePreferencesChanged) {
void deps.updateService
?.configure({
channel: nextPreferences.updateChannel,
policy: nextPreferences.updatePolicy
})
.catch((error: unknown) => {
deps.logger.warn("failed to apply desktop update preferences", {
error: error instanceof Error ? error.message : String(error)
});
});
}
if (themeSourceChanged) {
deps.applyThemeSource(nextPreferences.themeSource);
deps.syncWindowBackgroundColors();
}
}
);
void deps.eventStreamClient.connect().catch((error: unknown) => {
deps.logger.warn("failed to connect desktop preferences event stream", {
error: error instanceof Error ? error.message : String(error)
});
});
return {
dispose() {
unsubscribe();
deps.eventStreamClient.dispose();
}
};
}