From 04c620f30add5918085bdc5b58d8bda8486a8261 Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Mon, 23 Oct 2023 22:04:46 +0000 Subject: [PATCH] GUACAMOLE-1872: Show the recording playback controls when the mouse is moved. --- .../src/app/player/directives/player.js | 75 ++++++++++++++++++- .../app/settings/styles/history-player.css | 4 + 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/guacamole/src/main/frontend/src/app/player/directives/player.js b/guacamole/src/main/frontend/src/app/player/directives/player.js index 7b3e087928..f3f5337bf6 100644 --- a/guacamole/src/main/frontend/src/app/player/directives/player.js +++ b/guacamole/src/main/frontend/src/app/player/directives/player.js @@ -44,6 +44,8 @@ * THE SOFTWARE. */ +/* global _ */ + /** * Directive which plays back session recordings. This directive emits the * following events based on state changes within the current recording: @@ -77,6 +79,30 @@ */ angular.module('player').directive('guacPlayer', ['$injector', function guacPlayer($injector) { + /** + * The number of milliseconds after the last detected mouse activity after + * which the associated CSS class should be removed. + * + * @type {number} + */ + const MOUSE_CLEANUP_DELAY = 4000; + + /** + * The number of milliseconds after the last detected mouse activity before + * the cleanup timer to remove the associated CSS class should be scheduled. + * + * @type {number} + */ + const MOUSE_DEBOUNCE_DELAY = 250; + + /** + * The number of milliseconds, after the debounce delay, before the mouse + * activity cleanup timer should run. + * + * @type {number} + */ + const MOUSE_CLEANUP_TIMER_DELAY = MOUSE_CLEANUP_DELAY - MOUSE_DEBOUNCE_DELAY; + const config = { restrict : 'E', templateUrl : 'app/player/templates/player.html' @@ -93,8 +119,8 @@ angular.module('player').directive('guacPlayer', ['$injector', function guacPlay }; - config.controller = ['$scope', '$element', '$injector', - function guacPlayerController($scope) { + config.controller = ['$scope', '$element', '$window', + function guacPlayerController($scope, $element, $window) { /** * Guacamole.SessionRecording instance to be used to playback the @@ -160,6 +186,14 @@ angular.module('player').directive('guacPlayer', ['$injector', function guacPlay */ var resumeAfterSeekRequest = false; + /** + * A scheduled timer to clean up the mouse activity CSS class, or null + * if no timer is scheduled. + * + * @type {number} + */ + var mouseActivityTimer = null; + /** * Formats the given number as a decimal string, adding leading zeroes * such that the string contains at least two digits. The given number @@ -379,6 +413,43 @@ angular.module('player').directive('guacPlayer', ['$injector', function guacPlay $scope.$on('$destroy', function playerDestroyed() { $scope.recording.pause(); $scope.recording.abort(); + mouseActivityTimer !== null && $window.clearTimeout(mouseActivityTimer); + }); + + /** + * Clean up the mouse movement class after no mouse activity has been + * detected for the appropriate time period. + */ + const scheduleCleanupTimeout = _.debounce(() => + mouseActivityTimer = $window.setTimeout(() => { + mouseActivityTimer = null; + $element.removeClass('recent-mouse-movement'); + }, MOUSE_CLEANUP_TIMER_DELAY), + + /* + * Only schedule the cleanup task after the mouse hasn't moved + * for a reasonable amount of time to ensure that the number of + * created cleanup timers remains reasonable. + */ + MOUSE_DEBOUNCE_DELAY); + + /* + * When the mouse moves inside the player, add a CSS class signifying + * recent mouse movement, to be automatically cleaned up after a period + * of time with no detected mouse movement. + */ + $element.on('mousemove', () => { + + // Clean up any existing cleanup timer + if (mouseActivityTimer !== null) { + $window.clearTimeout(mouseActivityTimer); + mouseActivityTimer = null; + } + + // Add the marker CSS class, and schedule its removal + $element.addClass('recent-mouse-movement'); + scheduleCleanupTimeout(); + }); }]; diff --git a/guacamole/src/main/frontend/src/app/settings/styles/history-player.css b/guacamole/src/main/frontend/src/app/settings/styles/history-player.css index 7503cc8c30..bf4a909d12 100644 --- a/guacamole/src/main/frontend/src/app/settings/styles/history-player.css +++ b/guacamole/src/main/frontend/src/app/settings/styles/history-player.css @@ -112,3 +112,7 @@ -o-transition-delay: 0s; transition-delay: 0s; } + +.settings.connectionHistoryPlayer guac-player.recent-mouse-movement .guac-player-controls.playing { + opacity: 1; +}