diff --git a/client/src/javascript/actions/UIActions.ts b/client/src/javascript/actions/UIActions.ts index 93f0cfb9..23f495da 100644 --- a/client/src/javascript/actions/UIActions.ts +++ b/client/src/javascript/actions/UIActions.ts @@ -33,6 +33,10 @@ const UIActions = { TorrentStore.setSelectedTorrents(data); }, + selectAllTorrents: () => { + TorrentStore.selectAllTorrents(); + }, + setTorrentStatusFilter: (status: TorrentStatus) => { TorrentFilterStore.setStatusFilter(status); }, diff --git a/client/src/javascript/components/torrent-list/TorrentList.tsx b/client/src/javascript/components/torrent-list/TorrentList.tsx index cfc255ad..cde3b0de 100644 --- a/client/src/javascript/components/torrent-list/TorrentList.tsx +++ b/client/src/javascript/components/torrent-list/TorrentList.tsx @@ -1,7 +1,8 @@ -import {FC, ReactNode, useEffect, useRef} from 'react'; +import {FC, KeyboardEvent, ReactNode, useEffect, useRef} from 'react'; import {observer} from 'mobx-react'; import {reaction} from 'mobx'; import {Trans} from '@lingui/react'; +import {useEvent} from 'react-use'; import type {FixedSizeList, ListChildComponentProps} from 'react-window'; @@ -12,6 +13,7 @@ import SettingActions from '@client/actions/SettingActions'; import SettingStore from '@client/stores/SettingStore'; import TorrentFilterStore from '@client/stores/TorrentFilterStore'; import TorrentStore from '@client/stores/TorrentStore'; +import UIActions from '@client/actions/UIActions'; import SortDirections from '@client/constants/SortDirections'; @@ -47,6 +49,24 @@ const TorrentList: FC = observer(() => { return dispose; }, []); + useEvent('keydown', (e: KeyboardEvent) => { + const {ctrlKey, key, metaKey, repeat, target} = e; + + const tagName = (target as HTMLElement)?.tagName.toUpperCase(); + if (tagName === 'INPUT' || tagName === 'TEXTAREA') { + return; + } + + if (repeat) { + return; + } + + if ((metaKey || ctrlKey) && key === 'a') { + e.preventDefault(); + UIActions.selectAllTorrents(); + } + }); + const torrents = TorrentStore.filteredTorrents; const {torrentListViewSize = 'condensed'} = SettingStore.floodSettings; diff --git a/client/src/javascript/stores/TorrentStore.ts b/client/src/javascript/stores/TorrentStore.ts index 20e5b31c..92491004 100644 --- a/client/src/javascript/stores/TorrentStore.ts +++ b/client/src/javascript/stores/TorrentStore.ts @@ -65,6 +65,10 @@ class TorrentStore { }); } + selectAllTorrents() { + this.selectedTorrents = this.filteredTorrents.map((v) => v.hash); + } + handleTorrentListDiffChange(torrentListDiffs: Operation[]) { applyPatch(this.torrents, torrentListDiffs); }