Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 57 additions & 16 deletions css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
* It is assumed that the icon will have the standard width for buttons in
* inputs of 34px. However, further adjustments may be needed for the input and
* the padding depending on the context where they are used.
*
* The confirm icon can have a sibling loading icon to switch to (by hiding one
* icon and showing the other) while the operation is in progress.
*/
input[type="text"],
input[type="password"] {
Expand Down Expand Up @@ -114,6 +117,32 @@ input[type="password"] {
&:active:not(:disabled) {
opacity: 1;
}

+ .icon-loading-small {
/* Mimic size set in server for confirm button. */
width: 34px;
height: 34px;
padding: 7px 6px;
margin-top: 3px;
margin-bottom: 3px;

position: absolute;
top: 0;
right: 3px;
}
}
}

.menuitem input[type="text"],
.menuitem input[type="password"] {
& + .icon-confirm + .icon-loading-small {
/* Mimic size set in server for inputs in menu items. */
min-width: 44px;
max-height: 40px;
margin: 2px 0;

/* Override padding set in server for icons in menu items. */
padding: 7px 6px;
}
}

Expand Down Expand Up @@ -762,12 +791,10 @@ input[type="password"] {
.input-wrapper {
position: relative;

input[type="text"] {
& + .icon-confirm {
/* Needed to override an important rule set in the
* server. */
background-color: transparent !important;
}
.icon-confirm {
/* Needed to override an important rule set in the
* server. */
background-color: transparent !important;
}
}
.label {
Expand Down Expand Up @@ -849,18 +876,17 @@ input[type="password"] {
text-overflow: ellipsis;
}

.icon-confirm.confirm-button {
padding: 12px 21px;
margin: 0;
}

input[type="text"] {
padding-right: 44px;
}

& + .icon-confirm {
top: 4px;
right: 0;
}
.icon-confirm,
.icon-loading-small {
top: 4px;
right: 0;

padding: 12px 21px;
margin: 0;
}
}
}
Expand Down Expand Up @@ -913,6 +939,18 @@ input[type="password"] {
.link-checkbox-label {
white-space: nowrap;
padding: 12px;

/* If ".icon-loading-small" is set hide the checkbox and show a
* loading icon instead */
&.icon-loading-small:before {
background-image: none !important;
background-color: transparent !important;
border-color: transparent !important;
}
&.icon-loading-small:after {
top: 21px;
left: 23px;
}
}
.button {
cursor: pointer;
Expand Down Expand Up @@ -941,11 +979,14 @@ input[type="password"] {
.password-form {
position: relative;

.password-confirm {
.password-confirm,
.password-loading {
/* Inputs in menu items do not have a right margin, so
* it does not need to be compensated. */
right: 0;
}

.password-confirm {
/* Needed to override an important rule set in the
* server. */
background-color: transparent !important;
Expand Down
44 changes: 41 additions & 3 deletions js/views/callinfoview.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
'shareLinkOptions': '.share-link-options',
'clipboardButton': '.clipboard-button',
'linkCheckbox': '.link-checkbox',
'linkCheckboxLabel': '.link-checkbox-label',

'callButton': 'div.call-button',

Expand All @@ -74,6 +75,7 @@
'passwordOption': '.password-option',
'passwordInput': '.password-input',
'passwordConfirm': '.password-confirm',
'passwordLoading': '.password-loading',

'menu': '.password-menu',
},
Expand Down Expand Up @@ -120,6 +122,12 @@
this._nameEditableTextLabel = new OCA.SpreedMe.Views.EditableTextLabel({
model: this.model,
modelAttribute: nameAttribute,
modelSaveOptions: {
wait: true,
error: function() {
OC.Notification.show(t('spreed', 'Error occurred while renaming the room'), {type: 'error'});
}
},

extraClassNames: 'room-name',
labelTagName: 'h2',
Expand Down Expand Up @@ -243,9 +251,25 @@
* Share link
*/
toggleLinkCheckbox: function() {
var isPublic = this.ui.linkCheckbox.attr('checked') === 'checked';
var isPublic = this.ui.linkCheckbox.prop('checked');

this.model.setPublic(isPublic);
this.ui.linkCheckbox.prop('disabled', true);
this.ui.linkCheckboxLabel.addClass('icon-loading-small');

this.model.setPublic(isPublic, {
wait: true,
error: function() {
this.ui.linkCheckbox.prop('checked', !isPublic);
this.ui.linkCheckbox.prop('disabled', false);
this.ui.linkCheckboxLabel.removeClass('icon-loading-small');

if (isPublic) {
OC.Notification.show(t('spreed', 'Error occurred while making the room public'), {type: 'error'});
} else {
OC.Notification.show(t('spreed', 'Error occurred while making the room private'), {type: 'error'});
}
}.bind(this)
});
},

/**
Expand All @@ -256,14 +280,28 @@

var newPassword = this.ui.passwordInput.val().trim();

this.ui.passwordInput.prop('disabled', true);
this.ui.passwordConfirm.addClass('hidden');
this.ui.passwordLoading.removeClass('hidden');

var restoreState = function() {
this.ui.passwordInput.prop('disabled', false);
this.ui.passwordConfirm.removeClass('hidden');
this.ui.passwordLoading.addClass('hidden');
}.bind(this);

this.model.setPassword(newPassword, {
wait: true,
success: function() {
this.ui.passwordInput.val('');
restoreState();
OC.hideMenus();
}.bind(this),
error: function() {
restoreState();

OC.Notification.show(t('spreed', 'Error occurred while setting password'), {type: 'error'});
}
}.bind(this)
});
},

Expand Down
23 changes: 23 additions & 0 deletions js/views/editabletextlabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
* "inputPlaceholder" and "buttonTitle" can be used to customize some
* elements of the view.
*
* It is recommended, although not strictly needed, to wait for the server
* response before setting the new attribute value in the model; otherwise,
* in case of failure the label will show the new value of the attribute
* even if it was not set in the server.
*
* After initialization, and once the view has been rendered, the
* "modelAttribute" and "labelPlaceholder" options can be updated using the
* "setModelAttribute" and "setLabelPlaceholder" methods.
Expand All @@ -72,6 +77,7 @@
inputWrapper: '.input-wrapper',
input: 'input.username',
confirmButton: '.confirm-button',
loadingIcon: '.icon-loading-small',
},

events: {
Expand Down Expand Up @@ -208,10 +214,21 @@
return;
}

this.ui.input.prop('disabled', true);
this.ui.confirmButton.addClass('hidden');
this.ui.loadingIcon.removeClass('hidden');

var restoreState = function() {
this.ui.input.prop('disabled', false);
this.ui.confirmButton.removeClass('hidden');
this.ui.loadingIcon.addClass('hidden');
}.bind(this);

// TODO This should show the error message instead of just hiding
// the input without changes.
var hideInputOnValidationError = function(/*model, error*/) {
this.hideInput();
restoreState();
}.bind(this);
this.model.listenToOnce(this.model, 'invalid', hideInputOnValidationError);

Expand All @@ -220,6 +237,7 @@
this.model.stopListening(this.model, 'invalid', hideInputOnValidationError);

this.hideInput();
restoreState();

if (this.modelSaveOptions && _.isFunction(this.modelSaveOptions.success)) {
this.modelSaveOptions.success.apply(this, arguments);
Expand All @@ -229,6 +247,11 @@
this.model.stopListening(this.model, 'invalid', hideInputOnValidationError);

this.hideInput();
restoreState();

if (this.modelSaveOptions && _.isFunction(this.modelSaveOptions.error)) {
this.modelSaveOptions.error.apply(this, arguments);
}
}, this);

this.model.save(this.modelAttribute, newText, options);
Expand Down
6 changes: 3 additions & 3 deletions js/views/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ templates['callinfoview'] = template({"1":function(container,depth0,helpers,part
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasPassword : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : "")
+ "\"></span>\n <div class=\"popovermenu password-menu menu-right\">\n <ul>\n <li>\n <span class=\"menuitem "
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasPassword : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : "")
+ " password-option\">\n <form class=\"password-form\">\n <input class=\"password-input\" required maxlength=\"200\" type=\"password\"\n placeholder=\""
+ " password-option\">\n <form class=\"password-form\">\n <input class=\"password-input\" maxlength=\"200\" type=\"password\"\n placeholder=\""
+ container.escapeExpression(((helper = (helper = helpers.passwordInputPlaceholder || (depth0 != null ? depth0.passwordInputPlaceholder : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(alias1,{"name":"passwordInputPlaceholder","hash":{},"data":data}) : helper)))
+ "\">\n <input type=\"submit\" value=\"\" autocomplete=\"new-password\" class=\"icon icon-confirm password-confirm\"></input>\n </form>\n </span>\n </li>\n </ul>\n </div>\n </div>\n";
+ "\">\n <input type=\"submit\" value=\"\" autocomplete=\"new-password\" class=\"icon icon-confirm password-confirm\"></input>\n <span class=\"icon icon-loading-small password-loading hidden\"/>\n </form>\n </span>\n </li>\n </ul>\n </div>\n </div>\n";
},"8":function(container,depth0,helpers,partials,data) {
return "icon-password";
},"10":function(container,depth0,helpers,partials,data) {
Expand Down Expand Up @@ -210,7 +210,7 @@ templates['editabletextlabel'] = template({"1":function(container,depth0,helpers
+ container.escapeExpression(((helper = (helper = helpers.inputValue || (depth0 != null ? depth0.inputValue : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(alias1,{"name":"inputValue","hash":{},"data":data}) : helper)))
+ "\" "
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.inputPlaceholder : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ ">\n <input type=\"submit\" value=\"\" class=\"icon icon-confirm confirm-button\"></div>\n</div>\n";
+ ">\n <input type=\"submit\" value=\"\" class=\"icon icon-confirm confirm-button\">\n <span class=\"icon icon-loading-small hidden\"/>\n</div>\n";
},"5":function(container,depth0,helpers,partials,data) {
var helper;

Expand Down
3 changes: 2 additions & 1 deletion js/views/templates/callinfoview.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
<li>
<span class="menuitem {{#if hasPassword}}icon-password{{else}}icon-no-password{{/if}} password-option">
<form class="password-form">
<input class="password-input" required maxlength="200" type="password"
<input class="password-input" maxlength="200" type="password"
placeholder="{{passwordInputPlaceholder}}">
<input type="submit" value="" autocomplete="new-password" class="icon icon-confirm password-confirm"></input>
<span class="icon icon-loading-small password-loading hidden"/>
</form>
</span>
</li>
Expand Down
3 changes: 2 additions & 1 deletion js/views/templates/editabletextlabel.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
{{#if editionEnabled}}
<div class="input-wrapper hidden-important">
<input class="username" {{#if inputMaxLength}} maxlength="{{inputMaxLength}}" {{/if}} type="text" value="{{inputValue}}" {{#if inputPlaceholder}} placeholder="{{inputPlaceholder}}" {{/if}}>
<input type="submit" value="" class="icon icon-confirm confirm-button"></div>
<input type="submit" value="" class="icon icon-confirm confirm-button">
<span class="icon icon-loading-small hidden"/>
</div>
{{/if}}