Merge branch 'master' of github.com:coralproject/talk into instream-ban

This commit is contained in:
Belen Curcio
2017-09-18 14:08:41 -03:00
23 changed files with 123 additions and 73 deletions
+7 -6
View File
@@ -24,13 +24,14 @@
"promise/no-promise-in-callback": "warn",
"promise/no-callback-in-promise": "warn",
// TODO: Change all these to "error", or remove and use defaults.
"react/display-name": "off",
"react/jsx-no-duplicate-props": "warn",
"react/jsx-no-target-blank": "warn",
"react/no-find-dom-node": "warn",
"react/no-unknown-property": "warn",
"react/prop-types": "off",
// We'll keeping using this, as we'll switch over to Preact and we don't
// need to worry about deprecation.
"react/no-find-dom-node": "off",
// TODO: Use default after fixing the errors.
"react/prop-types": "warn",
"array-callback-return": "warn",
"arrow-parens": ["warn", "always"],
+7 -1
View File
@@ -5,7 +5,12 @@ const path = require('path');
const helmet = require('helmet');
const compression = require('compression');
const cookieParser = require('cookie-parser');
const {BASE_URL, BASE_PATH, MOUNT_PATH} = require('./url');
const {
BASE_URL,
BASE_PATH,
MOUNT_PATH,
STATIC_URL,
} = require('./url');
const routes = require('./routes');
const debug = require('debug')('talk:app');
@@ -55,6 +60,7 @@ app.set('view engine', 'ejs');
app.locals.BASE_URL = BASE_URL;
app.locals.BASE_PATH = BASE_PATH;
app.locals.MOUNT_PATH = MOUNT_PATH;
app.locals.STATIC_URL = STATIC_URL;
debug(`mounting routes on the ${MOUNT_PATH} path`);
@@ -28,7 +28,11 @@ const ActionButton = ({type = '', active, ...props}) => {
};
ActionButton.propTypes = {
active: PropTypes.bool
active: PropTypes.bool,
type: PropTypes.oneOf(['APPROVE', 'REJECT']),
minimal: PropTypes.bool,
acceptComment: PropTypes.func,
rejectComment: PropTypes.func,
};
export default ActionButton;
@@ -58,6 +58,7 @@ class ActionsMenu extends React.Component {
ActionsMenu.propTypes = {
icon: PropTypes.string,
children: PropTypes.node,
};
export default ActionsMenu;
@@ -1,9 +1,14 @@
import React from 'react';
import cn from 'classnames';
import {MenuItem} from 'react-mdl';
import PropTypes from 'prop-types';
import styles from './ActionsMenu.css';
const ActionsMenuItem = (props) =>
<MenuItem className={cn(styles.menuItem, props.className)} {...props} />;
ActionsMenuItem.propTypes = {
className: PropTypes.string,
};
export default ActionsMenuItem;
@@ -105,7 +105,9 @@ AdminLogin.propTypes = {
handleLogin: PropTypes.func.isRequired,
passwordRequestSuccess: PropTypes.string,
loginError: PropTypes.string,
recaptchaPublic: PropTypes.string
recaptchaPublic: PropTypes.string,
requestPasswordReset: PropTypes.func,
errorMessage: PropTypes.string,
};
export default AdminLogin;
@@ -2,8 +2,9 @@ import React from 'react';
import {murmur3} from 'murmurhash-js';
import {CSSTransitionGroup} from 'react-transition-group';
import styles from './CommentAnimatedEdit.css';
import PropTypes from 'prop-types';
export default ({children, body}) => {
const CommentBodyHighlighter = ({children, body}) => {
return (
<CSSTransitionGroup
component={'div'}
@@ -23,3 +24,10 @@ export default ({children, body}) => {
</CSSTransitionGroup>
);
};
CommentBodyHighlighter.propTypes = {
children: PropTypes.node,
body: PropTypes.string,
};
export default CommentBodyHighlighter;
@@ -1,4 +0,0 @@
.textareaContainer {
width: 100%;
}
@@ -183,7 +183,6 @@ export default class UserDetail extends React.Component {
key={comment.id}
user={user}
comment={comment}
selected={false}
suspectWords={suspectWords}
bannedWords={bannedWords}
actions={actionsMap[status]}
@@ -73,12 +73,12 @@ const CoralHeader = ({
<Menu target="menu-settings" align="right">
<MenuItem onClick={() => showShortcuts(true)}>{t('configure.shortcuts')}</MenuItem>
<MenuItem>
<a href="https://github.com/coralproject/talk/releases" target="_blank">
<a href="https://github.com/coralproject/talk/releases" target="_blank" rel="noopener noreferrer">
View latest version
</a>
</MenuItem>
<MenuItem>
<a href="https://coralproject.net/contribute.html#other-ideas-and-bug-reports" target="_blank">
<a href="https://coralproject.net/contribute.html#other-ideas-and-bug-reports" target="_blank" rel="noopener noreferrer">
Report a bug or give feedback
</a>
</MenuItem>
@@ -28,7 +28,8 @@ export default ({headers, commenters, onHeaderClickHandler, onRoleChange, onComm
{row.created_at}
</td>
<td className="mdl-data-table__cell--non-numeric">
<SelectField label={'Select me'} value={row.status || ''}
<SelectField
value={row.status || ''}
className={styles.selectField}
label={t('community.status')}
onChange={(status) => onCommenterStatusChange(row.id, status)}>
@@ -37,7 +38,8 @@ export default ({headers, commenters, onHeaderClickHandler, onRoleChange, onComm
</SelectField>
</td>
<td className="mdl-data-table__cell--non-numeric">
<SelectField label={'Select me'} value={row.roles[0] || ''}
<SelectField
value={row.roles[0] || ''}
className={styles.selectField}
label={t('community.role')}
onChange={(role) => onRoleChange(row.id, role)}>
@@ -150,7 +150,6 @@ class CommentBox extends React.Component {
return <div>
<CommentForm
defaultValue={this.props.defaultValue}
bodyInputId={isReply ? 'replyText' : 'commentText'}
bodyLabel={isReply ? t('comment_box.reply') : t('comment.comment')}
maxCharCount={maxCharCount}
charCountEnable={this.props.charCountEnable}
+7
View File
@@ -117,6 +117,13 @@ const CONFIG = {
// TALK_ROOT_URL and use it to mount the paths on.
ROOT_URL_MOUNT_PATH: process.env.TALK_ROOT_URL_MOUNT_PATH === 'TRUE',
// DISABLE_STATIC_SERVER when TRUE will disable the routes used for static
// asset serving.
DISABLE_STATIC_SERVER: process.env.TALK_DISABLE_STATIC_SERVER === 'TRUE',
// STATIC_URI is the base uri where static files are hosted.
STATIC_URI: process.env.TALK_STATIC_URI || process.env.TALK_ROOT_URL,
// The keepalive timeout (in ms) that should be used to send keep alive
// messages through the websocket to keep the socket alive.
KEEP_ALIVE: process.env.TALK_KEEP_ALIVE || '30s',
+6
View File
@@ -90,6 +90,12 @@ These are only used during the webpack build.
managing the auth state manually, auth cannot be persisted, for further
information refer to the [Persistence Documentation]({{ "/docs/running/persistence/" | absolute_url }})**
(Default `${ssl ? 'ws' : 'wss'}://${location.host}${TALK_ROOT_URL_MOUNT_PATH}api/v1/live`)
- `TALK_STATIC_URI` (_optional_) - Used to set the uri where the static assets
should be served from. This is used when you want to upload the static assets
through your build process to a service like Google Cloud Storage or Amazon S3
and you would then specify the CDN/Storage url. (Default `process.env.TALK_ROOT_URL`)
- `TALK_DISABLE_STATIC_SERVER` (_optional_) - When `TRUE`, it will not mount the
static asset serving routes on the router. (Default `FALSE`)
### Word Filter
+1 -9
View File
@@ -1,9 +1,6 @@
const express = require('express');
const router = express.Router();
const {
RECAPTCHA_PUBLIC,
WEBSOCKET_LIVE_URI,
} = require('../../config');
const {data} = require('../static');
// Get /email-confirmation expects a signed JWT in the hash
router.get('/confirm-email', (req, res) => {
@@ -20,11 +17,6 @@ router.get('/password-reset', (req, res) => {
});
router.get('*', (req, res) => {
const data = {
TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC,
LIVE_URI: WEBSOCKET_LIVE_URI,
};
res.render('admin', {data});
});
+1 -9
View File
@@ -1,20 +1,12 @@
const express = require('express');
const router = express.Router();
const SettingsService = require('../../services/settings');
const {
RECAPTCHA_PUBLIC,
WEBSOCKET_LIVE_URI,
} = require('../../config');
const {data} = require('../static');
router.use('/:embed', async (req, res, next) => {
switch (req.params.embed) {
case 'stream': {
const {customCssUrl} = await SettingsService.retrieve();
const data = {
TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC,
LIVE_URI: WEBSOCKET_LIVE_URI,
};
return res.render('embed/stream', {customCssUrl, data});
}
}
+19 -12
View File
@@ -11,6 +11,7 @@ const errors = require('../errors');
const {createGraphOptions} = require('../graph');
const accepts = require('accepts');
const apollo = require('graphql-server-express');
const {DISABLE_STATIC_SERVER} = require('../config');
const router = express.Router();
@@ -39,20 +40,26 @@ if (process.env.NODE_ENV === 'production') {
});
}
router.use('/client', express.static(path.join(__dirname, '../dist')));
router.use('/public', express.static(path.join(__dirname, '../public')));
if (!DISABLE_STATIC_SERVER) {
/**
* Serves a file based on a relative path.
*/
const serveFile = (filename) => (req, res) => res.sendFile(path.join(__dirname, filename));
/**
* Serve the directories under public/dist from this router.
*/
router.use('/client', express.static(path.join(__dirname, '../dist')));
router.use('/public', express.static(path.join(__dirname, '../public')));
/**
* Serves the embed javascript files.
*/
router.get('/embed.js', serveFile('../dist/embed.js'));
router.get('/embed.js.gz', serveFile('../dist/embed.js.gz'));
router.get('/embed.js.map', serveFile('../dist/embed.js.map'));
/**
* Serves a file based on a relative path.
*/
const serveFile = (filename) => (req, res) => res.sendFile(path.join(__dirname, filename));
/**
* Serves the embed javascript files.
*/
router.get('/embed.js', serveFile('../dist/embed.js'));
router.get('/embed.js.gz', serveFile('../dist/embed.js.gz'));
router.get('/embed.js.map', serveFile('../dist/embed.js.map'));
}
//==============================================================================
// PASSPORT MIDDLEWARE
+13
View File
@@ -0,0 +1,13 @@
const {
RECAPTCHA_PUBLIC,
WEBSOCKET_LIVE_URI,
} = require('../config');
const {
STATIC_URL,
} = require('../url');
module.exports.data = {
TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC,
LIVE_URI: WEBSOCKET_LIVE_URI,
STATIC_URL,
};
+15 -5
View File
@@ -1,9 +1,15 @@
const {ROOT_URL, ROOT_URL_MOUNT_PATH} = require('./config');
const {
ROOT_URL,
ROOT_URL_MOUNT_PATH,
STATIC_URI,
} = require('./config');
const {URL} = require('url');
const trailingSlash = (url) => url && url.length > 0 && url[url.length - 1] === '/' ? url : `${url}/`;
// Set the BASE_URL as the ROOT_URL, here we derive the root url by ensuring
// that it ends in a `/`.
const BASE_URL = ROOT_URL && ROOT_URL.length > 0 && ROOT_URL[ROOT_URL.length - 1] === '/' ? ROOT_URL : `${ROOT_URL}/`;
const BASE_URL = trailingSlash(ROOT_URL);
// The BASE_PATH is simply the path component of the BASE_URL.
const BASE_PATH = new URL(BASE_URL).pathname;
@@ -12,8 +18,12 @@ const BASE_PATH = new URL(BASE_URL).pathname;
// This will mount all the application routes onto it.
const MOUNT_PATH = ROOT_URL_MOUNT_PATH ? BASE_PATH : '/';
// The STATIC_URL is the url where static assets should be loaded from.
const STATIC_URL = trailingSlash(STATIC_URI);
module.exports = {
BASE_URL: BASE_URL,
BASE_PATH: BASE_PATH,
MOUNT_PATH: MOUNT_PATH,
BASE_URL,
BASE_PATH,
MOUNT_PATH,
STATIC_URL,
};
+14 -14
View File
@@ -4,19 +4,19 @@
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<title>Talk - Coral Admin</title>
<link rel="apple-touch-icon" sizes="57x57" href="public/img/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="public/img/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="public/img/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="public/img/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="public/img/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="public/img/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="public/img/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="public/img/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="public/img/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="32x32" href="public/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="public/img/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="public/img/favicon-16x16.png">
<link rel="manifest" href="public/manifest.json">
<link rel="apple-touch-icon" sizes="57x57" href="<%= STATIC_URL %>public/img/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="<%= STATIC_URL %>public/img/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="<%= STATIC_URL %>public/img/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="<%= STATIC_URL %>public/img/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="<%= STATIC_URL %>public/img/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="<%= STATIC_URL %>public/img/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="<%= STATIC_URL %>public/img/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="<%= STATIC_URL %>public/img/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="<%= STATIC_URL %>public/img/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="32x32" href="<%= STATIC_URL %>public/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="<%= STATIC_URL %>public/img/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="<%= STATIC_URL %>public/img/favicon-16x16.png">
<link rel="manifest" href="<%= STATIC_URL %>public/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
@@ -42,6 +42,6 @@
<body>
<div id="root"></div>
<script src='https://www.google.com/recaptcha/api.js?render=explicit' async defer></script>
<script src="<%= BASE_PATH %>client/coral-admin/bundle.js" charset="utf-8"></script>
<script src="<%= STATIC_URL %>client/coral-admin/bundle.js" charset="utf-8"></script>
</body>
</html>
+1 -1
View File
@@ -28,6 +28,6 @@
</head>
<body>
<div id="root"></div>
<script src="<%= BASE_PATH %>client/coral-docs/bundle.js" charset="utf-8"></script>
<script src="<%= STATIC_URL %>client/coral-docs/bundle.js" charset="utf-8"></script>
</body>
</html>
+1 -1
View File
@@ -24,7 +24,7 @@
<p><%= body %></p>
<p><a href="<%= BASE_PATH %>admin">Admin</a> - <a href="<%= BASE_PATH %>assets">All Assets</a></p>
<div id='coralStreamEmbed'></div>
<script src="<%= BASE_URL %>embed.js" async onload="
<script src="<%= STATIC_URL %>embed.js" async onload="
window.TalkEmbed = Coral.Talk.render(document.getElementById('coralStreamEmbed'), {
talk: '<%= BASE_URL %>',
asset_url: '<%= asset_url ? asset_url : '' %>',
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<link rel="stylesheet" type="text/css" href="<%= BASE_URL %>client/embed/stream/default.css">
<link rel="stylesheet" type="text/css" href="<%= STATIC_URL %>client/embed/stream/default.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<% if (locals.customCssUrl) { %>
@@ -17,6 +17,6 @@
<body>
<div id="talk-embed-stream-container"></div>
<script src="<%= BASE_PATH %>client/embed/stream/bundle.js"></script>
<script src="<%= STATIC_URL %>client/embed/stream/bundle.js"></script>
</body>
</html>