mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 02:15:01 +00:00
Inject lazy dependencies (#639)
Still TODO Find a nice way to expose WebampLazy as: ```JavaScript import WebampLazy from 'webamp/lazy'; ```
This commit is contained in:
parent
6591c98b40
commit
1bdb7d6345
9 changed files with 324 additions and 273 deletions
|
|
@ -7,7 +7,8 @@ module.exports = {
|
|||
node: {
|
||||
// Consider suggesting jsmediatags use: https://github.com/feross/is-buffer
|
||||
// Cuts 22k
|
||||
Buffer: false
|
||||
Buffer: false,
|
||||
fs: "empty"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
|
@ -64,7 +65,9 @@ module.exports = {
|
|||
],
|
||||
entry: {
|
||||
bundle: "./js/webamp.js",
|
||||
"bundle.min": "./js/webamp.js"
|
||||
"bundle.min": "./js/webamp.js",
|
||||
"lazy-bundle": "./js/webampLazy.js",
|
||||
"lazy-bundle.min": "./js/webampLazy.js"
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, "../built"),
|
||||
|
|
|
|||
|
|
@ -80,10 +80,23 @@ export function loadFilesFromReferences(
|
|||
}
|
||||
|
||||
export function setSkinFromArrayBuffer(arrayBuffer) {
|
||||
return async dispatch => {
|
||||
return async (dispatch, getState, { requireJSZip }) => {
|
||||
if (!requireJSZip) {
|
||||
alert("Webamp has not been configured to support custom skins.");
|
||||
return;
|
||||
}
|
||||
dispatch({ type: LOADING });
|
||||
let JSZip;
|
||||
try {
|
||||
const skinData = await skinParser(arrayBuffer);
|
||||
JSZip = await requireJSZip();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
dispatch({ type: LOADED });
|
||||
alert("Failed to load the skin parser.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const skinData = await skinParser(arrayBuffer, JSZip);
|
||||
dispatch({
|
||||
type: SET_SKIN_DATA,
|
||||
skinImages: skinData.images,
|
||||
|
|
@ -250,10 +263,10 @@ function queueFetchingMediaTags(id) {
|
|||
}
|
||||
|
||||
export function fetchMediaTags(file, id) {
|
||||
return async dispatch => {
|
||||
return async (dispatch, getState, { requireJSMediaTags }) => {
|
||||
dispatch({ type: MEDIA_TAG_REQUEST_INITIALIZED, id });
|
||||
try {
|
||||
const data = await genMediaTags(file);
|
||||
const data = await genMediaTags(file, await requireJSMediaTags());
|
||||
// There's more data here, but we don't have a use for it yet:
|
||||
// https://github.com/aadsm/jsmediatags#shortcuts
|
||||
const { artist, title, picture } = data.tags;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import invariant from "invariant";
|
||||
|
||||
export function genMediaTags(file) {
|
||||
export function genMediaTags(file, jsmediatags) {
|
||||
invariant(
|
||||
file != null,
|
||||
"Attempted to get the tags of media file without passing a file"
|
||||
|
|
@ -9,26 +9,22 @@ export function genMediaTags(file) {
|
|||
if (typeof file === "string" && !/^[a-z]+:\/\//i.test(file)) {
|
||||
file = `${location.protocol}//${location.host}${location.pathname}${file}`;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
require.ensure(
|
||||
["jsmediatags/dist/jsmediatags"],
|
||||
require => {
|
||||
const jsmediatags = require("jsmediatags/dist/jsmediatags");
|
||||
try {
|
||||
jsmediatags.read(file, { onSuccess: resolve, onError: reject });
|
||||
} catch (e) {
|
||||
// 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.
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
// The dependency failed to load
|
||||
},
|
||||
"jsmediatags"
|
||||
);
|
||||
});
|
||||
return new Promise(
|
||||
(resolve, reject) => {
|
||||
try {
|
||||
jsmediatags.read(file, { onSuccess: resolve, onError: reject });
|
||||
} catch (e) {
|
||||
// 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.
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
// The dependency failed to load
|
||||
},
|
||||
"jsmediatags"
|
||||
);
|
||||
}
|
||||
|
||||
export function genMediaDuration(url) {
|
||||
|
|
|
|||
40
js/index.js
40
js/index.js
|
|
@ -12,7 +12,7 @@ import zaxon from "../skins/ZaxonRemake1-0.wsz";
|
|||
import green from "../skins/Green-Dimension-V2.wsz";
|
||||
import MilkdropWindow from "./components/MilkdropWindow";
|
||||
import screenshotInitialState from "./screenshotInitialState";
|
||||
import Webamp from "./webamp";
|
||||
import WebampLazy from "./webampLazy";
|
||||
import {
|
||||
STEP_MARQUEE,
|
||||
UPDATE_TIME_ELAPSED,
|
||||
|
|
@ -34,6 +34,38 @@ import {
|
|||
disableMarquee
|
||||
} from "./config";
|
||||
|
||||
const requireJSZip = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
require.ensure(
|
||||
["jszip/dist/jszip"],
|
||||
require => {
|
||||
resolve(require("jszip/dist/jszip"));
|
||||
},
|
||||
e => {
|
||||
console.error("Error loading JSZip", e);
|
||||
reject(e);
|
||||
},
|
||||
"jszip"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const requireJSMediaTags = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
require.ensure(
|
||||
["jsmediatags/dist/jsmediatags"],
|
||||
require => {
|
||||
resolve(require("jsmediatags/dist/jsmediatags"));
|
||||
},
|
||||
e => {
|
||||
console.error("Error loading jsmediatags", e);
|
||||
reject(e);
|
||||
},
|
||||
"jsmediatags"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const NOISY_ACTION_TYPES = new Set([
|
||||
STEP_MARQUEE,
|
||||
UPDATE_TIME_ELAPSED,
|
||||
|
|
@ -122,7 +154,7 @@ Raven.context(() => {
|
|||
if (screenshot) {
|
||||
document.getElementsByClassName("about")[0].style.visibility = "hidden";
|
||||
}
|
||||
if (!Webamp.browserIsSupported()) {
|
||||
if (!WebampLazy.browserIsSupported()) {
|
||||
document.getElementById("browser-compatibility").style.display = "block";
|
||||
document.getElementById("app").style.visibility = "hidden";
|
||||
return;
|
||||
|
|
@ -165,7 +197,7 @@ Raven.context(() => {
|
|||
|
||||
const initialSkin = !skinUrl ? null : { url: skinUrl };
|
||||
|
||||
const webamp = new Webamp({
|
||||
const webamp = new WebampLazy({
|
||||
initialSkin,
|
||||
initialTracks: screenshot ? null : initialTracks,
|
||||
availableSkins: [
|
||||
|
|
@ -191,6 +223,8 @@ Raven.context(() => {
|
|||
}
|
||||
],
|
||||
enableHotkeys: true,
|
||||
requireJSZip,
|
||||
requireJSMediaTags,
|
||||
__extraWindows,
|
||||
__initialWindowLayout,
|
||||
__initialState: screenshot ? screenshotInitialState : initialState,
|
||||
|
|
|
|||
|
|
@ -3,21 +3,6 @@ import regionParser from "./regionParser";
|
|||
import { LETTERS, DEFAULT_SKIN } from "./constants";
|
||||
import { parseViscolors, parseIni, getFileExtension } from "./utils";
|
||||
|
||||
const getJSZip = () => {
|
||||
return new Promise(resolve => {
|
||||
require.ensure(
|
||||
["jszip/dist/jszip"],
|
||||
require => {
|
||||
resolve(require("jszip/dist/jszip"));
|
||||
},
|
||||
e => {
|
||||
console.error("Error loading JSZip", e);
|
||||
},
|
||||
"jszip"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const shallowMerge = objs =>
|
||||
objs.reduce((prev, img) => Object.assign(prev, img), {});
|
||||
|
||||
|
|
@ -249,8 +234,7 @@ async function genGenTextSprites(zip) {
|
|||
}
|
||||
|
||||
// A promise that, given an array buffer returns a skin style object
|
||||
async function skinParser(zipFileBuffer) {
|
||||
const JSZip = await getJSZip();
|
||||
async function skinParser(zipFileBuffer, JSZip) {
|
||||
const zip = await JSZip.loadAsync(zipFileBuffer);
|
||||
const [
|
||||
colors,
|
||||
|
|
|
|||
13
js/store.js
13
js/store.js
|
|
@ -10,12 +10,13 @@ const compose = composeWithDevTools({
|
|||
actionsBlacklist: [UPDATE_TIME_ELAPSED, STEP_MARQUEE]
|
||||
});
|
||||
|
||||
const getStore = (
|
||||
export default function(
|
||||
media,
|
||||
actionEmitter,
|
||||
customMiddlewares = [],
|
||||
stateOverrides
|
||||
) => {
|
||||
stateOverrides,
|
||||
extras
|
||||
) {
|
||||
let initialState;
|
||||
if (stateOverrides) {
|
||||
initialState = merge(
|
||||
|
|
@ -36,7 +37,7 @@ const getStore = (
|
|||
compose(
|
||||
applyMiddleware(
|
||||
...[
|
||||
thunk,
|
||||
thunk.withExtraArgument(extras),
|
||||
mediaMiddleware(media),
|
||||
emitterMiddleware,
|
||||
...customMiddlewares
|
||||
|
|
@ -44,6 +45,4 @@ const getStore = (
|
|||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default getStore;
|
||||
}
|
||||
|
|
|
|||
226
js/webamp.js
226
js/webamp.js
|
|
@ -1,224 +1,14 @@
|
|||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { Provider } from "react-redux";
|
||||
|
||||
import getStore from "./store";
|
||||
import App from "./components/App";
|
||||
import Hotkeys from "./hotkeys";
|
||||
import Media from "./media";
|
||||
import { getTrackCount, getTracks } from "./selectors";
|
||||
import {
|
||||
setSkinFromUrl,
|
||||
loadMediaFiles,
|
||||
setWindowSize,
|
||||
loadFilesFromReferences
|
||||
} from "./actionCreators";
|
||||
import { LOAD_STYLE } from "./constants";
|
||||
import { uniqueId, objectMap, objectForEach } from "./utils";
|
||||
|
||||
import {
|
||||
SET_AVAILABLE_SKINS,
|
||||
NETWORK_CONNECTED,
|
||||
NETWORK_DISCONNECTED,
|
||||
CLOSE_WINAMP,
|
||||
MINIMIZE_WINAMP,
|
||||
ADD_GEN_WINDOW,
|
||||
UPDATE_WINDOW_POSITIONS,
|
||||
LOADED,
|
||||
REGISTER_VISUALIZER,
|
||||
SET_Z_INDEX,
|
||||
SET_MEDIA
|
||||
} from "./actionTypes";
|
||||
import Emitter from "./emitter";
|
||||
|
||||
import "../css/base-skin.min.css";
|
||||
|
||||
// Return a promise that resolves when the store matches a predicate.
|
||||
const storeHas = (store, predicate) =>
|
||||
new Promise(resolve => {
|
||||
if (predicate(store.getState())) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const unsubscribe = store.subscribe(() => {
|
||||
if (predicate(store.getState())) {
|
||||
resolve();
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
class Winamp {
|
||||
static browserIsSupported() {
|
||||
const supportsAudioApi = !!(
|
||||
window.AudioContext || window.webkitAudioContext
|
||||
);
|
||||
const supportsCanvas = !!window.document.createElement("canvas").getContext;
|
||||
const supportsPromises = typeof Promise !== "undefined";
|
||||
return supportsAudioApi && supportsCanvas && supportsPromises;
|
||||
}
|
||||
import JSZip from "jszip";
|
||||
import jsmediatags from "jsmediatags";
|
||||
import WebampLazy from "./webampLazy";
|
||||
|
||||
class Winamp extends WebampLazy {
|
||||
constructor(options) {
|
||||
this._actionEmitter = new Emitter();
|
||||
this.options = options;
|
||||
const {
|
||||
initialTracks,
|
||||
initialSkin,
|
||||
avaliableSkins, // Old misspelled name
|
||||
availableSkins,
|
||||
enableHotkeys = false,
|
||||
zIndex,
|
||||
__extraWindows
|
||||
} = this.options;
|
||||
|
||||
this.media = new Media();
|
||||
this.store = getStore(
|
||||
this.media,
|
||||
this._actionEmitter,
|
||||
this.options.__customMiddlewares,
|
||||
this.options.__initialState
|
||||
);
|
||||
this.store.dispatch({
|
||||
type: navigator.onLine ? NETWORK_CONNECTED : NETWORK_DISCONNECTED
|
||||
super({
|
||||
...options,
|
||||
requireJSZip: () => JSZip,
|
||||
requireJSMediaTags: () => jsmediatags
|
||||
});
|
||||
|
||||
if (true) {
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.id = "webamp-file-input";
|
||||
fileInput.style.display = "none";
|
||||
fileInput.type = "file";
|
||||
fileInput.value = null;
|
||||
fileInput.addEventListener("change", e => {
|
||||
this.store.dispatch(loadFilesFromReferences(e.target.files));
|
||||
});
|
||||
document.body.appendChild(fileInput);
|
||||
}
|
||||
|
||||
if (zIndex != null) {
|
||||
this.store.dispatch({ type: SET_Z_INDEX, zIndex });
|
||||
}
|
||||
|
||||
this.genWindows = [];
|
||||
if (__extraWindows) {
|
||||
this.genWindows = __extraWindows.map(genWindow => ({
|
||||
id: genWindow.id || `${genWindow.title}-${uniqueId()}`,
|
||||
...genWindow
|
||||
}));
|
||||
|
||||
__extraWindows.forEach(genWindow => {
|
||||
if (genWindow.isVisualizer) {
|
||||
this.store.dispatch({ type: REGISTER_VISUALIZER, id: genWindow.id });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.genWindows.forEach(genWindow => {
|
||||
this.store.dispatch({
|
||||
type: ADD_GEN_WINDOW,
|
||||
windowId: genWindow.id,
|
||||
title: genWindow.title,
|
||||
open: genWindow.open
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener("online", () =>
|
||||
this.store.dispatch({ type: NETWORK_CONNECTED })
|
||||
);
|
||||
window.addEventListener("offline", () =>
|
||||
this.store.dispatch({ type: NETWORK_DISCONNECTED })
|
||||
);
|
||||
|
||||
if (initialSkin) {
|
||||
this.store.dispatch(setSkinFromUrl(initialSkin.url));
|
||||
} else {
|
||||
// We are using the default skin.
|
||||
this.store.dispatch({ type: LOADED });
|
||||
}
|
||||
|
||||
if (initialTracks) {
|
||||
this.appendTracks(initialTracks);
|
||||
}
|
||||
|
||||
if (avaliableSkins != null) {
|
||||
console.warn(
|
||||
"The misspelled option `avaliableSkins` is deprecated. Please use `availableSkins` instead."
|
||||
);
|
||||
this.store.dispatch({ type: SET_AVAILABLE_SKINS, skins: avaliableSkins });
|
||||
} else if (availableSkins != null) {
|
||||
this.store.dispatch({ type: SET_AVAILABLE_SKINS, skins: availableSkins });
|
||||
}
|
||||
|
||||
const layout = options.__initialWindowLayout;
|
||||
if (layout != null) {
|
||||
objectForEach(layout, (w, windowId) => {
|
||||
if (w.size != null) {
|
||||
this.store.dispatch(setWindowSize(windowId, w.size));
|
||||
}
|
||||
});
|
||||
this.store.dispatch({
|
||||
type: UPDATE_WINDOW_POSITIONS,
|
||||
positions: objectMap(layout, w => w.position)
|
||||
});
|
||||
}
|
||||
|
||||
if (enableHotkeys) {
|
||||
new Hotkeys(this.store.dispatch);
|
||||
}
|
||||
}
|
||||
|
||||
// Append this array of tracks to the end of the current playlist.
|
||||
appendTracks(tracks) {
|
||||
const nextIndex = getTrackCount(this.store.getState());
|
||||
this.store.dispatch(loadMediaFiles(tracks, LOAD_STYLE.BUFFER, nextIndex));
|
||||
}
|
||||
|
||||
// Replace any existing tracks with this array of tracks, and begin playing.
|
||||
setTracksToPlay(tracks) {
|
||||
this.store.dispatch(loadMediaFiles(tracks, LOAD_STYLE.PLAY));
|
||||
}
|
||||
|
||||
onClose(cb) {
|
||||
return this._actionEmitter.on(CLOSE_WINAMP, cb);
|
||||
}
|
||||
|
||||
onTrackDidChange(cb) {
|
||||
return this._actionEmitter.on(SET_MEDIA, action => {
|
||||
const tracks = getTracks(this.store.getState());
|
||||
const track = tracks[action.id];
|
||||
if (track == null) {
|
||||
return;
|
||||
}
|
||||
cb({ url: track.url });
|
||||
});
|
||||
}
|
||||
|
||||
onMinimize(cb) {
|
||||
return this._actionEmitter.on(MINIMIZE_WINAMP, cb);
|
||||
}
|
||||
|
||||
async skinIsLoaded() {
|
||||
// Wait for the skin to load.
|
||||
return storeHas(this.store, state => !state.display.loading);
|
||||
}
|
||||
|
||||
async renderWhenReady(node) {
|
||||
await this.skinIsLoaded();
|
||||
const genWindowComponents = {};
|
||||
this.genWindows.forEach(w => {
|
||||
genWindowComponents[w.id] = w.Component;
|
||||
});
|
||||
|
||||
render(
|
||||
<Provider store={this.store}>
|
||||
<App
|
||||
media={this.media}
|
||||
container={node}
|
||||
filePickers={this.options.filePickers}
|
||||
genWindowComponents={genWindowComponents}
|
||||
/>
|
||||
</Provider>,
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
231
js/webampLazy.js
Normal file
231
js/webampLazy.js
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { Provider } from "react-redux";
|
||||
|
||||
import getStore from "./store";
|
||||
import App from "./components/App";
|
||||
import Hotkeys from "./hotkeys";
|
||||
import Media from "./media";
|
||||
import { getTrackCount, getTracks } from "./selectors";
|
||||
import {
|
||||
setSkinFromUrl,
|
||||
loadMediaFiles,
|
||||
setWindowSize,
|
||||
loadFilesFromReferences
|
||||
} from "./actionCreators";
|
||||
import { LOAD_STYLE } from "./constants";
|
||||
import { uniqueId, objectMap, objectForEach } from "./utils";
|
||||
|
||||
import {
|
||||
SET_AVAILABLE_SKINS,
|
||||
NETWORK_CONNECTED,
|
||||
NETWORK_DISCONNECTED,
|
||||
CLOSE_WINAMP,
|
||||
MINIMIZE_WINAMP,
|
||||
ADD_GEN_WINDOW,
|
||||
UPDATE_WINDOW_POSITIONS,
|
||||
LOADED,
|
||||
REGISTER_VISUALIZER,
|
||||
SET_Z_INDEX,
|
||||
SET_MEDIA
|
||||
} from "./actionTypes";
|
||||
import Emitter from "./emitter";
|
||||
|
||||
import "../css/base-skin.min.css";
|
||||
|
||||
// Return a promise that resolves when the store matches a predicate.
|
||||
const storeHas = (store, predicate) =>
|
||||
new Promise(resolve => {
|
||||
if (predicate(store.getState())) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const unsubscribe = store.subscribe(() => {
|
||||
if (predicate(store.getState())) {
|
||||
resolve();
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
class Winamp {
|
||||
static browserIsSupported() {
|
||||
const supportsAudioApi = !!(
|
||||
window.AudioContext || window.webkitAudioContext
|
||||
);
|
||||
const supportsCanvas = !!window.document.createElement("canvas").getContext;
|
||||
const supportsPromises = typeof Promise !== "undefined";
|
||||
return supportsAudioApi && supportsCanvas && supportsPromises;
|
||||
}
|
||||
|
||||
constructor(options) {
|
||||
this._actionEmitter = new Emitter();
|
||||
this.options = options;
|
||||
const {
|
||||
initialTracks,
|
||||
initialSkin,
|
||||
avaliableSkins, // Old misspelled name
|
||||
availableSkins,
|
||||
enableHotkeys = false,
|
||||
zIndex,
|
||||
requireJSZip,
|
||||
requireJSMediaTags,
|
||||
__extraWindows
|
||||
} = this.options;
|
||||
|
||||
// TODO: Validate required options
|
||||
|
||||
this.media = new Media();
|
||||
this.store = getStore(
|
||||
this.media,
|
||||
this._actionEmitter,
|
||||
this.options.__customMiddlewares,
|
||||
this.options.__initialState,
|
||||
{ requireJSZip, requireJSMediaTags }
|
||||
);
|
||||
this.store.dispatch({
|
||||
type: navigator.onLine ? NETWORK_CONNECTED : NETWORK_DISCONNECTED
|
||||
});
|
||||
|
||||
if (true) {
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.id = "webamp-file-input";
|
||||
fileInput.style.display = "none";
|
||||
fileInput.type = "file";
|
||||
fileInput.value = null;
|
||||
fileInput.addEventListener("change", e => {
|
||||
this.store.dispatch(loadFilesFromReferences(e.target.files));
|
||||
});
|
||||
document.body.appendChild(fileInput);
|
||||
}
|
||||
|
||||
if (zIndex != null) {
|
||||
this.store.dispatch({ type: SET_Z_INDEX, zIndex });
|
||||
}
|
||||
|
||||
this.genWindows = [];
|
||||
if (__extraWindows) {
|
||||
this.genWindows = __extraWindows.map(genWindow => ({
|
||||
id: genWindow.id || `${genWindow.title}-${uniqueId()}`,
|
||||
...genWindow
|
||||
}));
|
||||
|
||||
__extraWindows.forEach(genWindow => {
|
||||
if (genWindow.isVisualizer) {
|
||||
this.store.dispatch({ type: REGISTER_VISUALIZER, id: genWindow.id });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.genWindows.forEach(genWindow => {
|
||||
this.store.dispatch({
|
||||
type: ADD_GEN_WINDOW,
|
||||
windowId: genWindow.id,
|
||||
title: genWindow.title,
|
||||
open: genWindow.open
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener("online", () =>
|
||||
this.store.dispatch({ type: NETWORK_CONNECTED })
|
||||
);
|
||||
window.addEventListener("offline", () =>
|
||||
this.store.dispatch({ type: NETWORK_DISCONNECTED })
|
||||
);
|
||||
|
||||
if (initialSkin) {
|
||||
this.store.dispatch(setSkinFromUrl(initialSkin.url));
|
||||
} else {
|
||||
// We are using the default skin.
|
||||
this.store.dispatch({ type: LOADED });
|
||||
}
|
||||
|
||||
if (initialTracks) {
|
||||
this.appendTracks(initialTracks);
|
||||
}
|
||||
|
||||
if (avaliableSkins != null) {
|
||||
console.warn(
|
||||
"The misspelled option `avaliableSkins` is deprecated. Please use `availableSkins` instead."
|
||||
);
|
||||
this.store.dispatch({ type: SET_AVAILABLE_SKINS, skins: avaliableSkins });
|
||||
} else if (availableSkins != null) {
|
||||
this.store.dispatch({ type: SET_AVAILABLE_SKINS, skins: availableSkins });
|
||||
}
|
||||
|
||||
const layout = options.__initialWindowLayout;
|
||||
if (layout != null) {
|
||||
objectForEach(layout, (w, windowId) => {
|
||||
if (w.size != null) {
|
||||
this.store.dispatch(setWindowSize(windowId, w.size));
|
||||
}
|
||||
});
|
||||
this.store.dispatch({
|
||||
type: UPDATE_WINDOW_POSITIONS,
|
||||
positions: objectMap(layout, w => w.position)
|
||||
});
|
||||
}
|
||||
|
||||
if (enableHotkeys) {
|
||||
new Hotkeys(this.store.dispatch);
|
||||
}
|
||||
}
|
||||
|
||||
// Append this array of tracks to the end of the current playlist.
|
||||
appendTracks(tracks) {
|
||||
const nextIndex = getTrackCount(this.store.getState());
|
||||
this.store.dispatch(loadMediaFiles(tracks, LOAD_STYLE.BUFFER, nextIndex));
|
||||
}
|
||||
|
||||
// Replace any existing tracks with this array of tracks, and begin playing.
|
||||
setTracksToPlay(tracks) {
|
||||
this.store.dispatch(loadMediaFiles(tracks, LOAD_STYLE.PLAY));
|
||||
}
|
||||
|
||||
onClose(cb) {
|
||||
return this._actionEmitter.on(CLOSE_WINAMP, cb);
|
||||
}
|
||||
|
||||
onTrackDidChange(cb) {
|
||||
return this._actionEmitter.on(SET_MEDIA, action => {
|
||||
const tracks = getTracks(this.store.getState());
|
||||
const track = tracks[action.id];
|
||||
if (track == null) {
|
||||
return;
|
||||
}
|
||||
cb({ url: track.url });
|
||||
});
|
||||
}
|
||||
|
||||
onMinimize(cb) {
|
||||
return this._actionEmitter.on(MINIMIZE_WINAMP, cb);
|
||||
}
|
||||
|
||||
async skinIsLoaded() {
|
||||
// Wait for the skin to load.
|
||||
return storeHas(this.store, state => !state.display.loading);
|
||||
}
|
||||
|
||||
async renderWhenReady(node) {
|
||||
await this.skinIsLoaded();
|
||||
const genWindowComponents = {};
|
||||
this.genWindows.forEach(w => {
|
||||
genWindowComponents[w.id] = w.Component;
|
||||
});
|
||||
|
||||
render(
|
||||
<Provider store={this.store}>
|
||||
<App
|
||||
media={this.media}
|
||||
container={node}
|
||||
filePickers={this.options.filePickers}
|
||||
genWindowComponents={genWindowComponents}
|
||||
/>
|
||||
</Provider>,
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Winamp;
|
||||
module.exports = Winamp;
|
||||
|
|
@ -6,7 +6,8 @@
|
|||
"files": [
|
||||
"built/webamp.bundle.js",
|
||||
"built/webamp.bundle.min.js",
|
||||
"index.d.ts"
|
||||
"built/webamp-lazy.bundle.js",
|
||||
"built/webamp-lazy.bundle.min.js"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue