add toggle for number key commands

This commit is contained in:
Pas 2026-02-20 17:08:05 -07:00
parent 1ae3ffc43b
commit 54e26c8a52
5 changed files with 53 additions and 2 deletions

View file

@ -308,7 +308,9 @@
"save": "Save",
"cancel": "Cancel",
"saveChanges": "Save Changes",
"resetToDefault": "Reset to default"
"resetToDefault": "Reset to default",
"numberKeySeeking": "Number key progress seeking",
"numberKeySeekingDescription": "Use number keys 0-9 to seek to specific positions in the video. 0 goes to the beginning, 1-8 jump to 10%-80%, and 9 goes to 90%."
}
},
"home": {

View file

@ -44,6 +44,7 @@ export interface SettingsInput {
manualSourceSelection?: boolean;
enableDoubleClickToSeek?: boolean;
enableAutoResumeOnPlaybackError?: boolean;
enableNumberKeySeeking?: boolean;
keyboardShortcuts?: KeyboardShortcuts;
customTheme?: CustomThemeSettings;
}
@ -82,6 +83,7 @@ export interface SettingsResponse {
manualSourceSelection?: boolean;
enableDoubleClickToSeek?: boolean;
enableAutoResumeOnPlaybackError?: boolean;
enableNumberKeySeeking?: boolean;
keyboardShortcuts?: KeyboardShortcuts;
customTheme?: CustomThemeSettings;
}

View file

@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
import { updateSettings } from "@/backend/accounts/settings";
import { Button } from "@/components/buttons/Button";
import { Toggle } from "@/components/buttons/Toggle";
import { Dropdown } from "@/components/form/Dropdown";
import { Icon, Icons } from "@/components/Icon";
import { Modal, ModalCard, useModal } from "@/components/overlays/Modal";
@ -203,6 +204,12 @@ export function KeyboardCommandsEditModal({
const setKeyboardShortcuts = usePreferencesStore(
(s) => s.setKeyboardShortcuts,
);
const enableNumberKeySeeking = usePreferencesStore(
(s) => s.enableNumberKeySeeking,
);
const setEnableNumberKeySeeking = usePreferencesStore(
(s) => s.setEnableNumberKeySeeking,
);
const [editingShortcuts, setEditingShortcuts] =
useState<KeyboardShortcuts>(keyboardShortcuts);
@ -212,6 +219,8 @@ export function KeyboardCommandsEditModal({
);
const [editingKey, setEditingKey] = useState<string>("");
const [isCapturingKey, setIsCapturingKey] = useState(false);
const [editingEnableNumberKeySeeking, setEditingEnableNumberKeySeeking] =
useState(enableNumberKeySeeking);
// Cancel any active editing when modal closes
useEffect(() => {
@ -220,8 +229,9 @@ export function KeyboardCommandsEditModal({
setEditingModifier("");
setEditingKey("");
setIsCapturingKey(false);
setEditingEnableNumberKeySeeking(enableNumberKeySeeking);
}
}, [modal.isShown]);
}, [modal.isShown, enableNumberKeySeeking]);
const shortcutGroups = getShortcutGroups(t, editingShortcuts).map(
(group) => ({
@ -339,11 +349,13 @@ export function KeyboardCommandsEditModal({
const handleSave = useCallback(async () => {
setKeyboardShortcuts(editingShortcuts);
setEnableNumberKeySeeking(editingEnableNumberKeySeeking);
if (account && backendUrl) {
try {
await updateSettings(backendUrl, account, {
keyboardShortcuts: editingShortcuts,
enableNumberKeySeeking: editingEnableNumberKeySeeking,
});
} catch (error) {
console.error("Failed to save keyboard shortcuts:", error);
@ -353,9 +365,11 @@ export function KeyboardCommandsEditModal({
hideModal(id);
}, [
editingShortcuts,
editingEnableNumberKeySeeking,
account,
backendUrl,
setKeyboardShortcuts,
setEnableNumberKeySeeking,
hideModal,
id,
]);
@ -508,6 +522,24 @@ export function KeyboardCommandsEditModal({
</div>
</div>
))}
<div className="flex items-center justify-between py-3 border-t border-gray-700">
<div className="flex-1">
<p className="text-white font-medium">
{t("global.keyboardShortcuts.numberKeySeeking")}
</p>
<p className="text-type-secondary text-sm">
{t("global.keyboardShortcuts.numberKeySeekingDescription")}
</p>
</div>
<Toggle
enabled={editingEnableNumberKeySeeking}
onClick={() =>
setEditingEnableNumberKeySeeking(
!editingEnableNumberKeySeeking,
)
}
/>
</div>
</div>
<div className="flex justify-end gap-3 pt-4 border-t border-gray-700">

View file

@ -67,6 +67,9 @@ export function KeyboardEvents() {
const setEnableNativeSubtitles = usePreferencesStore(
(s) => s.setEnableNativeSubtitles,
);
const enableNumberKeySeeking = usePreferencesStore(
(s) => s.enableNumberKeySeeking,
);
const [isRolling, setIsRolling] = useState(false);
const volumeDebounce = useRef<ReturnType<typeof setTimeout> | undefined>();
@ -314,6 +317,7 @@ export function KeyboardEvents() {
keyboardShortcuts,
enableNativeSubtitles,
setEnableNativeSubtitles,
enableNumberKeySeeking,
});
useEffect(() => {
@ -350,6 +354,7 @@ export function KeyboardEvents() {
keyboardShortcuts,
enableNativeSubtitles,
setEnableNativeSubtitles,
enableNumberKeySeeking,
};
}, [
setShowVolume,
@ -379,6 +384,7 @@ export function KeyboardEvents() {
keyboardShortcuts,
enableNativeSubtitles,
setEnableNativeSubtitles,
enableNumberKeySeeking,
]);
useEffect(() => {
@ -606,6 +612,7 @@ export function KeyboardEvents() {
// Skip to percentage with number keys (0-9) - locked, always use number keys
// Number keys are reserved for progress skipping, so handle them before customizable shortcuts
if (
dataRef.current.enableNumberKeySeeking &&
/^[0-9]$/.test(k) &&
dataRef.current.duration > 0 &&
!evt.ctrlKey &&

View file

@ -38,6 +38,7 @@ export interface PreferencesStore {
manualSourceSelection: boolean;
enableDoubleClickToSeek: boolean;
enableAutoResumeOnPlaybackError: boolean;
enableNumberKeySeeking: boolean;
keyboardShortcuts: KeyboardShortcuts;
setEnableThumbnails(v: boolean): void;
@ -70,6 +71,7 @@ export interface PreferencesStore {
setManualSourceSelection(v: boolean): void;
setEnableDoubleClickToSeek(v: boolean): void;
setEnableAutoResumeOnPlaybackError(v: boolean): void;
setEnableNumberKeySeeking(v: boolean): void;
setKeyboardShortcuts(v: KeyboardShortcuts): void;
}
@ -106,6 +108,7 @@ export const usePreferencesStore = create(
manualSourceSelection: false,
enableDoubleClickToSeek: false,
enableAutoResumeOnPlaybackError: true,
enableNumberKeySeeking: true,
keyboardShortcuts: DEFAULT_KEYBOARD_SHORTCUTS,
setEnableThumbnails(v) {
set((s) => {
@ -262,6 +265,11 @@ export const usePreferencesStore = create(
s.enableAutoResumeOnPlaybackError = v;
});
},
setEnableNumberKeySeeking(v) {
set((s) => {
s.enableNumberKeySeeking = v;
});
},
setKeyboardShortcuts(v) {
set((s) => {
s.keyboardShortcuts = v;