Merge branch 'master' into feature/talk-plugin-toxic-comments

This commit is contained in:
Kim Gardner
2017-07-31 18:44:05 -04:00
committed by GitHub
23 changed files with 119 additions and 70 deletions
+3 -5
View File
@@ -1,6 +1,6 @@
import React from 'react';
import {Router, Route, IndexRedirect, browserHistory, Redirect} from 'react-router';
import {useBasename} from 'history';
import {Router, Route, IndexRedirect, Redirect} from 'react-router';
import {history} from 'coral-framework/helpers/router';
import Configure from 'routes/Configure';
import Dashboard from 'routes/Dashboard';
@@ -57,8 +57,6 @@ const routes = (
</div>
);
const AppRouter = () => <Router history={useBasename(() => browserHistory)({
basename: '/talk/'
})} routes={routes}/>;
const AppRouter = () => <Router history={history} routes={routes}/>;
export default AppRouter;
+3 -2
View File
@@ -1,5 +1,6 @@
import React from 'react';
import {Router, Route, browserHistory} from 'react-router';
import {Router, Route} from 'react-router';
import {history} from 'coral-framework/helpers/router';
import Embed from './containers/Embed';
import {LoginContainer} from 'coral-sign-in/containers/LoginContainer';
@@ -11,6 +12,6 @@ const routes = (
</div>
);
const AppRouter = () => <Router history={browserHistory} routes={routes} />;
const AppRouter = () => <Router history={history} routes={routes} />;
export default AppRouter;
@@ -36,7 +36,7 @@ export default class Embed extends React.Component {
<div className={cn('talk-embed-stream', {'talk-embed-stream-highlight-comment': hasHighlightedComment})}>
<IfSlotIsNotEmpty slot="login">
<Popup
href='/embed/stream/login'
href='embed/stream/login'
title='Login'
features='menubar=0,resizable=0,width=500,height=550,top=200,left=500'
open={showSignInDialog}
@@ -265,8 +265,8 @@ const fragments = {
charCount
requireEmailConfirmation
}
commentCount(excludeIgnored: $excludeIgnored)
totalCommentCount(excludeIgnored: $excludeIgnored)
commentCount(excludeIgnored: $excludeIgnored) @skip(if: $hasComment)
totalCommentCount(excludeIgnored: $excludeIgnored) @skip(if: $hasComment)
comments(limit: 10, excludeIgnored: $excludeIgnored) @skip(if: $hasComment) {
nodes {
...CoralEmbedStream_Stream_comment
+12 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
import {render} from 'react-dom';
import {ApolloProvider} from 'react-apollo';
import {checkLogin} from 'coral-framework/actions/auth';
import {checkLogin, handleAuthToken, logout} from 'coral-framework/actions/auth';
import './graphql';
import {addExternalConfig} from 'coral-embed-stream/src/actions/config';
import {getStore, injectReducers, addListener} from 'coral-framework/services/store';
@@ -43,6 +43,17 @@ if (!window.opener) {
pym.onMessage('config', (config) => {
init(JSON.parse(config));
});
pym.onMessage('login', (token) => {
if (token) {
store.dispatch(handleAuthToken(token));
}
store.dispatch(checkLogin());
});
pym.onMessage('logout', () => {
store.dispatch(logout());
});
} else {
init();
}
@@ -257,6 +257,8 @@ body {
margin: 0px 5px;
padding: 5px 5px;
border-radius: 2px;
font-size: 12px;
font-weight: bold;
}
/* Comment Action Styles */
+40 -8
View File
@@ -5,8 +5,6 @@ import {buildUrl} from 'coral-framework/utils';
import queryString from 'query-string';
import EventEmitter from 'eventemitter2';
const eventEmitter = new EventEmitter({wildcard: true});
// TODO: Styles should live in a separate file
const snackbarStyles = {
position: 'fixed',
@@ -50,7 +48,7 @@ function buildStreamIframeUrl(talkBaseUrl, query) {
// Set up postMessage listeners/handlers on the pymParent
// e.g. to resize the iframe, and navigate the host page
function configurePymParent(pymParent, opts) {
function configurePymParent(pymParent, eventEmitter, opts) {
let notificationOffset = 200;
let cachedHeight;
const snackbar = document.createElement('div');
@@ -203,6 +201,23 @@ function configurePymParent(pymParent, opts) {
* @param {String} [opts.asset_url] - Asset URL
* @param {String} [opts.asset_id] - Asset ID
* @param {String} [opts.auth_token] - (optional) A jwt representing the session
* @return {Object}
*
* Example:
* ```
* const embed = Talk.render(document.getElementById('talkStreamEmbed'), opts);
*
* // trigger a login with optional token.
* embed.login(token);
*
* // trigger a logout.
* embed.logout();
*
* // listen to events (in this case all events).
* embed.on('**', function(value) {
* console.log(this.event, value);
* });
* ```
*/
Talk.render = function(el, opts) {
if (!el) {
@@ -256,14 +271,31 @@ Talk.render = function(el, opts) {
}
}
const pymParent = new pym.Parent(el.id, buildStreamIframeUrl(opts.talk, query), {
title: opts.title,
id: `${el.id}_iframe`,
name: `${el.id}_iframe`
});
const eventEmitter = new EventEmitter({wildcard: true});
configurePymParent(
new pym.Parent(el.id, buildStreamIframeUrl(opts.talk, query), {
title: opts.title,
id: `${el.id}_iframe`,
name: `${el.id}_iframe`
}),
pymParent,
eventEmitter,
opts
);
return {
on(eventName, callback) {
eventEmitter.on(eventName, callback);
},
login(token) {
pymParent.sendMessage('login', token);
},
logout() {
pymParent.sendMessage('logout');
}
};
};
export default Coral;
+7 -6
View File
@@ -276,9 +276,7 @@ export const fetchForgotPassword = (email) => (dispatch, getState) => {
export const logout = () => (dispatch) => {
return coralApi('/auth', {method: 'DELETE'}).then(() => {
if (!bowser.safari && !bowser.ios) {
Storage.removeItem('token');
}
Storage.removeItem('token');
// Reset the websocket.
resetWebsocket();
@@ -306,9 +304,7 @@ export const checkLogin = () => (dispatch) => {
coralApi('/auth')
.then((result) => {
if (!result.user) {
if (!bowser.safari && !bowser.ios) {
Storage.removeItem('token');
}
Storage.removeItem('token');
throw new Error('Not logged in');
}
@@ -325,6 +321,11 @@ export const checkLogin = () => (dispatch) => {
})
.catch((error) => {
console.error(error);
if (error.status && error.status === 401) {
// Unauthorized.
Storage.removeItem('token');
}
const errorMessage = error.translation_key ? t(`error.${error.translation_key}`) : error.toString();
dispatch(checkLoginFailure(errorMessage));
});
@@ -67,6 +67,7 @@ const handleResp = (res) => {
}
error.message = message;
error.status = res.status;
throw error;
});
} else if (res.status === 204) {
+7
View File
@@ -0,0 +1,7 @@
import {useBasename} from 'history';
import {browserHistory} from 'react-router';
import {BASE_PATH} from 'coral-framework/constants/url';
export const history = useBasename(() => browserHistory)({
basename: BASE_PATH
});
@@ -91,7 +91,7 @@ export default class FlagButton extends Component {
reason: null,
message
};
if (reason === 'I don\'t agree with this comment') {
if (reason === 'COMMENT_NOAGREE') {
postDontAgree(action)
.then(({data}) => {
if (itemType === 'COMMENTS') {
-9
View File
@@ -1,9 +0,0 @@
# Coral Talk Documentation
To preview the documentation, run:
```bash
docker run --rm --volume=$PWD:/srv/jekyll -p 127.0.0.1:4000:4000 -it jekyll/jekyll:pages jekyll serve
```
From the `docs` directory. Then visit: [http://127.0.0.1:4000/talk/](http://127.0.0.1:4000/talk/).
+2
View File
@@ -34,6 +34,8 @@ docs:
url: /docs/running/configuration/
- title: "Secrets"
url: /docs/running/secrets/
- title: "Plugins"
url: /docs/running/plugins/
- title: "Database Migrations"
url: /docs/running/migrations/
- title: "Architecture"
+3 -3
View File
@@ -58,10 +58,10 @@ Fork the Talk repo, clone it locally (no need to go through the install from sou
```
cd docs
docker build --no-cache -t mydocs .
docker run -v "$PWD:/src" -p 4000:4000 mydocs serve -H 0.0.0.0
docker run --rm --volume=$PWD:/srv/jekyll -p 127.0.0.1:4000:4000 -it jekyll/jekyll:pages jekyll serve
```
You can edit the files in docs with any editor and view the live updates in a browser by hitting `http://localhost:4000`.
You can edit the files in docs with any editor and view the live updates in a browser by hitting From the docs directory.
Then visit: [http://127.0.0.1:4000/talk/](http://127.0.0.1:4000/talk/).
Once you've made the changes, file a PR back to the `coralproject/talk` repo.
+1 -1
View File
@@ -18,4 +18,4 @@ While Talk can be installed in many ways, we support two install paths:
* [Install via Docker](docker) (deployment)
If you have success installing Talk in another way, please consider
[contributing to this documentation](faq#how-do-i-contribute-to-these-docs)!
[contributing to this documentation]({{ "/docs/faq/" | absolute_url }}#how-do-i-contribute-to-these-docs)!
+5 -3
View File
@@ -59,6 +59,10 @@ These are only used during the webpack build.
send keep alive messages through the websocket to keep the socket alive. (Default `30s`)
- `TALK_INSTALL_LOCK` (_optional for dynamic setup_) - When `TRUE`, disables the dynamic setup endpoint. (Default `FALSE`)
### Word Filter
- `TALK_DISABLE_AUTOFLAG_SUSPECT_WORDS` (_optional_) When `TRUE`, disables flagging of comments that match the suspect word filter. (Default `FALSE`)
### JWT
The following are configuration shared with every type of secret used.
@@ -125,6 +129,4 @@ The default could be read as:
### Plugins
- `TALK_PLUGINS_JSON` (_optional_) - used to specify the plugin config via the
environment.
- `TALK_DISABLE_AUTOFLAG_SUSPECT_WORDS` (_optional_) When `TRUE`, disables flagging of comments that match the suspect word filter. (Default `FALSE`)
Plugins configuration can be found on the [Plugins]({{ "/docs/running/plugins/" | absolute_url }}) page.
+25
View File
@@ -0,0 +1,25 @@
---
title: Plugins
permalink: /docs/running/plugins/
---
Configuration for the available plugins are stored in a JSON encoded string. The format
of this document are available with the [Plugins Overview]({{ "/docs/plugins/" | absolute_url }}).
You can override the plugin config by specifying the content in the `TALK_PLUGIN_JSON`
environment variable.
## Bundled Plugin Configuration
{:.no_toc}
Some of the core plugins that are bundled with Talk require specific configuration to be
available.
{% include toc %}
### Facebook Authentication
- `TALK_FACEBOOK_APP_ID` (*required*) - the Facebook app id for your Facebook
Login enabled app.
- `TALK_FACEBOOK_APP_SECRET` (*required*) - the Facebook app secret for your
Facebook Login enabled app.
+1 -1
View File
@@ -5,7 +5,7 @@ permalink: /docs/plugins/
## Recipes
Recipes are plugin templates provided by the Coral Core team. Developers can use these recipes to build their own plugins. You can find all the Talk recipes here: https://github.com/coralproject/talk-recipes/
Recipes are plugin templates provided by the Coral Core team. Developers can use these recipes to build their own plugins. You can find all the Talk recipes here: [https://github.com/coralproject/talk-recipes/](https://github.com/coralproject/talk-recipes/).
## Plugin Registration
@@ -1,24 +0,0 @@
# talk-plugin-facebook-auth
This plugin provides facebook authentication support for Talk.
## Configuration
This plugin looks for the following configuration from the environment:
- `TALK_FACEBOOK_APP_ID` (*required*) - the Facebook app id for your Facebook
Login enabled app.
- `TALK_FACEBOOK_APP_SECRET` (*required*) - the Facebook app secret for your
Facebook Login enabled app.
### License
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
@@ -17,7 +17,7 @@ const enhance = compose(
withFragments({
asset: gql`
fragment TalkFeaturedComments_Tab_asset on Asset {
featuredCommentsCount: totalCommentCount(tags: ["FEATURED"], excludeIgnored: $excludeIgnored)
featuredCommentsCount: totalCommentCount(tags: ["FEATURED"], excludeIgnored: $excludeIgnored) @skip(if: $hasComment)
}`,
}),
excludeIf((props) => props.asset.featuredCommentsCount === 0),
@@ -79,7 +79,7 @@ const enhance = compose(
asset: gql`
fragment TalkFeaturedComments_TabPane_asset on Asset {
id
featuredComments: comments(tags: ["FEATURED"], excludeIgnored: $excludeIgnored, deep: true) {
featuredComments: comments(tags: ["FEATURED"], excludeIgnored: $excludeIgnored, deep: true) @skip(if: $hasComment) {
nodes {
...${getDefinitionName(Comment.fragments.comment)}
}
+1 -1
View File
@@ -26,7 +26,7 @@
<p><a href="admin">Admin</a> - <a href="assets">All Assets</a></p>
<div id='coralStreamEmbed'></div>
<script src="embed.js" async onload="
Coral.Talk.render(document.getElementById('coralStreamEmbed'), {
window.TalkEmbed = Coral.Talk.render(document.getElementById('coralStreamEmbed'), {
talk: '<%= BASE_URL %>',
asset_url: '<%= asset_url ? asset_url : '' %>',
asset_id: '<%= asset_id ? asset_id : '' %>',