diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..05786794 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["react", "es2015"] +} diff --git a/.eslintrc b/.eslintrc index 8f853407..3a677e6b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,9 +1,18 @@ { "parserOptions": { - "ecmaVersion": 6 + "ecmaVersion": 6, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + }, }, - "ecmaFeatures": { - "modules": true + "plugins": [ + "react" + ], + "settings": { + "react": { + "version": "15.2" + } }, "env": { "browser": true, @@ -13,86 +22,87 @@ }, "rules": { - "block-scoped-var": 1, - "brace-style": [1, "1tbs"], - "camelcase": 2, - "comma-dangle": [2, "never"], - "comma-spacing": 2, - "consistent-return": 1, - "dot-notation": [2, { "allowKeywords": false }], - "eol-last": 2, - "eqeqeq": [2, "smart"], - "guard-for-in": 2, - "indent": [2, 2, {"SwitchCase": 1}], - "key-spacing": 1, - "linebreak-style": 2, - "max-depth": [1, 4], - "max-params": [1, 5], - "new-cap": 2, - "no-alert": 2, - "no-caller": 2, - "no-catch-shadow": 2, - "no-debugger": 2, - "no-delete-var": 2, - "no-div-regex": 1, - "no-dupe-args": 2, - "no-dupe-keys": 2, - "no-duplicate-case": 2, - "no-else-return": 1, - "no-empty-character-class": 2, - "no-empty-label": 2, - "no-eval": 2, - "no-ex-assign": 2, - "no-extend-native": 1, - "no-extra-boolean-cast": 2, - "no-extra-semi": 2, - "no-fallthrough": 2, - "no-floating-decimal": 2, - "no-func-assign": 2, - "no-implied-eval": 2, - "no-inner-declarations": 2, - "no-irregular-whitespace": 2, - "no-label-var": 2, - "no-lone-blocks": 2, - "no-lonely-if": 2, - "no-multi-spaces": 1, - "no-multi-str": 2, - "no-native-reassign": 2, - "no-negated-in-lhs": 1, - "no-nested-ternary": 2, - "no-new-object": 2, - "no-new-wrappers": 2, - "no-obj-calls": 2, - "no-octal": 2, - "no-octal-escape": 2, - "no-proto": 2, - "no-redeclare": 2, - "no-shadow": 2, - "no-spaced-func": 2, - "no-throw-literal": 2, - "no-trailing-spaces": 2, - "no-undef": 2, - "no-undef-init": 2, - "no-undefined": 2, - "no-unneeded-ternary": 2, - "no-unreachable": 2, - "no-unused-expressions": 2, - "no-unused-vars": 2, - "no-use-before-define": [2, "nofunc"], - "no-with": 2, - "quote-props": [1, "consistent-as-needed"], - "quotes": [2, "single", "avoid-escape"], - "radix": 2, - "semi": 2, - "space-after-keywords": [2, "always"], - "space-before-keywords": [2, "always"], - "space-before-function-paren": [2, {"anonymous": "never", "named": "never"}], - "object-curly-spacing": [2, "never"], - "space-infix-ops": 2, - "space-return-throw-case": 2, - "space-unary-ops": [2, { "words": true, "nonwords": false }], - "use-isnan": 2, - "valid-typeof": 2, - "wrap-iife": 2 + "block-scoped-var": "warn", + "brace-style": ["warn", "1tbs"], + "camelcase": "error", + "comma-dangle": ["error", "never"], + "comma-spacing": "error", + "consistent-return": "warn", + "dot-notation": ["error", { "allowKeywords": false }], + "eol-last": "error", + "eqeqeq": ["error", "smart"], + "guard-for-in": "error", + "indent": ["error", 2, {"SwitchCase": 1}], + "key-spacing": "warn", + "linebreak-style": "error", + "max-depth": ["warn", 4], + "max-params": ["warn", 5], + "new-cap": "error", + "no-alert": "error", + "no-caller": "error", + "no-catch-shadow": "error", + "no-debugger": "error", + "no-delete-var": "error", + "no-div-regex": "warn", + "no-dupe-args": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-else-return": "warn", + "no-empty-character-class": "error", + "no-labels": "error", + "no-eval": "error", + "no-ex-assign": "error", + "no-extend-native": "warn", + "no-extra-boolean-cast": "error", + "no-extra-semi": "error", + "no-fallthrough": "error", + "no-floating-decimal": "error", + "no-func-assign": "error", + "no-implied-eval": "error", + "no-inner-declarations": "error", + "no-irregular-whitespace": "error", + "no-label-var": "error", + "no-lone-blocks": "error", + "no-lonely-if": "error", + "no-multi-spaces": "warn", + "no-multi-str": "error", + "no-native-reassign": "error", + "no-negated-in-lhs": "warn", + "no-nested-ternary": "error", + "no-new-object": "error", + "no-new-wrappers": "error", + "no-obj-calls": "error", + "no-octal": "error", + "no-octal-escape": "error", + "no-proto": "error", + "no-redeclare": "error", + "no-shadow": "error", + "no-spaced-func": "error", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-undef": "error", + "no-undef-init": "error", + "no-undefined": "error", + "no-unneeded-ternary": "error", + "no-unreachable": "error", + "no-unused-expressions": "error", + "no-unused-vars": "error", + "no-use-before-define": ["error", "nofunc"], + "no-with": "error", + "object-curly-spacing": ["error", "never"], + "quote-props": ["warn", "consistent-as-needed"], + "quotes": ["error", "single", "avoid-escape"], + "radix": "error", + "react/jsx-uses-react": "error", + "react/jsx-no-bind": "error", + "react/jsx-uses-vars": "error", + "semi": "error", + "keyword-spacing": "error", + "space-before-function-paren": ["error", {"anonymous": "never", "named": "never"}], + "space-infix-ops": "error", + "space-unary-ops": ["error", { "words": true, "nonwords": false }], + "use-isnan": "error", + "valid-typeof": "error", + "wrap-iife": "error" } } diff --git a/js/ContextMenu.jsx b/js/ContextMenu.jsx new file mode 100644 index 00000000..5589e055 --- /dev/null +++ b/js/ContextMenu.jsx @@ -0,0 +1,83 @@ +import React from 'react'; +import MyFile from './my-file'; + +import '../css/context-menu.css'; + +class ContextMenu extends React.Component { + constructor(props) { + super(props); + this.state = { + selected: false + }; + + this.openFileDialog = this.openFileDialog.bind(this); + this.close = this.close.bind(this); + this.toggleMenu = this.toggleMenu.bind(this); + this.closeMenu = this.closeMenu.bind(this); + this.setSkin = this.setSkin.bind(this); + } + + componantWillMount() { + // Clicking anywhere outside the context menu will close the window + document.addEventListener('click', this.closeMenu); + } + + componantWillUnmount() { + document.removeEventListener('click', this.closeMenu); + } + + openFileDialog() { + this.props.winamp.openFileDialog(); + } + + close() { + // Close all of Winamp + this.props.winamp.close(); + } + + closeMenu() { + this.setState({selected: false}); + } + + toggleMenu(event) { + this.setState({selected: !this.state.selected}); + event.stopPropagation(); + } + + setSkin(e) { + const filename = e.target.dataset.filename; + const url = 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/' + filename; + const skinFile = new MyFile(); + skinFile.setUrl(url); + this.props.winamp.setSkin(skinFile); + } + + + render() { + var classes = this.state.selected ? 'selected' : ''; + return