diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 194c658e3a18..23834fa44de3 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -367,6 +367,21 @@
return model;
},
+ /**
+ * Displays the details view for the given file and
+ * selects the given tab
+ *
+ * @param {string} fileName file name for which to show details
+ * @param {string} [tabId] optional tab id to select
+ */
+ showDetailsView: function(fileName, tabId) {
+ this._updateDetailsView(fileName);
+ if (tabId) {
+ this._detailsView.selectTab(tabId);
+ }
+ OC.Apps.showAppSidebar();
+ },
+
/**
* Update the details view to display the given file
*
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 20f1b046d35b..8d919d1466fa 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -54,9 +54,18 @@
\OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
-\OCP\Util::addScript('files_sharing', 'share');
-\OCP\Util::addScript('files_sharing', 'external');
-\OCP\Util::addStyle('files_sharing', 'sharetabview');
+$eventDispatcher = \OC::$server->getEventDispatcher();
+$eventDispatcher->addListener(
+ 'OCA\Files::loadAdditionalScripts',
+ function() {
+ \OCP\Util::addScript('files_sharing', 'share');
+ \OCP\Util::addScript('files_sharing', 'sharetabview');
+ \OCP\Util::addScript('files_sharing', 'external');
+ \OCP\Util::addStyle('files_sharing', 'sharetabview');
+ }
+);
+
+// \OCP\Util::addStyle('files_sharing', 'sharetabview');
\OC::$server->getActivityManager()->registerExtension(function() {
return new \OCA\Files_Sharing\Activity(
diff --git a/apps/files_sharing/css/sharetabview.css b/apps/files_sharing/css/sharetabview.css
index 42c9bee71731..0cc812e917c3 100644
--- a/apps/files_sharing/css/sharetabview.css
+++ b/apps/files_sharing/css/sharetabview.css
@@ -1,3 +1,75 @@
.app-files .shareTabView {
min-height: 100px;
}
+
+.shareTabView .oneline { white-space: nowrap; }
+
+.shareTabView .shareWithLoading {
+ padding-left: 10px;
+ position: relative;
+ right: 30px;
+ top: 2px;
+}
+
+.shareTabView .shareWithRemoteInfo {
+ padding: 11px 0 11px 10px
+}
+
+.shareTabView label {
+ font-weight:400;
+ white-space: nowrap;
+}
+
+.shareTabView input[type="checkbox"] {
+ margin:0 3px 0 8px;
+ vertical-align: middle;
+}
+
+.shareTabView input[type="text"], .shareTabView input[type="password"] {
+ width: 91%;
+ margin-left: 7px;
+}
+
+.shareTabView form {
+ font-size: 100%;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#shareWithList {
+ list-style-type:none;
+ padding:8px;
+}
+
+#shareWithList li {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ font-weight: bold;
+ line-height: 21px;
+ white-space: normal;
+}
+
+#shareWithList .unshare img, #shareWithList .showCruds img {
+ vertical-align:text-bottom; /* properly align icons */
+}
+
+#shareWithList label input[type=checkbox]{
+ margin-left: 0;
+ position: relative;
+}
+#shareWithList .username{
+ padding-right: 8px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ max-width: 254px;
+ display: inline-block;
+ overflow: hidden;
+ vertical-align: middle;
+}
+#shareWithList li label{
+ margin-right: 8px;
+}
+
+.shareTabView .icon-loading-small {
+ margin-left: -30px;
+}
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index c124d390d047..5290dfbb7d19 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -79,7 +79,9 @@
$files = fileList.$fileList.find('tr');
}
_.each($files, function(file) {
- OCA.Sharing.Util.updateFileActionIcon($(file));
+ var $tr = $(file);
+ var shareStatus = OC.Share.statuses[$tr.data('id')];
+ OCA.Sharing.Util._updateFileActionIcon($tr, !!shareStatus, shareStatus && shareStatus.link);
});
}
@@ -104,71 +106,59 @@
permissions: OC.PERMISSION_SHARE,
icon: OC.imagePath('core', 'actions/share'),
type: OCA.Files.FileActions.TYPE_INLINE,
- actionHandler: function(filename, context) {
- var $tr = context.$file;
- var itemType = 'file';
- if ($tr.data('type') === 'dir') {
- itemType = 'folder';
- }
- var possiblePermissions = $tr.data('share-permissions');
- if (_.isUndefined(possiblePermissions)) {
- possiblePermissions = $tr.data('permissions');
- }
-
- var appendTo = $tr.find('td.filename');
- // Check if drop down is already visible for a different file
- if (OC.Share.droppedDown) {
- if ($tr.attr('data-id') !== $('#dropdown').attr('data-item-source')) {
- OC.Share.hideDropDown(function () {
- $tr.addClass('mouseOver');
- OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
- });
- } else {
- OC.Share.hideDropDown();
- }
- } else {
- $tr.addClass('mouseOver');
- OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
- }
- $('#dropdown').on('sharesChanged', function(ev) {
- // files app current cannot show recipients on load, so we don't update the
- // icon when changed for consistency
- if (context.fileList.$el.closest('#app-content-files').length) {
- return;
- }
- var recipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_USER], 'share_with_displayname');
- var groupRecipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_GROUP], 'share_with_displayname');
- recipients = recipients.concat(groupRecipients);
- // note: we only update the data attribute because updateIcon()
- // is called automatically after this event
- if (recipients.length) {
- $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
- }
- else {
- $tr.removeAttr('data-share-recipients');
- }
- });
+ actionHandler: function(fileName) {
+ fileList.showDetailsView(fileName, 'shareTabView');
}
});
- OC.addScript('files_sharing', 'sharetabview').done(function() {
- fileList.registerTabView(new OCA.Sharing.ShareTabView('shareTabView'));
+ var shareTab = new OCA.Sharing.ShareTabView('shareTabView');
+ // detect changes and change the matching list entry
+ shareTab.on('sharesChanged', function(shareModel) {
+ var fileInfoModel = shareModel.fileInfoModel;
+ var $tr = fileList.findFileEl(fileInfoModel.get('name'));
+ OCA.Sharing.Util._updateFileListDataAttributes(fileList, $tr, shareModel);
+ if (!OCA.Sharing.Util._updateFileActionIcon($tr, shareModel.hasUserShares(), shareModel.hasLinkShare())) {
+ // remove icon, if applicable
+ OC.Share.markFileAsShared($tr, false, false);
+ }
});
+ fileList.registerTabView(shareTab);
+ },
+
+ /**
+ * Update file list data attributes
+ */
+ _updateFileListDataAttributes: function(fileList, $tr, shareModel) {
+ // files app current cannot show recipients on load, so we don't update the
+ // icon when changed for consistency
+ if (fileList.id === 'files') {
+ return;
+ }
+ var recipients = _.pluck(shareModel.get('shares'), 'share_with_displayname');
+ // note: we only update the data attribute because updateIcon()
+ if (recipients.length) {
+ $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
+ }
+ else {
+ $tr.removeAttr('data-share-recipients');
+ }
},
/**
* Update the file action share icon for the given file
*
* @param $tr file element of the file to update
+ * @param {bool} hasUserShares true if a user share exists
+ * @param {bool} hasLinkShare true if a link share exists
+ *
+ * @return {bool} true if the icon was set, false otherwise
*/
- updateFileActionIcon: function($tr) {
+ _updateFileActionIcon: function($tr, hasUserShares, hasLinkShare) {
// if the statuses are loaded already, use them for the icon
// (needed when scrolling to the next page)
- var shareStatus = OC.Share.statuses[$tr.data('id')];
- if (shareStatus || $tr.attr('data-share-recipients') || $tr.attr('data-share-owner')) {
+ if (hasUserShares || hasLinkShare || $tr.attr('data-share-recipients') || $tr.attr('data-share-owner')) {
var permissions = $tr.data('permissions');
- var hasLink = !!(shareStatus && shareStatus.link);
- OC.Share.markFileAsShared($tr, true, hasLink);
+ OC.Share.markFileAsShared($tr, true, hasLinkShare);
if ((permissions & OC.PERMISSION_SHARE) === 0 && $tr.attr('data-share-owner')) {
// if no share action exists because the admin disabled sharing for this user
// we create a share notification action to inform the user about files
@@ -187,7 +177,9 @@
return $result;
});
}
+ return true;
}
+ return false;
},
/**
diff --git a/apps/files_sharing/js/sharetabview.js b/apps/files_sharing/js/sharetabview.js
index ee572b747ead..e24320604fb1 100644
--- a/apps/files_sharing/js/sharetabview.js
+++ b/apps/files_sharing/js/sharetabview.js
@@ -10,7 +10,9 @@
(function() {
var TEMPLATE =
- '
';
- if (data !== false && data.reshare !== false && data.reshare.uid_owner !== undefined && data.reshare.uid_owner !== OC.currentUser) {
- html += '
';
- if (oc_config.enable_avatars === true) {
- html += '
';
- }
-
- if (data.reshare.share_type == OC.Share.SHARE_TYPE_GROUP) {
- html += t('core', 'Shared with you and the group {group} by {owner}', {group: data.reshare.share_with, owner: data.reshare.displayname_owner});
- } else {
- html += t('core', 'Shared with you by {owner}', {owner: data.reshare.displayname_owner});
- }
- html += ' ';
- // reduce possible permissions to what the original share allowed
- possiblePermissions = possiblePermissions & data.reshare.permissions;
- }
-
- if (possiblePermissions & OC.PERMISSION_SHARE) {
- // Determine the Allow Public Upload status.
- // Used later on to determine if the
- // respective checkbox should be checked or
- // not.
-
- var publicUploadEnabled = $('#filestable').data('allow-public-upload');
- if (typeof publicUploadEnabled == 'undefined') {
- publicUploadEnabled = 'no';
- }
- var allowPublicUploadStatus = false;
-
- $.each(data.shares, function(key, value) {
- if (value.share_type === OC.Share.SHARE_TYPE_LINK) {
- allowPublicUploadStatus = (value.permissions & OC.PERMISSION_CREATE) ? true : false;
- return true;
- }
- });
-
- var sharePlaceholder = t('core', 'Share with users or groups …');
- if(oc_appconfig.core.remoteShareAllowed) {
- sharePlaceholder = t('core', 'Share with users, groups or remote users …');
+ var configModel = new OC.Share.ShareConfigModel();
+ var attributes = {itemType: itemType, itemSource: itemSource, possiblePermissions: possiblePermissions};
+ var itemModel = new OC.Share.ShareItemModel(attributes, {configModel: configModel});
+ var dialogView = new OC.Share.ShareDialogView({
+ id: 'dropdown',
+ model: itemModel,
+ configModel: configModel,
+ className: 'drop shareDropDown',
+ attributes: {
+ 'data-item-source-name': filename,
+ 'data-item-type': itemType,
+ 'data-item-soruce': itemSource
}
-
- html += '
'+t('core', 'Share')+' ';
- html += '
';
- if(oc_appconfig.core.remoteShareAllowed) {
- var federatedCloudSharingDoc = '
';
- html += federatedCloudSharingDoc.replace('{docLink}', oc_appconfig.core.federatedCloudShareDoc);
- }
- html += '
';
- html += '
';
- var linksAllowed = $('#allowShareWithLink').val() === 'yes';
- if (link && linksAllowed) {
- html += '
';
- var mailPublicNotificationEnabled = $('input:hidden[name=mailPublicNotificationEnabled]').val();
- if (mailPublicNotificationEnabled === 'yes') {
- html += '
';
- }
- }
-
- html += '
';
- html += ''+t('core', 'Set expiration date')+' ';
- html += ''+t('core', 'Expiration')+' ';
- html += ' ';
- html += ''+defaultExpireMessage+' ';
- html += '
';
- dropDownEl = $(html);
- dropDownEl = dropDownEl.appendTo(appendTo);
-
- // trigger remote share info tooltip
- if(oc_appconfig.core.remoteShareAllowed) {
- $('.shareWithRemoteInfo').tipsy({gravity: 'e'});
- }
-
- //Get owner avatars
- if (oc_config.enable_avatars === true && data !== false && data.reshare !== false && data.reshare.uid_owner !== undefined) {
- dropDownEl.find(".avatar").avatar(data.reshare.uid_owner, 32);
- }
-
- // Reset item shares
- OC.Share.itemShares = [];
- OC.Share.currentShares = {};
- if (data.shares) {
- $.each(data.shares, function(index, share) {
- if (share.share_type == OC.Share.SHARE_TYPE_LINK) {
- if (itemSource === share.file_source || itemSource === share.item_source) {
- OC.Share.showLink(share.token, share.share_with, itemSource);
- }
- } else {
- if (share.collection) {
- OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, share.collection);
- } else {
- if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) {
- OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE, share.mail_send, false);
- } else {
- OC.Share.addShareWith(share.share_type, share.share_with, share.share_with_displayname, share.permissions, possiblePermissions, share.mail_send, false);
- }
- }
- }
- if (share.expiration != null) {
- OC.Share.showExpirationDate(share.expiration, share.stime);
- }
- });
- }
- $('#shareWith').autocomplete({minLength: 2, delay: 750, source: function(search, response) {
- var $loading = $('#dropdown .shareWithLoading');
- $loading.removeClass('hidden');
- $.get(OC.filePath('core', 'ajax', 'share.php'), { fetch: 'getShareWith', search: search.term.trim(), limit: 200, itemShares: OC.Share.itemShares, itemType: itemType }, function(result) {
- $loading.addClass('hidden');
- if (result.status == 'success' && result.data.length > 0) {
- $( "#shareWith" ).autocomplete( "option", "autoFocus", true );
- response(result.data);
- } else {
- response();
- }
- }).fail(function(){
- $('#dropdown').find('.shareWithLoading').addClass('hidden');
- OC.Notification.show(t('core', 'An error occured. Please try again'));
- window.setTimeout(OC.Notification.hide, 5000);
- });
- },
- focus: function(event, focused) {
- event.preventDefault();
- },
- select: function(event, selected) {
- event.stopPropagation();
- var $dropDown = $('#dropdown');
- var itemType = $dropDown.data('item-type');
- var itemSource = $dropDown.data('item-source');
- var itemSourceName = $dropDown.data('item-source-name');
- var expirationDate = '';
- if ( $('#expirationCheckbox').is(':checked') === true ) {
- expirationDate = $( "#expirationDate" ).val();
- }
- var shareType = selected.item.value.shareType;
- var shareWith = selected.item.value.shareWith;
- $(this).val(shareWith);
- // Default permissions are Edit (CRUD) and Share
- // Check if these permissions are possible
- var permissions = OC.PERMISSION_READ;
- if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
- permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_READ;
- } else {
- if (possiblePermissions & OC.PERMISSION_UPDATE) {
- permissions = permissions | OC.PERMISSION_UPDATE;
- }
- if (possiblePermissions & OC.PERMISSION_CREATE) {
- permissions = permissions | OC.PERMISSION_CREATE;
- }
- if (possiblePermissions & OC.PERMISSION_DELETE) {
- permissions = permissions | OC.PERMISSION_DELETE;
- }
- if (oc_appconfig.core.resharingAllowed && (possiblePermissions & OC.PERMISSION_SHARE)) {
- permissions = permissions | OC.PERMISSION_SHARE;
- }
- }
-
- var $input = $(this);
- var $loading = $dropDown.find('.shareWithLoading');
- $loading.removeClass('hidden');
- $input.val(t('core', 'Adding user...'));
- $input.prop('disabled', true);
-
- OC.Share.share(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, function() {
- $input.prop('disabled', false);
- $loading.addClass('hidden');
- var posPermissions = possiblePermissions;
- if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
- posPermissions = permissions;
- }
- OC.Share.addShareWith(shareType, shareWith, selected.item.label, permissions, posPermissions);
- $('#shareWith').val('');
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
- OC.Share.updateIcon(itemType, itemSource);
- });
- return false;
- }
- })
- // customize internal _renderItem function to display groups and users differently
- .data("ui-autocomplete")._renderItem = function( ul, item ) {
- var insert = $( "
" );
- var text = item.label;
- if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
- text = text + ' ('+t('core', 'group')+')';
- } else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) {
- text = text + ' ('+t('core', 'remote')+')';
- }
- insert.text( text );
- if(item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
- insert = insert.wrapInner(' ');
- }
- return $( "" )
- .addClass((item.value.shareType === OC.Share.SHARE_TYPE_GROUP)?'group':'user')
- .append( insert )
- .appendTo( ul );
- };
- if (link && linksAllowed && $('#email').length != 0) {
- $('#email').autocomplete({
- minLength: 1,
- source: function (search, response) {
- $.get(OC.filePath('core', 'ajax', 'share.php'), { fetch: 'getShareWithEmail', search: search.term }, function(result) {
- if (result.status == 'success' && result.data.length > 0) {
- response(result.data);
- }
- });
- },
- select: function( event, item ) {
- $('#email').val(item.item.email);
- return false;
- }
- })
- .data("ui-autocomplete")._renderItem = function( ul, item ) {
- return $(' ')
- .append('' + escapeHTML(item.displayname) + " " + escapeHTML(item.email) + ' ' )
- .appendTo( ul );
- };
- }
-
- } else {
- html += ' ';
- html += ' ';
- dropDownEl = $(html);
- dropDownEl.appendTo(appendTo);
- }
- dropDownEl.attr('data-item-source-name', filename);
- $('#dropdown').slideDown(OC.menuSpeed, function() {
+ });
+ dialogView.setShowLink(link);
+ var $dialog = dialogView.render().$el;
+ $dialog.appendTo(appendTo);
+ $dialog.slideDown(OC.menuSpeed, function() {
OC.Share.droppedDown = true;
});
- if ($('html').hasClass('lte9')){
- $('#dropdown input[placeholder]').placeholder();
- }
- $('#shareWith').focus();
+ itemModel.fetch();
},
hideDropDown:function(callback) {
OC.Share.currentShares = null;
@@ -648,256 +419,10 @@ OC.Share={
}
});
},
- addShareWith:function(shareType, shareWith, shareWithDisplayName, permissions, possiblePermissions, mailSend, collection) {
- var shareItem = {
- share_type: shareType,
- share_with: shareWith,
- share_with_displayname: shareWithDisplayName,
- permissions: permissions
- };
- if (shareType === OC.Share.SHARE_TYPE_GROUP) {
- shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'group') + ')';
- }
- if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
- shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'remote') + ')';
- }
- if (!OC.Share.itemShares[shareType]) {
- OC.Share.itemShares[shareType] = [];
- }
- OC.Share.itemShares[shareType].push(shareWith);
- if (collection) {
- if (collection.item_type == 'file' || collection.item_type == 'folder') {
- var item = collection.path;
- } else {
- var item = collection.item_source;
- }
- var collectionList = $('#shareWithList li').filterAttr('data-collection', item);
- if (collectionList.length > 0) {
- $(collectionList).append(', '+shareWithDisplayName);
- } else {
- var html = '