annotate core/modules/history/js/history.es6.js @ 19:fa3358dc1485 tip

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