diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index fa6f49039a4a..b5d199815e2c 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,4 +1,6 @@
- [ ] Check the current issues to ensure you aren't creating a duplicate.
- [ ] Consider making small typo fixes and such directly as pull requests.
+- [ ] For the voting application, go to https://github.com/webpack-contrib/voting-app.
+- [ ] For loader/plugin docs, consider opening an issue in the corresponding repository.
- [ ] No existing issue? Go ahead and open a new one.
- __Remove these instructions from your PR as they are for your eyes only.__
diff --git a/package.json b/package.json
index 471f466b6aae..c8f71e076491 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
"antwar-helpers": "^0.19.0",
"antwar-interactive": "^0.19.0",
"async": "^2.5.0",
- "autoprefixer": "^7.1.3",
+ "autoprefixer": "^7.2.3",
"babel-core": "^6.26.0",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.1.2",
@@ -53,12 +53,12 @@
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
- "copy-webpack-plugin": "^4.0.1",
+ "copy-webpack-plugin": "^4.3.0",
"css-loader": "^0.28.5",
"duplexer": "^0.1.1",
"eslint": "4.5.0",
"eslint-loader": "^1.9.0",
- "eslint-plugin-markdown": "^1.0.0-beta.6",
+ "eslint-plugin-markdown": "^1.0.0-beta.7",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"fontgen-loader": "^0.2.1",
@@ -67,22 +67,22 @@
"github": "^10.0.0",
"html-webpack-plugin": "^2.30.1",
"http-server": "^0.10.0",
- "hyperlink": "^3.0.0",
+ "hyperlink": "^3.0.1",
"loader-utils": "^1.1.0",
"lodash": "^4.17.4",
"markdown-loader": "^2.0.1",
"markdownlint": "^0.6.0",
"markdownlint-cli": "^0.3.1",
- "marked": "^0.3.6",
+ "marked": "^0.3.7",
"mkdirp": "^0.5.1",
"modularscale-sass": "^3.0.3",
- "moment": "^2.18.1",
+ "moment": "^2.20.1",
"ncp": "^2.0.0",
"node-sass": "^4.5.3",
"npm-run-all": "^4.1.1",
"postcss-loader": "^2.0.6",
"prism-languages": "^0.3.3",
- "prismjs": "^1.6.0",
+ "prismjs": "^1.9.0",
"raw-loader": "^0.5.1",
"request": "^2.81.0",
"sass-loader": "^6.0.6",
@@ -92,14 +92,14 @@
"tap-parser": "^6.0.1",
"through2": "^2.0.3",
"url-loader": "^0.5.9",
- "webpack": "^3.5.5",
- "webpack-dev-server": "^2.7.1",
+ "webpack": "^3.10.0",
+ "webpack-dev-server": "^2.9.7",
"webpack-merge": "^4.1.0",
"yaml-frontmatter-loader": "^0.1.0"
},
"dependencies": {
- "ajv": "^5.2.2",
- "preact": "^8.2.5",
+ "ajv": "^5.5.2",
+ "preact": "^8.2.7",
"preact-compat": "3.17.0",
"prop-types": "^15.5.10",
"react": "^15.6.1",
@@ -107,6 +107,7 @@
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"tool-list": "^0.11.0",
+ "webpack.vote": "^0.1.0",
"whatwg-fetch": "^2.0.3"
}
}
diff --git a/src/components/Navigation/Links.json b/src/components/Navigation/Links.json
index 4546aa78e1fb..aafac7beec4f 100644
--- a/src/components/Navigation/Links.json
+++ b/src/components/Navigation/Links.json
@@ -15,8 +15,12 @@
"title": "Contribute",
"url": "contribute"
},
+ {
+ "title": "Vote",
+ "url": "vote"
+ },
{
"title": "Blog",
"url": "//medium.com/webpack"
}
-]
\ No newline at end of file
+]
diff --git a/src/components/Vote/App.jsx b/src/components/Vote/App.jsx
deleted file mode 100644
index cfba8704f200..000000000000
--- a/src/components/Vote/App.jsx
+++ /dev/null
@@ -1,411 +0,0 @@
-import React from 'react';
-import 'whatwg-fetch';
-import * as api from "./api";
-import VoteButton from './Button/Button';
-import Influence from './Influence';
-import GithubMark from '../../assets/github-logo.svg';
-
-function updateByProperty(array, property, propertyValue, update) {
- return array.map(item => {
- if(item[property] === propertyValue) {
- return update(item);
- } else {
- return item;
- }
- });
-}
-
-export default class VoteApp extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- selfInfo: undefined,
- listInfo: undefined,
- isFetchingSelf: false,
- isVoting: 0
- };
- }
-
- isBrowserSupported() {
- return typeof localStorage === 'object';
- }
-
- componentDidMount() {
- if(!this.isBrowserSupported())
- return;
-
- let { selfInfo, listInfo } = this.state;
-
- if(api.isLoginActive()) {
- this.setState({
- isLoginActive: true
- });
- api.continueLogin().then(token => {
- window.localStorage.voteAppToken = token;
- });
- } else {
- if(!selfInfo) {
- this.updateSelf();
- }
- if(!listInfo) {
- this.updateList();
- }
- }
- }
-
- componentWillReceiveProps(props) {
- if(!this.isBrowserSupported())
- return;
-
- this.updateList(props);
- }
-
- updateSelf() {
- let { voteAppToken } = localStorage;
- if(voteAppToken) {
- this.setState({
- isFetchingSelf: true
- });
- api.getSelf(voteAppToken).catch(e => {
- this.setState({
- selfInfo: null,
- isFetchingSelf: false
- });
- }).then(result => {
- this.setState({
- selfInfo: result,
- isFetchingSelf: false
- });
- });
- }
- }
-
- updateList(props = this.props) {
- let { name } = props;
- let { voteAppToken } = localStorage;
- this.setState({
- isFetchingList: true
- });
- api.getList(voteAppToken, name).catch(e => {
- this.setState({
- listInfo: null,
- isFetchingList: false
- });
- }).then(result => {
- this.setState({
- listInfo: result,
- isFetchingList: false
- });
- });
- }
-
- localVote(itemId, voteName, diffValue, currencyName, score) {
- let { selfInfo, listInfo } = this.state;
- this.setState({
- isVoting: this.state.isVoting + 1,
- listInfo: listInfo && {
- ...listInfo,
- items: updateByProperty(listInfo.items, "id", itemId, item => ({
- ...item,
- votes: updateByProperty(item.votes, "name", voteName, vote => ({
- ...vote,
- votes: vote.votes + diffValue
- })),
- userVotes: updateByProperty(item.userVotes, "name", voteName, vote => ({
- ...vote,
- votes: vote.votes + diffValue
- })),
- score: item.score + score * diffValue
- }))
- },
- selfInfo: selfInfo && {
- ...selfInfo,
- currencies: updateByProperty(selfInfo.currencies, "name", currencyName, currency => ({
- ...currency,
- used: currency.used + diffValue,
- remaining: currency.remaining - diffValue
- }))
- }
- });
- }
-
- vote(itemId, voteName, diffValue, currencyName, score) {
- if(!diffValue) return;
- this.localVote(itemId, voteName, diffValue, currencyName, score);
- let { voteAppToken } = localStorage;
- api.vote(voteAppToken, itemId, voteName, diffValue).catch(e => {
- console.error(e);
- // revert local vote
- this.localVote(itemId, voteName, -diffValue, currencyName, score);
- this.setState({
- isVoting: this.state.isVoting - 1
- });
- }).then(() => {
- this.setState({
- isVoting: this.state.isVoting - 1
- });
- });
- }
-
- render() {
- let { name } = this.props;
-
- if(!this.isBrowserSupported())
- return
Your browser is not supported.
;
-
- let { selfInfo, listInfo, isVoting, isFetchingList, isFetchingSelf, isCreating, isLoginActive, editItem, editItemTitle, editItemDescription } = this.state;
-
- let { voteAppToken } = localStorage;
-
- if(isLoginActive) {
- return Logging in...
;
- }
-
- const inProgress = isFetchingList || isFetchingSelf || isCreating || isVoting;
-
- let maxVoteInfo = listInfo && listInfo.possibleVotes.map(() => 0);
-
- if(listInfo) listInfo.items.forEach(item => {
- if(item.userVotes) {
- maxVoteInfo.forEach((max, idx) => {
- let votes = item.userVotes[idx].votes;
- if(votes > max)
- maxVoteInfo[idx] = votes;
- });
- }
- });
- return (
-
-
- Vote
-
-
-
-
-
-
-
-
-
- DISCLAIMER: Since this feature is its Alpha stages, the formula for calculating influence may change.
-
-
-
- {this.renderSelf(inProgress)}
-
-
-
- { listInfo &&
-
{listInfo.displayName}
-
{listInfo.description}
-
- { listInfo.items.map(item => -
-
-
-
{item.score}
- {listInfo.possibleVotes.map((voteSettings, idx) => {
- let vote = item.votes[idx];
- let userVote = item.userVotes && item.userVotes[idx];
- let currencyInfo = selfInfo && voteSettings.currency && this.findByName(selfInfo.currencies, voteSettings.currency);
- let maximum = voteSettings.maximum || 1000; // infinity
- let minimum = voteSettings.minimum || 0;
- let value = (userVote && userVote.votes) ? userVote.votes: 0;
- if(currencyInfo && currencyInfo.remaining + value < maximum) maximum = currencyInfo.remaining + value;
- return
- {
- this.vote(item.id, voteSettings.name, diffValue, voteSettings.currency, voteSettings.score);
- }}
- />
-
;
- })}
-
- { editItem !== item.id &&
-
{item.title}
-
{item.description}
- { listInfo.isAdmin &&
-
-
-
-
-
-
}
-
}
- { editItem === item.id &&
-
- this.setState({ editItemTitle: e.target.value })} />
-
-
-
-
-
}
-
- )}
- { listInfo.isAdmin && -
-
this.setState({newTitle: e.target.value})} />
-
-
- }
-
-
}
-
- );
- }
-
- renderSelf (inProgress) {
- let { listInfo, selfInfo, isFetchingSelf } = this.state;
- if(!selfInfo) {
- if(isFetchingSelf) {
- return Loading user info...
;
- }
- return ;
- } else {
- return
-
-

- {selfInfo.login}
-
- { listInfo &&
- { selfInfo.currencies
- .filter(currency => listInfo.possibleVotes.some(voteSettings => voteSettings.currency === currency.name))
- .map(currency => -
- {currency.remaining} {currency.displayName}
-
) }
-
}
-
-
-
-
-
;
- }
- }
-
- findByName(array, name) {
- for(var i = 0; i < array.length; i++)
- if(array[i].name === name)
- return array[i];
- return null;
- }
-
- getNiceVoteValues(maximum) {
- var arr = [];
- var b = true;
- for(var x = 1; x < maximum; x *= b ? 5 : 2, b = !b) {
- arr.push(x);
- }
- if(maximum)
- arr.push(maximum);
- return arr;
- }
-
- getStep(maximum) {
- return Math.floor(maximum / 20) * 2 || 1;
- }
-
- getColor(name) {
- switch(name) {
- case "influence": return "blue";
- case "golden": return "#bfa203";
- case "thumb": return "#535353";
- }
- return undefined;
- }
-}
diff --git a/src/components/Vote/App.scss b/src/components/Vote/App.scss
deleted file mode 100644
index bc91ef1c6be1..000000000000
--- a/src/components/Vote/App.scss
+++ /dev/null
@@ -1,228 +0,0 @@
-@import 'vars';
-@import 'mixins';
-@import 'functions';
-
-.vote-app {
- margin: 1.5em;
-
- &__top {
- display: flex;
- flex-direction: column;
-
- @include break(medium) {
- flex-direction: row;
- }
- }
-
- &__influence {
- flex: 0 0 75%;
- }
-
- &__influence-description {
- display: flex;
- flex-direction: column;
-
- @include break(medium) {
- flex-direction: row;
- }
- }
-
- &__user-section {
- padding: 0 0 30px;
-
- @include break(medium) {
- flex: 0 0 25%;
- padding: 0 0 0 20px;
- }
-
- @include break(large) {
- border-left: 2px solid getColor(elephant);
- }
- }
-
- &__influence-section {
- flex: 0 0 50%;
- }
-
- &__influence-disclaimer {
- padding: 1em 0;
- font-size: smaller;
- color: red;
-
- @include break(medium) {
- text-align: center;
- }
- }
-
- &__login-button {
- margin: 20px 0;
-
- button {
- border: none;
- outline: none;
- color: getColor(white);
- background: getColor(elephant);
- padding: 5px 10px 5px 10px;
- border-radius: 2px;
- font-size: 13px;
- cursor: pointer;
-
- &:hover {
- background: black;
- }
-
- &:active {
- background: getColor(elephant)
- }
- }
-
- img {
- height: 25px;
- vertical-align: middle;
- padding-left: 5px;
- }
- }
-
- &__userinfo {
- outline: none;
- border: none;
- background: getColor(elephant);
- color: white;
- border-radius: 3px;
- font-size: 13px;
- display: inline-block;
- padding: 3px 10px;
-
- img {
- height: 25px;
- vertical-align: middle;
- margin-right: 10px;
- }
- }
-
- &__self-info {
- margin-top: 10px;
- }
-
- &__button-area {
- margin: 5px 0;
- }
-
- &__update-button {
-
- }
-
- h1 {
- font-size: 16pt;
- font-weight: bold;
- margin-bottom: 10px;
- }
-
- &__item-title {
- font-size: 16pt;
- font-weight: bold;
- margin-right: 10px;
- }
-
- &__item-edit-title {
- width: 100%;
- }
-
- &__item-edit-description {
- width: 100%;
- }
-
- &__currency-list {
- display: block;
-
- & > li {
- display: inline-block;
- padding: 5px;
- }
- }
-
- &__item-card {
- display: flex;
- flex-direction: column;
- margin-top: 30px;
- margin-bottom: 30px;
-
- @include break(medium){
- flex-direction: row;
- }
- }
-
- &__score-section {
- display: flex;
- border: 1px solid lightgray;
- user-select: none;
- flex-wrap: wrap;
-
- @include break(medium){
- flex: 0 0 40%;
- margin-right: 30px;
- padding: 0 0 0 20px;
- }
- }
-
- &__item-score {
- align-self: center;
- font-size: 20pt;
- flex: 0 0 100%;
- text-align: center;
-
- @include break(medium){
- flex: 0 0 20%;
- text-align: left;
- }
- }
-
- &__item-button {
- align-self: center;
- flex: 0 0 50%;
-
- @include break(medium){
- flex: 0 0 40%;
- }
- }
-
- &__items-list {
- display: block;
-
- & > li {
- display: block;
- padding: 5px 0;
- }
- }
-
- &__currency-influence, &__vote-influence {
- color: blue;
- &:before {
- content: "◆\2009";
- }
- }
-
- &__currency-goldenInfluence, &__vote-golden {
- color: #bfa203;
- &:before {
- content: "◇\2009";
- }
- }
-
- &__currency-support, &__vote-support {
- color: green;
- &:before {
- content: "$\2009";
- }
- }
-
- &__vote-thumb {
-
- }
-
- &__admin {
- input, textarea, button {
- width: 100%;
- }
- }
-}
diff --git a/src/components/Vote/Button/Button.jsx b/src/components/Vote/Button/Button.jsx
deleted file mode 100644
index 0cff5ba33ec1..000000000000
--- a/src/components/Vote/Button/Button.jsx
+++ /dev/null
@@ -1,132 +0,0 @@
-import React, {Component} from 'react';
-
-export default class NewButton extends Component {
- handleClick (n) {
- const {maxUp, maxDown, onVote} = this.props;
- onVote(Math.min(maxUp, Math.max(n, -maxDown)));
- return false;
- }
-
- titleText (n, maxUp, maxDown) {
- n = Math.min(maxUp, Math.max(n, -maxDown));
- if(n === 0)
- return "";
- return n > 0 ? "+" + n : "" + n;
- }
-
- makeTriangle (n, fn, size, minForEnabled, increase) {
- const {maxUp, maxDown, color} = this.props;
- const enabled = n !== 0 && (n > 0 ? (maxUp >= minForEnabled) : (maxDown >= minForEnabled));
- const className = "vote-new-button__upDown";
-
- if(enabled) {
- return this.handleClick(n)}
- onMouseDown={() => this.startCounter(increase)}
- onMouseUp={() => this.stopCounter()}
- onMouseOut={() => this.stopCounter()}
- onTouchStart={() => this.startCounter(increase)}
- onTouchEnd={() => this.stopCounter()}
- onTouchCancel={() => this.stopCounter()}
- className={className}
- >
- {fn({size: size, color: color})}
- ;
- } else {
- return
- {fn({size: size, color: "#eee"})}
- ;
- }
- }
-
- startCounter(increase) {
- let current = 0;
- let add = 0;
- const that = this;
-
- if (this.interval) {
- clearInterval(this.interval);
- }
-
- this.interval = setInterval(function() {
- // increase for 1 between 0 and 5
- if(current <= 5) {
- current++;
- add = 1;
- }
- // increase for 2 between 6 and 10
- else if(current <= 10) {
- current+=2;
- add = 2;
- }
- // increase for 5 between 11 and 40
- else if(current <= 40) {
- current+=5;
- add = 5;
- }
- // increase for 10 between 41 and 70
- else if(current <= 70) {
- current+=10;
- add = 10;
- }
- // increase for 15 after 71
- else {
- current+=15;
- add = 15;
- }
-
- if(!increase) {
- add *= -1;
- }
-
- that.handleClick(add);
- }, 200);
- }
-
- stopCounter() {
- if (this.interval) {
- clearInterval(this.interval);
- }
- }
-
- render() {
- const {color, className, value, myValue, canVote} = this.props;
- return canVote ? (
-
- {this.makeTriangle(1, triangleUp, 10, 1, true)}
- {this.makeTriangle(-1, triangleDown, 10, 1, false)}
-
-
- {value}
-
-
- ({myValue})
-
-
): ();
- }
-}
-
-function triangleUp({color, size}) {
- let path = `m ${size},0 -${size},${size / 3 * 2} ${size*2},0 z`;
- return ;
-}
-
-function triangleDown({color, size}) {
- let path = `m ${size},${size / 3 * 2} ${size},-${size / 3 * 2} -${size*2},0 z`;
- return ;
-}
\ No newline at end of file
diff --git a/src/components/Vote/Button/Button.scss b/src/components/Vote/Button/Button.scss
deleted file mode 100644
index 7a3419a7c8a1..000000000000
--- a/src/components/Vote/Button/Button.scss
+++ /dev/null
@@ -1,57 +0,0 @@
-@import 'vars';
-@import 'mixins';
-@import 'functions';
-
-.vote-button {
- text-align: center;
- &__value {
- font-size: 150%;
- }
-
- &__value, &__my-value, &__upDown {
- display: block;
- width: 90px;
- }
-
- &__upDown {
- border: 0;
- padding: 0;
- margin: 0;
- }
-}
-
-.vote-new-button {
- display: flex;
- justify-content: center;
-
- @include break(medium) {
- justify-content: inherit;
- }
-
- &__arrows {
- flex: 0 0 10%;
- }
-
- &__value {
- font-size: 15pt;
- }
-
- &__value, &__my-value{
- display: inline;
- margin-left: 5px;
- align-self: center;
- }
-
- &__upDown {
- border: 0;
- padding: 0;
- margin: 0;
- cursor: pointer;
- }
-
- &__logout-value {
- align-self: center;
- font-size: 20pt;
- margin: auto;
- }
-}
\ No newline at end of file
diff --git a/src/components/Vote/Influence.jsx b/src/components/Vote/Influence.jsx
deleted file mode 100644
index e2ada69ddfca..000000000000
--- a/src/components/Vote/Influence.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-export default class InfluenceComponent extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- return (this.props.type === "normal" ? (
-
- Influence
- Influence is a unit of measure based on time you have been a member on GitHub. However, in 2017 and on you will recieve one influence per day.
-
- ) : (
-
- Golden Influence
- Golden Influence is equal to 100 normal influence. Golden Influence is obtained by being a backer or sponsor on our Open Collective page.
-
- ));
- }
-}
diff --git a/src/components/Vote/Influence.scss b/src/components/Vote/Influence.scss
deleted file mode 100644
index 7e9eba35bc84..000000000000
--- a/src/components/Vote/Influence.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-@import 'mixins';
-@import 'functions';
-
-.influence-info {
- em {
- font-weight: bolder;
- }
-
- i {
- font-style: italic;
- }
-
- &__section {
- padding: 0.5em 0;
- @include break(medium) {
- padding: 0 .5em;
- }
- }
-}
\ No newline at end of file
diff --git a/src/components/Vote/Vote.jsx b/src/components/Vote/Vote.jsx
index c913a5c50363..afd37f9ac1a5 100644
--- a/src/components/Vote/Vote.jsx
+++ b/src/components/Vote/Vote.jsx
@@ -1,30 +1,19 @@
import React from 'react';
import Interactive from 'antwar-interactive';
import Container from '../Container/Container';
-import VoteApp from './App';
-import '../../styles';
+import VoteApp from 'webpack.vote';
+import 'webpack.vote/dist/style.min.css';
import './Vote.scss';
-import './App.scss';
-import './Influence.scss';
-import './Button/Button.scss';
-const Vote = ({ section, page }) => {
- let arr = page.url.split('/').filter(Boolean);
- let name = arr[arr.length - 1];
-
- return (
-
-
-
-
- );
-};
+const Vote = ({ section, page }) => (
+
+
+
+);
Vote.title = 'Vote';
diff --git a/src/components/Vote/Vote.scss b/src/components/Vote/Vote.scss
index 8aa896a548e1..d9efe95ce407 100644
--- a/src/components/Vote/Vote.scss
+++ b/src/components/Vote/Vote.scss
@@ -2,3 +2,10 @@
@import 'mixins';
@import 'functions';
+.vote {
+ h1, h2, h3, h4, h5, h6 {
+ font-family: $font-stack-heading;
+ font-weight: 600;
+ color: getColor(fiord);
+ }
+}
diff --git a/src/components/Vote/api.dev.js b/src/components/Vote/api.dev.js
deleted file mode 100644
index 8aac367b8abc..000000000000
--- a/src/components/Vote/api.dev.js
+++ /dev/null
@@ -1,161 +0,0 @@
-let usedCurrencies = {
- influence: 100,
- goldenInfluence: 100
-};
-let totalCurrencies = {
- influence: 1000,
- goldenInfluence: 300
-};
-let lists = {
- todo: {
- possibleVotes: [
- {
- name: "influence",
- currency: "influence",
- score: 1,
- color: "blue"
- },
- {
- name: "golden",
- currency: "goldenInfluence",
- score: 1,
- color: "#bfa203"
- }
- ],
- items: [
- { id: "1234", list: "todo", title: "Finish up MVP documentation", description: "Take care for the remaining issues in the webpack.js.org repo which are relevant for the MVP.", influence: 15 },
- { id: "2345", list: "todo", title: "Review whole documentation", description: "Read over **all** of the documentation to find errors.", golden: 20 },
- ]
- }
-};
-let allItems = {
- "1234": lists.todo.items[0],
- "2345": lists.todo.items[1],
-};
-
-function delay(time) {
- return new Promise(function (fulfill) {
- setTimeout(fulfill, time);
- });
-}
-
-function clone(json) {
- return JSON.parse(JSON.stringify(json));
-}
-
-export function isLoginActive() {
- return /^\?login=/.test(window.location.search);
-}
-
-export function startLogin(callbackUrl) {
- window.location.search = "?login=" + encodeURIComponent(callbackUrl);
- return Promise.resolve();
-}
-
-export function continueLogin() {
- if(/^\?login=/.test(window.location.search)) {
- return delay(2000).then(() => {
- setTimeout(() => window.location = decodeURIComponent(window.location.search.substr(7), 100));
- return "developer";
- });
- }
- return Promise.resolve();
-}
-
-export function getSelf(token) {
- if(token !== "developer")
- return Promise.reject(new Error("Not logged in as developer"));
- return delay(500).then(() => ({
- login: "dev",
- name: "Developer",
- avatar: "https://github.com/webpack.png",
- currencies: [
- { name: "influence", displayName: "Influence", description: "Some **description**", value: totalCurrencies.influence, used: usedCurrencies.influence, remaining: totalCurrencies.influence - usedCurrencies.influence },
- { name: "goldenInfluence", displayName: "Golden Influence", description: "Some **description**", value: totalCurrencies.goldenInfluence, used: usedCurrencies.goldenInfluence, remaining: totalCurrencies.goldenInfluence - usedCurrencies.goldenInfluence }
- ]
- }));
-}
-
-export function getList(token, name) {
- const loggedIn = token === "developer";
- const listData = lists[name];
- return delay(500).then(() => ({
- name: name,
- displayName: "DEV: " + name,
- description: "Some **description**",
- lockable: true,
- deletable: true,
- archivable: true,
- isAdmin: true,
- possibleVotes: listData.possibleVotes,
- items: lists[name].items.map(item => {
- const votes = listData.possibleVotes.map(pv => ({
- name: pv.name,
- votes: (item[pv.name] || 0) + Math.floor(Math.random() * 100)
- }));
- const score = listData.possibleVotes.map((pv, i) => {
- return pv.score * votes[i].votes;
- }).reduce((a, b) => a + b, 0);
- return {
- id: item.id,
- list: item.list,
- title: item.title,
- description: item.description,
- votes,
- userVotes: loggedIn ? listData.possibleVotes.map(pv => ({
- name: pv.name,
- votes: item[pv.name] || 0
- })) : undefined,
- score
- };
- }).sort((a, b) => b.score - a.score)
- }));
-}
-
-export function createItem(token, list, title, description) {
- if(token !== "developer")
- return Promise.reject(new Error("Not logged in as developer"));
- let newItem = {
- id: Math.random() + "",
- list,
- title,
- description
- };
- allItems[newItem.id] = newItem;
- lists[list].items.push(newItem);
- return delay(500).then(() => ({
- ...newItem,
- votes: lists[list].possibleVotes.map(pv => ({
- name: pv.name,
- votes: 0
- })),
- userVotes: lists[list].possibleVotes.map(pv => ({
- name: pv.name,
- votes: 0
- })),
- score: 0
- }));
-}
-
-export function vote(token, itemId, voteName, value) {
- if(token !== "developer")
- return Promise.reject(new Error("Not logged in as developer"));
- var listId = allItems[itemId].list;
- let listData = lists[listId];
- let pv = listData.possibleVotes.filter(pv => pv.name === voteName)[0];
- if(pv.currency) {
- usedCurrencies[pv.currency] += value;
- }
- allItems[itemId][voteName] = (allItems[itemId][voteName] || 0) + value;
- return delay(500).then(() => true);
-}
-
-export function configItem(token, itemId, config) {
- if(token !== "developer")
- return Promise.reject(new Error("Not logged in as developer"));
- var item = allItems[itemId];
- Object.keys(config).forEach(key => {
- item[key] = config[key];
- });
- return delay(500).then(() => true);
-}
diff --git a/src/components/Vote/api.js b/src/components/Vote/api.js
deleted file mode 100644
index e29c7077fb58..000000000000
--- a/src/components/Vote/api.js
+++ /dev/null
@@ -1,139 +0,0 @@
-import {
- isLoginActive as devIsLoginActive,
- startLogin as devStartLogin,
- continueLogin as devContinueLogin,
- getSelf as devGetSelf,
- getList as devGetList,
- createItem as devCreateItem,
- vote as devVote,
- configItem as devConfigItem
-} from "./api.dev";
-
-const API_URL = "https://oswils44oj.execute-api.us-east-1.amazonaws.com/production/";
-const GITHUB_CLIENT_ID = "4d355e2799cb8926c665";
-const PRODUCTION_HOST = "webpack.js.org";
-
-// You can test the production mode with a host entry,
-// or by setting PRODUCTION_HOST to "localhost:3000" and stealing localStorage.voteAppToken from the production side.
-
-function checkResult(result) {
- if(!result)
- throw new Error("No result received");
- if(result.errorMessage)
- throw new Error(result.errorMessage);
- return result;
-}
-
-export function isLoginActive() {
- if(window.location.host !== PRODUCTION_HOST)
- return devIsLoginActive();
- return /^\?code=([^&]*)&state=([^&]*)/.test(window.location.search);
-}
-
-export function startLogin(callbackUrl) {
- if(window.location.host !== PRODUCTION_HOST)
- return devStartLogin(callbackUrl);
- let state = "" + Math.random();
- window.localStorage.githubState = state;
- window.location = "https://github.com/login/oauth/authorize?client_id=" + GITHUB_CLIENT_ID + "&scope=user:email&state=" + state + "&allow_signup=false&redirect_uri=" + encodeURIComponent(callbackUrl);
- return Promise.resolve();
-}
-
-export function continueLogin() {
- if(window.location.host !== PRODUCTION_HOST)
- return devContinueLogin();
- const match = /^\?code=([^&]*)&state=([^&]*)/.exec(window.location.search);
- if(match) {
- return login(match[1], match[2]).then(result => {
- setTimeout(() => {
- let href = window.location.href;
- window.location = href.substr(0, href.length - window.location.search.length);
- }, 100);
- return result;
- });
- }
- return Promise.resolve();
-}
-
-function login(code, state) {
- if(state !== window.localStorage.githubState)
- return Promise.reject(new Error("Request state doesn't match (Login was triggered by 3rd party)"));
- delete window.localStorage.githubState;
- return fetch(API_URL + "/login", {
- headers: {
- "Content-Type": "application/json"
- },
- method: "POST",
- body: JSON.stringify({
- code,
- state
- })
- }).then((res) => res.json()).then(checkResult).then(result => {
- if(!result.token)
- throw new Error("No token received from API");
- return result.token;
- });
-}
-
-export function getSelf(token) {
- if(window.location.host !== PRODUCTION_HOST)
- return devGetSelf(token);
- return fetch(API_URL + "/self?token=" + token, {
- mode: "cors"
- }).then((res) => res.json()).then(checkResult);
-}
-
-export function getList(token, name) {
- if(window.location.host !== PRODUCTION_HOST)
- return devGetList(token, name);
- return fetch(API_URL + "/list/" + name + (token ? "?token=" + token : ""), {
- mode: "cors"
- }).then((res) => res.json()).then(checkResult);
-}
-
-export function createItem(token, list, title, description) {
- if(window.location.host !== PRODUCTION_HOST)
- return devCreateItem(token, list, title, description);
- return fetch(API_URL + "/list/" + list + "?token=" + token, {
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- title,
- description
- }),
- method: "POST"
- }).then((res) => res.json()).then(checkResult);
-}
-
-export function vote(token, itemId, voteName, value) {
- if(window.location.host !== PRODUCTION_HOST)
- return devVote(token, itemId, voteName, value);
- return fetch(API_URL + "/vote/" + itemId + "/" + voteName + "?token=" + token, {
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- count: value
- }),
- method: "POST"
- }).then((res) => res.json()).then(checkResult).then(result => {
- return true;
- });
-}
-
-export function configItem(token, itemId, config) {
- if(window.location.host !== PRODUCTION_HOST)
- return devConfigItem(token, itemId, config);
- return fetch(API_URL + "/config/" + itemId + "?token=" + token, {
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- config: config
- }),
- method: "POST"
- }).then((res) => res.json()).then(checkResult).then(result => {
- return true;
- });
-}
diff --git a/webpack.config.js b/webpack.config.js
index 79d9d03bf0f8..12ed23f4b59c 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -6,10 +6,6 @@ var merge = require('webpack-merge');
var webpack = require('webpack');
var cwd = process.cwd();
-var stylePaths = [
- path.join(cwd, 'src', 'styles'),
- path.join(cwd, 'src', 'components')
-];
const commonConfig = env => ({
resolve: {
@@ -25,7 +21,7 @@ const commonConfig = env => ({
module: {
rules: [
{
- test: /\.(js|jsx)$/,
+ test: /\.jsx?$/,
use: [
'babel-loader',
{
@@ -55,8 +51,7 @@ const commonConfig = env => ({
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
- }),
- include: stylePaths
+ })
},
{
test: /\.scss$/,
@@ -72,8 +67,7 @@ const commonConfig = env => ({
}
}
]
- }),
- include: stylePaths
+ })
},
{
test: /\.woff2?$/,