File size: 1,284 Bytes
90f0300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useEffect, useMemo, useState } from 'react';
import { rateLimitLockFromError, remainingLockSeconds } from '../api.js';
import { retryAfterLabel } from '../app-core-utils.js';

export function useRelayOperationLocks() {
  const [locks, setLocks] = useState({});
  const [now, setNow] = useState(Date.now());

  useEffect(() => {
    const hasActiveLock = Object.values(locks).some((lock) => remainingLockSeconds(lock) > 0);
    if (!hasActiveLock) {
      return undefined;
    }
    const timer = window.setInterval(() => setNow(Date.now()), 500);
    return () => window.clearInterval(timer);
  }, [locks]);

  function rememberLock(scope, error) {
    const lock = rateLimitLockFromError(error, scope);
    if (!lock) {
      return false;
    }
    setLocks((current) => {
      if (current[scope]?.untilMs >= lock.untilMs) {
        return current;
      }
      return { ...current, [scope]: lock };
    });
    setNow(Date.now());
    return true;
  }

  const disabledReasons = useMemo(() => ({
    send: retryAfterLabel(locks.send, now),
    upload: retryAfterLabel(locks.upload, now),
    voice: retryAfterLabel(locks.voice, now),
    voiceDialog: retryAfterLabel(locks.voiceDialog, now)
  }), [locks, now]);

  return {
    rememberLock,
    disabledReasons
  };
}