Update client dependencies

This commit is contained in:
Ken-Håvard Lieng 2017-02-16 03:55:50 +01:00
parent c5062066cb
commit 77b53bfc5e
23 changed files with 1858 additions and 1363 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,9 @@
{ {
"presets": ["react", "es2015", "stage-0"], "presets": [
["es2015", { "modules": false }],
"react",
"stage-0"
],
"plugins": ["transform-decorators-legacy"], "plugins": ["transform-decorators-legacy"],
"env": { "env": {
"development": { "development": {

View File

@ -1,16 +1,24 @@
{ {
"extends": "airbnb", "extends": "airbnb",
"parser": "babel-eslint", "parser": "babel-eslint",
"env": {
"browser": true
},
"rules": { "rules": {
"arrow-parens": 0,
"comma-dangle": [2, "never"], "comma-dangle": [2, "never"],
"jsx-a11y/no-static-element-interactions": 0,
"new-cap": [2, { "capIsNewExceptions": ["Map", "List", "Record", "Set"] }], "new-cap": [2, { "capIsNewExceptions": ["Map", "List", "Record", "Set"] }],
"no-console": 0, "no-console": 0,
"no-param-reassign": 0, "no-param-reassign": 0,
"no-plusplus": 0,
"react/jsx-filename-extension": 0,
"react/no-array-index-key": 0,
"react/prop-types": 0, "react/prop-types": 0,
"react/prefer-stateless-function": 0, "react/prefer-stateless-function": 0,
"react/require-render-return": 0 "react/require-render-return": 0
}, },
"globals": { "globals": {
"__DEV__": true "DEV": true
} }
} }

View File

@ -4,57 +4,58 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"devDependencies": { "devDependencies": {
"babel-core": "^6.7.6", "babel-core": "^6.23.1",
"babel-eslint": "^6.0.2", "babel-eslint": "^7.1.1",
"babel-loader": "^6.2.4", "babel-loader": "^6.3.1",
"babel-plugin-react-transform": "^2.0.2", "babel-plugin-react-transform": "^2.0.2",
"babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-react-constant-elements": "^6.5.0", "babel-plugin-transform-react-constant-elements": "^6.23.0",
"babel-plugin-transform-react-inline-elements": "^6.6.5", "babel-plugin-transform-react-inline-elements": "^6.22.0",
"babel-preset-es2015": "^6.6.0", "babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.5.0", "babel-preset-react": "^6.23.0",
"babel-preset-stage-0": "^6.5.0", "babel-preset-stage-0": "^6.22.0",
"css-loader": "^0.23.1", "css-loader": "^0.26.1",
"eslint": "^2.8.0", "eslint": "^3.15.0",
"eslint-config-airbnb": "^7.0.0", "eslint-config-airbnb": "^14.1.0",
"eslint-loader": "^1.3.0", "eslint-loader": "^1.6.1",
"eslint-plugin-jsx-a11y": "^0.6.2", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-react": "^5.0.0", "eslint-plugin-jsx-a11y": "^4.0.0",
"express": "^4.13.4", "eslint-plugin-react": "^6.10.0",
"express-http-proxy": "^0.6.0", "express": "^4.14.1",
"express-http-proxy": "^0.11.0",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-autoprefixer": "3.1.0", "gulp-autoprefixer": "3.1.1",
"gulp-cached": "^1.1.0", "gulp-cached": "^1.1.1",
"gulp-concat": "^2.6.0", "gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.1", "gulp-cssnano": "^2.1.2",
"gulp-gzip": "1.2.0", "gulp-gzip": "1.4.0",
"gulp-util": "^3.0.7", "gulp-util": "^3.0.8",
"ify-loader": "^1.0.3", "ify-loader": "^1.0.3",
"react-transform-catch-errors": "^1.0.2", "react-transform-catch-errors": "^1.0.2",
"react-transform-hmr": "^1.0.4", "react-transform-hmr": "^1.0.4",
"redbox-react": "^1.2.3", "redbox-react": "^1.3.3",
"style-loader": "^0.13.1", "style-loader": "^0.13.1",
"webpack": "^1.13.0", "webpack": "^2.2.1",
"webpack-dev-middleware": "^1.6.1", "webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.10.0" "webpack-hot-middleware": "^2.17.0"
}, },
"dependencies": { "dependencies": {
"autolinker": "git+https://github.com/robbie-c/Autolinker.js.git", "autolinker": "git+https://github.com/robbie-c/Autolinker.js.git",
"backo": "^1.1.0", "backo": "^1.1.0",
"base64-arraybuffer": "^0.1.5", "base64-arraybuffer": "^0.1.5",
"eventemitter2": "^1.0.0", "eventemitter2": "^3.0.0",
"history": "^2.0.2", "history": "^4.5.1",
"immutable": "^3.8.0", "immutable": "^3.8.1",
"lodash": "^4.11.1", "lodash": "^4.17.4",
"pure-render-decorator": "^1.1.0", "pure-render-decorator": "^1.2.1",
"react": "^15.0.1", "react": "^15.4.2",
"react-dom": "^15.0.1", "react-dom": "^15.4.2",
"react-redux": "^4.4.5", "react-redux": "^5.0.2",
"react-router": "^2.2.4", "react-router": "^3.0.2",
"react-router-redux": "^4.0.2", "react-router-redux": "^4.0.8",
"react-virtualized": "^4.10.0", "react-virtualized": "^4.10.0",
"redux": "^3.4.0", "redux": "^3.6.0",
"redux-thunk": "^2.0.1", "redux-thunk": "^2.2.0",
"reselect": "^2.4.0" "reselect": "^2.5.4"
} }
} }

View File

@ -20,8 +20,8 @@ export default class ChatTitle extends Component {
render() { render() {
const { title, tab, channel, toggleSearch, toggleUserList } = this.props; const { title, tab, channel, toggleSearch, toggleUserList } = this.props;
const _topic = channel.get('topic'); let topic = channel.get('topic');
const topic = _topic ? linkify(_topic) : null; topic = topic ? linkify(topic) : null;
let leaveTitle; let leaveTitle;
if (tab.channel) { if (tab.channel) {

View File

@ -15,13 +15,13 @@ export default class MessageBox extends Component {
} }
componentWillReceiveProps() { componentWillReceiveProps() {
const el = this.refs.list.refs.scrollingContainer; const el = this.list.refs.scrollingContainer;
this.autoScroll = el.scrollTop + el.offsetHeight === el.scrollHeight; this.autoScroll = el.scrollTop + el.offsetHeight === el.scrollHeight;
} }
componentWillUpdate(nextProps) { componentWillUpdate(nextProps) {
if (nextProps.messages !== this.props.messages) { if (nextProps.messages !== this.props.messages) {
this.refs.list.recomputeRowHeights(); this.list.recomputeRowHeights();
} }
} }
@ -29,7 +29,7 @@ export default class MessageBox extends Component {
this.updateWidth(); this.updateWidth();
if (this.autoScroll) { if (this.autoScroll) {
const el = this.refs.list.refs.scrollingContainer; const el = this.list.refs.scrollingContainer;
el.scrollTop = el.scrollHeight; el.scrollTop = el.scrollHeight;
} }
} }
@ -50,9 +50,8 @@ export default class MessageBox extends Component {
updateWidth = resize => { updateWidth = resize => {
const { isChannel, setWrapWidth, updateMessageHeight } = this.props; const { isChannel, setWrapWidth, updateMessageHeight } = this.props;
const { list } = this.refs; if (this.list) {
if (list) { let width = this.list.refs.scrollingContainer.clientWidth - 30;
let width = list.refs.scrollingContainer.clientWidth - 30;
if (isChannel) { if (isChannel) {
width += 200; width += 200;
@ -78,7 +77,7 @@ export default class MessageBox extends Component {
const { messages } = this.props; const { messages } = this.props;
if (index === 0 || index === messages.size + 1) { if (index === 0 || index === messages.size + 1) {
return <span style={{ height: '7px' }}></span>; return <span style={{ height: '7px' }} />;
} }
const { select, openPrivateChat } = this.props; const { select, openPrivateChat } = this.props;
@ -97,7 +96,7 @@ export default class MessageBox extends Component {
return ( return (
<div className="messagebox"> <div className="messagebox">
<VirtualScroll <VirtualScroll
ref="list" ref={el => { this.list = el; }}
height={this.state.height} height={this.state.height}
rowsCount={this.props.messages.size + 2} rowsCount={this.props.messages.size + 2}
rowHeight={this.getRowHeight} rowHeight={this.getRowHeight}

View File

@ -44,7 +44,6 @@ export default class MessageInput extends Component {
return ( return (
<div className="message-input-wrap"> <div className="message-input-wrap">
<input <input
ref="input"
className="message-input" className="message-input"
type="text" type="text"
value={this.props.history || this.state.value} value={this.props.history || this.state.value}

View File

@ -9,7 +9,7 @@ class Navicon extends Component {
render() { render() {
return ( return (
<i className="icon-menu navicon" onClick={this.handleClick}></i> <i className="icon-menu navicon" onClick={this.handleClick} />
); );
} }
} }

View File

@ -6,7 +6,7 @@ import SearchResult from './SearchResult';
export default class Search extends Component { export default class Search extends Component {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (!prevProps.search.show && this.props.search.show) { if (!prevProps.search.show && this.props.search.show) {
this.refs.input.focus(); this.input.focus();
} }
} }
@ -27,7 +27,7 @@ export default class Search extends Component {
<div className="search-input-wrap"> <div className="search-input-wrap">
<i className="icon-search" /> <i className="icon-search" />
<input <input
ref="input" ref={el => { this.input = el; }}
className="search-input" className="search-input"
type="text" type="text"
onChange={this.handleSearch} onChange={this.handleSearch}

View File

@ -21,7 +21,7 @@ export default class Search extends Component {
{' '} {' '}
<span className="message-sender">{result.from}</span> <span className="message-sender">{result.from}</span>
</span> </span>
<span dangerouslySetInnerHTML={{ __html: ` ${content}` }}></span> <span dangerouslySetInnerHTML={{ __html: ` ${content}` }} />
</p> </p>
); );
} }

View File

@ -70,8 +70,8 @@ export default class TabList extends Component {
<button className="button-connect" onClick={this.handleConnectClick}>Connect</button> <button className="button-connect" onClick={this.handleConnectClick}>Connect</button>
<div className="tab-container">{tabs}</div> <div className="tab-container">{tabs}</div>
<div className="side-buttons"> <div className="side-buttons">
<i className="icon-user"></i> <i className="icon-user" />
<i className="icon-cog" onClick={this.handleSettingsClick}></i> <i className="icon-cog" onClick={this.handleSettingsClick} />
</div> </div>
</div> </div>
); );

View File

@ -30,7 +30,7 @@ export default class TabListItem extends Component {
style.background = '#F6546A'; style.background = '#F6546A';
} }
indicator = <i className="tab-indicator" style={style}></i>; indicator = <i className="tab-indicator" style={style} />;
} }
return ( return (

View File

@ -15,7 +15,7 @@ export default class UserList extends Component {
componentWillUpdate(nextProps) { componentWillUpdate(nextProps) {
if (nextProps.users.size === this.props.users.size) { if (nextProps.users.size === this.props.users.size) {
this.refs.list.forceUpdate(); this.list.forceUpdate();
} }
} }
@ -37,7 +37,7 @@ export default class UserList extends Component {
const { users } = this.props; const { users } = this.props;
if (index === 0 || index === users.size + 1) { if (index === 0 || index === users.size + 1) {
return <span style={{ height: '10px' }}></span>; return <span style={{ height: '10px' }} />;
} }
const { tab, openPrivateChat, select } = this.props; const { tab, openPrivateChat, select } = this.props;
@ -65,7 +65,7 @@ export default class UserList extends Component {
return ( return (
<div className={className} style={style}> <div className={className} style={style}>
<VirtualScroll <VirtualScroll
ref="list" ref={el => { this.list = el; }}
height={this.state.height} height={this.state.height}
rowsCount={this.props.users.size + 2} rowsCount={this.props.users.size + 2}
rowHeight={this.getRowHeight} rowHeight={this.getRowHeight}

View File

@ -13,7 +13,7 @@ class Connect extends Component {
passwordTouched: false passwordTouched: false
}; };
handleSubmit = (e) => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
const { dispatch } = this.props; const { dispatch } = this.props;
@ -59,7 +59,7 @@ class Connect extends Component {
}; };
render() { render() {
const defaults = window.__ENV__.defaults; const defaults = window.ENV.defaults;
let optionals = null; let optionals = null;
if (this.state.showOptionals) { if (this.state.showOptionals) {
@ -81,7 +81,7 @@ class Connect extends Component {
return ( return (
<div className="connect"> <div className="connect">
<Navicon /> <Navicon />
<form ref="form" className="connect-form" onSubmit={this.handleSubmit}> <form className="connect-form" onSubmit={this.handleSubmit}>
<h1>Connect</h1> <h1>Connect</h1>
<input name="name" type="text" placeholder="Name" defaultValue={defaults.name} /> <input name="name" type="text" placeholder="Name" defaultValue={defaults.name} />
<input name="address" type="text" placeholder="Address" defaultValue={defaults.address} /> <input name="address" type="text" placeholder="Address" defaultValue={defaults.address} />
@ -94,8 +94,8 @@ class Connect extends Component {
/> />
{optionals} {optionals}
<p> <p>
<label><input name="ssl" type="checkbox" defaultChecked={defaults.ssl} />SSL</label> <label htmlFor="ssl"><input name="ssl" type="checkbox" defaultChecked={defaults.ssl} />SSL</label>
<i className="icon-ellipsis" onClick={this.handleShowClick}></i> <i className="icon-ellipsis" onClick={this.handleShowClick} />
</p> </p>
<input type="submit" value="Connect" /> <input type="submit" value="Connect" />
</form> </form>

View File

@ -2,15 +2,15 @@ import React from 'react';
import { render } from 'react-dom'; import { render } from 'react-dom';
import { browserHistory } from 'react-router'; import { browserHistory } from 'react-router';
import { syncHistoryWithStore, replace } from 'react-router-redux'; import { syncHistoryWithStore, replace } from 'react-router-redux';
import 'react-virtualized/styles.css';
import configureStore from './store'; import configureStore from './store';
import createRoutes from './routes'; import createRoutes from './routes';
import Socket from './util/Socket'; import Socket from './util/Socket';
import handleSocket from './socket'; import handleSocket from './socket';
import Root from './containers/Root'; import Root from './containers/Root';
import 'react-virtualized/styles.css'; const host = DEV ? `${window.location.hostname}:1337` : window.location.host;
const host = __DEV__ ? `${window.location.hostname}:1337` : window.location.host;
const socket = new Socket(host); const socket = new Socket(host);
const store = configureStore(socket, browserHistory); const store = configureStore(socket, browserHistory);
@ -18,7 +18,7 @@ const store = configureStore(socket, browserHistory);
const env = JSON.parse(document.getElementById('env').innerHTML); const env = JSON.parse(document.getElementById('env').innerHTML);
// TODO: Handle this properly // TODO: Handle this properly
window.__ENV__ = { window.ENV = {
defaults: env.defaults defaults: env.defaults
}; };

View File

@ -5,7 +5,7 @@ export default function createCommandMiddleware(type, handlers) {
const command = words[0]; const command = words[0];
const params = words.slice(1); const params = words.slice(1);
if (handlers.hasOwnProperty(command)) { if (Object.prototype.hasOwnProperty.call(handlers, command)) {
handlers[command]({ handlers[command]({
dispatch: store.dispatch, dispatch: store.dispatch,
getState: store.getState, getState: store.getState,

View File

@ -1,7 +1,7 @@
import { Map, Record } from 'immutable'; import { Map, Record } from 'immutable';
import forEach from 'lodash/forEach';
import createReducer from '../util/createReducer'; import createReducer from '../util/createReducer';
import * as actions from '../actions'; import * as actions from '../actions';
import forEach from 'lodash/forEach';
const Server = Record({ const Server = Record({
nick: null, nick: null,

View File

@ -1,6 +1,6 @@
export default function createReducer(initialState, handlers) { export default function createReducer(initialState, handlers) {
return function reducer(state = initialState, action) { return function reducer(state = initialState, action) {
if (handlers.hasOwnProperty(action.type)) { if (Object.prototype.hasOwnProperty.call(handlers, action.type)) {
return handlers[action.type](state, action); return handlers[action.type](state, action);
} }
return state; return state;

View File

@ -6,7 +6,7 @@ const autolinker = new Autolinker({
doJoin: false, doJoin: false,
replaceFn: (linker, match) => { replaceFn: (linker, match) => {
if (match.getType() === 'url') { if (match.getType() === 'url') {
return <a target="_blank" href={match.getAnchorHref()}>{match.getAnchorText()}</a>; return <a target="_blank" rel="noopener noreferrer" href={match.getAnchorHref()}>{match.getAnchorText()}</a>;
} }
return null; return null;

View File

@ -8,7 +8,7 @@ export default function messageHeight(message, width, charWidth, indent = 0) {
width -= 200; width -= 200;
} }
if (pad + message.message.length * charWidth < width) { if (pad + (message.message.length * charWidth) < width) {
return height; return height;
} }
@ -21,7 +21,7 @@ export default function messageHeight(message, width, charWidth, indent = 0) {
if (c === ' ' || c === '-') { if (c === ' ' || c === '-') {
const end = c === ' ' ? i : i + 1; const end = c === ' ' ? i : i + 1;
if (pad + (end - prevBreak) * charWidth >= width) { if (pad + ((end - prevBreak) * charWidth) >= width) {
prevBreak = prevPos; prevBreak = prevPos;
pad = indent; pad = indent;
height += lineHeight; height += lineHeight;
@ -29,7 +29,7 @@ export default function messageHeight(message, width, charWidth, indent = 0) {
prevPos = i + 1; prevPos = i + 1;
} else if (i === len - 1) { } else if (i === len - 1) {
if (pad + (len - prevBreak) * charWidth >= width) { if (pad + ((len - prevBreak) * charWidth) >= width) {
height += lineHeight; height += lineHeight;
} }
} }

View File

@ -13,18 +13,16 @@ module.exports = {
publicPath: '/' publicPath: '/'
}, },
module: { module: {
preLoaders: [ rules: [
{ test: /\.js$/, loader: 'eslint', exclude: /node_modules/ } { test: /\.js$/, loader: 'eslint-loader', exclude: /node_modules/, enforce: 'pre' },
], { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ }, { test: /node_modules/, loader: 'ify-loader' }
{ test: /\.css$/, loader: 'style!css' },
{ test: /node_modules/, loader: 'ify' }
] ]
}, },
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
__DEV__: true, DEV: true,
}), }),
new webpack.HotModuleReplacementPlugin(), new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin() new webpack.NoErrorsPlugin()

View File

@ -11,24 +11,20 @@ module.exports = {
publicPath: '/' publicPath: '/'
}, },
module: { module: {
preLoaders: [ rules: [
{ test: /\.js$/, loader: 'eslint', exclude: /node_modules/ } { test: /\.js$/, loader: 'eslint-loader', exclude: /node_modules/, enforce: 'pre' },
], { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ }, { test: /node_modules/, loader: 'ify-loader' }
{ test: /\.css$/, loader: 'style!css' },
{ test: /node_modules/, loader: 'ify' }
] ]
}, },
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
__DEV__: false, DEV: false,
'process.env': { 'process.env': {
NODE_ENV: JSON.stringify('production') NODE_ENV: JSON.stringify('production')
} }
}), }),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ new webpack.optimize.UglifyJsPlugin({
compress: { compress: {
warnings: false warnings: false

File diff suppressed because it is too large Load Diff