mirror of
https://github.com/baairon/torlink.git
synced 2026-07-08 18:28:22 +02:00
Added navigating panes by arrows
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
package-lock.json
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "torlink",
|
"name": "torlnk",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "torlink",
|
"name": "torlnk",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"webtorrent": "^2.4.1"
|
"webtorrent": "^2.4.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"torlink": "dist/index.js"
|
"torlnk": "dist/index.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^25.9.2",
|
"@types/node": "^25.9.2",
|
||||||
|
|||||||
@@ -302,6 +302,14 @@ export function App({
|
|||||||
setRegion(region === "sidebar" ? "content" : "sidebar");
|
setRegion(region === "sidebar" ? "content" : "sidebar");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (key.rightArrow) {
|
||||||
|
if (region === "sidebar") setRegion("content");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (key.leftArrow) {
|
||||||
|
if (region === "content") setRegion("sidebar");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (key.escape) {
|
if (key.escape) {
|
||||||
if (captureMode === "esc") return;
|
if (captureMode === "esc") return;
|
||||||
if (region === "content") {
|
if (region === "content") {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export function Results() {
|
|||||||
submitQuery,
|
submitQuery,
|
||||||
section,
|
section,
|
||||||
region,
|
region,
|
||||||
|
setRegion,
|
||||||
setCaptureMode,
|
setCaptureMode,
|
||||||
startDownload,
|
startDownload,
|
||||||
contentWidth,
|
contentWidth,
|
||||||
@@ -155,9 +156,13 @@ export function Results() {
|
|||||||
setMode("search");
|
setMode("search");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (key.upArrow) {
|
||||||
|
if (results.length > 0 && clamped > 0) setCursor(clamped - 1);
|
||||||
|
else setMode("search");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (results.length === 0) return;
|
if (results.length === 0) return;
|
||||||
if (key.upArrow) setCursor(wrapStep(clamped, -1, results.length));
|
if (key.downArrow) setCursor(wrapStep(clamped, 1, results.length));
|
||||||
else if (key.downArrow) setCursor(wrapStep(clamped, 1, results.length));
|
|
||||||
else if (key.pageUp) setCursor(Math.max(0, clamped - pageJump));
|
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.pageDown) setCursor(Math.min(results.length - 1, clamped + pageJump));
|
||||||
else if (key.return) {
|
else if (key.return) {
|
||||||
@@ -271,12 +276,14 @@ export function Results() {
|
|||||||
editing={mode === "search"}
|
editing={mode === "search"}
|
||||||
placeholder={PLACEHOLDER}
|
placeholder={PLACEHOLDER}
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
|
onExitDown={() => setMode("list")}
|
||||||
|
onExitLeft={() => setRegion("sidebar")}
|
||||||
/>
|
/>
|
||||||
<Box marginTop={1}>
|
<Box marginTop={1}>
|
||||||
<Panel
|
<Panel
|
||||||
title={mode === "detail" ? "details" : browsing ? "latest" : "results"}
|
title={mode === "detail" ? "details" : browsing ? "latest" : "results"}
|
||||||
width={contentWidth}
|
width={contentWidth}
|
||||||
focused={focused}
|
focused={focused && mode !== "search"}
|
||||||
count={mode === "detail" ? undefined : count}
|
count={mode === "detail" ? undefined : count}
|
||||||
height={panelOuter}
|
height={panelOuter}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ interface SearchBarProps {
|
|||||||
editing: boolean;
|
editing: boolean;
|
||||||
onSubmit: (value: string) => void;
|
onSubmit: (value: string) => void;
|
||||||
onChange?: (value: string) => void;
|
onChange?: (value: string) => void;
|
||||||
|
onExitDown?: () => void;
|
||||||
|
onExitLeft?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SearchBar({
|
export function SearchBar({
|
||||||
@@ -19,6 +21,8 @@ export function SearchBar({
|
|||||||
editing,
|
editing,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onChange,
|
onChange,
|
||||||
|
onExitDown,
|
||||||
|
onExitLeft,
|
||||||
}: SearchBarProps) {
|
}: SearchBarProps) {
|
||||||
return (
|
return (
|
||||||
<Panel title="search" width={width} focused={editing} height={2}>
|
<Panel title="search" width={width} focused={editing} height={2}>
|
||||||
@@ -31,6 +35,8 @@ export function SearchBar({
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
onExitDown={onExitDown}
|
||||||
|
onExitLeft={onExitLeft}
|
||||||
/>
|
/>
|
||||||
) : value ? (
|
) : value ? (
|
||||||
<Text wrap="truncate-end">{value}</Text>
|
<Text wrap="truncate-end">{value}</Text>
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ export interface TextFieldProps {
|
|||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
onChange?: (value: string) => void;
|
onChange?: (value: string) => void;
|
||||||
onSubmit?: (value: string) => void;
|
onSubmit?: (value: string) => void;
|
||||||
|
onExitDown?: () => void;
|
||||||
|
onExitLeft?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Edit {
|
interface Edit {
|
||||||
@@ -48,6 +50,8 @@ export function TextField({
|
|||||||
placeholder = "",
|
placeholder = "",
|
||||||
onChange,
|
onChange,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
|
onExitDown,
|
||||||
|
onExitLeft,
|
||||||
}: TextFieldProps) {
|
}: TextFieldProps) {
|
||||||
const [value, setValue] = useState(defaultValue);
|
const [value, setValue] = useState(defaultValue);
|
||||||
const [cursor, setCursor] = useState(defaultValue.length);
|
const [cursor, setCursor] = useState(defaultValue.length);
|
||||||
@@ -60,8 +64,11 @@ export function TextField({
|
|||||||
|
|
||||||
useInput(
|
useInput(
|
||||||
(input, key) => {
|
(input, key) => {
|
||||||
if (key.upArrow || key.downArrow || key.tab || (key.ctrl && input === "c"))
|
if (key.downArrow) {
|
||||||
|
onExitDown?.();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (key.upArrow || key.tab || (key.ctrl && input === "c")) return;
|
||||||
|
|
||||||
if (key.return) {
|
if (key.return) {
|
||||||
onSubmit?.(value);
|
onSubmit?.(value);
|
||||||
@@ -91,7 +98,11 @@ export function TextField({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key.leftArrow) {
|
if (key.leftArrow) {
|
||||||
setCursor(Math.max(0, cursor - 1));
|
if (cursor === 0) {
|
||||||
|
onExitLeft?.();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCursor(cursor - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key.rightArrow) {
|
if (key.rightArrow) {
|
||||||
|
|||||||
+6
-2
@@ -14,7 +14,7 @@ export const HELP_GROUPS: HelpGroup[] = [
|
|||||||
{
|
{
|
||||||
title: "Navigate",
|
title: "Navigate",
|
||||||
hints: [
|
hints: [
|
||||||
{ keys: "↑ ↓", label: "Move" },
|
{ keys: "↑ ↓ ← →", label: "Navigate content and panes" },
|
||||||
{ keys: "↵", label: "Open" },
|
{ keys: "↵", label: "Open" },
|
||||||
{ keys: "tab", label: "Switch pane" },
|
{ keys: "tab", label: "Switch pane" },
|
||||||
{ keys: "esc", label: "Back" },
|
{ keys: "esc", label: "Back" },
|
||||||
@@ -48,6 +48,8 @@ export const HELP_GROUPS: HelpGroup[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const NAVIGATE: Hint = { keys: "↑ ↓ ← →", label: "Navigate content and panes" };
|
||||||
|
|
||||||
const ALWAYS: Hint = { keys: "?", label: "Keys" };
|
const ALWAYS: Hint = { keys: "?", label: "Keys" };
|
||||||
|
|
||||||
const SWITCH: Hint = { keys: "tab", label: "Switch pane" };
|
const SWITCH: Hint = { keys: "tab", label: "Switch pane" };
|
||||||
@@ -60,7 +62,7 @@ export function footerHints(
|
|||||||
): Hint[] {
|
): Hint[] {
|
||||||
if (region === "sidebar") {
|
if (region === "sidebar") {
|
||||||
return [
|
return [
|
||||||
{ keys: "↑↓", label: "Move" },
|
NAVIGATE,
|
||||||
{ keys: "↵", label: "Open" },
|
{ keys: "↵", label: "Open" },
|
||||||
SWITCH,
|
SWITCH,
|
||||||
ALWAYS,
|
ALWAYS,
|
||||||
@@ -81,6 +83,7 @@ export function footerHints(
|
|||||||
}
|
}
|
||||||
if (downloadFocus === "recent") {
|
if (downloadFocus === "recent") {
|
||||||
return [
|
return [
|
||||||
|
NAVIGATE,
|
||||||
{ keys: "d", label: "Download again" },
|
{ keys: "d", label: "Download again" },
|
||||||
{ keys: "c", label: "Remove" },
|
{ keys: "c", label: "Remove" },
|
||||||
{ keys: "x", label: "Clear" },
|
{ keys: "x", label: "Clear" },
|
||||||
@@ -91,6 +94,7 @@ export function footerHints(
|
|||||||
return [{ keys: "p", label: "Pause" }, { keys: "c", label: "Cancel" }, SWITCH, ALWAYS];
|
return [{ keys: "p", label: "Pause" }, { keys: "c", label: "Cancel" }, SWITCH, ALWAYS];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
|
NAVIGATE,
|
||||||
{ keys: "d", label: "Download" },
|
{ keys: "d", label: "Download" },
|
||||||
{ keys: "/", label: "Search" },
|
{ keys: "/", label: "Search" },
|
||||||
{ keys: "m", label: "Paste magnet" },
|
{ keys: "m", label: "Paste magnet" },
|
||||||
|
|||||||
Reference in New Issue
Block a user