aboutsummaryrefslogtreecommitdiffstats
path: root/core/js
diff options
context:
space:
mode:
Diffstat (limited to 'core/js')
-rw-r--r--core/js/js.js38
-rw-r--r--core/js/shareconfigmodel.js3
-rw-r--r--core/js/sharedialoglinkshareview.js39
-rw-r--r--core/js/sharedialogresharerinfoview.js13
-rw-r--r--core/js/sharedialogshareelistview.js28
-rw-r--r--core/js/sharedialogview.js55
-rw-r--r--core/js/shareitemmodel.js16
-rw-r--r--core/js/tests/specs/coreSpec.js6
-rw-r--r--core/js/tests/specs/sharedialogviewSpec.js23
9 files changed, 158 insertions, 63 deletions
diff --git a/core/js/js.js b/core/js/js.js
index 68b6f82648b..5f5f540af63 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -780,8 +780,18 @@ var OCP = {},
// sometimes "beforeunload" happens later, so need to defer the reload a bit
setTimeout(function() {
if (!self._userIsNavigatingAway && !self._reloadCalled) {
- OC.Notification.show(t('core', 'Problem loading page, reloading in 5 seconds'));
- setTimeout(OC.reload, 5000);
+ var timer = 0;
+ var seconds = 5;
+ var interval = setInterval( function() {
+ OC.Notification.showUpdate(n('core', 'Problem loading page, reloading in %n second', 'Problem loading page, reloading in %n seconds', seconds - timer));
+ if (timer >= seconds) {
+ clearInterval(interval);
+ OC.reload();
+ }
+ timer++;
+ }, 1000 // 1 second interval
+ );
+
// only call reload once
self._reloadCalled = true;
}
@@ -1174,6 +1184,30 @@ OC.Notification={
},
/**
+ * Updates (replaces) a sanitized notification.
+ *
+ * @param {string} text Message to display
+ * @return {jQuery} JQuery element for notificaiton row
+ */
+ showUpdate: function(text) {
+ var $notification = $('#notification');
+ // sanitise
+ var $html = $('<div/>').text(text).html();
+
+ // new notification
+ if (text && $notification.find('.row').length == 0) {
+ return this.showHtml($html);
+ }
+
+ var $row = $('<div class="row"></div>').prepend($html);
+
+ // just update html in notification
+ $notification.html($row);
+
+ return $row;
+ },
+
+ /**
* Shows a notification that disappears after x seconds, default is
* 7 seconds
*
diff --git a/core/js/shareconfigmodel.js b/core/js/shareconfigmodel.js
index 7c92853f682..98388cbd508 100644
--- a/core/js/shareconfigmodel.js
+++ b/core/js/shareconfigmodel.js
@@ -33,9 +33,10 @@
/**
* @returns {boolean}
+ * @deprecated here for legacy reasons - will always return true
*/
areAvatarsEnabled: function() {
- return oc_config.enable_avatars === true;
+ return true;
},
/**
diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js
index cb553947de6..84a3d18942f 100644
--- a/core/js/sharedialoglinkshareview.js
+++ b/core/js/sharedialoglinkshareview.js
@@ -43,6 +43,13 @@
'</div>' +
' {{/if}}' +
' {{/if}}' +
+ ' {{#if publicEditing}}' +
+ '<div id="allowPublicEditingWrapper">' +
+ ' <span class="icon-loading-small hidden"></span>' +
+ ' <input type="checkbox" value="1" name="allowPublicEditing" id="sharingDialogAllowPublicEditing-{{cid}}" class="checkbox publicEditingCheckbox" {{{publicEditingChecked}}} />' +
+ '<label for="sharingDialogAllowPublicEditing-{{cid}}">{{publicEditingLabel}}</label>' +
+ '</div>' +
+ ' {{/if}}' +
' {{#if showPasswordCheckBox}}' +
'<input type="checkbox" name="showPassword" id="showPassword-{{cid}}" class="checkbox showPasswordCheckbox" {{#if isPasswordSet}}checked="checked"{{/if}} value="1" />' +
'<label for="showPassword-{{cid}}">{{enablePasswordLabel}}</label>' +
@@ -87,6 +94,7 @@
'click .linkCheckbox': 'onLinkCheckBoxChange',
'click .linkText': 'onLinkTextClick',
'change .publicUploadCheckbox': 'onAllowPublicUploadChange',
+ 'change .publicEditingCheckbox': 'onAllowPublicEditingChange',
'change .hideFileListCheckbox': 'onHideFileListChange',
'click .showPasswordCheckbox': 'onShowPasswordClick'
},
@@ -128,7 +136,8 @@
'onLinkTextClick',
'onShowPasswordClick',
'onHideFileListChange',
- 'onAllowPublicUploadChange'
+ 'onAllowPublicUploadChange',
+ 'onAllowPublicEditingChange'
);
var clipboard = new Clipboard('.clipboardButton');
@@ -266,6 +275,20 @@
});
},
+ onAllowPublicEditingChange: function() {
+ var $checkbox = this.$('.publicEditingCheckbox');
+ $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');
+
+ var permissions = OC.PERMISSION_READ;
+ if($checkbox.is(':checked')) {
+ permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_READ;
+ }
+
+ this.model.saveLinkShare({
+ permissions: permissions
+ });
+ },
+
onHideFileListChange: function () {
var $checkbox = this.$('.hideFileListCheckbox');
$checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');
@@ -307,6 +330,12 @@
publicUploadChecked = 'checked="checked"';
}
+ var publicEditingChecked = '';
+ if(this.model.isPublicEditingAllowed()) {
+ publicEditingChecked = 'checked="checked"';
+ }
+
+
var hideFileList = publicUploadChecked;
var hideFileListChecked = '';
@@ -320,6 +349,11 @@
&& ( !this.configModel.get('enforcePasswordForPublicLink')
|| !this.model.get('linkShare').password);
+ var publicEditable =
+ !this.model.isFolder()
+ && isLinkShare
+ && this.model.updatePermissionPossible();
+
this.$el.html(linkShareTemplate({
cid: this.cid,
shareAllowed: true,
@@ -337,6 +371,9 @@
publicUploadChecked: publicUploadChecked,
hideFileListChecked: hideFileListChecked,
publicUploadLabel: t('core', 'Allow upload and editing'),
+ publicEditing: publicEditable,
+ publicEditingChecked: publicEditingChecked,
+ publicEditingLabel: t('core', 'Allow editing'),
hideFileListLabel: t('core', 'File drop (upload only)'),
mailPrivatePlaceholder: t('core', 'Email link to person'),
mailButtonText: t('core', 'Send')
diff --git a/core/js/sharedialogresharerinfoview.js b/core/js/sharedialogresharerinfoview.js
index 9a9d95cfb60..a82b495bdcc 100644
--- a/core/js/sharedialogresharerinfoview.js
+++ b/core/js/sharedialogresharerinfoview.js
@@ -17,9 +17,7 @@
var TEMPLATE =
'<span class="reshare">' +
- ' {{#if avatarEnabled}}' +
' <div class="avatar" data-userName="{{reshareOwner}}"></div>' +
- ' {{/if}}' +
' {{sharedByText}}' +
'</span><br/>'
;
@@ -93,17 +91,14 @@
}
this.$el.html(reshareTemplate({
- avatarEnabled: this.configModel.areAvatarsEnabled(),
reshareOwner: this.model.getReshareOwner(),
sharedByText: sharedByText
}));
- if(this.configModel.areAvatarsEnabled()) {
- this.$el.find('.avatar').each(function() {
- var $this = $(this);
- $this.avatar($this.data('username'), 32);
- });
- }
+ this.$el.find('.avatar').each(function() {
+ var $this = $(this);
+ $this.avatar($this.data('username'), 32);
+ });
return this;
},
diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js
index 4647dedd722..47dc62d14fe 100644
--- a/core/js/sharedialogshareelistview.js
+++ b/core/js/sharedialogshareelistview.js
@@ -21,9 +21,7 @@
'<ul id="shareWithList" class="shareWithList">' +
'{{#each sharees}}' +
'<li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}">' +
- '{{#if avatarEnabled}}' +
'<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" data-displayname="{{shareWithDisplayName}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>' +
- '{{/if}}' +
'<span class="has-tooltip username" title="{{shareWithTitle}}">{{shareWithDisplayName}}</span>' +
'<span class="sharingOptionsGroup">' +
'{{#if editPermissionPossible}}' +
@@ -41,9 +39,7 @@
'{{/each}}' +
'{{#each linkReshares}}' +
'<li data-share-id="{{shareId}}" data-share-type="{{shareType}}">' +
- '{{#if avatarEnabled}}' +
'<div class="avatar" data-username="{{shareInitiator}}"></div>' +
- '{{/if}}' +
'<span class="has-tooltip username" title="{{shareInitiator}}">' + t('core', '{{shareInitiatorDisplayName}} shared via link') + '</span>' +
'<span class="sharingOptionsGroup">' +
@@ -193,7 +189,6 @@
getShareProperties: function() {
return {
- avatarEnabled: this.configModel.areAvatarsEnabled(),
unshareLabel: t('core', 'Unshare'),
canShareLabel: t('core', 'can reshare'),
canEditLabel: t('core', 'can edit'),
@@ -247,7 +242,6 @@
getLinkReshares: function() {
var universal = {
unshareLabel: t('core', 'Unshare'),
- avatarEnabled: this.configModel.areAvatarsEnabled(),
};
if(!this.model.hasUserShares()) {
@@ -281,18 +275,16 @@
linkReshares: this.getLinkReshares()
}));
- if (this.configModel.areAvatarsEnabled()) {
- this.$('.avatar').each(function () {
- var $this = $(this);
- if ($this.hasClass('imageplaceholderseed')) {
- $this.css({width: 32, height: 32});
- $this.imageplaceholder($this.data('seed'));
- } else {
- // user, size, ie8fix, hidedefault, callback, displayname
- $this.avatar($this.data('username'), 32, undefined, undefined, undefined, $this.data('displayname'));
- }
- });
- }
+ this.$('.avatar').each(function () {
+ var $this = $(this);
+ if ($this.hasClass('imageplaceholderseed')) {
+ $this.css({width: 32, height: 32});
+ $this.imageplaceholder($this.data('seed'));
+ } else {
+ // user, size, ie8fix, hidedefault, callback, displayname
+ $this.avatar($this.data('username'), 32, undefined, undefined, undefined, $this.data('displayname'));
+ }
+ });
this.$('.has-tooltip').tooltip({
placement: 'bottom'
diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js
index 60cd97fb572..a63960da2b8 100644
--- a/core/js/sharedialogview.js
+++ b/core/js/sharedialogview.js
@@ -130,18 +130,46 @@
},
autocompleteHandler: function (search, response) {
- var view = this;
- var $loading = this.$el.find('.shareWithLoading');
+ var $shareWithField = $('.shareWithField'),
+ view = this,
+ $loading = this.$el.find('.shareWithLoading'),
+ $remoteShareInfo = this.$el.find('.shareWithRemoteInfo');
+
+ var count = oc_config['sharing.minSearchStringLength'];
+ if (search.term.trim().length < count) {
+ var title = n('core',
+ 'At least {count} character is needed for autocompletion',
+ 'At least {count} characters are needed for autocompletion',
+ count,
+ { count: count }
+ );
+ $shareWithField.addClass('error')
+ .attr('data-original-title', title)
+ .tooltip('hide')
+ .tooltip({
+ placement: 'bottom',
+ trigger: 'manual'
+ })
+ .tooltip('fixTitle')
+ .tooltip('show');
+ response();
+ return;
+ }
+
$loading.removeClass('hidden');
$loading.addClass('inlineblock');
- var $remoteShareInfo = this.$el.find('.shareWithRemoteInfo');
$remoteShareInfo.addClass('hidden');
+
+ $shareWithField.removeClass('error')
+ .tooltip('hide');
+
+ var perPage = 200;
$.get(
OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
{
format: 'json',
search: search.term.trim(),
- perPage: 200,
+ perPage: perPage,
itemType: view.model.get('itemType')
},
function (result) {
@@ -232,16 +260,27 @@
var suggestions = users.concat(groups).concat(remotes).concat(emails).concat(lookup);
if (suggestions.length > 0) {
- $('.shareWithField').removeClass('error')
- .tooltip('hide')
+ $shareWithField
.autocomplete("option", "autoFocus", true);
+
response(suggestions);
+
+ // show a notice that the list is truncated
+ // this is the case if one of the search results is at least as long as the max result config option
+ if(oc_config['sharing.maxAutocompleteResults'] > 0 &&
+ Math.min(perPage, oc_config['sharing.maxAutocompleteResults'])
+ <= Math.max(users.length, groups.length, remotes.length, emails.length, lookup.length)) {
+
+ var message = t('core', 'This list is maybe truncated - please refine your search term to see more results.');
+ $('.ui-autocomplete').append('<li class="autocomplete-note">' + message + '</li>');
+ }
+
} else {
- var title = t('core', 'No users or groups found for {search}', {search: $('.shareWithField').val()});
+ var title = t('core', 'No users or groups found for {search}', {search: $shareWithField.val()});
if (!view.configModel.get('allowGroupSharing')) {
title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()});
}
- $('.shareWithField').addClass('error')
+ $shareWithField.addClass('error')
.attr('data-original-title', title)
.tooltip('hide')
.tooltip({
diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js
index 9b10f067afc..ae4c07e3f4e 100644
--- a/core/js/shareitemmodel.js
+++ b/core/js/shareitemmodel.js
@@ -272,6 +272,10 @@
return this.get('allowPublicUploadStatus');
},
+ isPublicEditingAllowed: function() {
+ return this.get('allowPublicEditingStatus');
+ },
+
/**
* @returns {boolean}
*/
@@ -679,6 +683,17 @@
});
}
+ var allowPublicEditingStatus = true;
+ if(!_.isUndefined(data.shares)) {
+ $.each(data.shares, function (key, value) {
+ if (value.share_type === OC.Share.SHARE_TYPE_LINK) {
+ allowPublicEditingStatus = (value.permissions & OC.PERMISSION_UPDATE) ? true : false;
+ return true;
+ }
+ });
+ }
+
+
var hideFileListStatus = false;
if(!_.isUndefined(data.shares)) {
$.each(data.shares, function (key, value) {
@@ -762,6 +777,7 @@
linkShare: linkShare,
permissions: permissions,
allowPublicUploadStatus: allowPublicUploadStatus,
+ allowPublicEditingStatus: allowPublicEditingStatus,
hideFileListStatus: hideFileListStatus
};
},
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index d83c0cd9a38..3380b6be420 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -1000,7 +1000,7 @@ describe('Core base tests', function() {
describe('global ajax errors', function() {
var reloadStub, ajaxErrorStub, clock;
var notificationStub;
- var waitTimeMs = 6000;
+ var waitTimeMs = 6500;
var oldCurrentUser;
beforeEach(function() {
@@ -1075,10 +1075,12 @@ describe('Core base tests', function() {
it('displays notification', function() {
var xhr = { status: 401 };
+ notificationUpdateStub = sinon.stub(OC.Notification, 'showUpdate');
+
$(document).trigger(new $.Event('ajaxError'), xhr);
clock.tick(waitTimeMs);
- expect(notificationStub.calledOnce).toEqual(true);
+ expect(notificationUpdateStub.notCalled).toEqual(false);
});
it('shows a temporary notification if the connection is lost', function() {
var xhr = { status: 0 };
diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js
index cbb74714ff7..307adea85ff 100644
--- a/core/js/tests/specs/sharedialogviewSpec.js
+++ b/core/js/tests/specs/sharedialogviewSpec.js
@@ -24,7 +24,6 @@ describe('OC.Share.ShareDialogView', function() {
var $container;
var oldAppConfig;
var autocompleteStub;
- var oldEnableAvatars;
var avatarStub;
var placeholderStub;
var oldCurrentUser;
@@ -103,8 +102,6 @@ describe('OC.Share.ShareDialogView', function() {
return $el;
});
- oldEnableAvatars = oc_config.enable_avatars;
- oc_config.enable_avatars = false;
avatarStub = sinon.stub($.fn, 'avatar');
placeholderStub = sinon.stub($.fn, 'imageplaceholder');
@@ -123,7 +120,6 @@ describe('OC.Share.ShareDialogView', function() {
autocompleteStub.restore();
avatarStub.restore();
placeholderStub.restore();
- oc_config.enable_avatars = oldEnableAvatars;
});
describe('Share with link', function() {
// TODO: test ajax calls
@@ -440,18 +436,13 @@ describe('OC.Share.ShareDialogView', function() {
describe('avatars enabled', function() {
beforeEach(function() {
- oc_config.enable_avatars = true;
avatarStub.reset();
dialog.render();
});
- afterEach(function() {
- oc_config.enable_avatars = false;
- });
-
it('test correct function calls', function() {
expect(avatarStub.calledTwice).toEqual(true);
- expect(placeholderStub.calledTwice).toEqual(true);
+ expect(placeholderStub.callCount).toEqual(4);
expect(dialog.$('.shareWithList').children().length).toEqual(3);
expect(dialog.$('.avatar').length).toEqual(4);
});
@@ -481,18 +472,6 @@ describe('OC.Share.ShareDialogView', function() {
expect(args[0]).toEqual('foo@bar.com/baz ' + OC.Share.SHARE_TYPE_REMOTE);
});
});
-
- describe('avatars disabled', function() {
- beforeEach(function() {
- dialog.render();
- });
-
- it('no avatar classes', function() {
- expect($('.avatar').length).toEqual(0);
- expect(avatarStub.callCount).toEqual(0);
- expect(placeholderStub.callCount).toEqual(0);
- });
- });
});
describe('remote sharing', function() {
it('shows remote share info when allowed', function() {