Merge branch 'master' of https://github.com/coralproject/talk into reader-flags

This commit is contained in:
David Jay
2016-11-09 13:22:45 -05:00
47 changed files with 706 additions and 507 deletions
-7
View File
@@ -1,7 +0,0 @@
node_modules
public/bundle.js
public/embed/comment-stream
.DS_Store
npm-debug.log
config.json
yarn.lock
+3
View File
@@ -0,0 +1,3 @@
{
"basePath": "admin"
}
-3
View File
@@ -1,3 +0,0 @@
{
"basePath": "client/coral-admin"
}
-22
View File
@@ -1,22 +0,0 @@
<!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>
-42
View File
@@ -1,42 +0,0 @@
{
"name": "coral-admin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "./node_modules/.bin/webpack --config webpack.config.js",
"start": "./node_modules/.bin/webpack-dev-server --config webpack.config.dev.js --inline --hot --content-base public --port 3142"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"hammerjs": "2.0.8",
"immutable": "3.8.1",
"keymaster": "1.6.2",
"material-design-lite": "1.2.1",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-mdl": "^1.7.2",
"react-redux": "^4.4.5",
"react-router": "^3.0.0",
"redux": "3.6.0",
"redux-thunk": "2.1.0",
"timeago.js": "2.0.2"
},
"devDependencies": {
"autoprefixer": "6.5.0",
"babel-core": "^6.18.2",
"babel-loader": "^6.2.7",
"copy-webpack-plugin": "3.0.1",
"css-loader": "0.25.0",
"json-loader": "0.5.4",
"postcss-loader": "0.13.0",
"postcss-modules": "0.5.2",
"precss": "1.4.0",
"standard": "8.2.0",
"style-loader": "0.13.1",
"webpack": "^1.13.3",
"webpack-dev-server": "1.16.1"
}
}
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
plugins: [
require('postcss-smart-import')({ /* ...options */ }),
require('precss')({ /* ...options */ }),
require('autoprefixer')({ /* ...options */ })
]
}
-22
View File
@@ -1,22 +0,0 @@
<!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="client/coral-admin/bundle.js" charset="utf-8"></script>
</body>
</html>
+23
View File
@@ -0,0 +1,23 @@
import React from 'react'
import { Router, Route, Redirect, 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
+4 -13
View File
@@ -1,25 +1,16 @@
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 { Layout } from 'react-mdl'
import store from 'services/store'
import CommentStream from 'containers/CommentStream'
import EmbedLink from 'components/EmbedLink'
import Configure from 'containers/Configure'
import config from 'services/config'
import AppRouter from '../AppRouter'
export default class App extends React.Component {
render (props) {
return (
<Provider store={store}>
<Router history={browserHistory}>
<Route path={config.basePath} component={ModerationQueue} />
<Route path={`${config.basePath}/embed`} component={CommentStream} />
<Route path={`${config.basePath}/embedlink`} component={EmbedLink} />
<Route path={`${config.basePath}/configure`} component={Configure} />
</Router>
<AppRouter store={store} />
</Provider>
)
}
@@ -1,24 +0,0 @@
import React from 'react'
import { Layout, Navigation, Drawer, Header } from 'react-mdl'
import { Link } from 'react-router'
import styles from './Header.css'
import config from 'services/config'
// App header. If we add a navbar it should be here
export default (props) => (
<Layout fixedDrawer>
<Header title='Talk'>
<Navigation>
<Link className={styles.navLink} to={`/${config.basePath}/`}>Moderate</Link>
<Link className={styles.navLink} to={`/${config.basePath}/configure`}>Configure</Link>
</Navigation>
</Header>
<Drawer>
<Navigation>
<Link className={styles.navLink} to={`/${config.basePath}/`}>Moderate</Link>
<Link className={styles.navLink} to={`/${config.basePath}/configure`}>Configure</Link>
</Navigation>
</Drawer>
{props.children}
</Layout>
)
-12
View File
@@ -1,12 +0,0 @@
import React from 'react'
import {Layout} from 'react-mdl'
import 'material-design-lite'
import Header from 'components/Header'
export default (props) => (
<Layout>
<Header>
{props.children}
</Header>
</Layout>
)
@@ -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>
)
@@ -6,7 +6,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 +43,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,14 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
import I18n from 'coral-framework/i18n/i18n'
import translations from '../translations'
export default class CommunityContainer extends Component {
render() {
return (
<div>
<h1>Community</h1>
</div>
)
}
}
+22 -5
View File
@@ -10,8 +10,9 @@ 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'
class Configure extends React.Component {
constructor (props) {
@@ -40,12 +41,28 @@ class Configure extends React.Component {
</List>
}
copyToClipBoard (event) {
const copyTextarea = document.querySelector('.' + styles.embedInput)
copyTextarea.select()
try {
document.execCommand('copy')
} catch (err) {
console.error('Unable to copy')
}
}
getEmbed () {
const embedText =
`<div id='coralStreamEmbed'></div><script type='text/javascript' src='https://pym.nprapps.org/pym.v1.min.js'></script><script>var pymParent = new pym.Parent('coralStreamEmbed', '${window.location.protocol}//${window.location.host}/client/coral-embed-stream/', {title: 'comments'});</script>`
return <List>
<ListItem className={styles.configSettingEmbed}>
<p>Copy and paste code below into your CMS to embed your comment box in your articles</p>
<input type='text' className={styles.embedInput} />
<Button raised colored>Copy</Button>
<textarea type='text' className={styles.embedInput}>
{embedText}
</textarea>
<Button raised colored>{lang.t('embedlink.copy')}</Button>
</ListItem>
</List>
}
@@ -60,7 +77,6 @@ class Configure extends React.Component {
: 'Embed Comment Stream'
return (
<Page>
<div className={styles.container}>
<div className={styles.leftColumn}>
<List>
@@ -88,9 +104,10 @@ class Configure extends React.Component {
}
</div>
</div>
</Page>
)
}
}
export default connect(x => x)(Configure)
const lang = new I18n(translations)
@@ -0,0 +1,19 @@
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 = state => ({ data: {} })
const mapDispatchToProps = (dispatch, ownProps) => ({ dispatch })
export default connect(mapStateToProps, mapDispatchToProps)(LayoutContainer)
@@ -2,7 +2,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 +19,6 @@ class ModerationQueue extends React.Component {
constructor (props) {
super(props)
console.log('ModerationQueue', props)
this.state = { activeTab: 'pending', singleView: false, modalOpen: false }
}
@@ -60,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')}
@@ -109,7 +105,7 @@ class ModerationQueue extends React.Component {
<ModerationKeysModal open={modalOpen}
onClose={() => this.setState({ modalOpen: false })} />
</div>
</Page>
</div>
)
}
}
-42
View File
@@ -1,42 +0,0 @@
const path = require('path')
const fs = require('fs')
const autoprefixer = require('autoprefixer')
const precss = require('precss')
const config = require('./config.json')
// doing a string replace here because I spent a day trying to do it the "webpack" way
// ond nothing works. just trying to replace a string in an index.html file is
// apparently something no one has ever done in the js community.
let templateString = fs.readFileSync(path.join(__dirname, 'index.ejs')).toString()
templateString = templateString.replace('<%= basePath %>', config.basePath)
fs.writeFileSync(path.join(__dirname, 'public/index.html'), templateString)
module.exports = {
entry: {
'bundle': path.join(__dirname, 'src', 'index')
},
output: {
path: path.join(__dirname, '..', '..', 'dist', 'coral-admin'),
filename: '[name].js'
},
module: {
loaders: [
{ test: /.js$/, loader: 'babel', include: path.join(__dirname, 'src'), exclude: /node_modules/ },
{ test: /\.json$/, loaders: 'json', include: __dirname, exclude: /node_modules/ },
{ test: /.css$/, loaders: ['style-loader', 'css-loader?importLoaders=1', 'postcss-loader'] }
]
},
plugins: [ autoprefixer, precss ],
resolve: {
root: [
path.resolve('./src'),
path.resolve('../')
]
},
devServer: {
historyApiFallback: {
index: '/'
}
}
}
-32
View File
@@ -1,32 +0,0 @@
const path = require('path')
const fs = require('fs')
const devConfig = require('./webpack.config.dev')
const autoprefixer = require('autoprefixer')
const precss = require('precss')
const Copy = require('copy-webpack-plugin')
const config = require('./config.json')
// doing a string replace here because I spent a day trying to do it the "webpack" way
// ond nothing works. just trying to replace a string in an index.html file is
// apparently something no one has ever done in the js community.
let templateString = fs.readFileSync(path.join(__dirname, 'index.ejs')).toString()
templateString = templateString.replace('<%= basePath %>', config.basePath)
fs.writeFileSync(path.join(__dirname, 'public/index.html'), templateString)
module.exports = Object.assign({}, devConfig, {
module: {
context: __dirname,
loaders: [
{ test: /.js$/, loader: 'babel', include: [path.join(__dirname, 'src'), path.join(__dirname, '../', 'coral-framework')], exclude: /node_modules/ },
{ test: /.json$/, loader: 'json', include: __dirname, exclude: /node_modules/ },
{ test: /.css$/, loaders: ['style-loader', 'css-loader?importLoaders=1', 'postcss-loader'] }
]
},
plugins: [
new Copy([{
from: path.join(__dirname, '..', 'coral-embed-stream', 'dist'),
to: './embed/comment-stream'
}]),
autoprefixer, precss
]
})
-41
View File
@@ -1,41 +0,0 @@
var path = require('path')
var express = require('express')
var http = require('http')
var webpack = require('webpack')
var config = require('./webpack.config.dev')
var Dashboard = require('webpack-dashboard')
var DashboardPlugin = require('webpack-dashboard/plugin')
var app = express()
var server = http.Server(app)
var compiler = webpack(config)
var dashboard = new Dashboard()
compiler.apply(new DashboardPlugin(dashboard.setData))
app.use(express.static('public'))
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
quiet: true,
publicPath: config.output.publicPath
}))
app.use(require('webpack-hot-middleware')(compiler, {log: () => {}}))
app.get('/default.css', function (req, res) {
res.sendFile(path.join(__dirname, '/style/default.css'))
})
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'index.html'))
})
server.listen(6182, 'localhost', function (err) {
if (err) {
console.log(err)
return
}
console.log('Listening at http://localhost:6182')
})
-13
View File
@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="default.css">
<link href="https://fonts.googleapis.com/css?family=Lato|Open+Sans" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
</head>
<body>
<div id="coralStream"/>
<script src="./bundle.js"></script>
</body>
</html>
@@ -1,70 +0,0 @@
var path = require('path')
var webpack = require('webpack')
const Copy = require('copy-webpack-plugin')
module.exports = {
devtool: 'eval',
entry: [
'babel-polyfill',
'webpack-hot-middleware/client',
path.join(__dirname, 'src', 'app')
],
output: {
path: path.join(__dirname, '..', '..','dist', 'coral-embed-stream'),
filename: 'bundle.js',
publicPath: '/'
},
resolve: {
root: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, '..')
],
extensions: ['', '.js', '.jsx']
},
plugins: [
new Copy([{
from: path.join(__dirname, 'index.html')
},
{
from: path.join(__dirname, 'style', 'default.css')
},
{
from: path.join(__dirname, 'public'),
to: './'
}]),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.ProvidePlugin({
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
}),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [{
test: /\.(js|jsx)$/,
loaders: ['babel'],
exclude: /node_modules/,
include: path.join(__dirname, '../')
}, {
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.png$/,
loader: 'url-loader?limit=100000'
}, {
test: /\.(jpg|png|gif|svg)$/,
loader: 'file-loader'
}, {
test: /\.json$/,
loader: 'json-loader'
}, {
test: /\.woff$/,
loader: 'url?limit=100000'
}]
}
}
@@ -1,73 +0,0 @@
const path = require('path')
const webpack = require('webpack')
const Copy = require('copy-webpack-plugin')
//Keeping this file for reference, it should move to a global webpack.
module.exports = {
devtool: 'source-map',
entry: [
'babel-polyfill',
path.join(__dirname, 'src', 'app')
],
output: {
path: path.join(__dirname, '..', '..','dist', 'coral-embed-stream'),
filename: 'bundle.js',
publicPath: '/dist/'
},
resolve: {
root: [
path.resolve(__dirname, 'src')
],
extensions: ['', '.js', '.jsx']
},
plugins: [
new Copy([{
from: path.join(__dirname, 'index.html')
},
{
from: path.join(__dirname, 'style', 'default.css')
},
{
from: path.join(__dirname, 'public'),
to: './'
},
{
from: path.resolve(__dirname, '..', 'coral-framework', 'i18n', 'translations'),
to: './translations'
}]),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.ProvidePlugin({
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
}),
new webpack.ExtendedAPIPlugin()
],
module: {
loaders: [{
test: /\.(js|jsx)$/,
loaders: ['babel'],
exclude: /node_modules/,
include: path.join(__dirname, '../')
}, {
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.png$/,
loader: 'url-loader?limit=100000'
}, {
test: /\.jpg$/,
loader: 'file-loader'
}, {
test: /\.json$/,
loader: 'json-loader'
}, {
test: /\.woff$/,
loader: 'url?limit=100000'
}]
}
}