Skip to content

Commit 41dcb3b

Browse files
committed
[fix] Avoid triggering keyboard shortcuts when Alt or Ctrl key pressed.
1 parent aa9e25b commit 41dcb3b

File tree

1 file changed

+152
-152
lines changed

1 file changed

+152
-152
lines changed

src/index.js

Lines changed: 152 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,19 +1706,46 @@ function getFolderCover( uri ) {
17061706
*/
17071707
function keyboardControls( event ) {
17081708

1709-
if ( event.code == 'F1' && ! event.altKey && ! event.ctrlKey ) {
1709+
// ignore system shortcuts (with alt, ctrl or win key)
1710+
if ( event.altKey || event.ctrlKey || event.metaKey )
1711+
return;
1712+
1713+
const isShiftKey = event.shiftKey;
1714+
1715+
// F1 - help
1716+
if ( event.code == 'F1' && ! isShiftKey ) {
17101717
location.href = '#help';
17111718
event.preventDefault();
17121719
return;
17131720
}
17141721

1715-
if ( event.target.tagName != 'BODY' || event.altKey || event.ctrlKey )
1722+
// ignore all other keys when focus is not on body (e.g. input fields)
1723+
if ( event.target.tagName != 'BODY' )
17161724
return;
17171725

1718-
const isShiftKey = event.shiftKey;
1726+
// avoid automatic repetition if it's not an arrow key
1727+
if ( event.repeat && ! event.code.startsWith('Arrow') )
1728+
return;
17191729

1720-
// keys handled on 'keydown' allow automatic repetition
1721-
if ( event.type == 'keydown' ) {
1730+
// handle numeric keys (load / save user presets)
1731+
if ( event.code.match( /^(Digit|Numpad)[0-9]$/ ) ) {
1732+
const index = event.code.slice(-1) - 1;
1733+
if ( index == -1 ) { // '0' pressed
1734+
// ignore if Shift pressed as it could be a user mistake
1735+
if ( ! isShiftKey ) {
1736+
randomizeSettings( true );
1737+
setProperty( elRandomMode, false ); // restart randomize timer (if active)
1738+
}
1739+
}
1740+
else if ( isShiftKey ) {
1741+
const settings = getCurrentSettings();
1742+
settings.randomMode = 0; // when saving via keyboard shortcut, turn off Randomize
1743+
saveUserPreset( index, settings );
1744+
}
1745+
else
1746+
loadPreset( index );
1747+
}
1748+
else {
17221749
switch ( event.code ) {
17231750
case 'ArrowUp': // volume up
17241751
if ( isShiftKey )
@@ -1752,154 +1779,128 @@ function keyboardControls( event ) {
17521779
else
17531780
scheduleFastSearch('k');
17541781
break;
1782+
case 'Delete': // delete selected songs from the playlist
1783+
case 'Backspace': // for Mac
1784+
playlist.querySelectorAll('.selected').forEach( e => {
1785+
revokeBlobURL( e );
1786+
e.remove();
1787+
});
1788+
const current = getIndex( playlist.querySelector('.current') );
1789+
if ( current !== undefined )
1790+
playlistPos = current; // update playlistPos if current song hasn't been deleted
1791+
else if ( playlistPos > queueLength() - 1 )
1792+
playlistPos = queueLength() - 1;
1793+
else
1794+
playlistPos--;
1795+
if ( queueLength() )
1796+
loadNextSong();
1797+
else {
1798+
clearAudioElement( nextAudio );
1799+
if ( ! isPlaying() )
1800+
clearAudioElement();
1801+
}
1802+
storePlayQueue( true );
1803+
break;
1804+
case 'Space': // play / pause
1805+
setCanvasMsg( isPlaying() ? 'Pause' : 'Play', 1 );
1806+
playPause();
1807+
break;
1808+
case 'ArrowLeft': // previous song
1809+
case 'KeyJ':
1810+
if ( ! finishFastSearch() && ! isShiftKey ) {
1811+
setCanvasMsg( 'Previous track', 1 );
1812+
skipTrack(true);
1813+
}
1814+
break;
1815+
case 'KeyG': // gradient
1816+
cycleElement( elGradient, isShiftKey );
1817+
setCanvasMsg( getSelectedGradients() );
1818+
break;
1819+
case 'ArrowRight': // next song
1820+
case 'KeyK':
1821+
if ( ! finishFastSearch() && ! isShiftKey ) {
1822+
setCanvasMsg( 'Next track', 1 );
1823+
skipTrack();
1824+
}
1825+
break;
1826+
case 'KeyA': // cycle thru Randomize options
1827+
cycleElement( elRandomMode, isShiftKey );
1828+
setCanvasMsg( 'Randomize: ' + getText( elRandomMode ) );
1829+
setProperty( elRandomMode );
1830+
break;
1831+
case 'KeyB': // background or image fit (shift)
1832+
cycleElement( isShiftKey ? elBgImageFit : elBackground );
1833+
const bgOption = elBackground.value[0];
1834+
setCanvasMsg( 'Background: ' + getText( elBackground ) + ( bgOption > 1 && bgOption < 7 ? ` (${getText( elBgImageFit )})` : '' ) );
1835+
break;
1836+
case 'KeyC': // radial
1837+
elRadial.click();
1838+
setCanvasMsg( 'Radial ' + onOff( elRadial ) );
1839+
break;
1840+
case 'KeyD': // display information
1841+
toggleInfo();
1842+
break;
1843+
case 'KeyE': // shuffle queue
1844+
if ( queueLength() > 0 ) {
1845+
shufflePlayQueue();
1846+
setCanvasMsg( 'Shuffle' );
1847+
}
1848+
break;
1849+
case 'KeyF': // toggle fullscreen
1850+
fullscreen();
1851+
break;
1852+
case 'KeyH': // toggle fps display
1853+
elFPS.click();
1854+
break;
1855+
case 'KeyI': // toggle info display on track change
1856+
elShowSong.click();
1857+
setCanvasMsg( 'Song info display ' + onOff( elShowSong ) );
1858+
break;
1859+
case 'KeyL': // toggle LED display effect
1860+
elLedDisplay.click();
1861+
setCanvasMsg( 'LED effect ' + onOff( elLedDisplay ) );
1862+
break;
1863+
case 'KeyM': // visualization mode
1864+
case 'KeyV':
1865+
cycleElement( elMode, isShiftKey );
1866+
setCanvasMsg( 'Mode: ' + getText( elMode ) );
1867+
break;
1868+
case 'KeyN': // increase or reduce sensitivity
1869+
cycleElement( elSensitivity, isShiftKey );
1870+
setCanvasMsg( getText( elSensitivity ).toUpperCase() + ' sensitivity' );
1871+
break;
1872+
case 'KeyO': // toggle resolution
1873+
elLoRes.click();
1874+
setCanvasMsg( ( isSwitchOn( elLoRes ) ? 'LOW' : 'HIGH' ) + ' Resolution' );
1875+
break;
1876+
case 'KeyP': // toggle peaks display
1877+
elShowPeaks.click();
1878+
setCanvasMsg( 'Peaks ' + onOff( elShowPeaks ) );
1879+
break;
1880+
case 'KeyR': // toggle playlist repeat
1881+
elRepeat.click();
1882+
setCanvasMsg( 'Queue repeat ' + onOff( elRepeat ) );
1883+
break;
1884+
case 'KeyS': // toggle X and Y axis scales
1885+
setCanvasMsg( 'Scale: ' + ['None','Frequency (Hz)','Level (dB)','Both'][ cycleScale( isShiftKey ) ] );
1886+
break;
1887+
case 'KeyT': // toggle text shadow
1888+
elNoShadow.click();
1889+
setCanvasMsg( ( isSwitchOn( elNoShadow ) ? 'Flat' : 'Shadowed' ) + ' text mode' );
1890+
break;
1891+
case 'KeyU': // toggle lumi bars
1892+
elLumiBars.click();
1893+
setCanvasMsg( 'Luminance bars ' + onOff( elLumiBars ) );
1894+
break;
1895+
case 'KeyX':
1896+
cycleElement( elReflex, isShiftKey );
1897+
setCanvasMsg( 'Reflex: ' + getText( elReflex ) );
1898+
break;
17551899
default:
17561900
// no key match - quit and keep default behavior
17571901
return;
1758-
}
1759-
}
1760-
else {
1761-
if ( event.code.match( /^(Digit|Numpad)[0-9]$/ ) ) {
1762-
const index = event.code.slice(-1) - 1;
1763-
if ( index == -1 ) { // '0' pressed
1764-
// ignore if Shift pressed as it could be a user mistake
1765-
if ( ! isShiftKey ) {
1766-
randomizeSettings( true );
1767-
setProperty( elRandomMode, false ); // restart randomize timer (if active)
1768-
}
1769-
}
1770-
else if ( isShiftKey ) {
1771-
const settings = getCurrentSettings();
1772-
settings.randomMode = 0; // when saving via keyboard shortcut, turn off Randomize
1773-
saveUserPreset( index, settings );
1774-
}
1775-
else
1776-
loadPreset( index );
1777-
}
1778-
else {
1779-
switch ( event.code ) {
1780-
case 'Delete': // delete selected songs from the playlist
1781-
case 'Backspace': // for Mac
1782-
playlist.querySelectorAll('.selected').forEach( e => {
1783-
revokeBlobURL( e );
1784-
e.remove();
1785-
});
1786-
const current = getIndex( playlist.querySelector('.current') );
1787-
if ( current !== undefined )
1788-
playlistPos = current; // update playlistPos if current song hasn't been deleted
1789-
else if ( playlistPos > queueLength() - 1 )
1790-
playlistPos = queueLength() - 1;
1791-
else
1792-
playlistPos--;
1793-
if ( queueLength() )
1794-
loadNextSong();
1795-
else {
1796-
clearAudioElement( nextAudio );
1797-
if ( ! isPlaying() )
1798-
clearAudioElement();
1799-
}
1800-
storePlayQueue( true );
1801-
break;
1802-
case 'Space': // play / pause
1803-
setCanvasMsg( isPlaying() ? 'Pause' : 'Play', 1 );
1804-
playPause();
1805-
break;
1806-
case 'ArrowLeft': // previous song
1807-
case 'KeyJ':
1808-
if ( ! finishFastSearch() && ! isShiftKey ) {
1809-
setCanvasMsg( 'Previous track', 1 );
1810-
skipTrack(true);
1811-
}
1812-
break;
1813-
case 'KeyG': // gradient
1814-
cycleElement( elGradient, isShiftKey );
1815-
setCanvasMsg( getSelectedGradients() );
1816-
break;
1817-
case 'ArrowRight': // next song
1818-
case 'KeyK':
1819-
if ( ! finishFastSearch() && ! isShiftKey ) {
1820-
setCanvasMsg( 'Next track', 1 );
1821-
skipTrack();
1822-
}
1823-
break;
1824-
case 'KeyA': // cycle thru Randomize options
1825-
cycleElement( elRandomMode, isShiftKey );
1826-
setCanvasMsg( 'Randomize: ' + getText( elRandomMode ) );
1827-
setProperty( elRandomMode );
1828-
break;
1829-
case 'KeyB': // background or image fit (shift)
1830-
cycleElement( isShiftKey ? elBgImageFit : elBackground );
1831-
const bgOption = elBackground.value[0];
1832-
setCanvasMsg( 'Background: ' + getText( elBackground ) + ( bgOption > 1 && bgOption < 7 ? ` (${getText( elBgImageFit )})` : '' ) );
1833-
break;
1834-
case 'KeyC': // radial
1835-
elRadial.click();
1836-
setCanvasMsg( 'Radial ' + onOff( elRadial ) );
1837-
break;
1838-
case 'KeyD': // display information
1839-
toggleInfo();
1840-
break;
1841-
case 'KeyE': // shuffle queue
1842-
if ( queueLength() > 0 ) {
1843-
shufflePlayQueue();
1844-
setCanvasMsg( 'Shuffle' );
1845-
}
1846-
break;
1847-
case 'KeyF': // toggle fullscreen
1848-
fullscreen();
1849-
break;
1850-
case 'KeyH': // toggle fps display
1851-
elFPS.click();
1852-
break;
1853-
case 'KeyI': // toggle info display on track change
1854-
elShowSong.click();
1855-
setCanvasMsg( 'Song info display ' + onOff( elShowSong ) );
1856-
break;
1857-
case 'KeyL': // toggle LED display effect
1858-
elLedDisplay.click();
1859-
setCanvasMsg( 'LED effect ' + onOff( elLedDisplay ) );
1860-
break;
1861-
case 'KeyM': // visualization mode
1862-
case 'KeyV':
1863-
cycleElement( elMode, isShiftKey );
1864-
setCanvasMsg( 'Mode: ' + getText( elMode ) );
1865-
break;
1866-
case 'KeyN': // increase or reduce sensitivity
1867-
cycleElement( elSensitivity, isShiftKey );
1868-
setCanvasMsg( getText( elSensitivity ).toUpperCase() + ' sensitivity' );
1869-
break;
1870-
case 'KeyO': // toggle resolution
1871-
elLoRes.click();
1872-
setCanvasMsg( ( isSwitchOn( elLoRes ) ? 'LOW' : 'HIGH' ) + ' Resolution' );
1873-
break;
1874-
case 'KeyP': // toggle peaks display
1875-
elShowPeaks.click();
1876-
setCanvasMsg( 'Peaks ' + onOff( elShowPeaks ) );
1877-
break;
1878-
case 'KeyR': // toggle playlist repeat
1879-
elRepeat.click();
1880-
setCanvasMsg( 'Queue repeat ' + onOff( elRepeat ) );
1881-
break;
1882-
case 'KeyS': // toggle X and Y axis scales
1883-
setCanvasMsg( 'Scale: ' + ['None','Frequency (Hz)','Level (dB)','Both'][ cycleScale( isShiftKey ) ] );
1884-
break;
1885-
case 'KeyT': // toggle text shadow
1886-
elNoShadow.click();
1887-
setCanvasMsg( ( isSwitchOn( elNoShadow ) ? 'Flat' : 'Shadowed' ) + ' text mode' );
1888-
break;
1889-
case 'KeyU': // toggle lumi bars
1890-
elLumiBars.click();
1891-
setCanvasMsg( 'Luminance bars ' + onOff( elLumiBars ) );
1892-
break;
1893-
case 'KeyX':
1894-
cycleElement( elReflex, isShiftKey );
1895-
setCanvasMsg( 'Reflex: ' + getText( elReflex ) );
1896-
break;
1897-
default:
1898-
// no key match - quit and keep default behavior
1899-
return;
1900-
} // switch
1901-
}
1902-
} // else if ( event.type == 'keydown' )
1902+
} // switch
1903+
} // else
19031904

19041905
event.preventDefault();
19051906
}
@@ -5152,9 +5153,8 @@ function updateRangeValue( el ) {
51525153
setUIEventListeners();
51535154
});
51545155

5155-
// Add events listeners for keyboard controls
5156+
// Add event listener for keyboard shortcuts
51565157
window.addEventListener( 'keydown', keyboardControls );
5157-
window.addEventListener( 'keyup', keyboardControls );
51585158

51595159
// notie options
51605160
notie.setOptions({

0 commit comments

Comments
 (0)