diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index eea6715e57dff..ce7ba4091993a 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -94,6 +94,11 @@ 'url' => '/api/v1/sharees', 'verb' => 'GET', ], + [ + 'name' => 'ShareesAPI#findRecommended', + 'url' => '/api/v1/sharees_recommended', + 'verb' => 'GET', + ], /* * Remote Shares */ diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index c39547bdea501..a52ee88855a34 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -29,17 +29,29 @@ */ namespace OCA\Files_Sharing\Controller; +use function array_filter; +use function array_slice; +use function array_values; +use Generator; +use OC\Collaboration\Collaborators\SearchResult; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCSController; use OCP\Collaboration\Collaborators\ISearch; +use OCP\Collaboration\Collaborators\ISearchResult; +use OCP\Collaboration\Collaborators\SearchResultType; use OCP\IRequest; use OCP\IConfig; use OCP\IURLGenerator; use OCP\Share; use OCP\Share\IManager; +use function usort; class ShareesAPIController extends OCSController { + + /** @var userId */ + protected $userId; + /** @var IConfig */ protected $config; @@ -87,6 +99,7 @@ class ShareesAPIController extends OCSController { private $collaboratorSearch; /** + * @param string $UserId * @param string $appName * @param IRequest $request * @param IConfig $config @@ -95,6 +108,7 @@ class ShareesAPIController extends OCSController { * @param ISearch $collaboratorSearch */ public function __construct( + $UserId, string $appName, IRequest $request, IConfig $config, @@ -103,7 +117,7 @@ public function __construct( ISearch $collaboratorSearch ) { parent::__construct($appName, $request); - + $this->userId = $UserId; $this->config = $config; $this->urlGenerator = $urlGenerator; $this->shareManager = $shareManager; @@ -212,6 +226,148 @@ public function search(string $search = '', string $itemType = null, int $page = return $response; } + /** + * @param string $user + * @param int $shareType + * + * @return Generator> + */ + private function getAllShareesByType(string $user, int $shareType): Generator { + $offset = 0; + $pageSize = 50; + + while (count($page = $this->shareManager->getSharesBy( + $user, + $shareType, + null, + false, + $pageSize, + $offset + ))) { + foreach ($page as $share) { + yield [$share->getSharedWith(), $share->getSharedWithDisplayName() ?? $share->getSharedWith()]; + } + + $offset += $pageSize; + } + } + + private function sortShareesByFrequency(array $sharees): array { + usort($sharees, function(array $s1, array $s2) { + return $s2['count'] - $s1['count']; + }); + return $sharees; + } + + private $searchResultTypeMap = [ + Share::SHARE_TYPE_USER => 'users', + Share::SHARE_TYPE_GROUP => 'groups', + Share::SHARE_TYPE_REMOTE => 'remotes', + Share::SHARE_TYPE_REMOTE_GROUP => 'remote_groups', + Share::SHARE_TYPE_EMAIL => 'emails', + ]; + + private function getAllSharees(string $user, array $shareTypes): ISearchResult { + $result = []; + foreach ($shareTypes as $shareType) { + $sharees = $this->getAllShareesByType($user, $shareType); + $shareTypeResults = []; + foreach ($sharees as list($sharee, $displayname)) { + if (!isset($this->searchResultTypeMap[$shareType])) { + continue; + } + + if (!isset($shareTypeResults[$sharee])) { + $shareTypeResults[$sharee] = [ + 'count' => 1, + 'label' => $displayname, + 'value' => [ + 'shareType' => $shareType, + 'shareWith' => $sharee, + ], + ]; + } else { + $shareTypeResults[$sharee]['count']++; + } + } + $result = array_merge($result, array_values($shareTypeResults)); + } + + $top5 = array_slice( + $this->sortShareesByFrequency($result), + 0, + 5 + ); + + $searchResult = new SearchResult(); + foreach ($this->searchResultTypeMap as $int => $str) { + $searchResult->addResultSet(new SearchResultType($str), [], []); + foreach ($top5 as $x) { + if ($x['value']['shareType'] === $int) { + $searchResult->addResultSet(new SearchResultType($str), [], [$x]); + } + } + } + return $searchResult; + } + + /** + * @NoAdminRequired + * + * @param string $itemType + * @return DataResponse + * @throws OCSBadRequestException + */ + public function findRecommended(string $itemType = null, $shareType = null): DataResponse { + $shareTypes = [ + Share::SHARE_TYPE_USER, + ]; + + if ($itemType === null) { + throw new OCSBadRequestException('Missing itemType'); + } elseif ($itemType === 'file' || $itemType === 'folder') { + if ($this->shareManager->allowGroupSharing()) { + $shareTypes[] = Share::SHARE_TYPE_GROUP; + } + + if ($this->isRemoteSharingAllowed($itemType)) { + $shareTypes[] = Share::SHARE_TYPE_REMOTE; + } + + if ($this->isRemoteGroupSharingAllowed($itemType)) { + $shareTypes[] = Share::SHARE_TYPE_REMOTE_GROUP; + } + + if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) { + $shareTypes[] = Share::SHARE_TYPE_EMAIL; + } + + if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_ROOM)) { + $shareTypes[] = Share::SHARE_TYPE_ROOM; + } + } else { + $shareTypes[] = Share::SHARE_TYPE_GROUP; + $shareTypes[] = Share::SHARE_TYPE_EMAIL; + } + + // FIXME: DI + if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) { + $shareTypes[] = Share::SHARE_TYPE_CIRCLE; + } + + if (isset($_GET['shareType']) && is_array($_GET['shareType'])) { + $shareTypes = array_intersect($shareTypes, $_GET['shareType']); + sort($shareTypes); + } else if (is_numeric($shareType)) { + $shareTypes = array_intersect($shareTypes, [(int) $shareType]); + sort($shareTypes); + } + + return new DataResponse( + $this->getAllSharees($this->userId, $shareTypes)->asArray() + ); + } + /** * Method to get out the static call for better testing * diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php index adfb72f550a2b..618a1095407d9 100644 --- a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php @@ -50,6 +50,9 @@ class ShareesAPIControllerTest extends TestCase { /** @var ShareesAPIController */ protected $sharees; + /** @var string */ + protected $uid; + /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */ protected $request; @@ -62,6 +65,7 @@ class ShareesAPIControllerTest extends TestCase { protected function setUp() { parent::setUp(); + $this->uid = 'test123'; $this->request = $this->createMock(IRequest::class); $this->shareManager = $this->createMock(IManager::class); @@ -74,6 +78,7 @@ protected function setUp() { $this->collaboratorSearch = $this->createMock(ISearch::class); $this->sharees = new ShareesAPIController( + $this->uid, 'files_sharing', $this->request, $configMock, @@ -243,6 +248,8 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn ->method('allowGroupSharing') ->willReturn($allowGroupSharing); + /** @var string */ + $uid = 'test123'; /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */ $request = $this->createMock(IRequest::class); /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */ @@ -251,6 +258,7 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController') ->setConstructorArgs([ + $uid, 'files_sharing', $request, $config, @@ -335,6 +343,8 @@ public function testSearchInvalid($getData, $message) { $config->expects($this->never()) ->method('getAppValue'); + /** @var string */ + $uid = 'test123'; /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */ $request = $this->createMock(IRequest::class); /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */ @@ -343,6 +353,7 @@ public function testSearchInvalid($getData, $message) { /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController') ->setConstructorArgs([ + $uid, 'files_sharing', $request, $config, diff --git a/core/js/dist/share_backend.js b/core/js/dist/share_backend.js index d1692ca0078b6..c4b462464f641 100644 --- a/core/js/dist/share_backend.js +++ b/core/js/dist/share_backend.js @@ -20,5 +20,5 @@ * along with this program. If not, see . * */ -!function(){OC.Share||(OC.Share={}),OC.Share.Social={};var e=OC.Backbone.Model.extend({defaults:{key:null,url:null,name:null,iconClass:null,newWindow:!0}});OC.Share.Social.Model=e;var a=OC.Backbone.Collection.extend({model:OC.Share.Social.Model,comparator:"key"});OC.Share.Social.Collection=new a}()},function(e,a){!function(){OC.Share||(OC.Share={});var e=OC.Backbone.View.extend({id:"shareDialogResharerInfo",tagName:"div",className:"reshare",configModel:void 0,_template:void 0,initialize:function(e){var a=this;if(this.model.on("change:reshare",function(){a.render()}),_.isUndefined(e.configModel))throw"missing OC.Share.ShareConfigModel";this.configModel=e.configModel},render:function(){if(!this.model.hasReshare()||this.model.getReshareOwner()===OC.currentUser)return this.$el.empty(),this;var e=this.template(),a=this.model.getReshareOwnerDisplayname(),n=this.model.getReshareNote(),s="";return s=this.model.getReshareType()===OC.Share.SHARE_TYPE_GROUP?t("core","Shared with you and the group {group} by {owner}",{group:this.model.getReshareWithDisplayName(),owner:a},void 0,{escape:!1}):this.model.getReshareType()===OC.Share.SHARE_TYPE_CIRCLE?t("core","Shared with you and {circle} by {owner}",{circle:this.model.getReshareWithDisplayName(),owner:a},void 0,{escape:!1}):this.model.getReshareType()===OC.Share.SHARE_TYPE_ROOM?this.model.get("reshare").share_with_displayname?t("core","Shared with you and the conversation {conversation} by {owner}",{conversation:this.model.getReshareWithDisplayName(),owner:a},void 0,{escape:!1}):t("core","Shared with you in a conversation by {owner}",{owner:a},void 0,{escape:!1}):t("core","Shared with you by {owner}",{owner:a},void 0,{escape:!1}),this.$el.html(e({reshareOwner:this.model.getReshareOwner(),sharedByText:s,shareNote:n,hasShareNote:""!==n})),this.$el.find(".avatar").each(function(){var e=$(this);e.avatar(e.data("username"),32)}),this.$el.find(".reshare").contactsMenu(this.model.getReshareOwner(),OC.Share.SHARE_TYPE_USER,this.$el),this},template:function(){return OC.Share.Templates.sharedialogresharerinfoview}});OC.Share.ShareDialogResharerInfoView=e}()},function(e,a){!function(){OC.Share||(OC.Share={});var e=t("core","Choose a password for the public link"),a=t("core",'Choose a password for the public link or press the "Enter" key'),n=OC.Backbone.View.extend({id:"shareDialogLinkShare",configModel:void 0,showLink:!0,showPending:!1,password:"",newShareId:"new-share",events:{"click .share-menu .icon-more":"onToggleMenu","change .hideDownloadCheckbox":"onHideDownloadChange","click input.share-pass-submit":"onPasswordEntered","keyup input.linkPassText":"onPasswordKeyUp","change .showPasswordCheckbox":"onShowPasswordClick","change .passwordByTalkCheckbox":"onPasswordByTalkChange","change .publicEditingCheckbox":"onAllowPublicEditingChange","click .linkText":"onLinkTextClick","click .pop-up":"onPopUpClick","change .publicUploadRadio":"onPublicUploadChange","click .expireDate":"onExpireDateChange","change .datepicker":"onChangeExpirationDate","click .datepicker":"showDatePicker","click .share-add":"showNoteForm","click .share-note-delete":"deleteNote","click .share-note-submit":"updateNote","click .unshare":"onUnshare","click .new-share":"newShare","submit .enforcedPassForm":"enforcedPasswordSet"},initialize:function(e){var a=this;if(this.model.on("change:permissions",function(){a.render()}),this.model.on("change:itemType",function(){a.render()}),this.model.on("change:allowPublicUploadStatus",function(){a.render()}),this.model.on("change:hideFileListStatus",function(){a.render()}),this.model.on("change:linkShares",function(e,t){var n,s=e.previous("linkShares");if(s.length===t.length)for(n=0;n .icon-loading-small");if(!i.hasClass("hidden")&&""===this.password)return!1;n.find(".icon").addClass("hidden"),i.removeClass("hidden"),OC.hideMenus();var l={},r=this.configModel.get("enforcePasswordForPublicLink");if(this.configModel.get("isDefaultExpireDateEnforced")){var o=this.configModel.get("defaultExpireDate"),d=moment().add(o,"day").format("DD-MM-YYYY");l.expireDate=d}r&&""!==this.password&&(l.password=this.password);var h=!1;r&&!this.showPending&&""===this.password?(this.showPending=s,(a=this.render()).$el.find(".pending #enforcedPassText").focus()):$.when(this.model.saveLinkShare(l,{success:function(){if(i.addClass("hidden"),n.find(".icon").removeClass("hidden"),a.render(),h){var e=a.$el.find("li[data-share-id]"),t=a.$el.find('li[data-share-id="'+h+'"]');if(t&&1===e.length){var s=t.find(".popovermenu");OC.showMenu(null,s)}}},error:function(){}})).fail(function(e){if(a.password="",r&&e&&e.responseJSON&&e.responseJSON.ocs.meta&&e.responseJSON.ocs.meta.message){var s=a.$el.find(".pending #enforcedPassText");s.tooltip("destroy"),s.attr("title",e.responseJSON.ocs.meta.message),s.tooltip({placement:"bottom",trigger:"manual"}),s.tooltip("show")}else OC.Notification.showTemporary(t("core","Unable to create a link share")),i.addClass("hidden"),n.find(".icon").removeClass("hidden")}).then(function(e){h=e.ocs.data.id})},enforcedPasswordSet:function(e){e.preventDefault();var a=$(e.target).find("input.enforcedPassText");this.password=a.val(),this.showPending=!1,this.newShare(e)},onLinkTextClick:function(e){var a=$(e.target).closest("li[data-share-id]").find(".linkText");a.focus(),a.select()},onHideDownloadChange:function(e){var a=$(e.target).closest("li[data-share-id]"),n=a.data("share-id"),s=a.find(".hideDownloadCheckbox");s.siblings(".icon-loading-small").removeClass("hidden").addClass("inlineblock");var i=!1;s.is(":checked")&&(i=!0),this.model.saveLinkShare({hideDownload:i,cid:n},{success:function(){s.siblings(".icon-loading-small").addClass("hidden").removeClass("inlineblock")},error:function(e,a){OC.Notification.showTemporary(t("core","Unable to toggle this option")),s.siblings(".icon-loading-small").addClass("hidden").removeClass("inlineblock")}})},onShowPasswordClick:function(e){var a=$(e.target).closest("li[data-share-id]"),t=a.data("share-id");a.find(".linkPass").slideToggle(OC.menuSpeed),a.find(".linkPassMenu").toggleClass("hidden"),a.find(".showPasswordCheckbox").is(":checked")?OC.Util.isIE()||a.find(".linkPassText").focus():this.model.saveLinkShare({password:"",cid:t})},onPasswordKeyUp:function(e){13===e.keyCode&&this.onPasswordEntered(e)},onPasswordEntered:function(t){var n=$(t.target).closest("li[data-share-id]"),s=n.data("share-id"),i=n.find(".linkPassMenu .icon-loading-small");if(i.hasClass("hidden")){var l=n.find(".linkPassText");l.removeClass("error");var r=l.val();if(n.find(".linkPassText").attr("placeholder")===a)r===a&&(r="");else if(""===r||"**********"===r||r===e)return;i.removeClass("hidden").addClass("inlineblock"),this.model.saveLinkShare({password:r,cid:s},{complete:function(e){i.removeClass("inlineblock").addClass("hidden")},error:function(e,a){var t=l.parent();t.tooltip("destroy"),l.addClass("error"),t.attr("title",a),t.tooltip({placement:"bottom",trigger:"manual"}),t.tooltip("show")}})}},onPasswordByTalkChange:function(e){var a=$(e.target).closest("li[data-share-id]"),n=a.data("share-id"),s=a.find(".passwordByTalkCheckbox");s.siblings(".icon-loading-small").removeClass("hidden").addClass("inlineblock");var i=!1;s.is(":checked")&&(i=!0),this.model.saveLinkShare({sendPasswordByTalk:i,cid:n},{success:function(){s.siblings(".icon-loading-small").addClass("hidden").removeClass("inlineblock")},error:function(e,a){OC.Notification.showTemporary(t("core","Unable to toggle this option")),s.siblings(".icon-loading-small").addClass("hidden").removeClass("inlineblock")}})},onAllowPublicEditingChange:function(e){var a=$(e.target).closest("li[data-share-id]"),n=a.data("share-id"),s=a.find(".publicEditingCheckbox");s.siblings(".icon-loading-small").removeClass("hidden").addClass("inlineblock");var i=OC.PERMISSION_READ;s.is(":checked")&&(i=OC.PERMISSION_UPDATE|OC.PERMISSION_READ),this.model.saveLinkShare({permissions:i,cid:n},{success:function(){s.siblings(".icon-loading-small").addClass("hidden").removeClass("inlineblock")},error:function(e,a){OC.Notification.showTemporary(t("core","Unable to toggle this option")),s.siblings(".icon-loading-small").addClass("hidden").removeClass("inlineblock")}})},onPublicUploadChange:function(e){var a=$(e.target).closest("li[data-share-id]").data("share-id"),t=e.currentTarget.value;this.model.saveLinkShare({permissions:t,cid:a})},showNoteForm:function(e){e.preventDefault(),e.stopPropagation();var a=$(e.target),t=(a.closest("li[data-share-id]"),a.closest("li")),n=t.next("li.share-note-form");t.find(".share-note-delete").toggleClass("hidden"),n.toggleClass("hidden"),n.find("textarea").focus()},deleteNote:function(e){e.preventDefault(),e.stopPropagation();var a=$(e.target),t=a.closest("li[data-share-id]").data("share-id"),n=a.closest("li"),s=n.next("li.share-note-form");s.find(".share-note").val(""),s.addClass("hidden"),n.find(".share-note-delete").addClass("hidden"),this.sendNote("",t,n)},updateNote:function(e){e.preventDefault(),e.stopPropagation();var a=$(e.target),t=a.closest("li[data-share-id]").data("share-id"),n=a.closest("li.share-note-form"),s=n.prev("li"),i=n.find(".share-note").val().trim();i.length<1||this.sendNote(i,t,s)},sendNote:function(e,a,t){var n=t.next("li.share-note-form"),s=n.find("input.share-note-submit"),i=n.find("input.share-note-error");s.prop("disabled",!0),t.find(".icon-loading-small").removeClass("hidden"),t.find(".icon-edit").hide();$.ajax({method:"PUT",url:OC.linkToOCS("apps/files_sharing/api/v1/shares",2)+a+"?"+OC.buildQueryString({format:"json"}),data:{note:e},complete:function(){s.prop("disabled",!1),t.find(".icon-loading-small").addClass("hidden"),t.find(".icon-edit").show()},error:function(){i.show(),setTimeout(function(){i.hide()},3e3)}})},render:function(){this.$el.find(".has-tooltip").tooltip(),this.password="";var n=this.template(),s=this.model.sharePermissionPossible();if(!s||!this.showLink||!this.configModel.isShareWithLinkAllowed()){var i={shareAllowed:!1};return s||(i.noSharingPlaceholder=t("core","Resharing is not allowed")),this.$el.html(n(i)),this}var l=this.model.isFolder()&&this.model.createPermissionPossible()&&this.configModel.isPublicUploadEnabled(),r="";this.model.isPublicEditingAllowed()&&(r='checked="checked"');var o=this.configModel.get("enforcePasswordForPublicLink"),d=(this.configModel.get("enableLinkPasswordByDefault"),this.configModel.get("enforcePasswordForPublicLink")?e:a),h=!this.model.isFolder()&&this.model.updatePermissionPossible(),c=this.configModel.get("isDefaultExpireDateEnforced"),u=new Date;u.setDate(u.getDate()+1),$.datepicker.setDefaults({minDate:u}),this.$el.find(".datepicker").datepicker({dateFormat:"dd-mm-yy"});var p=4;oc_capabilities.password_policy&&oc_capabilities.password_policy.minLength&&(p=oc_capabilities.password_policy.minLength);var m={urlLabel:t("core","Link"),hideDownloadLabel:t("core","Hide download"),enablePasswordLabel:o?t("core","Password protection enforced"):t("core","Password protect"),passwordLabel:t("core","Password"),passwordPlaceholderInitial:d,publicUpload:l,publicEditing:h,publicEditingChecked:r,publicEditingLabel:t("core","Allow editing"),mailPrivatePlaceholder:t("core","Email link to person"),mailButtonText:t("core","Send"),publicUploadRWLabel:t("core","Allow upload and editing"),publicUploadRLabel:t("core","Read only"),publicUploadWLabel:t("core","File drop (upload only)"),publicUploadRWValue:OC.PERMISSION_UPDATE|OC.PERMISSION_CREATE|OC.PERMISSION_READ|OC.PERMISSION_DELETE,publicUploadRValue:OC.PERMISSION_READ,publicUploadWValue:OC.PERMISSION_CREATE,expireDateLabel:c?t("core","Expiration date enforced"):t("core","Set expiration date"),expirationLabel:t("core","Expiration"),expirationDatePlaceholder:t("core","Expiration date"),isExpirationEnforced:c,isPasswordEnforced:o,defaultExpireDate:moment().add(1,"day").format("DD-MM-YYYY"),addNoteLabel:t("core","Note to recipient"),unshareLabel:t("core","Unshare"),unshareLinkLabel:t("core","Delete share link"),newShareLabel:t("core","Add another link")},f={isPasswordEnforced:o,enforcedPasswordLabel:t("core","Password protection for links is mandatory"),passwordPlaceholder:d,minPasswordLength:p},g=this.pendingPopoverMenuTemplate(_.extend({},f)),v=this.getShareeList();if(_.isArray(v))for(var S=0;S li").each(function(){var e=$(this),a=e.data("share-with"),t=e.data("share-type");e.find("div.avatar, span.username").contactsMenu(a,t,e)});var n=this;if(this.getShareeList().forEach(function(e){var a=n.$("#canEdit-"+n.cid+"-"+e.shareId);1===a.length&&(a.prop("checked","checked"===e.editPermissionState),e.isFolder&&a.prop("indeterminate","indeterminate"===e.editPermissionState))}),this.$(".popovermenu").on("afterHide",function(){n._menuOpen=!1}),this.$(".popovermenu").on("beforeHide",function(){var e=parseInt(n._menuOpen,10);if(!_.isNaN(e)){var a=".expirationDateContainer-"+n.cid+"-"+e,t="#expirationDatePicker-"+n.cid+"-"+e,s="#expireDate-"+n.cid+"-"+e;$(s).prop("checked")&&($(t).removeClass("hidden-visually"),$(a).removeClass("hasDatepicker"),$(a+" .ui-datepicker").hide())}}),!1!==this._menuOpen){var s=parseInt(this._menuOpen,10);if(!_.isNaN(s)){var i="li[data-share-id="+s+"]";OC.showMenu(null,this.$(i+" .sharingOptionsGroup .popovermenu"))}}return this._renderPermissionChange=!1,autosize(this.$el.find(".share-note-form .share-note")),this.delegateEvents(),this},template:function(e){var a=e.sharees;if(_.isArray(a))for(var t=0;t0)}}else"edit"===a.attr("name")&&a.is(":checked")&&(i|=OC.PERMISSION_UPDATE);$(".permissions",n).not('input[name="edit"]').filter(":checked").each(function(e,a){i|=$(a).data("permissions")}),n.find("input[type=checkbox]").prop("disabled",!0);var h=function(){n.find("input[type=checkbox]").prop("disabled",!1)};this.model.updateShare(s,{permissions:i},{error:function(e,a){OC.dialogs.alert(a,t("core","Error while sharing")),h()},success:h}),this._renderPermissionChange=s},onSecureDropChange:function(e){e.preventDefault(),e.stopPropagation();var a=$(e.target),n=a.closest("li[data-share-id]"),s=n.data("share-id"),i=OC.PERMISSION_CREATE|OC.PERMISSION_UPDATE|OC.PERMISSION_DELETE|OC.PERMISSION_READ;a.is(":checked")&&(i=OC.PERMISSION_CREATE|OC.PERMISSION_UPDATE|OC.PERMISSION_DELETE),n.find("input[type=checkbox]").prop("disabled",!0);var l=function(){n.find("input[type=checkbox]").prop("disabled",!1)};this.model.updateShare(s,{permissions:i},{error:function(e,a){OC.dialogs.alert(a,t("core","Error while sharing")),l()},success:l}),this._renderPermissionChange=s}});OC.Share.ShareDialogShareeListView=a}()},function(e,a){!function(){OC.Share||(OC.Share={});var e=OC.Backbone.View.extend({_templates:{},_showLink:!0,tagName:"div",configModel:void 0,resharerInfoView:void 0,linkShareView:void 0,shareeListView:void 0,_lastSuggestions:void 0,_pendingOperationsCount:0,events:{"focus .shareWithField":"onShareWithFieldFocus","input .shareWithField":"onShareWithFieldChanged","click .shareWithConfirm":"_confirmShare"},initialize:function(e){var a=this;if(this.model.on("fetchError",function(){OC.Notification.showTemporary(t("core","Share details could not be loaded for this item."))}),_.isUndefined(e.configModel))throw"missing OC.Share.ShareConfigModel";this.configModel=e.configModel,this.configModel.on("change:isRemoteShareAllowed",function(){a.render()}),this.configModel.on("change:isRemoteGroupShareAllowed",function(){a.render()}),this.model.on("change:permissions",function(){a.render()}),this.model.on("request",this._onRequest,this),this.model.on("sync",this._onEndRequest,this);var n={model:this.model,configModel:this.configModel},s={resharerInfoView:"ShareDialogResharerInfoView",linkShareView:"ShareDialogLinkShareView",shareeListView:"ShareDialogShareeListView"};for(var i in s){var l=s[i];this[i]=_.isUndefined(e[i])?new OC.Share[l](n):e[i]}_.bindAll(this,"autocompleteHandler","_onSelectRecipient","onShareWithFieldChanged","onShareWithFieldFocus"),OC.Plugins.attach("OC.Share.ShareDialogView",this)},onShareWithFieldChanged:function(){var e=this.$el.find(".shareWithField");e.val().length<2&&e.removeClass("error").tooltip("hide")},onShareWithFieldFocus:function(){this.$el.find(".shareWithField").autocomplete("search")},_getSuggestions:function(e,a,t){if(this._lastSuggestions&&this._lastSuggestions.searchTerm===e&&this._lastSuggestions.perPage===a&&this._lastSuggestions.model===t)return this._lastSuggestions.promise;var n=$.Deferred();return $.get(OC.linkToOCS("apps/files_sharing/api/v1")+"sharees",{format:"json",search:e,perPage:a,itemType:t.get("itemType")},function(s){if(100===s.ocs.meta.statuscode){var i=function(e,a,n,s,i,l,r){var o,d,h,c,u,p,m,f,g;for(void 0===i&&(i=[]),void 0===l&&(l=[]),void 0===r&&(r=[]),o=e.length,f=0;fn?1:0})),E=null,_=P.length,k=(s=[],0);k<_;k++)void 0!==P[k].uuid&&P[k].uuid===E&&(P[k].merged=!0),e!==P[k].name&&void 0!==P[k].merged||s.push(P[k]),E=P[k].uuid;var O=oc_config["sharing.maxAutocompleteResults"]>0&&Math.min(a,oc_config["sharing.maxAutocompleteResults"])<=Math.max(m.length+l.length,f.length+r.length,v.length+d.length,g.length+o.length,C.length+h.length,w.length+c.length,b.length+u.length,S.length);n.resolve(s,p,O)}else n.reject(s.ocs.meta.message);var x}).fail(function(){n.reject()}),this._lastSuggestions={searchTerm:e,perPage:a,model:t,promise:n.promise()},this._lastSuggestions.promise},autocompleteHandler:function(e,a){var s=$(".shareWithField"),i=this,l=this.$el.find(".shareWithLoading"),r=this.$el.find(".shareWithConfirm"),o=oc_config["sharing.minSearchStringLength"];if(e.term.trim().length0){if(s.autocomplete("option","autoFocus",!0),a(e),o){var d=t("core","This list is maybe truncated - please refine your search term to see more results.");$(".ui-autocomplete").append('
  • '+d+"
  • ")}}else{var h=t("core","No users or groups found for {search}",{search:s.val()});i.configModel.get("allowGroupSharing")||(h=t("core","No users found for {search}",{search:$(".shareWithField").val()})),s.addClass("error").attr("data-original-title",h).tooltip("hide").tooltip({placement:"bottom",trigger:"manual"}).tooltip("fixTitle").tooltip("show"),a()}}).fail(function(e){i._pendingOperationsCount--,0===i._pendingOperationsCount&&(l.addClass("hidden"),l.removeClass("inlineblock"),r.removeClass("hidden")),e?OC.Notification.showTemporary(t("core",'An error occurred ("{message}"). Please try again',{message:e})):OC.Notification.showTemporary(t("core","An error occurred. Please try again"))})},autocompleteRenderItem:function(e,a){var n="icon-user",s=escapeHTML(a.label),i="",l="";void 0!==a.type&&null!==a.type&&(l=function(e){switch(e){case"HOME":return t("core","Home");case"WORK":return t("core","Work");case"OTHER":return t("core","Other");default:return""+e}}(a.type)+" "),void 0!==a.name&&(s=escapeHTML(a.name)),a.value.shareType===OC.Share.SHARE_TYPE_GROUP?n="icon-contacts-dark":a.value.shareType===OC.Share.SHARE_TYPE_REMOTE?(n="icon-shared",i+=a.value.shareWith):a.value.shareType===OC.Share.SHARE_TYPE_REMOTE_GROUP?(s=t("core","{sharee} (remote group)",{sharee:s},void 0,{escape:!1}),n="icon-shared",i+=a.value.shareWith):a.value.shareType===OC.Share.SHARE_TYPE_EMAIL?(n="icon-mail",i+=a.value.shareWith):a.value.shareType===OC.Share.SHARE_TYPE_CIRCLE?(s=t("core","{sharee} ({type}, {owner})",{sharee:s,type:a.value.circleInfo,owner:a.value.circleOwner},void 0,{escape:!1}),n="icon-circle"):a.value.shareType===OC.Share.SHARE_TYPE_ROOM&&(n="icon-talk");var r=$("