3 * JavaScript API for the History module, with client-side caching.
5 * May only be loaded for authenticated users, with the History module enabled.
8 (function($, Drupal, drupalSettings, storage) {
9 const currentUserID = parseInt(drupalSettings.user.uid, 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;
15 Math.round(new Date().getTime() / 1000) - secondsIn30Days;
17 // Use the data embedded in the page, if available.
18 let embeddedLastReadTimestamps = false;
19 if (drupalSettings.history && drupalSettings.history.lastReadTimestamps) {
20 embeddedLastReadTimestamps = drupalSettings.history.lastReadTimestamps;
28 * Fetch "last read" timestamps for the given nodes.
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.
35 fetchTimestamps(nodeIDs, callback) {
36 // Use the data embedded in the page, if available.
37 if (embeddedLastReadTimestamps) {
43 url: Drupal.url('history/get_node_read_timestamps'),
45 data: { 'node_ids[]': nodeIDs },
48 Object.keys(results || {}).forEach(nodeID => {
50 `Drupal.history.${currentUserID}.${nodeID}`,
60 * Get the last read timestamp for the given node.
62 * @param {number|string} nodeID
69 // Use the data embedded in the page, if available.
70 if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
71 return parseInt(embeddedLastReadTimestamps[nodeID], 10);
74 storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0,
80 * Marks a node as read, store the last read timestamp client-side.
82 * @param {number|string} nodeID
87 url: Drupal.url(`history/${nodeID}/read`),
91 // If the data is embedded in the page, don't store on the client
94 embeddedLastReadTimestamps &&
95 embeddedLastReadTimestamps[nodeID]
101 `Drupal.history.${currentUserID}.${nodeID}`,
109 * Determines whether a server check is necessary.
111 * Any content that is >30 days old never gets a "new" or "updated"
112 * indicator. Any content that was published before the oldest known reading
113 * also never gets a "new" or "updated" indicator, because it must've been
116 * @param {number|string} nodeID
118 * @param {number} contentTimestamp
119 * The time at which some content (e.g. a comment) was published.
122 * Whether a server check is necessary for the given node and its
125 needsServerCheck(nodeID, contentTimestamp) {
126 // First check if the content is older than 30 days, then we can bail
128 if (contentTimestamp < thirtyDaysAgo) {
132 // Use the data embedded in the page, if available.
133 if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
135 contentTimestamp > parseInt(embeddedLastReadTimestamps[nodeID], 10)
139 const minLastReadTimestamp = parseInt(
140 storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0,
143 return contentTimestamp > minLastReadTimestamp;
146 })(jQuery, Drupal, drupalSettings, window.localStorage);