diff --git a/src/App.tsx b/src/App.tsx
index fbd648b..077b389 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -18,22 +18,21 @@ const DEBUG = import.meta.env.DEBUG;
export function App() {
const nav = useNavigation();
- const audio = useAudio();
const toast = useToast();
const renderer = useRenderer();
const themeContext = useTheme();
const theme = themeContext.theme;
const keybind = useKeybinds();
- // Multimedia keys (physical play/seek keys) still feed the audio backend
- // regardless of the on-screen yazi keybinds.
+ // Multimedia keys (physical play/volume/speed keys) still feed the audio
+ // backend regardless of the on-screen yazi keybinds. Seek lives on the
+ // keybind router (< / > = shift+, / shift+.), so arrows stay on navigation.
useMultimediaKeys({
playerFocused: () =>
nav.activeTab() === TABS.PLAYER && nav.mode() !== NavMode.NORMAL
? true
: false,
inputFocused: () => nav.inputFocused(),
- hasEpisode: () => !!audio.currentEpisode(),
});
// Mouse text-selection → clipboard (unchanged from the old shell).
diff --git a/src/config/keybinds.jsonc b/src/config/keybinds.jsonc
index d740afc..a12ff10 100644
--- a/src/config/keybinds.jsonc
+++ b/src/config/keybinds.jsonc
@@ -72,6 +72,6 @@
"audio-toggle": ["P"], // play / pause (shift+p)
"audio-next": ["N"], // next episode (shift+n)
"audio-prev": ["B"], // prev episode (shift+b)
- "audio-seek-forward": ["shift-."], // seek forward (shift+.)
- "audio-seek-backward": ["shift-,"] // seek backward (shift+,)
+ "audio-seek-forward": ["shift-."], // seek forward (> = shift+.)
+ "audio-seek-backward": ["shift-,"] // seek backward (< = shift+,)
}
diff --git a/src/hooks/useAudio.ts b/src/hooks/useAudio.ts
index df3793c..5484324 100644
--- a/src/hooks/useAudio.ts
+++ b/src/hooks/useAudio.ts
@@ -421,14 +421,6 @@ export function useAudio(): AudioControls {
await doSetVolume(Math.max(0, Number((volume() - 0.05).toFixed(2))));
});
- const unsubMediaSeekFwd = on("media.seekForward", async () => {
- await seekRelative(10);
- });
-
- const unsubMediaSeekBack = on("media.seekBackward", async () => {
- await seekRelative(-10);
- });
-
const unsubMediaSpeed = on("media.speedCycle", async () => {
const next = speed() >= 2 ? 0.5 : Number((speed() + 0.25).toFixed(2));
await doSetSpeed(next);
@@ -515,8 +507,6 @@ export function useAudio(): AudioControls {
unsubMediaToggle();
unsubMediaVolUp();
unsubMediaVolDown();
- unsubMediaSeekFwd();
- unsubMediaSeekBack();
unsubMediaSpeed();
if (refCount <= 0) {
diff --git a/src/hooks/useMultimediaKeys.ts b/src/hooks/useMultimediaKeys.ts
index 3cc2ecb..939e17b 100644
--- a/src/hooks/useMultimediaKeys.ts
+++ b/src/hooks/useMultimediaKeys.ts
@@ -1,13 +1,14 @@
/**
* Global multimedia key handler hook.
*
- * Captures media-related key events (play/pause, volume, seek, speed)
+ * Captures media-related key events (play/pause, volume, speed)
* regardless of which component is focused. Uses the event bus to
* decouple key detection from audio control logic.
*
* Volume and speed are app-level settings — adjustable with or without
* an episode loaded (they apply to the next playback and persist). Seek
- * is playback-dependent, so it still requires a loaded episode.
+ * is NOT handled here: it lives on the yazi keybind router (`<` / `>` =
+ * shift+, / shift+.), so the arrow keys stay free for navigation.
*/
import { useKeyboard } from "@opentui/solid";
@@ -17,8 +18,6 @@ export type MediaKeyAction =
| "media.toggle"
| "media.volumeUp"
| "media.volumeDown"
- | "media.seekForward"
- | "media.seekBackward"
| "media.speedCycle";
export interface MultimediaKeysOptions {
@@ -26,8 +25,6 @@ export interface MultimediaKeysOptions {
playerFocused?: () => boolean;
/** When true, skip handling (text input has focus) */
inputFocused?: () => boolean;
- /** Whether an episode is currently loaded */
- hasEpisode?: () => boolean;
}
/**
@@ -59,16 +56,6 @@ export function useMultimediaKeys(options: MultimediaKeysOptions = {}) {
emit("media.volumeDown", {});
break;
- case "left":
- if (!options.hasEpisode?.()) return;
- emit("media.seekBackward", {});
- break;
-
- case "right":
- if (!options.hasEpisode?.()) return;
- emit("media.seekForward", {});
- break;
-
case "s":
emit("media.speedCycle", {});
break;
diff --git a/src/pages/Player/PlayerPage.tsx b/src/pages/Player/PlayerPage.tsx
index d5f51b4..cc93451 100644
--- a/src/pages/Player/PlayerPage.tsx
+++ b/src/pages/Player/PlayerPage.tsx
@@ -110,7 +110,7 @@ export function PlayerPage() {
- {"P play/pause N next B prev ◀▶ seek h back"}
+ {"P play/pause N next B prev < > seek h back"}
);
diff --git a/src/utils/event-bus.ts b/src/utils/event-bus.ts
index 777b2d9..d8e4587 100644
--- a/src/utils/event-bus.ts
+++ b/src/utils/event-bus.ts
@@ -132,8 +132,6 @@ export type AppEvents = {
"media.toggle": {};
"media.volumeUp": {};
"media.volumeDown": {};
- "media.seekForward": {};
- "media.seekBackward": {};
"media.speedCycle": {};
};
diff --git a/src/utils/keybinds-persistence.ts b/src/utils/keybinds-persistence.ts
index b315ecf..8f97602 100644
--- a/src/utils/keybinds-persistence.ts
+++ b/src/utils/keybinds-persistence.ts
@@ -69,8 +69,8 @@ const DEFAULT_KEYBINDS: KeybindsResolved = {
"audio-toggle": ["P"],
"audio-next": ["N"],
"audio-prev": ["B"],
- "audio-seek-forward": ["shift-."],
- "audio-seek-backward": ["shift-,"],
+ "audio-seek-forward": ["shift-."], // > = shift+.
+ "audio-seek-backward": ["shift-,"], // < = shift+,
};
/** Copy keybinds.jsonc to user config directory on first run */