Browse Source

Confirm a share also by pressing enter on the input field

Besides confirming a share by clicking on the confirm button now it is
possible to do it by pressing enter on the input field.

Clicking on the confirm button implicitly hides the autocomplete
dropdown. On the other hand, pressing enter on the input field does not,
so the autocompletion must be disabled and closed when the confirmation
begins and then enabled again once it finishes. Otherwise the
autocomplete dropdown would be visible and it would be possible to
interact with it while the share is being confirmed.

The order in which the input field and the autompletion are disabled is
important. Internally, the autocompletion sets a timeout when the input
field is modified that requests the suggestions to the server and then
shows them in the dropdown. That timeout is not cancelled when the
autocompletion is disabled, but when the input field loses its focus and
the autocompletion is not disabled. Therefore, the input field has to be
disabled (which causes it to lose the focus) before the autocompletion
is disabled. Otherwise it could happen that while a share is being
confirmed the timeout ends, so an autocompletion request is sent and
then, once the share is successfully confirmed and thus the
autocompletion is enabled again, the request is received and the
autocomplete dropdown is shown with the old suggestions. Strange, but
possible nevertheless ;-)

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
tags/v14.0.0beta1
Daniel Calviño Sánchez 6 years ago
parent
commit
10a4f8e45e
2 changed files with 47 additions and 0 deletions
  1. 36
    0
      core/js/sharedialogview.js
  2. 11
    0
      core/js/tests/specs/sharedialogviewSpec.js

+ 36
- 0
core/js/sharedialogview.js View File

@@ -415,6 +415,10 @@

_onSelectRecipient: function(e, s) {
e.preventDefault();
// Ensure that the keydown handler for the input field is not
// called; otherwise it would try to add the recipient again, which
// would fail.
e.stopImmediatePropagation();
$(e.target).attr('disabled', true)
.val(s.item.label);
var $loading = this.$el.find('.shareWithLoading');
@@ -451,6 +455,15 @@

$shareWithField.prop('disabled', true);

// Disabling the autocompletion does not clear its search timeout;
// removing the focus from the input field does, but only if the
// autocompletion is not disabled when the field loses the focus.
// Thus, the field has to be disabled before disabling the
// autocompletion to prevent an old pending search result from
// appearing once the field is enabled again.
$shareWithField.autocomplete('close');
$shareWithField.autocomplete('disable');

var perPage = 200;
var onlyExactMatches = true;
this._getSuggestions(
@@ -467,6 +480,8 @@
$shareWithField.prop('disabled', false);
$shareWithField.focus();

$shareWithField.autocomplete('enable');

// There is no need to show an error message here; it will
// be automatically shown when the autocomplete is activated
// again (due to the focus on the field) and it finds no
@@ -483,6 +498,8 @@
$shareWithField.prop('disabled', false);
$shareWithField.focus();

$shareWithField.autocomplete('enable');

return;
}

@@ -494,6 +511,8 @@
$shareWithField.val('');
$shareWithField.prop('disabled', false);
$shareWithField.focus();

$shareWithField.autocomplete('enable');
};

var actionError = function(obj, msg) {
@@ -504,6 +523,8 @@
$shareWithField.prop('disabled', false);
$shareWithField.focus();

$shareWithField.autocomplete('enable');

OC.Notification.showTemporary(msg);
};

@@ -519,6 +540,8 @@
$shareWithField.prop('disabled', false);
$shareWithField.focus();

$shareWithField.autocomplete('enable');

// There is no need to show an error message here; it will be
// automatically shown when the autocomplete is activated again
// (due to the focus on the field) and getting the suggestions
@@ -554,6 +577,7 @@
},

render: function() {
var self = this;
var baseTemplate = this._getTemplate('base', TEMPLATE_BASE);

this.$el.html(baseTemplate({
@@ -565,6 +589,16 @@

var $shareField = this.$el.find('.shareWithField');
if ($shareField.length) {
var shareFieldKeydownHandler = function(event) {
if (event.keyCode !== 13) {
return true;
}

self._confirmShare();

return false;
};

$shareField.autocomplete({
minLength: 1,
delay: 750,
@@ -574,6 +608,8 @@
source: this.autocompleteHandler,
select: this._onSelectRecipient
}).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem;

$shareField.on('keydown', null, shareFieldKeydownHandler);
}

this.resharerInfoView.$el = this.$el.find('.resharerInfoView');

+ 11
- 0
core/js/tests/specs/sharedialogviewSpec.js View File

@@ -1872,6 +1872,8 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
expect(autocompleteStub.lastCall.args[0]).toEqual('disable');
expect(autocompleteStub.calledWith('close')).toEqual(true);
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
});
@@ -1918,6 +1920,7 @@ describe('OC.Share.ShareDialogView', function() {
// Ensure that the UI is not restored before adding the share
expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
expect(autocompleteStub.lastCall.args[0]).toEqual('disable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');

@@ -1933,6 +1936,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('');
});
@@ -1981,6 +1985,7 @@ describe('OC.Share.ShareDialogView', function() {
// Ensure that the UI is not restored before adding the share
expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true);
expect(autocompleteStub.lastCall.args[0]).toEqual('disable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');

@@ -1996,6 +2001,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');

@@ -2037,6 +2043,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');

@@ -2088,6 +2095,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bo');
});
@@ -2143,6 +2151,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');
});
@@ -2171,6 +2180,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');

@@ -2188,6 +2198,7 @@ describe('OC.Share.ShareDialogView', function() {

expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true);
expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false);
expect(autocompleteStub.lastCall.args[0]).toEqual('enable');
expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false);
expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');


Loading…
Cancel
Save