From 9224a67a7b966c46bd455a8f9a9208ea71d90843 Mon Sep 17 00:00:00 2001 From: Deluan Date: Thu, 5 Nov 2020 17:38:53 -0500 Subject: [PATCH] Add <- and -> hotkeys, to jump to previous or next song Refers to #585 --- ui/package-lock.json | 12 ++--- ui/package.json | 2 +- ui/src/audioplayer/Player.js | 96 ++++++++++++++++++++++-------------- 3 files changed, 66 insertions(+), 44 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index f8a203935..a64ff3e4c 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -13562,14 +13562,12 @@ "resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.1.2.tgz", "integrity": "sha512-OJrMqaHEHbodm+XsnjA6ISBEHTwvpFrxco65mctzl/v3CASMSLSyUkFqz9yYrPDKGBUfNQzKCjuMJwctjlWBbw==" }, - "react-hot-keys": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/react-hot-keys/-/react-hot-keys-2.6.0.tgz", - "integrity": "sha512-q7UKLGxZyWhIeyNp4TIp5ardcIF5lPeS8Lmh5gTKH+4IOQDrfMkyvAoz1XFYKR2UDc4GW9sEDrzVrqVZu/HrAw==", + "react-hotkeys-hook": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-2.4.0.tgz", + "integrity": "sha512-Veh9FUe+iXab+lZ5shPoyGDnFBu5codQ15omOXiOvCC/Q5QfTY1lefLVx/Zi2NnYBSXfkfQbhnpE+Rnhi2+wBw==", "requires": { - "@babel/runtime": "^7.8.4", - "hotkeys-js": "^3.8.1", - "prop-types": "^15.7.2" + "hotkeys-js": "3.8.1" } }, "react-icons": { diff --git a/ui/package.json b/ui/package.json index 069cd3c3c..a22a42322 100644 --- a/ui/package.json +++ b/ui/package.json @@ -17,7 +17,7 @@ "react-dom": "^16.13.1", "react-drag-listview": "^0.1.7", "react-ga": "^3.1.2", - "react-hot-keys": "^2.6.0", + "react-hotkeys-hook": "^2.4.0", "react-icons": "^3.11.0", "react-image-lightbox": "^5.1.1", "react-jinke-music-player": "^4.19.0", diff --git a/ui/src/audioplayer/Player.js b/ui/src/audioplayer/Player.js index f5612fa38..71967f63f 100644 --- a/ui/src/audioplayer/Player.js +++ b/ui/src/audioplayer/Player.js @@ -5,7 +5,6 @@ import { Link } from 'react-router-dom' import { useAuthState, useDataProvider, useTranslate } from 'react-admin' import ReactJkMusicPlayer from 'react-jinke-music-player' import 'react-jinke-music-player/assets/index.css' -import Hotkeys from 'react-hot-keys' import { makeStyles } from '@material-ui/core/styles' import subsonic from '../subsonic' import { @@ -18,6 +17,7 @@ import { import themes from '../themes' import config from '../config' import PlayerToolbar from './PlayerToolbar' +import { useHotkeys } from 'react-hotkeys-hook' const useStyle = makeStyles((theme) => ({ audioTitle: { @@ -52,11 +52,55 @@ const Player = () => { const dataProvider = useDataProvider() const dispatch = useDispatch() const queue = useSelector((state) => state.queue) + const current = queue.current || {} const { authenticated } = useAuthState() const visible = authenticated && queue.queue.length > 0 const classes = useStyle({ visible }) + const nextSong = () => { + const idx = queue.queue.findIndex( + (item) => item.uuid === queue.current.uuid + ) + return idx !== null ? queue.queue[idx + 1] : null + } + + const prevSong = () => { + const idx = queue.queue.findIndex( + (item) => item.uuid === queue.current.uuid + ) + return idx !== null ? queue.queue[idx - 1] : null + } + + useHotkeys('space', (e) => { + e.preventDefault() + audioInstance && audioInstance.togglePlay() + }) + + useHotkeys( + 'left', + (e) => { + if (prevSong()) { + e.preventDefault() + audioInstance && audioInstance.playPrev() + } + }, + {}, + [queue] + ) + + useHotkeys( + 'right', + (e) => { + if (nextSong()) { + e.preventDefault() + audioInstance && audioInstance.playNext() + } + }, + {}, + [queue] + ) + const defaultOptions = { theme: playerTheme, bounds: 'body', @@ -108,7 +152,6 @@ const Player = () => { }, } - const current = queue.current || {} const options = useMemo(() => { return { ...defaultOptions, @@ -206,45 +249,26 @@ const Player = () => { }) }, [dispatch]) - const onKeyUp = useCallback((keyName, e) => { - if (keyName === 'space') { - e.preventDefault() - } - }, []) - const onKeyDown = useCallback((keyName, e) => { - if (keyName === 'space') { - e.preventDefault() - audioInstance && audioInstance.togglePlay() - } - }, []) - if (!visible) { document.title = 'Navidrome' } return ( - - { - audioInstance = instance - }} - /> - + { + audioInstance = instance + }} + /> ) }