openclaw/ui/src/ui/app-lifecycle.ts
2026-01-14 09:11:36 +00:00

106 lines
3.1 KiB
TypeScript

import type { Tab } from "./navigation";
import { connectGateway } from "./app-gateway";
import {
applySettingsFromUrl,
attachThemeListener,
detachThemeListener,
inferBasePath,
syncTabWithLocation,
syncThemeWithSettings,
} from "./app-settings";
import { observeTopbar, scheduleChatScroll, scheduleLogsScroll } from "./app-scroll";
import {
startLogsPolling,
startNodesPolling,
stopLogsPolling,
stopNodesPolling,
} from "./app-polling";
type LifecycleHost = {
basePath: string;
tab: Tab;
chatHasAutoScrolled: boolean;
chatLoading: boolean;
chatMessages: unknown[];
chatToolMessages: unknown[];
chatStream: string;
logsAutoFollow: boolean;
logsAtBottom: boolean;
logsEntries: unknown[];
popStateHandler: () => void;
topbarObserver: ResizeObserver | null;
};
export function handleConnected(host: LifecycleHost) {
host.basePath = inferBasePath();
syncTabWithLocation(
host as unknown as Parameters<typeof syncTabWithLocation>[0],
true,
);
syncThemeWithSettings(
host as unknown as Parameters<typeof syncThemeWithSettings>[0],
);
attachThemeListener(
host as unknown as Parameters<typeof attachThemeListener>[0],
);
window.addEventListener("popstate", host.popStateHandler);
applySettingsFromUrl(
host as unknown as Parameters<typeof applySettingsFromUrl>[0],
);
connectGateway(host as unknown as Parameters<typeof connectGateway>[0]);
startNodesPolling(host as unknown as Parameters<typeof startNodesPolling>[0]);
if (host.tab === "logs") {
startLogsPolling(host as unknown as Parameters<typeof startLogsPolling>[0]);
}
}
export function handleFirstUpdated(host: LifecycleHost) {
observeTopbar(host as unknown as Parameters<typeof observeTopbar>[0]);
}
export function handleDisconnected(host: LifecycleHost) {
window.removeEventListener("popstate", host.popStateHandler);
stopNodesPolling(host as unknown as Parameters<typeof stopNodesPolling>[0]);
stopLogsPolling(host as unknown as Parameters<typeof stopLogsPolling>[0]);
detachThemeListener(
host as unknown as Parameters<typeof detachThemeListener>[0],
);
host.topbarObserver?.disconnect();
host.topbarObserver = null;
}
export function handleUpdated(
host: LifecycleHost,
changed: Map<PropertyKey, unknown>,
) {
if (
host.tab === "chat" &&
(changed.has("chatMessages") ||
changed.has("chatToolMessages") ||
changed.has("chatStream") ||
changed.has("chatLoading") ||
changed.has("tab"))
) {
const forcedByTab = changed.has("tab");
const forcedByLoad =
changed.has("chatLoading") &&
changed.get("chatLoading") === true &&
host.chatLoading === false;
scheduleChatScroll(
host as unknown as Parameters<typeof scheduleChatScroll>[0],
forcedByTab || forcedByLoad || !host.chatHasAutoScrolled,
);
}
if (
host.tab === "logs" &&
(changed.has("logsEntries") || changed.has("logsAutoFollow") || changed.has("tab"))
) {
if (host.logsAutoFollow && host.logsAtBottom) {
scheduleLogsScroll(
host as unknown as Parameters<typeof scheduleLogsScroll>[0],
changed.has("tab") || changed.has("logsAutoFollow"),
);
}
}
}