Skip to content

Commit f20f832

Browse files
committed
Make arrow left/right keys toggle expandable rows
+ more render optimizations
1 parent b4bdc3b commit f20f832

12 files changed

Lines changed: 54 additions & 45 deletions

File tree

src/components/details.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,16 +305,16 @@ function FileTreePane(props: { torrent: Torrent }) {
305305
void refetch();
306306
}, [props.torrent, fileTree, refetch]);
307307

308-
const mutation = useMutateTorrent();
308+
const { mutate } = useMutateTorrent();
309309

310310
const onCheckboxChange = useUnwantedFiles(fileTree, true);
311311
const updateUnwanted = useCallback((entryPath: string, state: boolean) => {
312312
onCheckboxChange(entryPath, state);
313-
mutation.mutate({
313+
mutate({
314314
torrentIds: [props.torrent.id],
315315
fields: { [state ? "files-wanted" : "files-unwanted"]: fileTree.getChildFilesIndexes(entryPath) },
316316
});
317-
}, [fileTree, mutation, onCheckboxChange, props.torrent.id]);
317+
}, [fileTree, mutate, onCheckboxChange, props.torrent.id]);
318318

319319
return (
320320
<FileTreeTable

src/components/modals/add.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ export function AddMagnet(props: AddCommonModalProps) {
196196
});
197197
}, []),
198198
);
199-
const trackersMutation = useTorrentAddTrackers();
199+
const mutateAddTrackers = useTorrentAddTrackers();
200200

201201
const onAdd = useCallback(() => {
202202
if (magnet === "") return;
@@ -213,7 +213,7 @@ export function AddMagnet(props: AddCommonModalProps) {
213213
);
214214
common.location.addPath(common.location.path);
215215
} else {
216-
trackersMutation.mutate(
216+
mutateAddTrackers(
217217
{ torrentId: existingTorrent.id, trackers: magnetData?.trackers ?? [] },
218218
{
219219
onSuccess: () => {
@@ -227,7 +227,7 @@ export function AddMagnet(props: AddCommonModalProps) {
227227
}
228228
setMagnet("");
229229
close();
230-
}, [existingTorrent, close, addMutation, magnet, common, trackersMutation, magnetData]);
230+
}, [existingTorrent, close, addMutation, magnet, common, mutateAddTrackers, magnetData]);
231231

232232
const config = useContext(ConfigContext);
233233
const shouldOpen = !config.values.interface.skipAddDialog || typeof props.uri !== "string";
@@ -499,7 +499,7 @@ export function AddTorrent(props: AddCommonModalProps) {
499499
});
500500
}, []),
501501
);
502-
const trackersMutation = useTorrentAddTrackers();
502+
const mutateAddTrackers = useTorrentAddTrackers();
503503

