Compare commits

..
20 Commits
Author SHA1 Message Date
Kim Gardner a8368eb78d Merge pull request #1218 from coralproject/ci-fix
Disabling Firefox/Edge on E2E until fix pass
2017-12-18 13:58:02 -06:00
Wyatt Johnson e88bac6e0f Merge branch 'master' into ci-fix 2017-12-18 12:45:40 -07:00
Wyatt Johnson 583ab0ff74 disabling firefox,edge 2017-12-18 12:42:58 -07:00
Wyatt Johnson fb7ad76b8b Merge pull request #1215 from coralproject/ci-fix
*Fixes for sorted window handler
2017-12-18 11:36:47 -07:00
Wyatt Johnson f7d1543aa3 fixes for sorted window handler 2017-12-18 10:24:11 -07:00
Kim Gardner 950a35310b Merge pull request #1212 from coralproject/user-detail-load-more-fix
Fix load more in UserDetail issue
2017-12-18 10:23:50 -06:00
Kiwi 9af7ae0357 Merge branch 'master' into user-detail-load-more-fix 2017-12-18 17:12:36 +01:00
Wyatt Johnson 073eea2847 Merge pull request #1213 from coralproject/version-bump
Version Bump
2017-12-18 09:11:52 -07:00
Wyatt Johnson c699e044fd Update package.json 2017-12-18 08:55:49 -07:00
Kiwi 4ef7abc132 Merge branch 'master' into user-detail-load-more-fix 2017-12-18 16:55:31 +01:00
Wyatt Johnson 9e486f3a9d Merge pull request #1210 from coralproject/redis-optim
Redis Optimization Pass
2017-12-18 08:55:18 -07:00
Chi Vinh Le fbcd390220 Fix load more issue 2017-12-18 16:52:57 +01:00
Wyatt Johnson f0330ed21c fixed version paths 2017-12-18 08:35:17 -07:00
Wyatt Johnson 75a944eba8 upgrades, fixes to comment count logic 2017-12-18 08:02:43 -07:00
Wyatt Johnson 6850dd1a53 redis optim
- removes call for comment count when we already have
  totalCommentCount
