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