()
| 59 | } |
| 60 | |
| 61 | export function useDesktopShell() { |
| 62 | const queryClient = useQueryClient() |
| 63 | const loadMergedShellState = useCallback(async () => { |
| 64 | const nextState = await getShellStateQuery() |
| 65 | const currentState = queryClient.getQueryData<ShellState | null>(desktopQueryKeys.shellState()) |
| 66 | return mergeShellStateProjects(currentState, nextState) |
| 67 | }, [queryClient]) |
| 68 | |
| 69 | const shellStateQuery = useQuery<ShellState | null>({ |
| 70 | queryKey: desktopQueryKeys.shellState(), |
| 71 | queryFn: loadMergedShellState, |
| 72 | staleTime: Number.POSITIVE_INFINITY, |
| 73 | }) |
| 74 | |
| 75 | const shellRefreshDebouncer = useMemo( |
| 76 | () => |
| 77 | new Debouncer( |
| 78 | () => { |
| 79 | void queryClient.invalidateQueries({ queryKey: desktopQueryKeys.shellState() }) |
| 80 | }, |
| 81 | { wait: 140 }, |
| 82 | ), |
| 83 | [queryClient], |
| 84 | ) |
| 85 | |
| 86 | const refreshShellState = useCallback(async () => { |
| 87 | const nextState = await queryClient.fetchQuery({ |
| 88 | queryKey: desktopQueryKeys.shellState(), |
| 89 | queryFn: loadMergedShellState, |
| 90 | staleTime: 0, |
| 91 | }) |
| 92 | |
| 93 | return nextState |
| 94 | }, [loadMergedShellState, queryClient]) |
| 95 | |
| 96 | const scheduleShellStateRefresh = useCallback(() => { |
| 97 | shellRefreshDebouncer.maybeExecute() |
| 98 | }, [shellRefreshDebouncer]) |
| 99 | |
| 100 | const loadProjectThreads = useCallback( |
| 101 | async (projectId: string, options: { chat?: boolean | undefined } = {}) => { |
| 102 | const threadsScope = options.chat ? 'chat' : 'code' |
| 103 | const threads = await queryClient.fetchQuery({ |
| 104 | queryKey: desktopQueryKeys.projectThreads(projectId, options.chat === true), |
| 105 | queryFn: () => getProjectThreadsQuery(projectId, options.chat === true), |
| 106 | staleTime: 0, |
| 107 | }) |
| 108 | |
| 109 | queryClient.setQueryData<ShellState | null>(desktopQueryKeys.shellState(), (currentState) => { |
| 110 | if (!currentState) { |
| 111 | return currentState ?? null |
| 112 | } |
| 113 | |
| 114 | return { |
| 115 | ...currentState, |
| 116 | projects: currentState.projects.map((project) => |
| 117 | project.id === projectId |
| 118 | ? { |
no test coverage detected