- Progressive Reveal: ChatScreen spiegelt bei project_changed den Projekt-Typ sofort in projectFocus (kind_changed nach set_project_kind) → Editor/Desktop- Kacheln erscheinen live, nicht erst beim Reconnect. - useWorkspaceLayout: merkt pro Projekt die zuletzt fokussierte Kachel (AsyncStorage aria_workspace_layout) und stellt sie beim Zurueckkehren in ein Code-Projekt wieder her. tsc clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
/**
|
|
* useWorkspaceLayout — merkt sich pro Projekt die zuletzt fokussierte Kachel,
|
|
* damit man beim Zurueckkehren in ein Code-Projekt wieder dort landet (Editor/
|
|
* Desktop) statt immer im Chat. Persistiert nach AsyncStorage (Muster wie
|
|
* aria_project_drafts).
|
|
*/
|
|
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
import { TileId } from './layout';
|
|
|
|
const KEY = 'aria_workspace_layout';
|
|
|
|
interface Entry { focus: TileId | null }
|
|
type LayoutMap = Record<string, Entry>;
|
|
|
|
const keyOf = (projectId: string) => projectId || '__main__';
|
|
|
|
export function useWorkspaceLayout(projectId: string) {
|
|
const mapRef = useRef<LayoutMap>({});
|
|
const [loaded, setLoaded] = useState(false);
|
|
|
|
useEffect(() => {
|
|
AsyncStorage.getItem(KEY).then((v) => {
|
|
if (v) { try { mapRef.current = JSON.parse(v) || {}; } catch { /* ignore */ } }
|
|
setLoaded(true);
|
|
}).catch(() => setLoaded(true));
|
|
}, []);
|
|
|
|
const getFocus = useCallback((): TileId | null | undefined => {
|
|
return mapRef.current[keyOf(projectId)]?.focus;
|
|
}, [projectId]);
|
|
|
|
const saveFocus = useCallback((focus: TileId | null) => {
|
|
mapRef.current = { ...mapRef.current, [keyOf(projectId)]: { focus } };
|
|
AsyncStorage.setItem(KEY, JSON.stringify(mapRef.current)).catch(() => {});
|
|
}, [projectId]);
|
|
|
|
return { loaded, getFocus, saveFocus };
|
|
}
|