mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-1820: Extract and display richer information about key events.
This commit is contained in:
@@ -77,9 +77,6 @@
|
||||
*/
|
||||
angular.module('player').directive('guacPlayer', ['$injector', function guacPlayer($injector) {
|
||||
|
||||
// Required types
|
||||
const TextBatch = $injector.get('TextBatch');
|
||||
|
||||
// Required services
|
||||
const playerTimeService = $injector.get('playerTimeService');
|
||||
|
||||
@@ -151,7 +148,7 @@ angular.module('player').directive('guacPlayer', ['$injector', function guacPlay
|
||||
/**
|
||||
* Any batches of text typed during the recording.
|
||||
*
|
||||
* @type {TextBatch[]}
|
||||
* @type {Guacamole.KeyEventInterpeter.KeyEventBatch[]}
|
||||
*/
|
||||
$scope.textBatches = [];
|
||||
|
||||
@@ -277,6 +274,7 @@ angular.module('player').directive('guacPlayer', ['$injector', function guacPlay
|
||||
|
||||
resumeAfterSeekRequest && $scope.recording.play();
|
||||
$scope.recording.seek($scope.playbackPosition, function seekComplete() {
|
||||
$scope.seekPosition = null;
|
||||
$scope.operationMessage = null;
|
||||
$scope.$evalAsync();
|
||||
});
|
||||
@@ -357,8 +355,8 @@ angular.module('player').directive('guacPlayer', ['$injector', function guacPlay
|
||||
};
|
||||
|
||||
// Append any extracted batches of typed text
|
||||
$scope.recording.ontext = function appendTextBatch(text, timestamp) {
|
||||
$scope.textBatches.push({text, timestamp});
|
||||
$scope.recording.ontext = function appendTextBatch(batch) {
|
||||
$scope.textBatches.push(batch);
|
||||
}
|
||||
|
||||
// Notify listeners when current position within the recording
|
||||
|
@@ -25,9 +25,6 @@ const fuzzysort = require('fuzzysort')
|
||||
angular.module('player').directive('guacPlayerTextView',
|
||||
['$injector', function guacPlayer($injector) {
|
||||
|
||||
// Required types
|
||||
const TextBatch = $injector.get('TextBatch');
|
||||
|
||||
// Required services
|
||||
const playerTimeService = $injector.get('playerTimeService');
|
||||
|
||||
@@ -41,7 +38,7 @@ angular.module('player').directive('guacPlayerTextView',
|
||||
/**
|
||||
* All the batches of text extracted from this recording.
|
||||
*
|
||||
* @type {!TextBatch[]}
|
||||
* @type {!Guacamole.KeyEventInterpeter.KeyEventBatch[]}
|
||||
*/
|
||||
textBatches : '=',
|
||||
|
||||
@@ -77,7 +74,7 @@ angular.module('player').directive('guacPlayerTextView',
|
||||
* The text batches that match the current search phrase, or all
|
||||
* batches if no search phrase is set.
|
||||
*
|
||||
* @type {!TextBatch[]}
|
||||
* @type {!Guacamole.KeyEventInterpeter.KeyEventBatch[]}
|
||||
*/
|
||||
$scope.filteredBatches = $scope.textBatches;
|
||||
|
||||
@@ -111,7 +108,7 @@ angular.module('player').directive('guacPlayerTextView',
|
||||
// batches for it
|
||||
if (searchPhrase)
|
||||
$scope.filteredBatches = fuzzysort.go(
|
||||
searchPhrase, $scope.textBatches, {key: 'text'})
|
||||
searchPhrase, $scope.textBatches, {key: 'simpleValue'})
|
||||
.map(result => result.obj);
|
||||
|
||||
// Otherwise, do not filter the batches
|
||||
|
@@ -17,6 +17,33 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This session recording player implementation is based on the Session
|
||||
* Recording Player for Glyptodon Enterprise which is available at
|
||||
* https://github.com/glyptodon/glyptodon-enterprise-player under the
|
||||
* following license:
|
||||
*
|
||||
* Copyright (C) 2019 Glyptodon, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A service for formatting time, specifically for the recording player.
|
||||
*/
|
||||
|
@@ -17,33 +17,6 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This session recording player implementation is based on the Session
|
||||
* Recording Player for Glyptodon Enterprise which is available at
|
||||
* https://github.com/glyptodon/glyptodon-enterprise-player under the
|
||||
* following license:
|
||||
*
|
||||
* Copyright (C) 2019 Glyptodon, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
.text-batches {
|
||||
|
||||
display: flex;
|
||||
@@ -113,3 +86,25 @@
|
||||
margin: 0.25em;
|
||||
|
||||
}
|
||||
|
||||
.text-batches .text {
|
||||
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-width: 100%;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
}
|
||||
|
||||
.text-batches .text .not-typed {
|
||||
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
.text-batches .text .future {
|
||||
|
||||
color: dimgray;
|
||||
|
||||
}
|
||||
|
@@ -15,9 +15,15 @@
|
||||
translate-values="{RESULTS: filteredBatches.length}"></div>
|
||||
|
||||
<div class="text-batches">
|
||||
<div ng-repeat="batch in filteredBatches" class="text-batch" ng-click="seek({timestamp: batch.timestamp})">
|
||||
<div class="timestamp">{{ formatTime(batch.timestamp) }}</div>
|
||||
<div class="text">{{ batch.text }}</div>
|
||||
<div ng-repeat="batch in filteredBatches" class="text-batch" ng-click="seek({timestamp: batch.events[0].timestamp})">
|
||||
<div class="timestamp">{{ formatTime(batch.events[0].timestamp) }}</div>
|
||||
<div class="text">
|
||||
<span
|
||||
ng-repeat="event in batch.events"
|
||||
class="key-event"
|
||||
ng-class="{ 'not-typed' : !event.typed, 'future': event.timestamp >= currentPosition }"
|
||||
>{{ event.text }}</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Service which defines the TextBatch class.
|
||||
*/
|
||||
angular.module('player').factory('TextBatch', [function defineTextBatch() {
|
||||
|
||||
/**
|
||||
* A batch of text associated with a recording. The batch consists of a
|
||||
* string representation of the text that would be typed based on the key
|
||||
* events in the recording, as well as a timestamp when the batch started.
|
||||
*
|
||||
* @constructor
|
||||
* @param {TextBatch|Object} [template={}]
|
||||
* The object whose properties should be copied within the new TextBatch.
|
||||
*/
|
||||
const TextBatch = function TextBatch(template) {
|
||||
|
||||
// Use empty object by default
|
||||
template = template || {};
|
||||
|
||||
/**
|
||||
* The text that was typed in this batch.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
this.text = template.text;
|
||||
|
||||
/**
|
||||
* The timestamp at which the batch of text was typed.
|
||||
*
|
||||
* @type Number
|
||||
*/
|
||||
this.timestamp = template.timestamp;
|
||||
|
||||
};
|
||||
|
||||
return TextBatch;
|
||||
|
||||
}]);
|
Reference in New Issue
Block a user