|
|
|
|
@ -6,6 +6,7 @@ import { apiFetch, incrementMetric, setUnraidCsrfToken } from "src/api" |
|
|
|
|
import { ExitNode, noExitNode, runAsExitNode } from "src/hooks/exit-nodes" |
|
|
|
|
import { VersionInfo } from "src/hooks/self-update" |
|
|
|
|
import { assertNever } from "src/utils/util" |
|
|
|
|
import useSWR from "swr" |
|
|
|
|
|
|
|
|
|
export type NodeData = { |
|
|
|
|
Profile: UserProfile |
|
|
|
|
@ -120,19 +121,12 @@ type RoutesPOSTData = { |
|
|
|
|
|
|
|
|
|
// useNodeData returns basic data about the current node.
|
|
|
|
|
export default function useNodeData() { |
|
|
|
|
const [data, setData] = useState<NodeData>() |
|
|
|
|
const { data, mutate } = useSWR<NodeData>("/data") |
|
|
|
|
const [isPosting, setIsPosting] = useState<boolean>(false) |
|
|
|
|
|
|
|
|
|
const refreshData = useCallback( |
|
|
|
|
() => |
|
|
|
|
apiFetch("/data", "GET") |
|
|
|
|
.then((r) => r.json()) |
|
|
|
|
.then((d: NodeData) => { |
|
|
|
|
setData(d) |
|
|
|
|
setUnraidCsrfToken(d.IsUnraid ? d.UnraidToken : undefined) |
|
|
|
|
}) |
|
|
|
|
.catch((error) => console.error(error)), |
|
|
|
|
[setData] |
|
|
|
|
useEffect( |
|
|
|
|
() => setUnraidCsrfToken(data?.IsUnraid ? data.UnraidToken : undefined), |
|
|
|
|
[data] |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const prefsPATCH = useCallback( |
|
|
|
|
@ -147,12 +141,12 @@ export default function useNodeData() { |
|
|
|
|
// then make the prefs PATCH. If the request fails,
|
|
|
|
|
// data will be updated to it's previous value in
|
|
|
|
|
// onComplete below.
|
|
|
|
|
setData(optimisticUpdates) |
|
|
|
|
mutate(optimisticUpdates, false) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const onComplete = () => { |
|
|
|
|
setIsPosting(false) |
|
|
|
|
refreshData() // refresh data after PATCH finishes
|
|
|
|
|
mutate() // refresh data after PATCH finishes
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return apiFetch("/local/v0/prefs", "PATCH", d) |
|
|
|
|
@ -163,7 +157,7 @@ export default function useNodeData() { |
|
|
|
|
throw err |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
[setIsPosting, refreshData, setData, data] |
|
|
|
|
[data, mutate] |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const routesPOST = useCallback( |
|
|
|
|
@ -171,7 +165,7 @@ export default function useNodeData() { |
|
|
|
|
setIsPosting(true) |
|
|
|
|
const onComplete = () => { |
|
|
|
|
setIsPosting(false) |
|
|
|
|
refreshData() // refresh data after POST finishes
|
|
|
|
|
mutate() // refresh data after POST finishes
|
|
|
|
|
} |
|
|
|
|
const updateMetrics = () => { |
|
|
|
|
// only update metrics if values have changed
|
|
|
|
|
@ -195,26 +189,7 @@ export default function useNodeData() { |
|
|
|
|
throw err |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
[setIsPosting, refreshData, data?.AdvertisingExitNode] |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
useEffect( |
|
|
|
|
() => { |
|
|
|
|
// Initial data load.
|
|
|
|
|
refreshData() |
|
|
|
|
|
|
|
|
|
// Refresh on browser tab focus.
|
|
|
|
|
const onVisibilityChange = () => { |
|
|
|
|
document.visibilityState === "visible" && refreshData() |
|
|
|
|
} |
|
|
|
|
window.addEventListener("visibilitychange", onVisibilityChange) |
|
|
|
|
return () => { |
|
|
|
|
// Cleanup browser tab listener.
|
|
|
|
|
window.removeEventListener("visibilitychange", onVisibilityChange) |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
// Run once.
|
|
|
|
|
[refreshData] |
|
|
|
|
[mutate, data?.AdvertisingExitNode] |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const nodeUpdaters: NodeUpdaters = useMemo( |
|
|
|
|
@ -245,5 +220,5 @@ export default function useNodeData() { |
|
|
|
|
] |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return { data, refreshData, nodeUpdaters, isPosting } |
|
|
|
|
return { data, refreshData: mutate, nodeUpdaters, isPosting } |
|
|
|
|
} |
|
|
|
|
|