Add entry point

This commit is contained in:
Jordan Eldredge 2017-10-09 20:54:14 -07:00
parent 81ad02340e
commit f037498e9e
11 changed files with 187 additions and 40 deletions

View file

@ -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:
```
<div id='winamp2-js'></div>
```
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

View file

@ -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";

View file

@ -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: "<Base Skin>" },
{ 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 => (
<ContextMenu
@ -33,8 +18,8 @@ const MainContextMenu = props => (
<Node onClick={props.openFileDialog} label="Play File..." />
<Parent label="Skins">
<Node onClick={props.openFileDialog} label="Load Skin..." />
<Hr />
{SKINS.map(skin => (
{!!props.avaliableSkins.length && <Hr />}
{props.avaliableSkins.map(skin => (
<Node
key={skin.url}
onClick={() => props.setSkin(skin.url)}
@ -47,10 +32,14 @@ const MainContextMenu = props => (
</ContextMenu>
);
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);

View file

@ -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);
}
}

View file

@ -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: "<Base Skin>" },
{ 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";
}

View file

@ -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,

View file

@ -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;

27
library.html Executable file
View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<div id='winamp2-js'></div>
<script src="built/winamp.bundle.js"></script>
<script>
const Winamp = window.winamp2js;
new Winamp({
initialTrack: {
name: "1. DJ Mike Llama - Llama Whippin' Intro",
url: "mp3/llama-2.91.mp3"
},
initialSkin: {
url: "skins/base-2.91.wsz"
},
avaliableSkins: [
]
}).render(document.getElementById('winamp2-js'));
</script>
</body>
</html>

View file

@ -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": {

View file

@ -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)/,

39
webpack.library.config.js Normal file
View file

@ -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"
}
};