import { TRACK_HEIGHT } from "../constants" ; import * as Selectors from "../selectors" ; import { clamp , sort , findLastIndex } from "../utils" ; import { STOP , REMOVE_TRACKS , REMOVE_ALL_TRACKS , REVERSE_LIST , RANDOMIZE_LIST , SET_TRACK_ORDER , SET_PLAYLIST_SCROLL_POSITION , DRAG_SELECTED , SELECT_ALL , SELECT_ZERO , INVERT_SELECTION , } from "../actionTypes" ; import { Thunk , Action } from "../types" ; export function cropPlaylist ( ) { return ( dispatch , getState ) => { const state = getState ( ) ; if ( Selectors . getSelectedTrackObjects ( state ) . length === 0 ) { return ; } const selectedTrackIds = Selectors . getSelectedTrackIds ( state ) ; const { playlist : { trackOrder } , } = state ; dispatch ( { type : REMOVE_TRACKS , ids : trackOrder . filter ( ( id ) => ! selectedTrackIds . has ( id ) ) , } ) ; } ; } export function removeSelectedTracks ( ) { return ( dispatch , getState ) => { dispatch ( { type : REMOVE_TRACKS , ids : Array . from ( Selectors . getSelectedTrackIds ( getState ( ) ) ) , } ) ; } ; } export function removeAllTracks ( ) { return ( dispatch ) => { dispatch ( { type : STOP } ) ; dispatch ( { type : REMOVE_ALL_TRACKS } ) ; } ; } export function reverseList ( ) { return { type : REVERSE_LIST } ; } export function randomizeList ( ) { return { type : RANDOMIZE_LIST } ; } export function sortListByTitle ( ) { return ( dispatch , getState ) => { const state = getState ( ) ; const tracks = Selectors . getTracks ( state ) ; const trackOrder = sort ( Selectors . getTrackOrder ( state ) , ( i ) => `${ tracks [ i ] . title }` . toLowerCase ( ) ) ; return dispatch ( { type : SET_TRACK_ORDER , trackOrder } ) ; } ; } export function setPlaylistScrollPosition ( position ) { return { type : SET_PLAYLIST_SCROLL_POSITION , position } ; } export function scrollNTracks ( n ) { return ( dispatch , getState ) => { const state = getState ( ) ; const overflow = Selectors . getOverflowTrackCount ( state ) ; const currentOffset = Selectors . getScrollOffset ( state ) ; const position = overflow ? clamp ( ( currentOffset + n ) / overflow , 0 , 1 ) : 0 ; return dispatch ( { type : SET_PLAYLIST_SCROLL_POSITION , position : position * 100 , } ) ; } ; } export function scrollPlaylistByDelta ( e ) { e . preventDefault ( ) ; return ( dispatch , getState ) => { const state = getState ( ) ; if ( Selectors . getOverflowTrackCount ( state ) ) { e . stopPropagation ( ) ; } const totalPixelHeight = state . playlist . trackOrder . length * TRACK_HEIGHT ; const percentDelta = ( e . deltaY / totalPixelHeight ) * 100 ; dispatch ( { type : SET_PLAYLIST_SCROLL_POSITION , position : clamp ( state . display . playlistScrollPosition + percentDelta , 0 , 100 ) , } ) ; } ; } export function scrollUpFourTracks ( ) { return scrollNTracks ( - 4 ) ; } export function scrollDownFourTracks ( ) { return scrollNTracks ( 4 ) ; } export function dragSelected ( offset ) { return ( dispatch , getState ) => { const state = getState ( ) ; const tracks = Selectors . getTracks ( state ) ; const trackOrder = Selectors . getTrackOrder ( state ) ; const selectedIds = Selectors . getSelectedTrackIds ( state ) ; const firstSelected = trackOrder . findIndex ( ( trackId ) => tracks [ trackId ] && selectedIds . has ( trackId ) ) ; if ( firstSelected === - 1 ) { return ; } const lastSelected = findLastIndex ( trackOrder , ( trackId ) => tracks [ trackId ] && selectedIds . has ( trackId ) ) ; if ( lastSelected === - 1 ) { throw new Error ( "We found a first selected, but not a last selected." ) ; } const min = - firstSelected ; const max = trackOrder . length - 1 - lastSelected ; const normalizedOffset = clamp ( offset , min , max ) ; if ( normalizedOffset !== 0 ) { dispatch ( { type : DRAG_SELECTED , offset : normalizedOffset } ) ; } } ; } export function invertSelection ( ) { return { type : INVERT_SELECTION } ; } export function selectZero ( ) { return { type : SELECT_ZERO } ; } export function selectAll ( ) { return { type : SELECT_ALL } ; }