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);