feat(GUI): allow double-click to quick-select drives (#889)

The user can now double-click to swiftly select a drive in the
drive widget instead of having to toggle a drive and then clicking the
continue button to close the modal and finalize the drive selection.

Closes: https://github.com/resin-io/etcher/issues/880
Change-Type: patch
Changelog-Entry: Implement double-click to quick-select drives in the
drive widget.
This commit is contained in:
Benedict Aas 2016-11-30 15:11:11 +00:00 committed by Juan Cruz Viotti
parent ccd2076a20
commit cfeb35b531
2 changed files with 62 additions and 22 deletions

View File

@ -18,7 +18,7 @@
const _ = require('lodash');
module.exports = function($uibModalInstance, DrivesModel, SelectionStateModel, WarningModalService) {
module.exports = function($q, $uibModalInstance, DrivesModel, SelectionStateModel, WarningModalService) {
/**
* @summary The drive selector state
@ -40,12 +40,46 @@ module.exports = function($uibModalInstance, DrivesModel, SelectionStateModel, W
*/
this.drives = DrivesModel;
/**
* @summary Determine if we can change a drive's selection state
* @function
* @private
*
* @param {Object} drive - drive
* @returns {Promise}
*
* @example
* DriveSelectorController.shouldChangeDriveSelectionState(drive)
* .then((shouldChangeDriveSelectionState) => {
* if (shouldChangeDriveSelectionState) doSomething();
* });
*/
const shouldChangeDriveSelectionState = (drive) => {
if (!SelectionStateModel.isDriveValid(drive)) {
return $q.resolve(false);
}
if (SelectionStateModel.isDriveSizeRecommended(drive)) {
return $q.resolve(true);
}
return WarningModalService.display({
confirmationLabel: 'Yes, continue',
description: [
`This image recommends a ${SelectionStateModel.getImageRecommendedDriveSize()}`,
`bytes drive, however ${drive.device} is only ${drive.size} bytes.`,
'Are you sure you want to continue?'
].join(' ')
});
};
/**
* @summary Toggle a drive selection
* @function
* @public
*
* @param {Object} drive - drive
* @returns {Promise} - resolved promise
*
* @example
* DriveSelectorController.toggleDrive({
@ -55,27 +89,8 @@ module.exports = function($uibModalInstance, DrivesModel, SelectionStateModel, W
* });
*/
this.toggleDrive = (drive) => {
if (!SelectionStateModel.isDriveValid(drive)) {
return;
}
if (_.some([
SelectionStateModel.isDriveSizeRecommended(drive),
SelectionStateModel.isCurrentDrive(drive.device)
])) {
SelectionStateModel.toggleSetDrive(drive.device);
return;
}
WarningModalService.display({
confirmationLabel: 'Yes, continue',
description: [
`This image recommends a ${SelectionStateModel.getImageRecommendedDriveSize()}`,
`bytes drive, however ${drive.device} is only ${drive.size} bytes.`,
'Are you sure you want to continue?'
].join(' ')
}).then((userAccepted) => {
if (userAccepted) {
return shouldChangeDriveSelectionState(drive).then((canChangeDriveSelectionState) => {
if (canChangeDriveSelectionState) {
SelectionStateModel.toggleSetDrive(drive.device);
}
});
@ -103,4 +118,28 @@ module.exports = function($uibModalInstance, DrivesModel, SelectionStateModel, W
};
/**
* @summary Select a drive and close the modal
* @function
* @public
*
* @param {Object} drive - drive
* @returns {Promise} - resolved promise
*
* @example
* DriveSelectorController.selectDriveAndClose({
* device: '/dev/disk2',
* size: 999999999,
* name: 'Cruzer USB drive'
* });
*/
this.selectDriveAndClose = (drive) => {
return shouldChangeDriveSelectionState(drive).then((canChangeDriveSelectionState) => {
if (canChangeDriveSelectionState) {
SelectionStateModel.setDrive(drive.device);
this.closeModal();
}
});
};
};

View File

@ -7,6 +7,7 @@
<ul class="list-group">
<li class="list-group-item" ng-repeat="drive in modal.drives.getDrives() track by drive.device"
ng-disabled="!modal.state.isDriveValid(drive)"
ng-dblclick="modal.selectDriveAndClose(drive)"
ng-click="modal.toggleDrive(drive)">
<div>
<h4 class="list-group-item-heading">{{ drive.description }} - {{ drive.size | gigabyte | number:1 }} GB</h4>