mirror of
https://github.com/wassname/talk.git
synced 2026-07-07 19:58:38 +08:00
Merge branch 'master' into master
This commit is contained in:
@@ -190,20 +190,24 @@ class ModerationQueue extends React.Component {
|
||||
componentDidUpdate (prev) {
|
||||
const {commentCount, selectedCommentId} = this.props;
|
||||
|
||||
// If the user just moderated the last (visible) comment
|
||||
// AND there are more comments available on the server,
|
||||
// go ahead and load more comments
|
||||
if (prev.comments.length > 0 && this.getCommentCountWithoutDagling() === 0 && commentCount > 0) {
|
||||
this.props.loadMore();
|
||||
const switchedToMultiMode = prev.singleView && !this.props.singleView;
|
||||
const switchedMode = prev.singleView !== this.props.singleView;
|
||||
const selectedDifferentComment = prev.selectedCommentId !== selectedCommentId && selectedCommentId;
|
||||
const moderatedLastComment = prev.comments.length > 0 && this.getCommentCountWithoutDagling() === 0;
|
||||
const hasMoreComment = commentCount > 0;
|
||||
|
||||
if (switchedToMultiMode) {
|
||||
|
||||
// Reflow virtual list.
|
||||
this.reflowList();
|
||||
}
|
||||
|
||||
// Scroll to selected comment.
|
||||
if (prev.selectedCommentId !== selectedCommentId && this.listRef) {
|
||||
if (switchedMode || selectedDifferentComment) {
|
||||
this.scrollToSelectedComment();
|
||||
}
|
||||
|
||||
const view = this.state.view;
|
||||
const index = view.findIndex(({id}) => id === selectedCommentId);
|
||||
|
||||
this.listRef.scrollToRow(index);
|
||||
if (moderatedLastComment && hasMoreComment) {
|
||||
this.props.loadMore();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,6 +246,17 @@ class ModerationQueue extends React.Component {
|
||||
this.listRef = list;
|
||||
};
|
||||
|
||||
scrollToSelectedComment = (props = this.props, state = this.state) => {
|
||||
if (props.singleMode) {
|
||||
document.querySelector(`#comment_${props.selectedCommentId}`).scrollIntoView();
|
||||
}
|
||||
else if(this.listRef) {
|
||||
const view = state.view;
|
||||
const index = view.findIndex(({id}) => id === props.selectedCommentId);
|
||||
this.listRef.scrollToRow(index);
|
||||
}
|
||||
}
|
||||
|
||||
viewNewComments = (callback) => {
|
||||
this.setState(resetCursors, () => {
|
||||
this.reflowList();
|
||||
@@ -372,6 +387,7 @@ class ModerationQueue extends React.Component {
|
||||
rejectComment={props.rejectComment}
|
||||
currentAsset={props.currentAsset}
|
||||
currentUserId={this.props.currentUserId}
|
||||
dangling={!this.props.commentBelongToQueue(this.props.activeTab, comment)}
|
||||
/>;
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -72,8 +72,10 @@ class SharedCacheDataLoader extends DataLoader {
|
||||
constructor(prefix, expiry, batchLoadFn, options) {
|
||||
super(SharedCacheDataLoader.batchLoadFn(prefix, expiry, batchLoadFn), options);
|
||||
|
||||
// Expiry is provided as a number in ms, we're using commands optimized for
|
||||
// seconds, so convert this to seconds.
|
||||
this._expiry = Math.floor(expiry / 1000);
|
||||
this._prefix = prefix;
|
||||
this._expiry = expiry;
|
||||
this._keyFunc = SharedCacheDataLoader.keyFunc(this._prefix);
|
||||
}
|
||||
|
||||
|
||||
+34
-3
@@ -5,6 +5,7 @@ const debug = require('debug')('talk:graph:subscriptions');
|
||||
const pubsub = require('../services/pubsub');
|
||||
const schema = require('./schema');
|
||||
const Context = require('./context');
|
||||
const plugins = require('../services/plugins');
|
||||
|
||||
const {deserializeUser} = require('../services/subscriptions');
|
||||
const setupFunctions = require('./setupFunctions');
|
||||
@@ -16,16 +17,42 @@ const {
|
||||
|
||||
const {BASE_PATH} = require('../url');
|
||||
|
||||
const onConnect = ({token}, connection) => {
|
||||
// Collect all the plugin hooks that should be executed onConnect and
|
||||
// onDisconnect.
|
||||
const hooks = plugins.get('server', 'websockets')
|
||||
.map(({plugin, websockets}) => {
|
||||
debug(`added websocket hooks ${Object.keys(websockets)} from plugin '${plugin.name}'`);
|
||||
|
||||
return websockets;
|
||||
})
|
||||
.reduce((hooks, {onConnect = null, onDisconnect = null}) => {
|
||||
if (onConnect) {
|
||||
hooks.onConnect.push(onConnect);
|
||||
}
|
||||
|
||||
if (onDisconnect) {
|
||||
hooks.onDisconnect.push(onDisconnect);
|
||||
}
|
||||
|
||||
return hooks;
|
||||
}, {
|
||||
onConnect: [],
|
||||
onDisconnect: [],
|
||||
});
|
||||
|
||||
const onConnect = async (connectionParams, connection) => {
|
||||
|
||||
// Attach the token from the connection options if it was provided.
|
||||
if (token) {
|
||||
if (connectionParams.token) {
|
||||
|
||||
debug('token sent via onConnect, attaching to the headers of the upgrade request');
|
||||
|
||||
// Attach it to the upgrade request.
|
||||
connection.upgradeReq.headers['authorization'] = `Bearer ${token}`;
|
||||
connection.upgradeReq.headers['authorization'] = `Bearer ${connectionParams.token}`;
|
||||
}
|
||||
|
||||
// Call all the hooks.
|
||||
await Promise.all(hooks.onConnect.map((hook) => hook(connectionParams, connection)));
|
||||
};
|
||||
|
||||
const onOperation = (parsedMessage, baseParams, connection) => {
|
||||
@@ -52,6 +79,9 @@ const onOperation = (parsedMessage, baseParams, connection) => {
|
||||
return baseParams;
|
||||
};
|
||||
|
||||
const onDisconnect = (connection) =>
|
||||
Promise.all(hooks.onDisconnect.map((hook) => hook(connection)));
|
||||
|
||||
/**
|
||||
* This creates a new subscription manager.
|
||||
*/
|
||||
@@ -62,6 +92,7 @@ const createSubscriptionManager = (server) => new SubscriptionServer({
|
||||
setupFunctions,
|
||||
}),
|
||||
onConnect,
|
||||
onDisconnect,
|
||||
onOperation,
|
||||
keepAlive: ms(KEEP_ALIVE)
|
||||
}, {
|
||||
|
||||
@@ -78,7 +78,6 @@
|
||||
"babel-preset-es2015": "6.24.1",
|
||||
"babel-preset-react": "^6.23.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"body-parser": "1.18.2",
|
||||
"bowser": "^1.7.2",
|
||||
"cli-table": "^0.3.1",
|
||||
"clipboard": "^1.7.1",
|
||||
|
||||
@@ -57,6 +57,10 @@ const hookSchemas = {
|
||||
resolvers: Joi.object().pattern(/\w/, Joi.object().pattern(/(?:__resolveType|\w+)/, Joi.func())),
|
||||
typeDefs: Joi.string(),
|
||||
schemaLevelResolveFunction: Joi.func(),
|
||||
websockets: Joi.object({
|
||||
onConnect: Joi.func(),
|
||||
onDisconnect: Joi.func(),
|
||||
}),
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
const accepts = require('accepts');
|
||||
const apollo = require('graphql-server-express');
|
||||
const authentication = require('../middleware/authentication');
|
||||
const bodyParser = require('body-parser');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const debug = require('debug')('talk:routes');
|
||||
const enabled = require('debug').enabled;
|
||||
@@ -82,7 +81,7 @@ router.use('/embed', staticTemplate, require('./embed'));
|
||||
router.use(cookieParser());
|
||||
|
||||
// Parse the body json if it's there.
|
||||
router.use(bodyParser.json());
|
||||
router.use(express.json());
|
||||
|
||||
const passportDebug = require('debug')('talk:passport');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user