The live screen opens wide beside the chat while the bot works on it or asks for a takeover, a file the bot presents as its result opens next to the conversation, and a question that scrolled away gets a "Needs you" pill back to it. Shared core rules derive the focus from signals clients already have (pointer events, takeover requests, a new `present` flag on attach_file, pending asks), move the pane only on focus edges, never replace a pane the user opened, and learn per bot whether the screen opens on its own. Pane widths persist per device; mobile shows a pill that opens the computer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7VSRHHzyt2KwoCkUkZ2Gc
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import { parseScreenPaneHabit, type ScreenPaneHabit } from "@rakazo/core";
|
|
|
|
function screenHabitKey(userId: string | null | undefined, botId: string | null | undefined) {
|
|
if (!userId || !botId) return null;
|
|
return `rakazo:screen-pane:${userId}:${botId}`;
|
|
}
|
|
|
|
export function readScreenPaneHabit(
|
|
userId: string | null | undefined,
|
|
botId: string | null | undefined,
|
|
): ScreenPaneHabit {
|
|
const key = screenHabitKey(userId, botId);
|
|
if (!key) return 0;
|
|
try {
|
|
return parseScreenPaneHabit(window.localStorage.getItem(key));
|
|
} catch {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
export function writeScreenPaneHabit(
|
|
userId: string | null | undefined,
|
|
botId: string | null | undefined,
|
|
habit: ScreenPaneHabit,
|
|
): void {
|
|
const key = screenHabitKey(userId, botId);
|
|
if (!key) return;
|
|
try {
|
|
if (habit === 0) window.localStorage.removeItem(key);
|
|
else window.localStorage.setItem(key, String(habit));
|
|
} catch {
|
|
// Private mode or a full quota only loses the learned default.
|
|
}
|
|
}
|
|
|
|
export function readPaneWidth(storageKey: string, fallback: number, min: number, max: number) {
|
|
try {
|
|
const stored = Number(window.localStorage.getItem(storageKey));
|
|
if (Number.isFinite(stored) && stored > 0) return Math.max(min, Math.min(max, stored));
|
|
} catch {
|
|
// Fall through to the default width.
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
export function writePaneWidth(storageKey: string, width: number): void {
|
|
try {
|
|
window.localStorage.setItem(storageKey, String(Math.round(width)));
|
|
} catch {
|
|
// The width still applies for this session.
|
|
}
|
|
}
|