mmontag/chip-player-js

Move current selected/highlighted song with arrow keys.

Opened this issue · 4 comments

It would be nice if you could use the arrow keys to move up or down by a single song per keypress.

image

If I press the DOWN KEY, it will move the blue highlight cursor down to the next song or the UP KEY and previous song. Whether or not this should play the newly highlight song... I do not know. Currently the arrows move the scroll bar by a small amount up or down, and I presume no one uses this intentionally for scrolling as it is cucumbersome.

A nice touch might be to keep the cursor centered vertically in the container such that moving up or down "moves" the list but the highlight remains in position. Ideally this would not be a hard anchoring to the center, but a small window in which the cursor can move around without affecting the position of the list; when it goes out of that bound above or below, then the list itself moves, keeping the cursor in that box.

I mean, moving in the light gray area (below image) would not reposition/scroll the list, but would only move the cursor. Outside of the light gray area, the cursor stays put and the list scrolls.

image

Ah yes, List View selectable row behavior. Of course, this is a must-have for any software purporting to honor Winamp. Something that Spotify does (YouTube Music doesn't and Rdio never did).

I've put it off until now, waiting for someone to request it. I want to hear from the people.

If I can piggyback the browser's built-in focus mechanism, then we get the "selection following" behavior for free...

items = null; fidx = 0; listview = document.querySelector('.App-main-content-area'); window.addEventListener('keydown', e => { if (!['ArrowUp','ArrowDown'].includes(e.key)) return; e.preventDefault(); items = listview.querySelectorAll('a'); if (e.key === 'ArrowUp') { fidx = Math.max(0, fidx-1); } if (e.key === 'ArrowDown') { fidx = Math.min(items.length-1, fidx+1); } items.item(fidx).focus(); }); document.styleSheets[0].insertRule('.App-main-content-area>div>div>div:focus-within{box-shadow: 0 0 0 10px inset #66d6}');

I am still working on this. Don't worry, it's coming

Still working on this. Remember, I have to make it work with list virtualization.

And there are surprising edge cases to be resolved.

For example, if you select row 30, then scroll it out of view with the mouse wheel, and then press enter, it needs to start playing row 30, even though row 30 no longer exists in the component tree/DOM (due to virtualization). And then row 30 should be scrolled back into view so you can see what just happened.

Ultimately the browser's built in focus mechanisms do not work with virtualization. Because when you scroll the focused element out of view, it is removed from the DOM, and the browser resets focus to the body element. Therefore, the browser focus should be fixed to the virtual scroll element, and a synthetic focus must be maintained within it.