5df3494a9cd263a2895b66e13c5872ee9cc29334
[yaffs-website] / web / core / modules / tracker / js / tracker-history.es6.js
1 /**
2  * Attaches behaviors for the Tracker module's History module integration.
3  *
4  * May only be loaded for authenticated users, with the History module enabled.
5  */
6 (function ($, Drupal, window) {
7   /**
8    * Render "new" and "updated" node indicators, as well as "X new" replies links.
9    */
10   Drupal.behaviors.trackerHistory = {
11     attach(context) {
12       // Find all "new" comment indicator placeholders newer than 30 days ago that
13       // have not already been read after their last comment timestamp.
14       const nodeIDs = [];
15       const $nodeNewPlaceholders = $(context)
16         .find('[data-history-node-timestamp]')
17         .once('history')
18         .filter(function () {
19           const nodeTimestamp = parseInt(this.getAttribute('data-history-node-timestamp'), 10);
20           const nodeID = this.getAttribute('data-history-node-id');
21           if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) {
22             nodeIDs.push(nodeID);
23             return true;
24           }
25
26           return false;
27         });
28
29       // Find all "new" comment indicator placeholders newer than 30 days ago that
30       // have not already been read after their last comment timestamp.
31       const $newRepliesPlaceholders = $(context)
32         .find('[data-history-node-last-comment-timestamp]')
33         .once('history')
34         .filter(function () {
35           const lastCommentTimestamp = parseInt(this.getAttribute('data-history-node-last-comment-timestamp'), 10);
36           const nodeTimestamp = parseInt(this.previousSibling.previousSibling.getAttribute('data-history-node-timestamp'), 10);
37           // Discard placeholders that have zero comments.
38           if (lastCommentTimestamp === nodeTimestamp) {
39             return false;
40           }
41           const nodeID = this.previousSibling.previousSibling.getAttribute('data-history-node-id');
42           if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
43             if (nodeIDs.indexOf(nodeID) === -1) {
44               nodeIDs.push(nodeID);
45             }
46             return true;
47           }
48
49           return false;
50         });
51
52       if ($nodeNewPlaceholders.length === 0 && $newRepliesPlaceholders.length === 0) {
53         return;
54       }
55
56       // Fetch the node read timestamps from the server.
57       Drupal.history.fetchTimestamps(nodeIDs, () => {
58         processNodeNewIndicators($nodeNewPlaceholders);
59         processNewRepliesIndicators($newRepliesPlaceholders);
60       });
61     },
62   };
63
64   function processNodeNewIndicators($placeholders) {
65     const newNodeString = Drupal.t('new');
66     const updatedNodeString = Drupal.t('updated');
67
68     $placeholders.each((index, placeholder) => {
69       const timestamp = parseInt(placeholder.getAttribute('data-history-node-timestamp'), 10);
70       const nodeID = placeholder.getAttribute('data-history-node-id');
71       const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
72
73       if (timestamp > lastViewTimestamp) {
74         const message = (lastViewTimestamp === 0) ? newNodeString : updatedNodeString;
75         $(placeholder).append(`<span class="marker">${message}</span>`);
76       }
77     });
78   }
79
80   function processNewRepliesIndicators($placeholders) {
81     // Figure out which placeholders need the "x new" replies links.
82     const placeholdersToUpdate = {};
83     $placeholders.each((index, placeholder) => {
84       const timestamp = parseInt(placeholder.getAttribute('data-history-node-last-comment-timestamp'), 10);
85       const nodeID = placeholder.previousSibling.previousSibling.getAttribute('data-history-node-id');
86       const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
87
88       // Queue this placeholder's "X new" replies link to be downloaded from the
89       // server.
90       if (timestamp > lastViewTimestamp) {
91         placeholdersToUpdate[nodeID] = placeholder;
92       }
93     });
94
95     // Perform an AJAX request to retrieve node view timestamps.
96     const nodeIDs = Object.keys(placeholdersToUpdate);
97     if (nodeIDs.length === 0) {
98       return;
99     }
100     $.ajax({
101       url: Drupal.url('comments/render_new_comments_node_links'),
102       type: 'POST',
103       data: { 'node_ids[]': nodeIDs },
104       dataType: 'json',
105       success(results) {
106         for (const nodeID in results) {
107           if (results.hasOwnProperty(nodeID) && placeholdersToUpdate.hasOwnProperty(nodeID)) {
108             const url = results[nodeID].first_new_comment_link;
109             const text = Drupal.formatPlural(results[nodeID].new_comment_count, '1 new', '@count new');
110             $(placeholdersToUpdate[nodeID]).append(`<br /><a href="${url}">${text}</a>`);
111           }
112         }
113       },
114     });
115   }
116 }(jQuery, Drupal, window));