summaryrefslogtreecommitdiff
path: root/src/components/Proxies.js
blob: 96230106bc141de867c17cc7419b2747e8015e0d (plain)
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
94
95
96
97
98
99
100
101
102
103
import React from 'react';
// import { useStoreState } from '../misc/store';

import { connect } from './StateProvider';

import ContentHeader from './ContentHeader';
import ProxyGroup from './ProxyGroup';
import Button from './Button';
import { Zap } from 'react-feather';

import ProxyProviderList from './ProxyProviderList';

import s0 from './Proxies.module.css';

import {
  getProxies,
  getDelay,
  getProxyGroupNames,
  getProxyProviders,
  fetchProxies,
  requestDelayAll
} from '../store/proxies';
import { getClashAPIConfig } from '../store/app';

const { useEffect, useMemo, useCallback, useRef } = React;

function Proxies({
  dispatch,
  groupNames,
  proxies,
  delay,
  proxyProviders,
  apiConfig
}) {
  const refFetchedTimestamp = useRef({});
  const requestDelayAllFn = useCallback(
    () => dispatch(requestDelayAll(apiConfig)),
    [apiConfig, dispatch]
  );
  const fetchProxiesHooked = useCallback(() => {
    refFetchedTimestamp.current.startAt = new Date();
    dispatch(fetchProxies(apiConfig)).then(() => {
      refFetchedTimestamp.current.completeAt = new Date();
    });
  }, [apiConfig, dispatch]);
  useEffect(() => {
    // fetch it now
    fetchProxiesHooked();

    // arm a window on focus listener to refresh it
    const fn = () => {
      if (
        refFetchedTimestamp.current.startAt &&
        new Date() - refFetchedTimestamp.current.startAt > 3e4 // 30s
      ) {
        fetchProxiesHooked();
      }
    };
    window.addEventListener('focus', fn, false);
    return () => window.removeEventListener('focus', fn, false);
  }, [fetchProxiesHooked]);
  const icon = useMemo(() => <Zap width={16} />, []);

  return (
    <>
      <ContentHeader title="Proxies" />
      <div>
        <div className="fabgrp">
          <Button
            text="Test Latency"
            start={icon}
            onClick={requestDelayAllFn}
          />
        </div>
        {groupNames.map(groupName => {
          return (
            <div className={s0.group} key={groupName}>
              <ProxyGroup
                name={groupName}
                proxies={proxies}
                delay={delay}
                apiConfig={apiConfig}
                dispatch={dispatch}
              />
            </div>
          );
        })}
      </div>
      <ProxyProviderList items={proxyProviders} />
      <div style={{ height: 60 }} />
    </>
  );
}

const mapState = s => ({
  apiConfig: getClashAPIConfig(s),
  groupNames: getProxyGroupNames(s),
  proxies: getProxies(s),
  proxyProviders: getProxyProviders(s),
  delay: getDelay(s)
});

export default connect(mapState)(Proxies);