504504
const onAdd = useCallback(() => {
505505
if (torrentData === undefined) return;
@@ -521,7 +521,7 @@ export function AddTorrent(props: AddCommonModalProps) {
521521

522522
common.location.addPath(common.location.path);
523523
} else {
524-
trackersMutation.mutate(
524+
mutateAddTrackers(
525525
{ torrentId: existingTorrent.id, trackers: torrentData[0].trackers },
526526
{
527527
onSuccess: () => {
@@ -540,7 +540,7 @@ export function AddTorrent(props: AddCommonModalProps) {
540540
}
541541
setTorrentData(undefined);
542542
close();
543-
}, [torrentData, existingTorrent, close, common, addMutation, fileTree, trackersMutation, config]);
543+
}, [torrentData, existingTorrent, close, common, addMutation, fileTree, mutateAddTrackers, config]);
544544

545545
const shouldOpen = !config.values.interface.skipAddDialog && torrentData !== undefined;
546546
useEffect(() => {

src/components/modals/editlabels.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function EditLabelsModal(props: ModalState) {
4545
if (opened) setLabels(calculateInitialLabels());
4646
}, [calculateInitialLabels, opened]);
4747

48-
const mutation = useMutateTorrent();
48+
const { mutate } = useMutateTorrent();
4949

5050
const onSave = useCallback(() => {
5151
if (rpcVersion < 16) {
@@ -57,7 +57,7 @@ export function EditLabelsModal(props: ModalState) {
5757
close();
5858
return;
5959
}
60-
mutation.mutate(
60+
mutate(
6161
{
6262
torrentIds: Array.from(serverSelected),
6363
fields: { labels },
@@ -79,7 +79,7 @@ export function EditLabelsModal(props: ModalState) {
7979
},
8080
);
8181
close();
82-
}, [rpcVersion, mutation, serverSelected, labels, close]);
82+
}, [rpcVersion, mutate, serverSelected, labels, close]);
8383

8484
return <>
8585
{props.opened &&

src/components/modals/edittorrent.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ export function EditTorrent(props: ModalState) {
7373
});
7474
}, [setValues, torrent]);
7575

76-
const mutation = useMutateTorrent();
76+
const { mutate } = useMutateTorrent();
7777

7878
const onSave = useCallback(() => {
7979
if (torrentId === undefined || torrent === undefined) return;
8080

81-
mutation.mutate(
81+
mutate(
8282
{
8383
torrentIds: [...selected],
8484
fields: {
@@ -97,7 +97,7 @@ export function EditTorrent(props: ModalState) {
9797
},
9898
);
9999
props.close();
100-
}, [torrentId, torrent, mutation, selected, form.values, props]);
100+
}, [torrentId, torrent, mutate, selected, form.values, props]);
101101

102102
return <>{props.opened &&
103103
<SaveCancelModal

src/components/modals/edittrackers.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export function EditTrackers(props: ModalState) {
5959
});
6060
}, [rpcVersion, setValues, torrent]);
6161

62-
const mutation = useMutateTorrent();
62+
const { mutate } = useMutateTorrent();
6363

6464
const onSave = useCallback(() => {
6565
if (torrentId === undefined || torrent === undefined) return;
@@ -77,7 +77,7 @@ export function EditTrackers(props: ModalState) {
7777
if (toAdd.length === 0) toAdd = undefined;
7878
if (toRemove.length === 0) toRemove = undefined;
7979
}
80-
mutation.mutate(
80+
mutate(
8181
{
8282
torrentIds: [...selected],
8383
fields: {
@@ -97,7 +97,7 @@ export function EditTrackers(props: ModalState) {
9797
},
9898
);
9999
props.close();
100-
}, [torrentId, torrent, rpcVersion, mutation, selected, form.values, props]);
100+
}, [torrentId, torrent, rpcVersion, mutate, selected, form.values, props]);
101101

102102
const addDefaultTrackers = useCallback(() => {
103103
let list = form.values.trackerList;

src/components/modals/move.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ export function MoveModal(props: ModalState) {
3232
const location = useTorrentLocation();
3333
const { setPath } = location;
3434

35-
const mutation = useTorrentChangeDirectory();
35+
const changeDirectory = useTorrentChangeDirectory();
3636

3737
const onMove = useCallback(() => {
38-
mutation.mutate(
38+
changeDirectory(
3939
{
4040
torrentIds: Array.from(serverSelected),
4141
location: location.path,
@@ -53,7 +53,7 @@ export function MoveModal(props: ModalState) {
5353
);
5454

5555
props.close();
56-
}, [mutation, serverSelected, location.path, moveData, props]);
56+
}, [changeDirectory, serverSelected, location.path, moveData, props]);
5757

5858
const calculateInitialLocation = useCallback(() => {
5959
const [id] = [...serverSelected];

src/components/modals/remove.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ export function RemoveModal(props: ModalState) {
2828
const serverSelected = useServerSelectedTorrents();
2929
const [deleteData, setDeleteData] = useState<boolean>(false);
3030

31-
const mutation = useRemoveTorrents();
31+
const remove = useRemoveTorrents();
3232

3333
const onDelete = useCallback(() => {
34-
mutation.mutate(
34+
remove(
3535
{
3636
torrentIds: Array.from(serverSelected),
3737
deleteData,
@@ -47,7 +47,7 @@ export function RemoveModal(props: ModalState) {
4747
},
4848
);
4949
props.close();
50-
}, [mutation, serverSelected, deleteData, props]);
50+
}, [remove, serverSelected, deleteData, props]);
5151

5252
return (
5353
<HkModal opened={props.opened} onClose={props.close} title="Remove torrents" centered size="lg">

src/components/tables/common.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ export function TrguiTable<TData>(props: {
564564
interface EditableNameFieldProps extends React.PropsWithChildren {
565565
currentName: string,
566566
onUpdate?: (newName: string, onStart: () => void, onEnd: () => void) => void,
567+
onArrowLeftRight?: (key: string) => void,
567568
}
568569

569570
export function EditableNameField(props: EditableNameFieldProps) {
@@ -613,14 +614,18 @@ export function EditableNameField(props: EditableNameFieldProps) {
613614
}
614615
}, []);
615616

616-
const onF2 = useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {
617+
const { onArrowLeftRight } = props;
618+
619+
const onKeyDown = useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {
617620
if (event.key === "F2" && !isRenaming) {
618621
renameHandler();
622+
} else if (onArrowLeftRight !== undefined && ["ArrowLeft", "ArrowRight"].includes(event.key)) {
623+
onArrowLeftRight(event.key);
619624
}
620-
}, [isRenaming, renameHandler]);
625+
}, [isRenaming, onArrowLeftRight, renameHandler]);
621626

622627
return (
623-
<Box ref={ref} onKeyDown={onF2} tabIndex={-1}
628+
<Box ref={ref} onKeyDown={onKeyDown} tabIndex={-1}
624629
onMouseEnter={() => { setHover(true); }} onMouseLeave={() => { setHover(false); }}
625630
sx={{ display: "flex", alignItems: "center", width: "100%", height: "100%" }}>
626631
{props.children}

src/components/tables/filetreetable.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,14 @@ function NameField(props: TableFieldProps) {
9696

9797
const rpcVersion = useServerRpcVersion();
9898

99+
const onArrowLeftRight = useCallback((key: string) => {
100+
if (props.row.subRows.length === 0) return;
101+
if (key === "ArrowLeft" && props.row.getIsExpanded()) props.row.toggleExpanded();
102+
if (key === "ArrowRight" && !props.row.getIsExpanded()) props.row.toggleExpanded();
103+
}, [props.row]);
104+
99105
return (
100-
<EditableNameField currentName={props.entry.name}
106+
<EditableNameField currentName={props.entry.name} onArrowLeftRight={onArrowLeftRight}
101107
onUpdate={(props.treeName === "filetree" && rpcVersion >= 15) ? updatePath : undefined}>
102108
<Box sx={{ width: `${props.entry.level * 1.6}rem`, flexShrink: 0 }} />
103109
<Box w="1.4rem" mx="auto" sx={{ flexShrink: 0 }}>
@@ -282,9 +288,7 @@ export function FileTreeTable(props: FileTreeTableProps) {
282288
}), [props.brief, props.fileTree, nameSortFunc, onCheckboxChange]);
283289

284290
const getRowId = useCallback((row: FileDirEntryView) => row.fullpath, []);
285-
const getSubRows = useCallback((row: FileDirEntryView) => {
286-
return row.subrows;
287-
}, []);
291+
const getSubRows = useCallback((row: FileDirEntryView) => row.subrows, []);
288292

289293
const { selected, selectedReducer } = useSelected(props);
290294

@@ -412,7 +416,7 @@ function FiletreeContextMenu(props: {
412416
onEntryOpen(rowPath, reveal);
413417
}, [onEntryOpen, props.fileTree, props.selected]);
414418

415-
const mutation = useMutateTorrent();
419+
const { mutate } = useMutateTorrent();
416420

417421
const setPriority = useCallback((priority: "priority-high" | "priority-normal" | "priority-low") => {
418422
const fileIds = Array.from(props.selected
@@ -422,7 +426,7 @@ function FiletreeContextMenu(props: {
422426
return set;
423427
}, new Set<number>()));
424428

425-
mutation.mutate(
429+
mutate(
426430
{
427431
torrentIds: [props.fileTree.torrentId],
428432
fields: {
@@ -438,7 +442,7 @@ function FiletreeContextMenu(props: {
438442
},
439443
},
440444
);
441-
}, [mutation, props.fileTree, props.selected]);
445+
}, [mutate, props.fileTree, props.selected]);
442446

443447
const setWanted = useCallback((wanted: boolean) => {
444448
const fileIds = Array.from(props.selected
@@ -448,7 +452,7 @@ function FiletreeContextMenu(props: {
448452
return set;
449453
}, new Set<number>()));
450454

451-
mutation.mutate(
455+
mutate(
452456
{
453457
torrentIds: [props.fileTree.torrentId],
454458
fields: {
@@ -464,7 +468,7 @@ function FiletreeContextMenu(props: {
464468
},
465469
},
466470
);
467-
}, [mutation, props.fileTree, props.selected]);
471+
}, [mutate, props.fileTree, props.selected]);
468472

469473
return (
470474
<ContextMenu contextMenuInfo={props.contextMenuInfo} setContextMenuInfo={props.setContextMenuInfo}>

src/components/tables/torrenttable.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ function TorrentContextMenu(props: {
468468
onRowDoubleClick(torrent, reveal);
469469
}, [onRowDoubleClick, serverData.torrents, serverSelected]);
470470

471-
const mutation = useTorrentAction();
471+
const mutate = useTorrentAction();
472472

473473
const torrentAction = useCallback((method: TorrentActionMethodsType, successMessage: string) => {
474-
mutation.mutate(
474+
mutate(
475475
{
476476
method,
477477
torrentIds: Array.from(serverSelected),
@@ -485,7 +485,7 @@ function TorrentContextMenu(props: {
485485
},
486486
},
487487
);
488-
}, [mutation, serverSelected]);
488+
}, [mutate, serverSelected]);
489489

490490
const [queueSubmenuOpened, setQueueSubmenuOpened] = useState(false);
491491
const queueRef = useRef<HTMLButtonElement>(null);

0 commit comments

Comments
 (0)