Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / modules / history / js / history.es6.js
1 /**
2  * @file
3  * JavaScript API for the History module, with client-side caching.
4  *
5  * May only be loaded for authenticated users, with the History module enabled.
6  */
7
8 (function ($, Drupal, drupalSettings, storage) {
9   const currentUserID = parseInt(drupalSettings.user.uid, 10);
10
11   // Any comment that is older than 30 days is automatically considered read,
12   // so for these we don't need to perform a request at all!
13   const secondsIn30Days = 2592000;
14   const thirtyDaysAgo = Math.round(new Date().getTime() / 1000) - secondsIn30Days;
15
16   // Use the data embedded in the page, if available.
17   let embeddedLastReadTimestamps = false;
18   if (drupalSettings.history && drupalSettings.history.lastReadTimestamps) {
19     embeddedLastReadTimestamps = drupalSettings.history.lastReadTimestamps;
20   }
21
22   /**
23    * @namespace
24    */
25   Drupal.history = {
26
27     /**
28      * Fetch "last read" timestamps for the given nodes.
29      *
30      * @param {Array} nodeIDs
31      *   An array of node IDs.
32      * @param {function} callback
33      *   A callback that is called after the requested timestamps were fetched.
34      */
35     fetchTimestamps(nodeIDs, callback) {
36       // Use the data embedded in the page, if available.
37       if (embeddedLastReadTimestamps) {
38         callback();
39         return;
40       }
41
42       $.ajax({
43         url: Drupal.url('history/get_node_read_timestamps'),
44         type: 'POST',
45         data: { 'node_ids[]': nodeIDs },
46         dataType: 'json',
47         success(results) {
48           Object.keys(results || {}).forEach((nodeID) => {
49             storage.setItem(`Drupal.history.${currentUserID}.${nodeID}`, results[nodeID]);
50           });
51           callback();
52         },
53       });
54     },
55
56     /**
57      * Get the last read timestamp for the given node.
58      *
59      * @param {number|string} nodeID
60      *   A node ID.
61      *
62      * @return {number}
63      *   A UNIX timestamp.
64      */
65     getLastRead(nodeID) {
66       // Use the data embedded in the page, if available.
67       if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
68         return parseInt(embeddedLastReadTimestamps[nodeID], 10);
69       }
70       return parseInt(storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0, 10);
71     },
72
73     /**
74      * Marks a node as read, store the last read timestamp client-side.
75      *
76      * @param {number|string} nodeID
77      *   A node ID.
78      */
79     markAsRead(nodeID) {
80       $.ajax({
81         url: Drupal.url(`history/${nodeID}/read`),
82         type: 'POST',
83         dataType: 'json',
84         success(timestamp) {
85           // If the data is embedded in the page, don't store on the client
86           // side.
87           if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
88             return;
89           }
90
91           storage.setItem(`Drupal.history.${currentUserID}.${nodeID}`, timestamp);
92         },
93       });
94     },
95
96     /**
97      * Determines whether a server check is necessary.
98      *
99      * Any content that is >30 days old never gets a "new" or "updated"
100      * indicator. Any content that was published before the oldest known reading
101      * also never gets a "new" or "updated" indicator, because it must've been
102      * read already.
103      *
104      * @param {number|string} nodeID
105      *   A node ID.
106      * @param {number} contentTimestamp
107      *   The time at which some content (e.g. a comment) was published.
108      *
109      * @return {bool}
110      *   Whether a server check is necessary for the given node and its
111      *   timestamp.
112      */
113     needsServerCheck(nodeID, contentTimestamp) {
114       // First check if the content is older than 30 days, then we can bail
115       // early.
116       if (contentTimestamp < thirtyDaysAgo) {
117         return false;
118       }
119
120       // Use the data embedded in the page, if available.
121       if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
122         return contentTimestamp > parseInt(embeddedLastReadTimestamps[nodeID], 10);
123       }
124
125       const minLastReadTimestamp = parseInt(storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0, 10);
126       return contentTimestamp > minLastReadTimestamp;
127     },
128   };
129 }(jQuery, Drupal, drupalSettings, window.localStorage));