| 1 | import { useCallback, useRef, useState } from "react"; |
| 2 | import { app } from "./bridge"; |
| 3 | import { |
| 4 | beginKeyedResourceRequest, |
| 5 | emptyKeyedResource, |
| 6 | rejectKeyedResourceRequest, |
| 7 | resolveKeyedResourceRequest, |
| 8 | } from "./keyedResource"; |
| 9 | import type { WorkspaceChangesView } from "./types"; |
| 10 | |
| 11 | function errorMessage(error: unknown): string { |
| 12 | if (typeof error === "object" && error && "message" in error) { |
| 13 | return String((error as { message?: unknown }).message ?? error); |
| 14 | } |
| 15 | return String(error); |
| 16 | } |
| 17 | |
| 18 | export function useWorkspaceChangesResource(tabId: string, scopeKey: string, revision: number) { |
| 19 | const [resource, setResource] = useState(() => emptyKeyedResource<WorkspaceChangesView>()); |
| 20 | const requestSeq = useRef(0); |
| 21 | const key = `${scopeKey}\u0000working-tree`; |
| 22 | |
| 23 | const load = useCallback(async () => { |
| 24 | const requestId = ++requestSeq.current; |
| 25 | const requestKey = `${scopeKey}\u0000working-tree`; |
| 26 | setResource((current) => beginKeyedResourceRequest(current, requestKey, requestId, revision)); |
| 27 | try { |
| 28 | const result = await app.WorkspaceChanges(tabId); |
| 29 | const next = { |
| 30 | files: Array.isArray(result?.files) ? result.files : [], |
| 31 | gitAvailable: result?.gitAvailable !== false, |
| 32 | gitErr: result?.gitErr, |
| 33 | gitBranch: result?.gitBranch, |
| 34 | added: result?.added, |
| 35 | removed: result?.removed, |
| 36 | incomplete: result?.incomplete, |
| 37 | }; |
| 38 | setResource((current) => resolveKeyedResourceRequest(current, requestKey, requestId, next, revision)); |
| 39 | } catch (error) { |
| 40 | setResource((current) => rejectKeyedResourceRequest(current, requestKey, requestId, errorMessage(error))); |
| 41 | } |
| 42 | }, [revision, scopeKey, tabId]); |
| 43 | |
| 44 | const reset = useCallback(() => { |
| 45 | requestSeq.current += 1; |
| 46 | setResource(emptyKeyedResource()); |
| 47 | }, []); |
| 48 | |
| 49 | const current = resource.key === key; |
| 50 | return { |
| 51 | workspaceChanges: current ? resource.data : null, |
| 52 | loadingWorkspaceChanges: current && resource.status === "refreshing", |
| 53 | workspaceChangesErr: current ? resource.error : "", |
| 54 | loadWorkspaceChanges: load, |
| 55 | resetWorkspaceChanges: reset, |
| 56 | }; |
| 57 | } |
| 58 |