1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
import { useCallback, useRef, useState } from 'react';
import { CustomProxy } from '../../shared/daemon-rpc-types';
import { useScheduler } from '../../shared/scheduler';
import { useAppContext } from '../context';
import { useBoolean } from './utility-hooks';
export function useApiAccessMethodTest(
autoReset = true,
minDuration = 0,
): [
boolean,
boolean | undefined,
(method: CustomProxy | string) => Promise<boolean | void>,
() => void,
] {
const { testApiAccessMethodById, testCustomApiAccessMethod } = useAppContext();
const delayScheduler = useScheduler();
// Whether or not the method is currently being tested.
const [testing, setTesting, unsetTesting] = useBoolean();
const [testResult, setTestResult] = useState<boolean>();
// We keep the promise for the most recent test to compare it when we receive the results to know
// if it's canceled or not.
const lastTestPromise = useRef<Promise<boolean>>(undefined);
// A few seconds after the test has finished the result should not be displayed anymore. This
// scheduler is used to clear it.
const testResultResetScheduler = useScheduler();
const testApiAccessMethod = useCallback(
async (method: CustomProxy | string) => {
testResultResetScheduler.cancel();
setTestResult(undefined);
setTesting();
let reachable;
let testPromise;
const submitTimestamp = Date.now();
try {
testPromise =
typeof method === 'string'
? testApiAccessMethodById(method)
: testCustomApiAccessMethod(method);
lastTestPromise.current = testPromise;
reachable = await testPromise;
} catch {
reachable = false;
}
// Make sure the loading text is displayed for at least `minDuration` milliseconds.
const submitDuration = Date.now() - submitTimestamp;
if (submitDuration < minDuration) {
await new Promise<void>((resolve) =>
delayScheduler.schedule(resolve, minDuration - submitDuration),
);
}
if (testPromise !== lastTestPromise.current) {
return;
}
setTestResult(reachable);
unsetTesting();
if (autoReset) {
testResultResetScheduler.schedule(() => setTestResult(undefined), 5000);
}
return reachable;
},
[
autoReset,
delayScheduler,
minDuration,
setTesting,
testApiAccessMethodById,
testCustomApiAccessMethod,
testResultResetScheduler,
unsetTesting,
],
);
const resetTestResult = useCallback(() => {
lastTestPromise.current = undefined;
unsetTesting();
setTestResult(undefined);
}, [unsetTesting]);
return [testing, testResult, testApiAccessMethod, resetTestResult];
}
|