mirror of
https://github.com/baairon/torlink.git
synced 2026-07-08 18:28:22 +02:00
feat: add hjkl navigation alongside the arrow keys (#29)
Layer vim-style h/j/k/l onto the existing arrow navigation across the sidebar, results, downloads, and seeding. Arrows unchanged.
This commit is contained in:
+14
-10
@@ -107,15 +107,19 @@
|
||||
<text x="742.4" y="458" textLength="28.8" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6" fill-opacity="0.55">SUB</text>
|
||||
<rect x="784.9" y="442" width="1.4" height="22" fill="#a78bfa"/>
|
||||
<text x="204.8" y="480" textLength="585.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#a78bfa">╰───────────────────────────────────────────────────────────╯</text>
|
||||
<text x="41.6" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">d</text>
|
||||
<text x="60.8" y="502" textLength="76.8" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Download</text>
|
||||
<text x="166.4" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">/</text>
|
||||
<text x="185.6" y="502" textLength="57.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Search</text>
|
||||
<text x="272" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">m</text>
|
||||
<text x="291.2" y="502" textLength="115.2" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Paste magnet</text>
|
||||
<text x="435.2" y="502" textLength="28.8" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">tab</text>
|
||||
<text x="473.6" y="502" textLength="105.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Switch pane</text>
|
||||
<text x="608" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">?</text>
|
||||
<text x="627.2" y="502" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Keys</text>
|
||||
<text x="41.6" y="502" textLength="86.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">↑↓←→ hjkl</text>
|
||||
<text x="137.6" y="502" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Move</text>
|
||||
<text x="204.8" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">d</text>
|
||||
<text x="224" y="502" textLength="76.8" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Download</text>
|
||||
<text x="329.6" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">y</text>
|
||||
<text x="348.8" y="502" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Copy</text>
|
||||
<text x="416" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">s</text>
|
||||
<text x="435.2" y="502" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Sort</text>
|
||||
<text x="502.4" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">/</text>
|
||||
<text x="521.6" y="502" textLength="57.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Search</text>
|
||||
<text x="608" y="502" textLength="28.8" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">tab</text>
|
||||
<text x="646.4" y="502" textLength="57.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Switch</text>
|
||||
<text x="732.8" y="502" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">?</text>
|
||||
<text x="752" y="502" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Keys</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
@@ -105,9 +105,9 @@
|
||||
<text x="137.6" y="414" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">c</text>
|
||||
<text x="156.8" y="414" textLength="57.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Cancel</text>
|
||||
<text x="243.2" y="414" textLength="28.8" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">tab</text>
|
||||
<text x="281.6" y="414" textLength="105.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Switch pane</text>
|
||||
<text x="416" y="414" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">?</text>
|
||||
<text x="435.2" y="414" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Keys</text>
|
||||
<text x="281.6" y="414" textLength="57.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Switch</text>
|
||||
<text x="368" y="414" textLength="9.6" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill="#b9a7e6">?</text>
|
||||
<text x="387.2" y="414" textLength="38.4" lengthAdjust="spacingAndGlyphs" xml:space="preserve" fill-opacity="0.55">Keys</text>
|
||||
</g>
|
||||
<rect x="262.4" y="222" width="9.6" height="22" fill="#7c5cd6">
|
||||
<animate attributeName="fill" calcMode="discrete" dur="3.48s" values="#7c5cd6;#7f5fd7;#8669da;#9277de;#a18ae3;#b29ee8;#c3b3ee;#d2c5f3;#ded4f7;#e5ddfa;#e8e0fb;#e5ddfa;#ded4f7;#d2c5f3;#c3b3ee;#b29ee8;#a18ae3;#9277de;#8669da;#7f5fd7;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6;#7c5cd6" repeatCount="indefinite"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
+2
-2
@@ -351,11 +351,11 @@ export function App({
|
||||
setRegion(region === "sidebar" ? "content" : "sidebar");
|
||||
return;
|
||||
}
|
||||
if (key.rightArrow) {
|
||||
if (key.rightArrow || input === "l") {
|
||||
if (region === "sidebar") setRegion("content");
|
||||
return;
|
||||
}
|
||||
if (key.leftArrow) {
|
||||
if (key.leftArrow || input === "h") {
|
||||
if (region === "content") setRegion("sidebar");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ export function Downloads() {
|
||||
|
||||
useInput(
|
||||
(input, key) => {
|
||||
if (key.upArrow) setCursor(wrapStep(clamped, -1, total));
|
||||
else if (key.downArrow) setCursor(wrapStep(clamped, 1, total));
|
||||
if (key.upArrow || input === "k") setCursor(wrapStep(clamped, -1, total));
|
||||
else if (key.downArrow || input === "j") setCursor(wrapStep(clamped, 1, total));
|
||||
else if (input === "f") queue.retryFailed();
|
||||
else if (input === "x") queue.clearHistory();
|
||||
else if (inActive) {
|
||||
|
||||
@@ -177,13 +177,13 @@ export function Results() {
|
||||
setMode("search");
|
||||
return;
|
||||
}
|
||||
if (key.upArrow) {
|
||||
if (key.upArrow || input === "k") {
|
||||
if (results.length > 0 && clamped > 0) setCursor(clamped - 1);
|
||||
else setMode("search");
|
||||
return;
|
||||
}
|
||||
if (results.length === 0) return;
|
||||
if (key.downArrow) setCursor(wrapStep(clamped, 1, results.length));
|
||||
if (key.downArrow || input === "j") setCursor(wrapStep(clamped, 1, results.length));
|
||||
else if (key.pageUp) setCursor(Math.max(0, clamped - pageJump));
|
||||
else if (key.pageDown) setCursor(Math.min(results.length - 1, clamped + pageJump));
|
||||
else if (key.return) {
|
||||
|
||||
@@ -48,8 +48,8 @@ export function Seeding() {
|
||||
|
||||
useInput(
|
||||
(input, key) => {
|
||||
if (key.upArrow) setCursor(wrapStep(clamped, -1, total));
|
||||
else if (key.downArrow) setCursor(wrapStep(clamped, 1, total));
|
||||
if (key.upArrow || input === "k") setCursor(wrapStep(clamped, -1, total));
|
||||
else if (key.downArrow || input === "j") setCursor(wrapStep(clamped, 1, total));
|
||||
else if (input === "p") {
|
||||
const h = history[clamped];
|
||||
if (!h) return;
|
||||
|
||||
@@ -37,9 +37,9 @@ export function Sidebar() {
|
||||
const seeding = queue.seedingCount;
|
||||
|
||||
useInput(
|
||||
(_input, key) => {
|
||||
if (key.upArrow) setSection(NAV[wrapStep(idx, -1, NAV.length)]!.key);
|
||||
else if (key.downArrow) setSection(NAV[wrapStep(idx, 1, NAV.length)]!.key);
|
||||
(input, key) => {
|
||||
if (key.upArrow || input === "k") setSection(NAV[wrapStep(idx, -1, NAV.length)]!.key);
|
||||
else if (key.downArrow || input === "j") setSection(NAV[wrapStep(idx, 1, NAV.length)]!.key);
|
||||
else if (key.return) setRegion("content");
|
||||
},
|
||||
{ isActive: focused },
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ export const HELP_GROUPS: HelpGroup[] = [
|
||||
{
|
||||
title: "Navigate",
|
||||
hints: [
|
||||
{ keys: "↑ ↓ ← →", label: "Navigate content and panes" },
|
||||
{ keys: "↑ ↓ ← →, h j k l", label: "Navigate content and panes" },
|
||||
{ keys: "↵", label: "Open" },
|
||||
{ keys: "tab", label: "Switch pane" },
|
||||
{ keys: "esc", label: "Back" },
|
||||
@@ -53,7 +53,7 @@ export const HELP_GROUPS: HelpGroup[] = [
|
||||
|
||||
// Footer labels stay terse so the contextual hint row never wraps; the `?`
|
||||
// overlay (HELP_GROUPS) carries the full, descriptive list.
|
||||
const NAVIGATE: Hint = { keys: "↑↓←→", label: "Move" };
|
||||
const NAVIGATE: Hint = { keys: "↑↓←→ hjkl", label: "Move" };
|
||||
|
||||
const ALWAYS: Hint = { keys: "?", label: "Keys" };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user