From f037498e9ecd18a559250a0511b4f8b3086fa5ec Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Mon, 9 Oct 2017 20:54:14 -0700 Subject: [PATCH] Add entry point --- README.md | 44 +++++++++++++++++++++ js/actionTypes.js | 1 + js/components/MainWindow/MainContextMenu.js | 25 ++++-------- js/config.js | 2 +- js/index.js | 28 ++++++++++++- js/reducers.js | 17 +++++++- js/winamp.js | 29 ++++++++++---- library.html | 27 +++++++++++++ package.json | 6 ++- webpack.config.js | 9 ----- webpack.library.config.js | 39 ++++++++++++++++++ 11 files changed, 187 insertions(+), 40 deletions(-) create mode 100755 library.html create mode 100644 webpack.library.config.js diff --git a/README.md b/README.md index 74367e68..25ca817c 100755 --- a/README.md +++ b/README.md @@ -24,6 +24,50 @@ supported](http://caniuse.com/#feat=audio-api). A more detailed list of features can be found in [features.md](./features.md). +## Use Winamp2-js in your project **PRE ALPHA** + +Several people have expressed interest in including Winamp2-js inside their website. In an attempt to try this out, I have published Winamp2-js as an NPM package. You can attempt to use it in your JS project like so: + +Install the package: + +``` +npm install --save winamp2-js +npm install --save babel-polyfill +``` + +Create a DOM element somewhere in your HTML document: + +``` +
+``` + +Initialize Winamp2-js in your JavaScript: + +``` +import 'babel-polyfill'; +import Winamp from 'winamp2-js'; + +new Winamp({ + initialTrack: { + name: "1. DJ Mike Llama - Llama Whippin' Intro", + url: "mp3/llama-2.91.mp3" + }, + initialSkin: { + url: "skins/base-2.91.wsz" + } +}).render(document.getElementById('winamp2-js')); +``` + +*Notes:* + +* This should not be considered "production" code. + * Winamp2-js does not support Internet Explorer. + * Winamp2-js was built to run on it's own page, it may not play well with surrounding CSS. +* You will probably need to include [babel-polyfill](https://babeljs.io/docs/usage/polyfill/) on the page that includes Winamp2-js. +* Skin and audio URLs are subject to [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS). Please ensure they are either served from the same domain, or that the other domain is served with the correct headers. +* This API is subject to change at any time. +* Please reach out to me. I'd love to help you set it up, and understand how it's being used. I plan to expand this API as I learn how people want to use it. + ## Development yarn diff --git a/js/actionTypes.js b/js/actionTypes.js index aee00907..7a3cec1c 100644 --- a/js/actionTypes.js +++ b/js/actionTypes.js @@ -50,3 +50,4 @@ export const REMOVE_ALL_TRACKS = "REMOVE_ALL_TRACKS"; export const CROP_TRACKS = "CROP_TRACKS"; export const FILE_INFO = "FILE_INFO"; export const REMOVE_TRACKS = "REMOVE_TRACKS"; +export const SET_AVALIABLE_SKINS = "SET_AVALIABLE_SKINS"; diff --git a/js/components/MainWindow/MainContextMenu.js b/js/components/MainWindow/MainContextMenu.js index 5bfe0e11..50854cb8 100644 --- a/js/components/MainWindow/MainContextMenu.js +++ b/js/components/MainWindow/MainContextMenu.js @@ -2,21 +2,6 @@ import React from "react"; import { connect } from "react-redux"; import { close, setSkinFromUrl, openFileDialog } from "../../actionCreators"; import { ContextMenu, Hr, Node, Parent, LinkNode } from "../ContextMenu"; -import base from "../../../skins/base-2.91.wsz"; -import osx from "../../../skins/MacOSXAqua1-5.wsz"; -import topaz from "../../../skins/TopazAmp1-2.wsz"; -import visor from "../../../skins/Vizor1-01.wsz"; -import xmms from "../../../skins/XMMS-Turquoise.wsz"; -import zaxon from "../../../skins/ZaxonRemake1-0.wsz"; - -const SKINS = [ - { url: base, name: "" }, - { url: osx, name: "Mac OSX v1.5 (Aqua)" }, - { url: topaz, name: "TopazAmp" }, - { url: visor, name: "Vizor" }, - { url: xmms, name: "XMMS Turquoise " }, - { url: zaxon, name: "Zaxon Remake" } -]; const MainContextMenu = props => ( ( -
- {SKINS.map(skin => ( + {!!props.avaliableSkins.length &&
} + {props.avaliableSkins.map(skin => ( props.setSkin(skin.url)} @@ -47,10 +32,14 @@ const MainContextMenu = props => (
); +const mapStateToProps = state => ({ + avaliableSkins: state.settings.avaliableSkins +}); + const mapDispatchToProps = (dispatch, ownProps) => ({ close: () => dispatch(close()), openFileDialog: () => dispatch(openFileDialog(ownProps.fileInput)), setSkin: url => dispatch(setSkinFromUrl(url)) }); -export default connect(null, mapDispatchToProps)(MainContextMenu); +export default connect(mapStateToProps, mapDispatchToProps)(MainContextMenu); diff --git a/js/config.js b/js/config.js index 8fef1f46..e60c2297 100644 --- a/js/config.js +++ b/js/config.js @@ -7,7 +7,7 @@ if (hash) { try { config = JSON.parse(decodeURIComponent(hash).slice(1)); } catch (e) { - console.error("Failed to decode config from hash: ", e); + console.error("Failed to decode config from hash: ", hash); } } diff --git a/js/index.js b/js/index.js index 28458ebe..c18d2e55 100644 --- a/js/index.js +++ b/js/index.js @@ -2,14 +2,38 @@ import "babel-polyfill"; import Winamp from "./winamp"; import Browser from "./browser"; -import { hideAbout } from "./config"; +import base from "../skins/base-2.91.wsz"; +import osx from "../skins/MacOSXAqua1-5.wsz"; +import topaz from "../skins/TopazAmp1-2.wsz"; +import visor from "../skins/Vizor1-01.wsz"; +import xmms from "../skins/XMMS-Turquoise.wsz"; +import zaxon from "../skins/ZaxonRemake1-0.wsz"; + +import { hideAbout, skinUrl, audioUrl, initialState } from "./config"; if (new Browser(window).isCompatible) { if (hideAbout) { document.getElementsByClassName("about")[0].style.visibility = "hidden"; } - new Winamp({}).render(document.getElementById("winamp2-js")); + new Winamp({ + initialSkin: { + url: skinUrl + }, + initialTrack: { + name: "1. DJ Mike Llama - Llama Whippin' Intro", + url: audioUrl + }, + avaliableSkins: [ + { url: base, name: "" }, + { url: osx, name: "Mac OSX v1.5 (Aqua)" }, + { url: topaz, name: "TopazAmp" }, + { url: visor, name: "Vizor" }, + { url: xmms, name: "XMMS Turquoise " }, + { url: zaxon, name: "Zaxon Remake" } + ], + __initialState: initialState + }).render(document.getElementById("winamp2-js")); } else { document.getElementById("browser-compatibility").style.display = "block"; } diff --git a/js/reducers.js b/js/reducers.js index cc332456..1aeda697 100644 --- a/js/reducers.js +++ b/js/reducers.js @@ -41,7 +41,8 @@ import { INVERT_SELECTION, PLAYLIST_SIZE_CHANGED, REMOVE_ALL_TRACKS, - REMOVE_TRACKS + REMOVE_TRACKS, + SET_AVALIABLE_SKINS } from "./actionTypes"; import { playlistEnabled } from "./config"; @@ -170,6 +171,19 @@ const display = (state = defaultDisplayState, action) => { } }; +const defaultSettingsState = { + avaliableSkins: [] +}; + +const settings = (state = defaultSettingsState, action) => { + switch (action.type) { + case SET_AVALIABLE_SKINS: + return { ...state, avaliableSkins: action.skins }; + default: + return state; + } +}; + const equalizer = (state, action) => { if (!state) { state = { @@ -352,6 +366,7 @@ const reducer = combineReducers({ userInput, windows, display, + settings, equalizer, tracks, playlist, diff --git a/js/winamp.js b/js/winamp.js index 04482d23..afa892bb 100644 --- a/js/winamp.js +++ b/js/winamp.js @@ -11,9 +11,10 @@ import { loadMediaFromUrl, loadFileFromReference } from "./actionCreators"; -import { skinUrl, audioUrl, initialState } from "./config"; -export default class Winamp { +import { SET_AVALIABLE_SKINS } from "./actionTypes"; + +class Winamp { constructor(options) { this.options = options; @@ -22,7 +23,7 @@ export default class Winamp { this.fileInput.style.display = "none"; this.media = new Media(this.fileInput); - this.store = getStore(this.media, initialState); + this.store = getStore(this.media, this.options.__initialState); } render(node) { render( @@ -36,11 +37,25 @@ export default class Winamp { this.store.dispatch(loadFileFromReference(e.target.files[0])); }); - this.store.dispatch( - loadMediaFromUrl(audioUrl, "1. DJ Mike Llama - Llama Whippin' Intro") - ); - this.store.dispatch(setSkinFromUrl(skinUrl)); + if (this.options.initialTrack) { + this.store.dispatch( + loadMediaFromUrl( + this.options.initialTrack.url, + this.options.initialTrack.name + ) + ); + } + if (this.options.avaliableSkins) { + this.store.dispatch({ + type: SET_AVALIABLE_SKINS, + skins: this.options.avaliableSkins + }); + } + this.store.dispatch(setSkinFromUrl(this.options.initialSkin.url)); new Hotkeys(this.fileInput, this.store); } } + +export default Winamp; +module.exports = Winamp; diff --git a/library.html b/library.html new file mode 100755 index 00000000..90979743 --- /dev/null +++ b/library.html @@ -0,0 +1,27 @@ + + + + + + + + +
+ + + + + \ No newline at end of file diff --git a/package.json b/package.json index e961a44b..1efbfc95 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,11 @@ "name": "winamp2-js", "version": "1.0.0", "description": "Winamp 2 implemented in HTML5 and JavaScript", - "main": "index.html", + "main": "build/winamp.bundle.js", "scripts": { "lint": "eslint .", "build": "webpack --config=webpack.production.config.js", + "build-library": "webpack --config=webpack.library.config.js", "serve": "python -m SimpleHTTPServer 8000", "start": "webpack-dev-server", "weight": "npm run build && gzip-size built/winamp.js", @@ -16,7 +17,8 @@ "revert": "ssh jordaneldredge.com sh < scripts/revert.sh", "format": "prettier --write js/**/*.js css/**/*.css webpack.config.js webpack.production.config.js", - "build-skin": "rm skins/base-2.91.wsz && cd skins/base-2.91 && zip -x .* -x 'Skining Updates.txt' -r ../base-2.91.wsz .", + "build-skin": + "rm skins/base-2.91.wsz && cd skins/base-2.91 && zip -x .* -x 'Skining Updates.txt' -r ../base-2.91.wsz .", "skin-info": "unzip -vl skins/base-2.91.wsz" }, "repository": { diff --git a/webpack.config.js b/webpack.config.js index 59bf2eaf..074da6ee 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -10,15 +10,6 @@ module.exports = { test: /\.css$/, use: ["style-loader", "css-loader"] }, - { - test: /\.png$/i, - use: { - loader: "url-loader", - options: { - limit: 100000 - } - } - }, { test: /\.js$/, exclude: /(node_modules)/, diff --git a/webpack.library.config.js b/webpack.library.config.js new file mode 100644 index 00000000..5b6c29c3 --- /dev/null +++ b/webpack.library.config.js @@ -0,0 +1,39 @@ +const path = require("path"); + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: ["style-loader", "css-loader"] + }, + { + test: /\.js$/, + exclude: /(node_modules)/, + use: { + loader: "babel-loader" + } + }, + { + test: /\.(wsz|mp3)$/, + use: [ + { + loader: "file-loader", + options: { + emitFile: true, + name: "[path][name]-[hash].[ext]" + } + } + ] + } + ], + noParse: [/jszip\.js$/] + }, + entry: ["babel-polyfill", "./js/winamp.js"], + output: { + path: path.resolve(__dirname, "built"), + filename: "winamp.bundle.js", + library: "winamp2js", + libraryTarget: "umd" + } +};