mirror of
https://github.com/wassname/talk.git
synced 2026-07-27 11:28:12 +08:00
Merge branch 'master' into client-eslint
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
"no-var": [2],
|
||||
"no-lonely-if": [2],
|
||||
"curly": [2],
|
||||
"no-unused-vars": ["error", { "argsIgnorePattern": "next" }],
|
||||
"no-multiple-empty-lines": [
|
||||
"error",
|
||||
{"max": 1}
|
||||
|
||||
@@ -11,14 +11,57 @@ app.use(bodyParser.json());
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
app.set('view engine', 'ejs');
|
||||
|
||||
// API Routes.
|
||||
// Routes.
|
||||
app.use('/api/v1', require('./routes/api'));
|
||||
app.use('/client', express.static(path.join(__dirname, 'dist')));
|
||||
app.use('/admin', require('./routes/admin'));
|
||||
|
||||
// Static Routes.
|
||||
app.use('/client/', express.static(path.join(__dirname, 'dist')));
|
||||
//==============================================================================
|
||||
// ERROR HANDLING
|
||||
//==============================================================================
|
||||
|
||||
app.get('/admin*', (req, res) => {
|
||||
res.render('admin', {basePath: '/client/coral-admin'});
|
||||
const ErrNotFound = new Error('Not Found');
|
||||
ErrNotFound.status = 404;
|
||||
|
||||
// Catch 404 and forward to error handler.
|
||||
app.use((req, res, next) => {
|
||||
next(ErrNotFound);
|
||||
});
|
||||
|
||||
// General error handler. Respond with the message and error if we have it while
|
||||
// returning a status code that makes sense.
|
||||
if (app.get('env') === 'development') {
|
||||
app.use('/api', (err, req, res, next) => {
|
||||
res.status(err.status || 500);
|
||||
res.json({
|
||||
message: err.message,
|
||||
error: err
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/', (err, req, res, next) => {
|
||||
res.status(err.status || 500);
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: err
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
app.use('/api', (err, req, res, next) => {
|
||||
res.status(err.status || 500);
|
||||
res.json({
|
||||
message: err.message,
|
||||
error: {}
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/', (err, req, res, next) => {
|
||||
res.status(err.status || 500);
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: {}
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import {Router, Route, IndexRoute, browserHistory} from 'react-router';
|
||||
|
||||
import ModerationQueue from 'containers/ModerationQueue';
|
||||
import CommentStream from 'containers/CommentStream';
|
||||
import EmbedLink from 'components/EmbedLink';
|
||||
import Configure from 'containers/Configure';
|
||||
import CommunityContainer from 'containers/CommunityContainer';
|
||||
import LayoutContainer from 'containers/LayoutContainer';
|
||||
|
||||
const routes = (
|
||||
<Route path='admin' component={LayoutContainer}>
|
||||
<IndexRoute component={ModerationQueue} />
|
||||
<Route path='embed' component={CommentStream} />
|
||||
<Route path='embedlink' component={EmbedLink} />
|
||||
<Route path='community' component={CommunityContainer} />
|
||||
<Route path='configure' component={Configure} />
|
||||
</Route>
|
||||
);
|
||||
|
||||
const AppRouter = () => <Router history={browserHistory} routes={routes} />;
|
||||
|
||||
export default AppRouter;
|
||||
@@ -1,24 +1,15 @@
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
import 'material-design-lite';
|
||||
import {Router, Route, browserHistory} from 'react-router';
|
||||
import ModerationQueue from 'containers/ModerationQueue';
|
||||
import store from 'services/store';
|
||||
import CommentStream from 'containers/CommentStream';
|
||||
import EmbedLink from 'components/EmbedLink';
|
||||
import Configure from 'containers/Configure';
|
||||
|
||||
import AppRouter from '../AppRouter';
|
||||
|
||||
export default class App extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<Router history={browserHistory}>
|
||||
<Route path='admin' component={ModerationQueue} />
|
||||
<Route path='admin/embed' component={CommentStream} />
|
||||
<Route path='admin/embedlink' component={EmbedLink} />
|
||||
<Route path='admin/configure' component={Configure} />
|
||||
</Router>
|
||||
<AppRouter store={store} />
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import {Navigation, Drawer} from 'react-mdl';
|
||||
import {Link} from 'react-router';
|
||||
import styles from './Header.css';
|
||||
|
||||
export default () => (
|
||||
<Drawer>
|
||||
<Navigation>
|
||||
<Link className={styles.navLink} to="/admin">Moderate</Link>
|
||||
<Link className={styles.navLink} to="/admin/community">Community</Link>
|
||||
<Link className={styles.navLink} to="/admin/configure">Configure</Link>
|
||||
</Navigation>
|
||||
</Drawer>
|
||||
);
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import {Navigation, Header} from 'react-mdl';
|
||||
import {Link} from 'react-router';
|
||||
import styles from './Header.css';
|
||||
|
||||
export default () => (
|
||||
<Header title='Talk'>
|
||||
<Navigation>
|
||||
<Link className={styles.navLink} to="/admin">Moderate</Link>
|
||||
<Link className={styles.navLink} to="/admin/community">Community</Link>
|
||||
<Link className={styles.navLink} to="/admin/configure">Configure</Link>
|
||||
</Navigation>
|
||||
</Header>
|
||||
);
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import {Layout as LayoutMDL} from 'react-mdl';
|
||||
import Header from './Header';
|
||||
import Drawer from './Drawer';
|
||||
|
||||
export const Layout = ({children}) => (
|
||||
<LayoutMDL fixedDrawer>
|
||||
<Header />
|
||||
<Drawer />
|
||||
{children}
|
||||
</LayoutMDL>
|
||||
);
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import React from 'react';
|
||||
import styles from './CommentStream.css';
|
||||
import {Snackbar} from 'react-mdl';
|
||||
@@ -6,7 +5,6 @@ import {connect} from 'react-redux';
|
||||
import {createComment, flagComment} from 'actions/comments';
|
||||
import CommentList from 'components/CommentList';
|
||||
import CommentBox from 'components/CommentBox';
|
||||
import Page from 'components/Page';
|
||||
|
||||
/**
|
||||
* Renders a comment stream using a CommentList component
|
||||
@@ -44,19 +42,17 @@ class CommentStream extends React.Component {
|
||||
// Render the comment box along with the CommentList
|
||||
render ({comments}, {snackbar, snackbarMsg}) {
|
||||
return (
|
||||
<Page>
|
||||
<div className={styles.container}>
|
||||
<CommentBox onSubmit={this.onSubmit} />
|
||||
<CommentList isActive hideActive
|
||||
singleView={false}
|
||||
commentIds={comments.get('ids')}
|
||||
comments={comments.get('byId')}
|
||||
onClickAction={this.onClickAction}
|
||||
actions={['flag']}
|
||||
loading={comments.loading} />
|
||||
<Snackbar active={snackbar}>{snackbarMsg}</Snackbar>
|
||||
</div>
|
||||
</Page>
|
||||
<div className={styles.container}>
|
||||
<CommentBox onSubmit={this.onSubmit} />
|
||||
<CommentList isActive hideActive
|
||||
singleView={false}
|
||||
commentIds={comments.get('ids')}
|
||||
comments={comments.get('byId')}
|
||||
onClickAction={this.onClickAction}
|
||||
actions={['flag']}
|
||||
loading={comments.loading} />
|
||||
<Snackbar active={snackbar}>{snackbarMsg}</Snackbar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import React, {Component} from 'react';
|
||||
|
||||
export default class CommunityContainer extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Community</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
Button,
|
||||
Icon
|
||||
} from 'react-mdl';
|
||||
import Page from 'components/Page';
|
||||
import styles from './Configure.css';
|
||||
import I18n from 'coral-framework/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
@@ -78,7 +77,6 @@ class Configure extends React.Component {
|
||||
: 'Embed Comment Stream';
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.leftColumn}>
|
||||
<List>
|
||||
@@ -106,7 +104,6 @@ class Configure extends React.Component {
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import React, {Component}from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {Layout} from '../components/ui/Layout';
|
||||
|
||||
class LayoutContainer extends Component {
|
||||
render () {
|
||||
return <Layout { ...this.props } />;
|
||||
}
|
||||
}
|
||||
|
||||
LayoutContainer.propTypes = {};
|
||||
|
||||
const mapStateToProps = () => ({data: {}});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({dispatch});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LayoutContainer);
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import ModerationKeysModal from 'components/ModerationKeysModal';
|
||||
import Page from 'components/Page';
|
||||
import CommentList from 'components/CommentList';
|
||||
import {updateStatus} from 'actions/comments';
|
||||
import styles from './ModerationQueue.css';
|
||||
@@ -20,8 +18,6 @@ class ModerationQueue extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
console.log('ModerationQueue', props);
|
||||
|
||||
this.state = {activeTab: 'pending', singleView: false, modalOpen: false};
|
||||
}
|
||||
|
||||
@@ -61,10 +57,9 @@ class ModerationQueue extends React.Component {
|
||||
render () {
|
||||
const {comments} = this.props;
|
||||
const {activeTab, singleView, modalOpen} = this.state;
|
||||
console.log('moderation queue', styles);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<div>
|
||||
<div className='mdl-tabs mdl-js-tabs mdl-js-ripple-effect'>
|
||||
<div className='mdl-tabs__tab-bar'>
|
||||
<a href='#pending' onClick={() => this.onTabClick('pending')}
|
||||
@@ -110,7 +105,7 @@ class ModerationQueue extends React.Component {
|
||||
<ModerationKeysModal open={modalOpen}
|
||||
onClose={() => this.setState({modalOpen: false})} />
|
||||
</div>
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-15
@@ -43,7 +43,6 @@
|
||||
},
|
||||
"homepage": "https://github.com/coralproject/talk#readme",
|
||||
"dependencies": {
|
||||
"autoprefixer": "^6.5.2",
|
||||
"body-parser": "^1.15.2",
|
||||
"debug": "^2.2.0",
|
||||
"ejs": "^2.5.2",
|
||||
@@ -53,22 +52,22 @@
|
||||
"uuid": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "6.5.0",
|
||||
"babel-core": "^6.14.0",
|
||||
"babel-eslint": "^7.1.0",
|
||||
"babel-jest": "^15.0.0",
|
||||
"babel-loader": "^6.2.5",
|
||||
"babel-plugin-transform-async-to-generator": "^6.8.0",
|
||||
"autoprefixer": "^6.5.0",
|
||||
"babel-core": "^6.18.2",
|
||||
"babel-loader": "^6.2.7",
|
||||
"babel-plugin-transform-async-to-generator": "^6.16.0",
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||
"babel-plugin-transform-object-assign": "^6.8.0",
|
||||
"babel-plugin-transform-react-jsx": "^6.8.0",
|
||||
"babel-polyfill": "^6.13.0",
|
||||
"babel-preset-es2015": "6.13.0",
|
||||
"babel-polyfill": "^6.16.0",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-es2015-minimal": "^2.1.0",
|
||||
"babel-preset-stage-0": "^6.16.0",
|
||||
"chai": "^3.5.0",
|
||||
"chai-http": "^3.0.0",
|
||||
"copy-webpack-plugin": "^3.0.1",
|
||||
"copy-webpack-plugin": "^4.0.0",
|
||||
"css-loader": "^0.25.0",
|
||||
"eslint": "^3.9.1",
|
||||
"eslint-plugin-react": "^6.6.0",
|
||||
@@ -81,8 +80,9 @@
|
||||
"material-design-lite": "^1.2.1",
|
||||
"mocha": "^3.1.2",
|
||||
"mocha-junit-reporter": "^1.12.1",
|
||||
"postcss-loader": "^0.13.0",
|
||||
"postcss-modules": "0.5.2",
|
||||
"postcss-loader": "^1.1.0",
|
||||
"postcss-modules": "^0.5.2",
|
||||
"postcss-smart-import": "^0.5.1",
|
||||
"pre-git": "^3.10.0",
|
||||
"precss": "^1.4.0",
|
||||
"pym.js": "^1.1.1",
|
||||
@@ -97,11 +97,7 @@
|
||||
"style-loader": "^0.13.1",
|
||||
"supertest": "^2.0.1",
|
||||
"timeago.js": "^2.0.3",
|
||||
"webpack": "^1.13.2",
|
||||
"webpack-dashboard": "^0.2.0",
|
||||
"webpack-dev-middleware": "^1.8.3",
|
||||
"webpack-hot-middleware": "^2.12.2",
|
||||
"webpack-module-hot-accept": "^1.0.4",
|
||||
"webpack": "^1.13.3",
|
||||
"whatwg-fetch": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('postcss-smart-import')({ /* ...options */ }),
|
||||
require('precss')({ /* ...options */ }),
|
||||
require('autoprefixer')({ /* ...options */ })
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
const express = require('express');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/embed/stream/preview', (req, res) => {
|
||||
res.render('embed-stream', {basePath: '/client/embed/stream'});
|
||||
});
|
||||
|
||||
router.get('*', (req, res) => {
|
||||
res.render('admin', {basePath: '/client/coral-admin'});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
+2
-2
@@ -10,8 +10,8 @@
|
||||
body, #root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
|
||||
<title>Talk - Coral Admin</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
|
||||
<style media="screen">
|
||||
body, #root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="<%= basePath %>/bundle.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
|
||||
<title>Talk - Coral Admin</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
|
||||
<link rel="stylesheet" href="<%= basePath %>/default.css">
|
||||
<style media="screen">
|
||||
body, #root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="coralStream"></div>
|
||||
<script src="<%= basePath %>/bundle.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Error</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<pre><%= message %></pre>
|
||||
|
||||
<pre><%= error.stack %></pre>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -52,7 +52,11 @@ module.exports = {
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
loaders: ['style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]', 'postcss-loader'],
|
||||
loaders: [
|
||||
'style-loader',
|
||||
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
|
||||
'postcss-loader'
|
||||
],
|
||||
test: /.css$/,
|
||||
},
|
||||
{
|
||||
@@ -86,5 +90,6 @@ module.exports = {
|
||||
...buildTargets.map(target => path.join(__dirname, 'client', target, 'src')),
|
||||
...buildEmbeds.map(embed => path.join(__dirname, 'client', `coral-embed-${embed}`, 'src'))
|
||||
]
|
||||
}
|
||||
},
|
||||
postcss: require('./postcss.config.js')
|
||||
};
|
||||
|
||||
+2
-1
@@ -7,7 +7,8 @@ devConfig.devtool = null;
|
||||
devConfig.plugins = devConfig.plugins.concat([
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
'NODE_ENV': JSON.stringify('production')
|
||||
'NODE_ENV': `"${'production'}"`,
|
||||
'VERSION': `"${require('./package.json')}"`
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
|
||||
Reference in New Issue
Block a user