mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	Maintain proper history with roughly six entries, continuously update thumbnails.
This commit is contained in:
		| @@ -77,8 +77,8 @@ | |||||||
|                 <p id="no-recent">No recent connections.</p> |                 <p id="no-recent">No recent connections.</p> | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
|             <h2>Other Connections</h2> |             <h2>All Connections</h2> | ||||||
|             <div id="other-connections"> |             <div id="all-connections"> | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
|             <h2>Clipboard</h2> |             <h2>Clipboard</h2> | ||||||
|   | |||||||
| @@ -3,8 +3,53 @@ | |||||||
|  */ |  */ | ||||||
| GuacamoleHistory = new (function() { | GuacamoleHistory = new (function() { | ||||||
|  |  | ||||||
|     var history = |     /** | ||||||
|         JSON.parse(localStorage.getItem("GUAC_HISTORY") || "{}"); |      * Reference to this GuacamoleHistory. | ||||||
|  |      */ | ||||||
|  |     var guac_history = this; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The number of entries to allow before removing old entries based on the | ||||||
|  |      * cutoff. | ||||||
|  |      */ | ||||||
|  |     var IDEAL_LENGTH = 6; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The maximum age of a history entry before it is removed, in | ||||||
|  |      * milliseconds. | ||||||
|  |      */ | ||||||
|  |     var CUTOFF_AGE = 900000; | ||||||
|  |  | ||||||
|  |     var history = {}; | ||||||
|  |  | ||||||
|  |     function truncate() { | ||||||
|  |  | ||||||
|  |         // Avoid history growth beyond defined number of entries | ||||||
|  |         if (history.length > IDEAL_LENGTH) { | ||||||
|  |  | ||||||
|  |             // Build list of entries | ||||||
|  |             var entries = []; | ||||||
|  |             for (var old_entry in history) | ||||||
|  |                 entries.push(old_entry); | ||||||
|  |  | ||||||
|  |             // Sort list | ||||||
|  |             entries.sort(GuacamoleHistory.Entries.compare); | ||||||
|  |  | ||||||
|  |             // Remove entries until length is ideal or all are recent | ||||||
|  |             var now = new Date().getTime(); | ||||||
|  |             while (entries.length > IDEAL_LENGTH  | ||||||
|  |                     && entries[0].accessed - now > CUTOFF_AGE) { | ||||||
|  |  | ||||||
|  |                 // Remove entry | ||||||
|  |                 var removed = entries.shift(); | ||||||
|  |                 delete history[removed.id]; | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the URL for the thumbnail of the connection with the given ID, |      * Returns the URL for the thumbnail of the connection with the given ID, | ||||||
| @@ -29,12 +74,67 @@ GuacamoleHistory = new (function() { | |||||||
|  |  | ||||||
|         // Store entry in history |         // Store entry in history | ||||||
|         history[id] = entry; |         history[id] = entry; | ||||||
|  |         truncate(); | ||||||
|  |  | ||||||
|         // Save updated history |         // Save updated history | ||||||
|         localStorage.setItem("GUAC_HISTORY", JSON.stringify(history)); |         localStorage.setItem("GUAC_HISTORY", JSON.stringify(history)); | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Reloads all history data. | ||||||
|  |      */ | ||||||
|  |     this.reload = function() { | ||||||
|  |  | ||||||
|  |         // Get old and new for comparison | ||||||
|  |         var old_history = history; | ||||||
|  |         var new_history = JSON.parse(localStorage.getItem("GUAC_HISTORY") || "{}"); | ||||||
|  |  | ||||||
|  |         // Update history | ||||||
|  |         history = new_history; | ||||||
|  |  | ||||||
|  |         // Call onchange handler as necessary | ||||||
|  |         if (guac_history.onchange) { | ||||||
|  |  | ||||||
|  |             // Produce union of all known IDs | ||||||
|  |             var known_ids = {}; | ||||||
|  |             for (var new_id in new_history) known_ids[new_id] = true; | ||||||
|  |             for (var old_id in old_history) known_ids[old_id] = true; | ||||||
|  |  | ||||||
|  |             // For each known ID | ||||||
|  |             for (var id in known_ids) { | ||||||
|  |  | ||||||
|  |                 // Get entries | ||||||
|  |                 var old_entry = old_history[id];     | ||||||
|  |                 var new_entry = new_history[id];     | ||||||
|  |  | ||||||
|  |                 // Call handler for all changed  | ||||||
|  |                 if (!old_entry || !new_entry | ||||||
|  |                         || old_entry.accessed != new_entry.accessed) | ||||||
|  |                     guac_history.onchange(id, old_entry, new_entry); | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         } // end onchange | ||||||
|  |  | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Event handler called whenever a history entry is changed. | ||||||
|  |      *  | ||||||
|  |      * @event | ||||||
|  |      * @param {String} id The ID of the connection whose history entry is | ||||||
|  |      *                    changing. | ||||||
|  |      * @param {GuacamoleHistory.Entry} old_entry The old value of the entry, if | ||||||
|  |      *                                           any. | ||||||
|  |      * @param {GuacamoleHistory.Entry} new_entry The new value of the entry, if | ||||||
|  |      *                                           any. | ||||||
|  |      */ | ||||||
|  |     this.onchange = null; | ||||||
|  |  | ||||||
|  |     // Initial load | ||||||
|  |     guac_history.reload(); | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -67,3 +167,6 @@ GuacamoleHistory.Entry = function(id, thumbnail, last_access) { | |||||||
|  |  | ||||||
| }; | }; | ||||||
|   |   | ||||||
|  | GuacamoleHistory.Entry.compare = function(a, b) { | ||||||
|  |     return a.accessed - b.accessed; | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ var GuacamoleRootUI = { | |||||||
|     "sections": { |     "sections": { | ||||||
|         "login_form"         : document.getElementById("login-form"), |         "login_form"         : document.getElementById("login-form"), | ||||||
|         "recent_connections" : document.getElementById("recent-connections"), |         "recent_connections" : document.getElementById("recent-connections"), | ||||||
|         "other_connections"  : document.getElementById("other-connections") |         "all_connections"  : document.getElementById("all-connections") | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     "messages": { |     "messages": { | ||||||
| @@ -148,6 +148,11 @@ GuacamoleRootUI.getConfigurations = function(parameters) { | |||||||
|  */ |  */ | ||||||
| GuacamoleRootUI.Connection = function(config) { | GuacamoleRootUI.Connection = function(config) { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The configuration associated with this connection. | ||||||
|  |      */ | ||||||
|  |     this.configuration = config; | ||||||
|  |  | ||||||
|     function element(tagname, classname) { |     function element(tagname, classname) { | ||||||
|         var new_element = document.createElement(tagname); |         var new_element = document.createElement(tagname); | ||||||
|         new_element.className = classname; |         new_element.className = classname; | ||||||
| @@ -161,6 +166,7 @@ GuacamoleRootUI.Connection = function(config) { | |||||||
|     var name          = element("span", "name"); |     var name          = element("span", "name"); | ||||||
|     var protocol_icon = element("div",  "icon " + config.protocol); |     var protocol_icon = element("div",  "icon " + config.protocol); | ||||||
|     var thumbnail     = element("div",  "thumbnail"); |     var thumbnail     = element("div",  "thumbnail"); | ||||||
|  |     var thumb_img; | ||||||
|  |  | ||||||
|     // Get URL |     // Get URL | ||||||
|     var url = "client.xhtml?id=" + encodeURIComponent(config.id); |     var url = "client.xhtml?id=" + encodeURIComponent(config.id); | ||||||
| @@ -197,9 +203,9 @@ GuacamoleRootUI.Connection = function(config) { | |||||||
|     if (thumbnail_url) { |     if (thumbnail_url) { | ||||||
|  |  | ||||||
|         // Create thumbnail element |         // Create thumbnail element | ||||||
|         var img = document.createElement("img"); |         thumb_img = document.createElement("img"); | ||||||
|         img.src = thumbnail_url; |         thumb_img.src = thumbnail_url; | ||||||
|         thumbnail.appendChild(img); |         thumbnail.appendChild(thumb_img); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -214,11 +220,59 @@ GuacamoleRootUI.Connection = function(config) { | |||||||
|      * Returns whether this connection has an associated thumbnail. |      * Returns whether this connection has an associated thumbnail. | ||||||
|      */ |      */ | ||||||
|     this.hasThumbnail = function() { |     this.hasThumbnail = function() { | ||||||
|         return thumbnail_url && true; |         return thumb_img && true; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sets the thumbnail URL of this existing connection. Note that this will | ||||||
|  |      * only work if the connection already had a thumbnail associated with it. | ||||||
|  |      */ | ||||||
|  |     this.setThumbnail = function(url) { | ||||||
|  |  | ||||||
|  |         // If no image element, create it | ||||||
|  |         if (!thumb_img) { | ||||||
|  |             thumb_img = document.createElement("img"); | ||||||
|  |             thumb_img.src = url; | ||||||
|  |             thumbnail.appendChild(thumb_img); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Otherwise, set source of existing | ||||||
|  |         else | ||||||
|  |             thumb_img.src = url; | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Set of all thumbnailed connections, indexed by ID. | ||||||
|  |  */ | ||||||
|  | GuacamoleRootUI.thumbnailConnections = {}; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Set of all configurations, indexed by ID. | ||||||
|  |  */ | ||||||
|  | GuacamoleRootUI.configurations = {}; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Adds the given connection to the recent connections list. | ||||||
|  |  */ | ||||||
|  | GuacamoleRootUI.addRecentConnection = function(connection) { | ||||||
|  |  | ||||||
|  |     // Add connection object to list of thumbnailed connections | ||||||
|  |     GuacamoleRootUI.thumbnailConnections[connection.configuration.id] = | ||||||
|  |         connection; | ||||||
|  |      | ||||||
|  |     // Add connection to recent list | ||||||
|  |     GuacamoleRootUI.sections.recent_connections.appendChild( | ||||||
|  |         connection.getElement()); | ||||||
|  |  | ||||||
|  |     // Hide "No recent connections" message | ||||||
|  |     GuacamoleRootUI.messages.no_recent_connections.style.display = "none"; | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Resets the interface such that the login UI is displayed if |  * Resets the interface such that the login UI is displayed if | ||||||
|  * the user is not authenticated (or authentication fails) and |  * the user is not authenticated (or authentication fails) and | ||||||
| @@ -249,26 +303,19 @@ GuacamoleRootUI.reset = function() { | |||||||
|     // Add connection icons |     // Add connection icons | ||||||
|     for (var i=0; i<configs.length; i++) { |     for (var i=0; i<configs.length; i++) { | ||||||
|  |  | ||||||
|         // Create connection element |         // Add configuration to set | ||||||
|  |         GuacamoleRootUI.configurations[configs[i].id] = configs[i]; | ||||||
|  |  | ||||||
|  |         // Get connection element | ||||||
|         var connection = new GuacamoleRootUI.Connection(configs[i]); |         var connection = new GuacamoleRootUI.Connection(configs[i]); | ||||||
|  |  | ||||||
|         // If screenshot presennt, add to recent connections |         // If screenshot present, add to recent connections | ||||||
|         if (connection.hasThumbnail()) { |         if (connection.hasThumbnail()) | ||||||
|  |             GuacamoleRootUI.addRecentConnection(connection); | ||||||
|  |  | ||||||
|             // Add connection to recent list |         // Add connection to connection list | ||||||
|             GuacamoleRootUI.sections.recent_connections.appendChild( |         GuacamoleRootUI.sections.all_connections.appendChild( | ||||||
|                 connection.getElement()); |             new GuacamoleRootUI.Connection(configs[i]).getElement()); | ||||||
|  |  | ||||||
|             // Hide "No recent connections" message |  | ||||||
|             GuacamoleRootUI.messages.no_recent_connections.style.display = |  | ||||||
|                 "none"; |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Otherwise, add conection to other connection list |  | ||||||
|         else |  | ||||||
|             GuacamoleRootUI.sections.other_connections.appendChild( |  | ||||||
|                 connection.getElement()); |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -276,6 +323,53 @@ GuacamoleRootUI.reset = function() { | |||||||
|     GuacamoleRootUI.views.login.style.display = "none"; |     GuacamoleRootUI.views.login.style.display = "none"; | ||||||
|     GuacamoleRootUI.views.connections.style.display = ""; |     GuacamoleRootUI.views.connections.style.display = ""; | ||||||
|  |  | ||||||
|  |     // Reload history every 5 seconds | ||||||
|  |     window.setInterval(GuacamoleHistory.reload, 5000); | ||||||
|  |  | ||||||
|  |     // Reload history when focus gained | ||||||
|  |     window.onfocus = GuacamoleHistory.reload; | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | GuacamoleHistory.onchange = function(id, old_entry, new_entry) { | ||||||
|  |  | ||||||
|  |     // Get existing connection, if any | ||||||
|  |     var connection = GuacamoleRootUI.thumbnailConnections[id]; | ||||||
|  |  | ||||||
|  |     // If we are adding or updating a connection | ||||||
|  |     if (new_entry) { | ||||||
|  |  | ||||||
|  |         // Ensure connection is added | ||||||
|  |         if (!connection) { | ||||||
|  |  | ||||||
|  |             // Create new connection | ||||||
|  |             connection = new GuacamoleRootUI.Connection( | ||||||
|  |                 GuacamoleRootUI.configurations[id] | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             GuacamoleRootUI.addRecentConnection(connection); | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Set new thumbnail  | ||||||
|  |         connection.setThumbnail(new_entry.thumbnail); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Otherwise, delete existing connection | ||||||
|  |     else { | ||||||
|  |  | ||||||
|  |         GuacamoleRootUI.sections.recent_connections.removeChild( | ||||||
|  |             connection.getElement()); | ||||||
|  |  | ||||||
|  |         delete GuacamoleRootUI.thumbnailConnections[id]; | ||||||
|  |  | ||||||
|  |         // Display "No recent connections" message if none left | ||||||
|  |         if (GuacamoleRootUI.thumbnailConnections.length == 0) | ||||||
|  |             GuacamoleRootUI.messages.no_recent_connections.style.display = ""; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |      | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -216,7 +216,7 @@ div#logout-panel { | |||||||
| div#recent-connections, | div#recent-connections, | ||||||
| div#clipboardDiv, | div#clipboardDiv, | ||||||
| div#settings, | div#settings, | ||||||
| div#other-connections { | div#all-connections { | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     padding: 1em; |     padding: 1em; | ||||||
| } | } | ||||||
| @@ -269,16 +269,16 @@ div#recent-connections div.connection { | |||||||
|     max-width: 75%; |     max-width: 75%; | ||||||
| } | } | ||||||
|  |  | ||||||
| div#other-connections .connection { | div#all-connections .connection { | ||||||
|     display: block; |     display: block; | ||||||
|     text-align: left; |     text-align: left; | ||||||
| } | } | ||||||
|  |  | ||||||
| div#other-connections .connection .thumbnail { | div#all-connections .connection .thumbnail { | ||||||
|     display: none; |     display: none; | ||||||
| } | } | ||||||
|  |  | ||||||
| div#other-connections .connection { | div#all-connections .connection { | ||||||
|     padding: 0.1em; |     padding: 0.1em; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user