Chris@0: /** Chris@0: * Attaches behaviors for the Tracker module's History module integration. Chris@0: * Chris@0: * May only be loaded for authenticated users, with the History module enabled. Chris@0: */ Chris@17: (function($, Drupal, window) { Chris@0: function processNodeNewIndicators($placeholders) { Chris@0: const newNodeString = Drupal.t('new'); Chris@0: const updatedNodeString = Drupal.t('updated'); Chris@0: Chris@0: $placeholders.each((index, placeholder) => { Chris@17: const timestamp = parseInt( Chris@17: placeholder.getAttribute('data-history-node-timestamp'), Chris@17: 10, Chris@17: ); Chris@0: const nodeID = placeholder.getAttribute('data-history-node-id'); Chris@0: const lastViewTimestamp = Drupal.history.getLastRead(nodeID); Chris@0: Chris@0: if (timestamp > lastViewTimestamp) { Chris@17: const message = Chris@17: lastViewTimestamp === 0 ? newNodeString : updatedNodeString; Chris@0: $(placeholder).append(`${message}`); Chris@0: } Chris@0: }); Chris@0: } Chris@0: Chris@0: function processNewRepliesIndicators($placeholders) { Chris@0: // Figure out which placeholders need the "x new" replies links. Chris@0: const placeholdersToUpdate = {}; Chris@0: $placeholders.each((index, placeholder) => { Chris@17: const timestamp = parseInt( Chris@17: placeholder.getAttribute('data-history-node-last-comment-timestamp'), Chris@17: 10, Chris@17: ); Chris@17: const nodeID = placeholder.previousSibling.previousSibling.getAttribute( Chris@17: 'data-history-node-id', Chris@17: ); Chris@0: const lastViewTimestamp = Drupal.history.getLastRead(nodeID); Chris@0: Chris@0: // Queue this placeholder's "X new" replies link to be downloaded from the Chris@0: // server. Chris@0: if (timestamp > lastViewTimestamp) { Chris@0: placeholdersToUpdate[nodeID] = placeholder; Chris@0: } Chris@0: }); Chris@0: Chris@0: // Perform an AJAX request to retrieve node view timestamps. Chris@0: const nodeIDs = Object.keys(placeholdersToUpdate); Chris@0: if (nodeIDs.length === 0) { Chris@0: return; Chris@0: } Chris@0: $.ajax({ Chris@0: url: Drupal.url('comments/render_new_comments_node_links'), Chris@0: type: 'POST', Chris@0: data: { 'node_ids[]': nodeIDs }, Chris@0: dataType: 'json', Chris@0: success(results) { Chris@17: Object.keys(results || {}).forEach(nodeID => { Chris@14: if (placeholdersToUpdate.hasOwnProperty(nodeID)) { Chris@0: const url = results[nodeID].first_new_comment_link; Chris@17: const text = Drupal.formatPlural( Chris@17: results[nodeID].new_comment_count, Chris@17: '1 new', Chris@17: '@count new', Chris@17: ); Chris@17: $(placeholdersToUpdate[nodeID]).append( Chris@17: `
${text}`, Chris@17: ); Chris@0: } Chris@14: }); Chris@0: }, Chris@0: }); Chris@0: } Chris@17: Chris@17: /** Chris@17: * Render "new" and "updated" node indicators, as well as "X new" replies links. Chris@17: */ Chris@17: Drupal.behaviors.trackerHistory = { Chris@17: attach(context) { Chris@17: // Find all "new" comment indicator placeholders newer than 30 days ago that Chris@17: // have not already been read after their last comment timestamp. Chris@17: const nodeIDs = []; Chris@17: const $nodeNewPlaceholders = $(context) Chris@17: .find('[data-history-node-timestamp]') Chris@17: .once('history') Chris@17: .filter(function() { Chris@17: const nodeTimestamp = parseInt( Chris@17: this.getAttribute('data-history-node-timestamp'), Chris@17: 10, Chris@17: ); Chris@17: const nodeID = this.getAttribute('data-history-node-id'); Chris@17: if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) { Chris@17: nodeIDs.push(nodeID); Chris@17: return true; Chris@17: } Chris@17: Chris@17: return false; Chris@17: }); Chris@17: Chris@17: // Find all "new" comment indicator placeholders newer than 30 days ago that Chris@17: // have not already been read after their last comment timestamp. Chris@17: const $newRepliesPlaceholders = $(context) Chris@17: .find('[data-history-node-last-comment-timestamp]') Chris@17: .once('history') Chris@17: .filter(function() { Chris@17: const lastCommentTimestamp = parseInt( Chris@17: this.getAttribute('data-history-node-last-comment-timestamp'), Chris@17: 10, Chris@17: ); Chris@17: const nodeTimestamp = parseInt( Chris@17: this.previousSibling.previousSibling.getAttribute( Chris@17: 'data-history-node-timestamp', Chris@17: ), Chris@17: 10, Chris@17: ); Chris@17: // Discard placeholders that have zero comments. Chris@17: if (lastCommentTimestamp === nodeTimestamp) { Chris@17: return false; Chris@17: } Chris@17: const nodeID = this.previousSibling.previousSibling.getAttribute( Chris@17: 'data-history-node-id', Chris@17: ); Chris@17: if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) { Chris@17: if (nodeIDs.indexOf(nodeID) === -1) { Chris@17: nodeIDs.push(nodeID); Chris@17: } Chris@17: return true; Chris@17: } Chris@17: Chris@17: return false; Chris@17: }); Chris@17: Chris@17: if ( Chris@17: $nodeNewPlaceholders.length === 0 && Chris@17: $newRepliesPlaceholders.length === 0 Chris@17: ) { Chris@17: return; Chris@17: } Chris@17: Chris@17: // Fetch the node read timestamps from the server. Chris@17: Drupal.history.fetchTimestamps(nodeIDs, () => { Chris@17: processNodeNewIndicators($nodeNewPlaceholders); Chris@17: processNewRepliesIndicators($newRepliesPlaceholders); Chris@17: }); Chris@17: }, Chris@17: }; Chris@17: })(jQuery, Drupal, window);