From d43a3ed1a43d23e45daf2a39ae74b580c3da0919 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 | 67 ++++++++++++++++++- .../app/settings/styles/history-player.css | 8 +++ 2 files changed, 73 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 a239e0d2bf..294b73e7a9 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,24 @@ */ 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. + */ + 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. + */ + const MOUSE_DEBOUNCE_DELAY = 250; + + /** + * The number of milliseconds, after the debounce delay, before the mouse + * activity cleanup timer should run. + */ + const MOUSE_CLEANUP_TIMER_DELAY = MOUSE_CLEANUP_DELAY - MOUSE_DEBOUNCE_DELAY; + // Required services const keyEventDisplayService = $injector.get('keyEventDisplayService'); const playerTimeService = $injector.get('playerTimeService'); @@ -97,8 +117,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 @@ -179,6 +199,12 @@ 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. + */ + var mouseActivityTimer = null; + /** * Return true if any batches of key event logs are available for this * recording, or false otherwise. @@ -401,6 +427,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(() => + $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..acece79031 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,11 @@ -o-transition-delay: 0s; transition-delay: 0s; } + +.settings.connectionHistoryPlayer guac-player.recent-mouse-movement .guac-player-controls.playing { + opacity: 1; + -webkit-transition-delay: 0s; + -moz-transition-delay: 0s; + -o-transition-delay: 0s; + transition-delay: 0s; +}