diff --git a/README.md b/README.md index 4ea9ff0e4..68547e7a8 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ sign and verify tokens via a `HS256` algorithm. - `TALK_RECAPTCHA_SECRET` (*required for reCAPTCHA support*) - server secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout. - `TALK_RECAPTCHA_PUBLIC` (*required for reCAPTCHA support*) - client secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout. - `TALK_PLUGINS_JSON` (_optional_) - used to specify the plugin config via the environment +- `TALK_KEEP_ALIVE` (_optional_) - The keepalive timeout that should be used to send keep alive messages through the websocket to keep the socket alive. (Default `30s`) Refer to the wiki page on [Configuration Loading](https://github.com/coralproject/talk/wiki/Configuration-Loading) for alternative methods of loading configuration during development. diff --git a/client/coral-admin/src/routes/Moderation/components/Comment.js b/client/coral-admin/src/routes/Moderation/components/Comment.js index 3d3e2803f..bffe73a1c 100644 --- a/client/coral-admin/src/routes/Moderation/components/Comment.js +++ b/client/coral-admin/src/routes/Moderation/components/Comment.js @@ -129,7 +129,7 @@ class Comment extends React.Component {
Story: {comment.asset.title} {!props.currentAsset && - {t('modqueue.moderate')}} + {t('modqueue.moderate')}}
{ -
+
); }; @@ -89,7 +89,7 @@ const StorySearch = (props) => { StorySearch.propTypes = { search: PropTypes.func.isRequired, goToStory: PropTypes.func.isRequired, - closeSearch: PropTypes.func.isRequired, + clearAndCloseSearch: PropTypes.func.isRequired, moderation: PropTypes.object.isRequired, handleSearchChange: PropTypes.func.isRequired, assetId: PropTypes.string diff --git a/client/coral-admin/src/routes/Moderation/containers/StorySearch.js b/client/coral-admin/src/routes/Moderation/containers/StorySearch.js index f4ab6f23e..d5a0ad243 100644 --- a/client/coral-admin/src/routes/Moderation/containers/StorySearch.js +++ b/client/coral-admin/src/routes/Moderation/containers/StorySearch.js @@ -3,6 +3,7 @@ import {compose, gql} from 'react-apollo'; import StorySearch from '../components/StorySearch'; import {withRouter} from 'react-router'; import withQuery from 'coral-framework/hocs/withQuery'; +import {isEmpty} from 'lodash'; class StorySearchContainer extends React.Component { constructor(props) { @@ -13,6 +14,23 @@ class StorySearchContainer extends React.Component { }; } + componentWillUnmount() { + this.props.storySearchChange(''); + } + + clearSearch = () => { + this.setState({searchValue: ''}, () => { + this.search(); + }); + } + + clearAndCloseSearch = () => { + if (!isEmpty(this.state.searchValue)) { + this.clearSearch(); + } + this.props.closeSearch(); + } + handleSearchChange = (e) => { const {value} = e.target; this.setState({ @@ -23,7 +41,7 @@ class StorySearchContainer extends React.Component { handleEsc = (e) => { if (e.key === 'Escape') { e.preventDefault(); - this.props.closeSearch(); + this.clearAndCloseSearch(); } } @@ -40,15 +58,15 @@ class StorySearchContainer extends React.Component { } goToStory = (id) => { - const {router, closeSearch} = this.props; + const {router} = this.props; router.push(`/admin/moderate/all/${id}`); - closeSearch(); + this.clearAndCloseSearch(); } goToModerateAll = () => { - const {router, closeSearch} = this.props; + const {router} = this.props; router.push('/admin/moderate/all'); - closeSearch(); + this.clearAndCloseSearch(); } render () { @@ -61,6 +79,7 @@ class StorySearchContainer extends React.Component { handleEnter={this.handleEnter} searchValue={this.state.searchValue} handleSearchChange={this.handleSearchChange} + clearAndCloseSearch={this.clearAndCloseSearch} {...this.props} /> ); diff --git a/config.js b/config.js index 3d75f44a8..02f95d070 100644 --- a/config.js +++ b/config.js @@ -56,7 +56,11 @@ const CONFIG = { // The URL for this Talk Instance as viewable from the outside. ROOT_URL: 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', + //------------------------------------------------------------------------------ // Recaptcha configuration //------------------------------------------------------------------------------ diff --git a/graph/subscriptions.js b/graph/subscriptions.js index 2ba0c2c1f..ec2d5b786 100644 --- a/graph/subscriptions.js +++ b/graph/subscriptions.js @@ -10,6 +10,11 @@ const plugins = require('../services/plugins'); const {deserializeUser} = require('../services/subscriptions'); +const ms = require('ms'); +const { + KEEP_ALIVE +} = require('../config'); + const { SUBSCRIBE_COMMENT_ACCEPTED, SUBSCRIBE_COMMENT_REJECTED, @@ -119,7 +124,8 @@ const createSubscriptionManager = (server) => new SubscriptionServer({ }; return baseParams; - } + }, + keepAlive: ms(KEEP_ALIVE) }, { server, path: '/api/v1/live'