| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- import {
- activeClientToggled,
- masterSet,
- playPaused,
- queuePushed,
- queueRemoved,
- stateSet,
- } from '../../../../actions';
- import { ActionKeyPressed, Keys } from '../../../../hooks/vim';
- import { getFilteredSongs } from '../selectors';
- import { CmusUIState, LibraryModeWindow, Overlay, View } from '../types';
- import { handleOrder } from './order';
- import { handleScroll } from './scroll';
- import { withGlobalAction } from './utils';
- const libraryModeWindows: LibraryModeWindow[] = Object.values(LibraryModeWindow);
- const switchLibraryMode = (state: CmusUIState): CmusUIState => ({
- ...state,
- library: {
- ...state.library,
- modeWindow:
- libraryModeWindows[
- (libraryModeWindows.indexOf(state.library.modeWindow) + 1) % libraryModeWindows.length
- ],
- },
- });
- function toggleExpandArtist(library: CmusUIState['library']): CmusUIState['library'] {
- if (library.activeArtist === null) {
- return library;
- }
- if (library.expandedArtists.includes(library.activeArtist)) {
- return {
- ...library,
- expandedArtists: library.expandedArtists.filter(
- (compare) => compare !== library.activeArtist,
- ),
- activeAlbum: null,
- };
- }
- return { ...library, expandedArtists: [...library.expandedArtists, library.activeArtist] };
- }
- const activateSong = (state: CmusUIState, songId: number | null): CmusUIState =>
- songId
- ? withGlobalAction(
- state,
- stateSet({
- playing: true,
- songId,
- currentTime: 0,
- seekTime: 0,
- }),
- )
- : state;
- function handleActivate(state: CmusUIState): CmusUIState {
- switch (state.view) {
- case View.Library:
- switch (state.library.modeWindow) {
- case LibraryModeWindow.SongList:
- return activateSong(state, state.library.activeSongId);
- case LibraryModeWindow.ArtistList:
- return activateSong(state, getFilteredSongs(state)[0]?.id ?? null);
- default:
- return state;
- }
- case View.Queue:
- if (!state.queue.active) {
- return state;
- }
- return activateSong(state, state.queue.active);
- case View.ClientList:
- if (!state.clientList.active) {
- return state;
- }
- return withGlobalAction(state, masterSet(state.clientList.active));
- default:
- return state;
- }
- }
- function handleToggle(state: CmusUIState): CmusUIState {
- switch (state.view) {
- case View.Library:
- if (state.library.modeWindow === LibraryModeWindow.ArtistList) {
- return { ...state, library: toggleExpandArtist(state.library) };
- }
- return state;
- case View.ClientList:
- if (!state.clientList.active) {
- return state;
- }
- return withGlobalAction(state, activeClientToggled(state.clientList.active));
- default:
- return state;
- }
- }
- function addSelectedToQueue(state: CmusUIState): CmusUIState {
- if (state.view !== View.Library) {
- return state;
- }
- switch (state.library.modeWindow) {
- case LibraryModeWindow.ArtistList:
- return withGlobalAction(state, queuePushed(getFilteredSongs(state).map(({ id }) => id)));
- case LibraryModeWindow.SongList:
- if (!state.library.activeSongId) {
- return state;
- }
- return withGlobalAction(state, queuePushed([state.library.activeSongId]));
- default:
- return state;
- }
- }
- export function handleKeyPress(state: CmusUIState, action: ActionKeyPressed): CmusUIState {
- switch (action.key) {
- case Keys.colon:
- return { ...state, commandMode: true };
- case Keys['1']:
- return { ...state, view: View.Library };
- case Keys['2']:
- return { ...state, view: View.ClientList };
- case Keys['3']:
- return { ...state, view: View.Queue };
- case Keys.tab:
- if (state.view === View.Library) {
- return switchLibraryMode(state);
- }
- return state;
- case Keys.space:
- return handleToggle(state);
- case Keys.enter:
- return handleActivate(state);
- case Keys.esc:
- return { ...state, overlay: null };
- case Keys.slash:
- return { ...state, searchMode: true };
- case Keys.question:
- return { ...state, overlay: Overlay.Help };
- case Keys.B:
- return { ...state, skipSong: { delta: 1, serialNumber: state.skipSong.serialNumber + 1 } };
- case Keys.Z:
- return { ...state, skipSong: { delta: -1, serialNumber: state.skipSong.serialNumber + 1 } };
- case Keys.S:
- return withGlobalAction(
- state,
- stateSet((last) => ({ shuffleMode: !last.shuffleMode })),
- );
- case Keys.C:
- return withGlobalAction(state, playPaused());
- case Keys.D:
- if (state.view === View.Queue && state.queue.active) {
- return withGlobalAction(state, queueRemoved(state.queue.active));
- }
- return state;
- case Keys.E:
- return addSelectedToQueue(state);
- case Keys.J:
- return handleScroll(state, 1);
- case Keys.K:
- return handleScroll(state, -1);
- case Keys.p:
- return handleOrder(state, 1);
- case Keys.P:
- return handleOrder(state, -1);
- case Keys.pageDown:
- return handleScroll(state, 20);
- case Keys.pageUp:
- return handleScroll(state, -20);
- default:
- return state;
- }
- }
|