Support dragging files in at a given location in the playlist

This commit is contained in:
Jordan Eldredge 2018-01-01 14:27:24 -08:00
parent 8a8b1e991b
commit b053a83e9e
4 changed files with 105 additions and 12 deletions

View file

@ -171,13 +171,13 @@ function setEqFromFile(file) {
};
}
function addTracksFromReferences(fileReferences) {
function addTracksFromReferences(fileReferences, atIndex) {
return dispatch => {
Array.from(fileReferences).forEach((file, i) => {
const priority = i === 0 ? "PLAY" : "NONE";
const id = uniqueId();
const url = URL.createObjectURL(file);
dispatch(_addTrackFromUrl(url, file.name, id, priority));
dispatch(_addTrackFromUrl(url, file.name, id, priority, atIndex + i));
dispatch(fetchMediaTags(file, id));
});
};
@ -185,7 +185,7 @@ function addTracksFromReferences(fileReferences) {
const SKIN_FILENAME_MATCHER = new RegExp("(wsz|zip)$", "i");
const EQF_FILENAME_MATCHER = new RegExp("eqf$", "i");
export function loadFilesFromReferences(fileReferences) {
export function loadFilesFromReferences(fileReferences, atIndex = null) {
return dispatch => {
if (fileReferences.length < 1) {
return;
@ -201,7 +201,7 @@ export function loadFilesFromReferences(fileReferences) {
return;
}
}
dispatch(addTracksFromReferences(fileReferences));
dispatch(addTracksFromReferences(fileReferences, atIndex));
};
}
@ -225,9 +225,9 @@ function uniqueId() {
return counter++;
}
export function _addTrackFromUrl(url, name, id, priority) {
function _addTrackFromUrl(url, name, id, priority, atIndex) {
return dispatch => {
dispatch({ type: ADD_TRACK_FROM_URL, url, name, id });
dispatch({ type: ADD_TRACK_FROM_URL, url, name, id, atIndex });
switch (priority) {
case "BUFFER":
dispatch({ type: BUFFER_TRACK, name, id });

View file

@ -51,12 +51,12 @@ class PlaylistWindow extends React.Component {
_handleDrop(e, targetCoords) {
const top = e.clientY - targetCoords.y;
/*const startIndex = */ clamp(
(top - 23) % TRACK_HEIGHT,
const atIndex = clamp(
Math.round((top - 23) / TRACK_HEIGHT),
0,
this.props.maxTrackIndex
this.props.maxTrackIndex + 1
);
this.props.loadFilesFromReferences(e /*, startIndex*/);
this.props.loadFilesFromReferences(e, atIndex);
}
render() {

View file

@ -132,9 +132,15 @@ const playlist = (state = defaultPlaylistState, action) => {
const { trackOrder } = action;
return { ...state, trackOrder };
case ADD_TRACK_FROM_URL:
const atIndex =
action.atIndex == null ? state.trackOrder.length : action.atIndex;
return {
...state,
trackOrder: [...state.trackOrder, Number(action.id)],
trackOrder: [
...state.trackOrder.slice(0, atIndex),
Number(action.id),
...state.trackOrder.slice(atIndex)
],
tracks: {
...state.tracks,
[action.id]: {

View file

@ -1,11 +1,98 @@
import {
SHIFT_CLICKED_TRACK,
CLICKED_TRACK,
CTRL_CLICKED_TRACK
CTRL_CLICKED_TRACK,
ADD_TRACK_FROM_URL
} from "../actionTypes";
import reducer from "./playlist";
describe("playlist reducer", () => {
it("can handle adding a track", () => {
const initialState = {
tracks: {},
trackOrder: [],
lastSelectedIndex: null
};
const nextState = reducer(initialState, {
type: ADD_TRACK_FROM_URL,
id: 100,
name: "My Track Name",
url: "url://some-url"
});
expect(nextState).toEqual({
tracks: {
100: {
selected: false,
duration: null,
title: "My Track Name",
url: "url://some-url"
}
},
trackOrder: [100],
lastSelectedIndex: null
});
});
it("defaults to adding new tracks to the end of the list", () => {
const initialState = {
tracks: {
2: { selected: false },
3: { selected: false }
},
trackOrder: [3, 2],
lastSelectedIndex: 0
};
const nextState = reducer(initialState, {
type: ADD_TRACK_FROM_URL,
id: 100,
name: "My Track Name",
url: "url://some-url"
});
expect(nextState).toEqual({
tracks: {
2: { selected: false },
3: { selected: false },
100: {
selected: false,
duration: null,
title: "My Track Name",
url: "url://some-url"
}
},
trackOrder: [3, 2, 100],
lastSelectedIndex: null
});
});
it("can handle adding a track at a given index", () => {
const initialState = {
tracks: {
2: { selected: false },
3: { selected: false }
},
trackOrder: [3, 2],
lastSelectedIndex: 0
};
const nextState = reducer(initialState, {
type: ADD_TRACK_FROM_URL,
id: 100,
name: "My Track Name",
url: "url://some-url",
atIndex: 1
});
expect(nextState).toEqual({
tracks: {
2: { selected: false },
3: { selected: false },
100: {
selected: false,
duration: null,
title: "My Track Name",
url: "url://some-url"
}
},
trackOrder: [3, 100, 2],
lastSelectedIndex: null
});
});
it("can handle clicking a track", () => {
const initialState = {
tracks: {