mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-29 04:50:14 +00:00
Add infra for dropbox chooser and lazy id3 tags
This commit is contained in:
parent
f429fdcd0b
commit
5836e9f542
6 changed files with 104 additions and 5 deletions
|
|
@ -6,14 +6,20 @@ import {
|
|||
promptForFileReferences
|
||||
} from "./fileUtils";
|
||||
import skinParser from "./skinParser";
|
||||
import { BANDS, TRACK_HEIGHT, LOAD_STYLE } from "./constants";
|
||||
import {
|
||||
BANDS,
|
||||
TRACK_HEIGHT,
|
||||
LOAD_STYLE,
|
||||
MEDIA_TAG_REQUEST_STATUS
|
||||
} from "./constants";
|
||||
import {
|
||||
getEqfData,
|
||||
nextTrack,
|
||||
getScrollOffset,
|
||||
getOverflowTrackCount,
|
||||
getPlaylistURL,
|
||||
getSelectedTrackObjects
|
||||
getSelectedTrackObjects,
|
||||
getVisibleTracks
|
||||
} from "./selectors";
|
||||
|
||||
import {
|
||||
|
|
@ -53,7 +59,9 @@ import {
|
|||
SET_MEDIA_TAGS,
|
||||
SET_MEDIA_DURATION,
|
||||
TOGGLE_SHADE_MODE,
|
||||
TOGGLE_PLAYLIST_SHADE_MODE
|
||||
TOGGLE_PLAYLIST_SHADE_MODE,
|
||||
MEDIA_TAG_REQUEST_INITIALIZED,
|
||||
MEDIA_TAG_REQUEST_FAILED
|
||||
} from "./actionTypes";
|
||||
|
||||
function playRandomTrack() {
|
||||
|
|
@ -311,12 +319,27 @@ export function loadMediaFile(track, priority = null, atIndex = 0) {
|
|||
};
|
||||
}
|
||||
|
||||
export function fetchMediaTagsForVisibleTracks() {
|
||||
return (dispatch, getState) => {
|
||||
getVisibleTracks(getState())
|
||||
.filter(
|
||||
track =>
|
||||
track.mediaTagsRequestStatus ===
|
||||
MEDIA_TAG_REQUEST_STATUS.NOT_REQUESTED
|
||||
)
|
||||
.forEach(track => {
|
||||
dispatch(fetchMediaTags(track.url, track.id));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchMediaTags(file, id) {
|
||||
// Workaround https://github.com/aadsm/jsmediatags/issues/83
|
||||
if (typeof file === "string" && !/^[a-z]+:\/\//i.test(file)) {
|
||||
file = `${location.protocol}//${location.host}${location.pathname}${file}`;
|
||||
}
|
||||
return dispatch => {
|
||||
dispatch({ type: MEDIA_TAG_REQUEST_INITIALIZED, id });
|
||||
try {
|
||||
jsmediatags.read(file, {
|
||||
onSuccess: data => {
|
||||
|
|
@ -326,6 +349,7 @@ export function fetchMediaTags(file, id) {
|
|||
dispatch({ type: SET_MEDIA_TAGS, artist, title, id });
|
||||
},
|
||||
onError: () => {
|
||||
dispatch({ type: MEDIA_TAG_REQUEST_FAILED, id });
|
||||
// Nothing to do. The filename will have to suffice.
|
||||
}
|
||||
});
|
||||
|
|
@ -333,6 +357,7 @@ export function fetchMediaTags(file, id) {
|
|||
// Possibly jsmediatags could not find a parser for this file?
|
||||
// Nothing to do.
|
||||
// Consider removing this after https://github.com/aadsm/jsmediatags/issues/83 is resolved.
|
||||
dispatch({ type: MEDIA_TAG_REQUEST_FAILED, id });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -390,6 +415,35 @@ export function openSkinFileDialog() {
|
|||
return _openFileDialog(".zip, .wsz");
|
||||
}
|
||||
|
||||
// Requires Dropbox's Chooser to be loaded on the page
|
||||
function genAudioFileUrlsFromDropbox() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (window.Dropbox == null) {
|
||||
reject();
|
||||
}
|
||||
window.Dropbox.choose({
|
||||
success: resolve,
|
||||
error: reject,
|
||||
linkType: "direct",
|
||||
folderselect: false,
|
||||
multiselect: true,
|
||||
extensions: ["video", "audio"]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function openDropboxFileDialog() {
|
||||
return async dispatch => {
|
||||
const files = await genAudioFileUrlsFromDropbox();
|
||||
dispatch(
|
||||
loadMediaFiles(
|
||||
files.map(file => ({ url: file.link, defaultName: file.name })),
|
||||
LOAD_STYLE.PLAY
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function setEqBand(band, value) {
|
||||
return { type: SET_BAND_VALUE, band, value };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,3 +60,5 @@ export const SET_MEDIA_TAGS = "SET_MEDIA_TAGS";
|
|||
export const SET_MEDIA_DURATION = "SET_MEDIA_DURATION";
|
||||
export const OPEN_GEN_WINDOW = "OPEN_GEN_WINDOW";
|
||||
export const CLOSE_GEN_WINDOW = "CLOSE_GEN_WINDOW";
|
||||
export const MEDIA_TAG_REQUEST_INITIALIZED = "MEDIA_TAG_REQUEST_INITIALIZED";
|
||||
export const MEDIA_TAG_REQUEST_FAILED = "MEDIA_TAG_REQUEST_FAILED";
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ export const LOAD_STYLE = {
|
|||
PLAY: "PLAY"
|
||||
};
|
||||
|
||||
export const MEDIA_TAG_REQUEST_STATUS = {
|
||||
INITIALIZED: "INITIALIZED",
|
||||
FAILED: "FAILED",
|
||||
COMPLETE: "COMPLETE",
|
||||
NOT_REQUESTED: "NOT_REQUESTED"
|
||||
};
|
||||
|
||||
export const UTF8_ELLIPSIS = "\u2026";
|
||||
export const CHARACTER_WIDTH = 5;
|
||||
export const PLAYLIST_RESIZE_SEGMENT_WIDTH = 25;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,11 @@ import {
|
|||
BUFFER_TRACK,
|
||||
DRAG_SELECTED,
|
||||
SET_MEDIA_TAGS,
|
||||
SET_MEDIA_DURATION
|
||||
SET_MEDIA_DURATION,
|
||||
MEDIA_TAG_REQUEST_INITIALIZED,
|
||||
MEDIA_TAG_REQUEST_FAILED
|
||||
} from "../actionTypes";
|
||||
import { MEDIA_TAG_REQUEST_STATUS } from "../constants";
|
||||
|
||||
import { filenameFromUrl } from "../fileUtils";
|
||||
import { shuffle, moveSelected, mapObject, filterObject } from "../utils";
|
||||
|
|
@ -148,7 +151,8 @@ const playlist = (state = defaultPlaylistState, action) => {
|
|||
selected: false,
|
||||
defaultName: action.defaultName,
|
||||
duration: null,
|
||||
url: action.url
|
||||
url: action.url,
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.NOT_REQUESTED
|
||||
}
|
||||
},
|
||||
// TODO: This could probably be made to work, but we clear it just to be safe.
|
||||
|
|
@ -172,11 +176,34 @@ const playlist = (state = defaultPlaylistState, action) => {
|
|||
...state.tracks,
|
||||
[action.id]: {
|
||||
...state.tracks[action.id],
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.COMPLETE,
|
||||
title: action.title,
|
||||
artist: action.artist
|
||||
}
|
||||
}
|
||||
};
|
||||
case MEDIA_TAG_REQUEST_INITIALIZED:
|
||||
return {
|
||||
...state,
|
||||
tracks: {
|
||||
...state.tracks,
|
||||
[action.id]: {
|
||||
...state.tracks[action.id],
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.INITIALIZED
|
||||
}
|
||||
}
|
||||
};
|
||||
case MEDIA_TAG_REQUEST_FAILED:
|
||||
return {
|
||||
...state,
|
||||
tracks: {
|
||||
...state.tracks,
|
||||
[action.id]: {
|
||||
...state.tracks[action.id],
|
||||
mediaTagsRequestStatus: MEDIA_TAG_REQUEST_STATUS.FAILED
|
||||
}
|
||||
}
|
||||
};
|
||||
case SET_MEDIA_DURATION:
|
||||
return {
|
||||
...state,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ describe("playlist reducer", () => {
|
|||
selected: false,
|
||||
duration: null,
|
||||
defaultName: "My Track Name",
|
||||
mediaTagsRequestStatus: "NOT_REQUESTED",
|
||||
url: "url://some-url"
|
||||
}
|
||||
},
|
||||
|
|
@ -54,6 +55,7 @@ describe("playlist reducer", () => {
|
|||
100: {
|
||||
selected: false,
|
||||
duration: null,
|
||||
mediaTagsRequestStatus: "NOT_REQUESTED",
|
||||
defaultName: "My Track Name",
|
||||
url: "url://some-url"
|
||||
}
|
||||
|
|
@ -85,6 +87,7 @@ describe("playlist reducer", () => {
|
|||
100: {
|
||||
selected: false,
|
||||
duration: null,
|
||||
mediaTagsRequestStatus: "NOT_REQUESTED",
|
||||
defaultName: "My Track Name",
|
||||
url: "url://some-url"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,6 +156,12 @@ export const getVisibleTrackIds = createSelector(
|
|||
trackOrder.slice(offset, offset + numberOfVisibleTracks)
|
||||
);
|
||||
|
||||
export const getVisibleTracks = createSelector(
|
||||
getVisibleTrackIds,
|
||||
getTracks,
|
||||
(visibleTrackIds, tracks) => visibleTrackIds.map(id => tracks[id])
|
||||
);
|
||||
|
||||
export const getPlaylist = state => state.playlist;
|
||||
|
||||
export const getDuration = state => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue