Update share action text to display owner/recipients

- when a share was changed, update the share action text
- added file data attribute "data-share-recipients"
This commit is contained in:
Vincent Petry 2014-05-28 18:39:29 +02:00
parent f931df2dac
commit 7961d4a87e
4 changed files with 226 additions and 131 deletions

View File

@ -8,7 +8,9 @@
*
*/
OCA.Sharing = {};
if (!OCA.Sharing) {
OCA.Sharing = {};
}
OCA.Sharing.App = {
_inFileList: null,

View File

@ -8,7 +8,12 @@
*
*/
$(document).ready(function() {
(function() {
if (!OCA.Sharing) {
OCA.Sharing = {};
}
OCA.Sharing.Util = {
initialize: function() {
if (!_.isUndefined(OC.Share) && !_.isUndefined(OCA.Files)) {
// TODO: make a separate class for this or a hook or jQuery event ?
if (OCA.Files.FileList) {
@ -36,17 +41,11 @@ $(document).ready(function() {
var $fileList = $(this);
$fileList.find('[data-share-owner]').each(function() {
var $tr = $(this);
var $action;
var owner;
var message;
var permissions = $tr.data('permissions');
if(permissions & OC.PERMISSION_SHARE) {
$action = $tr.find('[data-Action="Share"]');
$action.addClass('permanent');
owner = $tr.closest('tr').attr('data-share-owner');
message = ' ' + t('files_sharing', 'Shared by {owner}', {owner: owner});
$action.find('span').text(message);
OC.Share.markFileAsShared($tr, true);
} else {
// TODO: make this work like/with OC.Share.markFileAsShared()
var shareNotification = '<a class="action action-share-notification permanent"' +
' data-action="Share-Notification" href="#" original-title="">' +
' <img class="svg" src="' + OC.imagePath('core', 'actions/share') + '"></img>';
@ -105,6 +104,58 @@ $(document).ready(function() {
$tr.addClass('mouseOver');
OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
}
$('#dropdown').on('sharesChanged', function(ev) {
// note: we only update the data attribute because updateIcon()
// is called automatically after this event
var userShares = ev.itemShares[OC.Share.SHARE_TYPE_USER] || [];
var groupShares = ev.itemShares[OC.Share.SHARE_TYPE_GROUP] || [];
var linkShares = ev.itemShares[OC.Share.SHARE_TYPE_LINK] || [];
var recipients = _.union(userShares, groupShares);
if (linkShares.length > 0) {
recipients.unshift(t('files_sharing', 'Public'));
}
// only update the recipients if they existed before
// (some file lists don't have them)
if (!_.isUndefined($tr.attr('data-share-recipients'))) {
// FIXME: use display names from users, we currently only got user ids
if (recipients.length) {
$tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
}
else {
$tr.attr('data-share-recipients', '');
}
}
});
});
}
},
/**
* Formats a recipient array to be displayed.
* The first four recipients will be shown and the
* other ones will be shown as "+x" where "x" is the number of
* remaining recipients.
*
* @param recipients recipients array
* @param count optional total recipients count (in case the array was shortened)
* @return formatted recipients display text
*/
formatRecipients: function(recipients, count) {
var maxRecipients = 4;
var text;
if (!_.isNumber(count)) {
count = recipients.length;
}
text = _.first(recipients, maxRecipients).join(', ');
if (count > maxRecipients) {
text += ', +' + (count - maxRecipients);
}
return text;
}
};
})();
$(document).ready(function() {
OCA.Sharing.Util.initialize();
});

View File

@ -48,6 +48,9 @@
if (this._sharedWithUser) {
$tr.attr('data-share-owner', fileData.shares[0].ownerDisplayName);
}
if (fileData.recipientsDisplayName) {
$tr.attr('data-share-recipients', fileData.recipientsDisplayName);
}
return $tr;
},
@ -179,15 +182,15 @@
// inside the same file object (by file id).
.reduce(function(memo, file) {
var data = memo[file.id];
var counterPart = file.share.ownerDisplayName || file.share.targetDisplayName;
var recipient = file.share.targetDisplayName;
if (!data) {
data = memo[file.id] = file;
data.shares = [file.share];
// using a hash to make them unique,
// this is only a list to be displayed
data.counterParts = {};
data.recipients = {};
// counter is cheaper than calling _.keys().length
data.counterPartsCount = 0;
data.recipientsCount = 0;
data.mtime = file.share.stime;
}
else {
@ -200,10 +203,14 @@
if (file.share.type === OC.Share.SHARE_TYPE_LINK) {
data.hasLinkShare = true;
} else if (counterPart && data.counterPartsCount < 10) {
} else if (recipient) {
// limit counterparts for output
data.counterParts[counterPart] = true;
data.counterPartsCount++;
if (data.recipientsCount < 3) {
// only store the first ones, they will be the only ones
// displayed
data.recipients[recipient] = true;
}
data.recipientsCount++;
}
delete file.share;
@ -213,14 +220,18 @@
.values()
// Clean up
.each(function(data) {
// convert the counterParts map to a flat
// convert the recipients map to a flat
// array of sorted names
data.counterParts = _.chain(data.counterParts).keys().sort().value();
data.recipients = _.chain(data.recipients).keys().sort().value();
if (data.hasLinkShare) {
data.counterParts.unshift(t('files_sharing', 'link'));
data.recipients.unshift(t('files_sharing', 'Public'));
delete data.hasLinkShare;
}
delete data.counterPartsCount;
data.recipientsDisplayName = OCA.Sharing.Util.formatRecipients(
data.recipients,
data.recipientsCount
);
delete data.recipientsCount;
})
// Sort by expected sort comparator
.sortBy(this._sortComparator)

View File

@ -56,20 +56,14 @@ OC.Share={
image = OC.imagePath('core', 'actions/public');
}
if (itemType !== 'file' && itemType !== 'folder') {
$fileList.find('a.share[data-item="'+item+'"]').css('background', 'url('+image+') no-repeat center');
$('a.share[data-item="'+item+'"]').css('background', 'url('+image+') no-repeat center');
} else {
// TODO: ultimately this part should be moved to files_sharing app
var file = $fileList.find('tr[data-id="'+item+'"]');
var shareFolder = OC.imagePath('core', 'filetypes/folder-shared');
var img;
if (file.length > 0) {
var type = file.data('type');
if (type === 'dir') {
file.children('.filename').css('background-image', 'url('+shareFolder+')');
}
var action = $(file).find('.fileactions .action[data-action="Share"]');
img = action.find('img').attr('src', image);
action.addClass('permanent');
action.html(' <span>'+t('core', 'Shared')+'</span>').prepend(img);
this.markFileAsShared(file, true, image);
} else {
var dir = currentDir;
if (dir.length > 1) {
@ -82,6 +76,7 @@ OC.Share={
var files = $fileList.find('.filename');
var i;
for (i = 0; i < actions.length; i++) {
// TODO: use this.markFileAsShared()
img = $(actions[i]).find('img');
if (img.attr('src') !== OC.imagePath('core', 'actions/public')) {
img.attr('src', image);
@ -125,29 +120,9 @@ OC.Share={
if (itemType != 'file' && itemType != 'folder') {
$('a.share[data-item="'+itemSource+'"]').css('background', 'url('+image+') no-repeat center');
} else {
var file = $('tr').filterAttr('data-id', String(itemSource));
if (file.length > 0) {
var type = file.data('type');
var shareFolder = OC.imagePath('core', 'filetypes/folder');
if (type === 'dir' && shares) {
shareFolder = OC.imagePath('core', 'filetypes/folder-shared');
file.children('.filename').css('background-image', 'url('+shareFolder+')');
} else if (type === 'dir') {
file.children('.filename').css('background-image', 'url('+shareFolder+')');
}
var action = $(file).find('.fileactions .action').filterAttr('data-action', 'Share');
// in case of multiple lists/rows, there might be more than one visible
action.each(function() {
var action = $(this);
var img = action.find('img').attr('src', image);
if (shares) {
action.addClass('permanent');
action.html(' <span>'+ escapeHTML(t('core', 'Shared'))+'</span>').prepend(img);
} else {
action.removeClass('permanent');
action.html(' <span>'+ escapeHTML(t('core', 'Share'))+'</span>').prepend(img);
}
});
var $tr = $('tr').filterAttr('data-id', String(itemSource));
if ($tr.length > 0) {
this.markFileAsShared($tr, shares, image);
}
}
if (shares) {
@ -157,6 +132,59 @@ OC.Share={
delete OC.Share.statuses[itemSource];
}
},
/**
* Marks/unmarks a given file as shared
*
* @param $tr file element to mark as shared
* @param state true to mark as shared, false to unmark
* @param image image to use for the icon
*/
markFileAsShared: function($tr, state, image) {
var action = $tr.find('.fileactions .action[data-action="Share"]');
var type = $tr.data('type');
var img = action.find('img');
var message;
var recipients;
var owner;
var shareFolderIcon;
if (type === 'dir' && state) {
shareFolderIcon = OC.imagePath('core', 'filetypes/folder-shared');
$tr.children('.filename').css('background-image', 'url(' + shareFolderIcon + ')');
} else if (type === 'dir') {
shareFolderIcon = OC.imagePath('core', 'filetypes/folder');
$tr.children('.filename').css('background-image', 'url(' + shareFolderIcon + ')');
}
if (state) {
recipients = $tr.attr('data-share-recipients');
owner = $tr.attr('data-share-owner');
action.addClass('permanent');
message = t('core', 'Shared');
if (owner && !recipients) {
message = t('files_sharing', 'Shared by {owner}', {owner: owner});
image = image || OC.imagePath('core', 'actions/share');
}
if (recipients) {
image = image || OC.imagePath('core', 'actions/shared');
if (owner) {
message = ' ' + t(
'files_sharing',
'Shared by {owner} with You, {recipients}',
{owner: owner, recipients: recipients}
);
}
else {
message = t('core', 'Shared with {recipients}', {recipients: recipients});
}
}
action.html(' <span>'+ message + '</span>').prepend(img);
}
else {
action.removeClass('permanent');
action.html(' <span>'+ escapeHTML(t('core', 'Share'))+'</span>').prepend(img);
}
img.attr('src', image);
},
loadItem:function(itemType, itemSource) {
var data = '';
var checkReshare = true;
@ -384,6 +412,7 @@ OC.Share={
OC.Share.share(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, function() {
OC.Share.addShareWith(shareType, shareWith, selected.item.label, permissions, possiblePermissions);
$('#shareWith').val('');
$('#dropdown').trigger(new $.Event('sharesChanged', {itemShares: OC.Share.itemShares}));
OC.Share.updateIcon(itemType, itemSource);
});
return false;
@ -665,6 +694,7 @@ $(document).ready(function() {
$li.remove();
var index = OC.Share.itemShares[shareType].indexOf(shareWith);
OC.Share.itemShares[shareType].splice(index, 1);
$('#dropdown').trigger(new $.Event('sharesChanged', {itemShares: OC.Share.itemShares}));
OC.Share.updateIcon(itemType, itemSource);
if (typeof OC.Share.statuses[itemSource] === 'undefined') {
$('#expiration').hide('blind');
@ -723,6 +753,7 @@ $(document).ready(function() {
if (oc_appconfig.core.enforcePasswordForPublicLink === false) {
OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, itemSourceName, expirationDate, function(data) {
OC.Share.showLink(data.token, null, itemSource);
$('#dropdown').trigger(new $.Event('sharesChanged', {itemShares: OC.Share.itemShares}));
OC.Share.updateIcon(itemType, itemSource);
});
} else {