summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorHaishan <[email protected]>2020-01-07 00:39:57 +0800
committerHaishan <[email protected]>2020-01-07 22:10:55 +0800
commitff04a47ca4c5a758a8a158062da19919a8c011c7 (patch)
treeede8b36f22a2016b30f95a375e2fa58d0d788c8a /src/components
parentdfbdee474979b21249461f270edfa0225994f298 (diff)
feat(Conns): keep up to 100 closed connections in another tab
Diffstat (limited to 'src/components')
-rw-r--r--src/components/Connections.css49
-rw-r--r--src/components/Connections.js88
-rw-r--r--src/components/Connections.module.css12
-rw-r--r--src/components/Root.css2
4 files changed, 130 insertions, 21 deletions
diff --git a/src/components/Connections.css b/src/components/Connections.css
new file mode 100644
index 0000000..bc69a62
--- /dev/null
+++ b/src/components/Connections.css
@@ -0,0 +1,49 @@
+.react-tabs {
+ -webkit-tap-highlight-color: transparent;
+}
+
+.react-tabs__tab-list {
+ margin: 0 0 10px;
+ padding: 0 30px;
+}
+
+.react-tabs__tab {
+ display: inline-flex;
+ align-items: center;
+ border: 1px solid transparent;
+ border-radius: 5px;
+ bottom: -1px;
+ position: relative;
+ list-style: none;
+ padding: 6px 10px;
+ cursor: pointer;
+ font-size: 1.2em;
+ opacity: 0.5;
+}
+
+.react-tabs__tab--selected {
+ opacity: 1;
+}
+
+.react-tabs__tab--disabled {
+ color: GrayText;
+ cursor: default;
+}
+
+.react-tabs__tab:focus {
+ border-color: hsl(208, 99%, 50%);
+ outline: none;
+}
+
+.react-tabs__tab:focus:after {
+ content: '';
+ position: absolute;
+}
+
+.react-tabs__tab-panel {
+ display: none;
+}
+
+.react-tabs__tab-panel--selected {
+ display: block;
+}
diff --git a/src/components/Connections.js b/src/components/Connections.js
index 70fe870..2f8e319 100644
--- a/src/components/Connections.js
+++ b/src/components/Connections.js
@@ -4,12 +4,14 @@ import ConnectionTable from './ConnectionTable';
import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight';
import { getClashAPIConfig } from '../store/app';
import { X as IconClose } from 'react-feather';
+import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import SvgYacd from './SvgYacd';
import Button from './Button';
import ModalCloseAllConnections from './ModalCloseAllConnections';
import { connect } from './StateProvider';
import * as connAPI from '../api/connections';
+import './Connections.css';
import s from './Connections.module.css';
const { useEffect, useState, useRef, useCallback, useMemo } = React;
@@ -36,9 +38,24 @@ function formatConnectionDataItem(i) {
};
}
+function renderTableOrPlaceholder(conns) {
+ return conns.length > 0 ? (
+ <ConnectionTable data={conns} />
+ ) : (
+ <div className={s.placeHolder}>
+ <SvgYacd width={200} height={200} c1="var(--color-text)" />
+ </div>
+ );
+}
+
+function ConnQty({ qty }) {
+ return qty < 100 ? '' + qty : '99+';
+}
+
function Conn({ apiConfig }) {
const [refContainer, containerHeight] = useRemainingViewPortHeight();
const [conns, setConns] = useState([]);
+ const [closedConns, setClosedConns] = useState([]);
const [isCloseAllModalOpen, setIsCloseAllModalOpen] = useState(false);
const openCloseAllModal = useCallback(() => setIsCloseAllModalOpen(true), []);
const closeCloseAllModal = useCallback(
@@ -54,6 +71,15 @@ function Conn({ apiConfig }) {
const read = useCallback(
({ connections }) => {
const x = connections.map(c => formatConnectionDataItem(c));
+ const closed = [];
+ for (const c of prevConnsRef.current) {
+ const idx = x.findIndex(conn => conn.id === c.id);
+ if (idx < 0) closed.push(c);
+ }
+ setClosedConns(prev => {
+ // keep max 100 entries
+ return [...closed, ...prev].slice(0, 101);
+ });
// if previous connections and current connections are both empty
// arrays, we wont update state to avaoid rerender
if (x && (x.length !== 0 || prevConnsRef.current.length !== 0)) {
@@ -71,30 +97,50 @@ function Conn({ apiConfig }) {
return (
<div>
<ContentHeader title="Connections" />
- <div
- ref={refContainer}
- style={{ padding: 30, paddingBottom, paddingTop: 0 }}
- >
+ <Tabs>
+ <TabList>
+ <Tab>
+ <span>Active</span>
+ <span className={s.connQty}>
+ <ConnQty qty={conns.length} />
+ </span>
+ </Tab>
+ <Tab>
+ <span>Closed</span>
+ <span className={s.connQty}>
+ <ConnQty qty={closedConns.length} />
+ </span>
+ </Tab>
+ </TabList>
<div
- style={{ height: containerHeight - paddingBottom, overflow: 'auto' }}
+ ref={refContainer}
+ style={{ padding: 30, paddingBottom, paddingTop: 0 }}
>
- {conns.length > 0 ? (
- <ConnectionTable data={conns} />
- ) : (
- <div className={s.placeHolder}>
- <SvgYacd width={200} height={200} c1="var(--color-text)" />
- </div>
- )}
+ <div
+ style={{
+ height: containerHeight - paddingBottom,
+ overflow: 'auto'
+ }}
+ >
+ <TabPanel>
+ <>{renderTableOrPlaceholder(conns)}</>
+ <div className="fabgrp">
+ <Button
+ text="Close"
+ start={iconClose}
+ onClick={openCloseAllModal}
+ />
+ </div>
+ </TabPanel>
+ <TabPanel>{renderTableOrPlaceholder(closedConns)}</TabPanel>
+ </div>
</div>
- </div>
- <div className="fabgrp">
- <Button text="Close" start={iconClose} onClick={openCloseAllModal} />
- </div>
- <ModalCloseAllConnections
- isOpen={isCloseAllModalOpen}
- primaryButtonOnTap={closeAllConnections}
- onRequestClose={closeCloseAllModal}
- />
+ <ModalCloseAllConnections
+ isOpen={isCloseAllModalOpen}
+ primaryButtonOnTap={closeAllConnections}
+ onRequestClose={closeCloseAllModal}
+ />
+ </Tabs>
</div>
);
}
diff --git a/src/components/Connections.module.css b/src/components/Connections.module.css
index 4991f29..45f20de 100644
--- a/src/components/Connections.module.css
+++ b/src/components/Connections.module.css
@@ -6,3 +6,15 @@
color: var(--color-background);
opacity: 0.1;
}
+
+.connQty {
+ font-family: var(--font-normal);
+ font-size: 0.75em;
+ margin-left: 3px;
+ padding: 2px 7px;
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ background-color: var(--bg-near-transparent);
+ border-radius: 30px;
+}
diff --git a/src/components/Root.css b/src/components/Root.css
index 3622d57..060edf7 100644
--- a/src/components/Root.css
+++ b/src/components/Root.css
@@ -100,6 +100,7 @@ body.dark {
--color-bg-proxy-selected: #303030;
--color-row-odd: #282828;
--bg-modal: #1f1f20;
+ --bg-near-transparent: rgba(255, 255, 255, 0.1);
}
body.light {
@@ -118,6 +119,7 @@ body.light {
--color-bg-proxy-selected: #cfcfcf;
--color-row-odd: #f5f5f5;
--bg-modal: #fbfbfb;
+ --bg-near-transparent: rgba(0, 0, 0, 0.1);
}
.flexCenter {