2015-07-31 01:07:41 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2015
|
|
|
|
*
|
|
|
|
* This file is licensed under the Affero General Public License version 3
|
|
|
|
* or later.
|
|
|
|
*
|
|
|
|
* See the COPYING-README file.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-08-19 22:03:25 +03:00
|
|
|
/* globals Handlebars */
|
|
|
|
|
2015-07-31 01:07:41 +03:00
|
|
|
(function() {
|
|
|
|
if(!OC.Share) {
|
|
|
|
OC.Share = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class OCA.Share.ShareDialogView
|
2015-08-08 01:23:06 +03:00
|
|
|
* @member {OC.Share.ShareItemModel} model
|
|
|
|
* @member {jQuery} $el
|
|
|
|
* @memberof OCA.Sharing
|
2015-07-31 01:07:41 +03:00
|
|
|
* @classdesc
|
|
|
|
*
|
|
|
|
* Represents the GUI of the share dialogue
|
|
|
|
*
|
|
|
|
*/
|
2015-08-08 01:23:06 +03:00
|
|
|
var ShareDialogView = OC.Backbone.View.extend({
|
|
|
|
/** @type {Object} **/
|
2015-07-31 01:07:41 +03:00
|
|
|
_templates: {},
|
|
|
|
|
2015-08-08 01:23:06 +03:00
|
|
|
/** @type {boolean} **/
|
2015-07-31 01:07:41 +03:00
|
|
|
_showLink: true,
|
|
|
|
|
2019-02-21 23:36:14 +03:00
|
|
|
_lookup: false,
|
|
|
|
|
|
|
|
_lookupAllowed: false,
|
|
|
|
|
2015-08-08 01:23:06 +03:00
|
|
|
/** @type {string} **/
|
|
|
|
tagName: 'div',
|
|
|
|
|
2015-08-13 03:38:14 +03:00
|
|
|
/** @type {OC.Share.ShareConfigModel} **/
|
|
|
|
configModel: undefined,
|
|
|
|
|
2015-08-19 01:04:16 +03:00
|
|
|
/** @type {object} **/
|
|
|
|
resharerInfoView: undefined,
|
|
|
|
|
2015-08-21 16:40:50 +03:00
|
|
|
/** @type {object} **/
|
|
|
|
linkShareView: undefined,
|
|
|
|
|
2015-09-01 13:43:04 +03:00
|
|
|
/** @type {object} **/
|
|
|
|
shareeListView: undefined,
|
|
|
|
|
2018-03-20 15:14:26 +03:00
|
|
|
/** @type {object} **/
|
|
|
|
_lastSuggestions: undefined,
|
|
|
|
|
2019-02-13 19:16:01 +03:00
|
|
|
/** @type {object} **/
|
|
|
|
_lastRecommendations: undefined,
|
|
|
|
|
2018-03-20 18:58:04 +03:00
|
|
|
/** @type {int} **/
|
|
|
|
_pendingOperationsCount: 0,
|
|
|
|
|
2016-02-12 12:25:42 +03:00
|
|
|
events: {
|
2017-08-15 14:36:51 +03:00
|
|
|
'focus .shareWithField': 'onShareWithFieldFocus',
|
2018-03-19 20:54:27 +03:00
|
|
|
'input .shareWithField': 'onShareWithFieldChanged',
|
|
|
|
'click .shareWithConfirm': '_confirmShare'
|
2016-02-12 12:25:42 +03:00
|
|
|
},
|
|
|
|
|
2015-08-13 03:38:14 +03:00
|
|
|
initialize: function(options) {
|
2015-08-11 23:36:28 +03:00
|
|
|
var view = this;
|
|
|
|
|
|
|
|
this.model.on('fetchError', function() {
|
|
|
|
OC.Notification.showTemporary(t('core', 'Share details could not be loaded for this item.'));
|
|
|
|
});
|
2015-08-13 03:38:14 +03:00
|
|
|
|
|
|
|
if(!_.isUndefined(options.configModel)) {
|
|
|
|
this.configModel = options.configModel;
|
|
|
|
} else {
|
2015-08-25 00:20:01 +03:00
|
|
|
throw 'missing OC.Share.ShareConfigModel';
|
2015-08-13 03:38:14 +03:00
|
|
|
}
|
2015-08-19 01:04:16 +03:00
|
|
|
|
2015-09-12 15:21:14 +03:00
|
|
|
this.configModel.on('change:isRemoteShareAllowed', function() {
|
|
|
|
view.render();
|
|
|
|
});
|
2018-07-02 12:29:03 +03:00
|
|
|
this.configModel.on('change:isRemoteGroupShareAllowed', function() {
|
|
|
|
view.render();
|
|
|
|
});
|
2015-09-15 16:29:30 +03:00
|
|
|
this.model.on('change:permissions', function() {
|
|
|
|
view.render();
|
|
|
|
});
|
2015-09-12 15:21:14 +03:00
|
|
|
|
2015-09-28 16:57:57 +03:00
|
|
|
this.model.on('request', this._onRequest, this);
|
|
|
|
this.model.on('sync', this._onEndRequest, this);
|
|
|
|
|
2015-08-19 01:04:16 +03:00
|
|
|
var subViewOptions = {
|
|
|
|
model: this.model,
|
|
|
|
configModel: this.configModel
|
|
|
|
};
|
|
|
|
|
2015-08-21 21:05:50 +03:00
|
|
|
var subViews = {
|
|
|
|
resharerInfoView: 'ShareDialogResharerInfoView',
|
|
|
|
linkShareView: 'ShareDialogLinkShareView',
|
2016-11-02 13:37:25 +03:00
|
|
|
shareeListView: 'ShareDialogShareeListView'
|
2015-08-21 21:05:50 +03:00
|
|
|
};
|
2015-08-21 20:35:13 +03:00
|
|
|
|
2015-08-21 21:05:50 +03:00
|
|
|
for(var name in subViews) {
|
|
|
|
var className = subViews[name];
|
|
|
|
this[name] = _.isUndefined(options[name])
|
|
|
|
? new OC.Share[className](subViewOptions)
|
|
|
|
: options[name];
|
|
|
|
}
|
2015-09-05 03:02:55 +03:00
|
|
|
|
2016-02-12 12:25:42 +03:00
|
|
|
_.bindAll(this,
|
|
|
|
'autocompleteHandler',
|
|
|
|
'_onSelectRecipient',
|
2017-08-15 14:36:51 +03:00
|
|
|
'onShareWithFieldChanged',
|
|
|
|
'onShareWithFieldFocus'
|
2016-02-12 12:25:42 +03:00
|
|
|
);
|
2017-02-24 17:45:47 +03:00
|
|
|
|
2017-04-28 10:48:33 +03:00
|
|
|
OC.Plugins.attach('OC.Share.ShareDialogView', this);
|
2016-02-12 12:25:42 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
onShareWithFieldChanged: function() {
|
|
|
|
var $el = this.$el.find('.shareWithField');
|
|
|
|
if ($el.val().length < 2) {
|
|
|
|
$el.removeClass('error').tooltip('hide');
|
|
|
|
}
|
2015-09-05 03:02:55 +03:00
|
|
|
},
|
|
|
|
|
2017-08-15 14:36:51 +03:00
|
|
|
/* trigger search after the field was re-selected */
|
|
|
|
onShareWithFieldFocus: function() {
|
2019-02-21 23:36:14 +03:00
|
|
|
var $shareWithField = this.$el.find('.shareWithField');
|
|
|
|
$shareWithField.autocomplete("search", $shareWithField.val());
|
2017-08-15 14:36:51 +03:00
|
|
|
},
|
|
|
|
|
2019-02-21 23:36:14 +03:00
|
|
|
_getSuggestions: function(searchTerm, perPage, model, lookup) {
|
2018-03-20 15:14:26 +03:00
|
|
|
if (this._lastSuggestions &&
|
|
|
|
this._lastSuggestions.searchTerm === searchTerm &&
|
2019-02-21 23:36:14 +03:00
|
|
|
this._lastSuggestions.lookup === lookup &&
|
2018-03-20 15:14:26 +03:00
|
|
|
this._lastSuggestions.perPage === perPage &&
|
|
|
|
this._lastSuggestions.model === model) {
|
|
|
|
return this._lastSuggestions.promise;
|
|
|
|
}
|
|
|
|
|
2018-03-16 19:19:47 +03:00
|
|
|
var deferred = $.Deferred();
|
2019-02-21 23:36:14 +03:00
|
|
|
var view = this;
|
2017-02-22 02:07:07 +03:00
|
|
|
|
2015-12-23 12:16:57 +03:00
|
|
|
$.get(
|
|
|
|
OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
|
|
|
|
{
|
|
|
|
format: 'json',
|
2018-03-16 19:19:47 +03:00
|
|
|
search: searchTerm,
|
2019-02-21 23:36:14 +03:00
|
|
|
lookup: lookup,
|
2017-02-22 02:07:07 +03:00
|
|
|
perPage: perPage,
|
2018-03-16 19:19:47 +03:00
|
|
|
itemType: model.get('itemType')
|
2015-12-23 12:16:57 +03:00
|
|
|
},
|
|
|
|
function (result) {
|
2016-08-19 22:03:25 +03:00
|
|
|
if (result.ocs.meta.statuscode === 100) {
|
2018-07-16 04:51:45 +03:00
|
|
|
var filter = function(users, groups, remotes, remote_groups, emails, circles, rooms) {
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
if (typeof(emails) === 'undefined') {
|
|
|
|
emails = [];
|
|
|
|
}
|
|
|
|
if (typeof(circles) === 'undefined') {
|
|
|
|
circles = [];
|
|
|
|
}
|
2018-07-16 04:51:45 +03:00
|
|
|
if (typeof(rooms) === 'undefined') {
|
|
|
|
rooms = [];
|
|
|
|
}
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
|
2018-03-19 18:57:16 +03:00
|
|
|
var usersLength;
|
|
|
|
var groupsLength;
|
|
|
|
var remotesLength;
|
2018-07-02 12:29:03 +03:00
|
|
|
var remoteGroupsLength;
|
2018-03-19 18:57:16 +03:00
|
|
|
var emailsLength;
|
|
|
|
var circlesLength;
|
2018-07-16 04:51:45 +03:00
|
|
|
var roomsLength;
|
2018-03-19 18:57:16 +03:00
|
|
|
|
|
|
|
var i, j;
|
2015-12-23 12:16:57 +03:00
|
|
|
|
2018-03-19 18:57:16 +03:00
|
|
|
//Filter out the current user
|
2015-12-23 12:38:53 +03:00
|
|
|
usersLength = users.length;
|
2018-03-19 18:57:16 +03:00
|
|
|
for (i = 0; i < usersLength; i++) {
|
|
|
|
if (users[i].value.shareWith === OC.currentUser) {
|
2015-12-23 12:38:53 +03:00
|
|
|
users.splice(i, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-12-23 12:16:57 +03:00
|
|
|
|
2018-03-19 18:57:16 +03:00
|
|
|
// Filter out the owner of the share
|
|
|
|
if (model.hasReshare()) {
|
2015-12-23 12:16:57 +03:00
|
|
|
usersLength = users.length;
|
2018-03-19 18:57:16 +03:00
|
|
|
for (i = 0 ; i < usersLength; i++) {
|
|
|
|
if (users[i].value.shareWith === model.getReshareOwner()) {
|
|
|
|
users.splice(i, 1);
|
2015-12-23 12:16:57 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-03-19 18:57:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
var shares = model.get('shares');
|
|
|
|
var sharesLength = shares.length;
|
|
|
|
|
|
|
|
// Now filter out all sharees that are already shared with
|
|
|
|
for (i = 0; i < sharesLength; i++) {
|
|
|
|
var share = shares[i];
|
|
|
|
|
|
|
|
if (share.share_type === OC.Share.SHARE_TYPE_USER) {
|
|
|
|
usersLength = users.length;
|
|
|
|
for (j = 0; j < usersLength; j++) {
|
|
|
|
if (users[j].value.shareWith === share.share_with) {
|
|
|
|
users.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
2015-12-23 12:16:57 +03:00
|
|
|
}
|
2018-03-19 18:57:16 +03:00
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) {
|
|
|
|
groupsLength = groups.length;
|
|
|
|
for (j = 0; j < groupsLength; j++) {
|
|
|
|
if (groups[j].value.shareWith === share.share_with) {
|
|
|
|
groups.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
2015-12-23 12:16:57 +03:00
|
|
|
}
|
2018-03-19 18:57:16 +03:00
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) {
|
|
|
|
remotesLength = remotes.length;
|
|
|
|
for (j = 0; j < remotesLength; j++) {
|
|
|
|
if (remotes[j].value.shareWith === share.share_with) {
|
|
|
|
remotes.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
2016-07-29 16:38:31 +03:00
|
|
|
}
|
2018-07-02 12:29:03 +03:00
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE_GROUP) {
|
|
|
|
remoteGroupsLength = remote_groups.length;
|
|
|
|
for (j = 0; j < remoteGroupsLength; j++) {
|
|
|
|
if (remote_groups[j].value.shareWith === share.share_with) {
|
|
|
|
remote_groups.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-03-19 18:57:16 +03:00
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) {
|
|
|
|
emailsLength = emails.length;
|
|
|
|
for (j = 0; j < emailsLength; j++) {
|
|
|
|
if (emails[j].value.shareWith === share.share_with) {
|
|
|
|
emails.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_CIRCLE) {
|
|
|
|
circlesLength = circles.length;
|
|
|
|
for (j = 0; j < circlesLength; j++) {
|
|
|
|
if (circles[j].value.shareWith === share.share_with) {
|
|
|
|
circles.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
2017-03-17 22:48:33 +03:00
|
|
|
}
|
2018-07-16 04:51:45 +03:00
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_ROOM) {
|
|
|
|
roomsLength = rooms.length;
|
|
|
|
for (j = 0; j < roomsLength; j++) {
|
|
|
|
if (rooms[j].value.shareWith === share.share_with) {
|
|
|
|
rooms.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-03-17 22:48:33 +03:00
|
|
|
}
|
2015-12-23 12:16:57 +03:00
|
|
|
}
|
2018-03-19 18:57:16 +03:00
|
|
|
};
|
|
|
|
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
filter(
|
|
|
|
result.ocs.data.exact.users,
|
|
|
|
result.ocs.data.exact.groups,
|
|
|
|
result.ocs.data.exact.remotes,
|
2018-07-02 12:29:03 +03:00
|
|
|
result.ocs.data.exact.remote_groups,
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
result.ocs.data.exact.emails,
|
2018-07-16 04:51:45 +03:00
|
|
|
result.ocs.data.exact.circles,
|
|
|
|
result.ocs.data.exact.rooms
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
var exactUsers = result.ocs.data.exact.users;
|
|
|
|
var exactGroups = result.ocs.data.exact.groups;
|
|
|
|
var exactRemotes = result.ocs.data.exact.remotes;
|
2018-07-02 12:29:03 +03:00
|
|
|
var exactRemoteGroups = result.ocs.data.exact.remote_groups;
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
var exactEmails = [];
|
|
|
|
if (typeof(result.ocs.data.emails) !== 'undefined') {
|
|
|
|
exactEmails = result.ocs.data.exact.emails;
|
|
|
|
}
|
|
|
|
var exactCircles = [];
|
|
|
|
if (typeof(result.ocs.data.circles) !== 'undefined') {
|
|
|
|
exactCircles = result.ocs.data.exact.circles;
|
|
|
|
}
|
2018-07-16 04:51:45 +03:00
|
|
|
var exactRooms = [];
|
|
|
|
if (typeof(result.ocs.data.rooms) !== 'undefined') {
|
|
|
|
exactRooms = result.ocs.data.exact.rooms;
|
|
|
|
}
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
|
2018-07-16 04:51:45 +03:00
|
|
|
var exactMatches = exactUsers.concat(exactGroups).concat(exactRemotes).concat(exactRemoteGroups).concat(exactEmails).concat(exactCircles).concat(exactRooms);
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
|
|
|
|
filter(
|
|
|
|
result.ocs.data.users,
|
|
|
|
result.ocs.data.groups,
|
|
|
|
result.ocs.data.remotes,
|
2018-07-02 12:29:03 +03:00
|
|
|
result.ocs.data.remote_groups,
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
result.ocs.data.emails,
|
2018-07-16 04:51:45 +03:00
|
|
|
result.ocs.data.circles,
|
|
|
|
result.ocs.data.rooms
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
var users = result.ocs.data.users;
|
|
|
|
var groups = result.ocs.data.groups;
|
|
|
|
var remotes = result.ocs.data.remotes;
|
2018-07-02 12:29:03 +03:00
|
|
|
var remoteGroups = result.ocs.data.remote_groups;
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
var lookup = result.ocs.data.lookup;
|
2019-02-21 23:36:14 +03:00
|
|
|
var lookupEnabled = result.ocs.data.lookupEnabled;
|
Return also exact matches besides all suggestions
"_getSuggestions" returned all the suggestions from the server, which
are composed by exact matches and partial matches. Now the exact matches
are also returned on their own parameter. This will be used by the
button to confirm a share.
Note that until now the order of the suggestions was "exact users,
partial users, exact groups, partial groups, exact..."; this commit also
changes that order to become "exact users, exact groups, exact...,
partial users, partial groups, partial...". This is not a problem, as
the suggestions were used in the autocomplete dropdown, and this new
order is arguably better than the old one, as all exact matches appear
now at the beginning.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2018-03-19 19:16:11 +03:00
|
|
|
var emails = [];
|
|
|
|
if (typeof(result.ocs.data.emails) !== 'undefined') {
|
|
|
|
emails = result.ocs.data.emails;
|
|
|
|
}
|
|
|
|
var circles = [];
|
|
|
|
if (typeof(result.ocs.data.circles) !== 'undefined') {
|
|
|
|
circles = result.ocs.data.circles;
|
|
|
|
}
|
2018-07-16 04:51:45 +03:00
|
|
|
var rooms = [];
|
|
|
|
if (typeof(result.ocs.data.rooms) !== 'undefined') {
|
|
|
|
rooms = result.ocs.data.rooms;
|
|
|
|
}
|
2015-12-23 12:16:57 +03:00
|
|
|
|
2018-07-16 04:51:45 +03:00
|
|
|
var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(remoteGroups).concat(emails).concat(circles).concat(rooms).concat(lookup);
|
2015-12-23 12:16:57 +03:00
|
|
|
|
2018-10-17 22:57:47 +03:00
|
|
|
function dynamicSort(property) {
|
|
|
|
return function (a,b) {
|
2018-10-18 13:36:37 +03:00
|
|
|
var aProperty = '';
|
|
|
|
var bProperty = '';
|
|
|
|
if (typeof a[property] !== 'undefined') {
|
|
|
|
aProperty = a[property];
|
|
|
|
}
|
|
|
|
if (typeof b[property] !== 'undefined') {
|
|
|
|
bProperty = b[property];
|
|
|
|
}
|
|
|
|
return (aProperty < bProperty) ? -1 : (aProperty > bProperty) ? 1 : 0;
|
2018-10-17 22:57:47 +03:00
|
|
|
}
|
|
|
|
}
|
2018-10-26 14:46:24 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sort share entries by uuid to properly group them
|
|
|
|
*/
|
2018-10-17 22:57:47 +03:00
|
|
|
var grouped = suggestions.sort(dynamicSort('uuid'));
|
2018-10-26 14:46:24 +03:00
|
|
|
|
2018-10-18 13:36:37 +03:00
|
|
|
var previousUuid = null;
|
2018-10-26 14:46:24 +03:00
|
|
|
var groupedLength = grouped.length;
|
|
|
|
var result = [];
|
|
|
|
/**
|
|
|
|
* build the result array that only contains all contact entries from
|
|
|
|
* merged contacts, if the search term matches its contact name
|
|
|
|
*/
|
2019-01-19 01:53:10 +03:00
|
|
|
for (var i = 0; i < groupedLength; i++) {
|
2018-10-18 13:36:37 +03:00
|
|
|
if (typeof grouped[i].uuid !== 'undefined' && grouped[i].uuid === previousUuid) {
|
|
|
|
grouped[i].merged = true;
|
|
|
|
}
|
2018-10-30 13:37:11 +03:00
|
|
|
if (searchTerm === grouped[i].name || typeof grouped[i].merged === 'undefined') {
|
2018-10-26 14:46:24 +03:00
|
|
|
result.push(grouped[i]);
|
|
|
|
}
|
2018-10-18 13:36:37 +03:00
|
|
|
previousUuid = grouped[i].uuid;
|
|
|
|
}
|
2018-09-03 18:18:00 +03:00
|
|
|
var moreResultsAvailable =
|
|
|
|
(
|
|
|
|
oc_config['sharing.maxAutocompleteResults'] > 0
|
|
|
|
&& Math.min(perPage, oc_config['sharing.maxAutocompleteResults'])
|
|
|
|
<= Math.max(
|
|
|
|
users.length + exactUsers.length,
|
|
|
|
groups.length + exactGroups.length,
|
|
|
|
remoteGroups.length + exactRemoteGroups.length,
|
|
|
|
remotes.length + exactRemotes.length,
|
|
|
|
emails.length + exactEmails.length,
|
|
|
|
circles.length + exactCircles.length,
|
|
|
|
rooms.length + exactRooms.length,
|
|
|
|
lookup.length
|
|
|
|
)
|
|
|
|
);
|
2019-02-21 23:36:14 +03:00
|
|
|
if (!view._lookup && lookupEnabled) {
|
|
|
|
result.push(
|
|
|
|
{
|
|
|
|
label: t('core', 'Search globally'),
|
|
|
|
value: {},
|
|
|
|
lookup: true
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
2018-09-03 18:18:00 +03:00
|
|
|
|
2019-02-21 23:36:14 +03:00
|
|
|
deferred.resolve(result, exactMatches, moreResultsAvailable, lookupEnabled);
|
2018-03-16 19:19:47 +03:00
|
|
|
} else {
|
2018-03-19 17:36:08 +03:00
|
|
|
deferred.reject(result.ocs.meta.message);
|
2018-03-16 19:19:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
).fail(function() {
|
|
|
|
deferred.reject();
|
|
|
|
});
|
2017-02-22 02:07:07 +03:00
|
|
|
|
2018-03-20 15:14:26 +03:00
|
|
|
this._lastSuggestions = {
|
|
|
|
searchTerm: searchTerm,
|
2019-02-21 23:36:14 +03:00
|
|
|
lookup: lookup,
|
2018-03-20 15:14:26 +03:00
|
|
|
perPage: perPage,
|
|
|
|
model: model,
|
|
|
|
promise: deferred.promise()
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._lastSuggestions.promise;
|
2018-03-16 19:19:47 +03:00
|
|
|
},
|
2017-02-22 02:07:07 +03:00
|
|
|
|
2019-02-13 19:16:01 +03:00
|
|
|
_getRecommendations: function(model) {
|
|
|
|
if (this._lastRecommendations &&
|
|
|
|
this._lastRecommendations.model === model) {
|
|
|
|
return this._lastRecommendations.promise;
|
|
|
|
}
|
|
|
|
|
|
|
|
var deferred = $.Deferred();
|
|
|
|
|
|
|
|
$.get(
|
|
|
|
OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees_recommended',
|
|
|
|
{
|
|
|
|
format: 'json',
|
|
|
|
itemType: model.get('itemType')
|
|
|
|
},
|
|
|
|
function (result) {
|
|
|
|
if (result.ocs.meta.statuscode === 100) {
|
|
|
|
var filter = function(users, groups, remotes, remote_groups, emails, circles, rooms) {
|
|
|
|
if (typeof(emails) === 'undefined') {
|
|
|
|
emails = [];
|
|
|
|
}
|
|
|
|
if (typeof(circles) === 'undefined') {
|
|
|
|
circles = [];
|
|
|
|
}
|
|
|
|
if (typeof(rooms) === 'undefined') {
|
|
|
|
rooms = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
var usersLength;
|
|
|
|
var groupsLength;
|
|
|
|
var remotesLength;
|
|
|
|
var remoteGroupsLength;
|
|
|
|
var emailsLength;
|
|
|
|
var circlesLength;
|
|
|
|
var roomsLength;
|
|
|
|
|
|
|
|
var i, j;
|
|
|
|
|
|
|
|
//Filter out the current user
|
|
|
|
usersLength = users.length;
|
|
|
|
for (i = 0; i < usersLength; i++) {
|
|
|
|
if (users[i].value.shareWith === OC.currentUser) {
|
|
|
|
users.splice(i, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Filter out the owner of the share
|
|
|
|
if (model.hasReshare()) {
|
|
|
|
usersLength = users.length;
|
|
|
|
for (i = 0 ; i < usersLength; i++) {
|
|
|
|
if (users[i].value.shareWith === model.getReshareOwner()) {
|
|
|
|
users.splice(i, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var shares = model.get('shares');
|
|
|
|
var sharesLength = shares.length;
|
|
|
|
|
|
|
|
// Now filter out all sharees that are already shared with
|
|
|
|
for (i = 0; i < sharesLength; i++) {
|
|
|
|
var share = shares[i];
|
|
|
|
|
|
|
|
if (share.share_type === OC.Share.SHARE_TYPE_USER) {
|
|
|
|
usersLength = users.length;
|
|
|
|
for (j = 0; j < usersLength; j++) {
|
|
|
|
if (users[j].value.shareWith === share.share_with) {
|
|
|
|
users.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) {
|
|
|
|
groupsLength = groups.length;
|
|
|
|
for (j = 0; j < groupsLength; j++) {
|
|
|
|
if (groups[j].value.shareWith === share.share_with) {
|
|
|
|
groups.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) {
|
|
|
|
remotesLength = remotes.length;
|
|
|
|
for (j = 0; j < remotesLength; j++) {
|
|
|
|
if (remotes[j].value.shareWith === share.share_with) {
|
|
|
|
remotes.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE_GROUP) {
|
|
|
|
remoteGroupsLength = remote_groups.length;
|
|
|
|
for (j = 0; j < remoteGroupsLength; j++) {
|
|
|
|
if (remote_groups[j].value.shareWith === share.share_with) {
|
|
|
|
remote_groups.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) {
|
|
|
|
emailsLength = emails.length;
|
|
|
|
for (j = 0; j < emailsLength; j++) {
|
|
|
|
if (emails[j].value.shareWith === share.share_with) {
|
|
|
|
emails.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_CIRCLE) {
|
|
|
|
circlesLength = circles.length;
|
|
|
|
for (j = 0; j < circlesLength; j++) {
|
|
|
|
if (circles[j].value.shareWith === share.share_with) {
|
|
|
|
circles.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (share.share_type === OC.Share.SHARE_TYPE_ROOM) {
|
|
|
|
roomsLength = rooms.length;
|
|
|
|
for (j = 0; j < roomsLength; j++) {
|
|
|
|
if (rooms[j].value.shareWith === share.share_with) {
|
|
|
|
rooms.splice(j, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
filter(
|
|
|
|
result.ocs.data.exact.users,
|
|
|
|
result.ocs.data.exact.groups,
|
|
|
|
result.ocs.data.exact.remotes,
|
|
|
|
result.ocs.data.exact.remote_groups,
|
|
|
|
result.ocs.data.exact.emails,
|
|
|
|
result.ocs.data.exact.circles,
|
|
|
|
result.ocs.data.exact.rooms
|
|
|
|
);
|
|
|
|
|
|
|
|
var exactUsers = result.ocs.data.exact.users;
|
|
|
|
var exactGroups = result.ocs.data.exact.groups;
|
|
|
|
var exactRemotes = result.ocs.data.exact.remotes || [];
|
|
|
|
var exactRemoteGroups = result.ocs.data.exact.remote_groups || [];
|
|
|
|
var exactEmails = [];
|
|
|
|
if (typeof(result.ocs.data.emails) !== 'undefined') {
|
|
|
|
exactEmails = result.ocs.data.exact.emails;
|
|
|
|
}
|
|
|
|
var exactCircles = [];
|
|
|
|
if (typeof(result.ocs.data.circles) !== 'undefined') {
|
|
|
|
exactCircles = result.ocs.data.exact.circles;
|
|
|
|
}
|
|
|
|
var exactRooms = [];
|
|
|
|
if (typeof(result.ocs.data.rooms) !== 'undefined') {
|
|
|
|
exactRooms = result.ocs.data.exact.rooms;
|
|
|
|
}
|
|
|
|
|
|
|
|
var exactMatches = exactUsers.concat(exactGroups).concat(exactRemotes).concat(exactRemoteGroups).concat(exactEmails).concat(exactCircles).concat(exactRooms);
|
|
|
|
|
|
|
|
filter(
|
|
|
|
result.ocs.data.users,
|
|
|
|
result.ocs.data.groups,
|
|
|
|
result.ocs.data.remotes,
|
|
|
|
result.ocs.data.remote_groups,
|
|
|
|
result.ocs.data.emails,
|
|
|
|
result.ocs.data.circles,
|
|
|
|
result.ocs.data.rooms
|
|
|
|
);
|
|
|
|
|
|
|
|
var users = result.ocs.data.users;
|
|
|
|
var groups = result.ocs.data.groups;
|
|
|
|
var remotes = result.ocs.data.remotes || [];
|
|
|
|
var remoteGroups = result.ocs.data.remote_groups || [];
|
|
|
|
var lookup = result.ocs.data.lookup || [];
|
|
|
|
var emails = [];
|
|
|
|
if (typeof(result.ocs.data.emails) !== 'undefined') {
|
|
|
|
emails = result.ocs.data.emails;
|
|
|
|
}
|
|
|
|
var circles = [];
|
|
|
|
if (typeof(result.ocs.data.circles) !== 'undefined') {
|
|
|
|
circles = result.ocs.data.circles;
|
|
|
|
}
|
|
|
|
var rooms = [];
|
|
|
|
if (typeof(result.ocs.data.rooms) !== 'undefined') {
|
|
|
|
rooms = result.ocs.data.rooms;
|
|
|
|
}
|
|
|
|
|
|
|
|
var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(remoteGroups).concat(emails).concat(circles).concat(rooms).concat(lookup);
|
|
|
|
|
|
|
|
function dynamicSort(property) {
|
|
|
|
return function (a,b) {
|
|
|
|
var aProperty = '';
|
|
|
|
var bProperty = '';
|
|
|
|
if (typeof a[property] !== 'undefined') {
|
|
|
|
aProperty = a[property];
|
|
|
|
}
|
|
|
|
if (typeof b[property] !== 'undefined') {
|
|
|
|
bProperty = b[property];
|
|
|
|
}
|
|
|
|
return (aProperty < bProperty) ? -1 : (aProperty > bProperty) ? 1 : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sort share entries by uuid to properly group them
|
|
|
|
*/
|
|
|
|
var grouped = suggestions.sort(dynamicSort('uuid'));
|
|
|
|
|
|
|
|
var previousUuid = null;
|
|
|
|
var groupedLength = grouped.length;
|
|
|
|
var result = [];
|
|
|
|
/**
|
|
|
|
* build the result array that only contains all contact entries from
|
|
|
|
* merged contacts, if the search term matches its contact name
|
|
|
|
*/
|
|
|
|
for (var i = 0; i < groupedLength; i++) {
|
|
|
|
if (typeof grouped[i].uuid !== 'undefined' && grouped[i].uuid === previousUuid) {
|
|
|
|
grouped[i].merged = true;
|
|
|
|
}
|
|
|
|
if (typeof grouped[i].merged === 'undefined') {
|
|
|
|
result.push(grouped[i]);
|
|
|
|
}
|
|
|
|
previousUuid = grouped[i].uuid;
|
|
|
|
}
|
|
|
|
|
2019-08-02 02:05:15 +03:00
|
|
|
deferred.resolve(result, exactMatches, false);
|
2019-02-13 19:16:01 +03:00
|
|
|
} else {
|
|
|
|
deferred.reject(result.ocs.meta.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
).fail(function() {
|
|
|
|
deferred.reject();
|
|
|
|
});
|
|
|
|
|
|
|
|
this._lastRecommendations = {
|
|
|
|
model: model,
|
|
|
|
promise: deferred.promise()
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._lastRecommendations.promise;
|
|
|
|
},
|
|
|
|
|
|
|
|
recommendationHandler: function (response) {
|
|
|
|
var view = this;
|
|
|
|
var $shareWithField = $('.shareWithField');
|
|
|
|
this._getRecommendations(
|
|
|
|
view.model
|
2019-02-21 23:36:14 +03:00
|
|
|
).done(function(suggestions) {
|
|
|
|
console.info('recommendations', suggestions);
|
2019-02-13 19:16:01 +03:00
|
|
|
if (suggestions.length > 0) {
|
|
|
|
$shareWithField
|
|
|
|
.autocomplete("option", "autoFocus", true);
|
|
|
|
|
|
|
|
response(suggestions);
|
|
|
|
} else {
|
|
|
|
console.info('no sharing recommendations found');
|
|
|
|
response();
|
|
|
|
}
|
|
|
|
}).fail(function(message) {
|
|
|
|
console.error('could not load recommendations', message)
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2018-03-16 19:19:47 +03:00
|
|
|
autocompleteHandler: function (search, response) {
|
2019-02-13 19:16:01 +03:00
|
|
|
// If nothing is entered we show recommendations instead of search
|
|
|
|
// results
|
|
|
|
if (search.term.length === 0) {
|
2019-02-21 23:36:14 +03:00
|
|
|
console.info(search.term, 'empty search term -> using recommendations');
|
2019-02-13 19:16:01 +03:00
|
|
|
this.recommendationHandler(response);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-16 19:19:47 +03:00
|
|
|
var $shareWithField = $('.shareWithField'),
|
|
|
|
view = this,
|
|
|
|
$loading = this.$el.find('.shareWithLoading'),
|
|
|
|
$confirm = this.$el.find('.shareWithConfirm');
|
2017-02-22 02:22:06 +03:00
|
|
|
|
2018-03-16 19:19:47 +03:00
|
|
|
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;
|
|
|
|
}
|
2017-02-22 02:07:07 +03:00
|
|
|
|
2018-03-16 19:19:47 +03:00
|
|
|
$loading.removeClass('hidden');
|
|
|
|
$loading.addClass('inlineblock');
|
|
|
|
$confirm.addClass('hidden');
|
2018-03-20 18:58:04 +03:00
|
|
|
this._pendingOperationsCount++;
|
2018-03-16 19:19:47 +03:00
|
|
|
|
|
|
|
$shareWithField.removeClass('error')
|
|
|
|
.tooltip('hide');
|
|
|
|
|
2018-09-03 18:43:49 +03:00
|
|
|
var perPage = parseInt(oc_config['sharing.maxAutocompleteResults'], 10) || 200;
|
2018-03-16 19:19:47 +03:00
|
|
|
this._getSuggestions(
|
|
|
|
search.term.trim(),
|
|
|
|
perPage,
|
2019-02-21 23:36:14 +03:00
|
|
|
view.model,
|
|
|
|
view._lookup
|
2018-09-03 18:18:00 +03:00
|
|
|
).done(function(suggestions, exactMatches, moreResultsAvailable) {
|
2018-03-20 18:58:04 +03:00
|
|
|
view._pendingOperationsCount--;
|
|
|
|
if (view._pendingOperationsCount === 0) {
|
|
|
|
$loading.addClass('hidden');
|
|
|
|
$loading.removeClass('inlineblock');
|
|
|
|
$confirm.removeClass('hidden');
|
|
|
|
}
|
2018-03-16 19:19:47 +03:00
|
|
|
|
2018-03-19 17:36:08 +03:00
|
|
|
if (suggestions.length > 0) {
|
2018-03-16 19:19:47 +03:00
|
|
|
$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
|
2018-09-03 18:18:00 +03:00
|
|
|
if(moreResultsAvailable) {
|
2018-03-16 19:19:47 +03:00
|
|
|
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>');
|
2015-12-23 12:16:57 +03:00
|
|
|
}
|
2018-03-16 19:19:47 +03:00
|
|
|
|
2018-03-19 17:36:08 +03:00
|
|
|
} else {
|
2018-03-16 19:19:47 +03:00
|
|
|
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')
|
|
|
|
.attr('data-original-title', title)
|
|
|
|
.tooltip('hide')
|
|
|
|
.tooltip({
|
2019-02-21 23:36:14 +03:00
|
|
|
placement: 'top',
|
2018-03-16 19:19:47 +03:00
|
|
|
trigger: 'manual'
|
|
|
|
})
|
|
|
|
.tooltip('fixTitle')
|
|
|
|
.tooltip('show');
|
|
|
|
response();
|
2015-09-05 03:02:55 +03:00
|
|
|
}
|
2018-03-19 17:36:08 +03:00
|
|
|
}).fail(function(message) {
|
2018-03-20 18:58:04 +03:00
|
|
|
view._pendingOperationsCount--;
|
|
|
|
if (view._pendingOperationsCount === 0) {
|
|
|
|
$loading.addClass('hidden');
|
|
|
|
$loading.removeClass('inlineblock');
|
|
|
|
$confirm.removeClass('hidden');
|
|
|
|
}
|
2018-03-19 17:36:08 +03:00
|
|
|
|
|
|
|
if (message) {
|
|
|
|
OC.Notification.showTemporary(t('core', 'An error occurred ("{message}"). Please try again', { message: message }));
|
|
|
|
} else {
|
|
|
|
OC.Notification.showTemporary(t('core', 'An error occurred. Please try again'));
|
|
|
|
}
|
2015-09-05 03:02:55 +03:00
|
|
|
});
|
2015-08-11 23:36:28 +03:00
|
|
|
},
|
|
|
|
|
2015-09-12 13:17:15 +03:00
|
|
|
autocompleteRenderItem: function(ul, item) {
|
2018-10-10 15:58:58 +03:00
|
|
|
var icon = 'icon-user';
|
2019-01-14 16:09:12 +03:00
|
|
|
var text = escapeHTML(item.label);
|
2018-11-07 17:40:50 +03:00
|
|
|
var description = '';
|
|
|
|
var type = '';
|
|
|
|
var getTranslatedType = function(type) {
|
|
|
|
switch (type) {
|
|
|
|
case 'HOME':
|
|
|
|
return t('core', 'Home');
|
|
|
|
case 'WORK':
|
|
|
|
return t('core', 'Work');
|
|
|
|
case 'OTHER':
|
|
|
|
return t('core', 'Other');
|
|
|
|
default:
|
|
|
|
return '' + type;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if (typeof item.type !== 'undefined' && item.type !== null) {
|
|
|
|
type = getTranslatedType(item.type) + ' ';
|
|
|
|
}
|
|
|
|
|
2018-10-26 14:46:24 +03:00
|
|
|
if (typeof item.name !== 'undefined') {
|
2019-01-14 16:09:12 +03:00
|
|
|
text = escapeHTML(item.name);
|
2018-10-26 14:46:24 +03:00
|
|
|
}
|
2015-09-12 13:17:15 +03:00
|
|
|
if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
|
2018-10-10 15:58:58 +03:00
|
|
|
icon = 'icon-contacts-dark';
|
2015-09-12 13:17:15 +03:00
|
|
|
} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) {
|
2018-10-10 15:58:58 +03:00
|
|
|
icon = 'icon-shared';
|
2018-11-07 17:40:50 +03:00
|
|
|
description += item.value.shareWith;
|
2018-07-02 12:29:03 +03:00
|
|
|
} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP) {
|
|
|
|
text = t('core', '{sharee} (remote group)', { sharee: text }, undefined, { escape: false });
|
2018-10-10 15:58:58 +03:00
|
|
|
icon = 'icon-shared';
|
2018-11-07 17:40:50 +03:00
|
|
|
description += item.value.shareWith;
|
2016-07-29 16:37:08 +03:00
|
|
|
} else if (item.value.shareType === OC.Share.SHARE_TYPE_EMAIL) {
|
2018-10-10 15:58:58 +03:00
|
|
|
icon = 'icon-mail';
|
2018-11-07 17:40:50 +03:00
|
|
|
description += item.value.shareWith;
|
2017-03-17 22:48:33 +03:00
|
|
|
} else if (item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) {
|
|
|
|
text = t('core', '{sharee} ({type}, {owner})', {sharee: text, type: item.value.circleInfo, owner: item.value.circleOwner}, undefined, {escape: false});
|
2018-10-10 15:58:58 +03:00
|
|
|
icon = 'icon-circle';
|
2018-07-16 04:51:45 +03:00
|
|
|
} else if (item.value.shareType === OC.Share.SHARE_TYPE_ROOM) {
|
2018-10-10 15:58:58 +03:00
|
|
|
icon = 'icon-talk';
|
2015-09-12 13:17:15 +03:00
|
|
|
}
|
2018-11-07 17:40:50 +03:00
|
|
|
|
2016-10-06 18:12:10 +03:00
|
|
|
var insert = $("<div class='share-autocomplete-item'/>");
|
2018-10-18 13:36:37 +03:00
|
|
|
if (item.merged) {
|
|
|
|
insert.addClass('merged');
|
|
|
|
text = item.value.shareWith;
|
2018-11-07 17:40:50 +03:00
|
|
|
description = type;
|
2019-02-21 23:36:14 +03:00
|
|
|
} else if (item.lookup) {
|
|
|
|
text = item.label;
|
|
|
|
icon = false;
|
|
|
|
insert.append('<span class="icon icon-search search-globally"></span>');
|
2016-10-06 18:12:10 +03:00
|
|
|
} else {
|
2018-10-18 13:36:37 +03:00
|
|
|
var avatar = $("<div class='avatardiv'></div>").appendTo(insert);
|
|
|
|
if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) {
|
|
|
|
avatar.avatar(item.value.shareWith, 32, undefined, undefined, undefined, item.label);
|
|
|
|
} else {
|
|
|
|
if (typeof item.uuid === 'undefined') {
|
|
|
|
item.uuid = text;
|
|
|
|
}
|
|
|
|
avatar.imageplaceholder(item.uuid, text, 32);
|
2018-10-17 22:57:22 +03:00
|
|
|
}
|
2018-11-07 17:40:50 +03:00
|
|
|
description = type + description;
|
2018-10-26 14:46:24 +03:00
|
|
|
}
|
|
|
|
if (description !== '') {
|
|
|
|
insert.addClass('with-description');
|
2015-09-12 13:17:15 +03:00
|
|
|
}
|
2016-10-06 18:12:10 +03:00
|
|
|
|
|
|
|
$("<div class='autocomplete-item-text'></div>")
|
2018-10-17 22:56:41 +03:00
|
|
|
.html(
|
|
|
|
text.replace(
|
|
|
|
new RegExp(this.term, "gi"),
|
|
|
|
"<span class='ui-state-highlight'>$&</span>")
|
2018-10-18 13:36:37 +03:00
|
|
|
+ '<span class="autocomplete-item-details">' + description + '</span>'
|
2018-10-17 22:56:41 +03:00
|
|
|
)
|
2016-10-06 18:12:10 +03:00
|
|
|
.appendTo(insert);
|
|
|
|
insert.attr('title', item.value.shareWith);
|
2019-02-21 23:36:14 +03:00
|
|
|
if (icon) {
|
|
|
|
insert.append('<span class="icon ' + icon + '" title="' + text + '"></span>');
|
|
|
|
}
|
2016-10-06 18:12:10 +03:00
|
|
|
insert = $("<a>")
|
|
|
|
.append(insert);
|
2015-09-12 13:17:15 +03:00
|
|
|
return $("<li>")
|
|
|
|
.addClass((item.value.shareType === OC.Share.SHARE_TYPE_GROUP) ? 'group' : 'user')
|
|
|
|
.append(insert)
|
|
|
|
.appendTo(ul);
|
|
|
|
},
|
|
|
|
|
2015-09-14 18:47:47 +03:00
|
|
|
_onSelectRecipient: function(e, s) {
|
2018-03-20 18:58:04 +03:00
|
|
|
var self = this;
|
|
|
|
|
2018-10-25 22:36:44 +03:00
|
|
|
if (e.keyCode == 9) {
|
|
|
|
e.preventDefault();
|
2018-10-26 14:46:24 +03:00
|
|
|
if (typeof s.item.name !== 'undefined') {
|
|
|
|
e.target.value = s.item.name;
|
|
|
|
} else {
|
|
|
|
e.target.value = s.item.label;
|
|
|
|
}
|
2018-10-25 22:36:44 +03:00
|
|
|
setTimeout(function() {
|
|
|
|
$(e.target).attr('disabled', false)
|
|
|
|
.autocomplete('search', $(e.target).val());
|
|
|
|
}, 0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:36:14 +03:00
|
|
|
if (s.item.lookup) {
|
|
|
|
// Retrigger search but with global lookup this time
|
|
|
|
this._lookup = true;
|
|
|
|
var $shareWithField = this.$el.find('.shareWithField');
|
|
|
|
var val = $shareWithField.val();
|
|
|
|
setTimeout(function() {
|
|
|
|
console.debug('searching again, but globally. search term: ' + val);
|
|
|
|
$shareWithField.autocomplete("search", val);
|
|
|
|
}, 0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-09-14 18:47:47 +03:00
|
|
|
e.preventDefault();
|
2018-03-20 14:02:49 +03:00
|
|
|
// Ensure that the keydown handler for the input field is not
|
|
|
|
// called; otherwise it would try to add the recipient again, which
|
|
|
|
// would fail.
|
|
|
|
e.stopImmediatePropagation();
|
2016-02-12 16:01:15 +03:00
|
|
|
$(e.target).attr('disabled', true)
|
|
|
|
.val(s.item.label);
|
2018-03-20 18:58:04 +03:00
|
|
|
|
2016-02-12 16:01:15 +03:00
|
|
|
var $loading = this.$el.find('.shareWithLoading');
|
2017-11-16 19:27:20 +03:00
|
|
|
var $confirm = this.$el.find('.shareWithConfirm');
|
2018-03-20 18:58:04 +03:00
|
|
|
|
|
|
|
$loading.removeClass('hidden');
|
|
|
|
$loading.addClass('inlineblock');
|
2017-11-16 19:27:20 +03:00
|
|
|
$confirm.addClass('hidden');
|
2018-03-20 18:58:04 +03:00
|
|
|
this._pendingOperationsCount++;
|
2016-02-12 16:01:15 +03:00
|
|
|
|
|
|
|
this.model.addShare(s.item.value, {success: function() {
|
2018-03-21 05:57:14 +03:00
|
|
|
// Adding a share changes the suggestions.
|
|
|
|
self._lastSuggestions = undefined;
|
|
|
|
|
2016-02-12 16:01:15 +03:00
|
|
|
$(e.target).val('')
|
|
|
|
.attr('disabled', false);
|
2018-03-20 18:58:04 +03:00
|
|
|
|
|
|
|
self._pendingOperationsCount--;
|
|
|
|
if (self._pendingOperationsCount === 0) {
|
|
|
|
$loading.addClass('hidden');
|
|
|
|
$loading.removeClass('inlineblock');
|
|
|
|
$confirm.removeClass('hidden');
|
|
|
|
}
|
2016-02-16 21:40:44 +03:00
|
|
|
}, error: function(obj, msg) {
|
|
|
|
OC.Notification.showTemporary(msg);
|
2016-02-17 11:19:21 +03:00
|
|
|
$(e.target).attr('disabled', false)
|
|
|
|
.autocomplete('search', $(e.target).val());
|
2018-03-20 18:58:04 +03:00
|
|
|
|
|
|
|
self._pendingOperationsCount--;
|
|
|
|
if (self._pendingOperationsCount === 0) {
|
|
|
|
$loading.addClass('hidden');
|
|
|
|
$loading.removeClass('inlineblock');
|
|
|
|
$confirm.removeClass('hidden');
|
|
|
|
}
|
2016-02-12 16:01:15 +03:00
|
|
|
}});
|
2015-09-14 18:47:47 +03:00
|
|
|
},
|
|
|
|
|
2018-03-19 20:54:27 +03:00
|
|
|
_confirmShare: function() {
|
|
|
|
var self = this;
|
|
|
|
var $shareWithField = $('.shareWithField');
|
|
|
|
var $loading = this.$el.find('.shareWithLoading');
|
|
|
|
var $confirm = this.$el.find('.shareWithConfirm');
|
|
|
|
|
|
|
|
$loading.removeClass('hidden');
|
|
|
|
$loading.addClass('inlineblock');
|
|
|
|
$confirm.addClass('hidden');
|
2018-03-20 18:58:04 +03:00
|
|
|
this._pendingOperationsCount++;
|
2018-03-19 20:54:27 +03:00
|
|
|
|
|
|
|
$shareWithField.prop('disabled', true);
|
|
|
|
|
2018-03-20 14:02:49 +03:00
|
|
|
// Disabling the autocompletion does not clear its search timeout;
|
|
|
|
// removing the focus from the input field does, but only if the
|
|
|
|
// autocompletion is not disabled when the field loses the focus.
|
|
|
|
// Thus, the field has to be disabled before disabling the
|
|
|
|
// autocompletion to prevent an old pending search result from
|
|
|
|
// appearing once the field is enabled again.
|
|
|
|
$shareWithField.autocomplete('close');
|
|
|
|
$shareWithField.autocomplete('disable');
|
|
|
|
|
2018-03-20 15:44:28 +03:00
|
|
|
var restoreUI = function() {
|
2018-03-20 18:58:04 +03:00
|
|
|
self._pendingOperationsCount--;
|
|
|
|
if (self._pendingOperationsCount === 0) {
|
|
|
|
$loading.addClass('hidden');
|
|
|
|
$loading.removeClass('inlineblock');
|
|
|
|
$confirm.removeClass('hidden');
|
|
|
|
}
|
2018-03-20 15:44:28 +03:00
|
|
|
|
|
|
|
$shareWithField.prop('disabled', false);
|
|
|
|
$shareWithField.focus();
|
|
|
|
};
|
|
|
|
|
2018-09-03 18:43:49 +03:00
|
|
|
var perPage = parseInt(oc_config['sharing.maxAutocompleteResults'], 10) || 200;
|
2018-03-19 20:54:27 +03:00
|
|
|
this._getSuggestions(
|
|
|
|
$shareWithField.val(),
|
|
|
|
perPage,
|
|
|
|
this.model,
|
2019-02-21 23:36:14 +03:00
|
|
|
this._lookup
|
2018-03-19 20:54:27 +03:00
|
|
|
).done(function(suggestions, exactMatches) {
|
|
|
|
if (suggestions.length === 0) {
|
2018-03-20 15:44:28 +03:00
|
|
|
restoreUI();
|
2018-03-19 20:54:27 +03:00
|
|
|
|
2018-03-20 14:02:49 +03:00
|
|
|
$shareWithField.autocomplete('enable');
|
|
|
|
|
2018-03-19 20:54:27 +03:00
|
|
|
// There is no need to show an error message here; it will
|
|
|
|
// be automatically shown when the autocomplete is activated
|
|
|
|
// again (due to the focus on the field) and it finds no
|
|
|
|
// matches.
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exactMatches.length !== 1) {
|
2018-03-20 15:44:28 +03:00
|
|
|
restoreUI();
|
2018-03-19 20:54:27 +03:00
|
|
|
|
2018-03-20 14:02:49 +03:00
|
|
|
$shareWithField.autocomplete('enable');
|
|
|
|
|
2018-03-19 20:54:27 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var actionSuccess = function() {
|
2018-03-21 05:57:14 +03:00
|
|
|
// Adding a share changes the suggestions.
|
|
|
|
self._lastSuggestions = undefined;
|
|
|
|
|
2018-03-19 20:54:27 +03:00
|
|
|
$shareWithField.val('');
|
2018-03-20 15:44:28 +03:00
|
|
|
|
|
|
|
restoreUI();
|
2018-03-20 14:02:49 +03:00
|
|
|
|
|
|
|
$shareWithField.autocomplete('enable');
|
2018-03-19 20:54:27 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
var actionError = function(obj, msg) {
|
2018-03-20 15:44:28 +03:00
|
|
|
restoreUI();
|
2018-03-19 20:54:27 +03:00
|
|
|
|
2018-03-20 14:02:49 +03:00
|
|
|
$shareWithField.autocomplete('enable');
|
|
|
|
|
2018-03-19 20:54:27 +03:00
|
|
|
OC.Notification.showTemporary(msg);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.model.addShare(exactMatches[0].value, {
|
|
|
|
success: actionSuccess,
|
|
|
|
error: actionError
|
|
|
|
});
|
|
|
|
}).fail(function(message) {
|
2018-03-20 15:44:28 +03:00
|
|
|
restoreUI();
|
2018-03-19 20:54:27 +03:00
|
|
|
|
2018-03-20 14:02:49 +03:00
|
|
|
$shareWithField.autocomplete('enable');
|
|
|
|
|
2018-03-19 20:54:27 +03:00
|
|
|
// There is no need to show an error message here; it will be
|
|
|
|
// automatically shown when the autocomplete is activated again
|
|
|
|
// (due to the focus on the field) and getting the suggestions
|
|
|
|
// fail.
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2015-09-28 16:57:57 +03:00
|
|
|
_toggleLoading: function(state) {
|
|
|
|
this._loading = state;
|
|
|
|
this.$el.find('.subView').toggleClass('hidden', state);
|
|
|
|
this.$el.find('.loading').toggleClass('hidden', !state);
|
|
|
|
},
|
|
|
|
|
|
|
|
_onRequest: function() {
|
|
|
|
// only show the loading spinner for the first request (for now)
|
|
|
|
if (!this._loadingOnce) {
|
|
|
|
this._toggleLoading(true);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_onEndRequest: function() {
|
2015-10-02 17:35:33 +03:00
|
|
|
var self = this;
|
2015-09-28 16:57:57 +03:00
|
|
|
this._toggleLoading(false);
|
2015-10-02 17:35:33 +03:00
|
|
|
if (!this._loadingOnce) {
|
|
|
|
this._loadingOnce = true;
|
|
|
|
}
|
2015-09-28 16:57:57 +03:00
|
|
|
},
|
|
|
|
|
2015-07-31 01:07:41 +03:00
|
|
|
render: function() {
|
2018-03-20 14:02:49 +03:00
|
|
|
var self = this;
|
2018-10-01 21:46:29 +03:00
|
|
|
var baseTemplate = OC.Share.Templates['sharedialogview'];
|
2015-07-31 01:07:41 +03:00
|
|
|
|
2015-08-08 01:23:06 +03:00
|
|
|
this.$el.html(baseTemplate({
|
2015-10-16 11:54:45 +03:00
|
|
|
cid: this.cid,
|
2015-07-31 01:07:41 +03:00
|
|
|
shareLabel: t('core', 'Share'),
|
|
|
|
sharePlaceholder: this._renderSharePlaceholderPart(),
|
2015-09-15 16:29:30 +03:00
|
|
|
isSharingAllowed: this.model.sharePermissionPossible()
|
2015-07-31 01:07:41 +03:00
|
|
|
}));
|
|
|
|
|
2015-10-16 11:54:45 +03:00
|
|
|
var $shareField = this.$el.find('.shareWithField');
|
2015-09-15 16:29:30 +03:00
|
|
|
if ($shareField.length) {
|
2018-03-20 14:02:49 +03:00
|
|
|
var shareFieldKeydownHandler = function(event) {
|
|
|
|
if (event.keyCode !== 13) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
self._confirmShare();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2015-09-15 16:29:30 +03:00
|
|
|
$shareField.autocomplete({
|
2019-02-13 19:16:01 +03:00
|
|
|
minLength: 0,
|
2015-09-15 16:29:30 +03:00
|
|
|
delay: 750,
|
2015-09-22 18:16:20 +03:00
|
|
|
focus: function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
},
|
2015-09-15 16:29:30 +03:00
|
|
|
source: this.autocompleteHandler,
|
2018-12-08 22:51:06 +03:00
|
|
|
select: this._onSelectRecipient,
|
|
|
|
open: function() {
|
|
|
|
var autocomplete = $(this).autocomplete('widget');
|
|
|
|
var numberOfItems = autocomplete.find('li').size();
|
|
|
|
autocomplete.removeClass('item-count-1');
|
|
|
|
autocomplete.removeClass('item-count-2');
|
|
|
|
if (numberOfItems <= 2) {
|
|
|
|
autocomplete.addClass('item-count-' + numberOfItems);
|
|
|
|
}
|
|
|
|
}
|
2015-09-15 16:29:30 +03:00
|
|
|
}).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem;
|
2018-03-20 14:02:49 +03:00
|
|
|
|
|
|
|
$shareField.on('keydown', null, shareFieldKeydownHandler);
|
2015-09-15 16:29:30 +03:00
|
|
|
}
|
2015-09-05 03:02:55 +03:00
|
|
|
|
2015-08-21 20:35:13 +03:00
|
|
|
this.resharerInfoView.$el = this.$el.find('.resharerInfoView');
|
2015-08-21 16:00:15 +03:00
|
|
|
this.resharerInfoView.render();
|
|
|
|
|
2015-08-21 21:29:12 +03:00
|
|
|
this.linkShareView.$el = this.$el.find('.linkShareView');
|
|
|
|
this.linkShareView.render();
|
|
|
|
|
2015-08-25 17:07:14 +03:00
|
|
|
this.shareeListView.$el = this.$el.find('.shareeListView');
|
2015-09-01 13:43:04 +03:00
|
|
|
this.shareeListView.render();
|
2015-08-25 17:07:14 +03:00
|
|
|
|
2015-08-18 18:23:32 +03:00
|
|
|
this.$el.find('.hasTooltip').tooltip();
|
|
|
|
|
2015-08-08 01:23:06 +03:00
|
|
|
return this;
|
2015-07-31 01:07:41 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets whether share by link should be displayed or not. Default is
|
|
|
|
* true.
|
|
|
|
*
|
|
|
|
* @param {bool} showLink
|
|
|
|
*/
|
|
|
|
setShowLink: function(showLink) {
|
|
|
|
this._showLink = (typeof showLink === 'boolean') ? showLink : true;
|
2015-08-21 16:40:50 +03:00
|
|
|
this.linkShareView.showLink = this._showLink;
|
2015-07-31 01:07:41 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
_renderSharePlaceholderPart: function () {
|
2016-10-31 13:52:00 +03:00
|
|
|
var allowRemoteSharing = this.configModel.get('isRemoteShareAllowed');
|
|
|
|
var allowMailSharing = this.configModel.get('isMailShareAllowed');
|
2016-03-21 21:47:10 +03:00
|
|
|
|
2017-04-18 13:08:35 +03:00
|
|
|
if (!allowRemoteSharing && allowMailSharing) {
|
|
|
|
return t('core', 'Name or email address...');
|
2016-10-31 13:52:00 +03:00
|
|
|
}
|
2017-04-18 13:08:35 +03:00
|
|
|
if (allowRemoteSharing && !allowMailSharing) {
|
|
|
|
return t('core', 'Name or federated cloud ID...');
|
2016-10-31 13:52:00 +03:00
|
|
|
}
|
2017-04-18 13:08:35 +03:00
|
|
|
if (allowRemoteSharing && allowMailSharing) {
|
|
|
|
return t('core', 'Name, federated cloud ID or email address...');
|
2015-07-31 01:07:41 +03:00
|
|
|
}
|
2016-03-21 21:47:10 +03:00
|
|
|
|
2017-04-18 13:08:35 +03:00
|
|
|
return t('core', 'Name...');
|
2015-07-31 01:07:41 +03:00
|
|
|
},
|
|
|
|
|
2015-08-08 01:23:06 +03:00
|
|
|
});
|
2015-07-31 01:07:41 +03:00
|
|
|
|
|
|
|
OC.Share.ShareDialogView = ShareDialogView;
|
|
|
|
|
|
|
|
})();
|