- removes job processor cleaner on non-processing nodes
- fixed some template issues
2017-12-15 15:49:56 -06:00
Wyatt Johnson 98ef60a48e Merge pull request #1205 from stephendonner/patch-1
s/setup/setup
2017-12-13 12:34:30 -06:00
Wyatt Johnson 8323344d7d Merge branch 'master' into patch-1 2017-12-13 12:26:24 -06:00
Wyatt Johnson fbecc363cf Merge pull request #1206 from coralproject/feature/infer-asset-url
Fix logic to generate asset_url even if the asset_id is provided
2017-12-13 12:25:27 -06:00
Jeff Nelson df925f5a1a Fix logic to generate asset_url even if the asset_id is provided so
an error is avoided
2017-12-13 07:38:10 -06:00
Stephen Donner 30073b88f1 s/setup/setup 2017-12-13 03:49:35 -06:00
16 changed files with 385 additions and 258 deletions
@@ -128,7 +128,7 @@ class UserDetailContainer extends React.Component {
const LOAD_MORE_QUERY = gql`
query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Cursor, $author_id: ID!, $statuses: [COMMENT_STATUS!]) {
comments(query: {limit: $limit, cursor: $cursor, author_id: $author_id, statuses: $statuses}) {
...CoralAdmin_Moderation_CommentConnection
...CoralAdmin_UserDetail_CommentConnection
}
}
${commentConnectionFragment}
+2 -16
View File
@@ -38,7 +38,7 @@ function applyToCommentsOrigin(root, callback) {
function findAndInsertComment(parent, comment) {
const isAsset = parent.__typename === 'Asset';
const [connectionField, countField, action] = isAsset
? ['comments', 'commentCount', '$unshift']
? ['comments', 'totalCommentCount', '$unshift']
: ['replies', 'replyCount', '$push'];
if (
@@ -67,19 +67,12 @@ function findAndInsertComment(parent, comment) {
}
export function insertCommentIntoEmbedQuery(root, comment) {
// Increase total comment count by one.
root = update(root, {
asset: {
totalCommentCount: {$apply: (c) => c + 1},
},
});
return applyToCommentsOrigin(root, (origin) => findAndInsertComment(origin, comment));
}
function findAndRemoveComment(parent, id) {
const [connectionField, countField] = parent.__typename === 'Asset'
? ['comments', 'commentCount']
? ['comments', 'totalCommentCount']
: ['replies', 'replyCount'];
const connection = parent[connectionField];
@@ -104,13 +97,6 @@ function findAndRemoveComment(parent, id) {
}
export function removeCommentFromEmbedQuery(root, id) {
// Decrease total comment by one.
root = update(root, {
asset: {
totalCommentCount: {$apply: (c) => c - 1},
},
});
return applyToCommentsOrigin(root, (origin) => findAndRemoveComment(origin, id));
}
@@ -324,7 +324,6 @@ const fragments = {
charCount
requireEmailConfirmation
}
commentCount @skip(if: $hasComment)
totalCommentCount @skip(if: $hasComment)
comments(query: {limit: 10, excludeIgnored: $excludeIgnored, sortOrder: $sortOrder, sortBy: $sortBy}) @skip(if: $hasComment) {
nodes {
@@ -345,7 +344,6 @@ const fragments = {
const mapStateToProps = (state) => ({
auth: state.auth,
refetching: state.embed.refetching,
commentCountCache: state.stream.commentCountCache,
activeReplyBox: state.stream.activeReplyBox,
commentId: state.stream.commentId,
assetId: state.stream.assetId,
+2 -3
View File
@@ -70,10 +70,9 @@ export class Talk {
// Extract the asset url.
if (opts.asset_url) {
query.asset_url = opts.asset_url;
} else if (!opts.asset_id) {
} else {
// The asset url was not provided and the asset id was also not provided,
// we need to infer the asset url from details on the page.
// The asset url was not provided so we need to infer the asset url from // details on the page.
try {
query.asset_url = document.querySelector('link[rel="canonical"]').href;
+4
View File
@@ -24,6 +24,10 @@ const CONFIG = {
// indexes.
CREATE_MONGO_INDEXES: process.env.DISABLE_CREATE_MONGO_INDEXES !== 'TRUE',
// SETTINGS_CACHE_TIME is the time that we'll cache the settings in redis before
// fetching again.
SETTINGS_CACHE_TIME: ms(process.env.TALK_SETTINGS_CACHE_TIME || '1hr'),
//------------------------------------------------------------------------------
// JWT based configuration
//------------------------------------------------------------------------------
+2 -2
View File
@@ -26,7 +26,7 @@ to persist data. The following versions are supported:
An optional dependency for Talk is
[Docker](https://www.docker.com/community-edition#/download){:target="_blank"}.
It is used during [development](#development) to setup the database and can be
It is used during [development](#development) to set up the database and can be
used to [install via Docker](#installation-from-docker). We have tested Talk
and this documentation with versions {{ site.versions.docker }}.
@@ -182,4 +182,4 @@ machine.
At this point you've successfully installed, configured, and ran your very own
instance of Talk! Continue through this documentation on this site to learn more
on how to configure, develop with, and contribute to Talk!
on how to configure, develop with, and contribute to Talk!
+1 -1
View File
@@ -178,7 +178,7 @@ const createComment = async (context, {tags = [], body, asset_id, parent_id = nu
// just added a new comment, hence the counts should be updated. We should
// perform these increments in the event that we do have a new comment that
// is approved or without a comment.
if (status === 'NONE' || status === 'APPROVED') {
if (status === 'NONE' || status === 'ACCEPTED') {
if (parent_id === null) {
Comments.parentCountByAssetID.incr(asset_id);
}
+2 -2
View File
@@ -9,13 +9,13 @@ module.exports = {
globals_path: './test/e2e/globals',
selenium: {
start_process: true,
server_path: 'node_modules/selenium-standalone/.selenium/selenium-server/3.6.0-server.jar',
server_path: 'node_modules/selenium-standalone/.selenium/selenium-server/3.7.1-server.jar',
log_path: './test/e2e/',
host: '127.0.0.1',
port: 6666,
cli_args: {
'webdriver.chrome.driver': 'node_modules/selenium-standalone/.selenium/chromedriver/2.33-x64-chromedriver',
'webdriver.gecko.driver': 'node_modules/selenium-standalone/.selenium/geckodriver/0.19.0-x64-geckodriver',
'webdriver.gecko.driver': 'node_modules/selenium-standalone/.selenium/geckodriver/0.19.1-x64-geckodriver',
}
},
test_settings: {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "talk",
"version": "3.8.2",
"version": "3.8.3",
"description": "A better commenting experience from Mozilla, The New York Times, and the Washington Post. https://coralproject.net",
"main": "app.js",
"private": true,
+2 -2
View File
@@ -110,9 +110,9 @@ router.use('/api/v1/graph/ql', apollo.graphqlExpress(createGraphOptions));
if (process.env.NODE_ENV !== 'production') {
// Interactive graphiql interface.
router.use('/api/v1/graph/iql', (req, res) => {
router.use('/api/v1/graph/iql', staticTemplate, (req, res) => {
res.render('graphiql', {
endpointURL: `${req.app.locals.BASE_URL}api/v1/graph/ql`
endpointURL: 'api/v1/graph/ql'
});
});
+4 -1
View File
@@ -8,7 +8,10 @@ E2E_MAX_RETRIES=${E2E_MAX_RETRIES:-1}
# Safari >= 8 has issues connecting to browserstack-local. Safari < 8 is too old.
# IE 64bit has issues with receiving keyboard input. Let's wait for them to fix it.
BROWSERS="chrome,firefox,edge" #ie safari
# FIXME: disabled firefox,edge until fixing pass is done
# BROWSERS="chrome,firefox,edge" #ie safari
BROWSERS="chrome"
if [[ "${CIRCLE_BRANCH}" == "master" && -n "$BROWSERSTACK_KEY" ]]; then
echo Testing on browserstack
+15 -4
View File
@@ -9,7 +9,8 @@ const kue = require('kue');
// singleton Queue instance. So you can configure and use only a single Queue
// object within your node.js process.
let queue = null;
const getQueue = () => {
let isManaging = false;
const getQueue = ({managed = false} = {}) => {
if (queue) {
return queue;
}
@@ -21,8 +22,16 @@ const getQueue = () => {
}
});
// Watch for stuck jobs to manage.
queue.watchStuckJobs(1000);
// If this is a managed queue, and we aren't managing yet, then start the
// management.
if (managed && !isManaging) {
// Watch for stuck jobs to manage.
queue.watchStuckJobs(60000);
// Mark that we've now started management routines.
isManaging = true;
}
return queue;
};
@@ -67,7 +76,9 @@ class Task {
* Process jobs for the queue.
*/
process(callback) {
return getQueue().process(this.name, callback);
// Get the queue in managed mode.
return getQueue({managed: true}).process(this.name, callback);
}
/**
+2 -1
View File
@@ -2,6 +2,7 @@ const SettingModel = require('../models/setting');
const cache = require('./cache');
const errors = require('../errors');
const {dotize} = require('./utils');
const {SETTINGS_CACHE_TIME} = require('../config');
/**
* The selector used to uniquely identify the settings document.
@@ -35,7 +36,7 @@ module.exports = class SettingsService {
if (process.env.NODE_ENV === 'production') {
// When in production, wrap the settings retrieval with a cache.
const settings = await cache.h.wrap('settings', fields, 60, () => retrieve(fields));
const settings = await cache.h.wrap('settings', fields, SETTINGS_CACHE_TIME / 1000, () => retrieve(fields));
return new SettingModel(settings);
}
+22 -2
View File
@@ -25,8 +25,28 @@ class SortedWindowHandler {
*/
windowHandles(callback) {
this.client.windowHandles((result) => {
this.handles = this.handles.filter((handle) => result.value.includes(handle));
const remaining = result.value.filter((handle) => !this.handles.includes(handle));
if (Array.isArray(result.value)) {
this.handles = this.handles.filter((handle) => {
for (let i = 0; i < result.value.length; i++) {
if (result.value[i] === handle) {
return true;
}
}
return false;
});
} else {
this.handles = [];
}
const remaining = result.value.filter((handle) => {
for (let i = 0; i < this.handles.length; i++) {
if (this.handles[i] === handle) {
return false;
}
}
return true;
});
if (remaining.length === 1) {
this.handles.push(remaining[0]);
}
+1 -1
View File
@@ -50,7 +50,7 @@
}
}
// We don't use safe-serialize for location, because it's not client input.
var fetchURL = locationQuery(otherParams, '<%= endpointURL %>');
var fetchURL = locationQuery(otherParams, '<%= BASE_URL %><%= endpointURL %>');
// Defines a GraphQL fetcher using the fetch API.
function graphQLFetcher(graphQLParams) {
+324 -219
View File
File diff suppressed because it is too large Load Diff