mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-23 10:07:35 +00:00
149 lines
3.6 KiB
JavaScript
149 lines
3.6 KiB
JavaScript
import { TRACK_HEIGHT } from "../constants";
|
|
import {
|
|
getScrollOffset,
|
|
getOverflowTrackCount,
|
|
getSelectedTrackObjects
|
|
} from "../selectors";
|
|
|
|
import { clamp, sort } from "../utils";
|
|
import {
|
|
REMOVE_TRACKS,
|
|
REMOVE_ALL_TRACKS,
|
|
REVERSE_LIST,
|
|
RANDOMIZE_LIST,
|
|
SET_TRACK_ORDER,
|
|
SET_PLAYLIST_SCROLL_POSITION,
|
|
DRAG_SELECTED
|
|
} from "../actionTypes";
|
|
|
|
export function cropPlaylist() {
|
|
return (dispatch, getState) => {
|
|
const state = getState();
|
|
if (getSelectedTrackObjects(state).length === 0) {
|
|
return;
|
|
}
|
|
const {
|
|
playlist: { tracks }
|
|
} = getState();
|
|
dispatch({
|
|
type: REMOVE_TRACKS,
|
|
ids: Object.keys(tracks).filter(id => !tracks[id].selected)
|
|
});
|
|
};
|
|
}
|
|
|
|
export function removeSelectedTracks() {
|
|
return (dispatch, getState) => {
|
|
const {
|
|
playlist: { tracks }
|
|
} = getState();
|
|
dispatch({
|
|
type: REMOVE_TRACKS,
|
|
ids: Object.keys(tracks).filter(id => tracks[id].selected)
|
|
});
|
|
};
|
|
}
|
|
|
|
export function removeAllTracks() {
|
|
return { 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 trackOrder = sort(state.playlist.trackOrder, i =>
|
|
`${state.playlist.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 = getOverflowTrackCount(state);
|
|
const currentOffset = 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 (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);
|
|
}
|
|
|
|
function findLastIndex(arr, cb) {
|
|
for (let i = arr.length - 1; i >= 0; i--) {
|
|
if (cb(arr[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
export function dragSelected(offset) {
|
|
return (dispatch, getState) => {
|
|
const {
|
|
playlist: { trackOrder, tracks }
|
|
} = getState();
|
|
const firstSelected = trackOrder.findIndex(
|
|
trackId => tracks[trackId] && tracks[trackId].selected
|
|
);
|
|
if (firstSelected === -1) {
|
|
return;
|
|
}
|
|
const lastSelected = findLastIndex(
|
|
trackOrder,
|
|
trackId => tracks[trackId] && tracks[trackId].selected
|
|
);
|
|
if (lastSelected === -1) {
|
|
throw new Error("We found a first selected, but not a last selected.");
|
|
}
|
|
// Ensure we don't try to drag off either end.
|
|
const min = -firstSelected;
|
|
const max = trackOrder.length - 1 - lastSelected;
|
|
const normalizedOffset = clamp(offset, min, max);
|
|
if (normalizedOffset !== 0) {
|
|
dispatch({ type: DRAG_SELECTED, offset: normalizedOffset });
|
|
}
|
|
};
|
|
}
|