Files
yaak-mountain-loop/apps/yaak-proxy/lib/windowSync.ts
T
Gregory SchierandClaude Opus 5.5 f7402f5f4f Open Yaak Proxy's Settings in its own window
Settings opens in a window labelled `settings`, created through the shared
window code, as Yaak's does. The page renders the settings alone or the app
by its window label. Opening it again focuses it and moves it to the tab
asked for; Escape closes it, and closing the main window closes it too.
Changes made there reach the main window at once: theme and sizes by an
event carrying the values, and engine settings by an event after each RPC
mutation that makes other windows read the proxy state and settings
queries again. The browser harness, with no second window, keeps the
dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 11:34:34 -07:00

52 lines
1.9 KiB
TypeScript

import type { QueryClient, QueryKey } from "@tanstack/react-query";
import type { createStore } from "jotai";
import { refreshProxyState } from "./store";
import { broadcast, currentWindowLabel, subscribe } from "./tauri";
type Store = ReturnType<typeof createStore>;
/** Sent after a change made through the engine, so the app's other windows read again */
const ENGINE_CHANGED_EVENT = "window_changed_engine";
interface EngineChanged {
/** The window the change was made in, which has read again already */
from: string;
}
/**
* The queries a change in another window can leave stale: what Settings sets, and the system
* proxy and certificate state the header and Settings both show. Flows and their bodies have
* events of their own, and reading them again would cost far more.
*/
const SHARED_STATE_QUERIES = new Set([
"system_proxy_status",
"ca_status",
"get_storage_size",
"get_decrypt_list",
"list_seen",
]);
export function isSharedStateQuery(queryKey: QueryKey): boolean {
return SHARED_STATE_QUERIES.has(String(queryKey[0]));
}
/** Tells the app's other windows a change was made here, such as a setting */
export function announceEngineChange() {
broadcast(ENGINE_CHANGED_EVENT, { from: currentWindowLabel() } satisfies EngineChanged).catch(
(err) => console.warn("Failed to tell the other windows of a change", err),
);
}
/**
* Reads the engine's state and the shared queries again when another window changes them, as
* that window does itself, so a setting changed in Settings shows in the main window at once.
*/
export function syncFromOtherWindows(store: Store, queryClient: QueryClient) {
const here = currentWindowLabel();
subscribe<EngineChanged>(ENGINE_CHANGED_EVENT, ({ from }) => {
if (from === here) return;
refreshProxyState(store).catch((err) => console.warn("Failed to read the proxy state", err));
void queryClient.invalidateQueries({ predicate: (q) => isSharedStateQuery(q.queryKey) });
});
}