mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUACAMOLE-190: Update client thumbnail roughly every 5 seconds.
This commit is contained in:
		| @@ -24,14 +24,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|     function defineManagedClient($rootScope, $injector) { | ||||
|  | ||||
|     // Required types | ||||
|     var ClientProperties     = $injector.get('ClientProperties'); | ||||
|     var ClientIdentifier     = $injector.get('ClientIdentifier'); | ||||
|     var ClipboardData        = $injector.get('ClipboardData'); | ||||
|     var ManagedClientState   = $injector.get('ManagedClientState'); | ||||
|     var ManagedDisplay       = $injector.get('ManagedDisplay'); | ||||
|     var ManagedFilesystem    = $injector.get('ManagedFilesystem'); | ||||
|     var ManagedFileUpload    = $injector.get('ManagedFileUpload'); | ||||
|     var ManagedShareLink     = $injector.get('ManagedShareLink'); | ||||
|     var ClientProperties       = $injector.get('ClientProperties'); | ||||
|     var ClientIdentifier       = $injector.get('ClientIdentifier'); | ||||
|     var ClipboardData          = $injector.get('ClipboardData'); | ||||
|     var ManagedClientState     = $injector.get('ManagedClientState'); | ||||
|     var ManagedClientThumbnail = $injector.get('ManagedClientThumbnail'); | ||||
|     var ManagedDisplay         = $injector.get('ManagedDisplay'); | ||||
|     var ManagedFilesystem      = $injector.get('ManagedFilesystem'); | ||||
|     var ManagedFileUpload      = $injector.get('ManagedFileUpload'); | ||||
|     var ManagedShareLink       = $injector.get('ManagedShareLink'); | ||||
|  | ||||
|     // Required services | ||||
|     var $document              = $injector.get('$document'); | ||||
| @@ -46,7 +47,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|     var guacHistory            = $injector.get('guacHistory'); | ||||
|     var guacImage              = $injector.get('guacImage'); | ||||
|     var guacVideo              = $injector.get('guacVideo'); | ||||
|          | ||||
|  | ||||
|     /** | ||||
|      * The minimum amount of time to wait between updates to the client | ||||
|      * thumbnail, in milliseconds. | ||||
|      * | ||||
|      * @type Number | ||||
|      */ | ||||
|     var THUMBNAIL_UPDATE_FREQUENCY = 5000; | ||||
|  | ||||
|     /** | ||||
|      * Object which serves as a surrogate interface, encapsulating a Guacamole | ||||
|      * client while it is active, allowing it to be detached and reattached | ||||
| @@ -98,6 +107,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|          */ | ||||
|         this.name = template.name; | ||||
|  | ||||
|         /** | ||||
|          * The most recently-generated thumbnail for this connection, as | ||||
|          * stored within the local connection history. If no thumbnail is | ||||
|          * stored, this will be null. | ||||
|          * | ||||
|          * @type ManagedClientThumbnail | ||||
|          */ | ||||
|         this.thumbnail = template.thumbnail; | ||||
|  | ||||
|         /** | ||||
|          * The current clipboard contents. | ||||
|          * | ||||
| @@ -227,45 +245,6 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Store the thumbnail of the given managed client within the connection | ||||
|      * history under its associated ID. If the client is not connected, this | ||||
|      * function has no effect. | ||||
|      * | ||||
|      * @param {String} managedClient | ||||
|      *     The client whose history entry should be updated. | ||||
|      */ | ||||
|     var updateHistoryEntry = function updateHistoryEntry(managedClient) { | ||||
|  | ||||
|         var display = managedClient.client.getDisplay(); | ||||
|  | ||||
|         // Update stored thumbnail of previous connection  | ||||
|         if (display && display.getWidth() > 0 && display.getHeight() > 0) { | ||||
|  | ||||
|             // Get screenshot | ||||
|             var canvas = display.flatten(); | ||||
|              | ||||
|             // Calculate scale of thumbnail (max 320x240, max zoom 100%) | ||||
|             var scale = Math.min(320 / canvas.width, 240 / canvas.height, 1); | ||||
|              | ||||
|             // Create thumbnail canvas | ||||
|             var thumbnail = $document[0].createElement("canvas"); | ||||
|             thumbnail.width  = canvas.width*scale; | ||||
|             thumbnail.height = canvas.height*scale; | ||||
|              | ||||
|             // Scale screenshot to thumbnail | ||||
|             var context = thumbnail.getContext("2d"); | ||||
|             context.drawImage(canvas, | ||||
|                 0, 0, canvas.width, canvas.height, | ||||
|                 0, 0, thumbnail.width, thumbnail.height | ||||
|             ); | ||||
|  | ||||
|             guacHistory.updateThumbnail(managedClient.id, thumbnail.toDataURL("image/png")); | ||||
|  | ||||
|         } | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Requests the creation of a new audio stream, recorded from the user's | ||||
|      * local audio input device. If audio input is supported by the connection, | ||||
| @@ -403,12 +382,14 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|                         // Begin streaming audio input if possible | ||||
|                         requestAudioStream(client); | ||||
|  | ||||
|                         // Update thumbnail with initial display contents | ||||
|                         ManagedClient.updateThumbnail(managedClient); | ||||
|                         break; | ||||
|  | ||||
|                     // Update history when disconnecting | ||||
|                     case 4: // Disconnecting | ||||
|                     case 5: // Disconnected | ||||
|                         updateHistoryEntry(managedClient); | ||||
|                         ManagedClient.updateThumbnail(managedClient); | ||||
|                         break; | ||||
|  | ||||
|                 } | ||||
| @@ -431,6 +412,21 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|             }); | ||||
|         }; | ||||
|  | ||||
|         // Automatically update the client thumbnail | ||||
|         client.onsync = function syncReceived() { | ||||
|  | ||||
|             var thumbnail = managedClient.thumbnail; | ||||
|             var timestamp = new Date().getTime(); | ||||
|  | ||||
|             // Update thumbnail if it doesn't exist or is old | ||||
|             if (!thumbnail || timestamp - thumbnail.timestamp >= THUMBNAIL_UPDATE_FREQUENCY) { | ||||
|                 $rootScope.$apply(function updateClientThumbnail() { | ||||
|                     ManagedClient.updateThumbnail(managedClient); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|         }; | ||||
|  | ||||
|         // Handle any received clipboard data | ||||
|         client.onclipboard = function clientClipboardReceived(stream, mimetype) { | ||||
|  | ||||
| @@ -651,6 +647,52 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Store the thumbnail of the given managed client within the connection | ||||
|      * history under its associated ID. If the client is not connected, this | ||||
|      * function has no effect. | ||||
|      * | ||||
|      * @param {ManagedClient} managedClient | ||||
|      *     The client whose history entry should be updated. | ||||
|      */ | ||||
|     ManagedClient.updateThumbnail = function updateThumbnail(managedClient) { | ||||
|  | ||||
|         var display = managedClient.client.getDisplay(); | ||||
|  | ||||
|         // Update stored thumbnail of previous connection | ||||
|         if (display && display.getWidth() > 0 && display.getHeight() > 0) { | ||||
|  | ||||
|             // Get screenshot | ||||
|             var canvas = display.flatten(); | ||||
|  | ||||
|             // Calculate scale of thumbnail (max 320x240, max zoom 100%) | ||||
|             var scale = Math.min(320 / canvas.width, 240 / canvas.height, 1); | ||||
|  | ||||
|             // Create thumbnail canvas | ||||
|             var thumbnail = $document[0].createElement("canvas"); | ||||
|             thumbnail.width  = canvas.width*scale; | ||||
|             thumbnail.height = canvas.height*scale; | ||||
|  | ||||
|             // Scale screenshot to thumbnail | ||||
|             var context = thumbnail.getContext("2d"); | ||||
|             context.drawImage(canvas, | ||||
|                 0, 0, canvas.width, canvas.height, | ||||
|                 0, 0, thumbnail.width, thumbnail.height | ||||
|             ); | ||||
|  | ||||
|             // Store updated thumbnail within client | ||||
|             managedClient.thumbnail = new ManagedClientThumbnail({ | ||||
|                 timestamp : new Date().getTime(), | ||||
|                 canvas    : thumbnail | ||||
|             }); | ||||
|  | ||||
|             // Update historical thumbnail | ||||
|             guacHistory.updateThumbnail(managedClient.id, thumbnail.toDataURL("image/png")); | ||||
|  | ||||
|         } | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     return ManagedClient; | ||||
|  | ||||
| }]); | ||||
| @@ -0,0 +1,58 @@ | ||||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one | ||||
|  * or more contributor license agreements.  See the NOTICE file | ||||
|  * distributed with this work for additional information | ||||
|  * regarding copyright ownership.  The ASF licenses this file | ||||
|  * to you under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance | ||||
|  * with the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, | ||||
|  * software distributed under the License is distributed on an | ||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
|  * KIND, either express or implied.  See the License for the | ||||
|  * specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Provides the ManagedClientThumbnail class used by ManagedClient. | ||||
|  */ | ||||
| angular.module('client').factory('ManagedClientThumbnail', [function defineManagedClientThumbnail() { | ||||
|  | ||||
|     /** | ||||
|      * Object which represents a thumbnail of the Guacamole client display, | ||||
|      * along with the time that the thumbnail was generated. | ||||
|      * | ||||
|      * @constructor | ||||
|      * @param {ManagedClientThumbnail|Object} [template={}] | ||||
|      *     The object whose properties should be copied within the new | ||||
|      *     ManagedClientThumbnail. | ||||
|      */ | ||||
|     var ManagedClientThumbnail = function ManagedClientThumbnail(template) { | ||||
|  | ||||
|         // Use empty object by default | ||||
|         template = template || {}; | ||||
|  | ||||
|         /** | ||||
|          * The time that this thumbnail was generated, as the number of | ||||
|          * milliseconds elapsed since midnight of January 1, 1970 UTC. | ||||
|          * | ||||
|          * @type Number | ||||
|          */ | ||||
|         this.timestamp = template.timestamp; | ||||
|  | ||||
|         /** | ||||
|          * The thumbnail of the Guacamole client display. | ||||
|          * | ||||
|          * @type HTMLCanvasElement | ||||
|          */ | ||||
|         this.canvas = template.canvas; | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     return ManagedClientThumbnail; | ||||
|  | ||||
| }]); | ||||
		Reference in New Issue
	
	Block a user