import './ConnectionTable.scss'; import cx from 'clsx'; import { formatDistance, Locale } from 'date-fns'; import { enUS, zhCN, zhTW } from 'date-fns/locale'; import React, { useEffect, useState } from 'react'; import { ChevronDown } from 'react-feather'; import { XCircle } from 'react-feather'; import { useTranslation } from 'react-i18next'; import { useSortBy, useTable } from 'react-table'; import { State } from '~/store/types'; import * as connAPI from '../api/connections'; import prettyBytes from '../misc/pretty-bytes'; import { getClashAPIConfig } from '../store/app'; import s from './ConnectionTable.module.scss'; import MOdalCloseConnection from './ModalCloseAllConnections'; import { connect } from './StateProvider'; const sortById = { id: 'id', desc: true }; function Table({ data, columns, hiddenColumns, apiConfig }) { const [operationId, setOperationId] = useState(''); const [showModalDisconnect, setShowModalDisconnect] = useState(false); // 从本地存储加载排序状态 const savedSortBy = JSON.parse(localStorage.getItem('tableSortBy')) || [sortById]; const tableState = { sortBy: savedSortBy, hiddenColumns, }; const table = useTable( { columns, data, initialState: tableState, autoResetSortBy: false, }, useSortBy ); const { getTableProps, setHiddenColumns, headerGroups, rows, prepareRow } = table; const state = table.state; useEffect(() => { setHiddenColumns(hiddenColumns); }, [setHiddenColumns, hiddenColumns]); const { t, i18n } = useTranslation(); let locale: Locale; if (i18n.language === 'zh-CN') { locale = zhCN; } else if (i18n.language === 'zh-TW') { locale = zhTW; } else { locale = enUS; } const disconnectOperation = () => { connAPI.closeConnById(apiConfig, operationId); setShowModalDisconnect(false); }; const handlerDisconnect = (id) => { setOperationId(id); setShowModalDisconnect(true); }; const renderCell = (cell, locale) => { switch (cell.column.id) { case 'ctrl': return ( handlerDisconnect(cell.row.original.id)} > ); case 'start': return formatDistance(cell.value, 0, { locale: locale }); case 'download': case 'upload': return prettyBytes(cell.value); case 'downloadSpeedCurr': case 'uploadSpeedCurr': return prettyBytes(cell.value) + '/s'; default: return cell.value; } }; // 当排序状态改变时,将新状态保存到本地存储 useEffect(() => { localStorage.setItem('tableSortBy', JSON.stringify(state.sortBy)); }, [state.sortBy]); return (
{headerGroups.map((headerGroup, trindex) => { return ( {headerGroup.headers.map((column) => ( ))} ); })} {rows.map((row, i) => { prepareRow(row); return ( {row.cells.map((cell) => { return ( ); })} ); })}
{t(column.render('Header'))} {column.id !== 'ctrl' ? ( {column.isSorted ? ( ) : null} ) : null}
{renderCell(cell, locale)}
setShowModalDisconnect(false)} primaryButtonOnTap={disconnectOperation} >
); } const mapState = (s: State) => ({ apiConfig: getClashAPIConfig(s), }); export default connect(mapState)(Table);