Explorar el Código

feat: queue position indicator

Fela Maslen hace 5 años
padre
commit
704eaafcc2

+ 0 - 6
gmus-web/src/components/ui/cmus/reducer/keypress.spec.ts

@@ -83,12 +83,6 @@ describe(ActionTypeKeyPressed, () => {
           const result = cmusUIReducer(stateWithActiveSong, action);
           expect(result.globalAction).toStrictEqual(queuePushed(1867));
         });
-
-        it('should select the next song in the list', () => {
-          expect.assertions(1);
-          const result = cmusUIReducer(stateWithActiveSong, action);
-          expect(result.library.activeSongId).toBe(46);
-        });
       });
     });
   });

+ 2 - 2
gmus-web/src/components/ui/cmus/reducer/keypress.ts

@@ -2,7 +2,7 @@ import { masterSet, playPaused, queuePushed, queueRemoved, stateSet } from '../.
 import { ActionKeyPressed, Keys } from '../../../../hooks/vim';
 import { CmusUIState, LibraryModeWindow, Overlay, View } from '../types';
 import { handleOrder } from './order';
-import { handleScroll, scrollSongs } from './scroll';
+import { handleScroll } from './scroll';
 import { withGlobalAction } from './utils';
 
 const libraryModeWindows: LibraryModeWindow[] = Object.values(LibraryModeWindow);
@@ -133,7 +133,7 @@ export function handleKeyPress(state: CmusUIState, action: ActionKeyPressed): Cm
         state.library.modeWindow === LibraryModeWindow.SongList &&
         state.library.activeSongId
       ) {
-        return withGlobalAction(scrollSongs(state, 1), queuePushed(state.library.activeSongId));
+        return withGlobalAction(state, queuePushed(state.library.activeSongId));
       }
       return state;
 

+ 7 - 0
gmus-web/src/components/ui/cmus/views/songs.styles.ts

@@ -13,6 +13,13 @@ export const Container = styled(FlexList)`
 
 export const Song = styled(ActiveHighlightRow)``;
 
+export const QueuePosition = styled.span<{ invert?: boolean }>`
+  color: ${({ invert }): string =>
+    invert ? colors.active.parentInactive : colors.title.background};
+  flex: 0 0 ${rem(16)};
+  font-weight: bold;
+`;
+
 export const Separator = styled(ActiveHighlightRow)`
   height: ${rem(26)};
   margin-top: ${rem(6)};

+ 33 - 3
gmus-web/src/components/ui/cmus/views/songs.tsx

@@ -23,6 +23,7 @@ type SongData = {
   active: boolean;
   parentActive: boolean;
   highlight: boolean;
+  queuePosition: number;
 };
 
 type Separator = {
@@ -35,6 +36,29 @@ const isSeparator = (item: ItemData | Separator): item is Separator => !Reflect.
 
 const itemKey = (index: number, data: ItemData[]): number => data[index].id;
 
+const queueSymbols = [
+  '⑴',
+  '⑵',
+  '⑶',
+  '⑷',
+  '⑸',
+  '⑹',
+  '⑺',
+  '⑻',
+  '⑼',
+  '⑽',
+  '⑾',
+  '⑿',
+  '⒀',
+  '⒁',
+  '⒂',
+  '⒃',
+  '⒄',
+  '⒅',
+  '⒆',
+  '⒇',
+];
+
 const Row = namedMemo<{ index: number; data: ItemData[]; style: CSSProperties }>(
   'Song',
   ({ index, data, style }) => {
@@ -46,9 +70,14 @@ const Row = namedMemo<{ index: number; data: ItemData[]; style: CSSProperties }>
         </Styled.Separator>
       );
     }
-    const { song, active, parentActive, highlight } = item;
+    const { song, active, parentActive, highlight, queuePosition } = item;
     return (
       <Styled.Song active={active} parentActive={parentActive} style={style} highlight={highlight}>
+        <Styled.QueuePosition invert={active && !parentActive}>
+          {queuePosition >= 0 && queuePosition < queueSymbols.length
+            ? queueSymbols[queuePosition]
+            : ''}
+        </Styled.QueuePosition>
         <NoWrapFill>
           {song.track ? `${song.track} - ` : ''}
           {song.title || 'Untitled Track'}
@@ -60,7 +89,7 @@ const Row = namedMemo<{ index: number; data: ItemData[]; style: CSSProperties }>
 
 export const Songs: React.FC<Props> = ({ active: parentActive }) => {
   const globalState = useContext(StateContext);
-  const { songId: playingSongId } = globalState.player;
+  const { songId: playingSongId, queue } = globalState.player;
 
   const state = useContext(CmusUIStateContext);
   const { activeArtist, activeAlbum, activeSongId } = state.library;
@@ -74,6 +103,7 @@ export const Songs: React.FC<Props> = ({ active: parentActive }) => {
       active: song.id === activeSongId,
       parentActive,
       highlight: song.id === playingSongId,
+      queuePosition: queue.indexOf(song.id),
     }));
 
     if (activeAlbum !== null) {
@@ -84,7 +114,7 @@ export const Songs: React.FC<Props> = ({ active: parentActive }) => {
       (last, [album, group], index) => [...last, { id: -index, album }, ...group],
       [],
     );
-  }, [parentActive, activeSongId, playingSongId, filteredSongs, activeAlbum]);
+  }, [parentActive, activeSongId, playingSongId, filteredSongs, activeAlbum, queue]);
 
   const getItemSize = useCallback(
     (index: number): number => lineHeight * (isSeparator(itemData[index]) ? 2 : 1),